/* $Revision$ $Author$ $Date$
*
* Copyright (C) 2004-2007 Rajarshi Guha <rajarshi@users.sourceforge.net>
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.openscience.cdk.qsar;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import nu.xom.Attribute;
import nu.xom.Element;
import nu.xom.Elements;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.dict.Dictionary;
import org.openscience.cdk.dict.DictionaryDatabase;
import org.openscience.cdk.dict.Entry;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* A class that provides access to automatic descriptor calculation and more.
* <p/>
* <p>The aim of this class is to provide an easy to use interface to automatically evaluate
* all the CDK descriptors for a given molecule. Note that at a given time this class
* will evaluate all <i>atomic</i> or <i>molecular</i> descriptors but not both.
* <p/>
* <p>The available descriptors are determined by scanning all the jar files in the users CLASSPATH
* and selecting classes that belong to the CDK QSAR atomic or molecular descriptors package.
* <p/>
* <p>An example of its usage would be
* <pre>
* Molecule someMolecule;
* ...
* DescriptorEngine descriptoEngine = new DescriptorEngine(DescriptorEngine.MOLECULAR, null);
* descriptorEngine.process(someMolecule);
* </pre>
* <p/>
* <p>The class allows the user to obtain a List of all the available descriptors in terms of their
* Java class names as well as instances of each descriptor class. For each descriptor, it is possible to
* obtain its classification as described in the CDK descriptor-algorithms OWL dictionary.
*
* @cdk.created 2004-12-02
* @cdk.module qsarmolecular
* @cdk.githash
* @cdk.depends xom-1.0.jar
* @see DescriptorSpecification
* @see Dictionary
* @see org.openscience.cdk.dict.OWLFile
*/
@TestClass(value="org.openscience.cdk.qsar.DescriptorEngineTest")
public class DescriptorEngine {
private static String rdfNS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
public static final int ATOMIC = 1;
public static final int BOND = 2;
public static final int MOLECULAR = 3;
private Dictionary dict = null;
private List<String> classNames = null;
private List<IDescriptor> descriptors = null;
private List<DescriptorSpecification> speclist = null;
private static ILoggingTool logger =
LoggingToolFactory.createLoggingTool(DescriptorEngine.class);
/**
* Instantiates the DescriptorEngine.
* <p/>
* This constructir instantiates the engine but does not perform any initialization. As a result calling
* the <code>process()</code> method will fail. To use the engine via this constructor you should use
* the following code
* <p/>
* <pre>
* List classNames = DescriptorEngine.getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.molecular",
* null);
* DescriptorEngine engine = DescriptorEngine(classNames);
* <p/>
* List instances = engine.instantiateDescriptors(classNames);
* List specs = engine.initializeSpecifications(instances)
* engine.setDescriptorInstances(instances);
* engine.setDescriptorSpecifications(specs);
* <p/>
* engine.process(someAtomContainer);
* </pre>
* <p/>
* This approach allows one to use find classes using the interface based approach ({@link #getDescriptorClassNameByInterface(String, String[])}.
* If you use this method it is preferable to specify the jar files to examine
*/
public DescriptorEngine(List<String> classNames) {
this.classNames = classNames;
descriptors = instantiateDescriptors(classNames);
speclist = initializeSpecifications(descriptors);
// get the dictionary for the descriptors
DictionaryDatabase dictDB = new DictionaryDatabase();
dict = dictDB.getDictionary("descriptor-algorithms");
}
/**
* Constructor that generates a list of descriptors to calculate.
* <p/>
* All available descriptors are included in the list of descriptors to
* calculate This constructor assumes that system classpath is the one to look at
* to find valid jar files.
*
* @param type Indicates whether molecular or atomic descriptors should be calculated. Possible values
* are DescriptorEngine.ATOMIC or DescriptorEngine.MOLECULAR
*/
@TestMethod(value="testConstructor")
public DescriptorEngine(int type) {
this(type, null);
}
/**
* Constructor that generates a list of descriptors to calculate.
* <p/>
* All available descriptors are included in the list of descriptors to
* calculate
*
* @param type Indicates whether molecular or atomic descriptors should be calculated. Possible values
* are DescriptorEngine.ATOMIC or DescriptorEngine.MOLECULAR
* @param jarFileNames A String[] containing the fully qualified names of the jar files
* to examine for descriptor classes. In general, this can be set to NULL, in which case
* the system classpath is examined for available jar files. This parameter can be set for
* situations where the system classpath is not available or is modified such as in an application
* container.
*/
public DescriptorEngine(int type, String[] jarFileNames) {
switch (type) {
case ATOMIC:
classNames = getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.atomic", jarFileNames);
break;
case BOND:
classNames = getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.bond", jarFileNames);
break;
case MOLECULAR:
classNames = getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.molecular", jarFileNames);
break;
}
descriptors = instantiateDescriptors(classNames);
speclist = initializeSpecifications(descriptors);
logger.debug("Found #descriptors: ", classNames.size());
// get the dictionary for the descriptors
DictionaryDatabase dictDB = new DictionaryDatabase();
dict = dictDB.getDictionary("descriptor-algorithms");
}
/**
* Calculates all available (or only those specified) descriptors for a molecule.
* <p/>
* The results for a given descriptor as well as associated parameters and
* specifications are used to create a <code>DescriptorValue</code>
* object which is then added to the molecule as a property keyed
* on the <code>DescriptorSpecification</code> object for that descriptor
*
* @param molecule The molecule for which we want to calculate descriptors
* @throws CDKException if an error occured during descriptor calculation or the descriptors and/or
* specifications have not been initialized
*/
public void process(IAtomContainer molecule) throws CDKException {
if (descriptors == null || speclist == null) throw new CDKException("Descriptors have not been instantiated");
if (speclist.size() != descriptors.size())
throw new CDKException("Number of specs and descriptors do not match");
for (int i = 0; i < descriptors.size(); i++) {
IDescriptor descriptor = (IDescriptor) descriptors.get(i);
if (descriptor instanceof IMolecularDescriptor) {
DescriptorValue value = ((IMolecularDescriptor) descriptor).calculate(molecule);
if (value.getException() == null) molecule.setProperty(speclist.get(i), value);
else {
logger.error("Could not calculate descriptor value for: ", descriptor.getClass().getName());
logger.debug(value.getException());
}
logger.debug("Calculated molecular descriptors...");
} else if (descriptor instanceof IAtomicDescriptor) {
Iterator atoms = molecule.atoms().iterator();
while (atoms.hasNext()) {
IAtom atom = (IAtom) atoms.next();
DescriptorValue value = ((IAtomicDescriptor) descriptor).calculate(atom, molecule);
if (value.getException() == null) atom.setProperty(speclist.get(i), value);
else {
logger.error("Could not calculate descriptor value for: ", descriptor.getClass().getName());
logger.debug(value.getException());
}
}
logger.debug("Calculated atomic descriptors...");
} else if (descriptor instanceof IBondDescriptor) {
Iterator bonds = molecule.bonds().iterator();
while (bonds.hasNext()) {
IBond bond = (IBond) bonds.next();
DescriptorValue value = ((IBondDescriptor) descriptor).calculate(bond, molecule);
if (value.getException() == null) bond.setProperty(speclist.get(i), value);
else {
logger.error("Could not calculate descriptor value for: ", descriptor.getClass().getName());
logger.debug(value.getException());
}
}
logger.debug("Calculated bond descriptors...");
} else {
logger.debug("Unknown descriptor type for: ", descriptor.getClass().getName());
}
}
}
/**
* Returns the type of the descriptor as defined in the descriptor dictionary.
* <p/>
* The method will look for the identifier specified by the user in the QSAR descriptor
* dictionary. If a corresponding entry is found, first child element that is called
* "isClassifiedAs" is returned. Note that the OWL descriptor spec allows both the class of
* descriptor (electronic, topological etc) as well as the type of descriptor (molecular, atomic)
* to be specified in an "isClassifiedAs" element. Thus we ignore any such element that
* indicates the descriptors class.
* <p/>
* The method assumes that any descriptor entry will have only one "isClassifiedAs" entry describing
* the descriptors type.
* <p/>
* The descriptor can be identified either by the name of the class implementing the descriptor
* or else the specification reference value of the descriptor which can be obtained from an instance
* of the descriptor class.
*
* @param identifier A String containing either the descriptors fully qualified class name or else the descriptors
* specification reference
* @return The type of the descriptor as stored in the dictionary, null if no entry is found matching
* the supplied identifier
*/
@TestMethod(value="testDictionaryType")
public String getDictionaryType(String identifier) {
Entry[] dictEntries = dict.getEntries();
String specRef = getSpecRef(identifier);
logger.debug("Got identifier: " + identifier);
logger.debug("Final spec ref: " + specRef);
for (Entry dictEntry : dictEntries) {
if (!dictEntry.getClassName().equals("Descriptor")) continue;
if (dictEntry.getID().equals(specRef.toLowerCase())) {
Element rawElement = (Element) dictEntry.getRawContent();
// assert(rawElement != null);
// We're not fully Java 1.5 yet, so commented it out now. If it is
// really important to have it, then add @cdk.require java1.5 in the
// Class javadoc (and all classes that use this class)
Elements classifications = rawElement.getChildElements("isClassifiedAs", dict.getNS());
for (int i = 0; i < classifications.size(); i++) {
Element element = classifications.get(i);
Attribute attr = element.getAttribute("resource", rdfNS);
if ((attr.getValue().indexOf("molecularDescriptor") != -1) ||
(attr.getValue().indexOf("atomicDescriptor") != -1)) {
String[] tmp = attr.getValue().split("#");
return tmp[1];
}
}
}
}
return null;
}
/**
* Returns the type of the descriptor as defined in the descriptor dictionary.
* <p/>
* The method will look for the identifier specified by the user in the QSAR descriptor
* dictionary. If a corresponding entry is found, first child element that is called
* "isClassifiedAs" is returned. Note that the OWL descriptor spec allows both the class of
* descriptor (electronic, topological etc) as well as the type of descriptor (molecular, atomic)
* to be specified in an "isClassifiedAs" element. Thus we ignore any such element that
* indicates the descriptors class.
* <p/>
* The method assumes that any descriptor entry will have only one "isClassifiedAs" entry describing
* the descriptors type.
* <p/>
* The descriptor can be identified it DescriptorSpecification object
*
* @param descriptorSpecification A DescriptorSpecification object
* @return he type of the descriptor as stored in the dictionary, null if no entry is found matching
* the supplied identifier
*/
@TestMethod(value="testDictionaryType")
public String getDictionaryType(DescriptorSpecification descriptorSpecification) {
return getDictionaryType(descriptorSpecification.getSpecificationReference());
}
/**
* Returns the class(es) of the decsriptor as defined in the descriptor dictionary.
* <p/>
* The method will look for the identifier specified by the user in the QSAR descriptor
* dictionary. If a corresponding entry is found, the meta-data list is examined to
* look for a dictRef attribute that contains a descriptorClass value. if such an attribute is
* found, the value of the contents attribute add to a list. Since a descriptor may be classed in
* multiple ways (geometric and electronic for example), in general, a given descriptor will
* have multiple classes associated with it.
* <p/>
* The descriptor can be identified either by the name of the class implementing the descriptor
* or else the specification reference value of the descriptor which can be obtained from an instance
* of the descriptor class.
*
* @param identifier A String containing either the descriptors fully qualified class name or else the descriptors
* specification reference
* @return A List containing the names of the QSAR descriptor classes that this descriptor was declared
* to belong to. If an entry for the specified identifier was not found, null is returned.
*/
@TestMethod(value="testDictionaryClass")
public String[] getDictionaryClass(String identifier) {
Entry[] dictEntries = dict.getEntries();
String specRef = getSpecRef(identifier);
if (specRef == null) {
logger.error("Cannot determine specification for id: ", identifier);
return new String[0];
}
List<String> dictClasses = new ArrayList<String>();
for (Entry dictEntry : dictEntries) {
if (!dictEntry.getClassName().equals("Descriptor")) continue;
if (dictEntry.getID().equals(specRef.toLowerCase())) {
Element rawElement = (Element) dictEntry.getRawContent();
Elements classifications = rawElement.getChildElements("isClassifiedAs", dict.getNS());
for (int i = 0; i < classifications.size(); i++) {
Element element = classifications.get(i);
Attribute attr = element.getAttribute("resource", rdfNS);
if ((attr.getValue().indexOf("molecularDescriptor") >= 0) ||
(attr.getValue().indexOf("atomicDescriptor") >= 0)) {
continue;
}
String[] tmp = attr.getValue().split("#");
dictClasses.add(tmp[1]);
}
}
}
if (dictClasses.size() == 0) return null;
else
return (String[]) dictClasses.toArray(new String[]{});
}
/**
* Returns the class(es) of the descriptor as defined in the descriptor dictionary.
* <p/>
* The method will look for the identifier specified by the user in the QSAR descriptor
* dictionary. If a corresponding entry is found, the meta-data list is examined to
* look for a dictRef attribute that contains a descriptorClass value. if such an attribute is
* found, the value of the contents attribute add to a list. Since a descriptor may be classed in
* multiple ways (geometric and electronic for example), in general, a given descriptor will
* have multiple classes associated with it.
* <p/>
* The descriptor can be identified by its DescriptorSpecification object.
*
* @param descriptorSpecification A DescriptorSpecification object
* @return A List containing the names of the QSAR descriptor classes that this descriptor was declared
* to belong to. If an entry for the specified identifier was not found, null is returned.
*/
@TestMethod(value="testDictionaryClass")
public String[] getDictionaryClass(DescriptorSpecification descriptorSpecification) {
return getDictionaryClass(descriptorSpecification.getSpecificationReference());
}
/**
* Gets the definition of the descriptor.
* <p/>
* All descriptors in the descriptor dictioanry will have a definition element. This function
* returns the value of that element. Many descriptors also have a description element which is
* more detailed. However the value of these elements can contain arbitrary mark up (such as MathML)
* and I'm not sure what I should return it as
*
* @param identifier A String containing either the descriptors fully qualified class name or else the descriptors
* specification reference
* @return The definition
*/
public String getDictionaryDefinition(String identifier) {
Entry[] dictEntries = dict.getEntries();
String specRef = getSpecRef(identifier);
String definition = null;
for (Entry dictEntry : dictEntries) {
if (!dictEntry.getClassName().equals("Descriptor")) continue;
if (dictEntry.getID().equals(specRef.toLowerCase())) {
definition = dictEntry.getDefinition();
break;
}
}
return definition;
}
/**
* Gets the definition of the descriptor.
* <p/>
* All descriptors in the descriptor dictioanry will have a definition element. This function
* returns the value of that element. Many descriptors also have a description element which is
* more detailed. However the value of these elements can contain arbitrary mark up (such as MathML)
* and I'm not sure what I should return it as
*
* @param descriptorSpecification A DescriptorSpecification object
* @return The definition
*/
public String getDictionaryDefinition(DescriptorSpecification descriptorSpecification) {
return getDictionaryDefinition(descriptorSpecification.getSpecificationReference());
}
/**
* Gets the label (title) of the descriptor.
*
* @param identifier A String containing either the descriptors fully qualified class name or else the descriptors
* specification reference
* @return The title
*/
public String getDictionaryTitle(String identifier) {
Entry[] dictEntries = dict.getEntries();
String specRef = getSpecRef(identifier);
String title = null;
for (Entry dictEntry : dictEntries) {
if (!dictEntry.getClassName().equals("Descriptor")) continue;
if (dictEntry.getID().equals(specRef.toLowerCase())) {
title = dictEntry.getLabel();
break;
}
}
return title;
}
/**
* Gets the label (title) of the descriptor.
*
* @param descriptorSpecification The specification object
* @return The title
*/
public String getDictionaryTitle(DescriptorSpecification descriptorSpecification) {
return getDictionaryTitle(descriptorSpecification.getSpecificationReference());
}
/**
* Returns the DescriptorSpecification objects for all available descriptors.
*
* @return An array of <code>DescriptorSpecification</code> objects. These are the keys
* with which the <code>DescriptorValue</code> objects can be obtained from a
* molecules property list
*/
public List<DescriptorSpecification> getDescriptorSpecifications() {
return (speclist);
}
/**
* Set the list of <code>DescriptorSpecification</code> objects.
*
* @param specs A list of specification objects
* @see #getDescriptorSpecifications
*/
public void setDescriptorSpecifications(List<DescriptorSpecification> specs) {
speclist = specs;
}
/**
* Returns a list containing the names of the classes implementing the descriptors.
*
* @return A list of class names.
*/
public List<String> getDescriptorClassNames() {
return classNames;
}
/**
* Returns a List containing the instantiated descriptor classes.
*
* @return A List containing descriptor classes
*/
@TestMethod(value="testLoadingOfMolecularDescriptors,testLoadingOfAtomicDescriptors,testLoadingOfBondDescriptors")
public List<IDescriptor> getDescriptorInstances() {
return descriptors;
}
/**
* Set the list of <code>Descriptor</code> objects.
*
* @param descriptors A List of descriptor objects
* @see #getDescriptorInstances()
*/
public void setDescriptorInstances(List<IDescriptor> descriptors) {
this.descriptors = descriptors;
}
/**
* Get the all the unique dictionary classes that the descriptors belong to.
*
* @return An array containing the unique dictionary classes.
*/
@TestMethod(value="testAvailableClass")
public String[] getAvailableDictionaryClasses() {
List<String> classList = new ArrayList<String>();
for (Iterator iter = speclist.iterator(); iter.hasNext();) {
DescriptorSpecification spec = (DescriptorSpecification) iter.next();
String[] tmp = getDictionaryClass(spec);
if (tmp != null) classList.addAll(Arrays.asList(tmp));
}
Set<String> uniqueClasses = new HashSet<String>(classList);
return (String[]) uniqueClasses.toArray(new String[]{});
}
/**
* Returns a list containing the classes that implement a specific interface.
* <p/>
* The interface name specified can be null or an empty string. In this case the interface name
* is automatcally set to <i>IDescriptor</i>. Specifying <i>IDescriptor</i> will
* return all available descriptor classes. Valid interface names are
* <ul>
* <li>IMolecularDescriptor
* <li>IAtomicDescripto
* <li>IBondDescriptor
* <li>IDescriptor
* </ul>
*
* @param interfaceName The name of the interface that classes should implement
* @param jarFileNames A String[] containing the fully qualified names of the jar files
* to examine for descriptor classes. In general this can be set to NULL, in which case
* the system classpath is examined for available jar files. This parameter can be set for
* situations where the system classpath is not available or is modified such as in an application
* container.
* @return A list containing the classes implementing the specified interface, null if an invalid interface
* is specified
*/
public static List<String> getDescriptorClassNameByInterface(String interfaceName, String[] jarFileNames) {
if (interfaceName == null || interfaceName.equals(""))
interfaceName = "IDescriptor";
if (!interfaceName.equals("IDescriptor") &&
!interfaceName.equals("IMolecularDescriptor") &&
!interfaceName.equals("IAtomicDescriptor") &&
!interfaceName.equals("IBondDescriptor")) return null;
String[] jars;
if (jarFileNames == null) {
String classPath = System.getProperty("java.class.path");
jars = classPath.split(File.pathSeparator);
} else {
jars = jarFileNames;
}
List<String> classlist = new ArrayList<String>();
for (int i = 0; i < jars.length; i++) {
logger.debug("Looking in " + jars[i]);
JarFile jarFile;
try {
jarFile = new JarFile(jars[i]);
Enumeration enumeration = jarFile.entries();
while (enumeration.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) enumeration.nextElement();
if (jarEntry.toString().indexOf(".class") != -1) {
String className = jarEntry.toString().replace('/', '.').replaceAll(".class", "");
if (className.indexOf('$') != -1) continue;
Class klass = null;
try {
klass = Class.forName(className);
} catch (ClassNotFoundException cnfe) {
logger.debug(cnfe);
} catch (NoClassDefFoundError ncdfe) {
logger.debug(ncdfe);
} catch (UnsatisfiedLinkError ule) {
logger.debug(ule);
}
if (klass == null) continue;
// check that its not abstract or an interface
int modifer = klass.getModifiers();
if (Modifier.isAbstract(modifer) ||
Modifier.isInterface(modifer)) continue;
// get the interfaces implemented and see if one matches the one we're looking for
Class[] interfaces = klass.getInterfaces();
for (int k = 0; k < interfaces.length; k++) {
if (interfaces[k].getName().equals(interfaceName)) {
classlist.add(className);
break;
}
}
}
}
} catch (IOException e) {
logger.error("Error opening the jar file: " + jars[i]);
logger.debug(e);
}
}
return classlist;
}
/**
* Returns a list containing the classes found in the specified descriptor package.
* <p/>
* The package name specified can be null or an empty string. In this case the package name
* is automatcally set to "org.openscience.cdk.qsar.descriptors" and as a result will return
* classes corresponding to both atomic and molecular descriptors.
*
* @param packageName The name of the package containing the required descriptor
* @param jarFileNames A String[] containing the fully qualified names of the jar files
* to examine for descriptor classes. In general this can be set to NULL, in which case
* the system classpath is examined for available jar files. This parameter can be set for
* situations where the system classpath is not available or is modified such as in an application
* container.
* @return A list containing the classes in the specified package
*/
public static List<String> getDescriptorClassNameByPackage(String packageName, String[] jarFileNames) {
if (packageName == null || packageName.equals("")) {
packageName = "org.openscience.cdk.qsar.descriptors";
}
String[] jars;
if (jarFileNames == null) {
String classPath = System.getProperty("java.class.path");
jars = classPath.split(File.pathSeparator);
} else {
jars = jarFileNames;
}
ArrayList<String> classlist = new ArrayList<String>();
for (String jar : jars) {
logger.debug("Looking in " + jar);
JarFile jarFile;
try {
jarFile = new JarFile(jar);
Enumeration enumeration = jarFile.entries();
while (enumeration.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) enumeration.nextElement();
if (jarEntry.toString().indexOf(".class") != -1) {
String tmp = jarEntry.toString().replace('/', '.').replaceAll(".class", "");
if (!(tmp.indexOf(packageName) != -1)) continue;
if (tmp.indexOf('$') != -1) continue;
if (tmp.indexOf("Test") != -1) continue;
if (tmp.indexOf("ChiIndexUtils") != -1) continue;
if (!classlist.contains(tmp)) classlist.add(tmp);
}
}
} catch (IOException e) {
logger.error("Error opening the jar file: " + jar);
logger.debug(e);
}
}
return classlist;
}
public List<IDescriptor> instantiateDescriptors(List<String> descriptorClassNames) {
List<IDescriptor> descriptors;
descriptors = new ArrayList<IDescriptor>();
for (String descriptorName : descriptorClassNames) {
try {
IDescriptor descriptor = (IDescriptor) this.getClass().getClassLoader().loadClass(descriptorName).newInstance();
descriptors.add(descriptor);
logger.info("Loaded descriptor: ", descriptorName);
} catch (NoClassDefFoundError error) {
logger.error("Could not find this Descriptor: ", descriptorName);
logger.debug(error);
} catch (ClassNotFoundException exception) {
logger.error("Could not find this Descriptor: ", descriptorName);
logger.debug(exception);
} catch (Exception exception) {
logger.error("Could not load this Descriptor: ", descriptorName);
logger.debug(exception);
}
}
return descriptors;
}
public List<DescriptorSpecification> initializeSpecifications(List<IDescriptor> descriptors) {
List<DescriptorSpecification> speclist = new ArrayList<DescriptorSpecification>();
for (IDescriptor descriptor : descriptors) {
speclist.add(descriptor.getSpecification());
}
return speclist;
}
private String getSpecRef(String identifier) {
String specRef = null;
// see if we got a descriptors java class name
for (int i = 0; i < classNames.size(); i++) {
String className = (String) classNames.get(i);
if (className.equals(identifier)) {
IDescriptor descriptor = (IDescriptor) descriptors.get(i);
DescriptorSpecification descSpecification = descriptor.getSpecification();
String[] tmp = descSpecification.getSpecificationReference().split("#");
if (tmp.length != 2) {
logger.debug("Something fishy with the spec ref: ", descSpecification.getSpecificationReference());
} else {
specRef = tmp[1];
}
}
}
// if we are here and specRef==null we have a SpecificationReference
if (specRef == null) {
String[] tmp = identifier.split("#");
if (tmp.length != 2) {
logger.debug("Something fishy with the identifier: ", identifier);
} else {
specRef = tmp[1];
}
}
return specRef;
}
}