com.espertech.esper.client.Configuration.java Source code

Java tutorial

Introduction

Here is the source code for com.espertech.esper.client.Configuration.java

Source

/**************************************************************************************
 * 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.client;

import com.espertech.esper.dataflow.ops.BeaconSource;
import com.espertech.esper.event.EventTypeUtility;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;

import java.io.*;
import java.net.URI;
import java.net.URL;
import java.util.*;

/**
 * An instance of <tt>Configuration</tt> allows the application
 * to specify properties to be used when
 * creating a <tt>EPServiceProvider</tt>. Usually an application will create
 * a single <tt>Configuration</tt>, then get one or more instances of
 * {@link EPServiceProvider} via {@link EPServiceProviderManager}.
 * The <tt>Configuration</tt> is meant
 * only as an initialization-time object. <tt>EPServiceProvider</tt>s are
 * immutable and do not retain any association back to the
 * <tt>Configuration</tt>.
 * <br>
 * The format of an Esper XML configuration file is defined in
 * <tt>esper-configuration-2.0.xsd</tt>.
 */
public class Configuration implements ConfigurationOperations, ConfigurationInformation, Serializable {
    private static final long serialVersionUID = -220881974438617882L;
    private static Log log = LogFactory.getLog(Configuration.class);

    /**
     * Default name of the configuration file.
     */
    protected static final String ESPER_DEFAULT_CONFIG = "esper.cfg.xml";

    /**
     * Map of event name and fully-qualified class name.
     */
    protected Map<String, String> eventClasses;

    /**
     * Map of event type name and XML DOM configuration.
     */
    protected Map<String, ConfigurationEventTypeXMLDOM> eventTypesXMLDOM;

    /**
     * Map of event type name and Legacy-type event configuration.
     */
    protected Map<String, ConfigurationEventTypeLegacy> eventTypesLegacy;

    /**
     * The type names for events that are backed by java.util.Map,
      * not containing strongly-typed nested maps.
     */
    protected Map<String, Properties> mapNames;

    /**
     * The type names for events that are backed by java.util.Map,
     * possibly containing strongly-typed nested maps.
     * <p>
     * Each entrie's value must be either a Class or a Map<String,Object> to
     * define nested maps.
     */
    protected Map<String, Map<String, Object>> nestableMapNames;

    /**
     * The type names for events that are backed by java.util.Map,
     * possibly containing strongly-typed nested maps.
     * <p>
     * Each entrie's value must be either a Class or a Map<String,Object> to
     * define nested maps.
     */
    protected Map<String, Map<String, Object>> nestableObjectArrayNames;

    /**
     * Map event types additional configuration information.
     */
    protected Map<String, ConfigurationEventTypeMap> mapTypeConfigurations;

    /**
     * Map event types additional configuration information.
     */
    protected Map<String, ConfigurationEventTypeObjectArray> objectArrayTypeConfigurations;

    /**
     * The class and package name imports that
     * will be used to resolve partial class names.
     */
    protected List<String> imports;

    /**
     * The class and package name imports that
     * will be used to resolve partial class names.
     */
    protected Map<String, ConfigurationDBRef> databaseReferences;

    /**
     * Optional classname to use for constructing services context.
     */
    protected String epServicesContextFactoryClassName;

    /**
     * List of configured plug-in views.
     */
    protected List<ConfigurationPlugInView> plugInViews;

    /**
     * List of configured plug-in views.
     */
    protected List<ConfigurationPlugInVirtualDataWindow> plugInVirtualDataWindows;

    /**
     * List of configured plug-in pattern objects.
     */
    protected List<ConfigurationPlugInPatternObject> plugInPatternObjects;

    /**
     * List of configured plug-in aggregation functions.
     */
    protected List<ConfigurationPlugInAggregationFunction> plugInAggregationFunctions;

    /**
     * List of configured plug-in aggregation multi-functions.
     */
    protected List<ConfigurationPlugInAggregationMultiFunction> plugInAggregationMultiFunctions;

    /**
     * List of configured plug-in single-row functions.
     */
    protected List<ConfigurationPlugInSingleRowFunction> plugInSingleRowFunctions;

    /**
     * List of adapter loaders.
     */
    protected List<ConfigurationPluginLoader> pluginLoaders;

    /**
     * Saves engine default configs such as threading settings
     */
    protected ConfigurationEngineDefaults engineDefaults;

    /**
     * Saves the packages to search to resolve event type names.
     */
    protected Set<String> eventTypeAutoNamePackages;

    /**
     * Map of variables.
     */
    protected Map<String, ConfigurationVariable> variables;

    /**
     * Map of class name and configuration for method invocations on that class.
     */
    protected Map<String, ConfigurationMethodRef> methodInvocationReferences;

    /**
     * Map of plug-in event representation name and configuration
     */
    protected Map<URI, ConfigurationPlugInEventRepresentation> plugInEventRepresentation;

    /**
     * Map of plug-in event types.
     */
    protected Map<String, ConfigurationPlugInEventType> plugInEventTypes;

    /**
     * URIs that point to plug-in event representations that are given a chance to dynamically resolve an event type name to an
     * event type, as it occurs in a new EPL statement.
     */
    protected URI[] plugInEventTypeResolutionURIs;

