1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.jcr.util;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.util.DateUtil;
38 import info.magnolia.context.MgnlContext;
39
40 import java.io.InputStream;
41 import java.math.BigDecimal;
42 import java.util.ArrayList;
43 import java.util.Calendar;
44 import java.util.Collection;
45 import java.util.Date;
46 import java.util.GregorianCalendar;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.TimeZone;
50
51 import javax.jcr.Binary;
52 import javax.jcr.Node;
53 import javax.jcr.Property;
54 import javax.jcr.PropertyType;
55 import javax.jcr.RepositoryException;
56 import javax.jcr.Value;
57 import javax.jcr.ValueFactory;
58
59 import org.apache.commons.lang.BooleanUtils;
60 import org.apache.commons.lang.StringUtils;
61 import org.apache.commons.lang.time.FastDateFormat;
62 import org.apache.jackrabbit.value.ValueFactoryImpl;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66
67
68
69 public class PropertyUtil {
70
71 private static final Logger log = LoggerFactory.getLogger(PropertyUtil.class);
72
73 public static Property renameProperty(Property property, String newName) throws RepositoryException {
74
75 if (property.getName().equals(newName)) {
76 return property;
77 }
78 Node node = property.getParent();
79 Property newProperty = node.setProperty(newName, property.getValue());
80 property.remove();
81 return newProperty;
82 }
83
84
85
86
87 @SuppressWarnings("unchecked")
88 public static void setProperty(Node node, String propertyName, Object propertyValue) throws RepositoryException {
89 if (node == null) {
90 throw new IllegalArgumentException("Cannot set a property on a null-node!");
91 }
92 if (propertyName == null) {
93 throw new IllegalArgumentException("Cannot set a property without a provided name");
94 }
95
96 if (propertyValue == null){
97 node.setProperty(propertyName, (Value) null);
98 } else if (propertyValue instanceof Value) {
99 node.setProperty(propertyName, (Value) propertyValue);
100 } else if (propertyValue instanceof Node) {
101 node.setProperty(propertyName, (Node) propertyValue);
102 } else if (propertyValue instanceof Binary) {
103 node.setProperty(propertyName, (Binary) propertyValue);
104 } else if (propertyValue instanceof Calendar) {
105 node.setProperty(propertyName, (Calendar) propertyValue);
106 } else if (propertyValue instanceof Date) {
107 Calendar cal = Calendar.getInstance();
108 cal.setTime((Date) propertyValue);
109 node.setProperty(propertyName, cal);
110 } else if (propertyValue instanceof BigDecimal) {
111 node.setProperty(propertyName, (BigDecimal) propertyValue);
112 } else if (propertyValue instanceof String) {
113 node.setProperty(propertyName, (String) propertyValue);
114 } else if (propertyValue instanceof Long) {
115 node.setProperty(propertyName, ((Long) propertyValue).longValue());
116 } else if (propertyValue instanceof Double) {
117 node.setProperty(propertyName, (Double) propertyValue);
118 } else if (propertyValue instanceof Boolean) {
119 node.setProperty(propertyName, (Boolean) propertyValue);
120 } else if (propertyValue instanceof InputStream) {
121 node.setProperty(propertyName, (InputStream) propertyValue);
122 } else if (propertyValue instanceof Collection) {
123 String[] list = new String[((Collection<Object>)propertyValue).size()];
124 int pos = 0;
125 for (Object value : (Collection<Object>)propertyValue) {
126 list[pos] = value.toString();
127 pos +=1;
128 }
129 node.setProperty(propertyName, list);
130 } else {
131
132 throw new IllegalArgumentException("Cannot set property to a value of type " + propertyValue.getClass());
133 }
134 }
135
136
137
138
139 public static Value createValue(String valueStr, int type, ValueFactory valueFactory) {
140 Value value = null;
141 if (type == PropertyType.STRING) {
142 value = valueFactory.createValue(valueStr);
143 } else if (type == PropertyType.BOOLEAN) {
144 value = valueFactory.createValue(BooleanUtils.toBoolean(valueStr));
145 } else if (type == PropertyType.DOUBLE) {
146 try {
147 value = valueFactory.createValue(Double.parseDouble(valueStr));
148 } catch (NumberFormatException e) {
149 value = valueFactory.createValue(0d);
150 }
151 } else if (type == PropertyType.LONG) {
152 try {
153 value = valueFactory.createValue(Long.parseLong(valueStr));
154 } catch (NumberFormatException e) {
155 value = valueFactory.createValue(0L);
156 }
157 } else if (type == PropertyType.DATE) {
158 try {
159 Calendar date = new GregorianCalendar();
160 try {
161 String newDateAndTime = valueStr;
162 String[] dateAndTimeTokens = newDateAndTime.split("T");
163 String newDate = dateAndTimeTokens[0];
164 String[] dateTokens = newDate.split("-");
165 int hour = 0;
166 int minute = 0;
167 int second = 0;
168 int year = Integer.parseInt(dateTokens[0]);
169 int month = Integer.parseInt(dateTokens[1]) - 1;
170 int day = Integer.parseInt(dateTokens[2]);
171 if (dateAndTimeTokens.length > 1) {
172 String newTime = dateAndTimeTokens[1];
173 String[] timeTokens = newTime.split(":");
174 hour = Integer.parseInt(timeTokens[0]);
175 minute = Integer.parseInt(timeTokens[1]);
176 second = Integer.parseInt(timeTokens[2]);
177 }
178 date.set(year, month, day, hour, minute, second);
179
180 date.set(Calendar.MILLISECOND, 0);
181 date.setTimeZone(TimeZone.getTimeZone("GMT"));
182 }
183
184 catch (Exception e) {
185
186 }
187 value = valueFactory.createValue(date);
188 } catch (Exception e) {
189 log.debug("Exception caught: " + e.getMessage(), e);
190 }
191 }
192
193 return value;
194
195 }
196
197
198
199
200 public static int getJCRPropertyType(Object obj) {
201 if (obj instanceof String) {
202 return PropertyType.STRING;
203 }
204 if (obj instanceof Double) {
205 return PropertyType.DOUBLE;
206 }
207 if (obj instanceof Float) {
208 return PropertyType.DOUBLE;
209 }
210 if (obj instanceof Long) {
211 return PropertyType.LONG;
212 }
213 if (obj instanceof Integer) {
214 return PropertyType.LONG;
215 }
216 if (obj instanceof Boolean) {
217 return PropertyType.BOOLEAN;
218 }
219 if (obj instanceof Calendar) {
220 return PropertyType.DATE;
221 }
222 if (obj instanceof Binary) {
223 return PropertyType.BINARY;
224 }
225 if (obj instanceof InputStream) {
226 return PropertyType.BINARY;
227 }
228 if (obj instanceof Content) {
229 return PropertyType.REFERENCE;
230 }
231 return PropertyType.UNDEFINED;
232 }
233
234
235
236
237 public static void updateOrCreate(Node node, String string, GregorianCalendar gregorianCalendar) throws RepositoryException {
238 if (node.hasProperty(string)) {
239 node.getProperty(string).setValue(gregorianCalendar);
240 } else {
241 node.setProperty(string, gregorianCalendar);
242 }
243 }
244
245 public static String getDateFormat() {
246 try {
247 return FastDateFormat.getDateInstance(
248 FastDateFormat.SHORT,
249 MgnlContext.getLocale()).getPattern();
250 } catch (IllegalStateException e) {
251
252 return DateUtil.YYYY_MM_DD;
253 }
254 }
255
256 public static List<String> getValuesStringList(Value[] values) {
257 ArrayList<String> list = new ArrayList<String>();
258 for (Value value : values) {
259 list.add(getValueString(value));
260 }
261 return list;
262 }
263
264
265
266
267 public static String getValueString(Property property) {
268 try {
269 return getValueString(property.getValue());
270 } catch (RepositoryException e) {
271 log.debug("RepositoryException caught: " + e.getMessage(), e);
272 return null;
273 }
274 }
275
276
277
278
279 public static String getValueString(Value value) {
280 try {
281 switch (value.getType()) {
282 case (PropertyType.STRING):
283 return value.getString();
284 case (PropertyType.DOUBLE):
285 return Double.toString(value.getDouble());
286 case (PropertyType.LONG):
287 return Long.toString(value.getLong());
288 case (PropertyType.BOOLEAN):
289 return Boolean.toString(value.getBoolean());
290 case (PropertyType.DATE):
291 Date valueDate = value.getDate().getTime();
292 return DateUtil.format(valueDate, PropertyUtil.getDateFormat());
293 case (PropertyType.BINARY):
294
295 default:
296 return StringUtils.EMPTY;
297 }
298 } catch (RepositoryException e) {
299 log.debug("RepositoryException caught: " + e.getMessage(), e);
300 }
301 return null;
302
303 }
304
305 public static Value createValue(Object obj, ValueFactory valueFactory) throws RepositoryException {
306 switch (PropertyUtil.getJCRPropertyType(obj)) {
307 case PropertyType.STRING:
308 return valueFactory.createValue((String) obj);
309 case PropertyType.BOOLEAN:
310 return valueFactory.createValue((Boolean) obj);
311 case PropertyType.DATE:
312 return valueFactory.createValue((Calendar) obj);
313 case PropertyType.LONG:
314 return obj instanceof Long ? valueFactory.createValue(((Long) obj).longValue()) : valueFactory.createValue(((Integer) obj).longValue());
315 case PropertyType.DOUBLE:
316 return obj instanceof Double ? valueFactory.createValue((Double) obj) : valueFactory.createValue(((Float) obj).doubleValue());
317 case PropertyType.BINARY:
318 return valueFactory.createValue((InputStream) obj);
319 case PropertyType.REFERENCE:
320 return valueFactory.createValue(((Content) obj).getJCRNode());
321 default:
322 return (obj != null ? valueFactory.createValue(obj.toString()) : valueFactory.createValue(StringUtils.EMPTY));
323 }
324 }
325
326
327
328
329
330
331 public static Calendar getDate(Node node, String name) {
332 return getDate(node, name, null);
333 }
334
335
336
337
338
339
340 public static Calendar getDate(Node node, String name, Calendar defaultValue) {
341 try {
342 if (node.hasProperty(name)) {
343 return node.getProperty(name).getDate();
344 }
345 } catch (RepositoryException e) {
346 log.error("can't read value '" + name + "' of the Node '" + node.toString() + "' will return default value", e);
347 }
348 return defaultValue;
349 }
350
351
352
353
354
355
356 public static String getString(Node node, String name) {
357 return getString(node, name, null);
358 }
359
360
361
362
363
364
365 public static String getString(Node node, String name, String defaultValue) {
366 if (node != null) {
367 try {
368 if (node.hasProperty(name)) {
369 return node.getProperty(name).getString();
370 }
371 } catch (RepositoryException e) {
372 log.error("can't read value '" + name + "' of the Node '" + node.toString() + "' will return default value", e);
373 }
374 }
375 return defaultValue;
376 }
377
378
379
380
381
382
383 public static boolean getBoolean(Node node, String name, boolean defaultValue) {
384 try {
385 if (node.hasProperty(name)) {
386 return node.getProperty(name).getBoolean();
387 }
388 } catch (RepositoryException e) {
389 log.error("can't read value '" + name + "' of the Node '" + node.toString() + "' will return default value", e);
390 }
391 return defaultValue;
392 }
393
394
395
396
397 public static Property getPropertyOrNull(Node node, String relativePath) {
398 try {
399 return node.hasProperty(relativePath) ? node.getProperty(relativePath) : null;
400 }
401 catch (RepositoryException e) {
402 log.debug("Could not retrieve property " + relativePath, e);
403 }
404 return null;
405 }
406
407
408
409
410 public static Property getProperty(Node node, String relativePath) {
411 return getPropertyOrNull(node, relativePath);
412 }
413
414
415
416
417
418
419
420 public static Object getPropertyValueObject(Node node, String relativePath) {
421 final Property property = getPropertyOrNull(node, relativePath);
422 if(property != null) {
423 try {
424
425 if(property.isMultiple()) {
426 Value[] values = property.getValues();
427 List<Object> res = new LinkedList<Object>();
428 for(Value value:values) {
429 res.add(getValueObject(value));
430 }
431 return res;
432 } else {
433 return getValueObject(property.getValue());
434 }
435
436 } catch (Exception e) {
437 log.warn("Exception during casting the property value", e);
438 }
439 }
440 return null;
441 }
442
443
444
445
446
447 public static Object getValueObject(Value value) {
448 try {
449 switch (value.getType()) {
450 case (PropertyType.DECIMAL):
451 return value.getDecimal();
452 case (PropertyType.STRING):
453 return value.getString();
454 case (PropertyType.DOUBLE):
455 return Double.valueOf(value.getDouble());
456 case (PropertyType.LONG):
457 return Long.valueOf(value.getLong());
458 case (PropertyType.BOOLEAN):
459 return Boolean.valueOf(value.getBoolean());
460 case (PropertyType.DATE):
461 return value.getDate().getTime();
462 case (PropertyType.BINARY):
463 return ValueFactoryImpl.getInstance().createBinary(value.getBinary().getStream());
464 default:
465 return null;
466 }
467 } catch (Exception e) {
468 log.warn("Exception during casting the property value", e);
469 }
470 return null;
471 }
472
473 }