Package org.apache.geronimo.deployment.plugin

Source Code of org.apache.geronimo.deployment.plugin.ConfigIDExtractor$ConfigIdHandler

/**
*
* Copyright 2005 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.deployment.plugin;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.util.Stack;
import java.util.Collection;
import java.util.List;
import java.util.LinkedList;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
import javax.enterprise.deploy.spi.TargetModuleID;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.kernel.repository.Artifact;
import org.apache.geronimo.kernel.repository.Version;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

/**
* Knows how to suck a Config ID out of a module and/or plan
*
* @version $Rev: 409817 $ $Date: 2006-05-27 09:56:38 +0200 (Sat, 27 May 2006) $
*/
public class ConfigIDExtractor {

    /**
     * Attempt to calculate the Geronimo ModuleID for a J2EE application
     * module.
     *
     * Given a File representing an archive (which may be a JAR file or a
     * directory laid out like a JAR file), identify it's J2EE module type
     * based on which (if any) deployment descriptor is present, and then look
     * for a Geronimo deployment plan in the usual place, and if one is found,
     * retrieve the configId from the Geronimo deployment plan.
     *
     * todo: Handle Spring and other weird deployment types?
     *
     * @param module A Jar file or directory representing a J2EE module
     * @return The configId in the Geronimo deployment plan for this module,
     *         or null if no Geronimo deployment plan was identified.
     */
    public static String extractModuleIdFromArchive(File module) throws IOException, DeploymentException {
        if(!module.canRead()) {
            throw new DeploymentException("Not a readable file ("+module.getAbsolutePath()+")");
        }
        if(module.isDirectory()) {
            File target;
            if(new File(module, "WEB-INF/web.xml").canRead()) {
                target = new File(module, "WEB-INF/geronimo-web.xml");
            } else if(new File(module, "META-INF/application.xml").canRead()) {
                target = new File(module, "META-INF/geronimo-application.xml");
            } else if(new File(module, "META-INF/ejb-jar.xml").canRead()) {
                target = new File(module, "META-INF/openejb-jar.xml");
            } else if(new File(module, "META-INF/ra.xml").canRead()) {
                target = new File(module, "META-INF/geronimo-ra.xml");
            } else if(new File(module, "META-INF/application-client.xml").canRead()) {
                target = new File(module, "META-INF/geronimo-application-client.xml");
            } else {
                target = new File(module, "META-INF/geronimo-service.xml");
            }
            if(target.canRead()) {
                Reader in = new BufferedReader(new FileReader(target));
                String name = extractModuleIdFromPlan(in);
                if(name != null) {
                    Artifact artifact = Artifact.create(name);
                    if(artifact.getArtifactId() == null) {
                        name = new Artifact(artifact.getGroupId(), module.getName(), artifact.getVersion(), artifact.getType()).toString();
                    }
                }
                return name;
            }
        } else {
            if(!isJarFile(module)) {
                throw new DeploymentException(module.getAbsolutePath()+" is neither a JAR file nor a directory!");
            }
            JarFile input = new JarFile(module);
            //todo: instead of looking for specific file names here, do something generic.
            //      Perhaps load a DConfigBeanRoot and look for a configId property on the first child,
            //      though that would probably be a little heavyweight.
            try {
                JarEntry entry;
                if(input.getJarEntry("WEB-INF/web.xml") != null) {
                    entry = input.getJarEntry("WEB-INF/geronimo-web.xml");
                } else if(input.getJarEntry("META-INF/application.xml") != null) {
                    entry = input.getJarEntry("META-INF/geronimo-application.xml");
                } else if(input.getJarEntry("META-INF/ejb-jar.xml") != null) {
                    entry = input.getJarEntry("META-INF/openejb-jar.xml");
                } else if(input.getJarEntry("META-INF/ra.xml") != null) {
                    entry = input.getJarEntry("META-INF/geronimo-ra.xml");
                } else if(input.getJarEntry("META-INF/application-client.xml") != null) {
                    entry = input.getJarEntry("META-INF/geronimo-application-client.xml");
                } else {
                    entry = input.getJarEntry("META-INF/geronimo-service.xml");
                }
                if(entry != null) {
                    Reader in = new BufferedReader(new InputStreamReader(input.getInputStream(entry)));
                    String name = extractModuleIdFromPlan(in);
                    if(name != null) {
                        Artifact artifact = Artifact.create(name);
                        if(artifact.getArtifactId() == null) {
                            name = new Artifact(artifact.getGroupId(), module.getName(), artifact.getVersion(), artifact.getType()).toString();
                        }
                    }
                    return name;
                }
            } finally {
                input.close();
            }
        }
        return null;
    }

    /**
     * Attempt to calculate the Geronimo ModuleID for a Geronimo deployment
     * plan.
     *
     * @param plan A Geronimo deployment plan (which must be an XML file).
     * @return The configId in the Geronimo deployment plan for this module.
     */
    public static String extractModuleIdFromPlan(File plan) throws IOException {
        if(plan.isDirectory() || !plan.canRead()) {
            throw new IllegalArgumentException(plan.getAbsolutePath()+" is not a readable XML file!");
        }
        Reader in = new BufferedReader(new FileReader(plan));
        return extractModuleIdFromPlan(in);
    }

