source: MDService2/trunk/MDService2/src/eu/clarin/cmdi/mdservice/action/SRUProxyAction.java @ 1467

Last change on this file since 1467 was 1467, checked in by gaba, 13 years ago

SRU queries added

File size: 16.6 KB
Line 
1package eu.clarin.cmdi.mdservice.action;
2
3import java.io.BufferedInputStream;
4import java.io.BufferedReader;
5import java.io.ByteArrayInputStream;
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.io.InputStreamReader;
11import java.io.StringWriter;
12import java.io.UnsupportedEncodingException;
13import java.net.MalformedURLException;
14import java.net.URISyntaxException;
15import java.net.URL;
16import java.util.HashMap;
17import java.util.Iterator;
18import java.util.Map;
19import java.util.Set;
20
21import javax.servlet.http.HttpServletRequest;
22import javax.servlet.http.HttpSession;
23import javax.xml.parsers.DocumentBuilder;
24import javax.xml.parsers.DocumentBuilderFactory;
25import javax.xml.parsers.ParserConfigurationException;
26import javax.xml.transform.TransformerConfigurationException;
27import javax.xml.transform.TransformerException;
28import javax.xml.transform.TransformerFactory;
29import javax.xml.transform.TransformerFactoryConfigurationError;
30import javax.xml.transform.dom.DOMSource;
31import javax.xml.transform.stream.StreamResult;
32
33import net.sf.json.JSON;
34import net.sf.json.JSONArray;
35import net.sf.json.JSONObject;
36import net.sf.json.JSONSerializer;
37import net.sf.json.xml.XMLSerializer;
38
39
40import org.apache.commons.io.IOUtils;
41import org.apache.commons.lang.StringEscapeUtils;
42import org.apache.struts2.interceptor.ServletRequestAware;
43import org.w3c.dom.Document;
44import org.w3c.dom.Element;
45import org.w3c.dom.Node;
46import org.xml.sax.InputSource;
47import org.xml.sax.SAXException;
48
49import com.opensymphony.xwork2.ActionSupport;
50
51import eu.clarin.cmdi.mdservice.model.Diagnostic;
52import eu.clarin.cmdi.mdservice.model.Diagnostics;
53
54
55public class SRUProxyAction extends GenericProxyAction//ActionSupport
56//implements ServletRequestAware
57{
58
59        private static final long serialVersionUID = 1L;
60       
61        private Diagnostics diagnostics;
62       
63        /**
64         * Properties to be filled by Struts with according request-parameters
65         */     
66        private String q;
67        private String version;
68        private String operation;
69        private String query;
70        private String scanClause;
71        private int startRecord;
72        private int maximumRecords;
73        private String recordPacking;
74        private String recordSchema;
75        private String recordXPath;
76        private int resultSetTTL;
77        private String sortKeys;
78        private String stylesheet;     
79        private String x_cmd_repository;
80        private String x_cmd_collections;
81
82        private MDRepoProxyAction mdrepoproxyaction;
83        private TermsProxyAction termsproxyaction;
84        //private InputStream resultStream;
85        //private HttpServletRequest request;
86       
87        private static int OP_SEARCHRETRIEVE = 1;
88        private static int OP_EXPLAIN = 2;
89        private static int OP_SCAN = 3;
90       
91        //TODO cache after analysis
92        @Override
93        public String getCache() {
94                return Cache.SKIP;
95        }
96       
97        private final static HashMap<String,String> hash_operations = new HashMap<String,String>();
98         static
99         {       
100                 hash_operations.put("searchRetrieve", "recordset");
101                 hash_operations.put("explain", "model"); /* could be terms*/ 
102                 hash_operations.put("scan", "values");
103         }
104         
105         private final static HashMap<String,Integer> operation_code = new HashMap<String,Integer>();
106         static
107         {       
108                 operation_code.put("searchRetrieve", OP_SEARCHRETRIEVE);
109                 operation_code.put("explain", OP_EXPLAIN);
110                 operation_code.put("scan", OP_SCAN);
111         }
112         
113         public SRUProxyAction(){
114                 super();
115                 initialize();
116         }
117         
118         protected void  initialize(){
119                 //repository = 1;
120                 this.startRecord = 1;
121                 this.maximumRecords = 50;
122         }
123         
124         /*@Override
125                public void setServletRequest(HttpServletRequest arg0) {
126                        request = arg0;
127                }
128
129                public HttpServletRequest getServletRequest() {
130                        return request;
131                }
132                */
133                public Diagnostics getDiagnostics(){
134                        return this.diagnostics;
135                }
136               
137                public void setDiagnostics(Diagnostics diagnostics){
138                        this.diagnostics = diagnostics;
139                }
140       
141               
142         public String getQ() {
143                        return q;
144                }
145
146                public void setQ(String q) {
147                        this.q = q;
148                }
149         /*
150         public InputStream getResultStream() {
151             return resultStream;
152         }
153         public void setResultStream(InputStream _resultStream){
154                resultStream = _resultStream;
155         }
156        */
157
158        public String getVersion() {
159                return version;
160        }
161
162        public void setVersion(String version) {
163                this.version = version;
164        }
165
166        public String getOperation() {
167                return operation;
168        }
169
170        public void setOperation(String operation) {
171                this.operation = operation;
172        }
173       
174        public String getQuery() {
175                return query;
176        }
177
178        public void setQuery(String query) {
179                this.query = query;
180        }
181
182        public String getScanClause() {
183                return scanClause;
184        }
185
186        public void setScanClause(String scanClause) {
187                this.scanClause = scanClause;
188        }
189
190       
191        public int getStartRecord() {
192                return startRecord;
193        }
194
195        public void setStartRecord(int startRecord) {
196                this.startRecord = startRecord;
197        }
198        public int getMaximumRecords() {
199                return maximumRecords;
200        }
201
202        public void setMaximumRecords(int maximumRecords) {
203                this.maximumRecords = maximumRecords;
204        }
205       
206        public String getRecordPacking() {
207                return recordPacking;
208        }
209
210        public void setRecordPacking(String recordPacking) {
211                this.recordPacking = recordPacking;
212        }
213
214        public String getRecordSchema() {
215                return recordSchema;
216        }
217
218        public void setRecordSchema(String recordSchema) {
219                this.recordSchema = recordSchema;
220        }
221
222        public String getRecordXPath() {
223                return recordXPath;
224        }
225
226        public void setRecordXPath(String recordXPath) {
227                this.recordXPath = recordXPath;
228        }
229
230        public int getResultSetTTL() {
231                return resultSetTTL;
232        }
233
234        public void setResultSetTTL(int resultSetTTL) {
235                this.resultSetTTL = resultSetTTL;
236        }
237       
238        public String getSortKeys() {
239                return sortKeys;
240        }
241
242        public void setSortKeys(String sortKeys) {
243                this.sortKeys = sortKeys;
244        }
245               
246        public String getStylesheet() {
247                return stylesheet;
248        }
249
250        public void setStylesheet(String stylesheet) {
251                this.stylesheet = stylesheet;
252        }
253       
254        public String getX_cmd_repository(){
255                return x_cmd_repository;
256        }
257       
258        public void setX_cmd_repository(String x_cmd_repository){
259                this.x_cmd_repository = x_cmd_repository;
260        }
261
262        public String getX_cmd_collections(){
263                return x_cmd_collections;
264        }
265       
266        public void setX_cmd_collections(String x_cmd_collections){
267                this.x_cmd_collections = x_cmd_collections;
268        }
269
270       
271        public String getDiagnosticStreamName() throws TransformerConfigurationException, UnsupportedEncodingException, ParserConfigurationException, TransformerException, TransformerFactoryConfigurationError{
272                this.setResultStream(this.Diagnostics().buildXMLStream());
273                return "resultStream";
274        }
275        /**
276         * primitive identification of the target-proxy
277         * base for finding the right base_url in the props
278         * subclass has to override with its specific proxykey
279         * @return
280         */
281        public String getProxyKey() {
282                return "";
283        }
284       
285        @Override
286        public String getBaseURI() {           
287                Admin.notifyUser("SRU-repositorypath:" + getRepositoryPath());
288                String uri = getRepositoryPath();//Admin.getConfig().getProperty(getProxyKey() + ".uri");               
289                return uri;
290        }
291       
292        public Diagnostics Diagnostics(){
293                if (this.diagnostics == null){
294                        this.diagnostics = new Diagnostics();
295                }
296                return this.diagnostics;
297        }
298       
299        public void prepareOperation() throws UnsupportedEncodingException{
300               
301                mdrepoproxyaction = new MDRepoProxyAction();
302                mdrepoproxyaction.setDiagnostics(diagnostics);
303                mdrepoproxyaction.setActionkey(hash_operations.get(this.getOperation()));
304               
305                // set the SRU extern property in proxyaction
306                if (this.getX_cmd_repository() != null ) {
307                        mdrepoproxyaction.setRepository(this.getX_cmd_repository());
308                        //TODO\
309                        if (mdrepoproxyaction.getBaseURI() == null) this.Diagnostics().Add(Diagnostic.UNSUPPORTED_PARAMETERVALUE, "Unknown repository." + getX_cmd_repository());
310                }
311               
312                if (operation.equals("searchRetrieve")){
313                       
314                        //query
315                        mdrepoproxyaction.setSquery("");
316                        if (this.query == null) {
317                                this.Diagnostics().Add(Diagnostic.MANDATORY_NOTSUPPLIED, "query");
318                                //return -1;
319                        }
320                        mdrepoproxyaction.setQ(getQuery());                     
321                        mdrepoproxyaction.setFormat("xml");
322                       
323                        if ((this.startRecord < 0 ) ||((getServletRequest().getParameter("startRecord") != null)&&(getServletRequest().getParameter("startRecord").equals("0")))) {
324                                this.Diagnostics().Add(new Diagnostic(Diagnostic.UNSUPPORTED_PARAMETERVALUE, "startRecord must by grater than 0."));//,Diagnostic.NONFATALNONSURORGATE));
325                                //mdrepoproxyaction.setStartItem("1");
326                        } else {
327                                mdrepoproxyaction.setStartItem(Integer.toString(getStartRecord()));
328                        }
329               
330                        if ((this.maximumRecords < 0 ) ||((getServletRequest().getParameter("maximumRecords") != null) && (getServletRequest().getParameter("maximumRecords").equals("0")))){
331                                   this.Diagnostics().Add(new Diagnostic(Diagnostic.UNSUPPORTED_PARAMETERVALUE, 
332                                                   "maximumRecords must by greater than 0."));
333                        } else {
334                                mdrepoproxyaction.setMaximumItems(Integer.toString(this.getMaximumRecords())); 
335                        }
336                       
337                        if (this.getX_cmd_repository() != null ) {
338                                mdrepoproxyaction.setRepository(this.getX_cmd_repository());
339                                //TODO\
340                                if (mdrepoproxyaction.getBaseURI() == null) this.Diagnostics().Add(Diagnostic.UNSUPPORTED_PARAMETERVALUE, "Unknown repository." + getX_cmd_repository());
341                        }
342                        if (this.getX_cmd_collections() != null ) {
343                                mdrepoproxyaction.setCollection(this.getX_cmd_collections());
344                        }
345
346                } else {
347                        if (operation.equals("explain") || operation == null){
348                                Admin.notifyUser("explaining", "debug");
349                        }else {
350                                if (operation.equals("scan")){
351                                        if (this.scanClause == null) {
352                                                this.Diagnostics().Add(Diagnostic.MANDATORY_NOTSUPPLIED, "scanClause");
353                                                //return -1;
354                                        } else{
355                                                if (this.scanClause.equals("cmd.Collections")){
356                                                       
357                                                } else {
358                                                        if (this.scanClause.equals("cmd.Repository")){
359                                                                XMLSerializer xmlserializer = new XMLSerializer();
360                                                                String xml = xmlserializer.write( mdrepoproxyaction.getRepositories() ); 
361                                                                this.setResultStream(new ByteArrayInputStream(xml.getBytes("UTF-8"))); 
362
363                                                        } else {
364                                                               
365                                                        }
366                                                }
367                                        }
368                                }else {
369                                        this.Diagnostics().Add(Diagnostic.UNSUPPOERTED_OPERATION, "Only searchRetrieve,explain scan supported.");                               }
370                        }
371                }
372        }
373       
374        public void sru2MD() throws UnsupportedEncodingException{
375                // special handling of parameter setting, x-cmd-... not alowed in java
376                this.setX_cmd_collections(getServletRequest().getParameter("x-cmd-collections"));
377               
378                // root call own SRU SERVER
379                //operation
380                if (operation.equals("explain") || operation == null){
381                        // TODO: version param is mandatory for explain as well, but for root-request not!
382                        //explain
383                        termsproxyaction = new TermsProxyAction();
384                        termsproxyaction.setDiagnostics(diagnostics);
385                        termsproxyaction.setActionkey("terms");
386                       
387                        termsproxyaction.setQ("all");                   
388                        termsproxyaction.setFormat("sru-explain");                     
389                       
390                        //return -1;
391                } else {                               
392                        //version               
393                        if (this.version == null) {
394                                this.Diagnostics().Add(Diagnostic.MANDATORY_NOTSUPPLIED, "version");
395                                //return -1;
396                        } else {
397                                if (!version.equals("1.2")) {
398                                        this.Diagnostics().Add(Diagnostic.UNSUPPORTED_VERSION, "Version 1.2 supported.");
399                                        //return -1;
400                                }
401                        }
402                       
403                        prepareOperation();
404                }
405               
406        }
407       
408        public void  prepareMD() throws Exception{
409                sru2MD();
410                if (Diagnostics().Accepted()){
411                        // root-explain
412                        if (this.termsproxyaction != null) {                   
413                                if (this.termsproxyaction.execute() == SUCCESS){
414                                        this.setResultStream(this.termsproxyaction.getResultStream());
415                                        //return SUCCESS;
416                                }
417                        } else {
418                                //TODO diagnostic                       
419                                if (this.mdrepoproxyaction.getTargetRequest() == null) {
420                                        Diagnostics().Add(Diagnostic.QUERYSYNTAXERROR);
421                                        //return ERROR;
422                                }
423                                if (this.mdrepoproxyaction.execute() == SUCCESS){
424                                        this.setResultStream(this.mdrepoproxyaction.getResultStream());
425                                        postprocess();
426                                        //return SUCCESS;
427                                }
428                        }
429                }
430                //return ERROR;
431        }
432       
433        public static String inputStreamAsString(InputStream stream)
434                throws IOException {
435                BufferedReader br = new BufferedReader(new InputStreamReader(stream));
436                StringBuilder sb = new StringBuilder();
437                String line = null;
438
439                while ((line = br.readLine()) != null) {
440                sb.append(line + "\n");
441                }
442
443                br.close();
444                return sb.toString();
445        }
446
447         public static Document newDocumentFromInputStream(InputStream in) {
448                    DocumentBuilderFactory factory = null;
449                    DocumentBuilder builder = null;
450                    Document ret = null;
451
452                    try {
453                      factory = DocumentBuilderFactory.newInstance();
454                      builder = factory.newDocumentBuilder();
455                    } catch (ParserConfigurationException e) {
456                      e.printStackTrace();
457                    }
458
459                    try {
460                      ret = builder.parse(new InputSource(in));
461                    } catch (SAXException e) {
462                      e.printStackTrace();
463                    } catch (IOException e) {
464                      e.printStackTrace();
465                    }
466                    return ret;
467                  }
468
469
470        public void postprocess() throws TransformerConfigurationException, UnsupportedEncodingException, ParserConfigurationException, TransformerException, TransformerFactoryConfigurationError{
471                //recordPacking
472                if (this.getRecordPacking() != null){
473                        if (this.getRecordPacking().toLowerCase().equals("string")){
474                                try {
475                                        this.setResultStream(IOUtils.toInputStream(StringEscapeUtils.escapeXml(inputStreamAsString(this.getResultStream()))));
476                                } catch (IOException e) {
477                                        // TODO Auto-generated catch block
478                                        e.printStackTrace();
479                                }
480
481                        }
482                }
483               
484                // add diagnostics
485                if (Diagnostics().Exists()){
486                        Document doc = newDocumentFromInputStream(this.getResultStream());
487                        Node r_element=  doc.getElementsByTagName("searchRetrieveResponse").item(0);
488                        Document ddoc = Diagnostics().buildXMLDocument();
489                        Node d_element=  ddoc.getElementsByTagName("diagnostics").item(0);
490                        doc.adoptNode(d_element);
491                        r_element.appendChild(d_element);
492                        DOMSource source = new DOMSource(doc);   
493                        StringWriter xmlAsWriter = new StringWriter();   
494                        StreamResult result = new StreamResult(xmlAsWriter);   
495                        TransformerFactory.newInstance().newTransformer().transform(source, result);
496                        this.setResultStream(new ByteArrayInputStream(xmlAsWriter.toString().getBytes("UTF-8")));
497                }
498        }
499       
500        @Override
501        public URL getTargetRequest() throws IOException {
502                String requestURI = "";
503                URL targetURL;
504               
505                if (this.getBaseURI() == null){
506                        requestURI = this.getX_cmd_repository();
507                } else {
508                        requestURI = this.getBaseURI();
509                }
510                //TODO params
511                Set set = getServletRequest().getParameterMap().entrySet();
512                Iterator i = set.iterator();
513                String params = "";
514            while(i.hasNext()){
515                      Map.Entry me = (Map.Entry)i.next();
516                      if (!(me.getKey().equals("x-cmd-repository") || me.getKey().equals("x-cmd-collections"))){
517                              params = params + "&" + me.getKey() + "=" + ((String[])me.getValue())[0]; 
518                      }
519                }
520            params = params.substring(1);
521            targetURL = new URL(requestURI + "?" + params);
522                return targetURL;
523        }
524       
525        @Override 
526        public void prepare() throws Exception{
527                this.setX_cmd_repository(getServletRequest().getParameter("x-cmd-repository"));
528                this.setRepository(this.getX_cmd_repository());
529                //TODO xsl usage according particular repositories ?
530                //this.setActionkey("recordset");
531                this.setFormat("xml");
532               
533                //extern SRU repository
534                if (this.isSRURepository() || this.getBaseURI() == null){
535                        super.prepare();
536                }
537                else {
538                         prepareMD();
539                }
540               
541        }
542        /**
543         * default Action method
544         */
545        /*
546        public String execute() throws Exception {
547                this.setX_cmd_repository(getServletRequest().getParameter("x-cmd-repository"));
548                //check if extern SRU repository
549                if (this.getX_cmd_repository() != null){
550                        MDRepoProxyAction a = new MDRepoProxyAction();
551                        a.setRepository(this.getX_cmd_repository());
552                        // direct SRU - URL
553                        if (a.isSRURepository() || (a.getBaseURI() == null)){
554                                String requestURL = "";
555                                if (a.getBaseURI() == null){
556                                        requestURL = this.getX_cmd_repository();
557                                } else {
558                                        requestURL = a.getBaseURI();
559                                }
560                                Set set = getServletRequest().getParameterMap().entrySet();
561                                Iterator i = set.iterator();
562                                String params = "";
563                            while(i.hasNext()){
564                                      Map.Entry me = (Map.Entry)i.next();
565                                      params = params + "&" + me.getKey() + "=" + ((String[])me.getValue())[0];
566                                }
567                            params = params.substring(1);
568                            URL url = new URL(requestURL + "?" + params);
569                            //getServletRequest().getRequestURL()
570                            resultStream =  url.openStream();//getServletRequest().getRequestURL().openStream();
571                                return SUCCESS;                         
572                        }
573                }
574                prepare();
575                if (Diagnostics().Accepted()){
576                        // root-explain
577                        if (this.termsproxyaction != null) {                   
578                                if (this.termsproxyaction.execute() == SUCCESS){
579                                        resultStream = this.termsproxyaction.getResultStream();
580                                        return SUCCESS;
581                                }
582                        } else {
583                                //TODO diagnostic                       
584                                if (this.mdrepoproxyaction.getTargetRequest() == null) {
585                                        Diagnostics().Add(Diagnostic.QUERYSYNTAXERROR);
586                                        return ERROR;
587                                }
588                                if (this.mdrepoproxyaction.execute() == SUCCESS){
589                                        resultStream = this.mdrepoproxyaction.getResultStream();
590                                        postprocess();
591                                        return SUCCESS;
592                                }
593                        }
594                }
595                return ERROR;
596        }
597*/
598
599}
Note: See TracBrowser for help on using the repository browser.