/************************************************************************************** * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package com.espertech.esper.epl.spec; import com.espertech.esper.client.ConfigurationException; import com.espertech.esper.client.ConfigurationPlugInPatternObject; import com.espertech.esper.client.ConfigurationPlugInView; import com.espertech.esper.client.ConfigurationPlugInVirtualDataWindow; import com.espertech.esper.collection.Pair; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Repository for pluggable objects of different types that follow a "namespace:name" notation. */ public class PluggableObjectCollection { // Map of namespace, name and class plus type private Map<String, Map<String, Pair<Class, PluggableObjectEntry>>> pluggables; /** * Ctor. */ public PluggableObjectCollection() { pluggables = new HashMap<String, Map<String, Pair<Class, PluggableObjectEntry>>>(); } /** * Add a plug-in view. * @param configurationPlugInViews is a list of configured plug-in view objects. * @throws ConfigurationException if the configured views don't resolve */ public void addViews(List<ConfigurationPlugInView> configurationPlugInViews, List<ConfigurationPlugInVirtualDataWindow> configurationPlugInVirtualDW) throws ConfigurationException { initViews(configurationPlugInViews); initVirtualDW(configurationPlugInVirtualDW); } /** * Add a plug-in pattern object. * @param configPattern is a list of configured plug-in pattern objects. * @throws ConfigurationException if the configured patterns don't resolve */ public void addPatternObjects(List<ConfigurationPlugInPatternObject> configPattern) throws ConfigurationException { initPatterns(configPattern); } /** * Add the plug-in objects for another collection. * @param other is the collection to add */ public void addObjects(PluggableObjectCollection other) { for (Map.Entry<String, Map<String, Pair<Class, PluggableObjectEntry>>> entry : other.getPluggables().entrySet()) { Map<String, Pair<Class, PluggableObjectEntry>> namespaceMap = pluggables.get(entry.getKey()); if (namespaceMap == null) { namespaceMap = new HashMap<String, Pair<Class, PluggableObjectEntry>>(); pluggables.put(entry.getKey(), namespaceMap); } for (String name : entry.getValue().keySet()) { if (namespaceMap.containsKey(name)) { throw new ConfigurationException("Duplicate object detected in namespace '" + entry.getKey() + "' by name '" + name + "'"); } } namespaceMap.putAll(entry.getValue()); } } /** * Add a single object to the collection. * @param namespace is the object's namespace * @param name is the object's name * @param clazz is the class the object resolves to * @param type is the object type */ public void addObject(String namespace, String name, Class clazz, PluggableObjectType type) { addObject(namespace, name, clazz, type, null); } /** * Add a single object to the collection also adding additional configuration. * @param namespace is the object's namespace * @param name is the object's name * @param clazz is the class the object resolves to * @param type is the object type */ public void addObject(String namespace, String name, Class clazz, PluggableObjectType type, Serializable configuration) { Map<String, Pair<Class, PluggableObjectEntry>> namespaceMap = pluggables.get(namespace); if (namespaceMap == null) { namespaceMap = new HashMap<String, Pair<Class, PluggableObjectEntry>>(); pluggables.put(namespace, namespaceMap); } namespaceMap.put(name, new Pair<Class, PluggableObjectEntry>(clazz, new PluggableObjectEntry(type, configuration))); } /** * Returns the underlying nested map of namespace keys and name-to-object maps. * @return pluggable object collected */ public Map<String, Map<String, Pair<Class, PluggableObjectEntry>>> getPluggables() { return pluggables; } private void initViews(List<ConfigurationPlugInView> configurationPlugInViews) { if (configurationPlugInViews == null) { return; } for (ConfigurationPlugInView entry : configurationPlugInViews) { handleAddPluggableObject(entry.getFactoryClassName(), entry.getNamespace(), entry.getName(), PluggableObjectType.VIEW, null); } } private void initVirtualDW(List<ConfigurationPlugInVirtualDataWindow> configurationPlugInVirtualDataWindows) { if (configurationPlugInVirtualDataWindows == null) { return; } for (ConfigurationPlugInVirtualDataWindow entry : configurationPlugInVirtualDataWindows) { handleAddPluggableObject(entry.getFactoryClassName(), entry.getNamespace(), entry.getName(), PluggableObjectType.VIRTUALDW, entry.getConfig()); } } private void handleAddPluggableObject(String factoryClassName, String namespace, String name, PluggableObjectType type, Serializable optionalCustomConfig) { if (factoryClassName == null) { throw new ConfigurationException("Factory class name has not been supplied for object '" + name + "'"); } if (namespace == null) { throw new ConfigurationException("Namespace name has not been supplied for object '" + name + "'"); } if (name == null) { throw new ConfigurationException("Name has not been supplied for object in namespace '" + namespace + "'"); } Class clazz; try { ClassLoader cl = Thread.currentThread().getContextClassLoader(); clazz = Class.forName(factoryClassName, true, cl); } catch (ClassNotFoundException ex) { throw new ConfigurationException("View factory class " + factoryClassName + " could not be loaded"); } Map<String, Pair<Class, PluggableObjectEntry>> namespaceMap = pluggables.get(namespace); if (namespaceMap == null) { namespaceMap = new HashMap<String, Pair<Class, PluggableObjectEntry>>(); pluggables.put(namespace, namespaceMap); } namespaceMap.put(name, new Pair<Class, PluggableObjectEntry>(clazz, new PluggableObjectEntry(type, optionalCustomConfig))); } private void initPatterns(List<ConfigurationPlugInPatternObject> configEntries) throws ConfigurationException { if (configEntries == null) { return; } for (ConfigurationPlugInPatternObject entry : configEntries) { if (entry.getPatternObjectType() == null) { throw new ConfigurationException("Pattern object type has not been supplied for object '" + entry.getName() + "'"); } PluggableObjectType typeEnum; if (entry.getPatternObjectType() == ConfigurationPlugInPatternObject.PatternObjectType.GUARD) { typeEnum = PluggableObjectType.PATTERN_GUARD; } else if (entry.getPatternObjectType() == ConfigurationPlugInPatternObject.PatternObjectType.OBSERVER) { typeEnum = PluggableObjectType.PATTERN_OBSERVER; } else { throw new IllegalArgumentException("Pattern object type '" + entry.getPatternObjectType() + "' not known"); } handleAddPluggableObject(entry.getFactoryClassName(), entry.getNamespace(), entry.getName(), typeEnum, null); } } }