    /**
     * All revision event types which allow updates to past events.
     */
    protected Map<String, ConfigurationRevisionEventType> revisionEventTypes;

    /**
     * Variant streams allow events of disparate types to be treated the same.
     */
    protected Map<String, ConfigurationVariantStream> variantStreams;

    /**
     * Constructs an empty configuration. The auto import values
     * are set by default to java.lang, java.math, java.text and
     * java.util.
     */
    public Configuration() {
        reset();
    }

    /**
     * Sets the class name of the services context factory class to use.
     * @param epServicesContextFactoryClassName service context factory class name
     */
    public void setEPServicesContextFactoryClassName(String epServicesContextFactoryClassName) {
        this.epServicesContextFactoryClassName = epServicesContextFactoryClassName;
    }

    public String getEPServicesContextFactoryClassName() {
        return epServicesContextFactoryClassName;
    }

    public void addPlugInAggregationFunction(String functionName, String aggregationClassName) {
        ConfigurationPlugInAggregationFunction entry = new ConfigurationPlugInAggregationFunction();
        entry.setFunctionClassName(aggregationClassName);
        entry.setName(functionName);
        plugInAggregationFunctions.add(entry);
    }

    public void addPlugInAggregationFunctionFactory(String functionName, String aggregationFactoryClassName)
            throws ConfigurationException {
        ConfigurationPlugInAggregationFunction entry = new ConfigurationPlugInAggregationFunction();
        entry.setName(functionName);
        entry.setFactoryClassName(aggregationFactoryClassName);
        plugInAggregationFunctions.add(entry);
    }

    public void addPlugInAggregationMultiFunction(ConfigurationPlugInAggregationMultiFunction config)
            throws ConfigurationException {
        plugInAggregationMultiFunctions.add(config);
    }

    public void addPlugInSingleRowFunction(String functionName, String className, String methodName)
            throws ConfigurationException {
        addPlugInSingleRowFunction(functionName, className, methodName,
                ConfigurationPlugInSingleRowFunction.ValueCache.DISABLED);
    }

    public void addPlugInSingleRowFunction(String functionName, String className, String methodName,
            ConfigurationPlugInSingleRowFunction.ValueCache valueCache) throws ConfigurationException {
        addPlugInSingleRowFunction(functionName, className, methodName, valueCache,
                ConfigurationPlugInSingleRowFunction.FilterOptimizable.ENABLED);
    }

    public void addPlugInSingleRowFunction(String functionName, String className, String methodName,
            ConfigurationPlugInSingleRowFunction.FilterOptimizable filterOptimizable)
            throws ConfigurationException {
        addPlugInSingleRowFunction(functionName, className, methodName,
                ConfigurationPlugInSingleRowFunction.ValueCache.DISABLED, filterOptimizable);
    }

    /**
     * Add single-row function with configurations.
     * @param functionName EPL name of function
     * @param className providing fully-qualified class name
     * @param methodName providing method name
     * @param valueCache value cache settings
     * @param filterOptimizable settings whether subject to optimizations
     * @throws ConfigurationException thrown to indicate that the configuration is invalid
     */
    public void addPlugInSingleRowFunction(String functionName, String className, String methodName,
            ConfigurationPlugInSingleRowFunction.ValueCache valueCache,
            ConfigurationPlugInSingleRowFunction.FilterOptimizable filterOptimizable)
            throws ConfigurationException {
        addPlugInSingleRowFunction(functionName, className, methodName, valueCache, filterOptimizable, false);
    }

    /**
     * Add single-row function with configurations.
     * @param functionName EPL name of function
     * @param className providing fully-qualified class name
     * @param methodName providing method name
     * @param valueCache value cache settings
     * @param filterOptimizable settings whether subject to optimizations
     * @throws ConfigurationException thrown to indicate that the configuration is invalid
     */
    public void addPlugInSingleRowFunction(String functionName, String className, String methodName,
            ConfigurationPlugInSingleRowFunction.ValueCache valueCache,
            ConfigurationPlugInSingleRowFunction.FilterOptimizable filterOptimizable, boolean rethrowExceptions)
            throws ConfigurationException {
        ConfigurationPlugInSingleRowFunction entry = new ConfigurationPlugInSingleRowFunction();
        entry.setFunctionClassName(className);
        entry.setFunctionMethodName(methodName);
        entry.setName(functionName);
        entry.setValueCache(valueCache);
        entry.setFilterOptimizable(filterOptimizable);
        entry.setRethrowExceptions(rethrowExceptions);
        plugInSingleRowFunctions.add(entry);
    }

    /**
     * Checks if an event type has already been registered for that name.
     * @since 2.1
     * @param eventTypeName the name
     * @return true if already registered
     */
    public boolean isEventTypeExists(String eventTypeName) {
        return eventClasses.containsKey(eventTypeName) || mapNames.containsKey(eventTypeName)
                || nestableMapNames.containsKey(eventTypeName)
                || nestableObjectArrayNames.containsKey(eventTypeName)
                || eventTypesXMLDOM.containsKey(eventTypeName);
        //note: no need to check legacy as they get added as class event type
    }

