PackageManager.java :  » Content-Management-System » contelligent » de » finix » contelligent » core » Java Open Source

Java Open Source » Content Management System » contelligent 
contelligent » de » finix » contelligent » core » PackageManager.java
/*
 * Copyright 2001-2006 C:1 Financial Services GmbH
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License Version 2.1, as published by the Free Software Foundation.
 *
 * 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
 */

package de.finix.contelligent.core;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.impl.Log4JCategoryLog;
import org.xml.sax.SAXException;

import de.finix.contelligent.CallData;
import de.finix.contelligent.Component;
import de.finix.contelligent.ComponentManager;
import de.finix.contelligent.ComponentNotFoundException;
import de.finix.contelligent.ComponentPath;
import de.finix.contelligent.Contelligent;
import de.finix.contelligent.Type;
import de.finix.contelligent.category.CategoryManager;
import de.finix.contelligent.exception.ComponentPersistenceException;
import de.finix.contelligent.exception.ComponentSystemException;
import de.finix.contelligent.exception.ContelligentException;
import de.finix.contelligent.logging.LoggingService;
import de.finix.contelligent.persistence.PackageManagerPersistenceAdapter;
import de.finix.contelligent.util.FileUtils;
import de.finix.contelligent.util.StringUtils;
import de.finix.contelligent.xml.DTDCatalog;
import de.finix.contelligent.xml.EchoingErrorHandler;
import de.finix.contelligent.xml.digester.PackageRuleSet;
import de.finix.contelligent.xml.elements.PackageElement;
import de.finix.contelligent.xml.elements.PackageImportElement;
import de.finix.contelligent.xml.elements.PackageRequiresElement;
import de.finix.contelligent.xml.export.ComponentXMLWriter;
import de.finix.contelligent.xml.export.DefaultComponentXMLPolicy;
import de.finix.contelligent.xml.export.LocalXMLExport;
import de.finix.contelligent.xml.export.PackageXMLWriter;

/**
 * Handles the import of Contelligent packages and acts as
 * {@link CategoryManager}. This implementation is NOT synchronized. Currently
 * packages can not be added or removed at runtime but only once and for all
 * after the creation of the <code>PackageManager</code>. Thus
 * synchronization is not an issue.
 */
class PackageManager {
    final static org.apache.log4j.Logger log = LoggingService.getLogger(PackageManager.class);

    public final static String PKG_RESOURCE_PREFIX = "META-INF/";

    PackageManagerPersistenceAdapter persistence;

    private URL[] packageURLs;

    final ContelligentImpl contelligent;

    private Set packageNames = new HashSet();

    private SystemState systemState;

    private Set resourceBundlePackages = new HashSet();

    PackageManager(ContelligentImpl contelligent, PackageManagerPersistenceAdapter persistence, URL[] packageURLs)
            throws Exception {
        this.contelligent = contelligent;
        this.persistence = persistence;
        this.packageURLs = packageURLs;
        Object[] tmp = getConfiguredPackages();
        Collection pkgs = (Collection) tmp[0]; // contains PackageElement
        // instances
        Map nameToURL = (Map) tmp[1]; // contains (String,URL) entries

        systemState = new SystemState(persistence, pkgs, nameToURL);
    }

    Set getResourceBundleNames() {
        return systemState.getResourceBundleNames();
    }

    CategoryManager getCategoryManager() {
        return contelligent.getCategoryManager();
    }

    String installedPackagesXML() {
        return systemState.installedPackagesXML();
    }

    /**
     * Update the system so that all packages listed in the configuration are
     * installed. A separate transaction is used per package.
     */
    void updatePackages() throws ContelligentException {
        try {
            systemState.processTransition(contelligent);
        } catch (PackageException e) {
            throw e;
        } catch (ContelligentException e) {
            throw e;
        } catch (Exception e) {
            throw new PackageException(e);
        }
    }

    // overwritten by ExplodedPackageManager
    /**
     * Returns the path to use when creating a {@link ComponentManager} for
     * import. This value gets passed to
     * {@link ComponentManagerHierarchy#createImportManager} which creates a
     * local file-adapter using this directory as repository.
     * 
     * @return a <code>String</code> value
     */
    protected String getBinaryPath() {
        return null;
    }

