/* * 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.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.Mediator; import org.apache.synapse.SynapseException; import org.apache.synapse.config.XMLToObjectMapper; import org.apache.synapse.config.xml.eventing.EventPublisherMediatorFactory; import org.apache.synapse.libraries.imports.SynapseImport; import org.apache.synapse.libraries.model.Library; import org.apache.synapse.mediators.Value; import org.apache.synapse.mediators.template.InvokeMediator; import sun.misc.Service; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; 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 Map<String, Library> synapseLibraryMap; private Map<String, SynapseImport> synapseImportMap; 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, 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, CallMediatorFactory.class, LoopBackMediatorFactory.class, RespondMediatorFactory.class, CommentMediatorFactory.class, ForEachMediatorFactory.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) { if (synapseLibraryMap != null && !synapseLibraryMap.isEmpty()) { for (Map.Entry<String, Library> entry : synapseLibraryMap.entrySet()) { if (entry.getValue().getLibArtifactDetails().containsKey(localName)) { return getDynamicInvokeMediator(element, entry.getValue().getPackage()); } } } if (!synapseImportMap.isEmpty()) { for (Map.Entry<String, SynapseImport> entry : synapseImportMap.entrySet()) { if (localName.startsWith(entry.getValue().getLibName())) { return getDynamicInvokeMediator(element, entry.getValue().getLibPackage()); } } } 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); } public Map<String, Library> getSynapseLibraryMap() { return synapseLibraryMap; } public void setSynapseLibraryMap(Map<String, Library> synapseLibraryMap) { this.synapseLibraryMap = synapseLibraryMap; } public Map<String, SynapseImport> getSynapseImportMap() { return synapseImportMap; } public void setSynapseImportMap(Map<String, SynapseImport> synapseImportMap) { this.synapseImportMap = synapseImportMap; } public static void main(String[] args) throws Exception{ String connectorStr = "<sfdc.getContact xmlns=\"http://ws.apache.org/ns/synapse\">\n" + "\t\t <parameter name=\"param1\" value=\"val1\"/>\n" + "\t\t <parameter name=\"param2\" value=\"val2\"/>\n" + "\t</sfdc.getContact>"; OMElement inConnectorElem = AXIOMUtil.stringToOM(connectorStr); String libName = "synapse.lang.eip"; InvokeMediator invokeMediator = MediatorFactoryFinder.getInstance().getDynamicInvokeMediator(inConnectorElem, libName); invokeMediator.getTargetTemplate(); } public OMElement getCallTemplateFromConnector(OMElement connectorElem, String libraryName) { String callTemplateConfig = "<call-template target=\"synapse.lang.eip.sfdc.getContact\">\n" + " <with-param name=\"p1\" value=\"abc\"/>\n" + " <with-param name=\"p2\" value=\"efg\"/>\n" + " </call-template>"; OMElement callTemplateElem = null; try { callTemplateElem = AXIOMUtil.stringToOM(callTemplateConfig); } catch (XMLStreamException e) { e.printStackTrace(); } return callTemplateElem; } public InvokeMediator getDynamicInvokeMediator(OMElement connectorElem, String libraryName) { InvokeMediator invokeMediator = new InvokeMediator(); if (connectorElem.getLocalName() != null && libraryName != null && !libraryName.equals("")) { invokeMediator.setTargetTemplate(libraryName + "." + connectorElem.getLocalName()); } // load configuration based references for the given connector OMAttribute config_key = connectorElem.getAttribute(new QName(XMLConfigConstants.CONFIG_REF)); if (config_key != null) { // ValueFactory for creating dynamic or static Value ValueFactory keyFac = new ValueFactory(); // create dynamic or static key based on OMElement Value generatedKey = keyFac.createValue(XMLConfigConstants.CONFIG_REF, connectorElem); // setKey invokeMediator.setKey(generatedKey); } buildParamteres(connectorElem, invokeMediator); invokeMediator.setPackageName(libraryName); invokeMediator.setDynamicMediator(true); return invokeMediator; } private void buildParamteres(OMElement connectorElem, InvokeMediator invokeMediator) { Iterator parameters = connectorElem.getChildElements(); while (parameters.hasNext()) { OMNode paramNode = (OMNode) parameters.next(); if (paramNode instanceof OMElement) { String paramName = ((OMElement) paramNode).getLocalName(); //((OMElement) paramNode).getAttributeValue(new QName("name")); String paramValueStr = ((OMElement) paramNode).getText();//((OMElement) paramNode).getAttributeValue(new QName("value")); if (paramName != null && !paramName.equals("") && paramValueStr != null && !paramValueStr.equals("")) { Value paramValue = new ValueFactory().createTextValue((OMElement) paramNode); invokeMediator.addExpressionForParamName(paramName, paramValue); } } } } }