source: MDService2/trunk/MDService2/src/eu/clarin/cmdi/mdservice/model/Query.java @ 1455

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

sru-reader first version

File size: 13.0 KB
Line 
1package eu.clarin.cmdi.mdservice.model;
2
3/**
4 * The main model class, carrying users_query
5 * able to parse and transform the user-string
6 * and execute the query, ie issue appropriate request on the MDRepository
7 * getting the url-wording right from MDRepositoryProxy
8 *   
9 * At the moment just responsible for querying MDRepository
10 * perhaps unify approach for other proxies - subtyping this Class 
11 */
12
13import java.io.IOException;
14import java.net.MalformedURLException;
15import java.net.URL;
16import java.util.Iterator;
17import java.util.Map;
18import java.util.Set;
19
20import javax.xml.parsers.DocumentBuilder;
21import javax.xml.parsers.DocumentBuilderFactory;
22
23import org.w3c.dom.Document;
24import org.z3950.zing.cql.CQLNode;
25import org.z3950.zing.cql.CQLParseException;
26import org.z3950.zing.cql.CQLParser;
27
28import eu.clarin.cmdi.mdservice.action.Admin;
29import eu.clarin.cmdi.mdservice.action.MDTransformer;
30
31public class Query {   
32        public static String COLLECTIONS = "collections";
33        public static String COLUMNS = "columns";
34        public static String MODEL = "model";
35        public static String VALUES = "values";
36        public static String RECORDSET = "recordset";
37        public static String RECORD = "record";
38        public static String SRUEXTERN = "sruextern";
39       
40        public static String PARSED = "parsed";
41        public static String UNPARSED = "unparsed";
42        public static String PARSEERROR = "parseerror";
43       
44        private String type;
45        /**
46         * meant a target url/service, allowing querying different services on per query basis
47         * not used yet
48         */
49        private String target; 
50       
51        private URL targetRequest;
52        private String syntax = "cql";  /* cql, cmdIndex, xpath */
53        private String squery_string;
54        private String query_string;
55        private String full_query_string;
56        private CQLNode query_cql;
57        private String msg;
58        /**
59         * temporary default;
60         */
61        private String collection="";
62        private String columns="Id,name";
63        private String startItem = "1";
64        private String maximumItems = "50";
65        private String squery = null;
66        private String options = null;
67        private String sort;
68        private int maxdepth=1;
69       
70        private Map sruMap = null;
71        /**
72         * reference to the result-object
73         */
74        private Result result = new Result(this);
75
76       
77        public Query(String squeryString, String queryString) {         
78                this(squeryString, queryString, MODEL);
79        }
80
81        /**     
82         * main constructor, with user's querystring and type of the query, and context-collection (at the moment just one)
83         * @param queryString
84         * @param type
85         * @param collection
86         */
87
88        public Query(String squeryString,String queryString, String type, String collection, String columns) {
89                this.type =type;
90                if (squeryString == null)squeryString ="";
91                if (queryString == null)queryString ="";
92                setFullQueryString(squeryString, queryString);
93                setCollection(collection);
94                setColumns(columns);
95        }
96       
97        /**     
98         * main constructor, with user's querystring and type of the query, and context-collection (at the moment just one)
99         * @param queryString
100         * @param type
101         * @param collection
102         */
103
104        public Query(String squeryString, String queryString, String type, String collection) {
105                //this.type =type;
106                //setFullQueryString(squeryString, queryString);
107                //setCollection(collection);
108                this(squeryString, queryString, type, collection, "Id,name");
109        }
110
111        /**     
112         * another constructor, with user's querystring and type of the query;
113         * problematic not setting the collection! 
114         * @param queryString
115         * @param type
116         */
117
118        public Query(String squeryString, String queryString, String type) {
119                //this.type =type;
120                //if (squeryString == null)squeryString ="";
121                //setFullQueryString(squeryString, queryString);
122                this(squeryString, queryString, type, "");
123        }
124
125        public Boolean isStatus(String qstatus) {
126                return (qstatus.equals(getStatus()));
127        }
128       
129        public String getStatus() {
130                if (type.equals(Query.RECORDSET) && query_cql== null && (full_query_string != "")) {
131                        return Query.PARSEERROR;
132                } else {
133                        return Query.UNPARSED;
134                }
135               
136        }
137       
138        public String getType() {
139                return type;
140        }
141
142        public void setType(String type) {
143                this.type = type;
144        }
145
146        public String getQueryString() {
147                return query_string;
148        }
149
150        public void setFullQueryString(String squeryString, String queryString) {
151               
152                query_string=queryString;
153               
154                if (squeryString.trim().length() == 0){
155                        squeryString = null;
156                }
157                if (queryString.trim().length() == 0){
158                        queryString = null;
159                }
160               
161                String squery = createsqueryString(squeryString);
162                if (squery != null && queryString != null){
163                        full_query_string = "(" + squery + " ) and (" + queryString + ")";
164                } else if (squery != null) {
165                        full_query_string = squery;
166                } else if (queryString != null){
167                        full_query_string = queryString;
168                } else {
169                        full_query_string = "";
170                }
171                Admin.notifyUser("QUERY.FULLQUERYSTRING:" + full_query_string);
172                if (type.equals(RECORDSET) && (full_query_string.length() > 0)) {       
173                        parse();
174                        //preprocess();
175                }
176                       
177        }
178       
179        public String getFullQueryString() {
180                return full_query_string;
181        }
182
183       
184        public void setCollection(String collection) {
185                if (collection!=null) {
186                        this.collection = collection;
187                }
188        }
189       
190        public String getCollection() {
191                return collection;
192        }
193       
194        public String getColumns() {
195                return columns;
196        }
197       
198        public void setColumns(String columns) {
199                if (columns!=null) {
200                        this.columns = columns;
201                }
202        }
203
204        public String getSQuery() {
205                return this.squery;
206        }
207       
208        public void setSQuery(String squery) {
209                if (squery!=null) {
210                        this.squery = squery;
211                }
212        }
213       
214        public String getOptions() {
215                return options;
216        }
217
218        public void setOptions(String options) {
219                this.options = options;
220        }
221
222        public String getSort() {
223                return sort;
224        }
225
226        public void setSort(String sort) {
227                this.sort = sort;
228        }
229
230        public String getStartItem() {
231                return startItem;
232        }
233       
234        public void setStartItem(String startItem) {
235                if (startItem!=null) {
236                        if (startItem.equals("")){
237                                // sets default startItem
238                                this.startItem = "1";
239                        }else {
240                                this.startItem = startItem;
241                        }
242                }
243        }
244       
245        public String getMaximumItems() {
246                return maximumItems;
247        }
248       
249        public void setMaximumItems(String maximumItems) {
250                if (maximumItems!=null) {
251                        if (maximumItems.equals("")){
252                                this.maximumItems = "50";
253                        } else {
254                                this.maximumItems = maximumItems;       
255                        }
256                }
257        }
258        public void setMaxdepth(int maxdepth) {
259                if (maxdepth > 0) {
260                        this.maxdepth = maxdepth;
261                }
262        }
263
264        public int getMaxdepth() {
265                return maxdepth;
266        }
267
268        public void setResult(Result result) {
269                this.result = result;
270        }
271
272
273        public Result getResult() {
274                return result;
275        }
276       
277        public String getMsg() {
278                return msg;
279        }
280
281        public void setMsg(String msg) {
282                this.msg = msg;
283        }
284
285       
286        public Map getSruMap() {
287                return sruMap;
288        }
289
290        public void setSruMap(Map sruMap) {
291                this.sruMap = sruMap;
292        }
293
294       
295        // apply rules form squery
296        public String createsqueryString (String _squery){
297                String sq = null;
298               
299                if (_squery !=null){
300                        sq = "* any " + _squery;
301                }
302
303                return sq;
304        }
305        public static String getSimpleQueryString(String querystring) {
306                String[] arr_and = querystring.split(" and ");
307                String simple_form = "";
308                String simple_form_all = "";
309                String rel = "";
310               
311                for( int i=0;i<arr_and.length;i++){
312                        arr_and[i] = arr_and[i].trim();
313                        String[] arr_or = arr_and[i].split(" or ");
314                        simple_form = "";
315                        for( int j=0;j<arr_or.length;j++){
316                                arr_or[j] = arr_or[j].trim();
317                                while (arr_or[j].substring(0,1).equals("(") ) {
318                                        arr_or[j] = arr_or[j].substring(1,arr_or[j].length());
319                                        arr_or[j] = arr_or[j].trim();
320                                }
321                                while ( arr_or[j].substring(arr_or[j].length()-1,arr_or[j].length()).equals(")")){
322                                        arr_or[j] = arr_or[j].substring(0,arr_or[j].length()-1);
323                                        arr_or[j] = arr_or[j].trim();
324                                }
325                                if (j > 0) { 
326                                        rel = " or ";
327                                } else {
328                                        rel = "";
329                                }
330                                simple_form = simple_form + rel + arr_or[j];
331                        }
332                        //Admin.notifyUser(simple_form);
333                        if (arr_or.length > 1){
334                                simple_form = "(" + simple_form + ") ";
335                        }
336                        if (i > 0) { 
337                                rel = " and  ";
338                        } else {
339                                rel = "";
340                        }
341                        simple_form_all = simple_form_all + rel + simple_form;
342                       
343                }
344               
345                return simple_form_all;
346        }
347        /**
348         * construct the URL-Param
349         * @return
350         * @throws MalformedURLException
351         * TODO url-encode (especially the query-param) !
352         */
353        public String toURLParam() throws MalformedURLException {
354               
355                String targetRequest;
356               
357                if (type.equals(MODEL)) {
358                        targetRequest = fromCMDIndex2Xpath() + "&maxdepth=" + getMaxdepth()  ; /* + "&maxdepth=" + getMaxdepth() );  "&collection=" + getCollection() + */
359                } else if (type.equals(SRUEXTERN)) {
360                        targetRequest = "";//fromCMDIndex2Xpath() + "&maxdepth=" + getMaxdepth()  ; /* + "&maxdepth=" + getMaxdepth() );  "&collection=" + getCollection() + */
361                       
362                        Set set = sruMap.entrySet();
363                        Iterator i = set.iterator();
364                       
365                    while(i.hasNext()){
366                              Map.Entry me = (Map.Entry)i.next();
367                              targetRequest = targetRequest + "&" + me.getKey() + "=" + me.getValue();
368                        }
369                                       
370                } else if (type.equals(VALUES)) {
371                        targetRequest = fromCMDIndex2Xpath() ; /* + "&maxdepth=" + getMaxdepth() );  "&collection=" + getCollection() + */
372                       
373                        if (startItem != null) {
374                                targetRequest = targetRequest +  "&startItem=" + getStartItem();
375                        }
376                        if (maximumItems != null) {
377                                targetRequest = targetRequest +  "&maxItems=" + getMaximumItems();
378                        }
379                        if (sort != null) {
380                                targetRequest = targetRequest +  "&sort=" + getSort();
381                        }
382                       
383                } else if (type.equals(RECORD)) {
384                        //  2010-07-11 this is just a hack, because url-encoding the handle acted strange
385                        //String corrid = getQueryString().replace('_', '/');
386                        //  2010-12-28 needed for the lucene-index to recognize..
387                                //  probably not the best place to handle -> move to repository: sanitize-query?
388                        String corrid = getQueryString().replace(":","\\:").toLowerCase();
389                        Admin.notifyUser("Query.toURLParam.corrid=" + corrid);
390                        targetRequest = "//MdSelfLink[ft:query(.,'" + corrid + "')]";                   
391                } else {
392                                if (query_cql == null){
393                                        targetRequest =  "//*" + "&collection=" + getCollection();
394                                } else {
395                                        targetRequest = toXPath() + "&collection=" + getCollection();   
396                                }
397                                if (startItem != null) {
398                                        targetRequest = targetRequest +  "&startItem=" + getStartItem();
399                                }
400                                if (maximumItems != null) {
401                                        targetRequest = targetRequest +  "&maxItems=" + getMaximumItems();
402                                }
403                                if ((options != null)) {
404                                        targetRequest = targetRequest +  "&format=xml-" + getOptions();
405                                }
406                }
407       
408                return targetRequest;
409               
410}
411       
412        /**
413         * tries to parse the full_query_string according the CQL-syntax
414         * if successful returns the root-node of the parse-tree
415         */
416        public CQLNode parse() {
417                 
418          try {
419                CQLParser parser = new CQLParser();             
420                query_cql = parser.parse(full_query_string);
421          }
422                catch (CQLParseException e) {
423                        // TODO better handling of failed parse 
424                        setMsg("Query.ParseError-"+ e.getClass() + ": " + e.getMessage());
425                } catch (IOException e) {
426                        // TODO Auto-generated catch block
427                        e.printStackTrace();
428                }
429               
430       
431                return query_cql;
432        }
433       
434        /**
435         */
436        public void  preprocess() {
437                 
438          try { 
439                Admin.notifyUser(toXCQL());
440                       
441               
442                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
443                DocumentBuilder builder = factory.newDocumentBuilder();
444                Document doc = builder.parse(new org.xml.sax.InputSource(new java.io.StringReader(toXCQL())));
445                       
446                //Admin.notifyUser("document created");
447                SearchClauses searchclauses = new SearchClauses(doc);
448                //do the processing
449                searchclauses.process();
450                String xml_s = searchclauses.toXML();
451               
452                //Admin.notifyUser("AAAA2:" + xml_s);
453          }
454                catch (Exception e) {
455                        e.printStackTrace();
456                }
457                return;
458        }
459       
460       
461        /**
462         * provides a xml-version of the query (if parsed successfully)
463         * according to the XCQL-schema defined in the SRU/CQL standard
464         * @return
465         */
466        public String toXCQL() {       
467                 return query_cql.toXCQL(0);
468        }
469
470        /**
471         * provides a xpath version of the query, based on the XCQL-version,
472         * applying a stylesheet on the XCQL-version 
473         * @return XPath-query
474         * @throws IOException
475         */
476        public String toXPath() {       
477                MDTransformer transformer = new MDTransformer();
478                transformer.setParams(MDTransformer.createParamsMap("XCQL2XPATH"));
479                return transformer.transformXML(toXCQL());
480        }
481
482        /**
483         * if the query is just a path-like structure
484         * "transforms" the cmdIndex-format to appropriate XPath, means replace('.', '/') ;)
485         * and resolves back possible profile-prefix
486         * @return
487         */
488        public String fromCMDIndex2Xpath() {
489                String xpath = "";
490                if (query_string.contains(":")) {
491                        int delim_index = query_string.indexOf(":");
492                        String profile_name = query_string.substring(0,delim_index );
493                        Termset res = (Termset) Termset.getTermset(profile_name);                         
494                        if (res!=null) {
495                                profile_name= res.getAttr("name");
496                        } 
497                        if (profile_name.equals("")) {
498                                xpath=query_string.substring(delim_index); 
499                        } else {
500                                xpath = profile_name + "//" + query_string.substring(delim_index+1);
501                        }
502                               
503                } else {
504                        xpath = query_string; 
505                }
506                               
507                 return xpath.replace(".", "//"); 
508        }
509
510        /**
511         * OBSOLETED! MDRepoProxyAction executes the request, Query only provides itself encoded
512         * runs the query! by opening the stream on the targetService/URL
513         * setting it as inputStream of the Result
514         * @throws Exception
515         */
516/*      public void execute() throws Exception {
517                       
518                result.setInputStream(getTargetRequest().openStream());
519       
520        }
521*/
522       
523       
524}
Note: See TracBrowser for help on using the repository browser.