    /**
     * Given a list of all available TargetModuleIDs and the name of a module,
     * find the TargetModuleIDs that represent that module.
     *
     * @param allModules  The list of all available modules
     * @param name        The module name to search for
     * @param fromPlan    Should be true if the module name was loaded from a
     *                    deployment plan (thus no group means the default
     *                    group) or false if the module name was provided by
     *                    the user (thus no group means any group).
     *
     * @throws DeploymentException If no TargetModuleIDs have that module.
     */
    public static Collection identifyTargetModuleIDs(TargetModuleID[] allModules, String name, boolean fromPlan) throws DeploymentException {
        List list = new LinkedList();
        int pos;
        if((pos = name.indexOf('|')) > -1) {
            String target = name.substring(0, pos);
            String module = name.substring(pos+1);
            Artifact artifact = Artifact.create(module);
            artifact = new Artifact(artifact.getGroupId() == null && fromPlan ? Artifact.DEFAULT_GROUP_ID : artifact.getGroupId(),
                    artifact.getArtifactId(), fromPlan ? (Version)null : artifact.getVersion(), artifact.getType());
            // First pass: exact match
            for(int i=0; i<allModules.length; i++) {
                if(allModules[i].getTarget().getName().equals(target) && artifact.matches(Artifact.create(allModules[i].getModuleID()))) {
                    list.add(allModules[i]);
                }
            }
        }
        if(!list.isEmpty()) {
            return list;
        }
        // second pass: module matches
        Artifact artifact;
        if (name.indexOf("/") > -1) {
            artifact = Artifact.create(name);
            artifact = new Artifact(artifact.getGroupId() == null && fromPlan ? Artifact.DEFAULT_GROUP_ID : artifact.getGroupId(),
                    artifact.getArtifactId(), fromPlan ? (Version)null : artifact.getVersion(), artifact.getType());
        } else {
            artifact = new Artifact(fromPlan ? Artifact.DEFAULT_GROUP_ID : null, name, (Version)null, null);
        }
        for(int i = 0; i < allModules.length; i++) {
            if(artifact.matches(Artifact.create(allModules[i].getModuleID()))) {
                list.add(allModules[i]);
            }
        }
        if(list.isEmpty()) {
            throw new DeploymentException(name+" does not appear to be a the name of a module " +
                    "available on the selected server. Perhaps it has already been " +
                    "stopped or undeployed?  If you're trying to specify a " +
                    "TargetModuleID, use the syntax TargetName|ModuleName instead. " +
                    "If you're not sure what's running, try the list-modules command.");
        }
        return list;
    }

    private static String extractModuleIdFromPlan(Reader plan) throws IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);
        try {
            SAXParser parser = factory.newSAXParser();
            ConfigIdHandler handler = new ConfigIdHandler();
            parser.parse(new InputSource(plan), handler);
            if(handler.formatIs10) {
                System.out.println("WARNING: Geronimo deployment plan uses Geronimo 1.0 syntax.  Please update to Geronimo 1.1 syntax when possible.");
            }
            return handler.configId;
        } catch (ParserConfigurationException e) {
            throw new IOException("Unable to read plan: "+e.getMessage());
        } catch (SAXException e) {
            throw new IOException("Unable to read plan: "+e.getMessage());
        } finally {
            plan.close();
        }
    }

    /**
     * Try to determine whether a file is a JAR File (or, at least, a ZIP file).
     */
    public static boolean isJarFile(File file) throws DeploymentException {
        if(file.isDirectory()) {
            return false;
        }
        if(!file.canRead()) {
            throw new DeploymentException("Cannot read file "+file.getAbsolutePath());
        }
        if(file.length() < 4) {
            return false;
        }
        try {
            DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            int test = in.readInt();
            in.close();
            return test == 0x504b0304;
        } catch(IOException e) {
            throw new DeploymentException("Cannot read from file "+file.getAbsolutePath(), e);
        }
    }

    private static class ConfigIdHandler extends DefaultHandler {
        private String configId;
        private boolean inConfigId;
        private String groupId = "", artifactId = "", version = "", type = "";
        private String inElement = null;
        private Stack parent = new Stack();
        private boolean formatIs10 = false;

        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if(inConfigId) {
                if(localName.equals("groupId") || localName.equals("artifactId") || localName.equals("version") || localName.equals("type")) {
                    inElement = localName;
                }
            } else {
                if(parent.size() == 2 && localName.equals("moduleId")) {
                    inConfigId = true; // only document/environment/configId, not e.g. configId in nested plan in EAR
                } else {
                    if(parent.size() == 0 && attributes.getIndex("moduleId") > -1) {
                        configId = attributes.getValue("moduleId");
                        formatIs10 = true;
                    }
                }
            }
            parent.push(localName);
        }

        public void characters(char ch[], int start, int length) throws SAXException {
            if(inElement != null) {
                formatIs10 = false;
                if(inElement.equals("groupId")) groupId += new String(ch, start, length);
                else if(inElement.equals("artifactId")) artifactId += new String(ch, start, length);
                else if(inElement.equals("version")) version += new String(ch, start, length);
                else if(inElement.equals("type")) type += new String(ch, start, length);
            }
        }

        public void endElement(String uri, String localName, String qName) throws SAXException {
            inElement = null;
            if(inConfigId && localName.equals("moduleId")) {
                inConfigId = false;
            }
            if(parent.peek().equals(localName)) {
                parent.pop();
            } else {
                throw new IllegalStateException("End of "+localName+" but expecting "+parent.peek());
            }
        }

        public void endDocument() throws SAXException {
            if(!formatIs10) {
                configId = groupId+"/"+artifactId+"/"+version+"/"+type;
            }
            if(configId.equals("///")) {
                configId = null;
            }
        }
    }
}
TOP

Related Classes of org.apache.geronimo.deployment.plugin.ConfigIDExtractor$ConfigIdHandler

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.