    /**
     * Add an name for an event type represented by Java-bean plain-old Java object events.
     * @param eventTypeName is the name for the event type
     * @param eventClassName fully-qualified class name of the event type
     */
    public void addEventType(String eventTypeName, String eventClassName) {
        eventClasses.put(eventTypeName, eventClassName);
    }

    /**
     * Add an name for an event type represented by Java-bean plain-old Java object events.
     * @param eventTypeName is the name for the event type
     * @param eventClass is the Java event class for which to add the name
     */
    public void addEventType(String eventTypeName, Class eventClass) {
        addEventType(eventTypeName, eventClass.getName());
    }

    /**
     * Add an name for an event type represented by Java-bean plain-old Java object events,
     * and the name is the simple class name of the class.
     * @param eventClass is the Java event class for which to add the name
     */
    public void addEventType(Class eventClass) {
        addEventType(eventClass.getSimpleName(), eventClass.getName());
    }

    /**
     * Add an name for an event type that represents java.util.Map events.
     * <p>
     * Each entry in the type map is the property name and the fully-qualified
     * Java class name or primitive type name.
     * @param eventTypeName is the name for the event type
     * @param typeMap maps the name of each property in the Map event to the type
     * (fully qualified classname) of its value in Map event instances.
     */
    public void addEventType(String eventTypeName, Properties typeMap) {
        mapNames.put(eventTypeName, typeMap);
    }

    public void addEventType(String eventTypeName, Map<String, Object> typeMap) {
        nestableMapNames.put(eventTypeName, typeMap);
    }

    public void addEventType(String eventTypeName, Map<String, Object> typeMap, String[] superTypes) {
        nestableMapNames.put(eventTypeName, typeMap);
        if (superTypes != null) {
            for (int i = 0; i < superTypes.length; i++) {
                this.addMapSuperType(eventTypeName, superTypes[i]);
            }
        }
    }

    public void addEventType(String eventTypeName, Map<String, Object> typeMap, ConfigurationEventTypeMap mapConfig)
            throws ConfigurationException {
        nestableMapNames.put(eventTypeName, typeMap);
        mapTypeConfigurations.put(eventTypeName, mapConfig);
    }

    /**
     * Add, for a given Map event type identified by the first parameter, the supertype (by its event type name).
     * <p>
     * Each Map event type may have any number of supertypes, each supertype must also be of a Map-type event.
     * @param mapeventTypeName the name of a Map event type, that is to have a supertype
     * @param mapSupertypeName the name of a Map event type that is the supertype
     */
    public void addMapSuperType(String mapeventTypeName, String mapSupertypeName) {
        ConfigurationEventTypeMap current = mapTypeConfigurations.get(mapeventTypeName);
        if (current == null) {
            current = new ConfigurationEventTypeMap();
            mapTypeConfigurations.put(mapeventTypeName, current);
        }
        Set<String> superTypes = current.getSuperTypes();
        superTypes.add(mapSupertypeName);
    }

    /**
     * Add, for a given Object-array event type identified by the first parameter, the supertype (by its event type name).
     * <p>
     * Each Object array event type may have any number of supertypes, each supertype must also be of a Object-array-type event.
     * @param eventTypeName the name of a Map event type, that is to have a supertype
     * @param supertypeName the name of a Map event type that is the supertype
     */
    public void addObjectArraySuperType(String eventTypeName, String supertypeName) {
        ConfigurationEventTypeObjectArray current = objectArrayTypeConfigurations.get(eventTypeName);
        if (current == null) {
            current = new ConfigurationEventTypeObjectArray();
            objectArrayTypeConfigurations.put(eventTypeName, current);
        }
        Set<String> superTypes = current.getSuperTypes();
        if (!superTypes.isEmpty()) {
            throw new ConfigurationException("Object-array event types may not have multiple supertypes");
        }
        superTypes.add(supertypeName);
    }

    /**
     * Add configuration for a map event type.
     * @param mapeventTypeName configuration to add
     * @param config map type configuration
     */
    public void addMapConfiguration(String mapeventTypeName, ConfigurationEventTypeMap config) {
        mapTypeConfigurations.put(mapeventTypeName, config);
    }

    /**
     * Add configuration for a object array event type.
     * @param objectArrayeventTypeName configuration to add
     * @param config map type configuration
     */
    public void addObjectArrayConfiguration(String objectArrayeventTypeName,
            ConfigurationEventTypeObjectArray config) {
        objectArrayTypeConfigurations.put(objectArrayeventTypeName, config);
    }

    /**
     * Add an name for an event type that represents org.w3c.dom.Node events.
     * @param eventTypeName is the name for the event type
     * @param xmlDOMEventTypeDesc descriptor containing property and mapping information for XML-DOM events
     */
    public void addEventType(String eventTypeName, ConfigurationEventTypeXMLDOM xmlDOMEventTypeDesc) {
        eventTypesXMLDOM.put(eventTypeName, xmlDOMEventTypeDesc);
    }

    public void addEventType(String eventTypeName, String[] propertyNames, Object[] propertyTypes)
            throws ConfigurationException {
        LinkedHashMap<String, Object> propertyTypesMap = EventTypeUtility.validateObjectArrayDef(propertyNames,
                propertyTypes);
        nestableObjectArrayNames.put(eventTypeName, propertyTypesMap);
    }