    // overwritten by ExplodedPackageManager
    /**
     * Returns whether to include file-adapters when destroying the
     * import-manager. This value gets passed to
     * {@link ComponentManagerHierarchy#destroyComponentManager}.
     * 
     * @return a <code>boolean</code> value
     */
    protected boolean getDestroyFileAdapters() {
        return true;
    }

    void exportPackage(String pkgName, File exportDir, boolean recalcRequires, boolean majorChange,
            boolean autoArchive, CallData callData) throws IOException, ContelligentException {
        File pkgResourceDir = new File(exportDir, PKG_RESOURCE_PREFIX);
        LocalXMLExport export = new LocalXMLExport(pkgResourceDir);
        File filesDir = export.getFilesDir();
        File typesDir = export.getTypesDir();
        File componentsDir = export.getComponentsDir();
        ComponentManager componentManager = callData.getActualManager();
        boolean debugEnabled = log.isDebugEnabled();

        Object[] tmp = getConfiguredPackages();
        Collection pkgElements = (Collection) tmp[0]; // contains
        // PackageElement
        // instances
        Map nameURLMapping = (Map) tmp[1]; // contains (String,URL) entries
        if (!nameURLMapping.containsKey(pkgName)) {
            log.error("exportPackage() - a package '" + pkgName + "' does not exist.");
            throw new PackageException("A package '" + pkgName + "' does not exist.");
        }
        URL pkgURL = (URL) nameURLMapping.get(pkgName);
        Iterator pkgs = pkgElements.iterator();

        // XXX: BAD HACK - do this right
        // build the package info from DB persistence only. don't
        // use the maybe not uptodate package descriptor from the deploy dir
        PackageElement pkgElement = null;
        while (pkgs.hasNext()) {
            pkgElement = (PackageElement) pkgs.next();
            if (pkgElement.getName().equals(pkgName)) {
                break;
            }
        }
        if (pkgElement == null) {
            throw new PackageException("A package '" + pkgName + "' does not exist.");
        }
        // Because of Bad Hack!! Update Version Number from Persistence Store so
        // increase will
        // operate on current version number
        synchPersistentVersionToPackageElement(pkgElement);

        File typesFile = new File(typesDir, "types.xml");
        Writer writer = null;
        try {
            if (debugEnabled) {
                log.debug("exportPackage() - writing types matching prefix '" + pkgName + "' to file '" + typesFile
                        + "' ...");
            }
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(typesFile), "UTF-8"));
            componentManager.exportTypes(writer, false, pkgName+".");
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (Exception e) {
                    log.warn("exportPackage() - exception while closing writer: ", e);
                }
            }
        }
        PackageImportElement typesElement = new PackageImportElement();
        /*
         * maybe i am wrong, but the File.separator seems to be incorrect here:
         * we need the '/'-character inside the package.xml file. With Windows,
         * we do get a '\' here, and the import fails F.Florey, 12.03 was:
         * typesElement.setFileName(typesDir.getName() + File.separator +
         * typesFile.getName());
         * 
         * !!! update alex: WE NEED THE File.separator, since we want to set the
         * FileName. The conversion should be done when the text is written as a
         * jar path.
         */
        typesElement.setFileName(typesDir.getName() + File.separator + typesFile.getName());
        List typesList = pkgElement.getTypes();
        typesList.clear();
        typesList.add(typesElement);

        // now export components of package and any homes associated with
        // principal-groups of this package
        List pathsToExport = getPackagePaths(pkgName);

        List componentsList = pkgElement.getComponents();
        componentsList.clear();
        Iterator paths = pathsToExport.iterator();
        while (paths.hasNext()) {
            ComponentPath path = (ComponentPath) paths.next();
            File componentsFile = new File(componentsDir, path.getName() + ".xml");
            int k = 1;
            while (componentsFile.exists()) {
                componentsFile = new File(componentsDir, path.getName() + (k++) + ".xml");
            }
            writer = null;
            try {
                if (debugEnabled) {
                    log.debug("exportPackage() - writing components starting with path '" + path + "' to file '"
                            + componentsFile + "' ...");
                }
                Component comp = componentManager.getComponent(path, callData);
                writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(componentsFile), "UTF-8"));
                ComponentXMLWriter xmlWriter = new ComponentXMLWriter(writer, new DefaultComponentXMLPolicy(
                        componentManager, filesDir));
                xmlWriter.write(comp);
                // append to package-descriptor:
                PackageImportElement componentsElement = new PackageImportElement();
                componentsElement.setFileName(componentsDir.getName() + File.separator + componentsFile.getName());
                componentsList.add(componentsElement);
            } catch (ComponentNotFoundException e) {
                log.warn("exportPackage() - could not find component '" + path + "' to export of package '" + pkgName
                        + "'!");
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (Exception e) {
                        log.warn("exportPackage() - Exception while closing writer: ", e);
                    }
                }
            }
        }

        if (recalcRequires) {

            Set relationPackageNames = new HashSet();
            // aggregate used references in exported trees!!
            Iterator i = pathsToExport.iterator();
            Set allTypes = new HashSet();
            Set externalRelations = new HashSet();

            while (i.hasNext()) {
                ComponentPath path = (ComponentPath) i.next();
                Collection typesInSubTree = getTypesInSubTree(path, callData);
                Collection subTreeRelations = getSubTreeRelations(path, callData);
                Collection relationsNotInPackage = extractExternalRelations(subTreeRelations, pathsToExport, callData);
                allTypes.addAll(typesInSubTree);
                externalRelations.addAll(relationsNotInPackage);
            }

            // now get all package names
            i = externalRelations.iterator();

            while (i.hasNext()) {
                ComponentPath path = (ComponentPath) i.next();
                PackageElement pkg = getPackageElementByPath(path);
                if (pkg != null) {
                    relationPackageNames.add(pkg.getName());
                } else {
                    log
                            .warn("exportPackage() - dependency on component without package from within package: externalResource not found : "
                                    + path);
                }
            }

            Map map = buildTypeNameToPackageNameMap();

            // extract packageNames from referenced and derived types
            i = allTypes.iterator();
            while (i.hasNext()) {
                Type type = (Type) i.next();

                String pName = (String) map.get(type.getName());
                if (!pkgName.equals(pName)) {
                    relationPackageNames.add(pName);
                } else {
                    while (pkgName.equals(pName)) {
                        type = type.getSuperType();
                        if (type == null) {
                            pName = null;
                            break;
                        }
                        pName = (String) map.get(type.getName());
                    }

                    // if a type in hierachy is found that is not from
                    // this package, it is a related type: therefore the
                    // containing package is added to the related packages
                    if (type != null) {
                        relationPackageNames.add(pName);
                    }
                }
            }

            i = relationPackageNames.iterator();
            List updatedPackageRequiresList = new LinkedList();

            while (i.hasNext()) {
                String tmpS = (String) i.next();
                PackageElement relatedPackage = getPackageElementByName(tmpS);
                PackageRequiresElement element = new PackageRequiresElement();
                element.setPackage(relatedPackage.getName());
                element.setVersion(">=" + relatedPackage.getVersion());
                updatedPackageRequiresList.add(element);
            }

            List oldList = pkgElement.updateRequiredPackages(updatedPackageRequiresList);
            log.info("exportPackage() - updated dependency package requires list old=" + oldList + "  new="
                    + updatedPackageRequiresList);

            // update version & persist version + requirements
            increaseVersionAndStorePackageData(pkgElement, majorChange);
            systemState.updatePackageVersionFromPackageElement(pkgElement);
        }

        File pkgFile = new File(pkgResourceDir, "package.xml");
        writer = null;
        String[] files = null;
        try {
            if (debugEnabled)
                log.debug("exportPackage() - writing package.xml to file '" + pkgFile + "' ...");
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(pkgFile), "UTF-8"));
            files = new PackageXMLWriter().writePackageElement(pkgElement, writer);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (Exception e) {
                    log.warn("exportPackage() - Exception while closing writer: ", e);
                }
            }
        }
        if (files != null && files.length > 0) {
            if (debugEnabled)
                log.debug("exportPackage() - additional files to export [" + StringUtils.createCSV(files, ',')
                        + "] ...");
            for (int i = 0; i < files.length; i++) {
                File file = new File(pkgResourceDir, files[i]);
                file.getParentFile().mkdirs();
                log.debug("exportPackage() - ... processing file '" + file + "' ...");
                InputStream in = getPackageResourceStream(pkgURL, PKG_RESOURCE_PREFIX + files[i]);
                if (in == null) {
                    log.error("exportPackage() - resource for file '" + file + "' not found! (ignored)");
                } else {
                    try {
                        FileUtils.copy(in, file);
                    } finally {
                        try {
                            in.close();
                        } catch (Exception e) {
                            log.warn("exportPackage() - Exception while closing InputStream: ", e);
                        }
                    }
                }
            }
        }

        // now copy all classes: Note that this is only possible if we have a
        // JarFile, with a mere URL
        // we can't list all possible resources!
        URLConnection con = pkgURL.openConnection();
        JarFile jarFile = null;

        try {
            if (!(con instanceof JarURLConnection)) {
                URL jarURL = new URL("jar:" + pkgURL + "!/");
                JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection();
                jarFile = jarCon.getJarFile();
            } else {
                jarFile = ((JarURLConnection) con).getJarFile();
            }
            log.debug("exportPackage() - ... processing JAR file '" + jarFile.getName() + "' ...");
            Enumeration entries = jarFile.entries();

            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                if (!entry.isDirectory() && !entry.getName().startsWith(PKG_RESOURCE_PREFIX)) {
                    File file = new File(exportDir, entry.getName());
                    if (debugEnabled) {
                        log.debug("exportPackage() - ... copying entry '" + entry + "' to file '" + file + "' ...");
                    }
                    file.getParentFile().mkdirs();
                    InputStream in = null;
                    try {
                        in = jarFile.getInputStream(entry);
                        FileUtils.copy(in, file);
                    } finally {
                        try {
                            in.close();
                        } catch (Exception e) {
                            log.warn("exportPackage() - Exception while closing InputStream: ", e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("exportPackage() - Exception while copying classes of package '" + pkgName + "': " + e);
            throw new ContelligentException("Exception while copying classes of package '" + pkgName + "'!", e);
        }

        if (autoArchive) {
            String archiveFile = new File(exportDir.getParent(), pkgName + ".cpkg").getPath();
            String command = "jar cf " + archiveFile + " -C " + exportDir.getPath() + " . ";
            try {
                Process process = Runtime.getRuntime().exec(command);
                int returnCode = process.waitFor();
            } catch (InterruptedException e1) {
                throw new ContelligentException("Executing jar command '" + command + "' interrupted !", e1);
            }
        }

        log.info("exportPackage() - successfully exported package '" + pkgName + "' to directory '" + exportDir + "'!");
    }

    /**
     * this synchs the version of the package Element given with the version in
     * persistence store. It will always overwrite the version number given in
     * pkgElement with the version in store. Not v.v.
     * 
     * Note: this is part of a bad hack!! Hopefully this will be gone, but maybe
     * this will produce pkgElements from persistence store!!
     * 
     * @param pkgElement
     */
    private void synchPersistentVersionToPackageElement(PackageElement pkgElement) throws ComponentPersistenceException {
        String pkgName = pkgElement.getName();
        Map map = persistence.getPackageInfo();
        String version = (String) map.get(pkgName);
        pkgElement.setVersion(version);
    }

    /**
     * @param pkgElement
     * @param majorChange
     */
    private void increaseVersionAndStorePackageData(PackageElement pkgElement, boolean majorChange)
            throws ComponentPersistenceException {
        String oldVersion = pkgElement.getVersion();

        // keep in mind: this should work with X.X and X.X.X versionnumbers.
        String majorVersion = "0";
        String minorVersion = "0";
        String microVersion = "0"; 

        // cut out major-version
        if (oldVersion.indexOf(".") > -1) {
            majorVersion = oldVersion.substring(0, oldVersion.indexOf("."));
            oldVersion = oldVersion.substring(oldVersion.indexOf(".") + 1);
        } else if (oldVersion.length() > 0) {
            majorVersion = oldVersion;
            oldVersion = "";
        }

        // cut out minor-version
        if (oldVersion.indexOf(".") > -1) {
            minorVersion = oldVersion.substring(0, oldVersion.indexOf("."));
            oldVersion = oldVersion.substring(oldVersion.indexOf(".") + 1);
        } else if (oldVersion.length() > 0) {
            minorVersion = oldVersion;
            oldVersion = "";
        }

        // cut out micro-version
        if (oldVersion.length() > 0) {
            microVersion = oldVersion;
            oldVersion = "";
        }

        if (majorChange) {
            int majV = Integer.parseInt(majorVersion);
            majV++;
            majorVersion = "" + majV;

            // reset minorVersion
            minorVersion = "0";
            microVersion = "0";
        } else {
            int minV = Integer.parseInt(microVersion);
            minV++;
            microVersion = "" + minV;
        }

        pkgElement.setVersion(majorVersion + "." + minorVersion + "." + microVersion);

        persistence.storePackageInfo(pkgElement.getName(), pkgElement.getVersion(), pkgElement.getDisplayName(),
                pkgElement.getProvider(), pkgElement.isReadOnly());
        persistence.storePackageRequirements(pkgElement.getName(), pkgElement.getRequirementsMap());

    }

    /**
     * @return
     */
    private Map buildTypeNameToPackageNameMap() throws PackageException {
        Map typeName2PackageName = new HashMap();
        Iterator i = getConfiguredPackageElements().iterator();

        while (i.hasNext()) {
            PackageElement elem = (PackageElement) i.next();
            List types = contelligent.getComponentFactory().getTypesFromPackage(elem.getName());
            Iterator j = types.iterator();
            while (j.hasNext()) {
                Type type = (Type) j.next();
                typeName2PackageName.put(type.getName(), elem.getName());
            }
        }
        return typeName2PackageName;
    }

    public PackageElement getPackageElementByPath(ComponentPath componentPath) throws PackageException {

        Collection pkgElements = getConfiguredPackageElements();

        Iterator i = pkgElements.iterator();

        while (i.hasNext()) {
            PackageElement pkgElem = (PackageElement) i.next();
            List packagePaths = getPackagePaths(pkgElem.getName());

            Iterator j = packagePaths.iterator();
            while (j.hasNext()) {
                ComponentPath path = (ComponentPath) j.next();

                if (componentPath.isSubPathOf(path))
                    return pkgElem;
            }
        }
        return null;
    }

    public PackageElement getPackageElementByName(String pkgName) throws PackageException {

        Collection pkgElements = getConfiguredPackageElements();

        Iterator i = pkgElements.iterator();

        while (i.hasNext()) {
            PackageElement pkgElem = (PackageElement) i.next();

            if (pkgElem.getName().equals(pkgName))
                return pkgElem;
        }
        return null;
    }

    /**
     * returns the root paths of the component tree associated with a given
     * package
     * 
     * @param pkgName
     *            name of the package to return associated paths from
     * @return list of unique package associated root nodes
     */
    private List getPackagePaths(String pkgName) {
        List groupIds = new LinkedList();
        List pathsToExport = new ArrayList(groupIds.size() + 1);
        ComponentPath mainPath = new ComponentPath(ComponentPath.SEPARATOR
                + pkgName.replace('.', ComponentPath.SEPARATOR));
        pathsToExport.add(mainPath);
        Iterator ids = groupIds.iterator();
        while (ids.hasNext()) {
            String id = (String) ids.next();
            ComponentPath homePath = UserHome.getRootPath().append(id);
            if (homePath.isSubPathOf(mainPath)) {
                if (log.isDebugEnabled()) {
                    log.debug("exportPackage() - skipping home of group '" + id + "' (='" + homePath
                            + "' because it is already included in main component-tree of package.");
                }
            } else {
                pathsToExport.add(homePath);
            }
        }
        return pathsToExport;
    }

    /**
     * Determines all paths included in subTreeRelations, which are no childs of
     * any of the components referenced by paths in pathsToExport.
     * 
     * @param subTreeRelations
     * @param pathsToExport
     * @return
     */
    private Collection extractExternalRelations(Collection subTreeRelations, Collection pathsToExport, CallData callData) {

        Iterator i = subTreeRelations.iterator();

        ComponentPath path[] = (ComponentPath[]) pathsToExport.toArray(new ComponentPath[0]);
        String pathInPackage[] = new String[path.length];

        int exportAmount = path.length;

        for (int a = 0; a < exportAmount; a++) {
            pathInPackage[a] = path[a].toPath();
        }

        Set externalRelations = new HashSet();

        while (i.hasNext()) {
            ComponentPath relation = (ComponentPath) i.next();
            String relationString = relation.toPath();

            boolean isIncludedInExport = false;
            for (int a = 0; a < exportAmount; a++) {
                if (relationString.startsWith(pathInPackage[a])) {
                    isIncludedInExport = true;
                    break;
                }
            }

            if (!isIncludedInExport) {
                externalRelations.add(relation);
            }
        }

        return externalRelations;
    }

    /**
     * @param path
     * @return
     */
    private Collection getSubTreeRelations(ComponentPath path, CallData callData) throws ContelligentException {

        Set set = contelligent.getRelationsManager().getTreeRelations(path,
                contelligent.getRootComponentManager().getId());
        return set;
    }

    /**
     * @param path
     * @return
     */
    private Collection getTypesInSubTree(ComponentPath path, CallData callData) throws ComponentSystemException {

        // currently deep tree digging
        Collection allTypes = callData.getActualManager().getTypesInSubTree(path);

        return allTypes;
    }

    public String getPackageNameByURL(URL location) throws PackageException {
        return getPackageDescriptor(location).getName();
    }

    protected InputStream getPackageResourceStream(URL packageURL, String resourceName) throws PackageException {
        InputStream result = null;
        try {
            log.debug("getPackageResource() - opening connection to URL '" + packageURL + "' ...");
            URLConnection con = packageURL.openConnection();
            if (!(con instanceof JarURLConnection)) {
                log.debug("getPackageResource() - ... could not use JarURLConnection for URL '" + packageURL
                        + "' -> trying to use URLClassLoader ...");
                URLClassLoader tmpCL = new URLClassLoader(new URL[] { packageURL });
                URL resourceURL = tmpCL.findResource(resourceName);
                if (resourceURL == null) {
                    log.error("getPackageResource() - cannot find resource '" + resourceName + "' in directory '"
                            + packageURL + "'!");
                } else {
                    result = resourceURL.openStream();
                }
            } else {
                log.debug("getPackageResource() - ... using JarURLConnection ...");
                JarURLConnection jarCon = (JarURLConnection) con;
                JarFile jarFile = jarCon.getJarFile();
                JarEntry resourceEntry = jarFile.getJarEntry(resourceName);
                if (resourceEntry == null) {
                    log.error("getPackageResource() - cannot find resource '" + resourceName + "' in jar '"
                            + jarFile.getName() + "'!");
                } else {
                    result = jarFile.getInputStream(resourceEntry);
                }
            }
        } catch (IOException e) {
            log.error("getPackageResource() - IOException: ", e);
            throw new PackageException("getPackageResource() - IOException !", e);
        } catch (Exception e) {
            log.error("getPackageResource() - Exception: ", e);
            throw new PackageException("getPackageResource() - Exception !", e);
        }
        return result;
    }

    private Collection getConfiguredPackageElements() throws PackageException {
        List list = new LinkedList();
        for (int i = 0; i < packageURLs.length; i++) {
            PackageElement desc = getPackageDescriptor(packageURLs[i]);
            if (desc != null) {
                list.add(desc);
            }
        }

        return list;
    }

    private Object[] getConfiguredPackages() throws PackageException {
        try {
            Collection answer = new ArrayList();
            Map nameURLMapping = new HashMap();
            Map packageInfo = persistence.getPackageInfo();

            for (int i = 0; i < packageURLs.length; i++) {
                PackageElement desc = getPackageDescriptor(packageURLs[i]);
                if (desc != null) {
                    answer.add(desc);
                    nameURLMapping.put(desc.getName(), packageURLs[i]);
                }
            }
            return new Object[] { answer, nameURLMapping };
        } catch (ContelligentException e) {
            throw new PackageException(e.getMessage(), e);
        }
    }

    /**
     * Returns a map with (String, PackageElement) entries mapping the name of
     * an installed package to its PackageElement containing all package
     * information.
     */
    Map createPackageMap(Collection pkgs) {
        Map answer = new HashMap();
        Iterator iterator = pkgs.iterator();

        while (iterator.hasNext()) {
            PackageElement pkg = (PackageElement) iterator.next();
            answer.put(pkg.getName(), pkg);
        }
        return answer;
    }

    private PackageElement getPackageDescriptor(URL url) throws PackageException {
        try {
            log.debug("getPackageDescriptor() - validating package from URL '" + url + "' ...");

            InputStream pkgDescSource = getPackageResourceStream(url, Contelligent.PKG_DESCRIPTION);
            if (pkgDescSource == null) {
                log.error("getPackageDescriptor() - cannot find package description '" + Contelligent.PKG_DESCRIPTION
                        + "' using URL '" + url + "'!");
                return null;
            }

            DTDCatalog catalog = DTDCatalog.getInstance();
            Digester digester = new Digester();
            digester.setClassLoader(ContelligentImpl.class.getClassLoader());
            catalog.registerAllDTDsWithDigester(digester);
            // digester.register(catalog.getPublicId(DTDCatalog.PACKAGE_DESCRIPTOR),
            // catalog.getFileURL(DTDCatalog.PACKAGE_DESCRIPTOR));
            // digester.register(catalog.getPublicId(DTDCatalog.CATEGORY_DEFINITION),
            // catalog.getFileURL(DTDCatalog.CATEGORY_DEFINITION));
            // digester.register(catalog.getPublicId(DTDCatalog.ACL),
            // catalog.getFileURL(DTDCatalog.ACL));
            // digester.register(catalog.getPublicId(DTDCatalog.DESCRIPTION),
            // catalog.getFileURL(DTDCatalog.DESCRIPTION));
            // digester.register(catalog.getPublicId(DTDCatalog.SEARCH_ENGINE),
            // catalog.getFileURL(DTDCatalog.SEARCH_ENGINE));
            // digester.register(catalog.getPublicId(DTDCatalog.ERROR_MAPPING),
            // catalog.getFileURL(DTDCatalog.ERROR_MAPPING));
            digester.setErrorHandler(new EchoingErrorHandler("While trying to get package description from URL '" + url
                    + "'"));
            digester.setValidating(true);
            // don't use a sub-log-category of this class' log for digester or
            // else
            // debug for this class can't be switched independently from
            // digester logging.
            digester.setLogger(new Log4JCategoryLog(LoggingService.getLogger(this.getClass().getName() + "-digester")));
            digester.addRuleSet(new PackageRuleSet("")); // no prefix
            return (PackageElement) digester.parse(pkgDescSource);
        } catch (IOException e) {
            log.error("getPackageDescriptor() - IOException: ", e);
            throw new PackageException("getPackageDescriptor() - IOException !", e);
        } catch (SAXException e) {
            Exception embedded = e.getException();
            if (embedded == null) {
                log.error("getPackageDescriptor() - SAXException: ", e);
                throw new PackageException("getPackageDescriptor() - SAXException !", e);
            } else {
                log.error("getPackageDescriptor() - SAXException [" + e + "] with embedded exception: ", embedded);
                throw new PackageException("validatePackage() - SAXException [" + e + "] with embedded exception!",
                        embedded);
            }
        } catch (Exception e) {
            log.error("validatePackage() - Exception: ", e);
            throw new PackageException("getPackageDescriptor() - Exception !", e);
        }
    }

    /**
     * Determines the order two {@link PackageImportElement} must be imported.
     */
    public static class PackageImportComparator implements Comparator {
        public int compare(Object obj1, Object obj2) {
            PackageImportElement types1 = (PackageImportElement) obj1;
            PackageImportElement types2 = (PackageImportElement) obj2;
            int tmp = types1.getOrderNumber().compareTo(types2.getOrderNumber());
            if (tmp == 0) {
                return types1.getFileName().compareTo(types2.getFileName());
            } else {
                return tmp;
            }
        }
    }

    /**
     * Answer root paths of all readOnly packages
     * 
     * @return collection of ComponentPath instances
     */
    Set getReadOnlyPaths() {
        return systemState.getReadOnlyPaths();
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.