/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* 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.client.annotation.Name;
import com.espertech.esper.dataflow.ops.BeaconSource;
import com.espertech.esper.event.EventTypeUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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-x.y.xsd</tt>.
*/
public class Configuration implements ConfigurationOperations, ConfigurationInformation, Serializable {
private static final long serialVersionUID = -220881974438617882L;
private static Logger log = LoggerFactory.getLogger(Configuration.class);
/**
* Import name of the package that hosts the annotation classes.
*/
public static final String ANNOTATION_IMPORT = Name.class.getPackage().getName() + ".*";
/**
* 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 XML DOM configuration.
*/
protected Map<String, ConfigurationEventTypeAvro> eventTypesAvro;
/**
* 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;
/**
* For annotations only, the class and package name imports that
* will be used to resolve partial class names (not available in EPL statements unless used in an annotation).
*/
protected List<String> annotationImports;
/**
* 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;
protected transient Map<String, Object> transientConfiguration;
/**
* 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 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(ConfigurationPlugInSingleRowFunction singleRowFunction) {
plugInSingleRowFunctions.add(singleRowFunction);
}
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);
}
/**
* Returns transient configuration, i.e. information that is passed along as a reference and not as a value
* @return map of transients
*/
public Map<String, Object> getTransientConfiguration() {
return transientConfiguration;
}
/**
* Sets transient configuration, i.e. information that is passed along as a reference and not as a value
* @param transientConfiguration map of transients
*/
public void setTransientConfiguration(Map<String, Object> transientConfiguration) {
this.transientConfiguration = transientConfiguration;
}
/**
* 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);
addPlugInSingleRowFunction(entry);
}
/**
* Checks if an event type has already been registered for that name.
*
* @param eventTypeName the name
* @return true if already registered
* @since 2.1
*/
public boolean isEventTypeExists(String eventTypeName) {
return eventClasses.containsKey(eventTypeName)
|| mapNames.containsKey(eventTypeName)
|| nestableMapNames.containsKey(eventTypeName)
|| nestableObjectArrayNames.containsKey(eventTypeName)
|| eventTypesXMLDOM.containsKey(eventTypeName)
|| eventTypesAvro.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.
* Note that when adding multiple names for the same Java class the names represent an
* alias to the same event type since event type identity for Java classes is per Java class.
*
* @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.
* Note that when adding multiple names for the same Java class the names represent an
* alias to the same event type since event type identity for Java classes is per Java class.
*
* @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, new LinkedHashMap<String, Object>(typeMap));
}
public void addEventType(String eventTypeName, Map<String, Object> typeMap, String[] superTypes) {
nestableMapNames.put(eventTypeName, new LinkedHashMap<String, Object>(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, new LinkedHashMap<String, Object>(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.
* Note that when adding multiple names for the same Java class the names represent an
* alias to the same event type since event type identity for Java classes is per Java class.
*
* @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());
}
public void addAnnotationImport(String autoImport) {
annotationImports.add(autoImport);
}
/**
* Add a class to the imports available for annotations only
* @param autoImport class to add
*/
public void addAnnotationImport(Class autoImport) {
addAnnotationImport(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, ConfigurationEventTypeAvro> getEventTypesAvro() {
return eventTypesAvro;
}
public Map<String, ConfigurationEventTypeLegacy> getEventTypesLegacy() {
return eventTypesLegacy;
}
public List<String> getImports() {
return imports;
}
public List<String> getAnnotationImports() {
return annotationImports;
}
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);
}
public void setMatchRecognizeMaxStates(Long maxStates) {
this.getEngineDefaults().getMatchRecognize().setMaxStates(maxStates);
}
/**
* 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>
* <p>
* See <tt>getResourceAsStream</tt> for information on how the resource name is resolved.
* </p>
*
* @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);
eventTypesAvro.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;
}
public void addEventTypeAvro(String eventTypeName, ConfigurationEventTypeAvro avro) {
eventTypesAvro.put(eventTypeName, avro);
}
/**
* 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 LinkedHashMap<String, String>();
mapNames = new LinkedHashMap<String, Properties>();
nestableMapNames = new LinkedHashMap<String, Map<String, Object>>();
nestableObjectArrayNames = new LinkedHashMap<String, Map<String, Object>>();
eventTypesXMLDOM = new LinkedHashMap<String, ConfigurationEventTypeXMLDOM>();
eventTypesAvro = new LinkedHashMap<String, ConfigurationEventTypeAvro>();
eventTypesLegacy = new LinkedHashMap<String, ConfigurationEventTypeLegacy>();
databaseReferences = new HashMap<String, ConfigurationDBRef>();
imports = new ArrayList<String>();
annotationImports = new ArrayList<String>(2);
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 LinkedHashMap<URI, ConfigurationPlugInEventRepresentation>();
plugInEventTypes = new LinkedHashMap<String, ConfigurationPlugInEventType>();
revisionEventTypes = new LinkedHashMap<String, ConfigurationRevisionEventType>();
variantStreams = new HashMap<String, ConfigurationVariantStream>();
mapTypeConfigurations = new HashMap<String, ConfigurationEventTypeMap>();
objectArrayTypeConfigurations = new HashMap<String, ConfigurationEventTypeObjectArray>();
transientConfiguration = new HashMap<>();
}
/**
* 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(ANNOTATION_IMPORT);
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;
}
}
}