001    package org.mycore.services.z3950;
002    
003    import java.io.IOException;
004    
005    import javax.servlet.ServletException;
006    import javax.servlet.ServletOutputStream;
007    import javax.servlet.http.HttpServletRequest;
008    import javax.servlet.http.HttpServletResponse;
009    
010    import org.apache.log4j.Logger;
011    import org.mycore.common.MCRConfiguration;
012    import org.mycore.common.MCRConfigurationException;
013    import org.mycore.frontend.servlets.MCRServlet;
014    import org.mycore.frontend.servlets.MCRServletJob;
015    
016    /**
017     * Dieses Servlet implementiert eine MyCoRe-Schnittstelle für einen
018     * Z39.50-Server. Die Suche wird dabei an eine Serviceklasse
019     * delegiert.
020     * @author Andreas de Azevedo
021     * @version 1.0
022     *
023     */
024    public class MCRZ3950Servlet extends MCRServlet {
025    
026        private static final long serialVersionUID = 10137452L;
027    
028        private static Logger logger = Logger.getLogger(MCRZ3950Servlet.class);
029    
030        // Z3950-Anfrage (find), soll im Format "Prefix" sein
031        private String query;
032    
033        // Dokumententyp
034        private String type;
035    
036        // Host, auf dem dies Suche angewandt wird
037        private String host;
038        
039        // Index des Suchergebnisses, beginnend bei 1
040        private int index;
041    
042        // Größe des Resultats (nicht implementiert)
043        private int size;
044        
045        // Ist true, wenn das Ergebnis gekürzt werden soll
046        private boolean cut;
047        
048        // Property, dass die Serviceklasse enthält
049        private static final String MCR_QUERYSERVICE = "MCR.z3950.queryservice";
050        
051        /**
052         * Method getServletInfo. Returns a short description of the servlet.
053         * 
054         * @return String
055         */
056        public String getServletInfo() {
057            return "This class implements an Z3950-Interface for MyCoRe";
058        }
059    
060        /**
061         * This method handles HTTP GET/POST requests and resolves them to output.
062         * 
063         * @param job
064         *            MCRServletJob containing request and response objects
065         * @exception IOException
066         *                for java I/O errors.
067         * @exception ServletException
068         *                for errors from the servlet engine.
069         */
070        public void doGetPost(MCRServletJob job) throws IOException, ServletException {
071               HttpServletRequest request = job.getRequest();
072           HttpServletResponse response = job.getResponse();
073    
074               // Ausgabe in UTF-8
075               response.setContentType("text/xml; charset=UTF-8");
076               
077               // Parameter überprüfen
078               if (!checkInputParameter(request)) {
079                       logger.error("Es wurden nicht genügend Parameter angegeben!");
080               // Keine Ergebnisse, es wird "0" zurückgegeben
081                       ServletOutputStream out = response.getOutputStream();
082                       out.write("0".getBytes("UTF-8"));
083                       out.close();           
084                       return;
085               }
086               
087               MCRZ3950Query service = null;
088    
089           try {
090               // check if property is set, else Exception is thrown
091               service = (MCRZ3950Query) MCRConfiguration.instance().getInstanceOf(MCR_QUERYSERVICE);
092           } catch (MCRConfigurationException mcrx) {
093               logger.fatal("Missing configuration item: " + MCR_QUERYSERVICE + ".", mcrx);
094               return;
095           }
096           
097           service.setQuery(query);
098            
099               if (service.search()) {
100                       /*
101                        * Wenn es Ergebnisse gab, dann sind zwei Fälle zu unterscheiden:
102                        * 1. Der Z39.50-Server hat eine search-Anfrage getätigt, in diesem
103                        *    Fall ist nur die Anzahl der Ergebnisse relevant und wird in
104                        *    den Response-Output-Stream geschrieben.
105                        * 2. Der Z39.50-Server hat eine present-Anfrage getätigt, d.h. die
106                        *    Ergebnisse der Suchanfrage sollen nun angezeigt werden. Dann
107                        *    wird entsprechend ein Ergebnis-Dokument als Antwort zurück-
108                        *    gegeben. Zur Zeit ist wird noch jedes Ergebnis einzeln
109                        *    abgefragt, daher wird das Ergebnis-Dokument immer auf ein
110                        *    einzelnes Ergebnis gekürzt. Außerdem werden noch alle Tags,
111                        *    die vom Typ "MCRMetaClassification" sind mit ihrem Label
112                        *    gefüllt, da die IDs an sich wertlos sind.
113                        */
114                       if (cut) {
115                               service.cutDownTo(index);
116                               service.setIndex(index - 1);
117                       }
118                       try {
119                               ServletOutputStream out = response.getOutputStream();
120                               if (cut) {
121                                       byte[] mycoreResult = service.getDocumentAsByteArray();
122                                       out.write(mycoreResult);
123                               } else {
124                                       out.write(String.valueOf(service.getSize()).getBytes("UTF-8"));
125                               }
126                               out.close();
127                       } catch (IOException ioe) {
128                               ioe.printStackTrace();
129                       }
130               } else {
131                       // Keine Ergebnisse
132                       ServletOutputStream out = response.getOutputStream();
133                       out.write("0".getBytes("UTF-8"));
134                       out.close();
135               }
136       }
137                
138       private final boolean checkInputParameter(HttpServletRequest request) {
139               query = request.getParameter("query");
140               type = request.getParameter("type");
141               String cutStr = request.getParameter("cut");
142               cut = false;
143               if (cutStr != null) {
144                       if (cutStr.equals("true")) cut = true;
145               } 
146               
147               String sizeStr = request.getParameter("size");
148               size = 0;
149               
150               if (sizeStr != null) {
151                       size = Integer.parseInt(sizeStr);
152               }
153               
154               String indexStr = request.getParameter("index");
155               index = 0;
156               
157               if (indexStr != null) {
158                       index = Integer.parseInt(indexStr);
159               }
160               
161               if (host == null) {
162                       host = "local";
163               }
164               
165               if (host.equals("")) {
166                       host = "local";
167               }
168               
169               if (query == null) {
170                       query = "";
171               }
172               
173               if (type == null) {
174                       logger.debug("Parameter type is NULL!");
175                       return false;
176               }
177               
178               if (type.equals("")) {
179                       logger.debug("Parameter type is EMPTY!");
180                       return false;
181               }
182               
183               type = type.toLowerCase();
184               
185               logger.info("MCRZ3950Servlet: RequestEncoding = " + request.getCharacterEncoding());
186               logger.info("MCRZ3950Servlet: ContentType = " + request.getContentType());
187               logger.info("MCRZ3950Servlet: type = " + type);
188               logger.info("MCRZ3950Servlet: hosts = " + host);
189               logger.info("MCRZ3950Servlet: query = \"" + query + "\"");
190               logger.info("MCRZ3950Servlet: cut = \"" + cut + "\"");
191               logger.info("MCRZ3950Servlet: index = \"" + index + "\"");
192               logger.info("MCRZ3950Servlet: size = \"" + size + "\"");
193               
194               return true;
195       }
196    
197    }