All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.woden.wsdl20.extensions.ExtensionRegistry Maven / Gradle / Ivy

There is a newer version: 5.0.22
Show newest version
/**
 * 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.woden.wsdl20.extensions;

import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;


import javax.xml.namespace.QName;

import org.apache.woden.ErrorReporter;
import org.apache.woden.WSDLException;
import org.apache.woden.XMLElement;
import org.apache.woden.wsdl20.WSDLComponent;
import org.apache.woden.wsdl20.validation.Assertion;
import org.apache.woden.wsdl20.validation.AssertionInfo;
import org.apache.woden.wsdl20.xml.WSDLElement;
import org.apache.woden.xml.UnknownAttr;
import org.apache.woden.xml.XMLAttr;


/**
 * This class is used to associate serializers, deserializers, and
 * Java implementation types with extension elements.
 * It also associates Java implementation types only with extension attributes,
 * but not serializers and deserializers.
 * 

* This class has been copied from WSDL4J and modified for Woden. * * TODO update method javadocs. * * @author Matthew J. Duftler ([email protected]) * @author John Kaputin ([email protected]) */ public class ExtensionRegistry { /** * Creates the extension registry, and sets the defaultSerializer * and defaultDeserializer properties to instances of an * UnknownExtensionSerializer, and an UnknownExtensionDeserializer, * respectively. */ public ExtensionRegistry(ErrorReporter errorReporter) { this.errorReporter = errorReporter; setDefaultSerializer(new UnknownExtensionSerializer()); setDefaultDeserializer(new UnknownExtensionDeserializer()); registerResourceBundle(CORE_RESOURCE_BUNDLE); } /** * The property containing the comma-separated listed of ExtensionRegistrars. * The property name is org.apache.woden.extensionregistrars. */ public static final String REGISTRAR_PROPERTY = "org.apache.woden.extensionregistrars"; /** * This property specifies the resource bundle containing the * core Woden extension registry error messages. * * TODO extract these errors to a new public (non-internal) bundle. */ static final private String CORE_RESOURCE_BUNDLE = "org.apache.woden.internal.Messages"; /* This is a Map of Maps. The top-level Map is keyed by (Class)parentType, and the inner Maps are keyed by (QName)elementQN. */ protected Map serializerReg = new Hashtable(); /* This is a Map of Maps. The top-level Map is keyed by (Class)parentType, and the inner Maps are keyed by (QName)elementQN. */ protected Map deserializerReg = new Hashtable(); /* This is a Map of Maps. The top-level Map is keyed by (Class)parentType, and the inner Maps are keyed by (QName)elementQN. */ protected Map extElementReg = new Hashtable(); protected ExtensionSerializer defaultSer = null; protected ExtensionDeserializer defaultDeser = null; /* This is a Map of Maps. The top-level Map is keyed by (Class)parentType, and the inner Maps are keyed by (QName)attrName. */ protected Map extAttributeReg = new Hashtable(); /* * This is a Map of Maps. The top-level Map is keyed by (Class)parentComponent * and the inner Map is keyed by (URI)extensionNamespace with a value of * (Class)componentExtensions. */ protected Map compExtReg = new Hashtable(); /* * Error message property files. */ private List fResourceBundleNames = new ArrayList(); private ErrorReporter errorReporter = null; public ErrorReporter getErrorReporter() { return this.errorReporter; } /* * A Map of assertions, where the key is an assertion id string and * the value is an AssertionInfo object. */ protected Map assertionReg = new Hashtable(); /** * Set the serializer to be used when none is found for an extensibility * element. Set this to null to have an exception thrown when * unexpected extensibility elements are encountered. Default value is * an instance of UnknownExtensionSerializer. * * @see UnknownExtensionSerializer */ public void setDefaultSerializer(ExtensionSerializer defaultSer) { this.defaultSer = defaultSer; } /** * Get the serializer to be used when none is found for an extensibility * element. Default value is an instance of UnknownExtensionSerializer. * * @see UnknownExtensionSerializer */ public ExtensionSerializer getDefaultSerializer() { return defaultSer; } /** * Set the deserializer to be used when none is found for an encountered * element. Set this to null to have an exception thrown when * unexpected extensibility elements are encountered. Default value is * an instance of UnknownExtensionDeserializer. * * @see UnknownExtensionDeserializer */ public void setDefaultDeserializer(ExtensionDeserializer defaultDeser) { this.defaultDeser = defaultDeser; } /** * Get the deserializer to be used when none is found for an encountered * element. Default value is an instance of UnknownExtensionDeserializer. * * @see UnknownExtensionDeserializer */ public ExtensionDeserializer getDefaultDeserializer() { return defaultDeser; } /** * Declare that the specified serializer should be used to serialize * all extensibility elements with a qname matching elementQN, when * encountered as children of the specified parentType. * * @param parentType a class object indicating where in the WSDL * definition this extension was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this extensibility element was found in the list of * extensibility elements belonging to a org.apache.woden.Binding. * @param elementType the qname of the extensibility element * @param es the extension serializer to use * * @see #querySerializer(Class, QName) */ public void registerSerializer(Class parentType, QName elementType, ExtensionSerializer es) { Map innerSerializerReg = (Map)serializerReg.get(parentType); if (innerSerializerReg == null) { innerSerializerReg = new Hashtable(); serializerReg.put(parentType, innerSerializerReg); } innerSerializerReg.put(elementType, es); } /** * Declare that the specified deserializer should be used to deserialize * all extensibility elements with a qname matching elementQN, when * encountered as immediate children of the element represented by the * specified parentType. * * @param parentType a class object indicating where in the WSDL * document this extensibility element was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this element was encountered as an immediate child of * a <wsdl:binding> element. * @param elementType the qname of the extensibility element * @param ed the extension deserializer to use * * @see #queryDeserializer(Class, QName) */ public void registerDeserializer(Class parentType, QName elementType, ExtensionDeserializer ed) { Map innerDeserializerReg = (Map)deserializerReg.get(parentType); if (innerDeserializerReg == null) { innerDeserializerReg = new Hashtable(); deserializerReg.put(parentType, innerDeserializerReg); } innerDeserializerReg.put(elementType, ed); } /** * Look up the serializer to use for the extensibility element with * the qname elementQN, which was encountered as a child of the * specified parentType. * * @param parentType a class object indicating where in the WSDL * definition this extension was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this extensibility element was found in the list of * extensibility elements belonging to a org.apache.woden.Binding. * @param elementType the qname of the extensibility element * * @return the extension serializer, if one was found. If none was * found, the behavior depends on the value of the defaultSerializer * property. If the defaultSerializer property is set to a non-null * value, that value is returned; otherwise, a WSDLException is * thrown. * * @see #registerSerializer(Class, QName, ExtensionSerializer) * @see #setDefaultSerializer(ExtensionSerializer) */ public ExtensionSerializer querySerializer(Class parentType, QName elementType) throws WSDLException { Map innerSerializerReg = (Map)serializerReg.get(parentType); ExtensionSerializer es = null; if (innerSerializerReg != null) { es = (ExtensionSerializer)innerSerializerReg.get(elementType); } if (es == null) { es = defaultSer; } if (es == null) { throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "No ExtensionSerializer found " + "to serialize a '" + elementType + "' element in the context of a '" + parentType.getName() + "'."); } return es; } /** * Look up the deserializer for the extensibility element with the * qname elementQN, which was encountered as an immediate child * of the element represented by the specified parentType. * * @param parentType a class object indicating where in the WSDL * document this extensibility element was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this element was encountered as an immediate child of * a <wsdl:binding> element. * @param elementType the qname of the extensibility element * * @return the extension deserializer, if one was found. If none was * found, the behavior depends on the value of the defaultDeserializer * property. If the defaultDeserializer property is set to a non-null * value, that value is returned; otherwise, a WSDLException is thrown. * * @see #registerDeserializer(Class, QName, ExtensionDeserializer) * @see #setDefaultDeserializer(ExtensionDeserializer) */ public ExtensionDeserializer queryDeserializer(Class parentType, QName elementType) throws WSDLException { Map innerDeserializerReg = (Map)deserializerReg.get(parentType); ExtensionDeserializer ed = null; if (innerDeserializerReg != null) { ed = (ExtensionDeserializer)innerDeserializerReg.get(elementType); } if (ed == null) { ed = defaultDeser; } if (ed == null) { throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "No ExtensionDeserializer found " + "to deserialize a '" + elementType + "' element in the context of a '" + parentType.getName() + "'."); } return ed; } /** * Look up the type of the extensibility element with the specified qname, which * was defined as a child of the element represented by the specified parent class. * * @param parentClass a class object indicating where in the WSDL * document this extensibility attribute was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this attribute was defined on a <wsdl:binding> element. * @param elemQN the qname of the extensibility attribute * * @return one of the constants defined on the AttributeExtensible class * * @see #registerExtAttributeType(Class, QName, Class) * @see AttributeExtensible */ public Class queryExtElementType(Class parentClass, QName elemQN) { Map innerExtensionAttributeReg = (Map)extAttributeReg.get(parentClass); Class elemClass = null; if (innerExtensionAttributeReg != null) { elemClass = (Class)innerExtensionAttributeReg.get(elemQN); } return elemClass; } /** * TODO make the return val typesafe, and create similar method for ext attrs. * * Returns a set of QNames representing the extensibility elements * that are allowed as children of the specified parent type. * Basically, this method returns the keys associated with the set * of extension deserializers registered for this parent type. * Returns null if no extension deserializers are registered for * this parent type. */ public Set getAllowableExtensions(Class parentType) { Map innerDeserializerReg = (Map)deserializerReg.get(parentType); return (innerDeserializerReg != null) ? innerDeserializerReg.keySet() : null; } /** * Declare that the specified extensionType is the concrete * class which should be used to represent extensibility elements * with qnames matching elementQN, that are intended to exist as * children of the specified parentType. * * @param parentType a class object indicating where in the WSDL * definition this extension would exist. For example, * org.apache.woden.Binding.class would be used to indicate * this extensibility element would be added to the list of * extensibility elements belonging to a org.apache.woden.Binding, * after being instantiated. * @param elementType the qname of the extensibility element * @param extensionType the concrete class which should be instantiated * * @see #createExtElement(Class, QName) */ public void registerExtElementType(Class parentType, QName elementType, Class extensionType) { Map innerExtensionTypeReg = (Map)extElementReg.get(parentType); if (innerExtensionTypeReg == null) { innerExtensionTypeReg = new Hashtable(); extElementReg.put(parentType, innerExtensionTypeReg); } innerExtensionTypeReg.put(elementType, extensionType); } /** * Create an instance of the type which was declared to be used to * represent extensibility elements with qnames matching elementQN, * when intended to exist as children of the specified parentType. * This method allows a user to instantiate an extensibility element * without having to know the implementing type. * * @param parentType a class object indicating where in the WSDL * definition this extension will exist. For example, * org.apache.woden.Binding.class would be used to indicate * this extensibility element is going to be added to the list of * extensibility elements belonging to a org.apache.woden.Binding, * after being instantiated. * @param elementType the qname of the extensibility element * * @return a new instance of the type used to represent the * specified extension * * @see #registerExtElementType(Class, QName, Class) */ public ExtensionElement createExtElement(Class parentType, QName elementType) throws WSDLException { Map innerExtensionTypeReg = (Map)extElementReg.get(parentType); Class extensionType = null; if (innerExtensionTypeReg != null) { extensionType = (Class)innerExtensionTypeReg.get(elementType); } if (extensionType == null) { //TODO use ErrorReporter to get formatted error msg WSDL012 throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "No Java extensionType found " + "to represent a '" + elementType + "' element in the context of a '" + parentType.getName() + "'."); } else if (!(ExtensionElement.class.isAssignableFrom(extensionType))) { //TODO use ErrorReporter to get formatted error msg WSDL013 throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "The Java extensionType '" + extensionType.getName() + "' does " + "not implement the ExtensibilityElement " + "interface."); } try { ExtensionElement ee = (ExtensionElement)extensionType.newInstance(); /* if (ee.getElementType() == null) { ee.setElementType(elementQN); } */ return ee; } catch (Exception e) { /* Catches: InstantiationException IllegalAccessException */ throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "Problem instantiating Java " + "extensionType '" + extensionType.getName() + "'.", e); } } /** * Declare that the type of the specified extension attribute, when it occurs * as an attribute of the specified parent type, should be assumed to be * attrType. * * @param ownerClass a class object indicating where in the WSDL * document this extensibility attribute was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this attribute was defined on a <wsdl:binding> element. * @param attrQName the qname of the extensibility attribute * @param attrClass one of the constants defined on the AttributeExtensible * class * * @see #queryExtAttributeType(Class, QName) * @see AttributeExtensible */ public void registerExtAttributeType(Class ownerClass, QName attrQName, Class attrClass) { Map innerExtensionAttributeReg = (Map)extAttributeReg.get(ownerClass); if (innerExtensionAttributeReg == null) { innerExtensionAttributeReg = new Hashtable(); extAttributeReg.put(ownerClass, innerExtensionAttributeReg); } innerExtensionAttributeReg.put(attrQName, attrClass); } /** * Look up the type of the extensibility attribute with the specified qname, * which was defined on an element represented by the specified parent class. * * @param parentClass a class object indicating where in the WSDL * document this extensibility attribute was encountered. For * example, org.apache.woden.Binding.class would be used to indicate * this attribute was defined on a <wsdl:binding> element. * @param attrQN the qname of the extensibility attribute * * @return one of the constants defined on the AttributeExtensible class * * @see #registerExtAttributeType(Class, QName, Class) * @see AttributeExtensible */ public Class queryExtAttributeType(Class parentClass, QName attrQN) { Map innerExtensionAttributeReg = (Map)extAttributeReg.get(parentClass); Class attrClass = null; if (innerExtensionAttributeReg != null) { attrClass = (Class)innerExtensionAttributeReg.get(attrQN); } return attrClass; } public XMLAttr createExtAttribute(Class ownerClass, QName attrQName, XMLElement ownerElement, String attrValue) throws WSDLException { Map innerExtensionAttributeReg = (Map)extAttributeReg.get(ownerClass); Class implClass = null; XMLAttr attr = null; if (innerExtensionAttributeReg != null) { implClass = (Class)innerExtensionAttributeReg.get(attrQName); } if (implClass == null) { /* * Implementations MAY register a default class to handle unknown extension attributes, * which will be retrieved here from the Extension Registry. For example, the * StringAttr implementation class may be registered as the default. * * TODO TBC, then add this info to javadoc and user docs. See sample code in PopulatedExtReg. */ implClass = queryExtAttributeType(WSDLElement.class, new QName("http://ws.apache.org/woden", "DefaultAttr")); //If no default Java class is registered, use the UnknownAttr class. if(implClass == null) implClass = UnknownAttr.class; //Decided it is not necessary to report WSDL010 as a warning to the user, //however we will keep the message code for now in case we add logging capability //later and can capture it in a log (i.e. pull vs. push diagnositic information) /* TODO the following line was replaced by null in the reportError call below * to avoid an API build problem for Milestone 2. This must be fixed, post-M2. * e.g. provide some creator for error locator that hides the Impl class. * * new ErrorLocatorImpl(), //TODO line/col nos. * getErrorReporter().reportError( null, //see comment above "WSDL010", new Object[] {attrQName.toString(), ownerClass.getName(), implClass.getName()}, ErrorReporter.SEVERITY_WARNING); */ } else if (!(XMLAttr.class.isAssignableFrom(implClass))) { String msg = getErrorReporter().getFormattedMessage("WSDL011", new Object[] {attrQName.toString()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL011: " + msg); } try { Class[] ctorParms = new Class[] {XMLElement.class, QName.class, String.class, ErrorReporter.class}; Constructor ctor = implClass.getConstructor(ctorParms); Object[] ctorParmValues = new Object[] {ownerElement, attrQName, attrValue, getErrorReporter()}; attr = (XMLAttr)ctor.newInstance(ctorParmValues); } catch (Exception e) { //SecurityException //NoSuchMethodException //InvocationTargetException //InstantiationException //IllegalAccessException String msg = getErrorReporter().getFormattedMessage("WSDL009", new Object[] {implClass.getName()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL009: " + msg, e); } return attr; } /** * Register the Java class which will represent extensions from a specified * namespace that will extend the specified WSDL component class. * The Java class must implement ComponentExtensionContext. * * @param parentClass the WSDL component class * @param extNamespace the extension namespace * @param compExtCtxClass the Java class representing these extensions */ public void registerComponentExtension(Class parentClass, URI extNamespace, Class compExtCtxClass) { if(!(ComponentExtensionContext.class.isAssignableFrom(compExtCtxClass))) { String msg = getErrorReporter().getFormattedMessage("WSDL016", new Object[] {compExtCtxClass.getName()}); throw new IllegalArgumentException(msg); } Map innerCompExtReg = (Map)compExtReg.get(parentClass); if (innerCompExtReg == null) { innerCompExtReg = new Hashtable(); compExtReg.put(parentClass, innerCompExtReg); } innerCompExtReg.put(extNamespace, compExtCtxClass); } /** * Return the Java class that represents the extensions from the specified * namespace that extend the specified WSDL component class. * This class will be an implementation of ComponentExtensionContext. * * @param parentClass the WSDL component * @param extNamespace the extension namespace * @return the Class of the component extensions */ public Class queryComponentExtension(Class parentClass, URI extNamespace) { Map innerCompExtReg = (Map)compExtReg.get(parentClass); Class compExtClass = null; if (innerCompExtReg != null) { compExtClass = (Class)innerCompExtReg.get(extNamespace); } return compExtClass; } /** * Return the extension namespaces registered for the specified WSDL Component class. * * @param parentClass the class of WSDL component extended by these namespaces * @return an array of namespace URIs */ public URI[] queryComponentExtensionNamespaces(Class parentClass) { Map innerCompExtReg = (Map)compExtReg.get(parentClass); if (innerCompExtReg != null) { Set namespaceKeys = innerCompExtReg.keySet(); URI[] extNamespaces = new URI[namespaceKeys.size()]; namespaceKeys.toArray(extNamespaces); return extNamespaces; } else { return new URI[0]; //return an empty array, rather than null } } /** * Return a ComponentExtensionContext object from the Java class registered for * the specified extension namespace against the specified WSDL component class. * * @param parentClass the WSDL component class. * @param extNamespace the extension namespace. * @return a ComponentExtensionContext object * @throws WSDLException if no Java class is registered for this namespace and WSDL component. */ public ComponentExtensionContext createComponentExtension(Class parentClass, WSDLComponent parentComp, URI extNamespace) throws WSDLException { Class compExtCtxClass = queryComponentExtension(parentClass, extNamespace); if(compExtCtxClass == null) { String msg = getErrorReporter().getFormattedMessage("WSDL015", new Object[] {extNamespace.toString(), parentClass.getName()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL015: " + msg); } ComponentExtensionContext compExtCtx = null; /* TODO remove with woden-47 try { compExtCtx = (ComponentExtensionContext)compExtCtxClass.newInstance(); } catch (InstantiationException e) { String msg = getErrorReporter().getFormattedMessage("WSDL009", new Object[] {compExtCtxClass.getName()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL009: " + msg, e); } catch (IllegalAccessException e) { String msg = getErrorReporter().getFormattedMessage("WSDL009", new Object[] {compExtCtxClass.getName()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL009: " + msg, e); } */ try { Class[] ctorParms = new Class[] {WSDLComponent.class, URI.class, ErrorReporter.class}; Constructor ctor = compExtCtxClass.getConstructor(ctorParms); Object[] ctorParmValues = new Object[] {parentComp, extNamespace, getErrorReporter()}; compExtCtx = (ComponentExtensionContext)ctor.newInstance(ctorParmValues); } catch (Exception e) { //SecurityException //NoSuchMethodException //InvocationTargetException //InstantiationException //IllegalAccessException String msg = getErrorReporter().getFormattedMessage("WSDL009", new Object[] {compExtCtxClass.getName()}); throw new WSDLException(WSDLException.CONFIGURATION_ERROR, "WSDL009: " + msg, e); } return compExtCtx; } public void registerResourceBundle(String resourceBundleName) { fResourceBundleNames.add(resourceBundleName); } public String[] queryResourceBundleNames() { String[] array = new String[fResourceBundleNames.size()]; fResourceBundleNames.toArray(array); return array; } /** * Register an Assertion along with the target Class that the assertion applies to. * TODO assertion dependencies. * * @param assertion an Assertion object representing the assertion to be registered. * @param targetClass the Class representing the component in the WSDL that the assertion applies to. */ public void registerAssertion(Assertion assertion, Class targetClass) { if(assertion == null) { String msg = this.errorReporter.getFormattedMessage("WSDL026", new Object[] {"assertion"}); throw new NullPointerException(msg); } else if(targetClass == null) { String msg = this.errorReporter.getFormattedMessage("WSDL026", new Object[] {"targetClass"}); throw new NullPointerException(msg); } this.assertionReg.put(assertion.getId(), new AssertionInfo(assertion, targetClass)); } public AssertionInfo queryAssertion(String assertionId) { return (AssertionInfo) this.assertionReg.get(assertionId); } public AssertionInfo[] queryAssertions() { Collection values = this.assertionReg.values(); AssertionInfo[] array = new AssertionInfo[values.size()]; values.toArray(array); return array; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy