/** * This file Copyright (c) 2010-2013 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.commands; import info.magnolia.commands.chain.Catalog; import info.magnolia.commands.chain.Chain; import info.magnolia.commands.chain.ChainBase; import info.magnolia.commands.chain.Command; import info.magnolia.jcr.node2bean.Node2BeanException; import info.magnolia.jcr.node2bean.PropertyTypeDescriptor; import info.magnolia.jcr.node2bean.TransformationState; import info.magnolia.jcr.node2bean.TypeDescriptor; import info.magnolia.jcr.node2bean.TypeMapping; import info.magnolia.jcr.node2bean.impl.Node2BeanTransformerImpl; import info.magnolia.objectfactory.Classes; import info.magnolia.objectfactory.ComponentProvider; import java.util.Iterator; import java.util.Map; import javax.jcr.Node; import javax.jcr.RepositoryException; import org.apache.commons.lang.StringUtils; /** * Command to transform old "impl" reference to implementing class to new "class" node data name for references. */ public class CommandTransformer extends Node2BeanTransformerImpl { private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CommandTransformer.class); private static final String DEPRECATED_CATALOG_NAME_NODE_DATA = "catalogName"; private static final String DEPRECATED_IMPL_NODE_DATA = "impl"; @Override protected TypeDescriptor onResolveType(TypeMapping typeMapping, TransformationState state, TypeDescriptor resolvedType, ComponentProvider componentProvider) { if(resolvedType != null){ return resolvedType; } Class klass = null; // default class to use if(state.getLevel() == 1){ klass = MgnlCatalog.class; } else{ Node node = state.getCurrentNode(); try { if(node.hasProperty(DEPRECATED_IMPL_NODE_DATA)){ log.warn("Rename '" + DEPRECATED_IMPL_NODE_DATA + "' to 'class' [" + node + "]!"); try { final String className = node.getProperty(DEPRECATED_IMPL_NODE_DATA).getString(); klass = Classes.getClassFactory().forName(className); } catch (ClassNotFoundException e) { klass = DelegateCommand.class; } } else{ // In case we are not yet building a concreate command we are creating a chain. // Otherwise we are building command properties boolean buildingCommand = false; for (int i = 0; i < state.getLevel() -1; i++) { TypeDescriptor td = state.peekType(i); if(isCommandClass(td.getType()) && !isChainClass(td.getType())){ buildingCommand = true; } } if(!buildingCommand){ klass = ChainBase.class; } } } catch (RepositoryException e) { log.error("Can't check " + DEPRECATED_IMPL_NODE_DATA + " nodedata [" + node + "]", e); } } if(klass != null){ return typeMapping.getTypeDescriptor(klass); } return resolvedType; } @Override public void initBean(TransformationState state, Map values) throws Node2BeanException { // we add the commands here (reflection does not work) if(state.getCurrentBean() instanceof Catalog){ Catalog catalog = (Catalog) state.getCurrentBean(); for (Iterator iter = values.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); if(values.get(name) instanceof Command){ Command command = (Command) values.get(name); if(!(command instanceof MgnlCommand) || ((MgnlCommand)command).isEnabled()){ catalog.addCommand(name, command); } } } } // support chains if(state.getCurrentBean() instanceof Chain){ Chain chain = (Chain) state.getCurrentBean(); for (Iterator iter = values.values().iterator(); iter.hasNext();) { Object value = iter.next(); if (value instanceof Command) { Command command = (Command) value; if(!(command instanceof MgnlCommand) || ((MgnlCommand)command).isEnabled()){ chain.addCommand(command); } } } } // support old way (using impl) of configuring delegate commands if(state.getCurrentBean() instanceof DelegateCommand){ DelegateCommand delegateCommand = (DelegateCommand) state.getCurrentBean(); if(StringUtils.isEmpty(delegateCommand.getCommandName())){ log.warn("You should define the commandName property on [{}]", state.getCurrentNode()); delegateCommand.setCommandName((String) values.get(DEPRECATED_IMPL_NODE_DATA)); } } super.initBean(state, values); } @Override public void setProperty(TypeMapping typeMapping, TransformationState state, PropertyTypeDescriptor descriptor, Map values) throws RepositoryException { Object bean = state.getCurrentBean(); if(bean instanceof MgnlCatalog){ MgnlCatalog catalog = (MgnlCatalog) bean; if(values.containsKey(DEPRECATED_CATALOG_NAME_NODE_DATA)){ log.warn("Rename the 'catalogName' nodedata to 'name' [" + state.getCurrentNode() + "]"); catalog.setName((String)values.get(DEPRECATED_CATALOG_NAME_NODE_DATA)); } if (!values.containsKey("name") && state.getCurrentNode().getName().equals("commands")) { try { catalog.setName(state.getCurrentNode().getParent().getName()); } catch (RepositoryException e) { log.error("Can't resolve catalog name by using parent node [" + state.getCurrentNode() + "]", e); } } } super.setProperty(typeMapping, state, descriptor, values); } protected boolean isCommandClass(Class<?> type) { return Command.class.isAssignableFrom(type); } protected boolean isChainClass(Class<?> type) { return Chain.class.isAssignableFrom(type); } }