Package org.apache.geronimo.jetty.deployment

Source Code of org.apache.geronimo.jetty.deployment.WARConfigBuilder

/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
*  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.apache.geronimo.jetty.deployment;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.transaction.UserTransaction;
import javax.naming.NamingException;

import org.apache.geronimo.deployment.ConfigurationBuilder;
import org.apache.geronimo.deployment.DeploymentContext;
import org.apache.geronimo.deployment.DeploymentException;
import org.apache.geronimo.deployment.service.GBeanHelper;
import org.apache.geronimo.common.xml.XmlBeansUtil;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoFactory;
import org.apache.geronimo.gbean.jmx.GBeanMBean;
import org.apache.geronimo.jetty.JettyWebApplicationContext;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.repository.Repository;
import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
import org.apache.geronimo.naming.java.ComponentContextBuilder;
import org.apache.geronimo.naming.java.ReadOnlyContext;
import org.apache.geronimo.naming.jmx.JMXReferenceFactory;
import org.apache.geronimo.xbeans.geronimo.jetty.JettyGbeanType;
import org.apache.geronimo.xbeans.geronimo.jetty.JettyLocalRefType;
import org.apache.geronimo.xbeans.geronimo.jetty.JettyWebAppDocument;
import org.apache.geronimo.xbeans.geronimo.jetty.JettyWebAppType;
import org.apache.geronimo.xbeans.j2ee.EnvEntryType;
import org.apache.geronimo.xbeans.j2ee.WebAppDocument;
import org.apache.geronimo.xbeans.j2ee.WebAppType;
import org.apache.geronimo.common.xml.XmlBeansUtil;
import org.apache.geronimo.transaction.UserTransactionImpl;

import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;

/**
*
*
* @version $Revision: 1.19 $ $Date: 2004/04/23 03:08:28 $
*/
public class WARConfigBuilder implements ConfigurationBuilder {
    private final Repository repository;
    private final Kernel kernel;

    public WARConfigBuilder(Kernel kernel, Repository repository) {
        this.kernel = kernel;
        this.repository = repository;
    }

    public boolean canConfigure(XmlObject plan) {
        return plan instanceof JettyWebAppDocument || plan instanceof WebAppDocument;
    }

    public SchemaTypeLoader[] getTypeLoaders() {
        return new SchemaTypeLoader[]{XmlBeans.getContextTypeLoader()};
    }

    public XmlObject getDeploymentPlan(URL module) throws XmlException {
        try {
            URL moduleBase;
            if (module.toString().endsWith("/")) {
                moduleBase = module;
            } else {
                moduleBase = new URL("jar:" + module.toString() + "!/");
            }
            XmlObject plan = XmlBeansUtil.getXmlObject(new URL(moduleBase, "WEB-INF/geronimo-jetty.xml"), JettyWebAppDocument.type);
// todo needs generic web XMLBeans
//            if (plan == null) {
//                plan = getPlan(new URL(moduleBase, "WEB-INF/geronimo-web.xml"));
//            }
// todo should be able to deploy a naked WAR
//            if (plan == null) {
//                plan = getPlan(new URL(moduleBase, "WEB-INF/web.xml"), WebAppDocument.type);
//            }
            return plan;
        } catch (MalformedURLException e) {
            return null;
        }
    }


