/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.system.deployers; import java.util.List; import javax.management.ObjectName; import org.jboss.deployers.spi.DeploymentException; import org.jboss.deployers.spi.deployer.helpers.AbstractComponentDeployer; import org.jboss.deployers.spi.deployer.helpers.DeploymentVisitor; import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.system.metadata.ServiceDeployment; import org.jboss.system.metadata.ServiceMetaData; import org.jboss.system.metadata.ServiceMetaDataParser; import org.jboss.util.xml.DOMWriter; import org.w3c.dom.Element; /** * ServiceDeployer.<p> * * This deployer is responsible for deploying services of * type {@link ServiceDeployment}. * * @author <a href="adrian@jboss.com">Adrian Brock</a> * @version $Revision: 85945 $ */ public class ServiceDeploymentDeployer extends AbstractComponentDeployer<ServiceDeployment, ServiceMetaData> { /** * Create a new ServiceDeploymentDeployer. */ public ServiceDeploymentDeployer() { setDeploymentVisitor(new ServiceDeploymentVisitor()); setComponentVisitor(new ServiceMetaDataVisitor()); } protected static void addServiceComponent(DeploymentUnit unit, ServiceMetaData service) { ObjectName objectName = service.getObjectName(); String name = objectName.getCanonicalName(); DeploymentUnit component = unit.addComponent(name); component.addAttachment(ServiceMetaData.class.getName(), service); } protected static void removeServiceComponent(DeploymentUnit unit, ServiceMetaData service) { ObjectName objectName = service.getObjectName(); String name = objectName.getCanonicalName(); unit.removeComponent(name); } /** * ServiceDeploymentVisitor. */ public class ServiceDeploymentVisitor implements DeploymentVisitor<ServiceDeployment> { public Class<ServiceDeployment> getVisitorType() { return ServiceDeployment.class; } public void deploy(DeploymentUnit unit, ServiceDeployment deployment) throws DeploymentException { try { List<ServiceMetaData> services = deployment.getServices(); if (services == null) { Element config = deployment.getConfig(); if (config == null) { log.debug("Service deployment has no services: " + deployment.getName()); return; } if (log.isDebugEnabled()) { String docStr = DOMWriter.printNode(config, true); int index = docStr.toLowerCase().indexOf("password"); if (index != -1) { docStr = maskPasswords(docStr, index); } log.debug(docStr); } ServiceMetaDataParser parser = new ServiceMetaDataParser(config); services = parser.parse(); deployment.setServices(services); } if (services == null || services.isEmpty()) return; for (ServiceMetaData service : services) addServiceComponent(unit, service); } catch (Throwable t) { throw DeploymentException.rethrowAsDeploymentException("Error deploying: " + deployment.getName(), t); } } public void undeploy(DeploymentUnit unit, ServiceDeployment deployment) { List<ServiceMetaData> services = deployment.getServices(); if (services == null) return; for (ServiceMetaData service : services) { ObjectName objectName = service.getObjectName(); String name = objectName.getCanonicalName(); unit.removeComponent(name); } } } /** * ServiceMetaDataVisitor. */ public static class ServiceMetaDataVisitor implements DeploymentVisitor<ServiceMetaData> { public Class<ServiceMetaData> getVisitorType() { return ServiceMetaData.class; } public void deploy(DeploymentUnit unit, ServiceMetaData deployment) throws DeploymentException { addServiceComponent(unit, deployment); } public void undeploy(DeploymentUnit unit, ServiceMetaData deployment) { removeServiceComponent(unit, deployment); } } /** * Masks passwords so they are not visible in the log. * * @param original <code>String</code> plain-text passwords * @param index index where the password keyword was found * @return modified <code>String</code> with masked passwords */ private String maskPasswords(String original, int index) { StringBuilder sb = new StringBuilder(original); String modified = null; int startPasswdStringIndex = sb.indexOf(">", index); if (startPasswdStringIndex != -1) { // checks if the keyword 'password' was not in a comment if (sb.charAt(startPasswdStringIndex - 1) != '-') { int endPasswdStringIndex = sb.indexOf("<", startPasswdStringIndex); if (endPasswdStringIndex != -1) // shouldn't happen, but check anyway { sb.replace(startPasswdStringIndex + 1, endPasswdStringIndex, "****"); } } modified = sb.toString(); // unlikely event of more than one password index = modified.toLowerCase().indexOf("password", startPasswdStringIndex); if (index != -1) return maskPasswords(modified, index); return modified; } return original; } }