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