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

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

repoaction created ,
options + repositories moved to workspaceprofile

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