/******************************************************************************* * Copyright (c) 2009 MATERNA Information & Communications. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html. For further * project-related information visit http://www.ws4d.org. The most recent * version of the JMEDS framework can be obtained from * http://sourceforge.net/projects/ws4d-javame. ******************************************************************************/ package org.ws4d.java.service; import java.io.IOException; import org.ws4d.java.DPWSFramework; import org.ws4d.java.communication.CommunicationManager; import org.ws4d.java.communication.CommunicationUtil; import org.ws4d.java.communication.DefaultResponseCallback; import org.ws4d.java.communication.ProtocolData; import org.ws4d.java.communication.TimeoutException; import org.ws4d.java.configuration.FrameworkProperties; import org.ws4d.java.constants.ConstantsHelper; import org.ws4d.java.constants.DPWSMessageConstants; import org.ws4d.java.dispatch.MissingMetadataException; import org.ws4d.java.dispatch.OutDispatcher; import org.ws4d.java.dispatch.ServiceReferenceInternal; import org.ws4d.java.eventing.ClientSubscription; import org.ws4d.java.eventing.ClientSubscriptionInternal; import org.ws4d.java.eventing.EventSink; import org.ws4d.java.eventing.EventingException; import org.ws4d.java.eventing.EventingFactory; import org.ws4d.java.message.FaultMessage; import org.ws4d.java.message.InvokeMessage; import org.ws4d.java.message.Message; import org.ws4d.java.message.SOAPHeader; import org.ws4d.java.message.eventing.GetStatusMessage; import org.ws4d.java.message.eventing.GetStatusResponseMessage; import org.ws4d.java.message.eventing.RenewMessage; import org.ws4d.java.message.eventing.RenewResponseMessage; import org.ws4d.java.message.eventing.SubscribeMessage; import org.ws4d.java.message.eventing.SubscribeResponseMessage; import org.ws4d.java.message.eventing.UnsubscribeMessage; import org.ws4d.java.message.eventing.UnsubscribeResponseMessage; import org.ws4d.java.schema.SchemaUtil; import org.ws4d.java.service.parameter.ParameterValue; import org.ws4d.java.service.reference.DeviceReference; import org.ws4d.java.service.reference.ServiceReference; import org.ws4d.java.structures.DataStructure; import org.ws4d.java.structures.HashSet; import org.ws4d.java.structures.Iterator; import org.ws4d.java.types.Delivery; import org.ws4d.java.types.EndpointReference; import org.ws4d.java.types.EprInfo; import org.ws4d.java.types.Filter; import org.ws4d.java.types.QName; import org.ws4d.java.types.QNameSet; import org.ws4d.java.types.ReferenceParametersMData; import org.ws4d.java.types.URI; import org.ws4d.java.types.URISet; import org.ws4d.java.types.XAddressInfo; import org.ws4d.java.util.Log; import org.ws4d.java.wsdl.WSDL; import org.ws4d.java.wsdl.WSDLOperation; import org.ws4d.java.wsdl.WSDLPortType; import org.ws4d.java.wsdl.WSDLRepository; /** * Proxy class of a dpws service. * * @author mspies */ public class ProxyService extends ServiceCommons { private ServiceReference serviceReference; /** * Constructor. Will create proxy service, which must be initialized by * {@link #initialize(ServiceReference, DeviceReference)()} later on. */ ProxyService() {} /** * @param serviceReference * @throws MissingMetadataException in case no service description metadata * (i.e. WSDL) was found for at least one of the service's port * types */ public ProxyService(ServiceReference serviceReference) throws MissingMetadataException { super(); try { initialize(serviceReference); } catch (InstantiationException e) { // won't happen } } /** * Must be called after construction of ProxyService without * {@link ServiceReference} as parameter. * * @param serviceReference */ protected void initialize(ServiceReference serviceReference) throws InstantiationException, MissingMetadataException { if (this.serviceReference != null) { throw new InstantiationException("ProxyService already initialized!"); } this.serviceReference = serviceReference; this.setSecure(serviceReference.isSecureService()); if (!WSDLRepository.DEMO_MODE) { if (loadFromEmbeddedWSDLs(getPortTypes())) { return; } } /* * not all found within embedded WSDLs, try building up from metadata * locations and local repo */ if (loadFromMetadataLocations(getPortTypes())) { return; } /* * finally, try to resolve port types within local repo */ if (loadFromRepository(getPortTypes())) { return; } throw new MissingMetadataException("Unable to resolve all port types of service"); } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getServiceReference() */ public ServiceReference getServiceReference() { return serviceReference; } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getParentDeviceReference() */ public DeviceReference getParentDeviceReference() { return serviceReference.getParentDeviceRef(); } // ------------------------------------------------------- /* * (non-Javadoc) * @see org.ws4d.java.service.Service#isRemote() */ public boolean isRemote() { return true; } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getServiceId() */ public URI getServiceId() { return serviceReference.getServiceId(); } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getEndpointReferences() */ public Iterator getEprInfos() { return serviceReference.getEprInfos(); } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getPortTypes() */ public Iterator getPortTypes() { return serviceReference.getPortTypes(); } public int getPortTypeCount() { return portTypes.size(); } /** * @param portTypes new port types to add to this proxy service * @throws MissingMetadataException if no metadata (WSDL) is found for at * least one of the specified <code>portTypes</code> */ public void appendPortTypes(QNameSet portTypes) throws MissingMetadataException { if (loadFromMetadataLocations(portTypes.iterator())) { return; } if (!loadFromRepository(portTypes.iterator())) { throw new MissingMetadataException("Unable to resolve some port types of service: " + portTypes); } } /** * Initializes event receiving from specified event sender. * * @param sink event sink which will receive the notifications. * @param clientSubscriptionId * @param eventActionURIs set of action URIs to subscribe to. * @param duration duration in milliseconds of subscription. If 0 no * expiration of subscription. * @return subscription id (wse:identifier) * @throws EventingException * @throws TimeoutException */ public ClientSubscription subscribe(EventSink sink, String clientSubscriptionId, URISet eventActionURIs, long duration) throws EventingException, TimeoutException { if (!sink.isOpen()) { Log.error("Cannot subscribe, event sink is not open"); throw new EventingException("EventSink not open"); } /* * Create subscibe message */ ServiceReferenceInternal serviceRef = (ServiceReferenceInternal) getServiceReference(); XAddressInfo preferredXAddressInfo = serviceRef.getPreferredXAddressInfo(); SubscribeMessage request = new SubscribeMessage(preferredXAddressInfo.getComManId()); request.getHeader().setEndpointReference(((EprInfo) getEprInfos().next()).getEndpointReference()); request.setTargetXAddressInfo(preferredXAddressInfo); // request.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(getParentDeviceReference().getEndpointReference())); request.setProtocolInfo(preferredXAddressInfo.getProtocolInfo()); ReferenceParametersMData refParams = new ReferenceParametersMData(); refParams.setWseIdentifier(clientSubscriptionId); /* * TODO find out which of the sink's bindings corresponds to the * communication interface, which from the address of one of the EPRs of * the target service is reachable from */ EndpointReference notifyTarget = new EndpointReference(URI.EMPTY_URI, refParams); Delivery delivery = new Delivery(null, notifyTarget); request.setDelivery(delivery); request.setEventSink(sink); if (duration != 0) { request.setExpires(SchemaUtil.createDuration(duration)); } CommunicationManager comMan = DPWSFramework.getCommunicationManager(preferredXAddressInfo.getComManId()); CommunicationUtil comUtil = comMan.getCommunicationUtil(); ConstantsHelper helper = null; if (request.getProtocolInfo() == null) { helper = comUtil.getHelper(comMan.getProtocolInfo().getVersion()); } else { helper = comUtil.getHelper(request.getProtocolInfo().getVersion()); } Filter filter = new Filter(helper.getDPWSUriFilterEeventingAction(), eventActionURIs); request.setFilter(filter); ProxyServiceCallback handler = new ProxyServiceCallback(preferredXAddressInfo); OutDispatcher.getInstance().send(request, preferredXAddressInfo, handler); synchronized (handler) { while (handler.pending) { try { handler.wait(); } catch (InterruptedException e) { // void } } } if (handler.exception != null) { throw handler.exception; } ClientSubscription subscription = null; if (handler.msg != null) { /* * CASE: Subscription Response received */ SubscribeResponseMessage subscribeRsp = (SubscribeResponseMessage) handler.msg; EventingFactory eFac = null; try { eFac = DPWSFramework.getEventingFactory(); } catch (IOException e) { throw new EventingException("Cannot subscribe for events Eventing support not found."); } subscription = eFac.createClientSubscription(sink, clientSubscriptionId, subscribeRsp.getSubscriptionManager(), handler.protocolData.getCommunicationManagerId(), SchemaUtil.parseDuration(subscribeRsp.getExpires()), serviceReference); // SubscriptionManager manager = new SubscriptionManagerProxy( // serviceSubscriptionId, sink, duration ); // // subscription = new // DefaultClientSubscription(clientSubscriptionId, // serviceSubscriptionId, serviceReference, manager); subscription.getSubscriptionManagerAddressInfo().setProtocolInfo(handler.protocolData.getProtocolInfo()); sink.addSubscription(clientSubscriptionId, subscription); } else if (handler.fault != null) { /* * CASE: Fault received */ throw new EventingException(handler.fault); } else { // shouldn't ever occur throw new TimeoutException("Subscribe timeout"); } return subscription; } /** * Unsubscribes from specified subscription. * * @param subscription subscription to terminate. * @throws EventingException * @throws TimeoutException */ public void unsubscribe(ClientSubscription subscription) throws EventingException, TimeoutException { if (subscription == null) { Log.error("Cannot unsubscribe, subscription is null"); throw new EventingException("Subscription is null"); } ((ClientSubscriptionInternal) subscription).dispose(); /* * Create unsubscribe message */ EprInfo subscriptionManagerXAddressInfo = subscription.getSubscriptionManagerAddressInfo(); UnsubscribeMessage request = new UnsubscribeMessage(subscriptionManagerXAddressInfo.getComManId()); request.setTargetXAddressInfo(subscriptionManagerXAddressInfo); SOAPHeader header = request.getHeader(); header.setEndpointReference(subscriptionManagerXAddressInfo.getEndpointReference()); // request.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(getParentDeviceReference().getEndpointReference())); request.setProtocolInfo(subscriptionManagerXAddressInfo.getProtocolInfo()); ProxyServiceCallback handler = new ProxyServiceCallback(subscriptionManagerXAddressInfo); /* * XXX this is based on the assumption that both the subscribed service * as well as its possibly stand-alone subscription manager use the same * communication protocol */ OutDispatcher.getInstance().send(request, subscriptionManagerXAddressInfo, handler); synchronized (handler) { while (handler.pending) { try { handler.wait(); } catch (InterruptedException e) { // void } } } if (handler.exception != null) { throw handler.exception; } if (handler.msg != null) { // CASE: Unsubscribe Response received, return return; } else if (handler.fault != null) { // CASE: Fault received throw new EventingException(handler.fault); } else { // CASE: Timeout of watchdog // shouldn't ever occur throw new TimeoutException("Unsubscribe timeout"); } } /** * Renews an existing subscription with new duration. If duration is "0" * subscription never terminates. * * @param subscription * @param duration * @return either the actual subscription duration as reported by the * service or<code>0</code> if the subscription doesn't expire at * all * @throws EventingException * @throws TimeoutException */ public long renew(ClientSubscription subscription, long duration) throws EventingException, TimeoutException { if (subscription == null) { Log.error("Cannot renew, subscription is null"); throw new EventingException("Subscription is null"); } if (!subscription.getEventSink().isOpen()) { Log.error("Cannot renew, event sink is not open"); throw new EventingException("EventSink not open"); } /* * Create renew message */ EprInfo subscriptionManagerXAddressInfo = subscription.getSubscriptionManagerAddressInfo(); RenewMessage request = new RenewMessage(subscriptionManagerXAddressInfo.getComManId()); request.setTargetXAddressInfo(subscriptionManagerXAddressInfo); request.getHeader().setEndpointReference(subscriptionManagerXAddressInfo.getEndpointReference()); if (duration != 0) { request.setExpires(SchemaUtil.createDuration(duration)); } // request.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(getParentDeviceReference().getEndpointReference())); request.setProtocolInfo(((ServiceReferenceInternal) getServiceReference()).getPreferredXAddressInfo().getProtocolInfo()); ProxyServiceCallback handler = new ProxyServiceCallback(subscriptionManagerXAddressInfo); /* * XXX this is based on the assumption that both the subscribed service * as well as its possibly stand-alone subscription manager use the same * communication protocol */ OutDispatcher.getInstance().send(request, subscriptionManagerXAddressInfo, handler); synchronized (handler) { while (handler.pending) try { handler.wait(); } catch (InterruptedException e) { // void } } if (handler.exception != null) { throw handler.exception; } // URI subscriptionId = null; if (handler.msg != null) { // CASE: Subscription Response received RenewResponseMessage renewRsp = (RenewResponseMessage) handler.msg; long newDuration = SchemaUtil.parseDuration(renewRsp.getExpires()); ((ClientSubscriptionInternal) subscription).renewInternal(newDuration); return newDuration; } else if (handler.fault != null) { // CASE: Fault received throw new EventingException(handler.fault); } else { // shouldn't ever occur throw new TimeoutException("Renew timeout"); } } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getStatus(org.ws4d.java.eventing. * ClientSubscription) */ public long getStatus(ClientSubscription subscription) throws EventingException, TimeoutException { if (subscription == null) { Log.error("Cannot get status, subscription is null"); throw new EventingException("Subscription is null"); } if (!subscription.getEventSink().isOpen()) { Log.error("Cannot get status, event sink is not open"); throw new EventingException("EventSink not open"); } /* * Create getStatus message */ EprInfo subscriptionManagerXAddressInfo = subscription.getSubscriptionManagerAddressInfo(); GetStatusMessage request = new GetStatusMessage(subscriptionManagerXAddressInfo.getComManId()); request.setTargetXAddressInfo(subscriptionManagerXAddressInfo); request.getHeader().setEndpointReference(subscriptionManagerXAddressInfo.getEndpointReference()); // request.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(getParentDeviceReference().getEndpointReference())); request.setProtocolInfo(((ServiceReferenceInternal) getServiceReference()).getPreferredXAddressInfo().getProtocolInfo()); ProxyServiceCallback handler = new ProxyServiceCallback(subscriptionManagerXAddressInfo); /* * XXX this is based on the assumption that both the subscribed service * as well as its possibly stand-alone subscription manager use the same * communication protocol */ OutDispatcher.getInstance().send(request, subscriptionManagerXAddressInfo, handler); synchronized (handler) { while (handler.pending) { try { handler.wait(); } catch (InterruptedException e) { // void } } } if (handler.exception != null) { throw handler.exception; } // URI subscriptionId = null; if (handler.msg != null) { // CASE: GetStatus response received GetStatusResponseMessage getStatusRsp = (GetStatusResponseMessage) handler.msg; return SchemaUtil.parseDuration(getStatusRsp.getExpires()); } else if (handler.fault != null) { // CASE: Fault received throw new EventingException(handler.fault); } else { // shouldn't ever occur throw new TimeoutException("GetStatus timeout"); } } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getDescription(java.lang.String) */ public WSDL getDescription(String targetNamespace) { return getExistingDescription(targetNamespace); } private boolean loadFromEmbeddedWSDLs(Iterator portTypes) { Iterator wsdls = serviceReference.getWSDLs(); if (!wsdls.hasNext()) { return false; } // make a copy of required port types DataStructure portTypesToResolve = new HashSet(); for (Iterator it = portTypes; it.hasNext();) { QName portTypeName = (QName) it.next(); portTypesToResolve.add(portTypeName); } while (wsdls.hasNext()) { WSDL wsdl = (WSDL) wsdls.next(); this.wsdls.put(wsdl.getTargetNamespace(), wsdl); for (Iterator it = portTypesToResolve.iterator(); it.hasNext();) { QName portTypeName = (QName) it.next(); WSDLPortType portType = wsdl.getPortType(portTypeName); /* * we don't check whether this port type has an actual binding * or service definition within the WSDL, as it is declared * within the service reference (aka. within the service's * hosted block) */ if (portType != null) { processWSDLPortType(portType); it.remove(); } } } return portTypesToResolve.isEmpty(); } private boolean loadFromRepository(Iterator portTypes) { if (FrameworkProperties.getInstance().isBypassWsdlRepository()) { // do not load anything from repository if (Log.isDebug()) { Log.debug("Bypassing WSDL repository due to configuration property."); } return false; } boolean allFound = true; WSDLRepository repo = WSDLRepository.getInstance(); for (Iterator it = portTypes; it.hasNext();) { QName portTypeName = (QName) it.next(); if (this.portTypes.containsKey(portTypeName)) { // port type already loaded continue; } WSDLPortType wsdlPortType = null; for (Iterator it2 = this.wsdls.values().iterator(); it2.hasNext();) { WSDL wsdl = (WSDL) it2.next(); wsdlPortType = wsdl.getPortType(portTypeName); if (wsdlPortType != null) { break; } } if (wsdlPortType == null) { WSDL wsdl = repo.getWsdl(portTypeName); if (wsdl == null) { allFound = false; if (Log.isDebug()) { Log.debug("Unable to find a WSDL within local repository for port type " + portTypeName, Log.DEBUG_LAYER_FRAMEWORK); } continue; } this.wsdls.put(wsdl.getTargetNamespace(), wsdl); wsdlPortType = wsdl.getPortType(portTypeName); } processWSDLPortType(wsdlPortType); } return allFound; } private boolean loadFromMetadataLocations(Iterator portTypes) throws MissingMetadataException { Iterator locations = serviceReference.getMetadataLocations(); // if (!locations.hasNext()) { /* * don't throw this here but rather let us log the missing (unresolved) * port types within the thrown exception below */ // throw new MissingMetadataException("No metadata locations found"); // } // make a copy of required port types DataStructure portTypesToResolve = new HashSet(); for (Iterator it = portTypes; it.hasNext();) { QName portTypeName = (QName) it.next(); // avoid already loaded if (!this.portTypes.containsKey(portTypeName)) { portTypesToResolve.add(portTypeName); } } while (locations.hasNext()) { if (portTypesToResolve.isEmpty()) { return true; } URI address = (URI) locations.next(); // Get WSDL from remote location try { WSDL wsdl = WSDLRepository.getInstance().getWSDL(address.toString()); if (wsdl == null) { wsdl = WSDLRepository.loadWsdl(address); } else if (Log.isDebug()) { Log.debug("WSDL from metadata location found within local repository: " + address); } this.wsdls.put(wsdl.getTargetNamespace(), wsdl); for (Iterator it = portTypesToResolve.iterator(); it.hasNext();) { QName portTypeName = (QName) it.next(); WSDLPortType portType = wsdl.getPortType(portTypeName); /* * we don't check whether this port type has an actual * binding or service definition within the WSDL, as it is * declared within the service reference (aka. within the * service's hosted block) */ if (portType != null) { processWSDLPortType(portType); it.remove(); } } } catch (IOException e) { Log.printStackTrace(e); throw new RuntimeException(e.getMessage()); } } if (!portTypesToResolve.isEmpty()) { Log.warn("Unable to resolve some port types of service from available metadata locations: " + portTypesToResolve); return false; } return true; } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#createOperation(org.ws4d.java.wsdl * .WSDLOperation) */ protected Operation createOperation(WSDLOperation wsdlOperation) { return new Operation(wsdlOperation) { public ParameterValue invoke(ParameterValue parameterValue) throws InvocationException, TimeoutException { /* * client side invocation dispatcher */ return dispatchInvoke(this, parameterValue); } }; } protected ParameterValue dispatchInvoke(Operation op, ParameterValue parameterValue) throws InvocationException, TimeoutException { // create InvokeInputMessage from op; set correct action URI InvokeMessage msg = new InvokeMessage(op.getInputAction(), CommunicationManager.ID_NULL); return dispatchInvoke(msg, op, parameterValue); } protected ParameterValue dispatchInvoke(InvokeMessage msg, Operation op, ParameterValue parameterValue) throws InvocationException, TimeoutException { msg.getHeader().setEndpointReference(((EprInfo) getEprInfos().next()).getEndpointReference()); ServiceReferenceInternal serviceRef = (ServiceReferenceInternal) getServiceReference(); XAddressInfo preferredXAddressInfo = serviceRef.getPreferredXAddressInfo(); msg.setTargetXAddressInfo(preferredXAddressInfo); msg.setContent(parameterValue); // msg.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(getParentDeviceReference().getEndpointReference())); msg.setProtocolInfo(preferredXAddressInfo.getProtocolInfo()); ProxyServiceCallback handler = new ProxyServiceCallback(preferredXAddressInfo, op); OutDispatcher.getInstance().send(msg, preferredXAddressInfo, handler); if (op.isOneWay()) { // don't block forever return null; } synchronized (handler) { while (handler.pending) { try { handler.wait(); } catch (InterruptedException e) { // void } } } if (handler.exception != null) { throw handler.exception; } if (handler.msg != null) { InvokeMessage rspMsg = (InvokeMessage) handler.msg; return rspMsg.getContent(); } else if (handler.fault != null) { /* * CASE: Fault received */ FaultMessage fault = handler.fault; throw new InvocationException(fault); } else { // shouldn't ever occur throw new TimeoutException("Invocation time out"); } } // ========================= INNER CLASS ========================= private class ProxyServiceCallback extends DefaultResponseCallback { Message msg = null; FaultMessage fault = null; TimeoutException exception = null; volatile boolean pending = true; ProtocolData protocolData; Operation op = null; ProxyServiceCallback(XAddressInfo targetXAddressInfo) { super(targetXAddressInfo); } ProxyServiceCallback(XAddressInfo targetXAddressInfo, Operation op) { super(targetXAddressInfo); this.op = op; } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, org.ws4d.java.message * .eventing.SubscribeResponseMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, SubscribeResponseMessage msg, ProtocolData protocolData) { releaseMessageSynchronization(msg, protocolData); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, * org.ws4d.java.message.invocation.InvokeMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, InvokeMessage msg, ProtocolData protocolData) { releaseMessageSynchronization(msg, protocolData); } /* * (non-Javadoc) * @see org.ws4d.java.communication.DefaultResponseCallback# * handleTransmissionException(org.ws4d.java.message.Message, * java.lang.Exception, org.ws4d.java.communication.ProtocolData) */ public void handleTransmissionException(Message request, Exception exception, ProtocolData protocolData) { if (Log.isDebug()) { Log.printStackTrace(exception); } this.exception = new TimeoutException("Malformed response: " + exception); // same as for timeouts handleTimeout(request); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, * org.ws4d.java.message.FaultMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, FaultMessage msg, ProtocolData protocolData) { synchronized (this) { pending = false; fault = msg; this.protocolData = protocolData; notifyAll(); } } /* * (non-Javadoc) * @see org.ws4d.java.communication.DefaultResponseCallback# * handleMalformedResponseException(org.ws4d.java.message.Message, * java.lang.Exception, org.ws4d.java.communication.ProtocolData) */ public void handleMalformedResponseException(Message request, Exception exception, ProtocolData protocolData) { // same as for timeouts if (Log.isDebug()) { Log.printStackTrace(exception); } synchronized (this) { this.exception = new TimeoutException("Malformed response: " + exception); pending = false; notifyAll(); } // handleTimeout(request); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handleTimeout * (org.ws4d.java.message.Message) */ public void handleTimeout(Message request) { try { ServiceReferenceInternal servRef = (ServiceReferenceInternal) getServiceReference(); XAddressInfo xAddressInfo = servRef.getNextXAddressInfoAfterFailure(request.getTargetAddress()); request.setTargetXAddressInfo(xAddressInfo); switch (request.getType()) { case (DPWSMessageConstants.INVOKE_MESSAGE): { OutDispatcher.getInstance().send((InvokeMessage) request, xAddressInfo, this); break; } case (DPWSMessageConstants.SUBSCRIBE_MESSAGE): { OutDispatcher.getInstance().send((SubscribeMessage) request, xAddressInfo, this); break; } case (DPWSMessageConstants.GET_STATUS_MESSAGE): { OutDispatcher.getInstance().send((GetStatusMessage) request, xAddressInfo, this); break; } case (DPWSMessageConstants.RENEW_MESSAGE): { OutDispatcher.getInstance().send((RenewMessage) request, xAddressInfo, this); break; } case (DPWSMessageConstants.UNSUBSCRIBE_MESSAGE): { OutDispatcher.getInstance().send((UnsubscribeMessage) request, xAddressInfo, this); break; } } } catch (Throwable e) { synchronized (this) { exception = new TimeoutException("Exception occured during transmission exception processing: " + e); pending = false; notifyAll(); } } } // ---------------------- MESSAGE HANDLING -------------------- private void releaseMessageSynchronization(Message msg, ProtocolData protocolData) { synchronized (this) { pending = false; this.msg = msg; this.protocolData = protocolData; notifyAll(); } } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, * org.ws4d.java.message.eventing.RenewResponseMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, RenewResponseMessage msg, ProtocolData protocolData) { releaseMessageSynchronization(msg, protocolData); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, org.ws4d.java.message * .eventing.UnsubscribeResponseMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, UnsubscribeResponseMessage msg, ProtocolData protocolData) { releaseMessageSynchronization(msg, protocolData); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#handle(org.ws4d * .java.communication.message.Message, org.ws4d.java.message * .eventing.GetStatusResponseMessage, * org.ws4d.java.communication.ProtocolData) */ public void handle(Message request, GetStatusResponseMessage msg, ProtocolData protocolData) { releaseMessageSynchronization(msg, protocolData); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultResponseCallback#getOperation() */ public OperationDescription getOperation() { return op; } } }