/******************************************************************************* * 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.dispatch; import java.io.IOException; import org.ws4d.java.DPWSFramework; import org.ws4d.java.communication.CommunicationManager; import org.ws4d.java.communication.Discovery; import org.ws4d.java.communication.ProtocolData; import org.ws4d.java.communication.ProtocolInfo; import org.ws4d.java.communication.ResponseCallback; import org.ws4d.java.communication.TimeoutException; import org.ws4d.java.message.discovery.ResolveMessage; import org.ws4d.java.message.metadata.GetMetadataMessage; import org.ws4d.java.service.LocalService; import org.ws4d.java.service.ProxyFactory; import org.ws4d.java.service.Service; import org.ws4d.java.service.reference.DeviceReference; import org.ws4d.java.service.reference.Reference; import org.ws4d.java.service.reference.ServiceListener; import org.ws4d.java.service.reference.ServiceReference; import org.ws4d.java.structures.ArrayList; import org.ws4d.java.structures.DataStructure; import org.ws4d.java.structures.EmptyStructures; import org.ws4d.java.structures.HashMap; import org.ws4d.java.structures.HashSet; import org.ws4d.java.structures.Iterator; import org.ws4d.java.structures.LinkedList; import org.ws4d.java.structures.List; import org.ws4d.java.structures.ReadOnlyIterator; import org.ws4d.java.types.EndpointReference; import org.ws4d.java.types.EndpointReferenceSet; import org.ws4d.java.types.EprInfo; import org.ws4d.java.types.EprInfoSet; import org.ws4d.java.types.HostedMData; import org.ws4d.java.types.QNameSet; import org.ws4d.java.types.URI; import org.ws4d.java.types.URISet; import org.ws4d.java.types.XAddressInfo; import org.ws4d.java.util.IDGenerator; import org.ws4d.java.util.Log; import org.ws4d.java.wsdl.WSDL; /** * Class holds service reference. */ public class DefaultServiceReference implements ServiceReferenceInternal { private static final int STATE_NEW = 0; private static final int STATE_NEEDS_UPDATE = 1; private static final int STATE_UP_TO_DATE = 2; private static final int SYNC_WAITTIME = 5000; private static final int SYNC_WAITRETRY = 5; private int currentState = STATE_NEW; private Service service = null; private HostedMData hosted = null; int hostedBlockVersion = 0; // list of EprInfos List resolvedEprInfos = null; // list of EndpointReferences List unresolvedEPRs = null; int currentXAddressIndex = -1; private DeviceReference parentDevRef = null; // a set of EndpointReferences pointing at the metadata locations private DataStructure metadataReferences = null; // a set of URIs pointing at the metadata locations private DataStructure metadataLocations = null; // a set of WSDLs belonging to the service private DataStructure wsdls = null; EprInfo preferredXAddressInfo; private int location = LOCATION_UNKNOWN; private boolean secure = false; private ServiceReferenceEventRegistry eventAnnouncer = ServiceReferenceEventRegistry.getInstance(); GetMetadataRequestSynchronizer getMetadataSynchronizer = null; ResolveRequestSynchronizer resolveSynchronizer = null; HashMap synchronizers = new HashMap(); /** * Constructor, used for proxy services. * * @param service */ protected DefaultServiceReference(HostedMData hosted, String comManId, ProtocolData protocolData) { if (DPWSFramework.hasModule(DPWSFramework.SECURITY_MODULE)) { Iterator iter = hosted.getEprInfoSet().iterator(); while (iter.hasNext()) { URI address = ((EprInfo) iter.next()).getXAddress(); if (address != null && DPWSFramework.getSecurityManager().isHTTPS(address)) { this.setSecureService(true); break; } } } setHostedFromDevice(hosted, comManId, protocolData); } /** * Constructor. Unknown location type of service. * * @param epr */ protected DefaultServiceReference(EndpointReference epr, String comManId) { this.hosted = new HostedMData(); EprInfo eprInfo = new EprInfo(epr, comManId); EprInfoSet eprInfoSet = new EprInfoSet(); eprInfoSet.add(eprInfo); hosted.setEprInfoSet(eprInfoSet); if (eprInfo.getXAddress() != null) { resolvedEprInfos = new ArrayList(); resolvedEprInfos.add(eprInfo); if (DPWSFramework.hasModule(DPWSFramework.SECURITY_MODULE)) { this.secure = DPWSFramework.getSecurityManager().isHTTPS(eprInfo.getXAddress()); } } } /* * (non-Javadoc) * @see java.lang.Object#toString() */ public synchronized String toString() { StringBuffer sb = new StringBuffer("DefaultServiceReference [ hosted="); sb.append(hosted); String loc = (location == LOCATION_UNKNOWN ? "unknown" : (location == LOCATION_REMOTE ? "remote" : "local")); sb.append(", location=").append(loc); if (location != LOCATION_LOCAL) { sb.append(", address=").append(preferredXAddressInfo); } sb.append(", service=").append(service); sb.append(" ]"); return sb.toString(); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getService() */ public Service getService() throws TimeoutException { return getService(true); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getService(boolean) */ public Service getService(boolean doBuildUp) throws TimeoutException { GetMetadataRequestSynchronizer sync = null; boolean havePendingSync = false; EprInfo xAddressInfo = null; synchronized (this) { if (location == LOCATION_LOCAL) { return service; } DeviceServiceRegistry.updateServiceReferenceInGarbageList(this); if (!doBuildUp || currentState == STATE_UP_TO_DATE) { return service; } if (getMetadataSynchronizer != null) { sync = getMetadataSynchronizer; havePendingSync = true; } else { // createProxyServiceFromLocalMetadata(); sync = getMetadataSynchronizer = new GetMetadataRequestSynchronizer(hostedBlockVersion); } } if (havePendingSync) { return waitForService(sync); } xAddressInfo = (EprInfo) getPreferredXAddressInfo(); // check whether there is a newer GetMetadata attempt GetMetadataRequestSynchronizer newerSync; synchronized (this) { newerSync = getMetadataSynchronizer; } if (newerSync != sync) { try { sync.service = getService(true); } catch (TimeoutException e) { sync.exception = e; } synchronized (sync) { sync.pending = false; sync.notifyAll(); } if (sync.exception != null) { throw sync.exception; } return sync.service; } synchronized (this) { synchronizers.put(sendGetMetadata(xAddressInfo).getMessageId(), sync); } return waitForService(sync); } /** * */ synchronized Service createProxyServiceFromLocalMetadata() { QNameSet types = hosted == null ? null : hosted.getTypes(); if (types != null && !types.isEmpty()) { // hosted block is not empty, we can try a local WSDL load try { ProxyFactory pFac = DPWSFramework.getProxyFactory(); service = pFac.createProxyService(this, null); // nice! :-) now let's see whether we have a service ID URI serviceId = hosted.getServiceId(); if (serviceId == null) { // set to a "faked" one serviceId = IDGenerator.getUUIDasURI(); hosted.setServiceId(serviceId); } eventAnnouncer.announceServiceCreated(this, service); return service; } catch (MissingMetadataException e) { /* * some port types not found within local repo :( try obtaining * service metadata */ } catch (IOException e) { Log.error("Cannot create service proxy from local metadata. " + e.getMessage()); } } return null; } /** * Instructs this service reference to asynchronously send a GetMetadata * message to the service and create a new proxy, if required. The new proxy * service is than announced asynchronously via * {@link ServiceListener#serviceCreated(ServiceReference, Service)} method. * <p> * Note that in order to reduce network traffic a GetMetadata message will * actually be sent only if it is detected that the service within this * device reference instance is not up to date anymore. */ public void buildUpService() { GetMetadataRequestSynchronizer sync; synchronized (this) { if (getMetadataSynchronizer != null) { return; } sync = getMetadataSynchronizer = new GetMetadataRequestSynchronizer(hostedBlockVersion); } buildUpService(sync); } private void buildUpService(final GetMetadataRequestSynchronizer newSynchronizer) { EprInfo xAddressInfo = null; synchronized (this) { if (getMetadataSynchronizer != newSynchronizer) { return; } xAddressInfo = preferredXAddressInfo; if (xAddressInfo != null) { synchronizers.put(sendGetMetadata(xAddressInfo).getMessageId(), newSynchronizer); return; } } // start new thread for resolving DPWSFramework.getThreadPool().execute(new Runnable() { public void run() { try { EprInfo xAddressInfo = (EprInfo) getPreferredXAddressInfo(); boolean callNotify = true; synchronized (DefaultServiceReference.this) { if (newSynchronizer == getMetadataSynchronizer) { synchronizers.put(sendGetMetadata(xAddressInfo).getMessageId(), newSynchronizer); callNotify = false; } } if (callNotify) { synchronized (newSynchronizer) { newSynchronizer.pending = false; newSynchronizer.notifyAll(); } } } catch (TimeoutException e) { Log.warn("Unablte to resolve remote service: " + e.getMessage()); } } }); } private Service waitForService(GetMetadataRequestSynchronizer sync) throws TimeoutException { while (true) { synchronized (sync) { int i = 0; while (sync.pending) { try { sync.wait(SYNC_WAITTIME); i++; if (i >= SYNC_WAITRETRY) { throw new TimeoutException("Service has not send an answer within " + (SYNC_WAITTIME * SYNC_WAITRETRY) + "ms."); } } catch (InterruptedException e) { Log.printStackTrace(e); } } if (sync.exception != null) { throw sync.exception; } else if (sync.service != null) { return sync.service; } /* * else { this means we had a concurrent update and someone was * started to obtain a newer device } */ } synchronized (this) { if (currentState == STATE_UP_TO_DATE) { return service; } else if (getMetadataSynchronizer != null) { sync = getMetadataSynchronizer; } else { throw new TimeoutException("Unknown communication error with service."); } } } } /** * */ GetMetadataMessage sendGetMetadata(EprInfo xAddress) { /* * must be called while we hold the lock on this service reference * instance */ GetMetadataMessage getMetadata = new GetMetadataMessage(xAddress.getComManId()); getMetadata.getHeader().setEndpointReference(xAddress.getEndpointReference()); getMetadata.setTargetXAddressInfo(xAddress); ProtocolInfo version = xAddress.getProtocolInfo(); if (version == null && parentDevRef != null) { version = parentDevRef.getPreferredXAddressInfo().getProtocolInfo(); } getMetadata.setProtocolInfo(version); ResponseCallback handler = ServiceReferenceFactory.getInstance().newResponseCallbackForServiceReference(this, xAddress); OutDispatcher.getInstance().send(getMetadata, xAddress, handler); return getMetadata; } private ResolveMessage sendResolve(EndpointReference eprToResolve) { /* * communication manager ID is null, because we must resolve that * endpoint reference and don't which communication manager will be * used. */ ResolveMessage resolve = new ResolveMessage(CommunicationManager.ID_NULL); // resolve.setProtocolVersionInfo(ProtocolVersionInfoRegistry.get(eprToResolve)); resolve.setEndpointReference(eprToResolve); ResponseCallback handler = ServiceReferenceFactory.getInstance().newResponseCallbackForServiceReference(this, null); OutDispatcher.getInstance().send(resolve, null, Discovery.getDefaultOutputDomains(), handler); return resolve; } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#setService(org.ws4d.java * .service.LocalService, org.ws4d.java.types.HostedMData) */ public synchronized Service setService(LocalService service, HostedMData hosted) { Service oldService = this.service; this.service = service; if (service != null) { this.hosted = hosted; if (location == LOCATION_UNKNOWN) { location = LOCATION_LOCAL; } eventAnnouncer.announceServiceCreated(this, service); } else { eventAnnouncer.announceServiceDisposed(this); } return oldService; } public Service rebuildService() throws TimeoutException { reset(); return getService(); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#reset() */ public synchronized void reset() { if (location == LOCATION_LOCAL) { Log.warn("DefaultServiceReference.reset: Not allowed to reset references to local services!"); return; } /* * add reset() method, which drops the old service proxy and other * metadata */ if (hosted != null) { // remove all service-related metadata but the EPRs hosted.setServiceId(null); hosted.setTypes(null); } hostedBlockVersion = 0; // xAddresses reset to initial state resolvedEprInfos = null; currentXAddressIndex = -1; unresolvedEPRs = null; currentState = STATE_NEEDS_UPDATE; parentDevRef = null; metadataReferences = null; metadataLocations = null; wsdls = null; preferredXAddressInfo = null; location = LOCATION_UNKNOWN; secure = false; DeviceServiceRegistry.addServiceReferenceToGarbageList(this); if (service != null) { service = null; eventAnnouncer.announceServiceDisposed(this); } } /** * Update service references with hosted metadata. If new metadata lacks of * previous transmitted port types, the associated service is removed. If * new metadata includes new port types, service is updated. * * @param endpoint Endpoint references to set. */ public void update(HostedMData newHostedBlock, DeviceReference devRef, ProtocolData protocolData) { synchronized (this) { if (newHostedBlock == hosted) { parentDevRef = devRef; return; } if (location == LOCATION_LOCAL) { Log.error("ServiceReferenceHandler.update: location is local"); return; } location = LOCATION_REMOTE; parentDevRef = devRef; DeviceServiceRegistry.updateServiceReferenceRegistration(newHostedBlock, this); } if (!newHostedBlock.getServiceId().equals(hosted.getServiceId())) { Log.info("ServiceReferenceHandler.update: Updating a service reference with a different service id: " + newHostedBlock.getServiceId()); } setHostedFromDevice(newHostedBlock, protocolData.getCommunicationManagerId(), protocolData); } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#disconnectFromDevice() */ public synchronized void disconnectFromDevice() { if (parentDevRef != null) { parentDevRef = null; DeviceServiceRegistry.addServiceReferenceToGarbageList(this); } } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getPortTypes() */ public synchronized Iterator getPortTypes() { QNameSet names = hosted.getTypes(); return names == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(names.iterator()); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getPortTypeCount() */ public synchronized int getPortTypeCount() { QNameSet names = hosted.getTypes(); return names == null ? 0 : names.size(); } /* * (non-Javadoc) * @see * org.ws4d.java.service.reference.ServiceReference#containsAllPortTypes * (org.ws4d.java.types.QNameSet) */ public synchronized boolean containsAllPortTypes(QNameSet newTypes) { if (newTypes == null || newTypes.size() == 0) { return true; } QNameSet ownPortTypes = hosted == null ? null : hosted.getTypes(); if (ownPortTypes == null) { return false; } if (newTypes.size() > ownPortTypes.size()) { return false; } return ownPortTypes.containsAll(newTypes); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.Reference#getLocation() */ public synchronized int getLocation() { return location; } /** * Location of service, which this reference is linked to. Allowed values: * <nl> * <li> {@link Reference#LOCATION_LOCAL}, * <li> {@link Reference#LOCATION_REMOTE} or * <li> {@link Reference#LOCATION_UNKNOWN} * </nl> * * @param location {@link Reference#LOCATION_LOCAL}, * {@link Reference#LOCATION_REMOTE} or * {@link Reference#LOCATION_UNKNOWN}. */ public synchronized void setLocation(int location) { this.location = location; } /* (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getEprInfos() */ public synchronized Iterator getEprInfos() { EprInfoSet eprs = hosted.getEprInfoSet(); return eprs == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(eprs.iterator()); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.ServiceReference#getServiceId() */ public synchronized URI getServiceId() { return hosted.getServiceId(); } /** * Returns an iterator over the set of {@link EndpointReference} instances * pointing at the locations of the target service's metadata descriptions * (i.e. usually its WSDL files). * * @return an iterator over {@link EndpointReference}s to the service's * metadata */ public synchronized Iterator getMetadataReferences() { return metadataReferences == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(metadataReferences); } /** * Returns an iterator over the set of {@link URI} instances pointing at the * addresses of the target service's metadata description locations (i.e. * usually its WSDL files). * * @return an iterator over {@link URI}s to the service's metadata */ public synchronized Iterator getMetadataLocations() { return metadataLocations == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(metadataLocations); } /** * Returns an iterator over the set of {@link WSDL} instances describing the * target service. * * @return an iterator over {@link WSDL}s containing the service's metadata */ public synchronized Iterator getWSDLs() { return wsdls == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(wsdls); } /* * (non-Javadoc) * @see org.ws4d.java.service.reference.Reference#getPreferredXAddress() */ public synchronized URI getPreferredXAddress() throws TimeoutException { return getPreferredXAddressInfo().getXAddress(); } /* * (non-Javadoc) * @see * org.ws4d.java.service.reference.Reference#getPreferredXAddressProtocol() */ public synchronized String getPreferredCommunicationManagerID() throws TimeoutException { return getPreferredXAddressInfo().getComManId(); } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#getPreferredXAddressInfo * () */ public XAddressInfo getPreferredXAddressInfo() throws TimeoutException { ResolveRequestSynchronizer sync; synchronized (this) { if (preferredXAddressInfo != null) { return preferredXAddressInfo; } if (resolvedEprInfos != null && currentXAddressIndex < resolvedEprInfos.size() - 1) { return preferredXAddressInfo = (EprInfo) resolvedEprInfos.get(++currentXAddressIndex); } sync = resolveSynchronizer; if (sync == null) { if (unresolvedEPRs == null || unresolvedEPRs.size() == 0) { if (hosted != null) { for (Iterator it = hosted.getEprInfoSet().iterator(); it.hasNext();) { EprInfo eprInfo = (EprInfo) it.next(); EndpointReference epr = eprInfo.getEndpointReference(); if (epr.getAddress().isURN() || eprInfo.getXAddress() == null) { if (unresolvedEPRs == null) { unresolvedEPRs = new LinkedList(); } unresolvedEPRs.add(epr); } } } currentXAddressIndex = -1; throw new TimeoutException("No more options to obtain transport address for service."); } sync = resolveSynchronizer = new ResolveRequestSynchronizer(hostedBlockVersion); synchronizers.put(sendResolve((EndpointReference) unresolvedEPRs.remove(0)).getMessageId(), sync); } } while (true) { synchronized (sync) { while (sync.pending) { try { sync.wait(); } catch (InterruptedException e) { Log.printStackTrace(e); } } if (sync.exception != null) { throw sync.exception; } else if (sync.xAddress != null) { return sync.xAddress; } /* * else { this means we had a concurrent update and someone was * started to obtain a newer address } */ } synchronized (this) { if (preferredXAddressInfo != null) { return preferredXAddressInfo; } else if (resolveSynchronizer != null) { sync = resolveSynchronizer; } else { break; } } } return getPreferredXAddressInfo(); } /* * (non-Javadoc) * @see org.ws4d.java.dispatch.ServiceReferenceInternal# * getNextXAddressInfoAfterFailure(org.ws4d.java.types.URI) */ public XAddressInfo getNextXAddressInfoAfterFailure(URI transportAddress) throws TimeoutException { synchronized (this) { if (preferredXAddressInfo != null) { URI address = preferredXAddressInfo.getXAddress(); if (transportAddress.equals(address)) { preferredXAddressInfo = null; } } } return getPreferredXAddressInfo(); } /** * @param devRef */ public synchronized void setParentDeviceReference(DeviceReference devRef) { this.parentDevRef = devRef; } public synchronized DeviceReference getParentDeviceRef() { return parentDevRef; } /* * (non-Javadoc) * @see * org.ws4d.java.service.reference.ServiceReference#isServiceObjectExisting * () */ public synchronized boolean isServiceObjectExisting() { return service != null; } public synchronized boolean isSecureService() { return secure; } /** * If this service uses security techniques this should be used to set the * state * * @param sec */ synchronized void setSecureService(boolean sec) { this.secure = sec; } /** * This method intentionally only creates new or updates existing port types * and never deletes obsolete ones. * * @throws MissingMetadataException */ void checkAndUpdateService(ProtocolData protocolData) throws MissingMetadataException { ProxyFactory pFac; try { pFac = DPWSFramework.getProxyFactory(); if (service == null) { // service gets filled from WSDL(s) referenced within msg Service newService = pFac.createProxyService(this, protocolData); service = newService; currentState = STATE_UP_TO_DATE; ServiceReferenceEventRegistry.getInstance().announceServiceCreated(this, newService); } else if (currentState == STATE_NEEDS_UPDATE) { // update existing service. QNameSet portTypes = hosted.getTypes(); if (portTypes != null) { currentState = STATE_UP_TO_DATE; if (pFac.checkServiceUpdate(service, portTypes)) { eventAnnouncer.announceServiceChanged(this, service); } } else { currentState = STATE_UP_TO_DATE; } } } catch (IOException e) { Log.error(e.getMessage()); } } private synchronized void setHostedFromDevice(HostedMData newHosted, String comManId, ProtocolData protocolData) { if (newHosted.isEqualTo(hosted)) { return; } checkPortTypeIncompatibilityAndUpdate(newHosted); hosted = newHosted; resetTransportAddresses(comManId, protocolData); } public synchronized void setHostedFromService(HostedMData newHosted, String comManId, ProtocolData protocolData) { if (newHosted.isEqualTo(hosted)) { return; } if (hosted == null) { hosted = newHosted; currentState = STATE_NEEDS_UPDATE; } else { if (checkPortTypeIncompatibilityAndUpdate(newHosted)) { hosted = newHosted; resetTransportAddresses(comManId, protocolData); } else { EprInfoSet oldEprs = hosted.getEprInfoSet(); hosted = newHosted; OUTER: for (Iterator it = newHosted.getEprInfoSet().iterator(); it.hasNext();) { EprInfo eprInfo = (EprInfo) it.next(); if (oldEprs.contains(eprInfo)) { continue; } EndpointReference epr = eprInfo.getEndpointReference(); URI address = epr.getAddress(); if (address.isURN() || eprInfo.getXAddress() == null) { if (unresolvedEPRs == null) { unresolvedEPRs = new LinkedList(); } if (!unresolvedEPRs.contains(epr)) { unresolvedEPRs.add(epr); } } else { if (resolvedEprInfos == null) { resolvedEprInfos = new ArrayList(); } for (Iterator it2 = resolvedEprInfos.iterator(); it2.hasNext();) { EprInfo oldInfo = (EprInfo) it2.next(); if (oldInfo.getXAddress().equals(address)) { continue OUTER; } } resolvedEprInfos.add(eprInfo); } } } } } /** * @param newHosted * @return <code>true</code> only if there are incompatible changes to the * service's port types, i.e. some previously existing port types * are gone now, <code>false</code> in any other case */ private boolean checkPortTypeIncompatibilityAndUpdate(HostedMData newHosted) { QNameSet newTypes = newHosted.getTypes(); if (hosted != null && ((hosted.getTypes() != null && newTypes == null) || (newTypes != null && !newTypes.containsAll(hosted.getTypes())))) { // CASE: some types are no more supported => discard service service = null; currentState = STATE_NEEDS_UPDATE; eventAnnouncer.announceServiceDisposed(this); return true; } else { QNameSet oldTypes = hosted == null ? null : hosted.getTypes(); int oldTypesCount = oldTypes == null ? 0 : oldTypes.size(); if (oldTypesCount < (newTypes == null ? 0 : newTypes.size())) { currentState = STATE_NEEDS_UPDATE; } return false; } } /** * @param comManId * @param protocolData */ private void resetTransportAddresses(String comManId, ProtocolData protocolData) { hostedBlockVersion++; currentXAddressIndex = -1; resolvedEprInfos = null; unresolvedEPRs = null; resolveSynchronizer = null; getMetadataSynchronizer = null; for (Iterator it = hosted.getEprInfoSet().iterator(); it.hasNext();) { EprInfo eprInfo = (EprInfo) it.next(); URI address = eprInfo.getEndpointReference().getAddress(); if (address.isURN() || eprInfo.getXAddress() == null) { if (unresolvedEPRs == null) { unresolvedEPRs = new LinkedList(); } unresolvedEPRs.add(eprInfo.getEndpointReference()); } else { if (resolvedEprInfos == null) { resolvedEprInfos = new ArrayList(); } if (protocolData != null && protocolData.sourceMatches(address)) { resolvedEprInfos.add(0, eprInfo); } else { // TODO: protocolData is null ... is it okay for us? :D resolvedEprInfos.add(eprInfo); } } } } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#setMetaDataLocations(org * .ws4d.java.types.URISet) */ public synchronized void setMetaDataLocations(URISet metaLocs) { if (metadataLocations == null) { metadataLocations = new HashSet(); } else { metadataLocations.clear(); } if (metaLocs != null) { for (Iterator it = metaLocs.iterator(); it.hasNext();) { URI location = (URI) it.next(); metadataLocations.add(location); } } } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#setMetadataReferences * (org.ws4d.java.types.EndpointReferenceSet) */ public synchronized void setMetadataReferences(EndpointReferenceSet metaRefs) { if (metadataReferences == null) { metadataReferences = new HashSet(); } else { metadataReferences.clear(); } if (metaRefs != null) { for (Iterator it = metaRefs.iterator(); it.hasNext();) { EndpointReference epr = (EndpointReference) it.next(); metadataReferences.add(epr); } } } /* * (non-Javadoc) * @see * org.ws4d.java.dispatch.ServiceReferenceInternal#setWSDLs(org.ws4d.java * .structures.DataStructure) */ public synchronized void setWSDLs(DataStructure wsdls) { if (this.wsdls == null) { this.wsdls = new HashSet(); } else { this.wsdls.clear(); } if (wsdls != null) { for (Iterator it = wsdls.iterator(); it.hasNext();) { WSDL wsdl = (WSDL) it.next(); this.wsdls.add(wsdl); } } } static class RequestSynchronizer { final int hostedBlockVersion; TimeoutException exception; volatile boolean pending = true; RequestSynchronizer(int hostedBlockVersion) { this.hostedBlockVersion = hostedBlockVersion; } } static class ResolveRequestSynchronizer extends RequestSynchronizer { EprInfo xAddress; ResolveRequestSynchronizer(int hostedBlockVersion) { super(hostedBlockVersion); } } static class GetMetadataRequestSynchronizer extends RequestSynchronizer { Service service; GetMetadataRequestSynchronizer(int hostedBlockVersion) { super(hostedBlockVersion); } } }