    public void addEventType(String eventTypeName, String[] propertyNames, Object[] propertyTypes,
            ConfigurationEventTypeObjectArray config) throws ConfigurationException {
        LinkedHashMap<String, Object> propertyTypesMap = EventTypeUtility.validateObjectArrayDef(propertyNames,
                propertyTypes);
        nestableObjectArrayNames.put(eventTypeName, propertyTypesMap);
        objectArrayTypeConfigurations.put(eventTypeName, config);
        if (config.getSuperTypes() != null && config.getSuperTypes().size() > 1) {
            throw new ConfigurationException(ConfigurationEventTypeObjectArray.SINGLE_SUPERTYPE_MSG);
        }
    }

    public void addRevisionEventType(String revisioneventTypeName,
            ConfigurationRevisionEventType revisionEventTypeConfig) {
        revisionEventTypes.put(revisioneventTypeName, revisionEventTypeConfig);
    }

    /**
     * Add a database reference with a given database name.
     * @param name is the database name
     * @param configurationDBRef descriptor containing database connection and access policy information
     */
    public void addDatabaseReference(String name, ConfigurationDBRef configurationDBRef) {
        databaseReferences.put(name, configurationDBRef);
    }

    /**
     * Add an name for an event type that represents legacy Java type (non-JavaBean style) events.
     * @param eventTypeName is the name for the event type
     * @param eventClass fully-qualified class name of the event type
     * @param legacyEventTypeDesc descriptor containing property and mapping information for Legacy Java type events
     */
    public void addEventType(String eventTypeName, String eventClass,
            ConfigurationEventTypeLegacy legacyEventTypeDesc) {
        eventClasses.put(eventTypeName, eventClass);
        eventTypesLegacy.put(eventTypeName, legacyEventTypeDesc);
    }

    public void addImport(String autoImport) {
        imports.add(autoImport);
    }

    public void addImport(Class autoImport) {
        addImport(autoImport.getName());
    }

    /**
     * Remove an import.
     * @param name to remove
     */
    public void removeImport(String name) {
        imports.remove(name);
    }

    /**
     * Adds a cache configuration for a class providing methods for use in the from-clause.
     * @param className is the class name (simple or fully-qualified) providing methods
     * @param methodInvocationConfig is the cache configuration
     */
    public void addMethodRef(String className, ConfigurationMethodRef methodInvocationConfig) {
        this.methodInvocationReferences.put(className, methodInvocationConfig);
    }

    /**
     * Adds a cache configuration for a class providing methods for use in the from-clause.
     * @param clazz is the class providing methods
     * @param methodInvocationConfig is the cache configuration
     */
    public void addMethodRef(Class clazz, ConfigurationMethodRef methodInvocationConfig) {
        this.methodInvocationReferences.put(clazz.getName(), methodInvocationConfig);
    }

    public Map<String, String> getEventTypeNames() {
        return eventClasses;
    }

    public Map<String, Properties> getEventTypesMapEvents() {
        return mapNames;
    }

    public Map<String, Map<String, Object>> getEventTypesNestableMapEvents() {
        return nestableMapNames;
    }

    public Map<String, Map<String, Object>> getEventTypesNestableObjectArrayEvents() {
        return nestableObjectArrayNames;
    }

    public Map<String, ConfigurationEventTypeXMLDOM> getEventTypesXMLDOM() {
        return eventTypesXMLDOM;
    }

    public Map<String, ConfigurationEventTypeLegacy> getEventTypesLegacy() {
        return eventTypesLegacy;
    }

    public List<String> getImports() {
        return imports;
    }

    public Map<String, ConfigurationDBRef> getDatabaseReferences() {
        return databaseReferences;
    }

    public List<ConfigurationPlugInView> getPlugInViews() {
        return plugInViews;
    }

    public Map<String, ConfigurationEventTypeObjectArray> getObjectArrayTypeConfigurations() {
        return objectArrayTypeConfigurations;
    }

    public List<ConfigurationPlugInVirtualDataWindow> getPlugInVirtualDataWindows() {
        return plugInVirtualDataWindows;
    }

    public List<ConfigurationPluginLoader> getPluginLoaders() {
        return pluginLoaders;
    }

    public List<ConfigurationPlugInAggregationFunction> getPlugInAggregationFunctions() {
        return plugInAggregationFunctions;
    }

    public List<ConfigurationPlugInAggregationMultiFunction> getPlugInAggregationMultiFunctions() {
        return plugInAggregationMultiFunctions;
    }

    public List<ConfigurationPlugInSingleRowFunction> getPlugInSingleRowFunctions() {
        return plugInSingleRowFunctions;
    }

    public List<ConfigurationPlugInPatternObject> getPlugInPatternObjects() {
        return plugInPatternObjects;
    }

    public Map<String, ConfigurationVariable> getVariables() {
        return variables;
    }

    public Map<String, ConfigurationMethodRef> getMethodInvocationReferences() {
        return methodInvocationReferences;
    }

    public Map<String, ConfigurationRevisionEventType> getRevisionEventTypes() {
        return revisionEventTypes;
    }

    public Map<String, ConfigurationEventTypeMap> getMapTypeConfigurations() {
        return mapTypeConfigurations;
    }

