View Javadoc

1   /**
2    * This file Copyright (c) 2008-2010 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.beans.runtime.FileProperties;
37  import info.magnolia.cms.core.Content;
38  import info.magnolia.cms.core.NodeData;
39  import info.magnolia.link.LinkException;
40  import info.magnolia.link.LinkTransformerManager;
41  
42  import java.util.ArrayList;
43  import java.util.Collection;
44  import java.util.HashSet;
45  import java.util.Iterator;
46  import java.util.Map;
47  import java.util.Set;
48  
49  import javax.jcr.PropertyType;
50  import javax.jcr.RepositoryException;
51  import javax.jcr.Value;
52  
53  import org.apache.commons.beanutils.PropertyUtils;
54  import org.slf4j.Logger;
55  import org.slf4j.LoggerFactory;
56  
57  
58  /**
59   * Wrapper for a content Node which exposes a Map interface, used to access its content using jstl.
60   * @author fguist
61   * @version $Revision: 2161 $ ($Author: fgiust $)
62   */
63  public class NodeMapWrapper extends ContentWrapper implements Map {
64  
65      private static final Logger log = LoggerFactory.getLogger(NodeMapWrapper.class);
66  
67      /**
68       * Handle used to construct links.
69       */
70      private final String handle;
71  
72      /**
73       * Instantiates a new NodeMapWrapper for the given node.
74       * @param node Content node
75       * @param handle Parent page handle or other prefix for links.
76       */
77      public NodeMapWrapper(Content node, String handle) {
78          super(node);
79          this.handle = handle;
80      }
81  
82      @Override
83      protected Content wrap(Content node) {
84          return new NodeMapWrapper(node, handle);
85      }
86  
87      /**
88       * @see java.util.Map#size()
89       */
90      public int size() {
91          return getWrappedContent().getNodeDataCollection().size();
92      }
93  
94      /**
95       * @see java.util.Map#isEmpty()
96       */
97      public boolean isEmpty() {
98          return getWrappedContent().getNodeDataCollection().isEmpty();
99      }
100 
101     /**
102      * @see java.util.Map#containsKey(java.lang.Object)
103      */
104     public boolean containsKey(Object key) {
105         return this.getWrappedContent().getNodeData((String) key).isExist() || hasProperty((String) key);
106     }
107 
108     /**
109      * @see java.util.Map#containsValue(java.lang.Object)
110      */
111     public boolean containsValue(Object value) {
112         // not implemented, only get() is needed
113         return false;
114     }
115 
116     /**
117      * Shortcut for Content.getNodeData(name).getString() or Content.getNodeData(name).getName().
118      * @see java.util.Map#get(Object)
119      */
120     public Object get(Object key) {
121         try {
122             if (!getWrappedContent().hasNodeData((String) key)) {
123                 // support the old lower case value
124                 if ("uuid".equalsIgnoreCase((String) key)) {
125                     key = "UUID";
126                 }
127                 if (hasProperty((String) key)) {
128                     try {
129                         return PropertyUtils.getProperty(this.getWrappedContent(), (String) key);
130                     }
131                     catch (Exception e) {
132                         log.error("can't read property " + key + " from the node " + this.getWrappedContent(), e);
133                     }
134                 }
135             }
136         }
137         catch (RepositoryException e) {
138             // should really not happen
139             log.error("can't check for node data {" + key + "}", e);
140         }
141 
142         NodeData nodeData = getWrappedContent().getNodeData((String) key);
143         Object value;
144         int type = nodeData.getType();
145         if (type == PropertyType.DATE) {
146             value = nodeData.getDate();
147         }
148         else if (type == PropertyType.BINARY) {
149             // only file path is supported
150             FileProperties props = new FileProperties(getWrappedContent(), (String) key);
151             value = props.getProperty(FileProperties.PATH);
152         }
153         else if (nodeData.isMultiValue() == NodeData.MULTIVALUE_TRUE) {
154 
155             Value[] values = nodeData.getValues();
156 
157             String[] valueStrings = new String[values.length];
158 
159             for (int j = 0; j < values.length; j++) {
160                 try {
161                     valueStrings[j] = values[j].getString();
162                 }
163                 catch (RepositoryException e) {
164                     log.debug(e.getMessage());
165                 }
166             }
167 
168             value = valueStrings;
169         }
170         else {
171             try {
172                 value = info.magnolia.link.LinkUtil.convertLinksFromUUIDPattern(nodeData.getString(), LinkTransformerManager.getInstance().getBrowserLink(handle));
173             }
174             catch (LinkException e) {
175                 log.warn("Failed to parse links with from " + nodeData.getName(), e);
176                 value = nodeData.getString();
177             }
178         }
179         return value;
180     }
181 
182     protected boolean hasProperty(Object key) {
183         try {
184             return PropertyUtils.getPropertyDescriptor(this.getWrappedContent(), (String) key) != null;
185         }
186         catch (Exception e) {
187             return false;
188         }
189     }
190 
191     /**
192      * @see java.util.Map#put(java.lang.Object, java.lang.Object)
193      */
194     public Object put(Object arg0, Object arg1) {
195         // not implemented, only get() is needed
196         return null;
197     }
198 
199     /**
200      * @see java.util.Map#remove(java.lang.Object)
201      */
202     public Object remove(Object key) {
203         // not implemented, only get() is needed
204         return null;
205     }
206 
207     /**
208      * @see java.util.Map#putAll(java.util.Map)
209      */
210     public void putAll(Map t) {
211         // not implemented, only get() is needed
212     }
213 
214     /**
215      * @see java.util.Map#clear()
216      */
217     public void clear() {
218         // not implemented, only get() is needed
219     }
220 
221     /**
222      * @see java.util.Map#keySet()
223      */
224     public Set keySet() {
225         Collection nodeDataCollection = getWrappedContent().getNodeDataCollection();
226         Set keys = new HashSet();
227         for (Iterator iter = nodeDataCollection.iterator(); iter.hasNext();) {
228             keys.add(((NodeData) iter.next()).getName());
229         }
230 
231         return keys;
232     }
233 
234     /**
235      * @see java.util.Map#values()
236      */
237     public Collection values() {
238         Collection nodeDataCollection = getWrappedContent().getNodeDataCollection();
239         Collection values = new ArrayList();
240         for (Iterator iter = nodeDataCollection.iterator(); iter.hasNext();) {
241             values.add(((NodeData) iter.next()).getString());
242         }
243 
244         return values;
245     }
246 
247     /**
248      * @see java.util.Map#entrySet()
249      */
250     public Set entrySet() {
251         Collection nodeDataCollection = getWrappedContent().getNodeDataCollection();
252         Set keys = new HashSet();
253         for (Iterator iter = nodeDataCollection.iterator(); iter.hasNext();) {
254             NodeData nd = (NodeData) iter.next();
255             final String key = nd.getName();
256             final String value = nd.getString();
257             keys.add(new Map.Entry() {
258 
259                 public Object getKey() {
260                     return key;
261                 }
262 
263                 public Object getValue() {
264                     return value;
265                 }
266 
267                 public Object setValue(Object value) {
268                     return value;
269                 }
270             });
271         }
272 
273         return keys;
274     }
275 }