/*
* 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();
}
}
|