    /**
     * Add a plugin loader (f.e. an input/output adapter loader).
     * <p>The class is expected to implement {@link com.espertech.esper.plugin.PluginLoader}</p>.
     * @param loaderName is the name of the loader
     * @param className is the fully-qualified classname of the loader class
     * @param configuration is loader cofiguration entries
     */
    public void addPluginLoader(String loaderName, String className, Properties configuration) {
        addPluginLoader(loaderName, className, configuration, null);
    }

    /**
     * Add a plugin loader (f.e. an input/output adapter loader) without any additional loader configuration
     * <p>The class is expected to implement {@link com.espertech.esper.plugin.PluginLoader}</p>.
     * @param loaderName is the name of the loader
     * @param className is the fully-qualified classname of the loader class
     */
    public void addPluginLoader(String loaderName, String className) {
        addPluginLoader(loaderName, className, null, null);
    }

    /**
     * Add a plugin loader (f.e. an input/output adapter loader).
     * <p>The class is expected to implement {@link com.espertech.esper.plugin.PluginLoader}</p>.
     * @param loaderName is the name of the loader
     * @param className is the fully-qualified classname of the loader class
     * @param configuration is loader cofiguration entries
     * @param configurationXML config xml if any
     */
    public void addPluginLoader(String loaderName, String className, Properties configuration,
            String configurationXML) {
        ConfigurationPluginLoader pluginLoader = new ConfigurationPluginLoader();
        pluginLoader.setLoaderName(loaderName);
        pluginLoader.setClassName(className);
        pluginLoader.setConfigProperties(configuration);
        pluginLoader.setConfigurationXML(configurationXML);
        pluginLoaders.add(pluginLoader);
    }

    /**
     * Add a view for plug-in.
     * @param namespace is the namespace the view should be available under
     * @param name is the name of the view
     * @param viewFactoryClass is the view factory class to use
     */
    public void addPlugInView(String namespace, String name, String viewFactoryClass) {
        ConfigurationPlugInView configurationPlugInView = new ConfigurationPlugInView();
        configurationPlugInView.setNamespace(namespace);
        configurationPlugInView.setName(name);
        configurationPlugInView.setFactoryClassName(viewFactoryClass);
        plugInViews.add(configurationPlugInView);
    }

    /**
     * Add a virtual data window for plug-in.
     * @param namespace is the namespace the virtual data window should be available under
     * @param name is the name of the data window
     * @param factoryClass is the view factory class to use
     */
    public void addPlugInVirtualDataWindow(String namespace, String name, String factoryClass) {
        addPlugInVirtualDataWindow(namespace, name, factoryClass, null);
    }

    /**
     * Add a virtual data window for plug-in.
     * @param namespace is the namespace the virtual data window should be available under
     * @param name is the name of the data window
     * @param factoryClass is the view factory class to use
     * @param customConfigurationObject additional configuration to be passed along
     */
    public void addPlugInVirtualDataWindow(String namespace, String name, String factoryClass,
            Serializable customConfigurationObject) {
        ConfigurationPlugInVirtualDataWindow configurationPlugInVirtualDataWindow = new ConfigurationPlugInVirtualDataWindow();
        configurationPlugInVirtualDataWindow.setNamespace(namespace);
        configurationPlugInVirtualDataWindow.setName(name);
        configurationPlugInVirtualDataWindow.setFactoryClassName(factoryClass);
        configurationPlugInVirtualDataWindow.setConfig(customConfigurationObject);
        plugInVirtualDataWindows.add(configurationPlugInVirtualDataWindow);
    }

    /**
     * Add a pattern event observer for plug-in.
     * @param namespace is the namespace the observer should be available under
     * @param name is the name of the observer
     * @param observerFactoryClass is the observer factory class to use
     */
    public void addPlugInPatternObserver(String namespace, String name, String observerFactoryClass) {
        ConfigurationPlugInPatternObject entry = new ConfigurationPlugInPatternObject();
        entry.setNamespace(namespace);
        entry.setName(name);
        entry.setFactoryClassName(observerFactoryClass);
        entry.setPatternObjectType(ConfigurationPlugInPatternObject.PatternObjectType.OBSERVER);
        plugInPatternObjects.add(entry);
    }

    /**
     * Add a pattern guard for plug-in.
     * @param namespace is the namespace the guard should be available under
     * @param name is the name of the guard
     * @param guardFactoryClass is the guard factory class to use
     */
    public void addPlugInPatternGuard(String namespace, String name, String guardFactoryClass) {
        ConfigurationPlugInPatternObject entry = new ConfigurationPlugInPatternObject();
        entry.setNamespace(namespace);
        entry.setName(name);
        entry.setFactoryClassName(guardFactoryClass);
        entry.setPatternObjectType(ConfigurationPlugInPatternObject.PatternObjectType.GUARD);
        plugInPatternObjects.add(entry);
    }

    public void addEventTypeAutoName(String packageName) {
        eventTypeAutoNamePackages.add(packageName);
    }

    public void addVariable(String variableName, Class type, Object initializationValue) {
        addVariable(variableName, type.getName(), initializationValue, false);
    }

