use of org.spongepowered.common.event.filter.FilterFactory in project SpongeCommon by SpongePowered.
the class SpongeEventManager method registerListener.
private void registerListener(final PluginContainer plugin, final Object listenerObject) {
Objects.requireNonNull(plugin, "plugin");
Objects.requireNonNull(listenerObject, "listener");
if (this.registeredListeners.contains(listenerObject)) {
SpongeCommon.logger().warn("Plugin {} attempted to register an already registered listener ({})", plugin.metadata().id(), listenerObject.getClass().getName());
Thread.dumpStack();
return;
}
final List<RegisteredListener<? extends Event>> handlers = new ArrayList<>();
final Map<ListenerClassVisitor.DiscoveredMethod, String> methodErrors = new HashMap<>();
final Class<?> handle = listenerObject.getClass();
final ClassLoader handleLoader = handle.getClassLoader();
AnnotatedEventListener.Factory handlerFactory = this.classLoaders.get(handleLoader);
if (handlerFactory == null) {
final DefineableClassLoader classLoader = new DefineableClassLoader(handleLoader);
handlerFactory = new ClassEventListenerFactory("org.spongepowered.common.event.listener", new FilterFactory("org.spongepowered.common.event.filters", classLoader), classLoader);
this.classLoaders.put(handleLoader, handlerFactory);
}
try {
final List<ListenerClassVisitor.DiscoveredMethod> methods = ListenerClassVisitor.getEventListenerMethods(handle);
for (final ListenerClassVisitor.DiscoveredMethod method : methods) {
final Listener listener = method.listener();
@Nullable final String error = SpongeEventManager.getHandlerErrorOrNull(method);
if (error == null) {
final Type eventType = method.parameterTypes()[0].genericType();
final AnnotatedEventListener handler;
try {
handler = handlerFactory.create(listenerObject, method);
} catch (final Exception e) {
SpongeCommon.logger().error("Failed to create handler for {} on {}", method, handle, e);
continue;
}
handlers.add(SpongeEventManager.createRegistration(plugin, eventType, listener.order(), listener.beforeModifications(), handler));
} else {
methodErrors.put(method, error);
}
}
} catch (final IOException ioe) {
SpongeCommon.logger().warn("Exception trying to register superclass listeners", ioe);
} catch (final NoSuchMethodException nsme) {
SpongeCommon.logger().warn("Discovered method listener somehow not found for class " + handle.getName(), nsme);
} catch (final ClassNotFoundException e) {
SpongeCommon.logger().warn("Somehow couldn't classload a class while trying to register event listeners for containing class: " + handle.getName(), e);
}
// about those.
for (Class<?> handleParent = handle; handleParent != Object.class; handleParent = handleParent.getSuperclass()) {
try {
final List<ListenerClassVisitor.DiscoveredMethod> methods = ListenerClassVisitor.getEventListenerMethods(handleParent);
for (final ListenerClassVisitor.DiscoveredMethod method : methods) {
if (!methodErrors.containsKey(method)) {
@Nullable final String error = SpongeEventManager.getHandlerErrorOrNull(method);
if (error != null) {
methodErrors.put(method, error);
}
}
}
} catch (final RuntimeException re) {
// This is the Forge classloader that checks for client sided classes
if (re.getMessage().startsWith("Attempted to load class")) {
continue;
}
SpongeCommon.logger().warn("Exception trying to register superclass listeners", re);
} catch (final Exception e) {
SpongeCommon.logger().warn("Attempted to register listeners but had an exception loading listeners for super classes", e);
}
}
for (final Map.Entry<ListenerClassVisitor.DiscoveredMethod, String> method : methodErrors.entrySet()) {
SpongeCommon.logger().warn("Invalid listener method {} in {}: {}", method.getKey(), method.getKey().declaringClass().getName(), method.getValue());
}
this.registeredListeners.add(listenerObject);
this.register(handlers);
}
Aggregations