/******************************************************************************* * 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.CommunicationBinding; import org.ws4d.java.communication.CommunicationManager; import org.ws4d.java.communication.CommunicationManagerRegistry; import org.ws4d.java.communication.CommunicationUtil; import org.ws4d.java.communication.DefaultIncomingMessageListener; import org.ws4d.java.communication.ProtocolData; import org.ws4d.java.communication.TimeoutException; import org.ws4d.java.communication.protocol.http.HTTPGroup; import org.ws4d.java.communication.protocol.http.HTTPUser; import org.ws4d.java.configuration.ServiceProperties; import org.ws4d.java.configuration.ServicesPropertiesHandler; import org.ws4d.java.constants.ConstantsHelper; import org.ws4d.java.constants.DPWSMessageConstants; import org.ws4d.java.dispatch.DeviceServiceRegistry; 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.EventSource; import org.ws4d.java.eventing.EventingException; import org.ws4d.java.eventing.EventingFactory; import org.ws4d.java.eventing.SubscriptionManager; import org.ws4d.java.message.FaultMessage; import org.ws4d.java.message.InvokeMessage; import org.ws4d.java.message.SOAPException; 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.message.metadata.GetMetadataMessage; import org.ws4d.java.message.metadata.GetMetadataResponseMessage; import org.ws4d.java.schema.Element; import org.ws4d.java.schema.Schema; 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.ArrayList; import org.ws4d.java.structures.DataStructure; import org.ws4d.java.structures.EmptyStructures; import org.ws4d.java.structures.HashMap; import org.ws4d.java.structures.HashMap.Entry; import org.ws4d.java.structures.HashSet; import org.ws4d.java.structures.Iterator; import org.ws4d.java.structures.ReadOnlyIterator; import org.ws4d.java.structures.Set; import org.ws4d.java.types.EndpointReference; import org.ws4d.java.types.EprInfo; import org.ws4d.java.types.EprInfoSet; import org.ws4d.java.types.HostMData; import org.ws4d.java.types.HostedMData; import org.ws4d.java.types.QName; import org.ws4d.java.types.QNameSet; import org.ws4d.java.types.RelationshipMData; import org.ws4d.java.types.URI; import org.ws4d.java.types.URISet; import org.ws4d.java.util.Log; import org.ws4d.java.util.StringUtil; import org.ws4d.java.util.WS4DIllegalStateException; import org.ws4d.java.wsdl.IOType; import org.ws4d.java.wsdl.UnsupportedBindingException; import org.ws4d.java.wsdl.WSDL; import org.ws4d.java.wsdl.WSDLBinding; import org.ws4d.java.wsdl.WSDLMessage; import org.ws4d.java.wsdl.WSDLMessagePart; import org.ws4d.java.wsdl.WSDLOperation; import org.ws4d.java.wsdl.WSDLPortType; import org.ws4d.java.wsdl.WSDLRepository; import org.ws4d.java.wsdl.WSDLService; import org.ws4d.java.wsdl.soap12.SOAP12DocumentLiteralHTTPBinding; import org.ws4d.java.wsdl.soap12.SOAP12DocumentLiteralHTTPPort; /** * Default implementation of a DPWS service. * <p> * This class should be used to create a DPWS service. A new service should * extend the <code>DefaultService</code> class and add operations to the newly * created service. It is also possible to use the default implementation. * </p> * * <pre> * * * * * * * * * public class SampleService extends DefaultService { * * public SampleService() { * // create operations here, add them to the service * } * } * </pre> */ public class DefaultService extends ServiceCommons implements LocalService { protected static final int[] SERVICE_MESSAGE_TYPES = { DPWSMessageConstants.GET_METADATA_MESSAGE, DPWSMessageConstants.INVOKE_MESSAGE }; protected static final int[] EVENTED_SERVICE_MESSAGE_TYPES = { DPWSMessageConstants.GET_METADATA_MESSAGE, DPWSMessageConstants.SUBSCRIBE_MESSAGE, DPWSMessageConstants.GET_STATUS_MESSAGE, DPWSMessageConstants.RENEW_MESSAGE, DPWSMessageConstants.UNSUBSCRIBE_MESSAGE, DPWSMessageConstants.INVOKE_MESSAGE }; protected static final byte SERVICE_STATE_UNREGISTERED = 1; protected static final byte SERVICE_STATE_REGISTERED = 2; protected static final byte SERVICE_STATE_RUNNING = 3; // ADDED 2010-08-11 SSch Added string constants and set most of them to // empty strings // "Message" protected static final String IN_MSG_POSTFIX = "Message"; // "Message" Response protected static final String OUT_MSG_POSTFIX = "Message"; // "Message" Response protected static final String FAULT_MSG_POSTFIX = "Message"; protected static final String BINDING_POSTFIX = "Binding"; /** Configuration identifier */ protected int configurationId; protected ServiceMessageListener incomingListener = new ServiceMessageListener(); protected final HostedMData hosted = new HostedMData(); protected ServiceReference serviceReference = null; protected LocalDevice parentDevice = null; protected final ServiceProperties serviceProp; // key = CommunicationBinding, value = HashSet of URIs protected final HashMap wsdlURIs = new HashMap(); // key = CommunicationBinding, value = HashSet of URIs protected final HashMap resourceURIs = new HashMap(); protected byte state = SERVICE_STATE_UNREGISTERED; protected SubscriptionManager subscriptionManager = null; protected final DataStructure bindings; protected String sid = null; /** Authentication */ private HTTPGroup userGroup = null; private static ResourcePath createResourcePath(String namespace, String resourceSuffix) { URI nsUri = new URI(namespace); String host = nsUri.getHost(); String path = nsUri.getPath(); if (nsUri.isURN()) { path = path.replace(':', '_'); } String nsPath = (host == null ? "" : host) + path + ((path.charAt(path.length() - 1) == '/' ? "" : "/") + resourceSuffix); int depth = 0; int idx = nsPath.indexOf('/'); while (idx != -1) { if (idx != 0) { depth++; } idx = nsPath.indexOf('/', idx + 1); } return new ResourcePath(nsPath, depth); } /** * Default DPWS service. * <p> * No configuration identifier used. No configuration will be loaded for * this service. * </p> */ public DefaultService() { this(-1); } /** * Default DPWS service with given configuration identifier. * <p> * Creates an default DPWS service and tries to load the configuration * properties for the service. * </p> * * @param configurationId configuration identifier. */ public DefaultService(int configurationId) { super(); hosted.setTypes(QNameSet.newInstanceReadOnly(portTypes.keySet())); this.configurationId = configurationId; if (this.configurationId != -1) { Integer cid = new Integer(configurationId); serviceProp = ServicesPropertiesHandler.getInstance().getServiceProperties(cid); if (serviceProp == null) { Log.error("DefaultService(configurationId): No service properties for configuration id " + configurationId); bindings = new ArrayList(2); } else { URI sid = serviceProp.getServiceId(); if (sid != null) { setServiceId(sid); } bindings = serviceProp.getBindings(); // if (bindings.size() > 0) { // for (Iterator it = bindings.iterator(); it.hasNext();) { // CommunicationBinding binding = (CommunicationBinding) // it.next(); // EndpointReference epr = new // EndpointReference(binding.getTransportAddress()); // hosted.addEndpointReference(epr); // } // } } } else { serviceProp = null; bindings = new ArrayList(2); } if (serviceProp != null && serviceProp.isServiceSecured() && DPWSFramework.hasModule(DPWSFramework.SECURITY_MODULE)) { try { this.setSecureService(); } catch (Exception e) { e.printStackTrace(); } } sid = StringUtil.simpleClassName(getClass()); } /* * (non-Javadoc) * @see org.ws4d.java.service.LocalService#start() */ public synchronized void start() throws IOException { if (!DPWSFramework.isRunning()) { throw new RuntimeException("DPWSFramework not running, please start it in advance!"); } if (Log.isDebug()) { Log.info("### Start Service: " + sid); } if (isRunning()) { Log.warn("Service already running, nothing to start"); return; } if (state == SERVICE_STATE_UNREGISTERED) { if (hosted.getServiceId() == null) { hosted.setServiceId(new URI(sid)); } int[] messageTypes = SERVICE_MESSAGE_TYPES; for (Iterator it = portTypes.values().iterator(); it.hasNext();) { PortType portType = (PortType) it.next(); portType.plomb(); if (portType.hasEventSources()) { messageTypes = EVENTED_SERVICE_MESSAGE_TYPES; } } if (!hasBindings()) { String descriptor = StringUtil.simpleClassName(getClass()); if (Log.isDebug()) { Log.info("No bindings found for Service. Autobinding service " + descriptor); } DataStructure autoBindings = new HashSet(); for (Iterator it = CommunicationManagerRegistry.getLoadedManagers(); it.hasNext();) { CommunicationManager manager = (CommunicationManager) it.next(); manager.getAutobindings(descriptor, autoBindings); } for (Iterator it = autoBindings.iterator(); it.hasNext();) { CommunicationBinding binding = (CommunicationBinding) it.next(); addBinding(binding); } } for (Iterator it = getBindings(); it.hasNext();) { CommunicationBinding binding = (CommunicationBinding) it.next(); CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); manager.registerService(messageTypes, binding, incomingListener, userGroup); EndpointReference eRef = new EndpointReference(binding.getTransportAddress()); hosted.addEprInfo(new EprInfo(eRef, binding.getCommunicationManagerId())); } if (this.secure) { URI addr = ((EndpointReference) this.getEprInfos().next()).getAddress(); String alias = addr.getHost() + ":" + addr.getPort() + addr.getPath(); if ((this.certificate = DPWSFramework.getSecurityManager().getCertificate(alias)) == null) { throw new IOException("Security credentials not found"); } this.privateKey = DPWSFramework.getSecurityManager().getPrivateKey(alias, null); this.secure = true; } DeviceServiceRegistry.register(this); deployMetadataResources(); state = SERVICE_STATE_REGISTERED; } if (Log.isInfo()) { Iterator it = hosted.getEprInfoSet().iterator(); StringBuffer sBuf = new StringBuffer(); while (it.hasNext()) { EprInfo epr = (EprInfo) it.next(); sBuf.append(epr.getEndpointReference().getAddress()); if (it.hasNext()) { sBuf.append(", "); } } Log.info("Service [ " + sBuf + " ] online."); } state = SERVICE_STATE_RUNNING; } /* * (non-Javadoc) * @see org.ws4d.java.service.LocalService#stop() */ public synchronized void stop() throws IOException { if (state == SERVICE_STATE_UNREGISTERED) { return; } if (subscriptionManager != null) { subscriptionManager.sendSubscriptionEnd(); } undeployMetadataResources(); int[] messageTypes = SERVICE_MESSAGE_TYPES; for (Iterator it = portTypes.values().iterator(); it.hasNext();) { PortType portType = (PortType) it.next(); if (portType.hasEventSources()) { messageTypes = EVENTED_SERVICE_MESSAGE_TYPES; break; } } DeviceServiceRegistry.unregister(this); for (Iterator it = bindings.iterator(); it.hasNext();) { CommunicationBinding binding = (CommunicationBinding) it.next(); EndpointReference eRef = new EndpointReference(binding.getTransportAddress()); hosted.getEprInfoSet().remove(new EprInfo(eRef, null, binding.getCommunicationManagerId())); CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); manager.unregisterService(messageTypes, binding, incomingListener); } state = SERVICE_STATE_UNREGISTERED; } /* * (non-Javadoc) * @see org.ws4d.java.service.LocalService#pause() */ public synchronized void pause() { state = SERVICE_STATE_REGISTERED; } /* * (non-Javadoc) * @see org.ws4d.java.service.LocalService#isRunning() */ public synchronized boolean isRunning() { return state == SERVICE_STATE_RUNNING; } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getServiceReference() */ public ServiceReference getServiceReference() { if (serviceReference == null) { serviceReference = DeviceServiceRegistry.getUpdatedServiceReference(hosted, getParentDeviceReference(), CommunicationManagerRegistry.getDefault(), null); ((ServiceReferenceInternal) serviceReference).setService(this, hosted); } return serviceReference; } /* * (non-Javadoc) * @see org.ws4d.java.communication.Bindable#hasBindings() */ public boolean hasBindings() { return (bindings.size() > 0); } /* * (non-Javadoc) * @see org.ws4d.java.communication.Bindable#getBindings() */ public Iterator getBindings() { return new ReadOnlyIterator(bindings); } /* * (non-Javadoc) * @see org.ws4d.java.communication.Bindable#supportsBindingChanges() */ public synchronized boolean supportsBindingChanges() { return state == SERVICE_STATE_UNREGISTERED; } /* * (non-Javadoc) * @see * org.ws4d.java.communication.Bindable#addBinding(org.ws4d.java.communication * .CommunicationBinding) */ public void addBinding(CommunicationBinding binding) throws WS4DIllegalStateException { exclusiveLock(); try { bindings.add(binding); // if (bindings.add(binding)) { // EndpointReference epr = new // EndpointReference(binding.getTransportAddress()); // hosted.addEndpointReference(epr); // } } finally { releaseExclusiveLock(); } } /* * (non-Javadoc) * @seeorg.ws4d.java.communication.Bindable#removeBinding(org.ws4d.java. * communication.CommunicationBinding) */ public boolean removeBinding(CommunicationBinding binding) throws WS4DIllegalStateException { exclusiveLock(); try { return bindings.remove(binding); // if (result) { // EndpointReference epr = new // EndpointReference(binding.getTransportAddress()); // hosted.getEndpointReferences().remove(epr); // wsdlURIs.remove(binding); // resourceURIs.remove(binding); // } // return result; } finally { releaseExclusiveLock(); } } /* * (non-Javadoc) * @see org.ws4d.java.communication.Bindable#clearBindings() */ public void clearBindings() throws WS4DIllegalStateException { exclusiveLock(); try { // for (Iterator it = bindings.iterator(); it.hasNext();) { // CommunicationBinding binding = (CommunicationBinding) it.next(); // EndpointReference epr = new // EndpointReference(binding.getTransportAddress()); // hosted.getEndpointReferences().remove(epr); // it.remove(); // wsdlURIs.remove(binding); // resourceURIs.remove(binding); // } bindings.clear(); } finally { releaseExclusiveLock(); } } /** * Creates a shared lock for this service. If the service has a parent * device, the lock is acquired from the device. */ protected void sharedLock() { if (parentDevice == null) { return; } parentDevice.sharedLock(); } /** * Creates a exclusive lock for this service. If the service has a parent * device, the lock is acquired from the device. */ protected void exclusiveLock() { if (state != SERVICE_STATE_UNREGISTERED) { throw new RuntimeException("Service must not be changed while running!"); } if (parentDevice == null) { return; } parentDevice.exclusiveLock(); } /** * Releases a shared lock for this service. If the service has a parent * device, the lock is released from the device. */ protected void releaseSharedLock() { if (parentDevice == null) { return; } parentDevice.releaseSharedLock(); } /** * Releases a exclusive lock for this service. If the service has a parent * device, the lock is released from the device. */ protected void releaseExclusiveLock() { if (state != SERVICE_STATE_UNREGISTERED) { throw new RuntimeException("Service must not be changed while running!"); } if (parentDevice == null) { return; } parentDevice.releaseExclusiveLock(); } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#isRemote() */ public boolean isRemote() { return true; } /* * (non-Javadoc) * @see org.ws4d.java.service.ServiceCommons#getServiceId() */ public URI getServiceId() { sharedLock(); try { URI serviceId = hosted.getServiceId(); if (serviceId == null) { serviceId = new URI(sid); exclusiveLock(); try { hosted.setServiceId(serviceId); } finally { releaseExclusiveLock(); } } return serviceId; } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getOperations() */ public Iterator getOperations() { sharedLock(); try { return super.getOperations(); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.Service#getOperations(org.ws4d.java.types.QName) */ public Iterator getOperations(QName portType) { sharedLock(); try { return super.getOperations(portType); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getOperation(org.ws4d.java.types. * QName, java.lang.String, java.lang.String, java.lang.String) */ public Operation getOperation(QName portType, String opName, String inputName, String outputName) { if (opName == null) { return null; } sharedLock(); try { return super.getOperation(portType, opName, inputName, outputName); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getOperation(java.lang.String) */ public Operation getOperation(String inputAction) { if (inputAction == null) { return null; } sharedLock(); try { return super.getOperation(inputAction); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getAnyOperation(org.ws4d.java.types * .QName, java.lang.String) */ public Operation getAnyOperation(QName portType, String operationName) { if (operationName == null) { return null; } sharedLock(); try { return super.getAnyOperation(portType, operationName); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see org.ws4d.java.service.ServiceCommons#getEventSources() */ public Iterator getEventSources() { sharedLock(); try { return super.getEventSources(); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getEventSources(org.ws4d.java.types * .QName) */ public Iterator getEventSources(QName portType) { sharedLock(); try { return super.getEventSources(portType); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getEventSource(org.ws4d.java.types * .QName, java.lang.String, java.lang.String, java.lang.String) */ public EventSource getEventSource(QName portType, String eventName, String inputName, String outputName) { if (eventName == null) { return null; } sharedLock(); try { return super.getEventSource(portType, eventName, inputName, outputName); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getEventSource(java.lang.String) */ public EventSource getEventSource(String outputAction) { if (outputAction == null) { return null; } sharedLock(); try { return super.getEventSource(outputAction); } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#getAnyEventSource(org.ws4d.java. * data.QName, java.lang.String) */ public EventSource getAnyEventSource(QName portType, String eventName) { if (eventName == null) { return null; } sharedLock(); try { return super.getAnyEventSource(portType, eventName); } finally { releaseSharedLock(); } } /** * Sets the service identifier for this service. * <p> * The service identifier identifies the service uniquely for the parent * device. * * @param serviceId the service identifier to set. */ public void setServiceId(URI serviceId) { exclusiveLock(); try { hosted.setServiceId(serviceId); } finally { releaseExclusiveLock(); } } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getPortTypes() */ public Iterator getPortTypes() { QNameSet s = hosted.getTypes(); return s == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(s.iterator()); } /* * (non-Javadoc) * @see * org.ws4d.java.service.LocalService#addPortType(org.ws4d.java.types.QName) */ public void addPortType(QName portTypeName) { if (portTypes.containsKey(portTypeName)) { return; } // null values not aloud within portTyps map! portTypes.put(portTypeName, new PortType()); } /* (non-Javadoc) * @see org.ws4d.java.service.Service#getEprInfos() */ public Iterator getEprInfos() { EprInfoSet s = hosted.getEprInfoSet(); return s == null ? EmptyStructures.EMPTY_ITERATOR : new ReadOnlyIterator(s.iterator()); } /* * (non-Javadoc) * @see * org.ws4d.java.service.LocalService#addOperation(org.ws4d.java.service * .Operation) */ public void addOperation(Operation operation) { // Check for necessary stuff. if (operation == null) { throw new NullPointerException("operation is null"); } exclusiveLock(); try { QName portType = operation.getPortType(); OperationSignature signature = new OperationSignature(operation); // Add operation to port type table. PortType type = (PortType) portTypes.get(portType); if (type == null) { type = new PortType(); portTypes.put(portType, type); } else { if (type.isPlombed()) { throw new WS4DIllegalStateException("Operations can not be added to an existing port type after a service has been started once"); } String inputName = operation.getInputName(); String outputName = operation.getOutputName(); int inputCounter = 1; int outputCounter = 1; while (type.contains(signature)) { if (operation.isInputNameSet()) { if (operation.isOneWay() || operation.isOutputNameSet()) { throw new IllegalArgumentException("duplicate operation or event: " + operation); } else { operation.setOutputNameInternal(outputName + outputCounter++); } } else { operation.setInputNameInternal(inputName + inputCounter++); } signature = new OperationSignature(operation); } } // check for duplicate input action String inputAction = operation.getInputAction(); if (operations.containsKey(inputAction)) { if (operation.isInputActionSet() || operation.isOneWay()) { throw new IllegalArgumentException("duplicate input action: " + inputAction); } inputAction = operation.setExtendedDefaultInputAction(); if (operations.containsKey(inputAction)) { throw new IllegalArgumentException("duplicate input action: " + inputAction); } } type.addOperation(signature, operation); // add operation with wsa:Action of input for faster access operations.put(operation.getInputAction(), operation); operation.setService(this); if (Log.isDebug()) { Log.debug("[NEW OPERATION]: " + operation.toString(), Log.DEBUG_LAYER_APPLICATION); } } finally { releaseExclusiveLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.LocalService#addEventSource(org.ws4d.java.service * .DefaultEventSource) */ public void addEventSource(EventSource event) { if (event == null) { throw new RuntimeException("Cannot add event to service. No event given."); } if (!(event instanceof OperationCommons)) { throw new RuntimeException("Cannot add event to service. Given event MUST extend the operation class."); } EventingFactory eFac = null; try { eFac = DPWSFramework.getEventingFactory(); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } exclusiveLock(); try { QName portType = event.getPortType(); OperationSignature signature = new OperationSignature(event); // add event to port type table PortType type = (PortType) portTypes.get(portType); if (type == null) { type = new PortType(); portTypes.put(portType, type); } else { if (type.isPlombed()) { throw new WS4DIllegalStateException("Events can not be added to an existing port type after a service has been started once"); } String outputName = event.getOutputName(); String inputName = event.getInputName(); int outputCounter = 1; int inputCounter = 1; while (type.contains(signature)) { if (((OperationCommons) event).isOutputNameSet()) { if (event.isNotification() || ((OperationCommons) event).isInputNameSet()) { throw new IllegalArgumentException("duplicate operation or event: " + event); } else { ((OperationCommons) event).setInputNameInternal(inputName + inputCounter++); } } else { ((OperationCommons) event).setOutputNameInternal(outputName + outputCounter++); } signature = new OperationSignature(event); } } // check for duplicate output action String outputAction = event.getOutputAction(); if (events.containsKey(outputAction)) { if (((OperationCommons) event).isOutputActionSet() || event.isNotification()) { throw new IllegalArgumentException("duplicate output action: " + outputAction); } outputAction = ((OperationCommons) event).setExtendedDefaultOutputAction(); if (events.containsKey(outputAction)) { throw new IllegalArgumentException("duplicate output action: " + outputAction); } } type.addEventSource(signature, event); // add event with wsa:Action of output for faster access events.put(event.getOutputAction(), event); if (subscriptionManager == null) { subscriptionManager = eFac.getSubscriptionManager(this); } ((OperationCommons) event).setService(this); if (Log.isDebug()) { Log.debug("[NEW EVENT SOURCE]: " + event.toString(), Log.DEBUG_LAYER_APPLICATION); } } finally { releaseExclusiveLock(); } } /** * Gets configuration identifier. * <p> * The configuration identifier is necessary to resolve properties based * configuration. * </p> * * @return the configuration identifier. */ public int getConfigurationID() { return configurationId; } /** * Sets the parent device for this service. * <p> * Every service is assigned to one device. * </p> * * @param devicet the device which the service should be assigned to. */ public void setParentDevice(LocalDevice device) { parentDevice = device; } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getParentDeviceReference() */ public DeviceReference getParentDeviceReference() { if (parentDevice == null) { return null; } return parentDevice.getDeviceReference(); } /** * Registers all WSDL and XML Schema files to the internal resource server * (e.g. HTTP). */ protected void deployMetadataResources() { try { String resourcesBasePath = "ws4d/resources/"; /* * get target namespaces for this service. */ Set targetNamespaces = new HashSet(portTypes.size() * 2); HashMap copy = new HashMap(); for (Iterator it = portTypes.keySet().iterator(); it.hasNext();) { QName key = (QName) it.next(); String targetNamespace = key.getNamespace(); if (targetNamespace.equals("")) { QName renew = new QName(key.getLocalPart(), this.parentDevice.getDefaultNamespace(), key.getPrefix(), key.getPriority()); PortType p = (PortType) portTypes.get(key); copy.put(renew, p); // portTypes.remove(key); for (Iterator i = p.getOperations(); i.hasNext();) { Operation o = (Operation) i.next(); // for input Element inputElement = o.getInput(); if (inputElement != null && inputElement.getName() != null) { QName pre = inputElement.getName(); if (pre.getNamespace().equals("")) { QName post = new QName(pre.getLocalPart(), this.parentDevice.getDefaultNamespace(), pre.getPrefix(), pre.getPriority()); o.getInput().setName(post); } } // for output Element outputElement = o.getOutput(); if (outputElement != null && outputElement.getName() != null) { QName pre = outputElement.getName(); if (pre.getNamespace().equals("")) { QName post = new QName(pre.getLocalPart(), this.parentDevice.getDefaultNamespace(), pre.getPrefix(), pre.getPriority()); outputElement.setName(post); } } } } else { PortType p = (PortType) portTypes.get(key); copy.put(key, p); } targetNamespaces.add(targetNamespace); } portTypes.clear(); portTypes.putAll(copy); /* * register at HTTP server. */ Iterator targets = targetNamespaces.iterator(); while (targets.hasNext()) { String targetNamespace = (String) targets.next(); if (targetNamespace.equals("")) { targetNamespace = this.parentDevice.getDefaultNamespace(); } WSDL wsdl = getDescription(targetNamespace); if (!wsdls.containsKey(targetNamespace)) { /* * this is an embedded, i.e. linked-in WSDL, we shouldn't * export it as top-level */ continue; } ResourcePath wsdlPath = createResourcePath(targetNamespace, "description.wsdl"); Iterator bit = bindings.iterator(); while (bit.hasNext()) { CommunicationBinding binding = (CommunicationBinding) bit.next(); CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); // TODO: Group user URI uri = manager.registerResource(wsdl, binding, resourcesBasePath + wsdlPath.path, null); Set uris = (Set) wsdlURIs.get(binding); if (uris == null) { uris = new HashSet(); wsdlURIs.put(binding, uris); } uris.add(uri); uris = (Set) resourceURIs.get(binding); if (uris == null) { uris = new HashSet(); resourceURIs.put(binding, uris); } uris.add(uri); if (Log.isDebug()) { Log.debug("Service [ WSDL = " + uri + " ]", Log.DEBUG_LAYER_APPLICATION); } recurseLinkedWsdls(wsdl, binding, resourcesBasePath, wsdlPath.depth); for (Iterator it = wsdl.getTypes(); it.hasNext();) { Schema schema = (Schema) it.next(); recurseLinkedSchemas(schema, binding, resourcesBasePath, wsdlPath.depth); } } } } catch (IOException e) { Log.warn("No HTTP Server found. Cannot register WSDL for download."); } } private void recurseLinkedWsdls(WSDL wsdl, CommunicationBinding binding, String resourcesBasePath, int depth) throws IOException { for (Iterator it = wsdl.getLinkedWsdls(); it.hasNext();) { WSDL linkedWsdl = (WSDL) it.next(); String targetNamespace = linkedWsdl.getTargetNamespace(); ResourcePath wsdlPath = createResourcePath(targetNamespace, "description.wsdl"); String location = wsdlPath.path; for (int i = 0; i < depth; i++) { location = "../" + location; } wsdl.addImport(targetNamespace, location); CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); // TODO: Group user URI uri = manager.registerResource(linkedWsdl, binding, resourcesBasePath + wsdlPath.path, null); Set uris = (Set) resourceURIs.get(binding); if (uris == null) { uris = new HashSet(); resourceURIs.put(binding, uris); } uris.add(uri); if (Log.isDebug()) { Log.debug("Service [ WSDL = " + uri + " ]", Log.DEBUG_LAYER_APPLICATION); } recurseLinkedWsdls(linkedWsdl, binding, resourcesBasePath, wsdlPath.depth); } } protected void recurseLinkedSchemas(Schema schema, CommunicationBinding binding, String resourcesBasePath, int depth) throws IOException { DataStructure deployedNamespaces = new HashSet(); recurseLinkedSchemas(schema, binding, resourcesBasePath, depth, deployedNamespaces); } protected void recurseLinkedSchemas(Schema schema, CommunicationBinding binding, String resourcesBasePath, int depth, DataStructure deployedNamespaces) throws IOException { for (Iterator it = schema.getLinkedSchemas(); it.hasNext();) { Schema linkedSchema = (Schema) it.next(); String targetNamespace = linkedSchema.getTargetNamespace(); ResourcePath schemaPath = createResourcePath(targetNamespace, "schema.xsd"); String location = schemaPath.path; for (int i = 0; i < depth; i++) { location = "../" + location; } schema.addImport(targetNamespace, location); if (deployedNamespaces.contains(targetNamespace)) { continue; } CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); // TODO: Group user URI uri = manager.registerResource(linkedSchema, binding, resourcesBasePath + schemaPath.path, null); deployedNamespaces.add(targetNamespace); Set uris = (Set) resourceURIs.get(binding); if (uris == null) { uris = new HashSet(); resourceURIs.put(binding, uris); } uris.add(uri); if (Log.isDebug()) { Log.debug("Service [ Schema = " + uri + " ]", Log.DEBUG_LAYER_APPLICATION); } recurseLinkedSchemas(linkedSchema, binding, resourcesBasePath, schemaPath.depth, deployedNamespaces); } } protected void undeployMetadataResources() { for (Iterator it = bindings.iterator(); it.hasNext();) { CommunicationBinding binding = (CommunicationBinding) it.next(); wsdlURIs.remove(binding); Set uris = (HashSet) resourceURIs.remove(binding); if (uris != null) { for (Iterator it2 = uris.iterator(); it2.hasNext();) { URI uri = (URI) it2.next(); try { CommunicationManager manager = CommunicationManagerRegistry.getManager(binding.getCommunicationManagerId()); manager.unregisterResource(uri, binding); } catch (IOException e) { Log.printStackTrace(e); } } } } } /** * Returns the namespaces based on the port types for this service. * * @return the namespaces based on the port types for this service. */ public Iterator getTargetNamespaces() { Set ts = new HashSet(); for (Iterator it = portTypes.keySet().iterator(); it.hasNext();) { QName key = (QName) it.next(); ts.add(key.getNamespace()); } return new ReadOnlyIterator(ts); } /* * (non-Javadoc) * @see org.ws4d.java.service.LocalService#getDescriptionsForPortTypes() */ public Iterator getDescriptionsForPortTypes() { Iterator targetNamespaces = getTargetNamespaces(); Set wsdls = new HashSet(); while (targetNamespaces.hasNext()) { String namespace = (String) targetNamespaces.next(); wsdls.add(getDescription(namespace)); } return new ReadOnlyIterator(wsdls); } /** * Returns a WSDL document describing this service by the given namespace. * * @param targetNamespace the namespace. * @return the WSDL document describing this service by the given namespace. */ public WSDL getDescription(String targetNamespace) { WSDL wsdl = getExistingDescription(targetNamespace); if (wsdl != null) { addServiceAndPortsIfMissing(wsdl); return wsdl; } /* * we have a WSDL instance for each distinct namespace within our * service types */ wsdl = new WSDL(targetNamespace); // wsdl.addTypes(SchemaUtil.createSchema(this)); // CHANGED 2010-08-11 SSch There may be a set of schemas not only one HashMap schemaList = SchemaUtil.createSchema(this, targetNamespace); Iterator schemasIt = schemaList.entrySet().iterator(); while (schemasIt.hasNext()) { Entry entry = (Entry) schemasIt.next(); wsdl.addTypes((Schema) entry.getValue()); } /* * Time to create the WSDL document for this service. No change allowed * if the service is running. */ Set ptypes = portTypes.entrySet(); Iterator ptit = ptypes.iterator(); while (ptit.hasNext()) { Entry entry = (Entry) ptit.next(); QName portTypeName = (QName) entry.getKey(); String namespace = portTypeName.getNamespace(); if (!targetNamespace.equals(namespace)) { // skip port types from other target namespaces continue; } PortType type = (PortType) entry.getValue(); WSDLPortType portType = new WSDLPortType(portTypeName); if (type.hasAttributes()) { portType.setAttributes(type.getAttributes()); } Iterator opit = type.getOperations(); while (opit.hasNext()) { /* * Get the next operation. */ Operation operation = (Operation) opit.next(); /* * Create a WSDL operation and add it to the actual port type. */ String operationName = operation.getName(); WSDLOperation wsdlOperation = new WSDLOperation(operationName); if (operation.hasAttributes()) { wsdlOperation.setAttributes(operation.getAttributes()); } /* * Create the input/output message names. */ String inputName = operation.getInputName(); QName inMsgName = new QName(inputName + IN_MSG_POSTFIX, namespace); IOType inputIO = new IOType(inMsgName); if (operation.hasInputAttributes()) { inputIO.setAttributes(operation.getInputAttributes()); } // check whether auto-generated or set if (operation.isInputNameSet()) { inputIO.setName(inputName); } if (operation.isInputActionSet() || operation.isInputActionExtended()) { inputIO.setAction(operation.getInputAction()); } WSDLMessage wsdlMessageInput = new WSDLMessage(inMsgName); Element input = operation.getInput(); if (input != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(input.getName()); wsdlMessageInput.addPart(part); } /* * in case there are no input parameters, we add an empty * message (with no parts) to WSDL operation */ wsdl.addMessage(wsdlMessageInput); wsdlOperation.setInput(inputIO); if (operation.isRequestResponse()) { String outputName = operation.getOutputName(); QName outMsgName = new QName(outputName + OUT_MSG_POSTFIX, namespace); IOType outputIO = new IOType(outMsgName); if (operation.hasOutputAttributes()) { outputIO.setAttributes(operation.getOutputAttributes()); } // check whether auto-generated or set if (operation.isOutputNameSet()) { outputIO.setName(outputName); } if (operation.isOutputActionSet()) { outputIO.setAction(operation.getOutputAction()); } /* * we always include an output message for real operations, * although their output element may be null */ WSDLMessage wsdlMessageOutput = new WSDLMessage(outMsgName); Element output = operation.getOutput(); if (output != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(output.getName()); wsdlMessageOutput.addPart(part); } wsdl.addMessage(wsdlMessageOutput); wsdlOperation.setOutput(outputIO); } // add fault IOTypes and action URIs for (Iterator it = operation.getFaults(); it.hasNext();) { Fault fault = (Fault) it.next(); String faultName = fault.getName(); QName faultMsgName = new QName(operationName + faultName + FAULT_MSG_POSTFIX, namespace); IOType faultIO = new IOType(faultMsgName); if (fault.hasAttributes()) { faultIO.setAttributes(fault.getAttributes()); } // check whether auto-generated or set faultIO.setName(faultName); String action = fault.getAction(); if (action != null) { faultIO.setAction(action); } WSDLMessage wsdlMessageFault = new WSDLMessage(faultMsgName); Element faultElement = fault.getElement(); if (faultElement != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(faultElement.getName()); wsdlMessageFault.addPart(part); } wsdl.addMessage(wsdlMessageFault); wsdlOperation.addFault(faultIO); } portType.addOperation(wsdlOperation); } Iterator evit = type.getEventSources(); while (evit.hasNext()) { /* * Get the next event. */ OperationCommons event = (OperationCommons) evit.next(); /* * Create a WSDL operation and add it to the actual port type. */ String eventName = event.getName(); portType.setEventSource(true); WSDLOperation wsdlOperation = new WSDLOperation(eventName); if (event.hasAttributes()) { wsdlOperation.setAttributes(event.getAttributes()); } /* * Create the input/output message names. */ String outputName = event.getOutputName(); QName outMsgName = new QName(outputName + OUT_MSG_POSTFIX, namespace); IOType outputIO = new IOType(outMsgName); if (event.hasOutputAttributes()) { outputIO.setAttributes(event.getOutputAttributes()); } // check whether auto-generated or set if (event.isOutputNameSet()) { outputIO.setName(outputName); } if (event.isOutputActionSet() || event.isOutputActionExtended()) { outputIO.setAction(event.getOutputAction()); } WSDLMessage wsdlMessageOutput = new WSDLMessage(outMsgName); Element output = event.getOutput(); if (output != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(output.getName()); wsdlMessageOutput.addPart(part); } /* * in case there are no output parameters, we add an empty * message (with no parts) to WSDL operation */ wsdl.addMessage(wsdlMessageOutput); wsdlOperation.setOutput(outputIO); if (((EventSource) event).isSolicitResponse()) { String inputName = event.getInputName(); QName inMsgName = new QName(inputName + IN_MSG_POSTFIX, namespace); IOType inputIO = new IOType(inMsgName); if (event.hasInputAttributes()) { inputIO.setAttributes(event.getInputAttributes()); } // check whether auto-generated or set if (event.isInputNameSet()) { inputIO.setName(inputName); } if (event.isInputActionSet()) { inputIO.setAction(event.getInputAction()); } /* * we always include an input message for real operations, * although their input element may be null */ WSDLMessage wsdlMessageInput = new WSDLMessage(inMsgName); Element input = event.getInput(); if (input != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(input.getName()); wsdlMessageInput.addPart(part); } wsdl.addMessage(wsdlMessageInput); wsdlOperation.setInput(inputIO); } // add fault IOTypes and action URIs for (Iterator it = event.getFaults(); it.hasNext();) { Fault fault = (Fault) it.next(); String faultName = fault.getName(); QName faultMsgName = new QName(eventName + faultName + FAULT_MSG_POSTFIX, namespace); IOType faultIO = new IOType(faultMsgName); if (fault.hasAttributes()) { faultIO.setAttributes(fault.getAttributes()); } // check whether auto-generated or set faultIO.setName(fault.getName()); String action = fault.getAction(); if (action != null) { faultIO.setAction(action); } WSDLMessage wsdlMessageFault = new WSDLMessage(faultMsgName); Element faultElement = fault.getElement(); if (faultElement != null) { WSDLMessagePart part = new WSDLMessagePart(); part.setElementName(faultElement.getName()); wsdlMessageFault.addPart(part); } wsdl.addMessage(wsdlMessageFault); wsdlOperation.addFault(faultIO); } portType.addOperation(wsdlOperation); } wsdl.addPortType(portType); wsdl.addBinding(new SOAP12DocumentLiteralHTTPBinding(new QName(portTypeName.getLocalPart() + BINDING_POSTFIX, namespace), portTypeName)); } wsdls.put(targetNamespace, wsdl); addServiceAndPortsIfMissing(wsdl); return wsdl; } private void addServiceAndPortsIfMissing(WSDL wsdl) { if (wsdl == null) { return; } WSDLService service = wsdl.getService(sid); if (service == null) { service = new WSDLService(new QName(sid, wsdl.getTargetNamespace())); try { wsdl.addService(service); } catch (UnsupportedBindingException e) { // shouldn't ever occur } } for (Iterator bindings = wsdl.getBindings(); bindings.hasNext();) { WSDLBinding binding = (WSDLBinding) bindings.next(); WSDLPortType bindingPortType = binding.getPortType(); if (service.containsPortsForBinding(binding.getName())) { continue; } int suffix = 0; String basePortName = bindingPortType.getLocalName() + "Port"; for (Iterator eprs = getEprInfos(); eprs.hasNext();) { EprInfo epr = (EprInfo) eprs.next(); SOAP12DocumentLiteralHTTPPort port = new SOAP12DocumentLiteralHTTPPort(basePortName + suffix++, binding.getName()); port.setLocation(epr.getXAddress()); service.addPort(port); } } } /** * Enables dynamic service creation from an existing WSDL description. * <p> * This method analyzes the WSDL loaded from <code>wsdlUri</code> and adds * all supported port types found to this service. For each supported * operation (i.e. either one-way or request-response transmission types), * an instance of class {@link OperationStub} is created and added, whereas * for each event source (aka. notification or solicit-response transmission * types) an instance of class {@link DefaultEventSource} is added. * </p> * <p> * The actual business logic of imported one-way or request-response * operations can be specified on the corresponding {@link OperationStub} * instance after having obtained it from this service via one of the * <code>getOperation(...)</code> methods like this: * * <pre> * DefaultService myService = ...; * myService.define("http://www.example.org/myService/description.wsdl"); * * InvokeDelegate myDelegate = ...; * * Operation myOp = (OperationStub) myService.getOperation("http://www.example.org/MyServicePortType/MyOperation"); * myOp.setDelegate(myDelegate); * </pre> * * The {@link InvokeDelegate} instance above defines the actual code to be * executed when the <code>myOperation</code> gets called. Its * {@link InvokeDelegate#invoke(Operation, ParameterValue)} method receives * the parameters sent to the operation, as well as the operation instance * itself. The latter is useful for implementors who want to share a single * {@link InvokeDelegate} instance between different operations. * </p> * <p> * Note that the cast to {@link OperationStub} above is only safe if the * operation being obtained was actually created via a call to this * {@link #define(URI)} method - in any other case, e.g. when it was added * manually by means of {@link #addOperation(Operation)}, this cast will * most likely result in a <code>java.lang.ClassCastException</code>. * </p> * * @param wsdlUri URI pointing to the location of the WSDL document to * define this service from; the URI may have an arbitrary schema * (e.g. file, http, https, etc.) as long as there is runtime * support available for accessing it within the DPWS framework, * see {@link DPWSFramework#getResourceAsStream(URI)} * @throws IOException if a failure occurs while attempting to obtain the * WSDL from the given {@link URI} */ public void define(URI wsdlUri) throws IOException { WSDL wsdl = WSDLRepository.loadWsdl(wsdlUri); define(wsdl); } /** * Enables dynamic service creation from an existing WSDL description. * <p> * This method analyzes the WSDL loaded from <code>wsdlUri</code> and adds * all supported port types found to this service. For each supported * operation (i.e. either one-way or request-response transmission types), * an instance of class {@link OperationStub} is created and added, whereas * for each event source (aka. notification or solicit-response transmission * types) an instance of class {@link DefaultEventSource} is added. * </p> * <p> * The actual business logic of imported one-way or request-response * operations can be specified on the corresponding {@link OperationStub} * instance after having obtained it from this service via one of the * <code>getOperation(...)</code> methods like this: * * <pre> * DefaultService myService = ...; * myService.define("http://www.example.org/myService/description.wsdl"); * * InvokeDelegate myDelegate = ...; * * Operation myOp = (OperationStub) myService.getOperation("http://www.example.org/MyServicePortType/MyOperation"); * myOp.setDelegate(myDelegate); * </pre> * * The {@link InvokeDelegate} instance above defines the actual code to be * executed when the <code>myOperation</code> gets called. Its * {@link InvokeDelegate#invoke(Operation, ParameterValue)} method receives * the parameters sent to the operation, as well as the operation instance * itself. The latter is useful for implementors who want to share a single * {@link InvokeDelegate} instance between different operations. * </p> * <p> * Note that the cast to {@link OperationStub} above is only safe if the * operation being obtained was actually created via a call to this * {@link #define(URI)} method - in any other case, e.g. when it was added * manually by means of {@link #addOperation(Operation)}, this cast will * most likely result in a <code>java.lang.ClassCastException</code>. * </p> * * @param wsdl the WSDL object which should be used to define the serivce. * @throws IOException if a failure occurs while attempting to obtain the * WSDL from the given {@link URI} */ public void define(WSDL wsdl) throws IOException { Iterator it = wsdl.getSupportedPortTypes().iterator(); if (!it.hasNext()) { Log.warn("WSDL doesn't contain any supported port types."); } else { while (it.hasNext()) { WSDLPortType portType = (WSDLPortType) it.next(); processWSDLPortType(portType); } /* * BUGFIX for SF 3043032: no subscription manager for event sources * defined via WSDL */ EventingFactory eFac = null; try { eFac = DPWSFramework.getEventingFactory(); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } if (!events.isEmpty() && subscriptionManager == null) { subscriptionManager = eFac.getSubscriptionManager(this); } } // wsdl.serialize(System.err); // System.err.println(); wsdls.put(wsdl.getTargetNamespace(), wsdl); } /* * (non-Javadoc) * @see * org.ws4d.java.service.ServiceCommons#createOperation(org.ws4d.java.wsdl * .WSDLOperation) */ protected Operation createOperation(WSDLOperation wsdlOperation) { return new OperationStub(wsdlOperation); } /* * (non-Javadoc) * @see * org.ws4d.java.service.Service#subscribe(org.ws4d.java.eventing.EventSink, * java.lang.String, org.ws4d.java.types.uri.URISet, long) */ public ClientSubscription subscribe(EventSink sink, String clientSubscriptionId, URISet eventActionURIs, long duration) throws EventingException, TimeoutException { ClientSubscription subscription = null; if (subscriptionManager != null) { subscription = subscriptionManager.subscribe(sink, clientSubscriptionId, eventActionURIs, duration); sink.addSubscription(clientSubscriptionId, subscription); } return subscription; } /* * (non-Javadoc) * @seeorg.ws4d.java.service.Service#unsubscribe(org.ws4d.java.eventing. * ClientSubscription) */ public void unsubscribe(ClientSubscription subscription) throws EventingException, TimeoutException { ((ClientSubscriptionInternal) subscription).dispose(); if (subscriptionManager != null) { subscriptionManager.unsubscribe(subscription); } } /* * (non-Javadoc) * @see * org.ws4d.java.service.Service#renew(org.ws4d.java.eventing.ClientSubscription * , long) */ public long renew(ClientSubscription subscription, long duration) throws EventingException, TimeoutException { if (subscriptionManager != null) { long newDuration = subscriptionManager.renew(subscription, duration); ((ClientSubscriptionInternal) subscription).renewInternal(newDuration); } return 0; } /* * (non-Javadoc) * @see org.ws4d.java.service.Service#getStatus(org.ws4d.java.eventing. * ClientSubscription) */ public long getStatus(ClientSubscription subscription) throws EventingException, TimeoutException { if (subscriptionManager != null) { return subscriptionManager.getStatus(subscription); } return 0L; } public void addUser(HTTPUser user) { if (userGroup == null) { userGroup = new HTTPGroup(); } userGroup.addUser(user); } public void addGroup(HTTPGroup group){ if(userGroup == null){ userGroup = group; } else { //TODO mehrere Gruppen hinzuf�gen k�nnen } } protected class ServiceMessageListener extends DefaultIncomingMessageListener { protected ServiceMessageListener() { super(); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org. * ws4d.java.communication.message.metadataexchange.GetMetadataMessage, * org.ws4d.java.communication.ProtocolData) */ public GetMetadataResponseMessage handle(GetMetadataMessage getMetadata, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(getMetadata)); } GetMetadataResponseMessage response = new GetMetadataResponseMessage(protocolData.getCommunicationManagerId()); response.setResponseTo(getMetadata); // set DPWSVersion from the Request to the Response response.setProtocolInfo(getMetadata.getProtocolInfo()); sharedLock(); try { if (parentDevice != null) { RelationshipMData relationship = new RelationshipMData(); // the host part HostMData host = new HostMData(); host.setEndpointReference(parentDevice.getEndpointReference()); QNameSet types = new QNameSet(); for (Iterator it = parentDevice.getPortTypes(); it.hasNext();) { QName type = (QName) it.next(); types.add(type); } host.setTypes(types); relationship.setHost(host); // HostedMData hosted = new HostedMData(); /* * Filter endpoint references which are not transport * addresses. DPWS specification 2.5 R0042 */ Iterator eprsCurrent = getEprInfos(); EprInfoSet eprsFiltered = new EprInfoSet(); while (eprsCurrent.hasNext()) { EprInfo epr = (EprInfo) eprsCurrent.next(); if (epr.getXAddress() != null) { eprsFiltered.add(epr); } } hosted.setEprInfoSet(eprsFiltered); Iterator typesCurrent = getPortTypes(); QNameSet typesFilled = new QNameSet(); while (typesCurrent.hasNext()) { QName name = (QName) typesCurrent.next(); typesFilled.add(name); } hosted.setTypes(typesFilled); if (hosted.getServiceId() == null) { hosted.setServiceId(new URI(sid)); } relationship.addHosted(hosted); CommunicationManager comMan = DPWSFramework.getCommunicationManager(protocolData.getCommunicationManagerId()); CommunicationUtil comUtil = comMan.getCommunicationUtil(); ConstantsHelper helper = comUtil.getHelper(protocolData.getProtocolInfo().getVersion()); response.addRelationship(relationship, helper); } for (Iterator it = wsdlURIs.values().iterator(); it.hasNext();) { Set uris = (Set) it.next(); if (uris == null) { continue; } for (Iterator it2 = uris.iterator(); it2.hasNext();) { URI uri = (URI) it2.next(); if (protocolData.destinationMatches(uri)) { response.addMetadataLocation(uri); } } } } finally { releaseSharedLock(); } return response; } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org.ws4d.java.message.eventing.SubscribeMessage, * org.ws4d.java.communication.ProtocolData) */ public SubscribeResponseMessage handle(SubscribeMessage subscribe, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(subscribe)); } if (subscriptionManager == null) { // eventing not supported throw new SOAPException(FaultMessage.createActionNotSupportedFault(subscribe)); } sharedLock(); try { return subscriptionManager.subscribe(subscribe, protocolData); } catch (SOAPException e) { Log.printStackTrace(e); throw e; } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org.ws4d.java.message.eventing.GetStatusMessage, * org.ws4d.java.communication.ProtocolData) */ public GetStatusResponseMessage handle(GetStatusMessage getStatus, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(getStatus)); } if (subscriptionManager == null) { // eventing not supported throw new SOAPException(FaultMessage.createActionNotSupportedFault(getStatus)); } sharedLock(); try { return subscriptionManager.getStatus(getStatus, protocolData); } catch (SOAPException e) { Log.printStackTrace(e); throw e; } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org.ws4d.java.message.eventing.RenewMessage, * org.ws4d.java.communication.ProtocolData) */ public RenewResponseMessage handle(RenewMessage renew, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(renew)); } if (subscriptionManager == null) { // eventing not supported throw new SOAPException(FaultMessage.createActionNotSupportedFault(renew)); } sharedLock(); try { return subscriptionManager.renew(renew, protocolData); } catch (SOAPException e) { Log.printStackTrace(e); throw e; } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org.ws4d.java.message.eventing.UnsubscribeMessage, * org.ws4d.java.communication.ProtocolData) */ public UnsubscribeResponseMessage handle(UnsubscribeMessage unsubscribe, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(unsubscribe)); } if (subscriptionManager == null) { // eventing not supported throw new SOAPException(FaultMessage.createActionNotSupportedFault(unsubscribe)); } sharedLock(); try { return subscriptionManager.unsubscribe(unsubscribe, protocolData); } catch (SOAPException e) { Log.printStackTrace(e); throw e; } finally { releaseSharedLock(); } } /* * (non-Javadoc) * @see * org.ws4d.java.communication.DefaultIncomingMessageListener#handle * (org.ws4d.java.message.invocation.InvokeMessage, * org.ws4d.java.communication.ProtocolData) */ public InvokeMessage handle(final InvokeMessage invokeRequest, ProtocolData protocolData) throws SOAPException { if (!isRunning()) { // send Fault wsa:ServiceUnavailable throw new SOAPException(FaultMessage.createEndpointUnavailableFault(invokeRequest)); } Operation operation = null; sharedLock(); try { // Remote invocation String inputAction = invokeRequest.getAction().toString(); if (Log.isDebug()) { Log.debug("<I> Receiving invocation input for " + inputAction, Log.DEBUG_LAYER_APPLICATION); } operation = (Operation) operations.get(inputAction); if (operation == null) { throw new SOAPException(FaultMessage.createActionNotSupportedFault(invokeRequest)); } } finally { releaseSharedLock(); } try { /* * User Thread */ /* * Resolve the types based on the input! */ ParameterValue reqVal = invokeRequest.getContent(); if (reqVal != null) { DataStructure wsdlCol = wsdls.values(); Iterator wsdlIt = wsdlCol.iterator(); while (wsdlIt.hasNext()) { WSDL wsdl = (WSDL) wsdlIt.next(); Iterator schemaIt = wsdl.getTypes(); while (schemaIt.hasNext()) { Schema schema = (Schema) schemaIt.next(); reqVal.resolveTypes(schema); } } } ParameterValue retVal = operation.invoke(reqVal); if (operation.isRequestResponse()) { /* * Send response */ InvokeMessage invokeResponse = new InvokeMessage(operation.getOutputAction(), false, protocolData.getCommunicationManagerId()); invokeResponse.setResponseTo(invokeRequest); // set DPWSVersion from the Request to the Response invokeResponse.setProtocolInfo(invokeRequest.getProtocolInfo()); invokeResponse.setContent(retVal); return invokeResponse; } else { // send HTTP response (202) return null; } } catch (InvocationException e) { // Log.printStackTrace(e); Log.warn("Exception during invocation: " + e.getMessage()); // respond with fault to sender FaultMessage fault = new FaultMessage(e.getAction(), protocolData.getCommunicationManagerId()); fault.setResponseTo(invokeRequest); fault.setCode(e.getCode()); fault.setSubcode(e.getSubcode()); fault.setReason(e.getReason()); fault.setDetail(e.getDetail()); throw new SOAPException(fault); } catch (TimeoutException e) { // this shouldn't ever occur locally Log.printStackTrace(e); return null; } } public OperationDescription getOperation(String action) { Operation operation = null; sharedLock(); try { operation = (Operation) operations.get(action); } finally { releaseSharedLock(); } return operation; } } private static class ResourcePath { final String path; final int depth; ResourcePath(String path, int depth) { super(); this.path = path; this.depth = depth; } } }