    /**
     * Add variable that can be a constant.
     * @param variableName name of variable
     * @param type variable type
     * @param initializationValue initial value
     * @param constant constant indicator
     */
    public void addVariable(String variableName, Class type, Object initializationValue, boolean constant) {
        addVariable(variableName, type.getName(), initializationValue, constant);
    }

    public void addVariable(String variableName, String type, Object initializationValue)
            throws ConfigurationException {
        addVariable(variableName, type, initializationValue, false);
    }

    public void addVariable(String variableName, String type, Object initializationValue, boolean constant)
            throws ConfigurationException {
        ConfigurationVariable configVar = new ConfigurationVariable();
        configVar.setType(type);
        configVar.setInitializationValue(initializationValue);
        configVar.setConstant(constant);
        variables.put(variableName, configVar);
    }

    /**
     * Adds an event representation responsible for creating event types (event metadata) and event bean instances (events) for
     * a certain kind of object representation that holds the event property values.
     * @param eventRepresentationRootURI uniquely identifies the event representation and acts as a parent
     * for child URIs used in resolving
     * @param eventRepresentationClassName is the name of the class implementing {@link com.espertech.esper.plugin.PlugInEventRepresentation}.
     * @param initializer is optional configuration or initialization information, or null if none required
     */
    public void addPlugInEventRepresentation(URI eventRepresentationRootURI, String eventRepresentationClassName,
            Serializable initializer) {
        ConfigurationPlugInEventRepresentation config = new ConfigurationPlugInEventRepresentation();
        config.setEventRepresentationClassName(eventRepresentationClassName);
        config.setInitializer(initializer);
        this.plugInEventRepresentation.put(eventRepresentationRootURI, config);
    }

    /**
     * Adds an event representation responsible for creating event types (event metadata) and event bean instances (events) for
     * a certain kind of object representation that holds the event property values.
     * @param eventRepresentationRootURI uniquely identifies the event representation and acts as a parent
     * for child URIs used in resolving
     * @param eventRepresentationClass is the class implementing {@link com.espertech.esper.plugin.PlugInEventRepresentation}.
     * @param initializer is optional configuration or initialization information, or null if none required
     */
    public void addPlugInEventRepresentation(URI eventRepresentationRootURI, Class eventRepresentationClass,
            Serializable initializer) {
        addPlugInEventRepresentation(eventRepresentationRootURI, eventRepresentationClass.getName(), initializer);
    }

    public void addPlugInEventType(String eventTypeName, URI[] resolutionURIs, Serializable initializer) {
        ConfigurationPlugInEventType config = new ConfigurationPlugInEventType();
        config.setEventRepresentationResolutionURIs(resolutionURIs);
        config.setInitializer(initializer);
        plugInEventTypes.put(eventTypeName, config);
    }

    public void setPlugInEventTypeResolutionURIs(URI[] urisToResolveName) {
        plugInEventTypeResolutionURIs = urisToResolveName;
    }

    public URI[] getPlugInEventTypeResolutionURIs() {
        return plugInEventTypeResolutionURIs;
    }

    public Map<URI, ConfigurationPlugInEventRepresentation> getPlugInEventRepresentation() {
        return plugInEventRepresentation;
    }

    public Map<String, ConfigurationPlugInEventType> getPlugInEventTypes() {
        return plugInEventTypes;
    }

    public Set<String> getEventTypeAutoNamePackages() {
        return eventTypeAutoNamePackages;
    }

    public ConfigurationEngineDefaults getEngineDefaults() {
        return engineDefaults;
    }

    public void addVariantStream(String varianteventTypeName, ConfigurationVariantStream variantStreamConfig) {
        variantStreams.put(varianteventTypeName, variantStreamConfig);
    }

    public Map<String, ConfigurationVariantStream> getVariantStreams() {
        return variantStreams;
    }

    public void updateMapEventType(String mapeventTypeName, Map<String, Object> typeMap)
            throws ConfigurationException {
        throw new UnsupportedOperationException("Map type update is only available in runtime configuration");
    }

    public void updateObjectArrayEventType(String myEvent, String[] namesNew, Object[] typesNew) {
        throw new UnsupportedOperationException(
                "Object-array type update is only available in runtime configuration");
    }

    public void replaceXMLEventType(String xmlEventTypeName, ConfigurationEventTypeXMLDOM config)
            throws ConfigurationException {
        throw new UnsupportedOperationException("XML type update is only available in runtime configuration");
    }

    public Set<String> getEventTypeNameUsedBy(String name) {
        throw new UnsupportedOperationException(
                "Get event type by name is only available in runtime configuration");
    }

    public boolean isVariantStreamExists(String name) {
        return variantStreams.containsKey(name);
    }

    public void setMetricsReportingInterval(String stmtGroupName, long newInterval) {
        this.getEngineDefaults().getMetricsReporting().setStatementGroupInterval(stmtGroupName, newInterval);
    }

    public void setMetricsReportingStmtEnabled(String statementName) {
        throw new UnsupportedOperationException(
                "Statement metric reporting can only be enabled or disabled at runtime");
    }

    public void setMetricsReportingStmtDisabled(String statementName) {
        throw new UnsupportedOperationException(
                "Statement metric reporting can only be enabled or disabled at runtime");
    }

