]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
5117e8d90547f3ca7665ce6ca86a463418edad6f
[tmp/jakarta-migration.git] /
1 /**     \r
2  * QueryManagerNuxeoImpl.java\r
3  *\r
4  * {Purpose of This Class}\r
5  *\r
6  * {Other Notes Relating to This Class (Optional)}\r
7  *\r
8  * $LastChangedBy: $\r
9  * $LastChangedRevision: $\r
10  * $LastChangedDate: $\r
11  *\r
12  * This document is a part of the source code and related artifacts\r
13  * for CollectionSpace, an open source collections management system\r
14  * for museums and related institutions:\r
15  *\r
16  * http://www.collectionspace.org\r
17  * http://wiki.collectionspace.org\r
18  *\r
19  * Copyright © 2009 {Contributing Institution}\r
20  *\r
21  * Licensed under the Educational Community License (ECL), Version 2.0.\r
22  * You may not use this file except in compliance with this License.\r
23  *\r
24  * You may obtain a copy of the ECL 2.0 License at\r
25  * https://source.collectionspace.org/collection-space/LICENSE.txt\r
26  */\r
27 package org.collectionspace.services.common.query.nuxeo;\r
28 \r
29 import org.slf4j.Logger;\r
30 import org.slf4j.LoggerFactory;\r
31 \r
32 import java.util.regex.Pattern;\r
33 \r
34 import org.nuxeo.ecm.core.api.DocumentModel;\r
35 import org.nuxeo.ecm.core.api.DocumentModelList;\r
36 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
37 import org.nuxeo.ecm.core.client.NuxeoClient;\r
38 \r
39 import org.collectionspace.services.jaxb.InvocableJAXBSchema;\r
40 import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;\r
41 import org.collectionspace.services.client.IQueryManager;\r
42 import org.collectionspace.services.common.invocable.Invocable;\r
43 import org.collectionspace.services.common.invocable.InvocableUtils;\r
44 import org.collectionspace.services.common.storage.DatabaseProductType;\r
45 import org.collectionspace.services.common.storage.JDBCTools;\r
46 \r
47 public class QueryManagerNuxeoImpl implements IQueryManager {\r
48         \r
49         private static String ECM_FULLTEXT_LIKE = \r
50                 "ecm:fulltext" + SEARCH_TERM_SEPARATOR + IQueryManager.SEARCH_LIKE;\r
51         private static String SEARCH_LIKE_FORM = null;\r
52 \r
53         private final Logger logger = LoggerFactory\r
54                         .getLogger(QueryManagerNuxeoImpl.class);\r
55         \r
56         // Consider that letters, letter-markers, numbers, '_' and apostrophe are words  \r
57         private static Pattern nonWordChars = Pattern.compile("[^\\p{L}\\p{M}\\p{N}_']");\r
58         private static Pattern unescapedDblQuotes = Pattern.compile("(?<!\\\\)\"");\r
59         private static Pattern unescapedSingleQuote = Pattern.compile("(?<!\\\\)'");\r
60         private static Pattern kwdSearchProblemChars = Pattern.compile("[\\:\\(\\)]");\r
61         private static Pattern kwdSearchHyphen = Pattern.compile(" - ");\r
62         \r
63         private static String getLikeForm() {\r
64                 if(SEARCH_LIKE_FORM == null) {\r
65                         try {\r
66                                 DatabaseProductType type = JDBCTools.getDatabaseProductType();\r
67                                 if(type == DatabaseProductType.MYSQL) {\r
68                                         SEARCH_LIKE_FORM = IQueryManager.SEARCH_LIKE;\r
69                                 } else if(type == DatabaseProductType.POSTGRESQL) {\r
70                                         SEARCH_LIKE_FORM = IQueryManager.SEARCH_ILIKE;\r
71                                 }\r
72                         } catch (Exception e) {\r
73                                 SEARCH_LIKE_FORM = IQueryManager.SEARCH_LIKE;\r
74                         }\r
75                 }\r
76                 return SEARCH_LIKE_FORM;\r
77         }\r
78 \r
79         //TODO: This is currently just an example fixed query.  This should eventually be\r
80         // removed or replaced with a more generic method.\r
81         /* (non-Javadoc)\r
82          * @see org.collectionspace.services.common.query.IQueryManager#execQuery(java.lang.String)\r
83          */\r
84         public void execQuery(String queryString) {\r
85                 NuxeoClient client = null;\r
86                 try {\r
87                         client = NuxeoConnector.getInstance().getClient();\r
88                         RepositoryInstance repoSession = client.openRepository();\r
89                         \r
90                         DocumentModelList docModelList = repoSession.query("SELECT * FROM Relation WHERE relation:relationtype.documentId1='updated-Subject-1'");\r
91 //                      DocumentModelList docModelList = repoSession.query("SELECT * FROM Relation");\r
92 //                      DocumentModelList docModelList = repoSession.query("SELECT * FROM CollectionObject WHERE collectionobject:objectNumber='objectNumber-1251305545865'");\r
93                         for (DocumentModel docModel : docModelList) {\r
94                                 System.out.println("--------------------------------------------");\r
95                                 System.out.println(docModel.getPathAsString());\r
96                                 System.out.println(docModel.getName());\r
97                                 System.out.println(docModel.getPropertyValue("dc:title"));\r
98 //                              System.out.println("documentId1=" + docModel.getProperty("relation", "relationtype/documentId1").toString());\r
99                         }\r
100                         \r
101                 } catch (Exception e) {\r
102                         // TODO Auto-generated catch block\r
103                         e.printStackTrace();\r
104                 }               \r
105         }\r
106 \r
107         /* (non-Javadoc)\r
108          * @see org.collectionspace.services.common.query.IQueryManager#createWhereClauseFromKeywords(java.lang.String)\r
109          */\r
110         // TODO handle keywords containing escaped punctuation chars, then we need to qualify the\r
111         // search by matching on the fulltext.simpletext field.\r
112         // TODO handle keywords containing unescaped double quotes by matching the phrase\r
113         // against the fulltext.simpletext field.\r
114         // Both these require using JDBC, since we cannot get to the fulltext table in NXQL\r
115         public String createWhereClauseFromKeywords(String keywords) {\r
116                 String result = null;\r
117                 StringBuffer fullTextWhereClause = new StringBuffer(SEARCH_GROUP_OPEN);\r
118                 //StringBuffer phraseWhereClause = new StringBuffer(SEARCH_GROUP_OPEN);\r
119                 boolean phrasesToAdd = false;\r
120                 // Split on unescaped double quotes to handle phrases\r
121                 String[] phrases = unescapedDblQuotes.split(keywords.trim());\r
122                 boolean first = true;\r
123                 for(String phrase : phrases ) {\r
124                         String trimmed = phrase.trim();\r
125                         // Ignore empty strings from match, or goofy input\r
126                         if(trimmed.isEmpty())\r
127                                 continue;\r
128                         // Add the phrase to the string to pass in for full text matching.\r
129                         // Note that we can pass in a set of words and it will do the OR for us.\r
130                         if(first) {\r
131                                 fullTextWhereClause.append(ECM_FULLTEXT_LIKE +"'");\r
132                                 first = false;\r
133                         } else {\r
134                                 fullTextWhereClause.append(SEARCH_TERM_SEPARATOR);\r
135                         }\r
136                         // ignore the special chars except single quote here - can't hurt\r
137                         // TODO this should become a special function that strips things the\r
138                         // fulltext will ignore, including non-word chars and too-short words,\r
139                         // and escaping single quotes. Can return a boolean for anything stripped,\r
140                         // which triggers the back-up search. We can think about whether stripping\r
141                         // short words not in a quoted phrase should trigger the backup.\r
142                         trimmed = unescapedSingleQuote.matcher(trimmed).replaceAll("\\\\'");\r
143                         // If there are non-word chars in the phrase, we need to match the\r
144                         // phrase exactly against the fulltext table for this object\r
145                         //if(nonWordChars.matcher(trimmed).matches()) {\r
146                         //}\r
147                         // Replace problem chars with spaces. Patches CSPACE-4147, CSPACE-4106 \r
148                         trimmed = kwdSearchProblemChars.matcher(trimmed).replaceAll(" ");\r
149                         trimmed = kwdSearchHyphen.matcher(trimmed).replaceAll(" ");\r
150 \r
151                         fullTextWhereClause.append(trimmed);\r
152                         if (logger.isTraceEnabled() == true) {\r
153                                 logger.trace("Current built whereClause is: " + fullTextWhereClause.toString());\r
154                         }\r
155                 }\r
156                 if(first) {\r
157                         throw new RuntimeException("No usable keywords specified in string:["\r
158                                         +keywords+"]");\r
159                 }\r
160                 fullTextWhereClause.append("'"+SEARCH_GROUP_CLOSE);\r
161                 \r
162                 result = fullTextWhereClause.toString();\r
163             if (logger.isDebugEnabled()) {\r
164                 logger.debug("Final built WHERE clause is: " + result);\r
165             }\r
166             \r
167             return result;\r
168         }\r
169 \r
170         /* (non-Javadoc)\r
171          * @see org.collectionspace.services.common.query.IQueryManager#createWhereClauseFromKeywords(java.lang.String)\r
172          */\r
173         // TODO handle keywords containing escaped punctuation chars, then we need to qualify the\r
174         // search by matching on the fulltext.simpletext field.\r
175         // TODO handle keywords containing unescaped double quotes by matching the phrase\r
176         // against the fulltext.simpletext field.\r
177         // Both these require using JDBC, since we cannot get to the fulltext table in NXQL\r
178         public String createWhereClauseForPartialMatch(String field, String partialTerm) {\r
179                 String trimmed = (partialTerm == null)?"":partialTerm.trim(); \r
180                 if (trimmed.isEmpty()) {\r
181                         throw new RuntimeException("No partialTerm specified.");\r
182                 }\r
183                 if (field==null || field.isEmpty()) {\r
184                         throw new RuntimeException("No match field specified.");\r
185                 }\r
186                 String ptClause = field\r
187                         + getLikeForm()\r
188                         + "'%" + unescapedSingleQuote.matcher(trimmed).replaceAll("\\\\'") + "%'";\r
189                 return ptClause;\r
190         }\r
191 \r
192         /**\r
193          * Creates a filtering where clause from docType, for invocables.\r
194          * \r
195          * @param docType the docType\r
196          * \r
197          * @return the string\r
198          */\r
199         public String createWhereClauseForInvocableByDocType(String schema, String docType) {\r
200                 String trimmed = (docType == null)?"":docType.trim(); \r
201                 if (trimmed.isEmpty()) {\r
202                         throw new RuntimeException("No docType specified.");\r
203                 }\r
204                 if (schema==null || schema.isEmpty()) {\r
205                         throw new RuntimeException("No match schema specified.");\r
206                 }\r
207                 String wClause = schema+":"+InvocableJAXBSchema.FOR_DOC_TYPE + " = '" + trimmed + "'";\r
208                 return wClause;\r
209         }\r
210         \r
211         /**\r
212          * Creates a filtering where clause from invocation mode, for invocables.\r
213          * \r
214          * @param mode the mode\r
215          * \r
216          * @return the string\r
217          */\r
218         public String createWhereClauseForInvocableByMode(String schema, String mode) {\r
219                 String trimmed = (mode == null)?"":mode.trim(); \r
220                 if (trimmed.isEmpty()) {\r
221                         throw new RuntimeException("No docType specified.");\r
222                 }\r
223                 if (schema==null || schema.isEmpty()) {\r
224                         throw new RuntimeException("No match schema specified.");\r
225                 }\r
226                 String wClause = \r
227                         InvocableUtils.getPropertyNameForInvocationMode(schema, trimmed)\r
228                         + " != 0";\r
229                 return wClause;\r
230         }\r
231         \r
232         \r
233         /**\r
234          * @param input\r
235          * @return true if there were any chars filtered, that will require a backup\r
236          *  qualifying search on the actual text.\r
237          */\r
238         private boolean filterForFullText(String input) {\r
239                 boolean fFilteredChars = false;\r
240                 \r
241                 return fFilteredChars;\r
242         }\r
243 }\r