blob: 0c0f439ac2f387db877ec15c746f408320dcc33c [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.savan.configuration;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory;
import org.apache.savan.SavanConstants;
import org.apache.savan.SavanException;
import org.apache.savan.filters.Filter;
import org.apache.savan.storage.SubscriberStore;
import org.apache.savan.subscribers.Subscriber;
import org.apache.savan.util.UtilFactory;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* This is responsible for loading Savan configuration data from a resource for e.g. from a
* savan-config.xml fie
*/
public class ConfigurationManager {
private HashMap protocolMap = null;
private HashMap subscriberStoreNamesMap = null;
private HashMap filterMap = null;
private HashMap subscribersMap = null;
private final String SAVAN_CONFIG = "savan-config";
private final String PROTOCOLS = "protocols";
private final String PROTOCOL = "protocol";
private final String NAME = "name";
private final String UTIL_FACTORY = "utilFactory";
private final String MAPPING_RULES = "mapping-rules";
private final String ACTION = "action";
private final String SUBSCRIBER_STORES = "subscriberStores";
private final String SUBSCRIBER_STORE = "subscriberStore";
private final String FILTERS = "filters";
private final String FILTER = "filter";
private final String KEY = "key";
private final String CLASS = "class";
private final String IDENTIFIER = "identifier";
private final String SUBSCRIBERS = "subscribers";
private final String SUBSCRIBER = "subscriber";
private final String URL_APPENDER = "urlAppender";
private final String DEFAULT_SUBSCRIBER = "defaultSubscriber";
private final String DEFAULT_FILTER = "defaultFilter";
public ConfigurationManager() {
protocolMap = new HashMap();
subscriberStoreNamesMap = new HashMap();
filterMap = new HashMap();
subscribersMap = new HashMap();
}
/**
* To load configurations from a savan-config.xml file in the classpath.
*
* @throws SavanException
*/
public void configure() throws SavanException {
ClassLoader classLoader = getClass().getClassLoader();
configure(classLoader);
}
public void configure(ClassLoader classLoader) throws SavanException {
InputStream in = classLoader.getResourceAsStream(SavanConstants.CONFIG_FILE);
if (in == null)
throw new SavanException(
"Cannot find the savan configuration file. Initialation cannot continue.");
configure(in);
}
/**
* To Load configurations from a file.
*
* @param file
* @throws SavanException
*/
public void configure(File file) throws SavanException {
try {
InputStream in = new FileInputStream(file);
configure(in);
} catch (IOException e) {
throw new SavanException(e);
}
}
/**
* To load configurations from a InputStream.
*
* @param in
* @throws SavanException
*/
public void configure(InputStream in) throws SavanException {
if (in == null) {
String message = "Invalid InputStream.";
throw new SavanException(message);
}
try {
XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(in);
OMFactory factory = OMAbstractFactory.getOMFactory();
StAXOMBuilder builder = OMXMLBuilderFactory.createStAXOMBuilder(factory, parser);
OMElement document = builder.getDocumentElement();
if (document == null) {
throw new SavanException("Configuration XML does not have a document element");
}
processSavanConfig(document);
} catch (Exception e) {
throw new SavanException(e);
}
}
private void processSavanConfig(OMElement element) throws SavanException {
if (!SAVAN_CONFIG.equals(element.getLocalName())) {
throw new SavanException(
"'savan-config'should be the document element of the savan configuration xml file");
}
OMElement protocolsElement = element.getFirstChildWithName(new QName(PROTOCOLS));
if (protocolsElement == null) {
throw new SavanException(
"'protocols' element should be present, as a sub-element of the 'savan-config' element");
}
processProtocols(protocolsElement);
OMElement subscriberStoresElement =
element.getFirstChildWithName(new QName(SUBSCRIBER_STORES));
if (subscriberStoresElement == null) {
throw new SavanException(
"'subscriberStores' element should be present, as a sub-element of the 'savan-config' element");
}
processSubscriberStores(subscriberStoresElement);
OMElement filtersElement = element.getFirstChildWithName(new QName(FILTERS));
if (subscriberStoresElement == null) {
throw new SavanException(
"'Filters' element should be present, as a sub-element of the 'savan-config' element");
}
processFilters(filtersElement);
OMElement subscribersElement = element.getFirstChildWithName(new QName(SUBSCRIBERS));
if (subscriberStoresElement == null) {
throw new SavanException(
"'Subscribers' element should be present as a sub-element of the 'savan-config' element");
}
processSubscribers(subscribersElement);
}
private void processProtocols(OMElement element) throws SavanException {
Iterator protocolElementsIterator = element.getChildrenWithName(new QName(PROTOCOL));
while (protocolElementsIterator.hasNext()) {
OMElement protocolElement = (OMElement)protocolElementsIterator.next();
processProtocol(protocolElement);
}
}
private void processProtocol(OMElement element) throws SavanException {
Protocol protocol = new Protocol();
OMElement nameElement = element.getFirstChildWithName(new QName(NAME));
if (nameElement == null)
throw new SavanException("Protocol must have a 'Name' subelement");
String name = nameElement.getText();
protocol.setName(name);
OMElement utilFactoryNameElement = element.getFirstChildWithName(new QName(UTIL_FACTORY));
if (utilFactoryNameElement == null)
throw new SavanException("Protocol must have a 'UtilFactory' subelement");
String utilFactoryName = utilFactoryNameElement.getText();
Object obj = getObject(utilFactoryName);
if (!(obj instanceof UtilFactory))
throw new SavanException("UtilFactory element" + utilFactoryName +
"is not a subtype of the UtilFactory class");
protocol.setUtilFactory((UtilFactory)obj);
OMElement mappingRulesElement = element.getFirstChildWithName(new QName(MAPPING_RULES));
if (mappingRulesElement == null)
throw new SavanException("Protocol must have a 'mappingRules' sub-element");
processMappingRules(mappingRulesElement, protocol);
OMElement defaultSubscriberElement =
element.getFirstChildWithName(new QName(DEFAULT_SUBSCRIBER));
if (defaultSubscriberElement == null)
throw new SavanException("Protocols must have a 'defaultSubscriber' sub-element");
String defaultSubscriber = defaultSubscriberElement.getText();
protocol.setDefaultSubscriber(defaultSubscriber);
OMElement defaultFilterElement = element.getFirstChildWithName(new QName(DEFAULT_FILTER));
if (defaultFilterElement == null)
throw new SavanException("Protocols must have a 'defaultFilter' sub-element");
String defaultFilter = defaultFilterElement.getText();
protocol.setDefaultFilter(defaultFilter);
protocolMap.put(protocol.getName(), protocol);
}
private void processMappingRules(OMElement element, Protocol protocol) {
MappingRules mappingRules = protocol.getMappingRules();
Iterator actionsIterator = element.getChildrenWithName(new QName(ACTION));
while (actionsIterator.hasNext()) {
OMElement actionElement = (OMElement)actionsIterator.next();
String action = actionElement.getText();
mappingRules.addRule(MappingRules.MAPPING_TYPE_ACTION, action);
}
}
private void processSubscriberStores(OMElement element) throws SavanException {
Iterator subscriberStoreElementsIterator =
element.getChildrenWithName(new QName(SUBSCRIBER_STORE));
while (subscriberStoreElementsIterator.hasNext()) {
OMElement subscriberStoreElement = (OMElement)subscriberStoreElementsIterator.next();
processSubscriberStore(subscriberStoreElement);
}
}
private void processSubscriberStore(OMElement element) throws SavanException {
OMElement keyElement = element.getFirstChildWithName(new QName(KEY));
if (keyElement == null)
throw new SavanException("SubscriberStore must have a 'key' subelement");
String key = keyElement.getText();
OMElement classElement = element.getFirstChildWithName(new QName(CLASS));
if (classElement == null)
throw new SavanException("SubscriberStore must have a 'Clazz' subelement'");
String clazz = classElement.getText();
//initialize the class to check weather it is value
Object obj = getObject(clazz);
if (!(obj instanceof SubscriberStore)) {
String message =
"Class " + clazz + " does not implement the SubscriberStore interface.";
throw new SavanException(message);
}
subscriberStoreNamesMap.put(key, clazz);
}
public HashMap getProtocolMap() {
return protocolMap;
}
public Protocol getProtocol(String name) {
return (Protocol)protocolMap.get(name);
}
public SubscriberStore getSubscriberStoreInstance(String key) throws SavanException {
String name = (String)subscriberStoreNamesMap.get(key);
return (SubscriberStore)getObject(name);
}
public Filter getFilterInstanceFromName(String name) throws SavanException {
for (Iterator it = filterMap.keySet().iterator(); it.hasNext();) {
String key = (String)it.next();
FilterBean filterBean = (FilterBean)filterMap.get(key);
if (name.equals(filterBean.getName()))
return (Filter)getObject(filterBean.getClazz());
}
return null;
}
public Filter getFilterInstanceFromId(String id) throws SavanException {
FilterBean filterBean = (FilterBean)filterMap.get(id);
String filterClass = filterBean.getClazz();
if (filterClass == null)
return null;
return (Filter)getObject(filterClass);
}
private Object getObject(String className) throws SavanException {
Object obj;
try {
Class c = Class.forName(className);
obj = c.newInstance();
} catch (Exception e) {
String message = "Can't instantiate the class:" + className;
throw new SavanException(message, e);
}
return obj;
}
private void processFilters(OMElement element) throws SavanException {
Iterator filterElementsIterator = element.getChildrenWithName(new QName(FILTER));
while (filterElementsIterator.hasNext()) {
OMElement filterElement = (OMElement)filterElementsIterator.next();
processFilter(filterElement);
}
}
private void processFilter(OMElement element) throws SavanException {
OMElement nameElement = element.getFirstChildWithName(new QName(NAME));
OMElement identifierElement = element.getFirstChildWithName(new QName(IDENTIFIER));
OMElement classElement = element.getFirstChildWithName(new QName(CLASS));
if (nameElement == null)
throw new SavanException("Name element is not present within the Filter");
if (identifierElement == null)
throw new SavanException("Identifier element is not present within the Filter");
if (classElement == null)
throw new SavanException("Class element is not present within the Filter");
String name = nameElement.getText();
String identifier = identifierElement.getText();
String clazz = classElement.getText();
//initialize the class to check weather it is value
Object obj = getObject(clazz);
if (!(obj instanceof Filter)) {
String message = "Class " + clazz + " does not implement the Filter interface.";
throw new SavanException(message);
}
FilterBean bean = new FilterBean();
bean.setName(name);
bean.setIdentifier(identifier);
bean.setClazz(clazz);
filterMap.put(identifier, bean);
}
private void processSubscribers(OMElement element) throws SavanException {
Iterator subscriberElementsIterator = element.getChildrenWithName(new QName(SUBSCRIBER));
while (subscriberElementsIterator.hasNext()) {
OMElement subscriberElement = (OMElement)subscriberElementsIterator.next();
processSubscriber(subscriberElement);
}
}
private void processSubscriber(OMElement element) throws SavanException {
OMElement nameElement = element.getFirstChildWithName(new QName(NAME));
OMElement urlAppenderElement = element.getFirstChildWithName(new QName(URL_APPENDER));
OMElement classElement = element.getFirstChildWithName(new QName(CLASS));
if (nameElement == null)
throw new SavanException("Name element is not present within the AbstractSubscriber");
if (classElement == null)
throw new SavanException("Class element is not present within the Filter");
String name = nameElement.getText();
String clazz = classElement.getText();
//initialize the class to check weather it is valid
Object obj = getObject(clazz);
if (!(obj instanceof Subscriber)) {
String message = "Class " + clazz + " does not implement the Subscriber interface.";
throw new SavanException(message);
}
SubscriberBean bean = new SubscriberBean();
bean.setName(name);
bean.setClazz(clazz);
subscribersMap.put(name, bean);
}
public Map getSubscriberBeans() {
return subscribersMap;
}
public Map getFilterBeans() {
return filterMap;
}
public SubscriberBean getSubscriberBean(String subscriberName) {
return (SubscriberBean)subscribersMap.get(subscriberName);
}
public Subscriber getSubscriberInstance(String subscriberName) throws SavanException {
SubscriberBean subscriberBean = (SubscriberBean)subscribersMap.get(subscriberName);
if (subscriberBean == null) {
String message = "A subscriber with the name '" + subscriberName + "' was not found.";
throw new SavanException(message);
}
return (Subscriber)getObject(subscriberBean.getClazz());
}
}