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

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

further work on terms/values (layout, behaviour)
fix in repository handling

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