Added: ode/trunk/scheduler-simple/src/test/java/org/apache/ode/scheduler/simple/RetriesTest.java URL: http://svn.apache.org/viewvc/ode/trunk/scheduler-simple/src/test/java/org/apache/ode/scheduler/simple/RetriesTest.java?rev=658024&view=auto ============================================================================== --- ode/trunk/scheduler-simple/src/test/java/org/apache/ode/scheduler/simple/RetriesTest.java (added) +++ ode/trunk/scheduler-simple/src/test/java/org/apache/ode/scheduler/simple/RetriesTest.java Mon May 19 15:57:24 2008 @@ -0,0 +1,73 @@ +package org.apache.ode.scheduler.simple; + +import org.apache.ode.bpel.iapi.Scheduler; +import org.apache.geronimo.transaction.manager.GeronimoTransactionManager; + +import javax.transaction.TransactionManager; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Date; + +import junit.framework.TestCase; + +/** + * @author Matthieu Riou <[EMAIL PROTECTED]> + */ +public class RetriesTest extends TestCase implements Scheduler.JobProcessor { + DelegateSupport _ds; + SimpleScheduler _scheduler; + ArrayList<Scheduler.JobInfo> _jobs; + ArrayList<Scheduler.JobInfo> _commit; + TransactionManager _txm; + int _tried = 0; + + public void setUp() throws Exception { + _txm = new GeronimoTransactionManager(); + _ds = new DelegateSupport(); + + _scheduler = newScheduler("n1"); + _jobs = new ArrayList<Scheduler.JobInfo>(100); + _commit = new ArrayList<Scheduler.JobInfo>(100); + } + + public void tearDown() throws Exception { + _scheduler.shutdown(); + } + + public void testRetries() throws Exception { + // speed things up a bit to hit the right code paths + _scheduler.setNearFutureInterval(5000); + _scheduler.setImmediateInterval(1000); + _scheduler.start(); + _txm.begin(); + try { + _scheduler.schedulePersistedJob(newDetail("123"), new Date()); + } finally { + _txm.commit(); + } + + Thread.sleep(5000); + assertEquals(3, _tried); + } + + + public void onScheduledJob(Scheduler.JobInfo jobInfo) throws Scheduler.JobProcessorException { + _tried++; + throw new Scheduler.JobProcessorException(jobInfo.retryCount < 2); + } + + Map<String, Object> newDetail(String x) { + HashMap<String, Object> det = new HashMap<String, Object>(); + det.put("foo", x); + return det; + } + + private SimpleScheduler newScheduler(String nodeId) { + SimpleScheduler scheduler = new SimpleScheduler(nodeId, _ds.delegate()); + scheduler.setJobProcessor(this); + scheduler.setTransactionManager(_txm); + return scheduler; + } + +}
Modified: ode/trunk/utils/src/main/java/org/apache/ode/utils/Namespaces.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/Namespaces.java?rev=658024&r1=658023&r2=658024&view=diff ============================================================================== --- ode/trunk/utils/src/main/java/org/apache/ode/utils/Namespaces.java (original) +++ ode/trunk/utils/src/main/java/org/apache/ode/utils/Namespaces.java Mon May 19 15:57:24 2008 @@ -43,8 +43,9 @@ public static final String WS_ADDRESSING_NS = "http://www.w3.org/2005/08/addressing"; public static final String WS_ADDRESSING_WSDL_NS = "http://www.w3.org/2006/05/addressing/wsdl"; public static final String WS_ADDRESSING_ANON_URI = "http://www.w3.org/2005/08/addressing/anonymous"; + public static final String HTTP_NS = "http://schemas.xmlsoap.org/wsdl/http/"; public static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/"; - public static final String SOAP_ENV_NS = "http://schemas.xmlsoap.org/soap/envelope/"; + public static final String SOAP_ENV_NS = "http://schemas.xmlsoap.org/soap/envelope/"; public static final String WSDL_11 = "http://schemas.xmlsoap.org/wsdl/"; public static final String WSDL_20 = "http://www.w3.org/2006/01/wsdl"; public static final String XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; Modified: ode/trunk/utils/src/main/java/org/apache/ode/utils/SerializableUtils.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/SerializableUtils.java?rev=658024&r1=658023&r2=658024&view=diff ============================================================================== --- ode/trunk/utils/src/main/java/org/apache/ode/utils/SerializableUtils.java (original) +++ ode/trunk/utils/src/main/java/org/apache/ode/utils/SerializableUtils.java Mon May 19 15:57:24 2008 @@ -26,79 +26,79 @@ */ public class SerializableUtils { - /** - * Clone a <code>Serializable</code> object; for use when a - * <code>clone()</code> method is not available. - * - * @param obj - * object to clone - * - * @return clone object - * - * @throws RuntimeException - */ - public static Object cloneSerializable(Object obj) { - Object ret = null; - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(StreamUtils.DEFAULT_BUFFER_SIZE); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(obj); - oos.close(); - - ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bis); - - try { - ret = ois.readObject(); - } - catch (ClassNotFoundException cnfe) { - assert false; - } - - ois.close(); - } - catch (IOException ioex) { - throw new RuntimeException("Unable to clone object: " + obj); - } - - return ret; - } - - public static byte[] toBytes(Object obj) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(StreamUtils.DEFAULT_BUFFER_SIZE); - try { - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(obj); + /** + * Clone a <code>Serializable</code> object; for use when a + * <code>clone()</code> method is not available. + * + * @param obj + * object to clone + * + * @return clone object + * + * @throws RuntimeException + */ + public static Object cloneSerializable(Object obj) { + Object ret = null; + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(StreamUtils.DEFAULT_BUFFER_SIZE); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + + try { + ret = ois.readObject(); + } + catch (ClassNotFoundException cnfe) { + assert false; + } + + ois.close(); + } + catch (IOException ioex) { + throw new RuntimeException("Unable to clone object: " + obj); + } + + return ret; + } + + public static byte[] toBytes(Object obj) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(StreamUtils.DEFAULT_BUFFER_SIZE); + try { + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + } + catch (IOException e) { + throw new RuntimeException("Error serializing object: " + obj.getClass() + ".", e); + } + return bos.toByteArray(); + } + + public static Object toObject(InputStream binaryStream, final ClassLoader cl) { + try { + ObjectInputStream ois = new ObjectInputStream(binaryStream) { + + protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { + String name = desc.getName(); + try { + return Class.forName(name, false, cl); + } catch (ClassNotFoundException ex) { + return super.resolveClass(desc); + } + } + }; + return ois.readObject(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static Object toObject(byte[] arr, final ClassLoader cl) { + ByteArrayInputStream bis = new ByteArrayInputStream(arr); + return toObject(bis, cl); } - catch (IOException e) { - throw new RuntimeException("Error serializing object: " + obj.getClass() + ".", e); - } - return bos.toByteArray(); - } - - public static Object toObject(InputStream binaryStream, final ClassLoader cl) { - try { - ObjectInputStream ois = new ObjectInputStream(binaryStream) { - - protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { - String name = desc.getName(); - try { - return Class.forName(name, false, cl); - } catch (ClassNotFoundException ex) { - return super.resolveClass(desc); - } - }; - return ois.readObject(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static Object toObject(byte[] arr, final ClassLoader cl) { - ByteArrayInputStream bis = new ByteArrayInputStream(arr); - return toObject(bis, cl); - } } Added: ode/trunk/utils/src/main/java/org/apache/ode/utils/fs/FileWatchDog.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/fs/FileWatchDog.java?rev=658024&view=auto ============================================================================== --- ode/trunk/utils/src/main/java/org/apache/ode/utils/fs/FileWatchDog.java (added) +++ ode/trunk/utils/src/main/java/org/apache/ode/utils/fs/FileWatchDog.java Mon May 19 15:57:24 2008 @@ -0,0 +1,141 @@ +/* + * 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.ode.utils.fs; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; + +/** + * This class is based on [EMAIL PROTECTED] org.apache.log4j.helpers.FileWatchdog}.<p/> + * Modifications have been made to support additional file events (creation, deletion and updates), and to allow "manual" + * invocations of [EMAIL PROTECTED] #checkAndConfigure()} (i.e wihtout having to use a thread) while preserving time checking.<p/> + * Now two use cases coexist: + * <ol> + * <li>Pass an instance of [EMAIL PROTECTED] FileWatchDog} to a new thread ([EMAIL PROTECTED] FileWatchDog} is a [EMAIL PROTECTED] Runnable}). + * So that [EMAIL PROTECTED] FileWatchDog#checkAndConfigure()} will be called automatically every [EMAIL PROTECTED] delay} milliseconds.</li> + * <li>Invoke [EMAIL PROTECTED] FileWatchDog#checkAndConfigure()} only when you feel like it. If the expiration date previously set is lower than NOW then event + * callback methods will be invoked accordingly.</li> + * </ol> + * + * @author Ceki Gülcü + * @author <a href="mailto:[EMAIL PROTECTED]">Alexis Midon</a> + */ +public class FileWatchDog implements Runnable { + static final public long DEFAULT_DELAY = 60000; + private final Log log; + + long expire; + long lastModif; + long delay = DEFAULT_DELAY; + boolean fileExistedBefore, warnedAlready, interrupted; + protected final File file; + + protected FileWatchDog(File file, long delay) { + this(file); + this.delay = delay; + } + + protected FileWatchDog(File file) { + this.file = file; + log = LogFactory.getLog(FileWatchDog.class); + } + + protected boolean isInitialized() throws Exception { + return true; + } + + protected void init() throws Exception { + } + + protected void doOnDelete() throws Exception { + init(); + } + + protected void doOnUpdate() throws Exception { + init(); + } + + public long getDelay() { + return delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + public void run() { + try { + while (!interrupted) { + try { + Thread.currentThread().sleep(delay); + } catch (InterruptedException e) { + // no interruption expected + } + checkAndConfigure(); + } + } catch (Exception e) { + log.warn("Exception occured. Thread will stop", e); + } + } + + + public final void checkAndConfigure() throws Exception { + long now = System.currentTimeMillis(); + if (expire <= now) { + expire = now + delay; + boolean fileExists; + try { + fileExists = file.exists(); + } catch (SecurityException e) { + log.warn("Was not allowed to read check file existance, file:[" + file.getPath() + "]."); + interrupted = true; // there is no point in continuing + return; + } + + if (fileExists) { + fileExistedBefore = true; + long l = file.lastModified(); + if (l > lastModif) { + lastModif = l; + if (log.isDebugEnabled()) + log.debug("File [" + file + "] has been modified"); + doOnUpdate(); + warnedAlready = false; + } + } else if (!isInitialized()) { + // first time and no file + init(); + } else { + if (fileExistedBefore) { + fileExistedBefore = false; + doOnDelete(); + } + if (!warnedAlready) { + warnedAlready = true; + if (log.isDebugEnabled()) log.debug("[" + file + "] does not exist."); + } + } + } + } + + +} Added: ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/Messages.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/Messages.java?rev=658024&view=auto ============================================================================== --- ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/Messages.java (added) +++ ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/Messages.java Mon May 19 15:57:24 2008 @@ -0,0 +1,208 @@ +/* + * 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.ode.utils.wsdl; + +import org.apache.ode.utils.msg.MessageBundle; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.Iterator; + +/** + * @author [EMAIL PROTECTED] + */ +public class Messages extends MessageBundle { + + + /** + * Attempted to import WSDL for namespace {0} from multiple locations: + * definitions from {1} will be ignored + */ + public String msgDuplicateWSDLImport(String tns, String location) { + return format("Attempted to import WSDL for namespace {0} from" + + " multiple locations: definitions from {1} will be ignored", tns, location); + } + + /** + * The WSDL for namespace "{0}" could not be found in "{1}". + */ + public String msgWsdlImportNotFound(String wsdlUri, String location) { + return format("The WSDL for namespace \"{0}\" could not be found in \"{1}\".", wsdlUri, location); + } + + /** + * No <http:operation> or <soap:operation> for operation {0} + */ + public String msgNoBindingForOperation(String operationName) { + return format("No <http:operation> or <soap:operation> for operation {0}", operationName); + } + + /** + * Opeartion {0} has multiple binding elements + */ + public String msgMultipleBindingsForOperation(String operationName) { + return format("Operation {0} has multiple binding elements", operationName); + } + + /** + * No <http:binding> or <soap:binding> for port {0} + */ + public String msgNoBinding(QName bindingName) { + return format("No <http:binding> or <soap:binding> for binding {0}", bindingName); + } + + /** + * Port {0} has multiple binding elements + */ + public String msgMultipleBindings(QName bindingName) { + return format("Binding {0} has multiple binding elements", bindingName); + } + + /** + * No HTTP binding for port: {0} + */ + public String msgNoHTTPBindingForPort(String name) { + return format("No HTTP binding for port: {0}", name); + } + + /** + * No SOAP binding for port: {0} + */ + public String msgNoSOAPBindingForPort(String name) { + return format("No SOAP binding for port: {0}", name); + } + + /** + * No address for port {0} + */ + public String msgNoAddressForPort(String portName) { + return format("No address for port {0}", portName); + } + + /** + * Multiple addresses for port {0} + */ + public String msgMultipleAddressesForPort(String portName) { + return format("Multiple addresses for port {0}", portName); + } + + public Throwable msgSOAPBodyDoesNotContainAllRequiredParts() { + String s = format("SOAP body does not contain all required parts"); + return new IllegalArgumentException(s); + } + + public Throwable msgSoapHeaderMissingRequiredElement(QName elementType) { + String s = format("SOAP header missing required element: {0}.", elementType); + return new IllegalArgumentException(s); + } + + + public Throwable msgUndefinedFault(QName serviceName, String portName, String opname, QName faultName) { + String s = format("Undefined fault: service {0} port {1} operation {2} fault {3}.", serviceName, portName, opname, faultName); + return new IllegalArgumentException(s); + } + + public Throwable msgOdeMessagePartMissingRequiredElement(QName serviceName, String portName, String opname, QName elementName) { + String s = format("Message part is missing required element: service {0} port {1} operation {2} element {3}.", + serviceName, portName, opname, elementName); + return new IllegalArgumentException(s); + } + + public Throwable msgBindingDefinesNonElementDocListParts() { + String s = format("Binding defines non-element document literal part(s)"); + return new IllegalArgumentException(s); + } + + public Throwable msgUnexpectedElementInSOAPBody(QName name, QName elementName) { + String s = format("Unexpected element in SOAP body: message {0} element {1}.", name, elementName); + return new IllegalArgumentException(s); + } + + + public Throwable msgSOAPBodyDoesNotContainRequiredPart(String name) { + String s = format("SOAP body does not contain required part: {0}.", name); + return new IllegalArgumentException(s); + } + + + public Throwable msgSoapBodyDoesNotContainExpectedPartWrapper(QName serviceName, String portName, QName rpcWrapQName) { + String s = format("SOAP body does not contain expected part wrapper: service {0} port {1} wrapper {2}", + serviceName, portName, rpcWrapQName); + return new IllegalArgumentException(s); + } + + public Throwable msgSoapHeaderReferencesUnkownPart(String part) { + String s = format("SOAP header references unknown part: {0}.", part); + return new IllegalArgumentException(s); + } + + + public Throwable msgOdeMessageMissingRequiredPart(String partName) { + String s = format("Message is missing required part: {0}", partName); + return new IllegalArgumentException(s); + } + + public Throwable msgUnexpectedBindingClass(Class passedClass) { + String s = format("Unexpected class: {0}! Must be passed javax.wsdl.extensions.soap.SOAPBinding or javax.wsdl.extensions.http.HTTPBinding", passedClass); + return new IllegalArgumentException(s); + } + + public String msgPortDefinitionNotFound(QName serviceName, String portName) { + return format("Port definition not found: service {0} port {1}.", serviceName, portName); + } + + public Throwable msgBindingOperationNotFound(QName serviceName, String portName, String name) { + String s = format("Binding operation not found: service {0} port {1} name {2}.", serviceName, portName, name); + return new IllegalArgumentException(s); + } + + public Throwable msgBindingInputNotFound(QName serviceName, String portName, String name) { + String s = format("Binding input not found: service {0} port {1} name {2}.", serviceName, portName, name); + return new IllegalArgumentException(s); + } + + + public Throwable msgBindingOutputNotFound(QName serviceName, String portName, String name) { + String s = format("Binding output not found: service {0} port {1} name {2}.", serviceName, portName, name); + return new IllegalArgumentException(s); + } + + public String msgServiceDefinitionNotFound(QName serviceName) { + return format("Service definition not found: {0}.", serviceName); + } + + public String msgBindingNotFound(String portName) { + return format("Binding not found: port {0}.", portName); + } + + public String msgMissingReplacementValuesFor(Collection<String> partNames) { + StringBuilder sb = new StringBuilder(); + for (Iterator it = partNames.iterator(); it.hasNext();) { + sb.append(it.next()); + if (it.hasNext()) sb.append(", "); + } + return format("Missing Replacement value for {0}", sb.toString()); + } + + + + public String msgMultipleMimeContent() { + return format("Multiple MIME Contents found!"); + } +} Added: ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/WsdlUtils.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/WsdlUtils.java?rev=658024&view=auto ============================================================================== --- ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/WsdlUtils.java (added) +++ ode/trunk/utils/src/main/java/org/apache/ode/utils/wsdl/WsdlUtils.java Mon May 19 15:57:24 2008 @@ -0,0 +1,219 @@ +/* + * 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.ode.utils.wsdl; + +import org.apache.ode.utils.stl.CollectionsX; + +import javax.wsdl.Binding; +import javax.wsdl.Port; +import javax.wsdl.BindingOperation; +import javax.wsdl.BindingInput; +import javax.wsdl.Service; +import javax.wsdl.Definition; +import javax.wsdl.extensions.ExtensibilityElement; +import javax.wsdl.extensions.mime.MIMEContent; +import javax.wsdl.extensions.mime.MIMEMultipartRelated; +import javax.wsdl.extensions.http.HTTPBinding; +import javax.wsdl.extensions.http.HTTPOperation; +import javax.wsdl.extensions.http.HTTPUrlEncoded; +import javax.wsdl.extensions.http.HTTPUrlReplacement; +import javax.wsdl.extensions.http.HTTPAddress; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author <a href="mailto:[EMAIL PROTECTED]">Alexis Midon</a> + */ +public class WsdlUtils { + + private static final Messages msgs = Messages.getMessages(Messages.class); + + /** + * Test if the given binding uses a Soap binding. + * + * @param binding + * @return true if [EMAIL PROTECTED] SOAPBinding} is assignable from the binding + * @see #getBindingExtension(javax.wsdl.Binding) + */ + public static boolean useSOAPBinding(Binding binding) { + ExtensibilityElement element = getBindingExtension(binding); + return SOAPBinding.class.isAssignableFrom(element.getClass()); + } + + + /** + * Test if the given binding uses a Http binding. + * + * @param binding + * @return true if [EMAIL PROTECTED] HTTPBinding} is assignable from the binding + * @see #getBindingExtension(javax.wsdl.Binding) + */ + public static boolean useHTTPBinding(Binding binding) { + ExtensibilityElement element = getBindingExtension(binding); + return HTTPBinding.class.isAssignableFrom(element.getClass()); + } + + + /** + * @see #useSOAPBinding(javax.wsdl.Binding) + */ + public static boolean useSOAPBinding(Port port) { + return useSOAPBinding(port.getBinding()); + } + + /** + * @see #useHTTPBinding(javax.wsdl.Binding) + */ + public static boolean useHTTPBinding(Port port) { + return useHTTPBinding(port.getBinding()); + } + + /** + * @see #useSOAPBinding(javax.wsdl.Binding) + */ + public static boolean useSOAPBinding(Definition def, QName serviceName, String portName) { + Service serviceDef = def.getService(serviceName); + if (serviceDef == null) + throw new IllegalArgumentException(msgs.msgServiceDefinitionNotFound(serviceName)); + Port port = serviceDef.getPort(portName); + if (port == null) + throw new IllegalArgumentException(msgs.msgPortDefinitionNotFound(serviceName, portName)); + return useSOAPBinding(port); + } + + /** + * @see #useHTTPBinding(javax.wsdl.Binding) + */ + public static boolean useHTTPBinding(Definition def, QName serviceName, String portName) { + Service serviceDef = def.getService(serviceName); + if (serviceDef == null) + throw new IllegalArgumentException(msgs.msgServiceDefinitionNotFound(serviceName)); + Port port = serviceDef.getPort(portName); + if (port == null) + throw new IllegalArgumentException(msgs.msgPortDefinitionNotFound(serviceName, portName)); + return useHTTPBinding(port); + } + + /** + * Look up the ExtensibilityElement defining the binding for the given Port or + * throw an [EMAIL PROTECTED] IllegalArgumentException} if no or multiple bindings found. + * + * @param port + * @return an instance of [EMAIL PROTECTED] SOAPBinding} or [EMAIL PROTECTED] HTTPBinding} + */ + public static ExtensibilityElement getBindingExtension(Binding binding) { + Collection bindings = new ArrayList(); + CollectionsX.filter(bindings, binding.getExtensibilityElements(), HTTPBinding.class); + CollectionsX.filter(bindings, binding.getExtensibilityElements(), SOAPBinding.class); + if (bindings.size() == 0) { + // exception if no bindings found + throw new IllegalArgumentException(msgs.msgNoBinding(binding.getQName())); + } else if (bindings.size() > 1) { + // exception if multiple bindings found + throw new IllegalArgumentException(msgs.msgMultipleBindings(binding.getQName())); + } else { + // retrieve the single element + ExtensibilityElement result = (ExtensibilityElement) bindings.iterator().next(); + return result; + } + } + + public static ExtensibilityElement getBindingExtension(Port port) { + Binding binding = port.getBinding(); + if (binding == null) { + throw new IllegalArgumentException(msgs.msgBindingNotFound(port.getName())); + } + + return getBindingExtension(binding); + } + + public static ExtensibilityElement getOperationExtension(BindingOperation bindingOperation) { + Collection operations = new ArrayList(); + CollectionsX.filter(operations, bindingOperation.getExtensibilityElements(), HTTPOperation.class); + CollectionsX.filter(operations, bindingOperation.getExtensibilityElements(), SOAPOperation.class); + + if (operations.size() == 0) { + // exception if no bindings found + throw new IllegalArgumentException(msgs.msgNoBindingForOperation(bindingOperation.getName())); + } else if (operations.size() > 1) { + // exception if multiple bindings found + throw new IllegalArgumentException(msgs.msgMultipleBindingsForOperation(bindingOperation.getName())); + } else { + // retrieve the single element + ExtensibilityElement result = (ExtensibilityElement) operations.iterator().next(); + return result; + } + + } + + public static boolean useUrlEncoded(BindingInput bindingInput) { + Collection<HTTPUrlEncoded> coll = CollectionsX.filter(bindingInput.getExtensibilityElements(), HTTPUrlEncoded.class); + return !coll.isEmpty(); + } + + public static boolean useUrlReplacement(BindingInput bindingInput) { + Collection<HTTPUrlReplacement> coll = CollectionsX.filter(bindingInput.getExtensibilityElements(), HTTPUrlReplacement.class); + return !coll.isEmpty(); + } + + public static boolean useMimeMultipartRelated(BindingInput bindingInput) { + Collection<MIMEMultipartRelated> coll = CollectionsX.filter(bindingInput.getExtensibilityElements(), MIMEMultipartRelated.class); + return !coll.isEmpty(); + } + + public static String getMimeContentType(List extensibilityElements) { + Collection<MIMEContent> coll = CollectionsX.filter(extensibilityElements, MIMEContent.class); + if (coll.size() == 0) { + return null; + } else if (coll.size() > 1) { + // exception if multiple contents found + throw new IllegalArgumentException(msgs.msgMultipleMimeContent()); + } else { + // retrieve the single element + MIMEContent mimeContent = coll.iterator().next(); + return mimeContent.getType(); + } + } + + public static ExtensibilityElement getAddressExtension(Port port) { + Collection operations = new ArrayList(); + CollectionsX.filter(operations, port.getExtensibilityElements(), HTTPAddress.class); + CollectionsX.filter(operations, port.getExtensibilityElements(), SOAPAddress.class); + + if (operations.size() == 0) { + // exception if no bindings found + throw new IllegalArgumentException(msgs.msgNoAddressForPort(port.getName())); + } else if (operations.size() > 1) { + // exception if multiple bindings found + throw new IllegalArgumentException(msgs.msgMultipleAddressesForPort(port.getName())); + } else { + // retrieve the single element + ExtensibilityElement result = (ExtensibilityElement) operations.iterator().next(); + return result; + } + } + + +} Added: ode/trunk/utils/src/test/java/org/apache/ode/utils/wsdl/WsdlUtilsTest.java URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/test/java/org/apache/ode/utils/wsdl/WsdlUtilsTest.java?rev=658024&view=auto ============================================================================== --- ode/trunk/utils/src/test/java/org/apache/ode/utils/wsdl/WsdlUtilsTest.java (added) +++ ode/trunk/utils/src/test/java/org/apache/ode/utils/wsdl/WsdlUtilsTest.java Mon May 19 15:57:24 2008 @@ -0,0 +1,212 @@ +/* + * 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.ode.utils.wsdl; + +import junit.framework.TestCase; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.Service; +import javax.wsdl.extensions.ExtensibilityElement; +import javax.wsdl.extensions.http.HTTPAddress; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; + +/** + * @author <a href="mailto:[EMAIL PROTECTED]">Alexis Midon</a> + */ +public class WsdlUtilsTest extends TestCase { + private Definition definition; + private Service dummyService; + + protected void setUp() throws Exception { + super.setUp(); + + URL wsdlURL = getClass().getResource("/wsdl-utils.wsdl"); + WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader(); + wsdlReader.setFeature("javax.wsdl.verbose", false); + definition = wsdlReader.readWSDL(wsdlURL.toURI().toString()); + dummyService = definition.getService(new QName("http://axis2.ode.apache.org", "DummyService")); + } + + public void testNoBinding() { + Port noBindingPort = dummyService.getPort("DummyService_port_with_no_binding"); + + try { + WsdlUtils.getBindingExtension(noBindingPort); + fail("IllegalArgumentException expected!"); + } catch (IllegalArgumentException e) { + // expected behavior + } + } + + + public void testEmptyBinding() { + Port noBindingPort = dummyService.getPort("DummyService_port_with_empty_binding"); + try { + WsdlUtils.getBindingExtension(noBindingPort); + fail("IllegalArgumentException expected!"); + } catch (IllegalArgumentException e) { + // expected behavior + } + } + + public void testMultipleBinding() { + // don't know how to test this edge case + assertTrue(true); + } + + public void testGetBindingExtension() { + Port[] ports = new Port[]{ + dummyService.getPort("DummyServiceSOAP11port_http"), + dummyService.getPort("DummyServiceHttpport") + }; + for (Port port : ports) { + try { + ExtensibilityElement elt = WsdlUtils.getBindingExtension(port); + assertNotNull("Non-null element expected!", elt); + } catch (Exception e) { + fail("No exception should be thrown!"); + } + } + } + + public void testUseSOAPBinding() { + Port soapPort = dummyService.getPort("DummyServiceSOAP11port_http"); + Port httpPort = dummyService.getPort("DummyServiceHttpport"); + + assertTrue(WsdlUtils.useSOAPBinding(soapPort)); + assertFalse(WsdlUtils.useSOAPBinding(httpPort)); + } + + public void testUseHTTPBinding() { + Port soapPort = dummyService.getPort("DummyServiceSOAP11port_http"); + Port httpPort = dummyService.getPort("DummyServiceHttpport"); + + assertTrue(WsdlUtils.useHTTPBinding(httpPort)); + assertFalse(WsdlUtils.useHTTPBinding(soapPort)); + } + + + public void testGetOperationExtension() { + Port[] ports = new Port[]{ + dummyService.getPort("DummyServiceSOAP11port_http"), + dummyService.getPort("DummyServiceHttpport") + }; + for (Port port : ports) { + BindingOperation bindingOperation = port.getBinding().getBindingOperation("hello", null, null); + ExtensibilityElement operationExtension = WsdlUtils.getOperationExtension(bindingOperation); + assertNotNull("Operation Binding expected!", operationExtension); + } + } + + public void testUseUrlEncoded() { + for (Object o : dummyService.getPorts().entrySet()) { + Map.Entry e = (Map.Entry) o; + String portName = (String) e.getKey(); + Port port = (Port) e.getValue(); + Binding binding = port.getBinding(); + if (binding == null) continue; // some bindings intentionally missing + BindingOperation bindingOperation = binding.getBindingOperation("hello", null, null); + if (bindingOperation == null) continue; // some bindings intentionally empty + if ("DummyServiceHttpport_urlEncoded".equals(portName)) { + assertTrue(WsdlUtils.useUrlEncoded(bindingOperation.getBindingInput())); + } else { + assertFalse(WsdlUtils.useUrlEncoded(bindingOperation.getBindingInput())); + } + } + } + + public void testUseUrlReplacement() { + for (Iterator it = dummyService.getPorts().entrySet().iterator(); it.hasNext();) { + Map.Entry e = (Map.Entry) it.next(); + String portName = (String) e.getKey(); + Port port = (Port) e.getValue(); + Binding binding = port.getBinding(); + if (binding == null) continue; // some bindings intentionally missing + BindingOperation bindingOperation = binding.getBindingOperation("hello", null, null); + if (bindingOperation == null) continue; // some bindings intentionally empty + if ("DummyServiceHttpport_urlReplacement".equals(portName)) { + assertTrue(WsdlUtils.useUrlReplacement(bindingOperation.getBindingInput())); + } else { + assertFalse(WsdlUtils.useUrlReplacement(bindingOperation.getBindingInput())); + } + } + } + + public void testUseMimeMultipartRelated() { + for (Iterator it = dummyService.getPorts().values().iterator(); it.hasNext();) { + Port port = (Port) it.next(); + Binding binding = port.getBinding(); + if (binding == null) continue; // some bindings intentionally missing + BindingOperation bindingOperation = binding.getBindingOperation("hello", null, null); + if (bindingOperation == null) continue; // some bindings intentionally empty + for (int i = 0; i < binding.getBindingOperations().size(); i++) { + BindingOperation operation = (BindingOperation) binding.getBindingOperations().get(i); + assertFalse(WsdlUtils.useMimeMultipartRelated(operation.getBindingInput())); + } + } + } + + public void testGetAddresExtgension() { + for (Iterator it = dummyService.getPorts().entrySet().iterator(); it.hasNext();) { + Map.Entry e = (Map.Entry) it.next(); + Port port = (Port) e.getValue(); + + if("DummyService_port_with_empty_binding".equals(port.getName()) + || "DummyService_port_with_no_binding".equals(port.getName())){ + continue; + } + + if (WsdlUtils.useHTTPBinding(port)) { + HTTPAddress add = (HTTPAddress) WsdlUtils.getAddressExtension(port); + assertNotNull("Address expected", add); + assertNotNull("Non-null Location expected", add.getLocationURI()); + assertTrue("Non-empty Location expected", add.getLocationURI().length() > 0); + } else if (WsdlUtils.useHTTPBinding(port)) { + SOAPAddress add = (SOAPAddress) WsdlUtils.getAddressExtension(port); + assertNotNull("Address expected", add); + assertNotNull("Non-null Location expected", add.getLocationURI()); + assertTrue("Non-empty Location expected", add.getLocationURI().length() > 0); + } + } + } + + public void testGetMimeContentType() { + Binding binding = definition.getBinding(new QName("http://axis2.ode.apache.org", "DummyServiceHttpBinding")); + BindingOperation operation = binding.getBindingOperation("hello", null, null); + String mimeContentType = WsdlUtils.getMimeContentType(operation.getBindingInput().getExtensibilityElements()); + assertEquals("text/xml", mimeContentType); + + binding = definition.getBinding(new QName("http://axis2.ode.apache.org", "DummyServiceSOAP11Binding")); + operation = binding.getBindingOperation("hello", null, null); + mimeContentType = WsdlUtils.getMimeContentType(operation.getBindingInput().getExtensibilityElements()); + assertNull(mimeContentType); + + + } +} Added: ode/trunk/utils/src/test/resources/wsdl-utils.wsdl URL: http://svn.apache.org/viewvc/ode/trunk/utils/src/test/resources/wsdl-utils.wsdl?rev=658024&view=auto ============================================================================== --- ode/trunk/utils/src/test/resources/wsdl-utils.wsdl (added) +++ ode/trunk/utils/src/test/resources/wsdl-utils.wsdl Mon May 19 15:57:24 2008 @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8"?> +<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" + xmlns:ns0="http://axis2.ode.apache.org/xsd" + xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" + xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" + xmlns:ns1="http://axis2.ode.apache.org" + xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + targetNamespace="http://axis2.ode.apache.org"> + <wsdl:message name="helloRequest"> + <wsdl:part name="TestPart" type="xs:string"/> + </wsdl:message> + <wsdl:message name="helloResponse"> + <wsdl:part name="TestPart" type="xs:string"/> + </wsdl:message> + <wsdl:portType name="DummyServicePortType"> + <wsdl:operation name="hello"> + <wsdl:input message="ns1:helloRequest" wsaw:Action="urn:hello"/> + <wsdl:output message="ns1:helloResponse" wsaw:Action="urn:helloResponse"/> + </wsdl:operation> + </wsdl:portType> + <wsdl:binding name="DummyServiceSOAP11Binding" type="ns1:DummyServicePortType"> + <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> + <wsdl:operation name="hello"> + <soap:operation soapAction="urn:hello" style="document"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:binding name="DummyServiceHttpBinding" type="ns1:DummyServicePortType"> + <http:binding verb="POST"/> + <wsdl:operation name="hello"> + <http:operation location="DummyService/hello"/> + <wsdl:input> + <mime:content type="text/xml" part="hello"/> + </wsdl:input> + <wsdl:output> + <mime:content type="text/xml" part="hello"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:binding name="DummyServiceHttpBinding_urlReplacement" type="ns1:DummyServicePortType"> + <http:binding verb="POST"/> + <wsdl:operation name="hello"> + <http:operation location="DummyService/hello/(part1)"/> + <wsdl:input> + <http:urlReplacement/> + </wsdl:input> + <wsdl:output> + <mime:content type="text/xml" part="hello"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:binding name="DummyServiceHttpBinding_urlEncoded" type="ns1:DummyServicePortType"> + <http:binding verb="POST"/> + <wsdl:operation name="hello"> + <http:operation location="DummyService/hello"/> + <wsdl:input> + <http:urlEncoded/> + </wsdl:input> + <wsdl:output> + <mime:content type="text/xml" part="hello"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:binding name="DummyServiceHttpBinding_form-urlencoded" type="ns1:DummyServicePortType"> + <http:binding verb="POST"/> + <wsdl:operation name="hello"> + <http:operation location="DummyService/hello"/> + <wsdl:input> + <mime:content type="application/x-www-form-urlencoded" part="hello"/> + </wsdl:input> + <wsdl:output> + <mime:content type="text/xml" part="hello"/> + </wsdl:output> + </wsdl:operation> + </wsdl:binding> + <wsdl:service name="DummyService"> + <wsdl:port name="DummyServiceSOAP11port_http" binding="ns1:DummyServiceSOAP11Binding"> + <soap:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + <wsdl:port name="DummyServiceHttpport" binding="ns1:DummyServiceHttpBinding"> + <http:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + <wsdl:port name="DummyService_port_with_no_binding"> + <http:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + <wsdl:port name="DummyService_port_with_empty_binding" binding=""> + <http:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + <wsdl:port name="DummyServiceHttpport_urlEncoded" binding="ns1:DummyServiceHttpBinding_urlEncoded"> + <http:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + <wsdl:port name="DummyServiceHttpport_urlReplacement" binding="ns1:DummyServiceHttpBinding_urlReplacement"> + <http:address location="http://localhost:8080/processes/DummyService"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> \ No newline at end of file
