org.hawkular.alerts.actions.bus.ActionPlugins Maven / Gradle / Ivy
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.alerts.actions.bus;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hawkular.alerts.actions.api.ActionPluginListener;
import org.hawkular.alerts.actions.api.ActionPluginSender;
import org.hawkular.alerts.actions.api.Global;
import org.hawkular.alerts.actions.api.Plugin;
import org.hawkular.alerts.actions.api.Sender;
import org.jboss.vfs.VirtualFile;
/**
* Helper class to find the classes annotated with ActionPlugin and instantiate them.
*
* @author Lucas Ponce
*/
public class ActionPlugins {
private static ActionPlugins instance;
private Map plugins;
private Set globals;
private Map senders;
public static synchronized Map getPlugins() {
if (instance == null) {
instance = new ActionPlugins();
}
return Collections.unmodifiableMap(instance.plugins);
}
public static synchronized Set getGlobals() {
if (instance == null) {
instance = new ActionPlugins();
}
return Collections.unmodifiableSet(instance.globals);
}
public static synchronized Map getSenders() {
if (instance == null) {
instance = new ActionPlugins();
}
return Collections.unmodifiableMap(instance.senders);
}
private ActionPlugins() {
try {
plugins = new HashMap<>();
globals = new HashSet<>();
senders = new HashMap<>();
URL webInfUrl = getWebInfUrl();
List pluginClasses = findAnnotationInClasses(webInfUrl, Plugin.class);
for (Class pluginClass : pluginClasses) {
Annotation actionPlugin = pluginClass.getDeclaredAnnotation(Plugin.class);
if (actionPlugin instanceof Plugin) {
String name = ((Plugin) actionPlugin).name();
Object newInstance = pluginClass.newInstance();
if (newInstance instanceof ActionPluginListener) {
ActionPluginListener pluginInstance = (ActionPluginListener)newInstance;
injectActionPluginSender(name, pluginInstance);
plugins.put(name, pluginInstance);
if (pluginClass.isAnnotationPresent(Global.class)) {
globals.add(name);
}
} else {
throw new IllegalStateException("Plugin [" + name + "] is not instance of " +
"ActionPluginListener");
}
}
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private URL getWebInfUrl() throws Exception {
Enumeration allUrls = Thread.currentThread().getContextClassLoader().getResources("");
while (allUrls != null && allUrls.hasMoreElements()) {
URL url = allUrls.nextElement();
if (url.toExternalForm().contains("WEB-INF/classes")) {
return url;
}
}
return null;
}
private List findAnnotationInClasses(URL url, Class annotation) throws Exception {
if (url == null || annotation == null) {
throw new IllegalArgumentException("url or annotation must be not null");
}
List plugins = new ArrayList<>();
URLConnection conn = url.openConnection();
VirtualFile root = (VirtualFile)conn.getContent();
List children = root.getChildrenRecursively();
for (VirtualFile vf : children) {
String vfName = vf.toURI().toString();
if (vfName.endsWith(".class")) {
int startName = vfName.indexOf("classes/") + 8;
int stopName = vfName.indexOf(".class");
String className = vfName.substring(startName, stopName).replace("/", ".");
Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
if (clazz.isAnnotationPresent(annotation)) {
plugins.add(clazz);
}
}
}
return plugins;
}
/*
Search and inject ActionPluginSender inside ActionPluginListener
*/
private void injectActionPluginSender(String actionPlugin, ActionPluginListener pluginInstance) throws Exception {
if (pluginInstance == null) {
throw new IllegalArgumentException("pluginInstance must be not null");
}
Field[] fields = pluginInstance.getClass().getDeclaredFields();
Field sender = null;
for (Field field : fields) {
if (field.isAnnotationPresent(Sender.class) &&
field.getType().isAssignableFrom(ActionPluginSender.class)) {
sender = field;
break;
}
}
if (sender != null) {
ActionPluginSender busSender = new BusActionPluginSender(actionPlugin);
sender.setAccessible(true);
sender.set(pluginInstance, busSender);
senders.put(actionPlugin, busSender);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy