package org.etk.kernel.container.util; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import org.etk.common.logging.Logger; import org.etk.kernel.container.KernelContainer; import org.etk.kernel.container.configuration.ConfigurationManager; import org.etk.kernel.container.xml.Component; import org.etk.kernel.container.xml.ComponentLifecyclePlugin; import org.etk.kernel.container.xml.ContainerLifecyclePlugin; import org.etk.kernel.container.xml.Deserializer; import org.picocontainer.defaults.ConstructorInjectionComponentAdapter; @SuppressWarnings("unchecked") public class ContainerUtil { /** The logger. */ private static final Logger log = Logger.getLogger(ContainerUtil.class); static public Constructor<?>[] getSortedConstructors(Class<?> clazz) throws NoClassDefFoundError { Constructor<?>[] constructors = clazz.getConstructors(); for (int i = 0; i < constructors.length; i++) { for (int j = i + 1; j < constructors.length; j++) { if (constructors[i].getParameterTypes().length < constructors[j] .getParameterTypes().length) { Constructor<?> tmp = constructors[i]; constructors[i] = constructors[j]; constructors[j] = tmp; } } } return constructors; } static public Collection<URL> getConfigurationURL(String configuration) throws Exception { ClassLoader cl = Thread.currentThread().getContextClassLoader(); Collection c = Collections.list(cl.getResources(configuration)); Map<String, URL> map = new HashMap<String, URL>(); Iterator i = c.iterator(); while (i.hasNext()) { URL url = (URL) i.next(); String key = url.toString(); // jboss bug, jboss has a very weird behavior. It copy all the jar // files // and // deploy them to a temp dir and include both jars, the one in sar // and tmp // dir, // in the class path. It cause the configuration run twice int index1 = key.lastIndexOf("exo-"); int index2 = key.lastIndexOf("etk."); int index = index1 < index2 ? index2 : index1; if (index >= 0) key = key.substring(index); map.put(key, url); } i = map.values().iterator(); // while(i.hasNext()) { // URL url = (URL) i.next() ; // System.out.println("==> Add " + url); // } return map.values(); } static public void addContainerLifecyclePlugin(KernelContainer container, ConfigurationManager conf) { Iterator i = conf.getConfiguration().getContainerLifecyclePluginIterator(); while (i.hasNext()) { ContainerLifecyclePlugin plugin = (ContainerLifecyclePlugin) i.next(); addContainerLifecyclePlugin(container, plugin); } } private static void addContainerLifecyclePlugin(KernelContainer container, ContainerLifecyclePlugin plugin) { try { Class clazz = Class.forName(plugin.getType()); org.etk.kernel.container.ContainerLifecyclePlugin cplugin = (org.etk.kernel.container.ContainerLifecyclePlugin) container.createComponent(clazz, plugin.getInitParams()); cplugin.setName(plugin.getName()); cplugin.setDescription(plugin.getDescription()); container.addContainerLifecylePlugin(cplugin); } catch (Exception ex) { log.error("Failed to instanciate plugin " + plugin.getType() + ": " + ex.getMessage(), ex); } } static public void addComponentLifecyclePlugin(KernelContainer container, ConfigurationManager conf) { Collection plugins = conf.getConfiguration().getComponentLifecyclePlugins(); Iterator i = plugins.iterator(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); while (i.hasNext()) { ComponentLifecyclePlugin plugin = (ComponentLifecyclePlugin) i.next(); try { Class classType = loader.loadClass(plugin.getType()); org.etk.kernel.container.ComponentLifecyclePlugin instance = (org.etk.kernel.container.ComponentLifecyclePlugin) classType.newInstance(); container.addComponentLifecylePlugin(instance); } catch (Exception ex) { log.error("Failed to instanciate plugin " + plugin.getType() + ": " + ex.getMessage(), ex); } } } static public void addComponents(KernelContainer container, ConfigurationManager conf) { Collection components = conf.getComponents(); if (components == null) return; Iterator i = components.iterator(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); while (i.hasNext()) { Component component = (Component) i.next(); String type = component.getType(); String key = component.getKey(); try { Class classType = loader.loadClass(type); if (key == null) { if (component.isMultiInstance()) { container.registerComponent(new ConstructorInjectionComponentAdapter(classType, classType)); log.debug("===>>> Thread local component " + classType.getName() + " registered."); } else { container.registerComponentImplementation(classType); } } else { try { Class keyType = loader.loadClass(key); if (component.isMultiInstance()) { container.registerComponent(new ConstructorInjectionComponentAdapter(keyType, classType)); log.debug("===>>> Thread local component " + classType.getName() + " registered."); } else { container.registerComponentImplementation(keyType, classType); } } catch (Exception ex) { container.registerComponentImplementation(key, classType); } } } catch (ClassNotFoundException ex) { log.error("Cannot register the component corresponding to key = '" + key + "' and type = '" + type + "'", ex); } } } /** * Loads the properties file corresponding to the given url * * @param url * the url of the properties file * @return a {@link Map} of properties */ public static Map<String, String> loadProperties(URL url) { return loadProperties(url, true); } /** * Loads the properties file corresponding to the given url * * @param url * the url of the properties file * @param resolveVariables * indicates if the variables must be resolved * @return a {@link Map} of properties */ public static Map<String, String> loadProperties(URL url, boolean resolveVariables) { LinkedHashMap<String, String> props = null; String path = null; InputStream in = null; try { // if (url != null) { path = url.getPath(); in = url.openStream(); } // if (in != null) { String fileName = url.getFile(); if (Tools.endsWithIgnoreCase(path, ".properties")) { if (log.isDebugEnabled()) log.debug("Attempt to load property file " + path); props = PropertiesLoader.load(in); } else if (Tools.endsWithIgnoreCase(fileName, ".xml")) { if (log.isDebugEnabled()) log.debug("Attempt to load property file " + path + " with XML format"); props = PropertiesLoader.loadFromXML(in); } else if (log.isDebugEnabled()) { log.debug("Will not load property file" + path + " because its format is not recognized"); } if (props != null && resolveVariables) { // Those properties are used for variables resolution final Map<String, Object> currentProps = new HashMap<String, Object>(); for (Map.Entry<String, String> entry : props.entrySet()) { String propertyName = entry.getKey(); String propertyValue = entry.getValue(); propertyValue = Deserializer.resolveVariables( propertyValue, currentProps); props.put(propertyName, propertyValue); currentProps.put(propertyName, propertyValue); } } } else { log.error("Could not load property file " + path); } } catch (Exception e) { log.error("Cannot load property file " + path, e); } finally { if (in != null) { try { in.close(); } catch (IOException ignore) { } } } return props; } }