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    }