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