Package org.openscience.cdk
Class DynamicFactory
- java.lang.Object
-
- org.openscience.cdk.DynamicFactory
-
public class DynamicFactory extends Object
A factory class for constructingICDKObject
andIChemObject
implementations. Instances can be created by registering a construction key (DynamicFactory.ConstructorKey
) with a corresponding creator (DynamicFactory.Creator
). In most cases a class can simply be registered by providing an interface and an implementationregister(Class, Class)
. Internally the factory stores the object creators in a symbol table which allows near constant time access for all registered classes. In cases of a non-direct parameter match (e.g.Atom(Atom)
can resolve toAtom(Element)
) the constructor is matched by invokingfind(ConstructorKey)
. If a constructor was found the new key will be registered with cache to avoid the overhead of finding the correct constructor again.
It is not always convenient to specify a custom// create an instance of the factory DynamicFactory factory = new DynamicFactory(5); // register some implementations factory.register(IAtom.class, Atom.class); factory.register(IElement.class, Element.class); factory.register(IAtomContainer.class, AtomContainer.class); // create an instance using the default constructor IAtom a1 = factory.ofClass(IAtom.class); // create an instance using a parametrised constructor IAtom c = factory.ofClass(IAtom.class, "C"); // using a custom creator to actually invoke a constructor // import static org.openscience.cdk.DynamicFactory.key; // import static org.openscience.cdk.DynamicFactory.BasicCreator; factory.register(key(IBond.class, IAtom[].class), new BasicCreator<IAtom>(null) { public IAtom create(Object[] objects) { return new Bond((IAtom[]) objects); } });
DynamicFactory.Creator
for every construction type but the objects may still need some modification directly after creation. The factory providesDynamicFactory.CreationModifier
which is invoked directly after object creation. This allows changing the default of creation. As an example it is possible to set a non-null charge on all atoms that are created.
It is also possible change the object creation based on the input parameters.// import static org.openscience.cdk.DynamicFactory.CreationModifier; factory.register(IAtom.class, Atom.class, new CreationModifier<Atom>() { public void modify(Atom atom) { atom.setFormalCharge(0); } }));
factory.register(key(IAtom.class, String.class), new DynamicFactory.BasicCreator<IAtom>() { public IAtom create(Object[] objects) { String symbol = (String) objects[0]; return "R".equals(symbol) ? new PseudoAtom(symbol) : new Atom(symbol); } }); factory.ofClass(IAtom.class, "C"); // IAtom factory.ofClass(IAtom.class, "R"); // IPseudoAtom
- Author:
- John May
- Source code:
- main
- Belongs to CDK module:
- core
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
DynamicFactory.BasicCreator<T>
A simple creator that helps in creating an anonymous classes for a creator.static class
DynamicFactory.ConstructorKey
A class which encapsulates the information about an interface (of this implementation) and the parameter types of the constructor.static interface
DynamicFactory.CreationModifier<T>
An interface that allows posterior modification of an instance after it has been created.static interface
DynamicFactory.Creator<T>
An interface that wraps object creation via theDynamicFactory.Creator.create(Object[])
method.protected static class
DynamicFactory.DefaultInterfaceProvider
A default interface provider implementation that simply returns the classes fromClass.getInterfaces()
.static interface
DynamicFactory.InterfaceProvider
An interface that can provide which interfaces the given class implements.
-
Constructor Summary
Constructors Constructor Description DynamicFactory(int n)
Create a new default factory with an expected number of registered classes and a default interface provider.DynamicFactory(DynamicFactory.InterfaceProvider interfaceProvider, int n)
Create a new default factory with an expected number of registered classes and an interface provider.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description <T extends ICDKObject>
Set<Class<?>>implementorsOf(Class<T> intf)
Access the registered implementations for a given interface.static DynamicFactory.ConstructorKey
key(Class<?> intf, Class<?>... types)
Creates a constructor key for use in accessing constructors.<T extends ICDKObject>
TofClass(Class<T> intf)
Construct an implementation using the default constructor.<T extends ICDKObject>
TofClass(Class<T> intf, Object... objects)
Construct an implementation using a constructor whose parameters match that of the provided objects.<T extends ICDKObject>
booleanregister(Class<? extends T> impl)
Registers a class with the factory.<S extends ICDKObject,T extends S>
booleanregister(Class<S> intf, Class<T> impl, DynamicFactory.CreationModifier<T> modifier)
Explicitly register a concrete class with a provided interface and a given modifier.<S extends ICDKObject,T extends S>
booleanregister(Class<S> intf, Constructor<T> constructor)
Register a specific constructor with an explicit interface.<S extends ICDKObject,T extends S>
booleanregister(Class<S> intf, Constructor<T> constructor, DynamicFactory.CreationModifier<T> modifier)
Register a specific constructor with a creation modifier to an explicit interface.<T extends ICDKObject>
booleanregister(Class<T> intf, Class<? extends T> impl)
Explicitly register a concrete class with a provided interface.<T> DynamicFactory.Creator<T>
register(DynamicFactory.ConstructorKey key, DynamicFactory.Creator<T> creator)
Register a constructor key with a definedDynamicFactory.Creator
.Iterator<DynamicFactory.ConstructorKey>
suggest(Class<?> intf)
Provides a list of all possible constructor keys for the provided interface.
-
-
-
Constructor Detail
-
DynamicFactory
public DynamicFactory(DynamicFactory.InterfaceProvider interfaceProvider, int n)
Create a new default factory with an expected number of registered classes and an interface provider. The interface provider is used when registering an implementation without a specified interfaceregister(Class)
.- Parameters:
interfaceProvider
- provides the interfaces of a given implementation classn
- the expected number of constructors that will be stored.- See Also:
DynamicFactory(int)
-
DynamicFactory
public DynamicFactory(int n)
Create a new default factory with an expected number of registered classes and a default interface provider. The default interface provider simply invokesClass.getInterfaces()
when registering an implementation without an explicit interfaceregister(Class)
.- Parameters:
n
- the expected number of constructors that will be stored.
-
-
Method Detail
-
register
public <T extends ICDKObject> boolean register(Class<? extends T> impl)
Registers a class with the factory. The interfaces of the class will be checked to see if they are CDK interfaces before they are registered. This method is provided for utility but will register the implementation with all valid interfaces. If a restricted registration is required then the saferregister(Class, Class)
can be used.- Parameters:
impl
- a concrete class- Throws:
IllegalArgumentException
- thrown if a non-concrete class is registered- See Also:
register(Class, Class)
,register(Class, java.lang.reflect.Constructor)
,register(org.openscience.cdk.DynamicFactory.ConstructorKey, org.openscience.cdk.DynamicFactory.Creator)
-
register
public <T extends ICDKObject> boolean register(Class<T> intf, Class<? extends T> impl)
Explicitly register a concrete class with a provided interface. TheDynamicFactory.Creator
will be automatically created for all public constructors.- Parameters:
intf
- the interface class to registerimpl
- the concrete class which should implement the interface class- Returns:
- whether registration was successful
-
register
public <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Class<T> impl, DynamicFactory.CreationModifier<T> modifier)
Explicitly register a concrete class with a provided interface and a given modifier. TheDynamicFactory.Creator
will be automatically created for all public constructors. The modifier is incorporated into theDynamicFactory.Creator
and is invoked directly after instantiation.// import static org.openscience.cdk.DynamicFactory.CreationModifier; factory.register(IAtom.class, Atom.class, new CreationModifier<Atom>() { public void modify(Atom atom) { atom.setFormalCharge(0); } }));
- Type Parameters:
S
- interface typeT
- implementation type (must extend interface)- Parameters:
intf
- the interface class to registerimpl
- the concrete class which should implement the interface classmodifier
- modify a instance after creation- Returns:
- whether registration was successful
-
register
public <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Constructor<T> constructor)
Register a specific constructor with an explicit interface.// only register construction of IAtom using a string - Atom("C") factory.register(IAtom.class, Atom.class.getConstructor(String.class));
- Type Parameters:
S
- interface typeT
- implementation type (must extend interface)- Parameters:
intf
- the interfaceconstructor
- a constructor which builds the given interface- Returns:
- whether the constructor was registered
-
register
public <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Constructor<T> constructor, DynamicFactory.CreationModifier<T> modifier)
Register a specific constructor with a creation modifier to an explicit interface.// only register construction of IAtom using a string - Atom("C") factory.register(IAtom.class, Atom.class.getConstructor(String.class), new DynamicFactory.CreationModifier<Atom>() { public void modify(Atom instance) { instance.setFormalCharge(0); } });
- Type Parameters:
S
- interface typeT
- implementation type (must extend interface)- Parameters:
intf
- the interfaceconstructor
- a constructor which builds the given interface- Returns:
- whether the constructor was registered
-
register
public <T> DynamicFactory.Creator<T> register(DynamicFactory.ConstructorKey key, DynamicFactory.Creator<T> creator)
Register a constructor key with a definedDynamicFactory.Creator
. The key defines the interface and parameters of the creation and the creator actually creates the object.// import static org.openscience.cdk.DynamicFactory.key; factory.register(key(IBond.class, IAtom[].class), new BasicCreator<IAtom>(null) { public IAtom create(Object[] objects) { return new Bond((IAtom[]) objects); } });
- Type Parameters:
T
- type of object that will be created- Parameters:
key
- construction key, defines interface and parameter typescreator
- creates the actual object- Returns:
- the registered creator - null if not registered
-
key
public static DynamicFactory.ConstructorKey key(Class<?> intf, Class<?>... types)
Creates a constructor key for use in accessing constructors. The key combines the interface and types in a single instance which we can then use in a map.- Parameters:
intf
- the interface to build the key fortypes
- the classes that the the constructor requires- Returns:
- a constructor key which can be used to lookup a constructor
-
ofClass
public <T extends ICDKObject> T ofClass(Class<T> intf, Object... objects)
Construct an implementation using a constructor whose parameters match that of the provided objects.- Type Parameters:
T
- the type of the class- Parameters:
intf
- the interface to construct an instance of- Returns:
- an implementation of provided interface
- Throws:
IllegalArgumentException
- thrown if the implementation can not be constructedIllegalArgumentException
- thrown if the provided class is not an interface
-
ofClass
public <T extends ICDKObject> T ofClass(Class<T> intf)
Construct an implementation using the default constructor. This provides some speed boost over invokingofClass(Class, Object...)
.- Type Parameters:
T
- the type of the class- Parameters:
intf
- the interface to construct an instance of- Returns:
- an implementation of provided interface constructed using the default constructor.
- Throws:
IllegalArgumentException
- thrown if the implementation can not be constructedIllegalArgumentException
- thrown if the provided class is not an interface
-
implementorsOf
public <T extends ICDKObject> Set<Class<?>> implementorsOf(Class<T> intf)
Access the registered implementations for a given interface.- Type Parameters:
T
- the type of the interface- Parameters:
intf
- an interface which has registered implementations in the factory- Returns:
- set of implementation classes (empty if none found)
-
suggest
public Iterator<DynamicFactory.ConstructorKey> suggest(Class<?> intf)
Provides a list of all possible constructor keys for the provided interface.- Parameters:
intf
- an interface to find all constructors for- Returns:
- an iterator of constructor keys
-
-