Skip to content

Commit

Permalink
allow DescriptorEngine to load the two descriptors that require an IC…
Browse files Browse the repository at this point in the history
…hemObjectBuilder injection. DescriptorTest was updated and generiffied to allow testing of the modified descriptors.
  • Loading branch information
johnmay authored and egonw committed Mar 19, 2013
1 parent 9b736ad commit f30e2b2
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 38 deletions.
40 changes: 32 additions & 8 deletions src/main/org/openscience/cdk/qsar/DescriptorEngine.java
Expand Up @@ -33,11 +33,14 @@
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -94,6 +97,7 @@ public class DescriptorEngine {
private List<IImplementationSpecification> speclist = null;
private static ILoggingTool logger =
LoggingToolFactory.createLoggingTool(DescriptorEngine.class);
private final IChemObjectBuilder builder;

/**
* Instantiates the DescriptorEngine.
Expand All @@ -118,8 +122,9 @@ public class DescriptorEngine {
* 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) {
public DescriptorEngine(List<String> classNames, IChemObjectBuilder builder) {
this.classNames = classNames;
this.builder = builder;
descriptors = instantiateDescriptors(classNames);
speclist = initializeSpecifications(descriptors);

Expand All @@ -139,8 +144,8 @@ public DescriptorEngine(List<String> classNames) {
* are DescriptorEngine.ATOMIC or DescriptorEngine.MOLECULAR
*/
@TestMethod(value="testConstructor")
public DescriptorEngine(int type) {
this(type, null);
public DescriptorEngine(int type, IChemObjectBuilder builder) {
this(type, null, builder);
}

/**
Expand All @@ -157,7 +162,7 @@ public DescriptorEngine(int type) {
* situations where the system classpath is not available or is modified such as in an application
* container.
*/
public DescriptorEngine(int type, String[] jarFileNames) {
public DescriptorEngine(int type, String[] jarFileNames, IChemObjectBuilder builder) {
switch (type) {
case ATOMIC:
classNames = getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.atomic", jarFileNames);
Expand All @@ -172,6 +177,7 @@ public DescriptorEngine(int type, String[] jarFileNames) {
classNames = getDescriptorClassNameByPackage("org.openscience.cdk.qsar.descriptors.atompair", jarFileNames);
break;
}
this.builder = builder;
descriptors = instantiateDescriptors(classNames);
speclist = initializeSpecifications(descriptors);
logger.debug("Found #descriptors: ", classNames.size());
Expand Down Expand Up @@ -692,12 +698,13 @@ public static List<String> getDescriptorClassNameByPackage(String packageName, S
}

public List<IDescriptor> instantiateDescriptors(List<String> descriptorClassNames) {
List<IDescriptor> descriptors;
descriptors = new ArrayList<IDescriptor>();
List<IDescriptor> descriptors = new ArrayList<IDescriptor>();
ClassLoader classLoader = getClass().getClassLoader();
for (String descriptorName : descriptorClassNames) {
try {
IDescriptor descriptor = (IDescriptor) this.getClass().getClassLoader().loadClass(descriptorName).newInstance();
descriptors.add(descriptor);
@SuppressWarnings("unchecked")
Class<? extends IDescriptor> c = (Class<? extends IDescriptor>) classLoader.loadClass(descriptorName);
descriptors.add(instantiate(c));
logger.info("Loaded descriptor: ", descriptorName);
} catch (NoClassDefFoundError error) {
logger.error("Could not find this Descriptor: ", descriptorName);
Expand All @@ -713,6 +720,23 @@ public List<IDescriptor> instantiateDescriptors(List<String> descriptorClassName
return descriptors;
}

private IDescriptor instantiate(Class<? extends IDescriptor> c) throws
IllegalAccessException,
InvocationTargetException,
InstantiationException {
for(Constructor constructor : c.getConstructors()){
Class<?>[] params = constructor.getParameterTypes();
System.out.println(c.getSimpleName() + Arrays.toString(params));
if(params.length == 0){
return (IDescriptor) constructor.newInstance();
} else if(params.length == 1
&& params[0].equals(IChemObjectBuilder.class)){
return (IDescriptor) constructor.newInstance(builder);
}
}
throw new IllegalStateException("descriptor " + c.getSimpleName() + " has no usable constructors");
}

public List<IImplementationSpecification> initializeSpecifications(List<IDescriptor> descriptors) {
List<IImplementationSpecification> speclist = new ArrayList<IImplementationSpecification>();
for (IDescriptor descriptor : descriptors) {
Expand Down
29 changes: 19 additions & 10 deletions src/test/org/openscience/cdk/qsar/DescriptorEngineTest.java
Expand Up @@ -37,20 +37,22 @@
*
* @cdk.module test-qsarmolecular
*/
public class DescriptorEngineTest extends CDKTestCase {
public class DescriptorEngineTest extends CDKTestCase {

public DescriptorEngineTest() {
}

@Test
public void testConstructor() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());
Assert.assertNotNull(engine);
}

@Test
public void testLoadingOfMolecularDescriptors() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());
Assert.assertNotNull(engine);
int loadedDescriptors = engine.getDescriptorInstances().size();
Assert.assertTrue("Could not load any descriptors", 0 != loadedDescriptors);
Expand All @@ -60,7 +62,8 @@ public void testLoadingOfMolecularDescriptors() {

@Test
public void testLoadingOfAtomicDescriptors() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.ATOMIC);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.ATOMIC,
DefaultChemObjectBuilder.getInstance());
Assert.assertNotNull(engine);
int loadedDescriptors = engine.getDescriptorInstances().size();
Assert.assertNotSame(0, loadedDescriptors);
Expand All @@ -70,7 +73,8 @@ public void testLoadingOfAtomicDescriptors() {

@Test
public void testLoadingOfBondDescriptors() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.BOND);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.BOND,
DefaultChemObjectBuilder.getInstance());
Assert.assertNotNull(engine);
int loadedDescriptors = engine.getDescriptorInstances().size();
Assert.assertNotSame(0, loadedDescriptors);
Expand All @@ -80,7 +84,8 @@ public void testLoadingOfBondDescriptors() {

@Test
public void testDictionaryType() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());

String className = "org.openscience.cdk.qsar.descriptors.molecular.ZagrebIndexDescriptor";
DescriptorSpecification specRef = new DescriptorSpecification(
Expand All @@ -95,7 +100,8 @@ public void testDictionaryType() {

@Test
public void testDictionaryClass() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());

String className = "org.openscience.cdk.qsar.descriptors.molecular.TPSADescriptor";
DescriptorSpecification specRef = new DescriptorSpecification(
Expand All @@ -117,7 +123,8 @@ public void testDictionaryClass() {

@Test
public void testAvailableClass() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());
String[] availClasses = engine.getAvailableDictionaryClasses();
Assert.assertEquals(5, availClasses.length);
}
Expand All @@ -136,15 +143,17 @@ public void testjunk() throws Exception {
TemplateHandler3D template = TemplateHandler3D.getInstance();
ModelBuilder3D mb3d = ModelBuilder3D.getInstance(template, "mm2");
molecule = mb3d.generate3DCoordinates(molecule, true);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());

engine.process(molecule);

}

@Test
public void testLoadingOfAtomPairDescriptors() {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.ATOMPAIR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.ATOMPAIR,
DefaultChemObjectBuilder.getInstance());
Assert.assertNotNull(engine);
int loadedDescriptors = engine.getDescriptorInstances().size();
Assert.assertNotSame(0, loadedDescriptors);
Expand Down
4 changes: 3 additions & 1 deletion src/test/org/openscience/cdk/qsar/DescriptorNamesTest.java
Expand Up @@ -28,6 +28,7 @@
import org.junit.Test;
import org.openscience.cdk.ChemFile;
import org.openscience.cdk.CDKTestCase;
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.IImplementationSpecification;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.io.ISimpleChemObjectReader;
Expand All @@ -50,7 +51,8 @@ public DescriptorNamesTest() {

@Test
public void checkUniqueMolecularDescriptorNames() throws Exception {
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR);
DescriptorEngine engine = new DescriptorEngine(DescriptorEngine.MOLECULAR,
DefaultChemObjectBuilder.getInstance());
List<IImplementationSpecification> specs = engine.getDescriptorSpecifications();

// we work with a simple molecule with 3D coordinates
Expand Down
19 changes: 15 additions & 4 deletions src/test/org/openscience/cdk/qsar/descriptors/DescriptorTest.java
Expand Up @@ -23,24 +23,35 @@
import org.junit.Assert;
import org.junit.Test;
import org.openscience.cdk.CDKTestCase;
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.IImplementationSpecification;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.qsar.DescriptorSpecification;
import org.openscience.cdk.qsar.IDescriptor;

import java.lang.reflect.Constructor;

/**
* Tests for molecular descriptors.
*
* @cdk.module test-qsar
*/
public abstract class DescriptorTest extends CDKTestCase {
public abstract class DescriptorTest<T extends IDescriptor> extends CDKTestCase {

protected IDescriptor descriptor;
protected T descriptor;

public DescriptorTest() {}

public void setDescriptor(Class<? extends IDescriptor> descriptorClass) throws Exception {
public void setDescriptor(Class<? extends T> descriptorClass) throws Exception {
if (descriptor == null) {
this.descriptor = descriptorClass.newInstance();
try {
Constructor<? extends T> defaultConstructor = descriptorClass.getConstructor();
this.descriptor = defaultConstructor.newInstance();
} catch (NoSuchMethodException ex) {
// no default constructor, try with an IChemObjectBuilder...
Constructor<? extends T> builderConstructor = descriptorClass.getConstructor(IChemObjectBuilder.class);
this.descriptor = builderConstructor.newInstance(DefaultChemObjectBuilder.getInstance());
}
}
}

Expand Down
Expand Up @@ -39,6 +39,7 @@
import org.openscience.cdk.interfaces.IBond.Order;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.qsar.IDescriptor;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.qsar.DescriptorValue;
import org.openscience.cdk.qsar.IMolecularDescriptor;
Expand All @@ -52,32 +53,21 @@
import org.openscience.cdk.tools.diff.AtomContainerDiff;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;

import java.lang.reflect.Constructor;

/**
* Tests for molecular descriptors.
*
* @cdk.module test-qsarmolecular
*/
public abstract class MolecularDescriptorTest extends DescriptorTest {

protected IMolecularDescriptor descriptor;
public abstract class MolecularDescriptorTest extends DescriptorTest<IMolecularDescriptor> {

private static DictionaryDatabase dictDB = new DictionaryDatabase();
private static Dictionary dict = dictDB.getDictionary("descriptor-algorithms");

public MolecularDescriptorTest() {}

public void setDescriptor(Class descriptorClass) throws Exception {
if (descriptor == null) {
Object descriptor = descriptorClass.newInstance();
if (!(descriptor instanceof IMolecularDescriptor)) {
throw new CDKException("The passed descriptor class must be a IMolecularDescriptor");
}
this.descriptor = (IMolecularDescriptor)descriptor;
}
super.setDescriptor(descriptorClass);
}

@Test
@Test
public void testDescriptorIdentifierExistsInOntology() {
Entry ontologyEntry = dict.getEntry(
descriptor.getSpecification().getSpecificationReference()
Expand Down

0 comments on commit f30e2b2

Please sign in to comment.