FactoryEnumerationpublic final class FactoryEnumeration extends Object The FactoryEnumeration is used for returning factory instances. |
Fields Summary |
---|
private List | factories | private int | posn | private ClassLoader | loader |
Constructors Summary |
---|
FactoryEnumeration(List factories, ClassLoader loader)Records the input list and uses it directly to satisfy
hasMore()/next() requests. An alternative would have been to use
an enumeration/iterator from the list, but we want to update the
list so we keep the
original list. The list initially contains Class objects.
As each element is used, the Class object is replaced by an
instance of the Class itself; eventually, the list contains
only a list of factory instances and no more updates are required.
Both Class objects and factories are wrapped in weak
references so as not to prevent GC of the class loader. Each
weak reference is tagged with the factory's class name so the
class can be reloaded if the reference is cleared.
this.factories = factories;
this.loader = loader;
|
Methods Summary |
---|
public boolean | hasMore()
synchronized (factories) {
return posn < factories.size();
}
| public java.lang.Object | next()
synchronized (factories) {
NamedWeakReference ref = (NamedWeakReference) factories.get(posn++);
Object answer = ref.get();
if ((answer != null) && !(answer instanceof Class)) {
return answer;
}
String className = ref.getName();
try {
if (answer == null) { // reload class if weak ref cleared
answer = Class.forName(className, true, loader);
}
// Instantiate Class to get factory
answer = ((Class) answer).newInstance();
ref = new NamedWeakReference(answer, className);
factories.set(posn-1, ref); // replace Class object or null
return answer;
} catch (ClassNotFoundException e) {
NamingException ne =
new NamingException("No longer able to load " + className);
ne.setRootCause(e);
throw ne;
} catch (InstantiationException e) {
NamingException ne =
new NamingException("Cannot instantiate " + answer);
ne.setRootCause(e);
throw ne;
} catch (IllegalAccessException e) {
NamingException ne = new NamingException("Cannot access " + answer);
ne.setRootCause(e);
throw ne;
}
}
|
|