/* * 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.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.jboss.bootstrap.spi.ServerConfig; import org.jboss.deployers.spi.DeploymentException; import org.jboss.deployers.spi.deployer.managed.ManagedObjectCreator; import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.deployers.vfs.spi.deployer.JAXPDeployer; import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; import org.jboss.managed.api.ManagedObject; import org.jboss.managed.api.factory.ManagedObjectFactory; import org.jboss.managed.plugins.ManagedObjectImpl; import org.jboss.managed.plugins.factory.ManagedObjectFactoryBuilder; import org.jboss.system.metadata.ServiceDeployment; import org.jboss.system.metadata.ServiceDeploymentClassPath; import org.jboss.system.metadata.ServiceDeploymentParser; import org.jboss.system.metadata.ServiceMetaData; import org.jboss.system.metadata.ServiceMetaDataParser; import org.jboss.system.server.ServerConfigLocator; import org.jboss.util.xml.DOMWriter; import org.jboss.virtual.VFS; import org.jboss.virtual.VirtualFile; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * SARDeployer.<p> * * This deployer is responsible for looking for -service.xml * and creating the metadata object.<p> * * The {@link ServiceClassLoaderDeployer} and {@link ServiceDeployer} does the * real work of deployment. * * @author <a href="adrian@jboss.com">Adrian Brock</a> * @author Scott.Stark@jboss.org * @author <a href="ales.justin@jboss.com">Ales Justin</a> * @version $Revision: 106340 $ */ public class SARDeployer extends JAXPDeployer<ServiceDeployment> implements ManagedObjectCreator { /** The managed object factory. */ private static final ManagedObjectFactory factory = ManagedObjectFactoryBuilder.create(); /** * Create a new SARDeployer. * * @throws IllegalArgumentException for a null kernel */ public SARDeployer() { super(ServiceDeployment.class); setSuffix("-service.xml"); // Enable the super class ManagedObjectCreator implementation setBuildManagedObject(true); setAllowMultipleFiles(true); } /** * @param unit - the deployment unit * @param file - the vf for the jboss-service.xml descriptor * @param document - the jaxp document for the jboss-service.xml descriptor */ @Override protected ServiceDeployment parse(VFSDeploymentUnit unit, VirtualFile file, Document document) throws Exception { ServiceDeploymentParser parser = new ServiceDeploymentParser(document); ServiceDeployment parsed = parser.parse(); String name = file.toURI().toString(); parsed.setName(name); List<ServiceDeploymentClassPath> classPaths = parsed.getClassPaths(); if (classPaths != null) processXMLClasspath(unit, classPaths); List<ServiceMetaData> services = parsed.getServices(); if (services == null) { Element config = parsed.getConfig(); if (config == null) { log.debug("Service deployment has no services: " + parsed.getName()); return parsed; } 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 SMDparser = new ServiceMetaDataParser(config); services = SMDparser.parse(); parsed.setServices(services); } return parsed; } /** * Process the xml classpath * * @param unit the unit * @param classpaths the classpaths * @throws Exception for any error */ private void processXMLClasspath(VFSDeploymentUnit unit, List<ServiceDeploymentClassPath> classpaths) throws Exception { ArrayList<VirtualFile> classpath = new ArrayList<VirtualFile>(); for (ServiceDeploymentClassPath path : classpaths) { String codebase = path.getCodeBase(); String archives = path.getArchives(); log.debug("Processing classpath: " + unit.getName() + " codebase=" + codebase + " archives=" + archives); VirtualFile codebaseFile = unit.getRoot(); if (".".equals(codebase) == false) { ServerConfig config = ServerConfigLocator.locate(); URL codeBaseURL = new URL(config.getServerHomeURL(), codebase); codebaseFile = VFS.getRoot(codeBaseURL); } if (codebaseFile == null) throw new DeploymentException("Cannot use classpath without a root: " + unit.getName()); if (archives == null) { classpath.add(codebaseFile); log.debug("Using codebase as classpath: " + unit.getName()); } else { SARArchiveFilter filter = new SARArchiveFilter(archives); List<VirtualFile> archiveFiles = codebaseFile.getChildren(filter); classpath.addAll(archiveFiles); } } unit.prependClassPath(classpath); } 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; } /** * {@inheritDoc} * * handle multiple attachments * */ public void build(DeploymentUnit unit, Set<String> attachmentNames, Map<String, ManagedObject> managedObjects) throws DeploymentException { for(final Entry<String, Object> entry : unit.getAttachments().entrySet()) { final String key = entry.getKey(); if(ServiceDeployment.class.isInstance(entry.getValue())) { ManagedObject mo = managedObjects.get(key); if(mo == null) { // allowMultipleAttachments mo = factory.initManagedObject(entry.getValue(), null, unit.getMetaData(), key, null); if (mo != null) { if (mo instanceof ManagedObjectImpl) { ManagedObjectImpl.class.cast(mo).setAttachmentName(key); } managedObjects.put(key, mo); } } } } } }