/******************************************************************************* * 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 org.ws4d.java.communication.ProtocolData; import org.ws4d.java.communication.ResponseCallback; import org.ws4d.java.constants.DPWSMessageConstants; import org.ws4d.java.message.Message; import org.ws4d.java.message.discovery.ProbeMatchesMessage; import org.ws4d.java.message.discovery.ResolveMatchesMessage; import org.ws4d.java.structures.LockedMap; import org.ws4d.java.types.URI; import org.ws4d.java.util.Log; import org.ws4d.java.util.TimedEntry; import org.ws4d.java.util.WatchDog; /** * Class memorizes outgoing requests and returns callbacks to incoming * responses. * * @author mspies */ public class RequestResponseCoordinator { /** message id<URI> -> <TimedEntry> */ protected final LockedMap map_msgId_2_entry = new LockedMap(); /** singleton of this */ protected static RequestResponseCoordinator rrc = new RequestResponseCoordinator(); /** * Private Constructor. */ private RequestResponseCoordinator() {} /** * Get singleton instance of request response coordinator. * * @return request response coordinator. */ public static RequestResponseCoordinator getInstance() { return rrc; } // --------------------------------------------------------------------- /** * Registers callback for an outgoing request message. Timeouts will be * generated by underlying communication layer. * * @param msg - the request message. * @param callback - callback for responses, faults or timeouts. * @param timeUntilTimeout */ public void registerResponseCallback(Message msg, ResponseCallback callback, long timeUntilTimeout) { TimedResponseCallback timedCallback = new TimedResponseCallback(msg, callback); WatchDog.getInstance().register(timedCallback, timeUntilTimeout); map_msgId_2_entry.put(msg.getMessageId(), timedCallback); } /** * Handle response message. Message will be sent to local callbacks. * * @param msg * @param protocolData * @return <code>true</code> - if message is exclusively handled by * RequestResponseCoordinator */ public void handleResponse(Message msg, ProtocolData protocolData) { URI requestMsgId = msg.getRelatesTo(); switch (msg.getType()) { // DISCOVERY case DPWSMessageConstants.PROBE_MATCHES_MESSAGE: { // More than one responses possible. ProbeMatchesMessage probeMatches = (ProbeMatchesMessage) msg; TimedResponseCallback entry = getCallback(requestMsgId); if (entry != null) { entry.callback.handle(entry.request, probeMatches, protocolData); } break; } case DPWSMessageConstants.RESOLVE_MATCHES_MESSAGE: { ResolveMatchesMessage resolveMatches = (ResolveMatchesMessage) msg; TimedResponseCallback entry = getCallback(requestMsgId); if (entry != null) { entry.callback.handle(entry.request, resolveMatches, protocolData); } break; } default: Log.error("Cannot determine response message type. Message = " + msg); } } // /** // * Init timeout for registered message. // * // * @param msgId message id of message to time out. // */ // public void initTimeout( URI msgId ){ // TimedResponseCallback msgEntry = (TimedResponseCallback) // map_msgId_2_entry.get(msgId); // if( msgEntry != null ){ // msgEntry.timedOut(); // } // } // ------------------------------- PRIVATE --------------------------- /** * Returns <code>true</code> if msgId is managed by the request response * coordinator, else <code>false</false>. * * @param msgId The msg id to look for. * @return Returns <code>true</code> if msgId is managed by the request * response coordinator, else <code>false</false>. */ public boolean containsMsgId(URI msgId) { return map_msgId_2_entry.containsKey(msgId); } /** * Get callback by msg id. * * @param msgId * @return callback */ private TimedResponseCallback getCallback(URI msgId) { return (TimedResponseCallback) map_msgId_2_entry.get(msgId); } private class TimedResponseCallback extends TimedEntry { /** request message */ Message request; /** callback to be called if response is received */ ResponseCallback callback; // /** response was received? */ // boolean responseReceived = false; TimedResponseCallback(Message request, ResponseCallback callback) { super(); this.request = request; this.callback = callback; } /* * (non-Javadoc) * @see org.ws4d.java.concurrency.TimedEntry#timedOut() */ public void timedOut() { // if( responseReceived == false ){ // callback.receivedTimeout(msgId); // } map_msgId_2_entry.remove(request.getMessageId()); callback.handleTimeout(request); } } }