org.codehaus.cargo.container.weblogic.WebLogic9x10x103x12xConfigXmlInstalledLocalDeployer.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.cargo.container.weblogic.WebLogic9x10x103x12xConfigXmlInstalledLocalDeployer.java

Source

/*
 * ========================================================================
 *
 * Codehaus CARGO, copyright 2004-2011 Vincent Massol, 2012-2015 Ali Tokmen.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ========================================================================
 */
package org.codehaus.cargo.container.weblogic;

import java.io.File;
import java.util.List;

import org.codehaus.cargo.container.InstalledLocalContainer;
import org.codehaus.cargo.container.deployable.Deployable;
import org.codehaus.cargo.container.deployable.DeployableException;
import org.codehaus.cargo.container.deployable.DeployableType;
import org.codehaus.cargo.container.deployable.EAR;
import org.codehaus.cargo.container.deployable.WAR;
import org.codehaus.cargo.container.spi.deployer.AbstractInstalledLocalDeployer;
import org.codehaus.cargo.util.Dom4JUtil;
import org.codehaus.cargo.util.FileHandler;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;

/**
 * Static deployer that manages deployment configuration by manipulating the WebLogic config.xml
 * file.
 * 
 */
public class WebLogic9x10x103x12xConfigXmlInstalledLocalDeployer extends AbstractInstalledLocalDeployer {
    /**
     * used to manipulate the config.xml document.
     */
    private Dom4JUtil xmlTool;

    /**
     * XML namespace to use.
     */
    private String namespace;

    /**
     * {@inheritDoc}
     * 
     * @param container container to configure
     */
    public WebLogic9x10x103x12xConfigXmlInstalledLocalDeployer(InstalledLocalContainer container) {
        super(container);

        xmlTool = new Dom4JUtil();
        if (container instanceof WebLogic12xInstalledLocalContainer
                || container instanceof WebLogic121xInstalledLocalContainer) {
            namespace = "http://xmlns.oracle.com/weblogic/domain";
        } else {
            namespace = "http://www.bea.com/ns/weblogic/920/domain";
        }
        xmlTool.getNamespaces().put("weblogic", namespace);

        // using the same filehandler as the container will help pass unit tests
        FileHandler handler = container.getFileHandler();
        xmlTool.setFileHandler(handler);
    }

    /**
     * read the domain's config.xml file into a Document.
     * 
     * @return Document corresponding with config.xml
     */
    public Document readConfigXml() {
        String configFile = getConfigXmlPath();
        return xmlTool.loadXmlFromFile(configFile);
    }

    /**
     * Return the absolute path of the config.xml file.
     * 
     * @return path including config.xml
     */
    protected String getConfigXmlPath() {
        String configDir = getFileHandler().append(getDomainHome(), "config");
        String configFile = getFileHandler().append(configDir, "config.xml");
        return configFile;
    }

    /**
     * write the domain's config.xml to disk.
     * 
     * @param configXml document to write to disk
     */
    public void writeConfigXml(Document configXml) {
        String configFile = getConfigXmlPath();
        xmlTool.saveXml(configXml, configFile);
    }

    /**
     * get the DOMAIN_HOME of the server.
     * 
     * @return location to find files like config.xml
     */
    protected String getDomainHome() {
        return ((WebLogicConfiguration) getContainer().getConfiguration()).getDomainHome();
    }

    /**
     * {@inheritDoc} deploys files by adding their configuration to the config.xml file of the
     * WebLogic server.
     * 
     * @see org.codehaus.cargo.container.spi.deployer.AbstractDeployer#deploy(org.codehaus.cargo.container.deployable.Deployable)
     */
    @Override
    public void deploy(Deployable deployable) {
        Document configXml = readConfigXml();
        Element domain = configXml.getRootElement();
        addDeployableToDomain(deployable, domain);
        writeConfigXml(configXml);
    }

    /**
     * {@inheritDoc} undeploys files by removing their configuration to the config.xml file of the
     * WebLogic server.
     * 
     * @see org.codehaus.cargo.container.spi.deployer.AbstractDeployer#undeploy(org.codehaus.cargo.container.deployable.Deployable)
     */
    @Override
    public void undeploy(Deployable deployable) {
        Document configXml = readConfigXml();
        Element domain = configXml.getRootElement();
        removeDeployableFromDomain(deployable, domain);
        writeConfigXml(configXml);
    }

    /**
     * Remove the corresponding app-deployment element from the domain of the WebLogic server.
     * 
     * @param deployable - application component to remove
     * @param domain - Domain element of the WebLogic server
     */
    protected void removeDeployableFromDomain(Deployable deployable, Element domain) {
        // use contains in case there is whitespace
        List<Element> results = selectAppDeployments(deployable, domain);
        for (Element element : results) {
            domain.remove(element);
        }
    }

