This project has retired. For details please refer to its Attic page.
QueryStatementImpl xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * with the License.  You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing,
12   * software distributed under the License is distributed on an
13   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14   * KIND, either express or implied.  See the License for the
15   * specific language governing permissions and limitations
16   * under the License.
17   */
18  package org.apache.chemistry.opencmis.client.runtime;
19  
20  import java.net.URI;
21  import java.net.URL;
22  import java.text.SimpleDateFormat;
23  import java.util.Calendar;
24  import java.util.Date;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.TimeZone;
28  
29  import org.apache.chemistry.opencmis.client.api.ItemIterable;
30  import org.apache.chemistry.opencmis.client.api.ObjectId;
31  import org.apache.chemistry.opencmis.client.api.ObjectType;
32  import org.apache.chemistry.opencmis.client.api.OperationContext;
33  import org.apache.chemistry.opencmis.client.api.QueryResult;
34  import org.apache.chemistry.opencmis.client.api.QueryStatement;
35  import org.apache.chemistry.opencmis.client.api.Session;
36  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
37  
38  /**
39   * QueryStatement implementation.
40   */
41  public class QueryStatementImpl implements QueryStatement {
42  
43      private final Session session;
44      private final String statement;
45      private final Map<Integer, String> parametersMap;
46  
47      public QueryStatementImpl(Session session, String statement) {
48          if (session == null) {
49              throw new IllegalArgumentException("Session must be set!");
50          }
51  
52          if (statement == null) {
53              throw new IllegalArgumentException("Statement must be set!");
54          }
55  
56          this.session = session;
57          this.statement = statement.trim();
58  
59          parametersMap = new HashMap<Integer, String>();
60      }
61  
62      public void setType(int parameterIndex, String typeId) {
63          setType(parameterIndex, session.getTypeDefinition(typeId));
64      }
65  
66      public void setType(int parameterIndex, ObjectType type) {
67          if (type == null) {
68              throw new IllegalArgumentException("Type must be set!");
69          }
70  
71          String queryName = type.getQueryName();
72          if (queryName == null) {
73              throw new IllegalArgumentException("Type has no query name!");
74          }
75  
76          parametersMap.put(parameterIndex, queryName);
77      }
78  
79      public void setProperty(int parameterIndex, String typeId, String propertyId) {
80          ObjectType type = session.getTypeDefinition(typeId);
81  
82          PropertyDefinition<?> propertyDefinition = type.getPropertyDefinitions().get(propertyId);
83          if (propertyDefinition == null) {
84              throw new IllegalArgumentException("Property does not exist!");
85          }
86  
87          setProperty(parameterIndex, propertyDefinition);
88      }
89  
90      public void setProperty(int parameterIndex, PropertyDefinition<?> propertyDefinition) {
91          if (propertyDefinition == null) {
92              throw new IllegalArgumentException("Property must be set!");
93          }
94  
95          String queryName = propertyDefinition.getQueryName();
96          if (queryName == null) {
97              throw new IllegalArgumentException("Property has no query name!");
98          }
99  
100         parametersMap.put(parameterIndex, queryName);
101     }
102 
103     public void setNumber(int parameterIndex, Number... num) {
104         if (num == null || num.length == 0) {
105             throw new IllegalArgumentException("Number must be set!");
106         }
107 
108         StringBuilder sb = new StringBuilder();
109         for (Number n : num) {
110             if (n == null) {
111                 throw new IllegalArgumentException("Number is null!");
112             }
113 
114             if (sb.length() > 0) {
115                 sb.append(",");
116             }
117 
118             sb.append(n.toString());
119         }
120 
121         parametersMap.put(parameterIndex, sb.toString());
122     }
123 
124     public void setString(int parameterIndex, String... str) {
125         if (str == null || str.length == 0) {
126             throw new IllegalArgumentException("String must be set!");
127         }
128 
129         StringBuilder sb = new StringBuilder();
130         for (String s : str) {
131             if (s == null) {
132                 throw new IllegalArgumentException("String is null!");
133             }
134 
135             if (sb.length() > 0) {
136                 sb.append(",");
137             }
138 
139             sb.append(escape(s));
140         }
141 
142         parametersMap.put(parameterIndex, sb.toString());
143     }
144 
145     public void setStringLike(int parameterIndex, String str) {
146         if (str == null) {
147             throw new IllegalArgumentException("String must be set!");
148         }
149 
150         parametersMap.put(parameterIndex, escapeLike(str));
151     }
152 
153     public void setId(int parameterIndex, ObjectId... id) {
154         if (id == null || id.length == 0) {
155             throw new IllegalArgumentException("Id must be set!");
156         }
157 
158         StringBuilder sb = new StringBuilder();
159         for (ObjectId oid : id) {
160             if (oid == null || oid.getId() == null) {
161                 throw new IllegalArgumentException("Id is null!");
162             }
163 
164             if (sb.length() > 0) {
165                 sb.append(",");
166             }
167 
168             sb.append(escape(oid.getId()));
169         }
170 
171         parametersMap.put(parameterIndex, sb.toString());
172     }
173 
174     public void setUri(int parameterIndex, URI... uri) {
175         if (uri == null) {
176             throw new IllegalArgumentException("URI must be set!");
177         }
178 
179         StringBuilder sb = new StringBuilder();
180         for (URI u : uri) {
181             if (u == null) {
182                 throw new IllegalArgumentException("URI is null!");
183             }
184 
185             if (sb.length() > 0) {
186                 sb.append(",");
187             }
188 
189             sb.append(escape(u.toString()));
190         }
191 
192         parametersMap.put(parameterIndex, sb.toString());
193     }
194 
195     public void setUrl(int parameterIndex, URL... url) {
196         if (url == null) {
197             throw new IllegalArgumentException("URL must be set!");
198         }
199 
200         StringBuilder sb = new StringBuilder();
201         for (URL u : url) {
202             if (u == null) {
203                 throw new IllegalArgumentException("URI is null!");
204             }
205 
206             if (sb.length() > 0) {
207                 sb.append(",");
208             }
209 
210             sb.append(escape(u.toString()));
211         }
212 
213         parametersMap.put(parameterIndex, sb.toString());
214     }
215 
216     public void setBoolean(int parameterIndex, boolean... bool) {
217         if (bool == null || bool.length == 0) {
218             throw new IllegalArgumentException("Boolean must not be set!");
219         }
220 
221         StringBuilder sb = new StringBuilder();
222         for (boolean b : bool) {
223             if (sb.length() > 0) {
224                 sb.append(",");
225             }
226 
227             sb.append(b ? "TRUE" : "FALSE");
228         }
229 
230         parametersMap.put(parameterIndex, sb.toString());
231     }
232 
233     public void setDateTime(int parameterIndex, Calendar... cal) {
234         if (cal == null || cal.length == 0) {
235             throw new IllegalArgumentException("Calendar must be set!");
236         }
237 
238         StringBuilder sb = new StringBuilder();
239         for (Calendar c : cal) {
240             if (c == null) {
241                 throw new IllegalArgumentException("DateTime is null!");
242             }
243 
244             if (sb.length() > 0) {
245                 sb.append(",");
246             }
247 
248             sb.append(convert(c.getTime()));
249         }
250 
251         parametersMap.put(parameterIndex, sb.toString());
252     }
253 
254     public void setDateTime(int parameterIndex, Date... date) {
255         if (date == null || date.length == 0) {
256             throw new IllegalArgumentException("Date must be set!");
257         }
258 
259         StringBuilder sb = new StringBuilder();
260         for (Date d : date) {
261             if (d == null) {
262                 throw new IllegalArgumentException("DateTime is null!");
263             }
264 
265             if (sb.length() > 0) {
266                 sb.append(",");
267             }
268 
269             sb.append(convert(d));
270         }
271 
272         parametersMap.put(parameterIndex, sb.toString());
273     }
274 
275     public void setDateTime(int parameterIndex, long... ms) {
276         if (ms == null || ms.length == 0) {
277             throw new IllegalArgumentException("Timestamp must be set!");
278         }
279 
280         StringBuilder sb = new StringBuilder();
281         for (long l : ms) {
282             if (sb.length() > 0) {
283                 sb.append(",");
284             }
285 
286             sb.append(convert(new Date(l)));
287         }
288 
289         parametersMap.put(parameterIndex, sb.toString());
290     }
291 
292     public String toQueryString() {
293         boolean inStr = false;
294         int parameterIndex = 0;
295 
296         StringBuilder sb = new StringBuilder();
297         for (int i = 0; i < statement.length(); i++) {
298             char c = statement.charAt(i);
299 
300             if (c == '\'') {
301                 if (inStr && statement.charAt(i - 1) == '\\') {
302                     inStr = true;
303                 } else {
304                     inStr = !inStr;
305                 }
306                 sb.append(c);
307             } else if (c == '?' && !inStr) {
308                 parameterIndex++;
309                 String s = parametersMap.get(parameterIndex);
310                 if (s == null) {
311                     sb.append(c);
312                 } else {
313                     sb.append(s);
314                 }
315             } else {
316                 sb.append(c);
317             }
318         }
319 
320         return sb.toString();
321     }
322 
323     public ItemIterable<QueryResult> query(boolean searchAllVersions) {
324         return session.query(toQueryString(), searchAllVersions);
325     }
326 
327     public ItemIterable<QueryResult> query(boolean searchAllVersions, OperationContext context) {
328         return session.query(toQueryString(), searchAllVersions, context);
329     }
330 
331     @Override
332     protected Object clone() throws CloneNotSupportedException {
333         QueryStatementImpl qs = new QueryStatementImpl(session, statement);
334         qs.parametersMap.putAll(parametersMap);
335 
336         return qs;
337     }
338 
339     @Override
340     public String toString() {
341         return toQueryString();
342     }
343 
344     // --- internal ---
345 
346     private static String escape(String str) {
347         StringBuilder sb = new StringBuilder("'");
348         for (int i = 0; i < str.length(); i++) {
349             char c = str.charAt(i);
350 
351             if (c == '\'' || c == '\\') {
352                 sb.append("\\");
353             }
354 
355             sb.append(c);
356         }
357 
358         sb.append("'");
359 
360         return sb.toString();
361     }
362 
363     private static String escapeLike(String str) {
364         StringBuilder sb = new StringBuilder("'");
365         for (int i = 0; i < str.length(); i++) {
366             char c = str.charAt(i);
367 
368             if (c == '\'') {
369                 sb.append("\\");
370             } else if (c == '\\') {
371                 if (i + 1 < str.length() && (str.charAt(i + 1) == '%' || str.charAt(i + 1) == '_')) {
372                     // no additional back slash
373                 } else {
374                     sb.append("\\");
375                 }
376             }
377 
378             sb.append(c);
379         }
380 
381         sb.append("'");
382 
383         return sb.toString();
384     }
385 
386     private static String convert(Date date) {
387         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
388         sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
389 
390         return "'" + sdf.format(date) + "'";
391     }
392 }