    public EventType getEventType(String eventTypeName) {
        throw new UnsupportedOperationException("Obtaining an event type by name is only available at runtime");
    }

    public EventType[] getEventTypes() {
        throw new UnsupportedOperationException("Obtaining event types is only available at runtime");
    }

    public void setMetricsReportingEnabled() {
        this.getEngineDefaults().getMetricsReporting().setEnableMetricsReporting(true);
    }

    public void setMetricsReportingDisabled() {
        this.getEngineDefaults().getMetricsReporting().setEnableMetricsReporting(false);
    }

    public void setPatternMaxSubexpressions(Long maxSubexpressions) {
        this.getEngineDefaults().getPatterns().setMaxSubexpressions(maxSubexpressions);
    }

    /**
    * Use the configuration specified in an application
    * resource named <tt>esper.cfg.xml</tt>.
     * @return Configuration initialized from the resource
     * @throws EPException thrown to indicate error reading configuration
     */
    public Configuration configure() throws EPException {
        configure('/' + ESPER_DEFAULT_CONFIG);
        return this;
    }

    /**
     * Use the configuration specified in the given application
     * resource. The format of the resource is defined in
     * <tt>esper-configuration-2.0.xsd</tt>.
     * <p/>
     * The resource is found via <tt>getConfigurationInputStream(resource)</tt>.
     * That method can be overridden to implement an arbitrary lookup strategy.
     * <p/>
     * See <tt>getResourceAsStream</tt> for information on how the resource name is resolved.
     * @param resource if the file name of the resource
     * @return Configuration initialized from the resource
     * @throws EPException thrown to indicate error reading configuration
     */
    public Configuration configure(String resource) throws EPException {
        if (log.isDebugEnabled()) {
            log.debug("Configuring from resource: " + resource);
        }
        InputStream stream = getConfigurationInputStream(resource);
        ConfigurationParser.doConfigure(this, stream, resource);
        return this;
    }

    /**
     * Get the configuration file as an <tt>InputStream</tt>. Might be overridden
     * by subclasses to allow the configuration to be located by some arbitrary
     * mechanism.
     * <p>
     * See <tt>getResourceAsStream</tt> for information on how the resource name is resolved.
     * @param resource is the resource name
     * @return input stream for resource
     * @throws EPException thrown to indicate error reading configuration
     */
    protected static InputStream getConfigurationInputStream(String resource) throws EPException {
        return getResourceAsStream(resource);
    }

    /**
     * Use the configuration specified by the given URL.
     * The format of the document obtained from the URL is defined in
     * <tt>esper-configuration-2.0.xsd</tt>.
     *
     * @param url URL from which you wish to load the configuration
     * @return A configuration configured via the file
     * @throws EPException is thrown when the URL could not be access
     */
    public Configuration configure(URL url) throws EPException {
        if (log.isDebugEnabled()) {
            log.debug("configuring from url: " + url.toString());
        }
        try {
            ConfigurationParser.doConfigure(this, url.openStream(), url.toString());
            return this;
        } catch (IOException ioe) {
            throw new EPException("could not configure from URL: " + url, ioe);
        }
    }

