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