/** * This file Copyright (c) 2008-2012 Magnolia International * Ltd. (http://www.magnolia-cms.com). All rights reserved. * * * This file is dual-licensed under both the Magnolia * Network Agreement and the GNU General Public License. * You may elect to use one or the other of these licenses. * * This file is distributed in the hope that it will be * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. * Redistribution, except as permitted by whichever of the GPL * or MNA you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or * modify this file under the terms of the GNU General * Public License, Version 3, as published by the Free Software * Foundation. You should have received a copy of the GNU * General Public License, Version 3 along with this program; * if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * 2. For the Magnolia Network Agreement (MNA), this file * and the accompanying materials are made available under the * terms of the MNA which accompanies this distribution, and * is available at http://www.magnolia-cms.com/mna.html * * Any modifications to this file must keep this entire header * intact. * */ package info.magnolia.cms.util; import info.magnolia.cms.beans.runtime.FileProperties; import info.magnolia.cms.core.Content; import info.magnolia.cms.core.NodeData; import info.magnolia.link.LinkException; import info.magnolia.link.LinkTransformerManager; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Value; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wrapper for a content Node which exposes a Map interface, used to access its content using jstl. * @author fguist * @version $Revision: 2161 $ ($Author: fgiust $) */ public class NodeMapWrapper extends ContentWrapper implements Map { private static final Logger log = LoggerFactory.getLogger(NodeMapWrapper.class); /** * Handle used to construct links. */ private final String handle; /** * Instantiates a new NodeMapWrapper for the given node. * @param node Content node * @param handle Parent page handle or other prefix for links. */ public NodeMapWrapper(Content node, String handle) { super(node); this.handle = handle; } @Override protected Content wrap(Content node) { return new NodeMapWrapper(node, handle); } /** * @see java.util.Map#size() */ @Override public int size() { return getWrappedContent().getNodeDataCollection().size(); } /** * @see java.util.Map#isEmpty() */ @Override public boolean isEmpty() { return getWrappedContent().getNodeDataCollection().isEmpty(); } /** * @see java.util.Map#containsKey(java.lang.Object) */ @Override public boolean containsKey(Object key) { return this.getWrappedContent().getNodeData((String) key).isExist() || hasProperty(key); } /** * @see java.util.Map#containsValue(java.lang.Object) */ @Override public boolean containsValue(Object value) { // not implemented, only get() is needed return false; } /** * Shortcut for Content.getNodeData(name).getString() or Content.getNodeData(name).getName(). * @see java.util.Map#get(Object) */ @Override public Object get(Object key) { try { if (!getWrappedContent().hasNodeData((String) key)) { // support the old lower case value if ("uuid".equalsIgnoreCase((String) key)) { key = "UUID"; } if (hasProperty(key)) { try { return PropertyUtils.getProperty(this.getWrappedContent(), (String) key); } catch (Exception e) { log.error("can't read property " + key + " from the node " + this.getWrappedContent(), e); } } } } catch (RepositoryException e) { // should really not happen log.error("can't check for node data {" + key + "}", e); } NodeData nodeData = getWrappedContent().getNodeData((String) key); Object value; int type = nodeData.getType(); if (type == PropertyType.DATE) { value = nodeData.getDate(); } else if (type == PropertyType.BINARY) { // only file path is supported FileProperties props = new FileProperties(getWrappedContent(), (String) key); value = props.getProperty(FileProperties.PATH); } else if (nodeData.isMultiValue() == NodeData.MULTIVALUE_TRUE) { Value[] values = nodeData.getValues(); String[] valueStrings = new String[values.length]; for (int j = 0; j < values.length; j++) { try { valueStrings[j] = values[j].getString(); } catch (RepositoryException e) { log.debug(e.getMessage()); } } value = valueStrings; } else { try { value = info.magnolia.link.LinkUtil.convertLinksFromUUIDPattern(nodeData.getString(), LinkTransformerManager.getInstance().getBrowserLink(handle)); } catch (LinkException e) { log.warn("Failed to parse links with from " + nodeData.getName(), e); value = nodeData.getString(); } } return value; } protected boolean hasProperty(Object key) { try { return PropertyUtils.getPropertyDescriptor(this.getWrappedContent(), (String) key) != null; } catch (Exception e) { return false; } } /** * @see java.util.Map#put(java.lang.Object, java.lang.Object) */ @Override public Object put(Object arg0, Object arg1) { // not implemented, only get() is needed return null; } /** * @see java.util.Map#remove(java.lang.Object) */ @Override public Object remove(Object key) { // not implemented, only get() is needed return null; } /** * @see java.util.Map#putAll(java.util.Map) */ @Override public void putAll(Map t) { // not implemented, only get() is needed } /** * @see java.util.Map#clear() */ @Override public void clear() { // not implemented, only get() is needed } /** * @see java.util.Map#keySet() */ @Override public Set<String> keySet() { Collection<NodeData> nodeDataCollection = getWrappedContent().getNodeDataCollection(); Set<String> keys = new HashSet<String>(); for (Iterator<NodeData> iter = nodeDataCollection.iterator(); iter.hasNext();) { keys.add(iter.next().getName()); } return keys; } /** * @see java.util.Map#values() */ @Override public Collection<String> values() { Collection<NodeData> nodeDataCollection = getWrappedContent().getNodeDataCollection(); Collection<String> values = new ArrayList<String>(); for (Iterator<NodeData> iter = nodeDataCollection.iterator(); iter.hasNext();) { values.add((iter.next()).getString()); } return values; } /** * @see java.util.Map#entrySet() */ @Override public Set entrySet() { Collection<NodeData> nodeDataCollection = getWrappedContent().getNodeDataCollection(); Set<Map.Entry> keys = new HashSet<Map.Entry>(); for (Iterator<NodeData> iter = nodeDataCollection.iterator(); iter.hasNext();) { NodeData nd = iter.next(); final String key = nd.getName(); final String value = nd.getString(); keys.add(new Map.Entry() { @Override public Object getKey() { return key; } @Override public Object getValue() { return value; } @Override public Object setValue(Object value) { return value; } }); } return keys; } }