blob: 4629de29fcd74c996bcde31aafd2cf30f7b18070 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.synapse.config.xml;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.SynapseException;
import org.apache.synapse.Mediator;
import org.apache.synapse.config.XMLToObjectMapper;
import org.apache.synapse.config.xml.eventing.EventPublisherMediatorFactory;
import sun.misc.Service;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
/**
*
*
* This class is based on J2SE Service Provider model
* http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider
*/
public class MediatorFactoryFinder implements XMLToObjectMapper {
private static final Log log = LogFactory.getLog(MediatorFactoryFinder.class);
private static final Class[] mediatorFactories = {
SequenceMediatorFactory.class,
LogMediatorFactory.class,
SendMediatorFactory.class,
FilterMediatorFactory.class,
SynapseMediatorFactory.class,
DropMediatorFactory.class,
HeaderMediatorFactory.class,
FaultMediatorFactory.class,
PropertyMediatorFactory.class,
SwitchMediatorFactory.class,
InMediatorFactory.class,
OutMediatorFactory.class,
ClassMediatorFactory.class,
ValidateMediatorFactory.class,
XSLTMediatorFactory.class,
AnnotatedCommandMediatorFactory.class,
POJOCommandMediatorFactory.class,
CloneMediatorFactory.class,
IterateMediatorFactory.class,
AggregateMediatorFactory.class,
DBReportMediatorFactory.class,
DBLookupMediatorFactory.class,
CacheMediatorFactory.class,
CalloutMediatorFactory.class,
EventPublisherMediatorFactory.class,
TransactionMediatorFactory.class,
EnqueueMediatorFactory.class,
ConditionalRouterMediatorFactory.class,
SamplingThrottleMediatorFactory.class,
URLRewriteMediatorFactory.class,
EnrichMediatorFactory.class,
MessageStoreMediatorFactory.class,
TemplateMediatorFactory.class,
InvokeMediatorFactory.class,
PayloadFactoryMediatorFactory.class,
BeanMediatorFactory.class,
EJBMediatorFactory.class,
RespondMediatorFactory.class
};
private final static MediatorFactoryFinder instance = new MediatorFactoryFinder();
/**
* A map of mediator QNames to implementation class
*/
private static Map<QName, Class> factoryMap = new HashMap<QName, Class>();
private static boolean initialized = false;
public static synchronized MediatorFactoryFinder getInstance() {
if (!initialized) {
loadMediatorFactories();
}
return instance;
}
/**
* Force re initialization next time
*/
public static synchronized void reset() {
factoryMap.clear();
initialized = false;
}
private MediatorFactoryFinder() {
}
private static void loadMediatorFactories() {
for (Class c : mediatorFactories) {
try {
MediatorFactory fac = (MediatorFactory) c.newInstance();
factoryMap.put(fac.getTagQName(), c);
} catch (Exception e) {
throw new SynapseException("Error instantiating " + c.getName(), e);
}
}
// now iterate through the available pluggable mediator factories
registerExtensions();
initialized = true;
}
/**
* Register pluggable mediator factories from the classpath
*
* This looks for JAR files containing a META-INF/services that adheres to the following
* http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider
*/
private static void registerExtensions() {
// register MediatorFactory extensions
Iterator it = Service.providers(MediatorFactory.class);
while (it.hasNext()) {
MediatorFactory mf = (MediatorFactory) it.next();
QName tag = mf.getTagQName();
factoryMap.put(tag, mf.getClass());
if (log.isDebugEnabled()) {
log.debug("Added MediatorFactory " + mf.getClass() + " to handle " + tag);
}
}
}
/**
* This method returns a Processor given an OMElement. This will be used
* recursively by the elements which contain processor elements themselves
* (e.g. rules)
*
* @param element XML representation of a mediator
* @param properties bag of properties to pass in any information to the factory
* @return Processor
*/
public Mediator getMediator(OMElement element, Properties properties) {
String localName = element.getLocalName();
QName qName;
if (element.getNamespace() != null) {
qName = new QName(element.getNamespace().getNamespaceURI(), localName);
} else {
qName = new QName(localName);
}
if (log.isDebugEnabled()) {
log.debug("getMediator(" + qName + ")");
}
Class cls = factoryMap.get(qName);
if (cls == null && localName.indexOf('.') > -1) {
String newLocalName = localName.substring(0, localName.indexOf('.'));
qName = new QName(element.getNamespace().getNamespaceURI(), newLocalName);
if (log.isDebugEnabled()) {
log.debug("getMediator.2(" + qName + ")");
}
cls = factoryMap.get(qName);
}
if (cls == null) {
String msg = "Unknown mediator referenced by configuration element : " + qName;
log.error(msg);
throw new SynapseException(msg);
}
try {
MediatorFactory mf = (MediatorFactory) cls.newInstance();
return mf.createMediator(element, properties);
} catch (InstantiationException e) {
String msg = "Error initializing mediator factory : " + cls;
log.error(msg);
throw new SynapseException(msg, e);
} catch (IllegalAccessException e) {
String msg = "Error initializing mediator factory : " + cls;
log.error(msg);
throw new SynapseException(msg, e);
}
}
/**
* This method exposes all the MediatorFactories and its Extensions
* @return factoryMap
*/
public Map<QName, Class> getFactoryMap() {
return factoryMap;
}
/**
* Allow the mediator factory finder to act as an XMLToObjectMapper for Mediators
* (i.e. Sequence Mediator) loaded dynamically from a Registry
* @param om node from which the object is expected
* @return Object buit from the om node
*/
public Object getObjectFromOMNode(OMNode om, Properties properties) {
if (om instanceof OMElement) {
return getMediator((OMElement) om, properties);
} else {
handleException("Invalid mediator configuration XML : " + om);
}
return null;
}
private void handleException(String msg) {
log.error(msg);
throw new SynapseException(msg);
}
}