View Javadoc
1   /**
2    * This file Copyright (c) 2003-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.util;
35  
36  import info.magnolia.cms.core.Content;
37  import info.magnolia.cms.core.NodeData;
38  import info.magnolia.cms.i18n.Messages;
39  import info.magnolia.cms.i18n.MessagesManager;
40  import info.magnolia.cms.i18n.MessagesUtil;
41  import info.magnolia.cms.security.AccessDeniedException;
42  import info.magnolia.context.MgnlContext;
43  import info.magnolia.jcr.util.PropertyUtil;
44  import info.magnolia.repository.RepositoryConstants;
45  
46  import java.io.InputStream;
47  import java.util.Calendar;
48  import java.util.Date;
49  import java.util.List;
50  
51  import javax.jcr.PropertyType;
52  import javax.jcr.RepositoryException;
53  import javax.jcr.Session;
54  import javax.jcr.Value;
55  import javax.jcr.ValueFactory;
56  
57  import org.apache.commons.lang3.StringUtils;
58  import org.slf4j.Logger;
59  import org.slf4j.LoggerFactory;
60  
61  /**
62   * Util to work with {@link NodeData}.
63   *
64   * @deprecated since 5.6. Use {@link PropertyUtil} instead.
65   */
66  @Deprecated
67  public class NodeDataUtil {
68      private static final Logger log = LoggerFactory.getLogger(NodeDataUtil.class);
69  
70      /**
71       * Same as getValueString(nd, dateFormat) but using the users short date format.
72       */
73      public static String getValueString(NodeData nodeData) {
74          String dateFormat = null;
75          if (nodeData.getType() == PropertyType.DATE) {
76              dateFormat = PropertyUtil.getDateFormat();
77          }
78          return getValueString(nodeData, dateFormat);
79      }
80  
81      /**
82       * Returns a String representation of the value. In case of a binary the path including filename and extension is returned
83       *
84       * @param dateFormat date format to use in the case it is a date
85       */
86      public static String getValueString(NodeData nodeData, String dateFormat) {
87          // we can't use FileProperties since this class is in the GUI package
88          if (nodeData.getType() == PropertyType.BINARY) {
89              String filename = nodeData.getAttribute("fileName");
90              String ext = nodeData.getAttribute("extension");
91              String fullName = filename;
92              String fullExt = StringUtils.EMPTY;
93              if (StringUtils.isNotEmpty(ext)) {
94                  fullExt = "." + ext;
95                  fullName += fullExt;
96              }
97              return nodeData.getHandle() + "/" + fullName;
98          } else if (nodeData.isMultiValue() == NodeData.MULTIVALUE_TRUE) {
99              return StringUtils.join(getValuesStringList(nodeData.getValues()), ",");
100         } else {
101             return getValueString(nodeData.getValue(), dateFormat);
102         }
103     }
104 
105     /**
106      * Same as value.getString(), but using custom date format.
107      */
108     public static String getValueString(Value value, String dateFormat) {
109         try {
110             switch (value.getType()) {
111             case (PropertyType.STRING):
112                 return value.getString();
113             case (PropertyType.DOUBLE):
114                 return Double.toString(value.getDouble());
115             case (PropertyType.LONG):
116                 return Long.toString(value.getLong());
117             case (PropertyType.BOOLEAN):
118                 return Boolean.toString(value.getBoolean());
119             case (PropertyType.DATE):
120                 Date valueDate = value.getDate().getTime();
121                 return DateUtil.format(valueDate, dateFormat);
122             case (PropertyType.BINARY):
123                 // ???
124             default:
125                 return StringUtils.EMPTY;
126             }
127         } catch (Exception e) {
128             log.debug("Exception caught: {}", e.getMessage(), e);
129         }
130         return StringUtils.EMPTY;
131     }
132 
133     /**
134      * Inherit a value. Uses the string value. The "inherit" means that the method will look for the value in the content itself and if not found
135      * it will go up in the tree and try to locate value in one of the parents of the content until reaching the root. The first value found while
136      * traversing the tree way up is the one that will be returned.
137      *
138      * @param node Node expected to define or inherit the searched node value.
139      * @param name Name of the nodeData.
140      */
141     public static String inheritString(Content node, String name) throws RepositoryException {
142         String value = "";
143 
144         if (node.hasNodeData(name)) {
145             value = NodeDataUtil.getString(node, name);
146         }
147         if (StringUtils.isEmpty(value) && node.getLevel() > 0) {
148             value = inheritString(node.getParent(), name);
149         }
150         return value;
151     }
152 
153     /**
154      * Inherit a value. You can provide a default value if not found
155      */
156     public static String inheritString(Content node, String name, String dflt) throws RepositoryException {
157         String value = inheritString(node, name);
158         if (StringUtils.isEmpty(value)) {
159             return dflt;
160         }
161         return value;
162     }
163 
164     /**
165      * Inherit a value. Uses the string value
166      */
167     public static Object inherit(Content node, String name) throws RepositoryException {
168         Object value = null;
169 
170         if (node.hasNodeData(name)) {
171             value = NodeDataUtil.getValueObject(node.getNodeData(name));
172         }
173         if (value == null && node.getLevel() > 0) {
174             value = inherit(node.getParent(), name);
175         }
176         return value;
177     }
178 
179     /**
180      * Inherit a value. You can provide a default value if not found
181      */
182     public static Object inherit(Content node, String name, Object dflt) throws RepositoryException {
183         Object value = inherit(node, name);
184         if (value == null) {
185             return dflt;
186         }
187         return value;
188     }
189 
190     /**
191      * Returns the value as an Object.
192      */
193     public static Object getValueObject(NodeData nd) {
194         try {
195             switch (nd.getType()) {
196             case (PropertyType.STRING):
197                 return nd.getString();
198             case (PropertyType.DOUBLE):
199                 return Double.valueOf(nd.getDouble());
200             case (PropertyType.LONG):
201                 return Long.valueOf(nd.getLong());
202             case (PropertyType.BOOLEAN):
203                 return Boolean.valueOf(nd.getBoolean());
204             case (PropertyType.DATE):
205                 return nd.getDate().getTime();
206             case (PropertyType.BINARY):
207                 return null;
208             default:
209                 return null;
210             }
211         } catch (Exception e) {
212             log.debug("Exception caught: {}", e.getMessage(), e);
213         }
214         return null;
215     }
216 
217     /**
218      * Calls the correct setValue method based on object type. If the value is null an empty string is set.
219      */
220     public static NodeData setValue(NodeData nodeData, Object valueObj) throws AccessDeniedException, RepositoryException {
221         if (valueObj == null) {
222             nodeData.setValue(StringUtils.EMPTY);
223         } else {
224             switch (PropertyUtil.getJCRPropertyType(valueObj)) {
225             case PropertyType.STRING:
226                 nodeData.setValue((String) valueObj);
227                 break;
228             case PropertyType.BOOLEAN:
229                 nodeData.setValue(((Boolean) valueObj).booleanValue());
230                 break;
231             case PropertyType.DATE:
232                 nodeData.setValue((Calendar) valueObj);
233                 break;
234             case PropertyType.LONG:
235                 // can either be a Long or Integer - see #getJCRPropertyType(Object)
236                 long longToSet = (valueObj instanceof Integer) ? ((Integer) valueObj).longValue() : ((Long) valueObj).longValue();
237                 nodeData.setValue(longToSet);
238                 break;
239             case PropertyType.DOUBLE:
240                 // can either be a Double or Float - see #getJCRPropertyType(Object)
241                 double doubleToSet = (valueObj instanceof Float) ? ((Float) valueObj).doubleValue() : ((Double) valueObj).doubleValue();
242                 nodeData.setValue(doubleToSet);
243                 break;
244             case PropertyType.BINARY:
245                 nodeData.setValue((InputStream) valueObj);
246                 break;
247             case PropertyType.REFERENCE:
248                 nodeData.setValue((Content) valueObj);
249                 break;
250             default:
251                 nodeData.setValue(valueObj.toString());
252             }
253         }
254         return nodeData;
255     }
256 
257 
258     /**
259      * String representation of the jcr property type.
260      */
261     public static String getTypeName(NodeData nd) {
262         return PropertyType.nameFromValue(nd.getType());
263     }
264 
265     /**
266      * Simple method to get strings like configuration informations.
267      */
268     public static String getString(String repository, String path) {
269         return getString(repository, path, null);
270     }
271 
272     /**
273      * Get the string or the empty string if not existing.
274      */
275     public static String getString(Content node, String name) {
276         return getString(node, name, "");
277     }
278 
279     /**
280      * You can define a default value if not found.
281      */
282     public static String getString(String repository, String path, String defaultValue) {
283         try {
284             String name = StringUtils.substringAfterLast(path, "/");
285             String nodeHandle = StringUtils.substringBeforeLast(path, "/");
286             Content node = ContentUtil.asContent(MgnlContext.getJCRSession(repository).getNode(nodeHandle));
287             return getString(node, name);
288         } catch (Exception e) {
289             return defaultValue;
290         }
291     }
292 
293     /**
294      * You can define a default value if not found.
295      */
296     public static String getString(Content node, String name, String defaultValue) {
297         try {
298             if (node.hasNodeData(name)) {
299                 return getValueString(node.getNodeData(name));
300             }
301 
302             return defaultValue;
303         } catch (Exception e) {
304             return defaultValue;
305         }
306     }
307 
308     public static long getLong(Content node, String name, long defaultValue) {
309         try {
310             if (node.hasNodeData(name)) {
311                 return node.getNodeData(name).getLong();
312             }
313         }
314         // should not happen
315         catch (RepositoryException e) {
316             log.error("can't read value will return default value", e);
317         }
318         return defaultValue;
319     }
320 
321     public static Calendar getDate(Content node, String name, Calendar defaultValue) {
322         try {
323             if (node.hasNodeData(name)) {
324                 return node.getNodeData(name).getDate();
325             }
326         }
327         // should not happen
328         catch (RepositoryException e) {
329             log.error("can't read value will return default value", e);
330         }
331         return defaultValue;
332     }
333 
334     public static boolean getBoolean(Content node, String name, boolean defaultValue) {
335         try {
336             if (node.hasNodeData(name)) {
337                 return node.getNodeData(name).getBoolean();
338             }
339         }
340         // should not happen
341         catch (RepositoryException e) {
342             log.error("can't read value will return default value", e);
343         }
344         return defaultValue;
345     }
346 
347     /**
348      * If the NodeData does not exist yet, just create it.
349      *
350      * @return the found or created NodeData
351      */
352     public static NodeData getOrCreate(Content node, String name) throws AccessDeniedException, RepositoryException {
353         return getOrCreate(node, name, PropertyType.STRING);
354     }
355 
356     /**
357      * If the NodeData does not exist yet, just create it.
358      *
359      * @return the found or created NodeData
360      */
361     public static NodeData getOrCreate(Content node, String name, int type) throws AccessDeniedException,
362             RepositoryException {
363         if (node.hasNodeData(name)) {
364             return node.getNodeData(name);
365         }
366 
367         return node.createNodeData(name, type);
368     }
369 
370     public static NodeData getOrCreate(Content node, String name, Object obj) throws AccessDeniedException,
371             RepositoryException {
372 
373         return getOrCreate(node, name, PropertyUtil.getJCRPropertyType(obj));
374     }
375 
376 
377     public static NodeData getOrCreateAndSet(Content node, String name, Object obj) throws AccessDeniedException, RepositoryException {
378         // TODO we should not use the jcr node
379         ValueFactory valueFactory = node.getJCRNode().getSession().getValueFactory();
380         NodeData nd = getOrCreate(node, name, PropertyUtil.getJCRPropertyType(obj));
381         nd.setValue(createValue(obj, valueFactory));
382         return nd;
383     }
384 
385     public static NodeData getOrCreateAndSet(Content node, String name, long value) throws AccessDeniedException, RepositoryException {
386         return getOrCreateAndSet(node, name, Long.valueOf(value));
387     }
388 
389     public static NodeData getOrCreateAndSet(Content node, String name, Value[] value) throws AccessDeniedException, RepositoryException {
390         if (node.hasNodeData(name)) {
391             node.setNodeData(name, value);
392             return node.getNodeData(name);
393         }
394 
395         return node.createNodeData(name, value);
396 
397     }
398 
399     public static NodeData getOrCreateAndSet(Content node, String name, int value) throws AccessDeniedException, RepositoryException {
400         return getOrCreateAndSet(node, name, Long.valueOf(value));
401     }
402 
403     public static NodeData getOrCreateAndSet(Content node, String name, boolean value) throws AccessDeniedException, RepositoryException {
404         return getOrCreateAndSet(node, name, Boolean.valueOf(value));
405     }
406 
407     /**
408      * Uses the i18n mechanism to translate the message if the resulting string is a key.
409      */
410     public static String getI18NString(Content node, String str) {
411         Messages msgs = MessagesManager.getMessages();
412         String key = getString(node, str);
413         String i18nBasename = null;
414         try {
415             i18nBasename = NodeDataUtil.inheritString(node, "i18nBasename");
416         } catch (RepositoryException e) {
417             log.error("can't read i18nBasename value, will default back", e);
418         }
419 
420         if (StringUtils.isNotEmpty(i18nBasename)) {
421             msgs = MessagesUtil.chainWithDefault(i18nBasename);
422         }
423 
424         return msgs.getWithDefault(key, key);
425     }
426 
427     /**
428      * Uses the i18n mechanism to translate the message if the resulting string is a key.
429      */
430     public static String getI18NString(Content node, String str, String basename) {
431         String key = getString(node, str);
432         return MessagesManager.getMessages(basename).getWithDefault(key, key);
433     }
434 
435     /**
436      * Uses the default value factory.
437      */
438     public static Value createValue(String valueStr, int type) throws RepositoryException {
439         final Session session = MgnlContext.getSystemContext().getJCRSession(RepositoryConstants.CONFIG);
440         final ValueFactory valueFactory = session.getValueFactory();
441         return createValue(valueStr, type, valueFactory);
442     }
443 
444     /**
445      * @deprecated since 4.5 - use {@link PropertyUtil#createValue(Object, ValueFactory)} instead
446      */
447     @Deprecated
448     public static Value createValue(Object obj, ValueFactory valueFactory) throws RepositoryException {
449         return PropertyUtil.createValue(obj, valueFactory);
450     }
451 
452     /**
453      * Transforms a string to a jcr value object.
454      *
455      * @deprecated since 4.5 - directly use {@link PropertyUtil#createValue(String, int, ValueFactory)} instead.
456      */
457     @Deprecated
458     public static Value createValue(String valueStr, int type, ValueFactory valueFactory) {
459         return PropertyUtil.createValue(valueStr, type, valueFactory);
460     }
461 
462     /**
463      * @deprecated since 4.5 - use {@link PropertyUtil#getJCRPropertyType(Object)} instead
464      */
465     @Deprecated
466     public static int getJCRPropertyType(Object obj) {
467         return PropertyUtil.getJCRPropertyType(obj);
468     }
469 
470     /**
471      * @deprecated since 4.5  - use {@link PropertyUtil#getValuesStringList(Value[])} instead
472      */
473     @Deprecated
474     public static List<String> getValuesStringList(Value[] values) {
475         return PropertyUtil.getValuesStringList(values);
476     }
477 
478     /**
479      * @deprecated since 4.5 - use {@link PropertyUtil#getDateFormat()} instead
480      */
481     @Deprecated
482     public static String getDateFormat() {
483         return PropertyUtil.getDateFormat();
484     }
485 }