| /* |
| * 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.Subscriber; |
| 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 = "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()); |
| } |
| |
| } |