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 Long) {
116 node.setProperty(propertyName, ((Long) propertyValue).longValue());
117 } else if (propertyValue instanceof Double) {
118 node.setProperty(propertyName, (Double) propertyValue);
119 } else if (propertyValue instanceof Boolean) {
120 node.setProperty(propertyName, (Boolean) propertyValue);
121 } else if (propertyValue instanceof InputStream) {
122 node.setProperty(propertyName, createBinaryFromInputStream((InputStream) propertyValue));
123 } else if (propertyValue instanceof Collection) {
124 ValueFactory valueFactory = ValueFactoryImpl.getInstance();
125 ArrayList<Value> values = new ArrayList<Value>();
126 for (Object value : (Collection<Object>)propertyValue) {
127 values.add(createValue(value, valueFactory));
128 }
129 node.setProperty(propertyName, values.toArray(new Value[values.size()]));
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 Date) {
223 return PropertyType.DATE;
224 }
225 if (obj instanceof Binary) {
226 return PropertyType.BINARY;
227 }
228 if (obj instanceof InputStream) {
229 return PropertyType.BINARY;
230 }
231 if (obj instanceof Content) {
232 return PropertyType.REFERENCE;
233 }
234 return PropertyType.UNDEFINED;
235 }
236
237
238
239
240 public static void updateOrCreate(Node node, String string, GregorianCalendar gregorianCalendar) throws RepositoryException {
241 if (node.hasProperty(string)) {
242 node.getProperty(string).setValue(gregorianCalendar);
243 } else {
244 node.setProperty(string, gregorianCalendar);
245 }
246 }
247
248 public static String getDateFormat() {
249 try {
250 return FastDateFormat.getDateInstance(
251 FastDateFormat.SHORT,
252 MgnlContext.getLocale()).getPattern();
253 } catch (IllegalStateException e) {
254
255 return DateUtil.YYYY_MM_DD;
256 }
257 }
258
259 public static List<String> getValuesStringList(Value[] values) {
260 ArrayList<String> list = new ArrayList<String>();
261 for (Value value : values) {
262 list.add(getValueString(value));
263 }
264 return list;
265 }
266
267
268
269
270 public static String getValueString(Property property) {
271 try {
272 return getValueString(property.getValue());
273 } catch (RepositoryException e) {
274 log.debug("RepositoryException caught: {}", e.getMessage(), e);
275 return null;
276 }
277 }
278
279
280
281
282 public static String getValueString(Value value) {
283 try {
284 switch (value.getType()) {
285 case (PropertyType.STRING):
286 return value.getString();
287 case (PropertyType.DOUBLE):
288 return Double.toString(value.getDouble());
289 case (PropertyType.LONG):
290 return Long.toString(value.getLong());
291 case (PropertyType.BOOLEAN):
292 return Boolean.toString(value.getBoolean());
293 case (PropertyType.DATE):
294 Date valueDate = value.getDate().getTime();
295 return DateUtil.format(valueDate, PropertyUtil.getDateFormat());
296 case (PropertyType.BINARY):
297
298 default:
299 return StringUtils.EMPTY;
300 }
301 } catch (RepositoryException e) {
302 log.debug("RepositoryException caught: {}", e.getMessage(), e);
303 }
304 return null;
305
306 }
307
308 public static Value createValue(Object obj, ValueFactory valueFactory) throws RepositoryException {
309 switch (PropertyUtil.getJCRPropertyType(obj)) {
310 case PropertyType.STRING:
311 return valueFactory.createValue((String) obj);
312 case PropertyType.BOOLEAN:
313 return valueFactory.createValue((Boolean) obj);
314 case PropertyType.DATE:
315 if (obj instanceof Calendar) {
316 return valueFactory.createValue((Calendar) obj);
317 } else {
318 Calendar cal = Calendar.getInstance();
319 cal.setTime((Date) obj);
320 return valueFactory.createValue(cal);
321 }
322 case PropertyType.LONG:
323 return obj instanceof Long ? valueFactory.createValue(((Long) obj).longValue()) : valueFactory.createValue(((Integer) obj).longValue());
324 case PropertyType.DOUBLE:
325 return obj instanceof Double ? valueFactory.createValue((Double) obj) : valueFactory.createValue(((Float) obj).doubleValue());
326 case PropertyType.BINARY:
327 return valueFactory.createValue(createBinaryFromInputStream((InputStream) obj));
328 case PropertyType.REFERENCE:
329 return valueFactory.createValue(((Content) obj).getJCRNode());
330 default:
331 return (obj != null ? valueFactory.createValue(obj.toString()) : valueFactory.createValue(StringUtils.EMPTY));
332 }
333 }
334
335
336
337
338
339
340 public static Calendar getDate(Node node, String name) {
341 return getDate(node, name, null);
342 }
343
344
345
346
347
348
349 public static Calendar getDate(Node node, String name, Calendar defaultValue) {
350 try {
351 if (node.hasProperty(name)) {
352 return node.getProperty(name).getDate();
353 }
354 } catch (RepositoryException e) {
355 log.error("can't read value '{}' of the Node '{}' will return default value", name, node.toString(), e);
356 }
357 return defaultValue;
358 }
359
360
361
362
363
364
365 public static String getString(Node node, String name) {
366 return getString(node, name, null);
367 }
368
369
370
371
372
373
374 public static String getString(Node node, String name, String defaultValue) {
375 if (node != null) {
376 try {
377 if (node.hasProperty(name)) {
378 return node.getProperty(name).getString();
379 }
380 } catch (RepositoryException e) {
381 log.error("can't read value '{}' of the Node '{}' will return default value", name, node.toString(), e);
382 }
383 }
384 return defaultValue;
385 }
386
387 public static Long getLong(Node node, String name) {
388 return getLong(node, name, null);
389 }
390
391 public static Long getLong(Node node, String name, Long defaultValue) {
392 if (node != null) {
393 try {
394 if (node.hasProperty(name)) {
395 return node.getProperty(name).getLong();
396 }
397 } catch (RepositoryException e) {
398 log.error("can't read value '{}' of the Node '{}' will return default value", name, node.toString(), e);
399 }
400 }
401 return defaultValue;
402 }
403
404
405
406
407
408
409 public static boolean getBoolean(Node node, String name, boolean defaultValue) {
410 try {
411 if (node.hasProperty(name)) {
412 return node.getProperty(name).getBoolean();
413 }
414 } catch (RepositoryException e) {
415 log.error("can't read value '{}' of the Node '{}' will return default value", name, node.toString(), e);
416 }
417 return defaultValue;
418 }
419
420
421
422
423
424 public static Property getPropertyOrNull(Node node, String relativePath) {
425 try {
426 return node.hasProperty(relativePath) ? node.getProperty(relativePath) : null;
427 }
428 catch (RepositoryException e) {
429 log.debug("Could not retrieve property {}", relativePath, e);
430 }
431 return null;
432 }
433
434
435
436
437 public static Property getProperty(Node node, String relativePath) {
438 return getPropertyOrNull(node, relativePath);
439 }
440
441
442
443
444
445
446
447 public static Object getPropertyValueObject(Node node, String relativePath) {
448 final Property property = getPropertyOrNull(node, relativePath);
449 if(property != null) {
450 try {
451
452 if(property.isMultiple()) {
453 Value[] values = property.getValues();
454 List<Object> res = new LinkedList<Object>();
455 for(Value value:values) {
456 res.add(getValueObject(value));
457 }
458 return res;
459 } else {
460 return getValueObject(property.getValue());
461 }
462
463 } catch (Exception e) {
464 log.warn("Exception during casting the property value", e);
465 }
466 }
467 return null;
468 }
469
470
471
472
473
474 public static Object getValueObject(Value value) {
475 try {
476 switch (value.getType()) {
477 case (PropertyType.DECIMAL):
478 return value.getDecimal();
479 case (PropertyType.STRING):
480 return value.getString();
481 case (PropertyType.DOUBLE):
482 return Double.valueOf(value.getDouble());
483 case (PropertyType.LONG):
484 return Long.valueOf(value.getLong());
485 case (PropertyType.BOOLEAN):
486 return Boolean.valueOf(value.getBoolean());
487 case (PropertyType.DATE):
488 return value.getDate().getTime();
489 case (PropertyType.BINARY):
490 return ValueFactoryImpl.getInstance().createBinary(value.getBinary().getStream());
491 default:
492 return value.getString();
493 }
494 } catch (Exception e) {
495 log.warn("Exception during casting the property value", e);
496 }
497 return null;
498 }
499
500
501
502
503
504
505 private static Binary createBinaryFromInputStream(InputStream in) throws RepositoryException {
506 try {
507 return new BinaryImpl((InputStream) in);
508 } catch (IOException ioe) {
509 log.warn("Could not create a Binary Object from the property input Stream.");
510 throw new RepositoryException(ioe);
511 }
512 }
513
514 }