1 package org.argeo.connect.util;
2
3 import static org.argeo.connect.util.ConnectJcrUtils.notEmpty;
4
5 import java.text.DateFormat;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8
9 import javax.jcr.RepositoryException;
10 import javax.jcr.Session;
11 import javax.jcr.query.Query;
12 import javax.jcr.query.QueryManager;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.apache.jackrabbit.util.ISO9075;
17 import org.argeo.connect.ConnectConstants;
18
19
20 public class XPathUtils {
21 private final static Log log = LogFactory.getLog(XPathUtils.class);
22
23 public static String descendantFrom(String parentPath) {
24 if (notEmpty(parentPath)) {
25 if ("/".equals(parentPath))
26 parentPath = "";
27
28 String result = "/jcr:root" + ISO9075.encodePath(parentPath);
29 if (log.isTraceEnabled()) {
30 String result2 = "/jcr:root" + parentPath;
31 if (!result2.equals(result))
32 log.warn("Encoded Path " + result2 + " --> " + result);
33 }
34 return result;
35 } else
36 return "";
37 }
38
39 public static String localAnd(String... conditions) {
40 StringBuilder builder = new StringBuilder();
41 for (String condition : conditions) {
42 if (notEmpty(condition)) {
43 builder.append(" ").append(condition).append(" and ");
44 }
45 }
46 if (builder.length() > 3)
47 return builder.substring(0, builder.length() - 4);
48 else
49 return "";
50 }
51
52 public static String xPathNot(String condition) {
53 if (notEmpty(condition))
54 return "not(" + condition + ")";
55 else
56 return "";
57 }
58
59 public static String getFreeTextConstraint(String filter) throws RepositoryException {
60 StringBuilder builder = new StringBuilder();
61 if (notEmpty(filter)) {
62 String[] strs = filter.trim().split(" ");
63 for (String token : strs) {
64 builder.append("jcr:contains(.,'*" + encodeXPathStringValue(token) + "*') and ");
65 }
66 return builder.substring(0, builder.length() - 4);
67 }
68 return "";
69 }
70
71 public static String getPropertyContains(String propertyName, String filter) throws RepositoryException {
72 if (notEmpty(filter))
73 return "jcr:contains(@" + propertyName + ",'*" + encodeXPathStringValue(filter) + "*')";
74 return "";
75 }
76
77 private final static DateFormat jcrRefFormatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'+02:00'");
78
79
80
81
82
83
84
85
86
87
88 public static String getPropertyDateComparaison(String propertyName, Calendar cal, String lowerOrGreater)
89 throws RepositoryException {
90 if (cal != null) {
91 String jcrDateStr = jcrRefFormatter.format(cal.getTime());
92
93
94 String result = "@" + propertyName + " " + lowerOrGreater + " xs:dateTime('" + jcrDateStr + "')";
95 return result;
96 }
97 return "";
98 }
99
100 public static String getPropertyEquals(String propertyName, String value) {
101 if (notEmpty(value))
102 return "@" + propertyName + "='" + encodeXPathStringValue(value) + "'";
103 return "";
104 }
105
106 public static String encodeXPathStringValue(String propertyValue) {
107
108
109
110 String result = propertyValue.replaceAll("'", "''");
111 return result;
112 }
113
114 public static void andAppend(StringBuilder builder, String condition) {
115 if (notEmpty(condition)) {
116 builder.append(condition);
117 builder.append(" and ");
118 }
119 }
120
121 public static void appendOrderByProperties(StringBuilder builder, boolean ascending, String... propertyNames) {
122 if (propertyNames.length > 0) {
123 builder.append(" order by ");
124 for (String propName : propertyNames)
125 builder.append("@").append(propName).append(", ");
126 builder = builder.delete(builder.length() - 2, builder.length());
127 if (ascending)
128 builder.append(" ascending ");
129 else
130 builder.append(" descending ");
131 }
132 }
133
134 public static void appendAndPropStringCondition(StringBuilder builder, String propertyName, String filter)
135 throws RepositoryException {
136 if (notEmpty(filter)) {
137 andAppend(builder, getPropertyContains(propertyName, filter));
138 }
139 }
140
141 public static void appendAndNotPropStringCondition(StringBuilder builder, String propertyName, String filter)
142 throws RepositoryException {
143 if (notEmpty(filter)) {
144 String cond = getPropertyContains(propertyName, filter);
145 builder.append(xPathNot(cond));
146 builder.append(" and ");
147 }
148 }
149
150 public static Query createQuery(Session session, String queryString) throws RepositoryException {
151 QueryManager queryManager = session.getWorkspace().getQueryManager();
152
153 queryString = localiseJcrItemNames(queryString);
154 return queryManager.createQuery(queryString, ConnectConstants.QUERY_XPATH);
155 }
156
157 private final static String NS_JCR = "\\{http://www.jcp.org/jcr/1.0\\}";
158 private final static String NS_NT = "\\{http://www.jcp.org/jcr/nt/1.0\\}";
159 private final static String NS_MIX = "\\{http://www.jcp.org/jcr/mix/1.0\\}";
160
161
162
163
164
165 public static String localiseJcrItemNames(String name) {
166 name = name.replaceAll(NS_JCR, "jcr:");
167 name = name.replaceAll(NS_NT, "nt:");
168 name = name.replaceAll(NS_MIX, "mix:");
169 return name;
170 }
171 }