in mixins/core-mixins/src/main/java/org/apache/axiom/core/NodeFactoryImpl.java [41:120]
public NodeFactoryImpl(ClassLoader cl, String factory2ClassName, String... packages) {
try {
factory2 =
(NodeFactory2)
cl.loadClass(factory2ClassName).getDeclaredField("INSTANCE").get(null);
} catch (ReflectiveOperationException ex) {
throw new NodeFactoryException("Failed to instantiate NodeFactory2 implementation", ex);
}
List<Class<?>> implementations = new ArrayList<Class<?>>();
for (String pkg : packages) {
try {
BufferedReader in =
new BufferedReader(
new InputStreamReader(
cl.getResourceAsStream(
pkg.replace('.', '/') + "/nodetypes.index"),
StandardCharsets.UTF_8));
try {
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith("#")) {
continue;
}
String className = pkg + "." + line;
try {
implementations.add(cl.loadClass(className));
} catch (ClassNotFoundException ex) {
throw new NodeFactoryException("Failed to load class " + className, ex);
}
}
} finally {
in.close();
}
} catch (IOException ex) {
throw new NodeFactoryException(
"Failed to load node type index for package " + pkg, ex);
}
}
implementations =
TopologicalSort.sort(
implementations,
new EdgeRelation<Class<?>>() {
@Override
public boolean isEdge(Class<?> from, Class<?> to) {
return to.isAssignableFrom(from);
}
});
Map<Class<?>, Class<?>> interfaceToImplementationMap = new HashMap<Class<?>, Class<?>>();
Map<Class<?>, Constructor<?>> implementationToConstructorMap =
new HashMap<Class<?>, Constructor<?>>();
Set<Class<?>> ambiguousInterfaces = new HashSet<Class<?>>();
for (Class<?> implementation : implementations) {
Set<Class<?>> interfaces = new HashSet<Class<?>>();
collectInterfaces(implementation, interfaces);
for (Class<?> iface : interfaces) {
if (!ambiguousInterfaces.contains(iface)) {
Class<?> clazz = interfaceToImplementationMap.get(iface);
if (clazz == null || implementation.isAssignableFrom(clazz)) {
interfaceToImplementationMap.put(iface, implementation);
} else if (!clazz.isAssignableFrom(implementation)) {
interfaceToImplementationMap.remove(iface);
ambiguousInterfaces.add(iface);
}
}
}
try {
implementationToConstructorMap.put(implementation, implementation.getConstructor());
} catch (NoSuchMethodException ex) {
throw new NodeFactoryException(
"Failed to get constructor for " + implementation.getName(), ex);
}
}
constructorMap = new HashMap<Class<?>, Constructor<?>>();
for (Map.Entry<Class<?>, Class<?>> entry : interfaceToImplementationMap.entrySet()) {
constructorMap.put(
entry.getKey(), implementationToConstructorMap.get(entry.getValue()));
}
// TODO: this should eventually go away
constructorMap.putAll(implementationToConstructorMap);
}