001 package org.mycore.services.z3950;
002
003 import java.io.StringReader;
004 import java.util.Iterator;
005 import java.util.List;
006
007 import org.apache.log4j.Logger;
008 import org.jdom.Element;
009 import org.mycore.common.MCRConfiguration;
010 import org.mycore.common.MCRUtils;
011 import org.mycore.datamodel.metadata.MCRObjectID;
012 import org.mycore.datamodel.common.MCRXMLTableManager;
013 import org.mycore.parsers.bool.MCRCondition;
014 import org.mycore.services.fieldquery.MCRQueryManager;
015 import org.mycore.services.fieldquery.MCRResults;
016
017 import org.mycore.services.fieldquery.*;
018
019 import org.mycore.datamodel.classifications2.MCRCategory;
020 import org.mycore.datamodel.classifications2.MCRCategoryDAOFactory;
021 import org.mycore.datamodel.classifications2.MCRCategoryID;
022 /**
023 * Diese Klasse ist eine Implementierung eines Suchservice f�r die Z39.50-
024 * Schnittstelle. Dabei werden nur Z39.50-Anfragen im Prefixformat
025 * entgegengenommen.
026 * @author Andreas de Azevedo
027 * @version 1.0
028 *
029 */
030 public class MCRZ3950QueryService implements MCRZ3950Query {
031
032 protected static MCRConfiguration CONFIG = MCRConfiguration.instance();
033
034 private static Logger logger = Logger.getLogger(MCRZ3950QueryService.class);
035
036 private static MCRXMLTableManager TM = MCRXMLTableManager.instance();
037
038 // Die Z39.50-Anfrage als String
039 private String query;
040
041 // Das Ergebnis der Suche
042 private MCRResults mycoreResults;
043
044 // Wir geben immer nur ein Ergebnis zur�ck, normalerweise das erste
045 private int index;
046
047
048 public MCRZ3950QueryService() {
049 this(null);
050 }
051
052 public MCRZ3950QueryService(String query) {
053 this.query = query;
054 index = 0;
055 }
056
057 public void cutDownTo(int maxresults) {
058 if (mycoreResults.getNumHits() > 0 && maxresults > 0)
059 mycoreResults.cutResults(maxresults);
060 }
061
062 public void sort() {}
063
064 /**
065 * Gibt alle Ergebnisse als Bytestrom zur�ck.
066 * @return Das Ergebnisdokument als Byte-Array, null falls es keine Ergebnisse gab.
067 */
068 public byte[] getDocumentAsByteArray() {
069 byte[] result = null;
070 if (mycoreResults.getNumHits() > 0)
071 {
072 MCRHit hit = mycoreResults.getHit(index);
073 String id = hit.getID();
074 // check the ID and retrieve the data
075 org.jdom.Document d = TM.readDocument(new MCRObjectID(id));
076 fillClassificationsWithLabels(d.getRootElement());
077
078 // build old MCRXMLContainer so that stylesheets in jzkit package must not be changed
079 // cleaning action in Hamburg 2006/11/21 has caused this
080 org.jdom.Element root = new org.jdom.Element( "mcr_results");
081 org.jdom.Element ele = new org.jdom.Element( "mcr_result");
082 root.addContent(ele);
083 ele.setAttribute("id", id);
084 ele.addContent(d.cloneContent());
085
086 org.jdom.output.XMLOutputter outputter = new org.jdom.output.XMLOutputter();
087 logger.debug(outputter.outputString(root));
088 result = MCRUtils.getByteArray(new org.jdom.Document( root));
089 }
090 return result;
091 }
092
093 /**
094 * F�hrt eine Suchanfrage in MyCoRe aus.
095 * @return True falls es Ergebnisse gab, sonst False.
096 */
097 public boolean search() {
098 MCRZ3950PrefixQueryParser pqs = new MCRZ3950PrefixQueryParser( new StringReader( query ) );
099 MCRCondition condition = pqs.parse();
100
101 if (logger.isDebugEnabled())
102 logger.debug("Transformed query: " + condition.toString());
103
104 mycoreResults = MCRQueryManager.search(new MCRQuery( condition ));
105 if (mycoreResults.getNumHits() > 0)
106 return true;
107 else
108 return false;
109 }
110
111 /**
112 * Die Methode <code>fillClassificationsWithLabels</code> durchsucht alle
113 * Metadaten und untersucht deren benutzte Klassifikationen. Da in den
114 * Metadaten nur ein Verweis auf Klasse und Kategorie ist, wird dieser
115 * erg�nzt durch sein Label.
116 */
117 private void fillClassificationsWithLabels(org.jdom.Element result) {
118 Element metadata = result.getChild("metadata");
119 // Alle Kinder des Knotens, also alle Metadaten
120 List metadataChildren = metadata.getChildren();
121 Iterator itm = metadataChildren.iterator();
122 // Iteriere �ber alle Knoten
123 while (itm.hasNext()) {
124 // Pr�fe, ob der Knoten eine Klassifikation benutzt
125 Element parent = (Element) itm.next();
126 String cl = parent.getAttributeValue("class");
127 if (cl.equals("MCRMetaClassification")) {
128 // Iteriere �ber alle Kinder des Knotens (z.B. Subject)
129 List children = parent.getChildren();
130 Iterator it = children.iterator();
131 while (it.hasNext()) {
132 Element e = (Element) it.next();
133 String classificationId = e.getAttributeValue("classid");
134 String categoryId = e.getAttributeValue("categid");
135 MCRCategory category = MCRCategoryDAOFactory.getInstance().getCategory(new MCRCategoryID(classificationId, categoryId), -1);
136 // Fülle den Knoten mit dem Klassifiaktions-Label
137 // TODO: please change: language is random
138 e.setText(category.getLabels().iterator().next().getText());
139 }
140 }
141 }
142 }
143
144 public int getSize() {
145 return mycoreResults.getNumHits();
146 }
147
148 public int getIndex() {
149 return index;
150 }
151
152 public void setIndex(int index) {
153 this.index = index;
154 // mycoreResults = mycoreResults.exportElementToContainer(index);
155 }
156
157 public String getQuery() {
158 return query;
159 }
160
161 public void setQuery(String query) {
162 this.query = query;
163 }
164
165 }