blob: fc165935aaef2cae120b9af238699446080a985d [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 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;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
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.AbstractSubscriber;
import org.apache.savan.subscribers.Subscriber;
import org.apache.savan.util.UtilFactory;
/**
* 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 = "mapping-rules";
private final String SOAP_ACTION = "mapping-rules";
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 = new MappingRules ();
Iterator actionsIterator = element.getChildrenWithName(new QName (ACTION));
while (actionsIterator.hasNext()) {
OMElement actionElement = (OMElement) actionsIterator.next();
String action = actionElement.getText();
mappingRules.addAction(action);
}
Iterator SOAPActionsIterator = element.getChildrenWithName(new QName (SOAP_ACTION));
while (SOAPActionsIterator.hasNext()) {
OMElement SOAPactionElement = (OMElement) SOAPActionsIterator.next();
String SOAPaction = SOAPactionElement.getText();
mappingRules.addAction(SOAPaction);
}
}
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 AbstractSubscriber 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 (AbstractSubscriber) getObject(subscriberBean.getClazz());
}
}