    /**
     * Use the configuration specified in the given application
     * file. The format of the file is defined in
     * <tt>esper-configuration-2.0.xsd</tt>.
     *
     * @param configFile <tt>File</tt> from which you wish to load the configuration
     * @return A configuration configured via the file
     * @throws EPException when the file could not be found
     */
    public Configuration configure(File configFile) throws EPException {
        if (log.isDebugEnabled()) {
            log.debug("configuring from file: " + configFile.getName());
        }

        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(configFile);
            ConfigurationParser.doConfigure(this, inputStream, configFile.toString());
        } catch (FileNotFoundException fnfe) {
            throw new EPException("could not find file: " + configFile, fnfe);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.debug("Error closing input stream", e);
                }
            }
        }
        return this;
    }

    public boolean removeEventType(String eventTypeName, boolean force) throws ConfigurationException {
        eventClasses.remove(eventTypeName);
        eventTypesXMLDOM.remove(eventTypeName);
        eventTypesLegacy.remove(eventTypeName);
        mapNames.remove(eventTypeName);
        nestableMapNames.remove(eventTypeName);
        mapTypeConfigurations.remove(eventTypeName);
        plugInEventTypes.remove(eventTypeName);
        revisionEventTypes.remove(eventTypeName);
        variantStreams.remove(eventTypeName);
        return true;
    }

    public Set<String> getVariableNameUsedBy(String variableName) {
        throw new UnsupportedOperationException(
                "Get variable use information is only available in runtime configuration");
    }

    public boolean removeVariable(String name, boolean force) throws ConfigurationException {
        return this.variables.remove(name) != null;
    }

    /**
    * Use the mappings and properties specified in the given XML document.
    * The format of the file is defined in
    * <tt>esper-configuration-2.0.xsd</tt>.
    *
    * @param document an XML document from which you wish to load the configuration
    * @return A configuration configured via the <tt>Document</tt>
    * @throws EPException if there is problem in accessing the document.
    */
    public Configuration configure(Document document) throws EPException {
        if (log.isDebugEnabled()) {
            log.debug("configuring from XML document");
        }
        ConfigurationParser.doConfigure(this, document);
        return this;
    }

    /**
     * Returns an input stream from an application resource in the classpath.
     * <p>
     * The method first removes the '/' character from the resource name if
     * the first character is '/'.
     * <p>
     * The lookup order is as follows:
     * <p>
     * If a thread context class loader exists, use <tt>Thread.currentThread().getResourceAsStream</tt>
     * to obtain an InputStream.
     * <p>
     * If no input stream was returned, use the <tt>Configuration.class.getResourceAsStream</tt>.
     * to obtain an InputStream.
     * <p>
     * If no input stream was returned, use the <tt>Configuration.class.getClassLoader().getResourceAsStream</tt>.
     * to obtain an InputStream.
     * <p>
     * If no input stream was returned, throw an Exception.
     *
     * @param resource to get input stream for
     * @return input stream for resource
     */
    protected static InputStream getResourceAsStream(String resource) {
        String stripped = resource.startsWith("/") ? resource.substring(1) : resource;

        InputStream stream = null;
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader != null) {
            stream = classLoader.getResourceAsStream(stripped);
        }
        if (stream == null) {
            stream = Configuration.class.getResourceAsStream(resource);
        }
        if (stream == null) {
            stream = Configuration.class.getClassLoader().getResourceAsStream(stripped);
        }
        if (stream == null) {
            throw new EPException(resource + " not found");
        }
        return stream;
    }

    /**
     * Reset to an empty configuration.
     */
    protected void reset() {
        eventClasses = new HashMap<String, String>();
        mapNames = new HashMap<String, Properties>();
        nestableMapNames = new HashMap<String, Map<String, Object>>();
        nestableObjectArrayNames = new HashMap<String, Map<String, Object>>();
        eventTypesXMLDOM = new HashMap<String, ConfigurationEventTypeXMLDOM>();
        eventTypesLegacy = new HashMap<String, ConfigurationEventTypeLegacy>();
        databaseReferences = new HashMap<String, ConfigurationDBRef>();
        imports = new ArrayList<String>();
        addDefaultImports();
        plugInViews = new ArrayList<ConfigurationPlugInView>();
        plugInVirtualDataWindows = new ArrayList<ConfigurationPlugInVirtualDataWindow>();
        pluginLoaders = new ArrayList<ConfigurationPluginLoader>();
        plugInAggregationFunctions = new ArrayList<ConfigurationPlugInAggregationFunction>();
        plugInAggregationMultiFunctions = new ArrayList<ConfigurationPlugInAggregationMultiFunction>();
        plugInSingleRowFunctions = new ArrayList<ConfigurationPlugInSingleRowFunction>();
        plugInPatternObjects = new ArrayList<ConfigurationPlugInPatternObject>();
        engineDefaults = new ConfigurationEngineDefaults();
        eventTypeAutoNamePackages = new LinkedHashSet<String>();
        variables = new HashMap<String, ConfigurationVariable>();
        methodInvocationReferences = new HashMap<String, ConfigurationMethodRef>();
        plugInEventRepresentation = new HashMap<URI, ConfigurationPlugInEventRepresentation>();
        plugInEventTypes = new HashMap<String, ConfigurationPlugInEventType>();
        revisionEventTypes = new HashMap<String, ConfigurationRevisionEventType>();
        variantStreams = new HashMap<String, ConfigurationVariantStream>();
        mapTypeConfigurations = new HashMap<String, ConfigurationEventTypeMap>();
        objectArrayTypeConfigurations = new HashMap<String, ConfigurationEventTypeObjectArray>();
    }

    /**
     * Use these imports until the user specifies something else.
     */
    private void addDefaultImports() {
        imports.add("java.lang.*");
        imports.add("java.math.*");
        imports.add("java.text.*");
        imports.add("java.util.*");
        imports.add("com.espertech.esper.client.annotation.*");
        imports.add(BeaconSource.class.getPackage().getName() + ".*");
    }

    /**
     * Enumeration of different resolution styles for resolving property names.
     */
    public static enum PropertyResolutionStyle {
        /**
         * Properties are only matched if the names are identical in name
         * and case to the original property name.
         */
        CASE_SENSITIVE,

        /**
         * Properties are matched if the names are identical.  A case insensitive
         * search is used and will choose the first property that matches
         * the name exactly or the first property that matches case insensitively
         * should no match be found.
         */
        CASE_INSENSITIVE,

        /**
         * Properties are matched if the names are identical.  A case insensitive
         * search is used and will choose the first property that matches
         * the name exactly case insensitively.  If more than one 'name' can be
         * mapped to the property an exception is thrown.
         */
        DISTINCT_CASE_INSENSITIVE;

        /**
         * Returns the default property resolution style.
         * @return is the case-sensitive resolution
         */
        public static PropertyResolutionStyle getDefault() {
            return CASE_SENSITIVE;
        }
    }

    /**
     * Enumeration of event representation.
     */
    public static enum EventRepresentation {
        /**
         * Event representation is object-array (Object[]).
         */
        OBJECTARRAY,

        /**
         * Event representation is Map (any java.util.Map interface implementation).
         */
        MAP;

        /**
         * Returns the default property resolution style.
         * @return is the case-sensitive resolution
         */
        public static EventRepresentation getDefault() {
            return MAP;
        }
    }

}