    /**
     * this will select the node(s) that match the below deployment.
     * 
     * @param deployable what to search for
     * @param domain root element to search in
     * @return list of child elements that match the deployment
     */
    protected List<Element> selectAppDeployments(Deployable deployable, Element domain) {
        String xpath = "//weblogic:app-deployment[weblogic:name/text()='" + createIdForDeployable(deployable)
                + "']";
        Element toSearch = domain;
        return xmlTool.selectElementsMatchingXPath(xpath, toSearch);
    }

    /**
     * Create and insert an app-deployment element into the domain of the WebLogic server. Ensure
     * that schema ordering is correct.
     * 
     * @param deployable - application component to configure
     * @param domain - Domain element of the WebLogic server
     */
    protected void addDeployableToDomain(Deployable deployable, Element domain) {
        createElementForDeployableInDomain(deployable, domain);
        reorderAppDeploymentsAfterConfigurationVersion(domain);
    }

    /**
     * create the config.xml element representing the Deployable. In WebLogic 9x, this is the
     * element app-deployment.
     * 
     * @param deployable to configure
     * @param domain root element of the config.xml file
     * @return app-deployment element
     */
    protected Element createElementForDeployableInDomain(Deployable deployable, Element domain) {
        QName appDeploymentQName = new QName("app-deployment", new Namespace("", namespace));
        Element appDeployment = domain.addElement(appDeploymentQName);
        String id = createIdForDeployable(deployable);
        // the name element is a unique identifier in the config.xml file. that's why this is being
        // named id as opposed to name
        Element appId = appDeployment.addElement("name");
        appId.setText(id);
        Element target = appDeployment.addElement("target");
        target.setText(getServerName());
        Element sourcePath = appDeployment.addElement("source-path");
        sourcePath.setText(getAbsolutePath(deployable));
        return appDeployment;
    }

    /**
     * Per current schema of the weblogic domain, app-deployment elements need to come directly
     * after the configuration-version element.
     * 
     * @param domain - domain to re-order
     */
    protected void reorderAppDeploymentsAfterConfigurationVersion(Element domain) {
        Element configurationVersion = xmlTool.selectElementMatchingXPath("weblogic:configuration-version", domain);

        List<Element> appDeployments = xmlTool.selectElementsMatchingXPath("weblogic:app-deployment", domain);

        List<Element> domainElements = domain.content();
        int indexOfConfigurationVersion = domainElements.indexOf(configurationVersion);

        domainElements.removeAll(appDeployments);
        domainElements.addAll(indexOfConfigurationVersion + 1, appDeployments);

    }

    /**
     * Get a string name for the configuration of this deployable. This should be XML friendly. For
     * example, the String returned will have no slashes or colons, and be as short as possible.
     * 
     * @param deployable used to construct the id
     * @return a string that can be used to name this configuration
     */
    protected String createIdForDeployable(Deployable deployable) {
        String name = null;
        // TODO this code should be moved into the deployable objects themselves, as they
        // are better responsible for their name.
        if (deployable.getType() == DeployableType.WAR) {
            name = ((WAR) deployable).getContext();
        } else if (deployable.getType() == DeployableType.EAR) {
            name = ((EAR) deployable).getName();
        } else if (deployable.getType() == DeployableType.EJB || deployable.getType() == DeployableType.RAR) {
            name = createIdFromFileName(deployable);
        } else {
            throw new DeployableException(
                    "name extraction for " + deployable.getType() + " not currently supported");
        }
        return name;
    }

    /**
     * Get a string name for the configuration of this deployable based on its filename.
     * 
     * @param deployable used to construct the id
     * @return a string that can be used to name this configuration
     */
    protected String createIdFromFileName(Deployable deployable) {
        File file = new File(deployable.getFile());
        return file.getName();
    }

    /**
     * return the running server's name.
     * 
     * @return the WebLogic server's name
     */
    protected String getServerName() {
        return getContainer().getConfiguration().getPropertyValue(WebLogicPropertySet.SERVER);
    }

    /**
     * gets the URI from a file. This is the basic filename. ex. web.war.
     * 
     * @param deployable - what to extract the uri from
     * @return - uri of the deployable
     */
    String getURI(Deployable deployable) {
        String path = deployable.getFile();
        return new File(path).getName();
    }

    /**
     * gets the absolute path from a file that may be relative to the current directory.
     * 
     * @param deployable - what to extract the file path from
     * @return - absolute path to the deployable
     */
    String getAbsolutePath(Deployable deployable) {
        String path = deployable.getFile();
        return getFileHandler().getAbsolutePath(path);
    }

}