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