    public void buildConfiguration(File outfile, Manifest manifest, File module, XmlObject plan) throws IOException, DeploymentException {
        if (!module.isDirectory()) {
            FileInputStream in = new FileInputStream(module);
            try {
                buildConfiguration(outfile, manifest, in, plan);
                return;
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        WebAppType webApp = getDD(module);
        JettyWebAppType jettyWebApp = ((JettyWebAppDocument) plan).getWebApp();
        URI configID = getConfigID(jettyWebApp);
        URI parentID = getParentID(jettyWebApp);

        FileOutputStream fos = new FileOutputStream(outfile);
        try {
            JarOutputStream os = new JarOutputStream(new BufferedOutputStream(fos));
            DeploymentContext context = null;
            try {
                context = new DeploymentContext(os, configID, parentID, kernel);
            } catch (MalformedObjectNameException e) {
                throw new DeploymentException(e);
            }

            buildGBeanConfiguration(context, jettyWebApp, webApp, module.getAbsoluteFile().toURI());

            context.close();
            os.flush();
        } finally {
            fos.close();
        }
    }

    private WebAppType getDD(File module) throws IOException, DeploymentException {
        File dd = new File(module, "WEB-INF/web.xml");
        if (!(dd.exists() && dd.canRead())) {
            throw new DeploymentException("Cannot read WEB-INF/web.xml from module directory");
        }
        FileInputStream is = new FileInputStream(dd);
        try {
            try {
                WebAppDocument doc = (WebAppDocument) XmlBeansUtil.parse(new BufferedInputStream(is), WebAppDocument.type);
                return doc.getWebApp();
            } catch (XmlException e) {
                throw new DeploymentException("Unable to parse web.xml", e);
            }
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }

    public void buildConfiguration(File outfile, Manifest manifest, InputStream in, XmlObject plan) throws IOException, DeploymentException {
        WebAppType webApp = null;
        JettyWebAppType jettyWebApp = ((JettyWebAppDocument) plan).getWebApp();
        URI configID = getConfigID(jettyWebApp);
        URI parentID = getParentID(jettyWebApp);

        FileOutputStream fos = new FileOutputStream(outfile);
        JarInputStream module = null;
        try {
            module = new JarInputStream(new BufferedInputStream(in));
            JarOutputStream os = new JarOutputStream(new BufferedOutputStream(fos));
            DeploymentContext context = null;
            try {
                context = new DeploymentContext(os, configID, parentID, kernel);
            } catch (MalformedObjectNameException e) {
                throw new DeploymentException(e);
            }

            // add the warfile's content to the configuration
            URI warRoot = URI.create("war/");
            ZipEntry src;
            while ((src = module.getNextEntry()) != null) {
                URI target = warRoot.resolve(src.getName());
                if ("WEB-INF/web.xml".equals(src.getName())) {
                    byte[] buffer = getBytes(module);
                    context.addFile(target, new ByteArrayInputStream(buffer));
                    try {
                        WebAppDocument doc = (WebAppDocument) XmlBeansUtil.parse(new ByteArrayInputStream(buffer), WebAppDocument.type);
                        webApp = doc.getWebApp();
                    } catch (XmlException e) {
                        throw new DeploymentException("Unable to parse web.xml");
                    }
                } else {
                    context.addFile(target, module);
                }
            }

            if (webApp == null) {
                throw new DeploymentException("Did not find WEB-INF/web.xml in module");
            }

            buildGBeanConfiguration(context, jettyWebApp, webApp, warRoot);


            context.close();
            os.flush();
        } finally {
            if (module != null) {
                try {
                    module.close();
                } catch (IOException e) {
                    // ignore
                }
            }
            fos.close();
        }
    }

    private void buildGBeanConfiguration(DeploymentContext context, JettyWebAppType jettyWebApp, WebAppType webApp, URI warRoot) throws DeploymentException {
        // todo do we need to support include and dependency or can we rely on the parent?
        // add low-level GBean definitions to the config
//            addIncludes(context, configType);
//            addDependencies(context, configType.getDependencyArray());
        ClassLoader cl = context.getClassLoader(repository);

        JettyGbeanType[] gbeans = jettyWebApp.getGbeanArray();
        for (int i = 0; i < gbeans.length; i++) {
            GBeanHelper.addGbean(new JettyGBeanAdapter(gbeans[i]), cl, context);
        }


        // add the GBean for the web application
        addWebAppGBean(context, webApp, jettyWebApp, warRoot, cl);

        // todo do we need to add GBeans to make the servlets JSR77 ManagedObjects?
    }

    private void addWebAppGBean(DeploymentContext context, WebAppType webApp, JettyWebAppType jettyWebApp, URI warRoot, ClassLoader cl) throws DeploymentException {
        String contextRoot = jettyWebApp.getContextRoot().trim();
        if (contextRoot.length() == 0) {
            throw new DeploymentException("Missing value for context-root");
        }
        URI configID = context.getConfigID();

        Properties nameProps = new Properties();
        nameProps.put("J2EEServer", "null");
        nameProps.put("J2EEApplication", "null");
        nameProps.put("J2EEType", "WebModule");
        nameProps.put("ContextRoot", contextRoot);
        nameProps.put("Config", configID.toString());
        ObjectName name;
        try {
            name = new ObjectName("geronimo.jetty", nameProps);
        } catch (MalformedObjectNameException e) {
            throw new DeploymentException("Unable to construct ObjectName", e);
        }

        UserTransaction userTransaction = new UserTransactionImpl();
        ReadOnlyContext compContext = buildComponentContext(webApp, jettyWebApp, userTransaction, cl);

        GBeanMBean gbean = new GBeanMBean(JettyWebApplicationContext.GBEAN_INFO);
        try {
            gbean.setAttribute("URI", warRoot);
            gbean.setAttribute("ContextPath", contextRoot);
            gbean.setAttribute("ContextPriorityClassLoader", Boolean.valueOf(jettyWebApp.getContextPriorityClassloader()));
            gbean.setAttribute("PolicyContextID", null);
            gbean.setAttribute("ComponentContext", compContext);
            gbean.setAttribute("UserTransaction", userTransaction);
            gbean.setReferencePatterns("Configuration", Collections.singleton(ConfigurationManager.getConfigObjectName(configID)));
            gbean.setReferencePatterns("JettyContainer", Collections.singleton(new ObjectName("*:type=WebContainer,container=Jetty"))); // @todo configurable
            gbean.setReferencePatterns("TransactionManager", Collections.singleton(new ObjectName("*:type=TransactionManager,*")));
            gbean.setReferencePatterns("TrackedConnectionAssociator", Collections.singleton(new ObjectName("*:type=ConnectionTracker,*")));
        } catch (Exception e) {
            throw new DeploymentException("Unable to initialize webapp GBean", e);
        }
        context.addGBean(name, gbean);
    }

    private ReadOnlyContext buildComponentContext(WebAppType webApp, JettyWebAppType jettyWebApp, UserTransaction userTransaction, ClassLoader cl) throws DeploymentException {
        ComponentContextBuilder builder = new ComponentContextBuilder(new JMXReferenceFactory());
        if (userTransaction != null) {
            try {
                builder.addUserTransaction(userTransaction);
            } catch (NamingException e) {
                throw new DeploymentException("Unable to bind UserTransaction into ENC", e);
            }
        }

        EnvEntryType[] envEntries = webApp.getEnvEntryArray();
        ENCConfigBuilder.addEnvEntries(envEntries, builder);
        // todo ejb-ref
        // todo ejb-local-ref
        // todo resource-ref
        Map resourceRefMap = new HashMap();
        JettyLocalRefType[] jettyResourceRefs = jettyWebApp.getResourceRefArray();
        for (int i = 0; i < jettyResourceRefs.length; i++) {
            JettyLocalRefType jettyResourceRef = jettyResourceRefs[i];
            resourceRefMap.put(jettyResourceRef.getRefName(), new JettyRefAdapter(jettyResourceRef));
        }
        ENCConfigBuilder.addResourceRefs(webApp.getResourceRefArray(), cl, resourceRefMap, builder);
        // todo resource-env-ref
        Map resourceEnvRefMap = new HashMap();
        JettyLocalRefType[] jettyResourceEnvRefs = jettyWebApp.getResourceEnvRefArray();
        for (int i = 0; i < jettyResourceEnvRefs.length; i++) {
            JettyLocalRefType jettyResourceEnvRef = jettyResourceEnvRefs[i];
            resourceEnvRefMap.put(jettyResourceEnvRef.getRefName(), new JettyRefAdapter(jettyResourceEnvRef));
        }
        ENCConfigBuilder.addResourceEnvRefs(webApp.getResourceEnvRefArray(), cl, resourceEnvRefMap, builder);
        // todo message-destination-ref
        return builder.getContext();
    }


    private URI getParentID(JettyWebAppType jettyWebApp) throws DeploymentException {
        URI parentID;
        if (jettyWebApp.isSetParentId()) {
            try {
                parentID = new URI(jettyWebApp.getParentId());
            } catch (URISyntaxException e) {
                throw new DeploymentException("Invalid parentId " + jettyWebApp.getParentId(), e);
            }
        } else {
            parentID = null;
        }
        return parentID;
    }

    private URI getConfigID(JettyWebAppType jettyWebApp) throws DeploymentException {
        URI configID;
        try {
            configID = new URI(jettyWebApp.getConfigId());
        } catch (URISyntaxException e) {
            throw new DeploymentException("Invalid configId " + jettyWebApp.getConfigId(), e);
        }
        return configID;
    }

    private byte[] getBytes(InputStream is) throws IOException {
        byte[] buffer = new byte[4096];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int count;
        while ((count = is.read(buffer)) > 0) {
            baos.write(buffer, 0, count);
        }
        return baos.toByteArray();
    }

    public static final GBeanInfo GBEAN_INFO;

    static {
        GBeanInfoFactory infoFactory = new GBeanInfoFactory(WARConfigBuilder.class);
        infoFactory.addInterface(ConfigurationBuilder.class);
        infoFactory.addReference("Repository", Repository.class);
        infoFactory.addReference("Kernel", Kernel.class);
        infoFactory.setConstructor(
                new String[]{"Kernel", "Repository"},
                new Class[]{Kernel.class, Repository.class}
        );
        GBEAN_INFO = infoFactory.getBeanInfo();
    }

    public static GBeanInfo getGBeanInfo() {
        return GBEAN_INFO;
    }
}
TOP

Related Classes of org.apache.geronimo.jetty.deployment.WARConfigBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.