001: /*
002: * %W% %E%
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.jump.command;
028:
029: import com.sun.jump.message.JUMPMessage;
030: import com.sun.jump.message.JUMPMessageReader;
031: import com.sun.jump.message.JUMPMessagingService;
032: import com.sun.jump.message.JUMPOutgoingMessage;
033:
034: /**
035: * <code>JUMPCommand</code> is base class that encapsulates any command that
036: * is sent from the executive to an isolate (and vice-versa). The
037: * <code>JUMPCommand</code> abstracts the contents of the data part (payload)
038: * of the <code>JUMPMessage</code>. The following code samples shows sending
039: * and receiving of <code>JUMPCommand</code> using the messaging
040: * infrastructure.
041: * <h3>Sending a JUMPCommand.</h3>
042: * <pre>
043: * JUMPCommand command; // JUMPRequest or JUMPResponse
044: * JUMPMessagingService thisProcess; // JUMPExecutive or JUMPIsolateProcess
045: * JUMPMessageSender target; // JUMPIsolateProcessProxy or JUMPProcessProxy
046: *
047: * JUMPCommand command = new JUMPRequest(<id>, args);
048: * // create a message of the command type
049: * JUMPOutgoingMessage message = command.toMessage(thisProcess);
050: *
051: * // (a) synchronous send of a message
052: * JUMPMessage responseMessage = target.sendMessage(message, 0L);
053: * JUMPResponse response = JUMPResponse.fromMessage(responseMessage);
054: *
055: * // (b) asynchronous send of a message
056: * JUMPMessageDispatcher disp = thisProcess.getMessageDispatcher();
057: * // Register a handler for a response to this message
058: * Object token = disp.registerHandler(message, ResponseHandler.getInstance());
059: *
060: * // send the message to the isolate
061: * target.sendMessage(message);
062: * </pre>
063: *
064: * <h3>Receving a JUMPResponse</h3>
065: * <pre>
066: * public class ResponseHandler implements JUMPMessageHandler {
067: * void handleMessage(JUMPMessage message) {
068: * JUMPResponse response = JUMPResponse.fromMessage(message);
069: * // "response" usage follows ...
070: * // Unregister registration for this transaction.
071: * disp.cancelRegistration(token);
072: * }
073: * }
074: * </pre>
075: * <h3>Receiving a JUMPCommand and sending a response. </h3>
076: * <pre>
077: * public class RequestHandler implements JUMPMessageHandler {
078: * void handleMessage(JUMPMessage message) {
079: * JUMPRequest request = JUMPRequest.fromMessage(message);
080: * JUMPMessageResponseSender requestSender = message.getSender();
081: * // process request
082: * // ...
083: * JUMPResponse response = new JUMPResponse(<responseId>);
084: * // fill in response...
085: * // ...
086: * JUMPMessagingService myProcess; // JUMPExecutive or
087: * JUMPIsolateProcess
088: *
089: * // create a response message of the command type
090: * JUMPOutgoingMessage responseMessage =
091: * response.toMessage(myProcess);
092: *
093: * // The response goes back to the sender
094: * requestSender.sendResponseMessage(responseMessage);
095: * }
096: * }
097: * </pre>
098: */
099: public abstract class JUMPCommand {
100: protected String messageType;
101: protected String id;
102: protected String[] data;
103:
104: /**
105: * Creates a new instance of JUMPCommand
106: * @param messageType the type of the message to carry this command
107: * @param id the type of the command
108: * @param data the data carried in the command
109: */
110: JUMPCommand(String messageType, String id, String[] data) {
111: this .messageType = messageType;
112: this .id = id;
113: this .data = data;
114: }
115:
116: //
117: // To be filled in when de-serializing
118: //
119: protected JUMPCommand() {
120: }
121:
122: private void setMessageType(String mType) {
123: this .messageType = mType;
124: }
125:
126: public String[] getCommandData() {
127: return this .data;
128: }
129:
130: public String getCommandId() {
131: return this .id;
132: }
133:
134: public String getCommandMessageType() {
135: return this .messageType;
136: }
137:
138: /**
139: * Convert this command into an outgoing message
140: */
141: public final JUMPOutgoingMessage toMessage(JUMPMessagingService s) {
142: JUMPOutgoingMessage m = s.newOutgoingMessage(this .messageType);
143: this .serializeInto(m);
144: return m;
145: }
146:
147: /**
148: * Convert this command into an outgoing message
149: */
150: public final JUMPOutgoingMessage toMessageInResponseTo(
151: JUMPMessage r, JUMPMessagingService s) {
152: JUMPOutgoingMessage m = s.newOutgoingMessage(r);
153: this .serializeInto(m);
154: return m;
155: }
156:
157: /**
158: * Creates a new instance of <code>JUMPCommand</code> by deserializing
159: * the data from the <code>JUMPMessage</code>
160: */
161: public static JUMPCommand fromMessage(JUMPMessage message,
162: Class commandClass) {
163: JUMPCommand c;
164: try {
165: c = (JUMPCommand) commandClass.newInstance();
166: } catch (InstantiationException e) {
167: e.printStackTrace();
168: return null;
169: } catch (IllegalAccessException e) {
170: e.printStackTrace();
171: return null;
172: }
173: c.setMessageType(message.getType());
174: c.deserializeFrom(message);
175: return c;
176: }
177:
178: protected final void deserializeFrom(JUMPMessage message) {
179: this .messageType = message.getType();
180: JUMPMessageReader r = new JUMPMessageReader(message);
181: deserializeFrom(r);
182: }
183:
184: /**
185: * For subclasses to use to initialize any fields
186: * using <code>JUMPMessage.get*</code> methods.
187: */
188: protected void deserializeFrom(JUMPMessageReader message) {
189: this .id = message.getUTF();
190: this .data = message.getUTFArray();
191: }
192:
193: /**
194: * For subclasses to use to put data in a message
195: * using <code>JUMPOutgoingMessage.add*</code> methods.
196: */
197: protected void serializeInto(JUMPOutgoingMessage message) {
198: message.addUTF(this.id);
199: message.addUTFArray(this.data);
200: }
201: }
|