source: MDService2/trunk/MDService2/src/eu/clarin/cmdi/mdservice/action/GenericProxyAction.java @ 1495

Last change on this file since 1495 was 1495, checked in by vronk, 13 years ago

started cleaning up code, adding inline-documentation;
also changes to output method in xsl (xhtml)

File size: 19.1 KB
Line 
1package eu.clarin.cmdi.mdservice.action;
2
3import java.io.BufferedInputStream;
4import java.io.BufferedReader;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.IOException;
8import java.io.InputStream;
9import java.io.InputStreamReader;
10import java.net.MalformedURLException;
11import java.net.URISyntaxException;
12import java.net.URL;
13import java.util.HashMap;
14
15import javax.servlet.http.HttpServletRequest;
16import javax.servlet.http.HttpSession;
17import javax.xml.transform.TransformerException;
18
19import net.sf.json.JSON;
20import net.sf.json.JSONArray;
21import net.sf.json.JSONObject;
22import net.sf.json.JSONSerializer;
23//import net.sf.saxon.Controller;
24//import net.sf.saxon.event.MessageEmitter;
25
26
27import org.apache.struts2.interceptor.ServletRequestAware;
28import com.opensymphony.xwork2.ActionSupport;
29import eu.clarin.cmdi.mdservice.model.Diagnostics;
30
31/**
32 * main Struts2 controller (ie implemenets the struts' execute()-method), all other Actions are derived from.   
33 * Defines the methods used for retrieving the data
34 * and provides basic implementation where possible.
35 * 
36 * @author vronk
37 */
38public class GenericProxyAction extends ActionSupport
39implements ServletRequestAware
40{
41
42        private static final long serialVersionUID = 1L;
43       
44        private static JSONArray repositories = null;
45        private static JSONObject wp_options = null;
46       
47        private Diagnostics diagnostics;
48        /**
49         * Properties to be filled by Struts with according request-parameters
50         */     
51        private String actionkey;
52        private String q;
53        private String squery;
54        private String cache = Cache.USE;
55        private String collection;
56        private String columns;
57        private String startItem;
58        private String maximumItems;
59        private String sort;
60        private String lang="en";
61        private int maxdepth;   
62        private String format;
63        private String options;
64        private String actionContentType;
65        private String userMsg;
66        private String repository;
67        //private Map<String,Object> session;
68        private HttpServletRequest request; 
69        private long duration = 0;
70        private InputStream resultStream;
71        private InputStream sourceStream;
72        protected URL base_url ;
73               
74         public GenericProxyAction(){
75                 super();
76                 initialize();
77         }
78         
79         public void setRepositoryByIndex(int id){
80                 try {
81                                setRepositories(GenericProxyAction.createRepositories());
82                                // static repositories
83                                net.sf.json.JSONArray json = getRepositories();
84                                if (json.size() > 0){
85                                        repository = json.getJSONObject(id).getString("name");
86                                }
87                        } catch (IOException e) {
88                                // TODO Auto-generated catch block
89                                e.printStackTrace();
90                        } catch (InterruptedException e) {
91                                // TODO Auto-generated catch block
92                                e.printStackTrace();
93                        } catch (TransformerException e) {
94                                // TODO Auto-generated catch block
95                                e.printStackTrace();
96                        } catch (NoStylesheetException e) {
97                                // TODO Auto-generated catch block
98                                e.printStackTrace();
99                        }
100         }
101         
102         protected void  initialize(){
103                 //repository = 1;
104                 setRepositoryByIndex(0);                               
105         }
106         
107         
108         public Diagnostics getDiagnostics(){
109                 return this.diagnostics;
110         }
111         
112         public void setDiagnostics(Diagnostics diagnostics){
113                 this.diagnostics = diagnostics;
114         }
115         public Diagnostics Diagnostics(){
116                 if (diagnostics == null){
117                         diagnostics  = new Diagnostics();
118                 }
119                 return this.diagnostics;
120         }
121        public String getQ() {
122                return q;
123        }
124
125        public void setQ(String pq) {
126                if (pq == null) pq="";
127                /*
128                if (q != null){
129                        if (q.trim().length() == 0){
130                                q = null;
131                        }
132                }
133                */
134                this.q = pq;
135        }
136
137        public String getSquery() {
138                return squery;
139        }
140
141        public void setSquery(String psquery) {
142                if (psquery==null) psquery="";
143                this.squery = psquery;
144        }
145       
146        public String getCache() {
147                return cache;
148        }
149
150        public void setCache(String cache) {
151                this.cache = cache;
152        }
153
154        public String getCollection() {
155                return collection;
156        }
157
158        public void setCollection(String collection) {
159                this.collection = collection;
160        }
161       
162        //TODO defaults
163        public String getColumns() {
164                String cols = columns;
165                /*if (columns == null){
166                        cols = "Id,Name,Title";
167                }
168                */
169                return cols;
170        }
171
172        public void setColumns(String columns) {
173                this.columns = columns;
174        }
175       
176        public int getMaxdepth() {
177                return maxdepth;
178        }
179
180        public void setMaxdepth(int maxdepth) {
181                this.maxdepth = maxdepth;
182        }
183
184        public String getFormat() {
185                return format;
186        }
187
188        public void setFormat(String format) {
189                this.format = format;
190        }
191
192        public String getOptions() {
193                return options;
194        }
195
196        public void setOptions(String options) {
197                this.options = options;
198        }
199
200        /**
201         * is used in struts.xml to dynamically set the mime-type of the result, depending on the format-parameter
202         * @return
203         */
204        public String getActionContentType() {
205                if (format.toLowerCase().startsWith("html")) {
206                        this.actionContentType = "text/html";           
207                        //this.actionContentType = "application/xhtml+xml";
208                } else {
209                        this.actionContentType = "text/xml";
210                }
211               
212                return actionContentType;
213        }
214
215        public void setActionContentType(String actionContentType) {
216                this.actionContentType = actionContentType;
217        }
218       
219
220        public void setRepository(String repository) {
221                this.repository = repository;
222        }
223       
224        public String getRepository() {
225                //default repository = 1 (set on init)
226                return repository;
227        }
228        public String getActionkey() {
229                return actionkey;
230        }
231
232        public void setActionkey(String actionKey) {
233                actionkey = actionKey;
234        }
235
236       
237        public String getStartItem() {
238                return startItem;
239        }
240
241        public void setStartItem(String startItem) {
242                this.startItem = startItem;
243        }
244
245        public String getMaximumItems() {
246                return maximumItems;
247        }
248
249        public void setMaximumItems(String maximumItems) {
250                this.maximumItems = maximumItems;
251        }
252       
253
254        public String getSort() {
255                return sort;
256        }
257
258        public void setSort(String sort) {
259                this.sort = sort;
260        }
261
262        public String getLang() {
263                return lang;
264        }
265
266        public void setLang(String lang) {
267                this.lang = lang;
268        }
269
270        public String getFullFormat() {         
271                return actionkey + "2" + format;
272        }
273
274        /**
275         * internal identification of the target-proxy
276         * base for finding the right base_url in the properties
277         * subclass has to override with its specific proxykey
278         * @return the key identifying this type of proxy
279         */
280        public String getProxyKey() {
281                return "";
282        }
283       
284        /**
285         * TODO: check what this does, where it is used?
286         * @return
287         */
288        public String getUserMsg() {
289                return userMsg;
290        }
291
292        public void setUserMsg(String userMsg) {
293                this.userMsg = this.userMsg + "\n" + userMsg;
294        }
295       
296        /**
297         * TODO: check what this does, where it is used?
298         * @return
299         */
300        @Override
301        public void setServletRequest(HttpServletRequest arg0) {
302                request = arg0;
303        }
304
305        public HttpServletRequest getServletRequest() {
306                return request;
307        }
308
309        /**
310         * The stream holding the resulting data to be sent back to the user as response
311         * @return
312         */
313        public InputStream getResultStream() {
314                return resultStream;
315    }
316        public void setResultStream(InputStream _resultStream){
317                resultStream = _resultStream;
318        }
319        public void setSourceStream(InputStream _sourceStream){
320                sourceStream = _sourceStream;
321        }
322       
323        /*
324        public InputStream getSourceStream() throws IOException {
325                return getTargetRequest().openStream();
326    }
327*/
328       
329        public JSONArray getRepositories(){
330                return repositories;
331        }
332       
333        public void setRepositories(JSONArray rep){
334                GenericProxyAction.repositories = rep;
335        }
336       
337        public JSONObject getWPOptions(){
338                return wp_options;
339        }
340       
341        public void setWPOptions(JSONObject op){
342                GenericProxyAction.wp_options = op;
343        }
344       
345        /**
346         * Reads URI from the configuration (mdservice.properties) based on the proxy-key
347         * @return the base-URI of the target repository or registry
348         */
349        public String getBaseURI() {           
350                String uri =Admin.getConfig().getProperty(getProxyKey() + ".uri");             
351                return uri;
352        }
353
354        /**
355         * Provides the base-URL specific to given target repository or registry
356         * @return
357         * @throws MalformedURLException
358         */     
359        public URL getBaseURL() throws MalformedURLException {         
360                if (base_url == null) {
361                        base_url = new URL(getBaseURI());//Admin.getConfig().getProperty(getProxyKey() + ".uri"));
362                }
363                return base_url;
364        }
365       
366        /**
367         * Constructs the actual URL to be send to the target repository/registry
368         * It has to be overridden by the subclasses
369         * as every target service has a different request-pattern. 
370         * @return URL of the target request
371         * @throws IOException
372         */
373        public URL getTargetRequest() throws IOException {
374                URL targetURL = getBaseURL();                     
375        return targetURL;
376        }
377       
378        /**
379         * Constructs an unambiguous key for the request (encoding all the parameters).
380         * This is used as identifier for caching
381         * @return key unambiguously encoding the request
382         */
383       
384         public String getRequestKey() {
385                        String key="";
386                        if (getActionkey()!=null) {
387                                key += getActionkey() + "//-" ;
388                        }else {
389                                key +="//-" ;
390                        }
391                        if (getQ()!=null) {
392                                key += getQ() + "//-" ;
393                        } else {
394                                key +="//-" ;
395                        }
396                        if (getCollection()!=null) {
397                                key += getCollection() + "//-";
398                        } else {
399                                key +="//-" ;
400                        }
401                        if (getSquery()!=null) {
402                                key += getSquery() + "//-" ;
403                        } else {
404                                key +="//-" ;
405                        }
406                        if (getStartItem()!=null) {
407                                key += getStartItem() + "//-";
408                        }
409                                else{
410                                        key +="//-" ;
411                        }
412                        if (getMaximumItems()!=null) {
413                                key += getMaximumItems() + "//-";
414                        }
415                        else{
416                                key +="//-" ;
417                        }
418                       
419                        key += getRepository()  + "//-";
420                        key += getMaxdepth()  + "//-";
421                       
422                        if (getLang()!=null) {
423                                key += getLang() + "//-";
424                        }else{
425                                key +="//-" ;
426                        }                       
427                         
428                return key;
429        }
430         
431         
432        public InputStream getSourceStream() throws IOException, NoStylesheetException {               
433                return getTargetRequest().openStream();
434 
435        }
436       
437        /*
438         * TODO: this should go to Utilities!
439         */
440        public  static String convertStreamToString(InputStream is) { 
441               
442                BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
443                StringBuilder sb = new StringBuilder(); 
444                String line = null; 
445               
446                try {
447                        while ((line = reader.readLine()) != null) { 
448                                         sb.append(line + "\n"); 
449                        }
450                } catch (IOException e) {
451                        // TODO Auto-generated catch block
452                        e.printStackTrace();
453                }  finally {
454                        try {
455                                is.close();
456                        } catch (IOException e) {
457                                // TODO Auto-generated catch block
458                                e.printStackTrace();
459                        }
460                        try {
461                                is.reset();
462                        } catch (IOException e) {
463                                // TODO Auto-generated catch block
464                                e.printStackTrace();
465                        }
466                }
467                 
468               
469                return sb.toString(); 
470        }
471
472       
473        public static JSONArray createRepositories() throws IOException, InterruptedException, TransformerException, NoStylesheetException{
474                String path = Admin.getConfig().getProperty("workspaceprofile.path") + WorkspaceAction.WORKSPACE_FILENAME;//PROFILENAME_SERVER;
475                File file=new File(path);
476                InputStream in  = new BufferedInputStream( new FileInputStream(path));;
477               
478                MDTransformer transformer = new MDTransformer();
479                transformer.setSrcFile(file.toURI().toURL());
480                transformer.setParams(MDTransformer.createParamsMap("xml2json"));
481                InputStream jsonstream = transformer.transformXML(in);
482               
483                JSONObject json = JSONObject.fromObject(convertStreamToString(jsonstream));
484                JSONArray wparray = json.getJSONObject("Profiles").getJSONArray("WorkspaceProfiles");
485                JSONArray array = null;
486                for (int i = 0; i < wparray.size(); ++i) {     
487                        JSONObject wp = wparray.getJSONObject(i); 
488                        if (wp.get("Repositories") != null){
489                                array = wp.getJSONArray("Repositories");
490                                break;
491                        }
492                }       
493               
494                // repository as static variable
495                return array;
496       
497                // repository as session attribute
498                /*
499                HttpSession session = getServletRequest().getSession();
500                //JSONArray param = (JSONArray) session.getAttribute("repositories");
501                JSONArray param = new JSONArray();
502        param.add(array);
503        session.setAttribute("repositories", param);
504                 */
505        }
506       
507        public static JSONObject createWPOptions() throws IOException, InterruptedException, TransformerException, NoStylesheetException{
508                String path = Admin.getConfig().getProperty("workspaceprofile.path") + WorkspaceAction.WORKSPACE_FILENAME;//PROFILENAME_SERVER;
509                File file=new File(path);
510                InputStream in  = new BufferedInputStream( new FileInputStream(path));;
511               
512                MDTransformer transformer = new MDTransformer();
513                transformer.setSrcFile(file.toURI().toURL());
514                transformer.setParams(MDTransformer.createParamsMap("xml2json"));
515                InputStream jsonstream = transformer.transformXML(in);
516               
517                JSONObject json = JSONObject.fromObject(convertStreamToString(jsonstream));
518                JSONArray wparray = json.getJSONObject("Profiles").getJSONArray("WorkspaceProfiles");
519                JSONObject obj = null;
520                for (int i = 0; i < wparray.size(); ++i) {     
521                        JSONObject wp = wparray.getJSONObject(i); 
522                        if (wp.get("Options") != null){
523                                obj = wp.getJSONObject("Options");
524                                break;
525                        }
526                }       
527               
528                // options as static variable
529                return obj;
530       
531        }
532       
533        public String getWPOption(String opt_key){
534                String option_val = null;
535               
536               
537                if (wp_options == null ) {
538                        try {
539                                setWPOptions(GenericProxyAction.createWPOptions());
540                        } catch (IOException e) {
541                                // TODO Auto-generated catch block
542                                e.printStackTrace();
543                        } catch (InterruptedException e) {
544                                // TODO Auto-generated catch block
545                                e.printStackTrace();
546                        } catch (TransformerException e) {
547                                // TODO Auto-generated catch block
548                                e.printStackTrace();
549                        } catch (NoStylesheetException e) {
550                                // TODO Auto-generated catch block
551                                e.printStackTrace();
552                        }
553                }
554                // static options
555                if (wp_options != null){
556                        net.sf.json.JSONObject json = getWPOptions(); 
557                        option_val = json.getString(opt_key);
558                }
559               
560               
561                return option_val;
562               
563        }
564       
565        public String getRepositoryPath(){
566                String repository_path = null;
567               
568               
569                if (repositories == null ) {
570                        try {
571                                setRepositories(GenericProxyAction.createRepositories());
572                        } catch (IOException e) {
573                                // TODO Auto-generated catch block
574                                e.printStackTrace();
575                        } catch (InterruptedException e) {
576                                // TODO Auto-generated catch block
577                                e.printStackTrace();
578                        } catch (TransformerException e) {
579                                // TODO Auto-generated catch block
580                                e.printStackTrace();
581                        } catch (NoStylesheetException e) {
582                                // TODO Auto-generated catch block
583                                e.printStackTrace();
584                        }
585                }
586                // static repositories
587                net.sf.json.JSONArray json = getRepositories(); 
588                for(int i=0;i<json.size();i++){
589                        if (json.getJSONObject(i).getString("name").equals(getRepository())){
590                                repository_path =  json.getJSONObject(i).getString("uri");
591                        }
592                }
593                //Admin.notifyUser("REPOSITORY_PATH:" + repository_path);
594               
595                //session repositories
596                /*
597                HttpSession session = getServletRequest().getSession();
598                json = (net.sf.json.JSONArray) session.getAttribute("repositories");
599                for(int i=0;i<json.size();i++){
600                        if (json.getJSONObject(i).getInt("id") == getRepository()){
601                                repository_path =  json.getJSONObject(i).getString("uri");
602                        }
603                }
604                Admin.notifyUser("REPOSITORY_PATH-SESSIONATTR:" + repository_path);
605                */
606                return repository_path;
607               
608        }
609       
610        public String getRepositoryType(){
611        String typestr = "";
612               
613                if (repositories == null ) {
614                        try {
615                                setRepositories(GenericProxyAction.createRepositories());
616                        } catch (IOException e) {
617                                // TODO Auto-generated catch block
618                                e.printStackTrace();
619                        } catch (InterruptedException e) {
620                                // TODO Auto-generated catch block
621                                e.printStackTrace();
622                        } catch (TransformerException e) {
623                                // TODO Auto-generated catch block
624                                e.printStackTrace();
625                        } catch (NoStylesheetException e) {
626                                // TODO Auto-generated catch block
627                                e.printStackTrace();
628                        }
629                }
630                // static repositories
631                net.sf.json.JSONArray json = getRepositories(); 
632                for(int i=0;i<json.size();i++){
633                        if (json.getJSONObject(i).getString("name").equals(getRepository())){
634                                typestr =  json.getJSONObject(i).getString("type");
635                        }
636                }
637               
638                return (typestr);
639
640        }
641        public Boolean isSRURepository(){
642                //Boolean issru = false;
643                String typestr = getRepositoryType();
644               
645                return (typestr.equals("sru"));
646               
647        }
648        public String addDurationKey(){
649                String req_key = getRequestKey();
650       
651                Double duration_d;
652
653            duration_d = (double)duration; 
654            duration_d = duration_d/1000.0;
655                req_key += duration_d + "//-";
656                return req_key;
657        }
658       
659        public HashMap<String,String> createTransformerParams(){
660               
661                HashMap<String,String> hm = new HashMap<String,String>();
662               
663            if (getFullFormat() != null){
664                        hm.put("format", getFullFormat());
665            }
666                if (getColumns() != null){
667                        hm.put("cols", getColumns());
668                } else {
669                        hm.put("cols", "");
670                }
671                if (getStartItem() != null){
672                        hm.put("startItem", getStartItem());
673                }
674                if (getMaximumItems() != null){
675                        hm.put("maximumItems", getMaximumItems());     
676                }
677                if (getLang() != null){
678                        hm.put("lang", getLang());
679                }
680                if (getQ() != null){
681                        hm.put("q", getQ());
682                }
683                //if (getRepository() != null){
684                hm.put("repository_name", String.valueOf(getRepository()));     
685                //}
686       
687                return hm;
688               
689        }
690       
691        /**
692         * This is the work-horse function.
693         * It does two things:
694         * a) check if the source data is already in cache (based on cache-key that is constructed from the request parameters)
695         * b) if format-parameter provided, invokes the transformation.
696         * at the end the data to be returned as result is contained in the resultStream
697         * If format is xml, then the data from sourceStream is passed further as resultStream.
698         *   
699         * @throws Exception  This is handled by struts (is mapped to some result in struts.xml based on the Exception-Class)
700         */
701       
702        public void prepare() throws Exception {               
703               
704                String req_key = getRequestKey();
705                Admin.notifyUser("request_key: " +  req_key); 
706                Admin.notifyUser(getProxyKey() + ".targetURL: " + getTargetRequest() + " .format:" + getFullFormat());
707               
708                // Caching
709                String xcid;
710       
711                // Admin.notifyUser("GPA.prepareSourceStream");
712               
713                if (getCache().equals(Cache.SKIP)) {
714                       
715                        sourceStream = getSourceStream();
716                       
717                } else { 
718                        if (getCache().equals(Cache.USE)) {
719                                        sourceStream = Cache.getCache().getFromCache(req_key);
720                        }
721                        if (sourceStream == null) { // either not in cache or cache_flag=refresh
722                                //sourceStream = getTargetRequest().openStream();
723                                long startMillis = System.currentTimeMillis();
724                                sourceStream = getSourceStream();
725                                duration = System.currentTimeMillis() - startMillis;
726                                req_key = addDurationKey();
727                               
728                                long now = System.currentTimeMillis();
729                                xcid = Cache.getCache().putInCache(req_key,sourceStream);                       
730                                //Admin.notifyUser("putting in cache: " + req_key);                     
731                                sourceStream = Cache.getCache().getFromCache(req_key);
732                        } /* else {
733                                Admin.notifyUser("reading from cache: " + req_key);
734                        } */
735                }
736                       
737                if (format.equals("xml")) {                     
738                        resultStream = sourceStream;   
739                }else {
740                        MDTransformer transformer = new MDTransformer();
741                        // set URL as srcFile (for MDTransformer to pass to xsl-scripts)
742                        // TODO: WHY??
743                        transformer.setSrcFile(getTargetRequest());
744                        transformer.setParams(createTransformerParams());
745                        // here the transformation is invoked
746                        resultStream = transformer.transformXML(sourceStream);
747                }
748                       
749                Admin.notifyUser(getProxyKey() + " success:" + (resultStream!=null));
750        }
751
752        /**
753         * default Action method that gets called by Struts. Everything interesting happens in prepare()
754         */
755        public String execute() throws Exception {
756//              HttpServletRequest request = ServletActionContext.getRequest();
757
758               
759                //Admin.notifyUser("session-attrs:");
760        //Admin.notifyUser(getServletRequest().getRemoteUser() );
761        //Admin.notifyUser(String.valueOf(getSession()));
762       
763        long now = System.currentTimeMillis();
764
765                prepare();
766                long duration = (System.currentTimeMillis() - now);
767                //duration
768
769                if (resultStream == null) {
770                        return ERROR;   
771                } else {
772                        return SUCCESS;
773                }               
774        }
775
776
777}
Note: See TracBrowser for help on using the repository browser.