]> git.argeo.org Git - gpl/argeo-suite.git/blob - core/org.argeo.suite.core/src/org/argeo/suite/util/XPathUtils.java
Fix issue when admin layers are not set.
[gpl/argeo-suite.git] / core / org.argeo.suite.core / src / org / argeo / suite / util / XPathUtils.java
1 package org.argeo.suite.util;
2
3 import java.text.DateFormat;
4 import java.text.SimpleDateFormat;
5 import java.util.Calendar;
6
7 import javax.jcr.RepositoryException;
8 import javax.jcr.Session;
9 import javax.jcr.query.Query;
10 import javax.jcr.query.QueryManager;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.apache.jackrabbit.util.ISO9075;
15
16 /** Ease XPath generation for JCR requests */
17 public class XPathUtils {
18 private final static Log log = LogFactory.getLog(XPathUtils.class);
19
20 private final static String QUERY_XPATH = "xpath";
21
22 public static String descendantFrom(String parentPath) {
23 if (notEmpty(parentPath)) {
24 if ("/".equals(parentPath))
25 parentPath = "";
26 // Hardcoded dependency to Jackrabbit. Remove
27 String result = "/jcr:root" + ISO9075.encodePath(parentPath);
28 if (log.isTraceEnabled()) {
29 String result2 = "/jcr:root" + parentPath;
30 if (!result2.equals(result))
31 log.warn("Encoded Path " + result2 + " --> " + result);
32 }
33 return result;
34 } else
35 return "";
36 }
37
38 public static String localAnd(String... conditions) {
39 StringBuilder builder = new StringBuilder();
40 for (String condition : conditions) {
41 if (notEmpty(condition)) {
42 builder.append(" ").append(condition).append(" and ");
43 }
44 }
45 if (builder.length() > 3)
46 return builder.substring(0, builder.length() - 4);
47 else
48 return "";
49 }
50
51 public static String xPathNot(String condition) {
52 if (notEmpty(condition))
53 return "not(" + condition + ")";
54 else
55 return "";
56 }
57
58 public static String getFreeTextConstraint(String filter) throws RepositoryException {
59 StringBuilder builder = new StringBuilder();
60 if (notEmpty(filter)) {
61 String[] strs = filter.trim().split(" ");
62 for (String token : strs) {
63 builder.append("jcr:contains(.,'*" + encodeXPathStringValue(token) + "*') and ");
64 }
65 return builder.substring(0, builder.length() - 4);
66 }
67 return "";
68 }
69
70 public static String getPropertyContains(String propertyName, String filter) throws RepositoryException {
71 if (notEmpty(filter))
72 return "jcr:contains(@" + propertyName + ",'*" + encodeXPathStringValue(filter) + "*')";
73 return "";
74 }
75
76 private final static DateFormat jcrRefFormatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'+02:00'");
77
78 /**
79 * @param propertyName
80 * @param calendar the reference date
81 * @param lowerOrGreater "<", ">" TODO validate ">="
82 * @return
83 * @throws RepositoryException
84 */
85 public static String getPropertyDateComparaison(String propertyName, Calendar cal, String lowerOrGreater)
86 throws RepositoryException {
87 if (cal != null) {
88 String jcrDateStr = jcrRefFormatter.format(cal.getTime());
89
90 // jcrDateStr = "2015-08-03T05:00:03:000Z";
91 String result = "@" + propertyName + " " + lowerOrGreater + " xs:dateTime('" + jcrDateStr + "')";
92 return result;
93 }
94 return "";
95 }
96
97 public static String getPropertyEquals(String propertyName, String value) {
98 if (notEmpty(value))
99 return "@" + propertyName + "='" + encodeXPathStringValue(value) + "'";
100 return "";
101 }
102
103 public static String encodeXPathStringValue(String propertyValue) {
104 // TODO implement safer mechanism to escape invalid characters
105 // Also check why we have used this regex in ResourceSerrviceImpl l 474
106 // String cleanedKey = key.replaceAll("(?:')", "''");
107 String result = propertyValue.replaceAll("'", "''");
108 return result;
109 }
110
111 public static void andAppend(StringBuilder builder, String condition) {
112 if (notEmpty(condition)) {
113 builder.append(condition);
114 builder.append(" and ");
115 }
116 }
117
118 public static void appendOrderByProperties(StringBuilder builder, boolean ascending, String... propertyNames) {
119 if (propertyNames.length > 0) {
120 builder.append(" order by ");
121 for (String propName : propertyNames)
122 builder.append("@").append(propName).append(", ");
123 builder = builder.delete(builder.length() - 2, builder.length());
124 if (ascending)
125 builder.append(" ascending ");
126 else
127 builder.append(" descending ");
128 }
129 }
130
131 public static void appendAndPropStringCondition(StringBuilder builder, String propertyName, String filter)
132 throws RepositoryException {
133 if (notEmpty(filter)) {
134 andAppend(builder, getPropertyContains(propertyName, filter));
135 }
136 }
137
138 public static void appendAndNotPropStringCondition(StringBuilder builder, String propertyName, String filter)
139 throws RepositoryException {
140 if (notEmpty(filter)) {
141 String cond = getPropertyContains(propertyName, filter);
142 builder.append(xPathNot(cond));
143 builder.append(" and ");
144 }
145 }
146
147 public static Query createQuery(Session session, String queryString) throws RepositoryException {
148 QueryManager queryManager = session.getWorkspace().getQueryManager();
149 // Localise JCR properties for XPATH
150 queryString = localiseJcrItemNames(queryString);
151 return queryManager.createQuery(queryString, QUERY_XPATH);
152 }
153
154 private final static String NS_JCR = "\\{http://www.jcp.org/jcr/1.0\\}";
155 private final static String NS_NT = "\\{http://www.jcp.org/jcr/nt/1.0\\}";
156 private final static String NS_MIX = "\\{http://www.jcp.org/jcr/mix/1.0\\}";
157
158 /**
159 * Replace the generic namespace with the local "jcr:", "nt:", "mix:" values. It
160 * is a workaround that must be later cleaned
161 */
162 public static String localiseJcrItemNames(String name) {
163 name = name.replaceAll(NS_JCR, "jcr:");
164 name = name.replaceAll(NS_NT, "nt:");
165 name = name.replaceAll(NS_MIX, "mix:");
166 return name;
167 }
168
169 private static boolean notEmpty(String stringToTest) {
170 return !(stringToTest == null || "".equals(stringToTest.trim()));
171 }
172
173 /** Singleton. */
174 private XPathUtils() {
175
176 }
177 }