1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2003-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: Request.java,v 1.3 2005/04/14 15:08:06 tanderson Exp $
44 */
45 package org.exolab.jms.net.connector;
46
47 import java.io.IOException;
48 import java.io.ObjectInput;
49 import java.io.ObjectOutput;
50 import java.io.Serializable;
51 import java.lang.reflect.Method;
52 import java.rmi.server.ObjID;
53
54 import org.exolab.jms.net.util.SerializationHelper;
55
56
57 /***
58 * A <code>Request</code> wraps all of the information needed to invoke a method
59 * on a remote object.
60 *
61 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
62 * @version $Revision: 1.3 $ $Date: 2005/04/14 15:08:06 $
63 * @see Response
64 * @see Connection
65 */
66 public class Request implements Serializable {
67
68 /***
69 * The URI of the remote server.
70 */
71 private transient String _uri;
72
73 /***
74 * The identifier of the object to invoke the method on.
75 */
76 private ObjID _objID;
77
78 /***
79 * The method to invoke.
80 */
81 private transient Method _method;
82
83 /***
84 * The serialized method arguments.
85 */
86 private transient ObjectInput _argStream;
87
88 /***
89 * The arguments to pass to the method. Note that if the method doesn't
90 * take any arguments, this may be <code>null</code>, to avoid the
91 * overhead of serializing an empty Object[].
92 */
93 private Object[] _args;
94
95 /***
96 * The unique identifier of the method to invoke.
97 */
98 private long _methodID;
99
100
101 /***
102 * Construct a new <code>Request</code>.
103 *
104 * @param objID the object to invoke the method on
105 * @param method the method to invoke
106 * @param args the arguments to pass to the method.
107 * May be <code>null</code>.
108 * @param methodID the unique identifier of the method
109 */
110 public Request(ObjID objID, Method method, Object[] args, long methodID) {
111 _objID = objID;
112 _method = method;
113 _args = args;
114 _methodID = methodID;
115 }
116
117 /***
118 * Construct a new <code>Request</code>.
119 *
120 * @param uri the URI of the remote server
121 * @param objID the object to invoke the method on
122 * @param methodID a unique identifier for the method
123 * @param argStream the serialized arguments to pass to the method
124 * @see {@link #getArgs}
125 * @see {@link #readArgs}
126 */
127 private Request(String uri, ObjID objID, long methodID,
128 ObjectInput argStream) {
129 _uri = uri;
130 _objID = objID;
131 _argStream = argStream;
132 _methodID = methodID;
133 }
134
135 /***
136 * Returns the URI of the remote server.
137 *
138 * @return the URI of the remote server
139 */
140 public String getURI() {
141 return _uri;
142 }
143
144 /***
145 * Returns the object identifier.
146 *
147 * @return the object identifier
148 */
149 public ObjID getObjID() {
150 return _objID;
151 }
152
153 /***
154 * Returns the method to invoke.
155 *
156 * @return the method to invoke
157 */
158 public Method getMethod() {
159 return _method;
160 }
161
162 /***
163 * Returns the arguments to pass to the method.
164 *
165 * @return the arguments to pass to the method, or <code>null</code>
166 * if the method doesn't take any arguments, or the arguments haven't yet
167 * been read via {@link #readArgs}
168 */
169 public Object[] getArgs() {
170 return _args;
171 }
172
173 /***
174 * Reads the serialized arguments, using the supplied method to determine
175 * the argument types.
176 *
177 * @param method the method
178 * @return the deserialized arguments
179 * @throws ClassNotFoundException if an argument can't be deserialized
180 * @throws IOException for any I/O error
181 * @see #read
182 */
183 public Object[] readArgs(Method method)
184 throws ClassNotFoundException, IOException {
185 Class[] types = method.getParameterTypes();
186 _args = new Object[types.length];
187 _method = method;
188 for (int i = 0; i < types.length; ++i) {
189 _args[i] = SerializationHelper.read(types[i], _argStream);
190 }
191 if (_argStream != null) {
192 _argStream.close();
193 _argStream = null;
194 }
195 return _args;
196 }
197
198 /***
199 * Returns the unique identifier of the method to invoke.
200 *
201 * @return the identifier of the method to invoke
202 */
203 public long getMethodID() {
204 return _methodID;
205 }
206
207 /***
208 * Write this request to a stream.
209 *
210 * @param out the stream to write to
211 * @throws IOException for any I/O error
212 */
213 public void write(ObjectOutput out) throws IOException {
214 _objID.write(out);
215 out.writeLong(_methodID);
216
217
218 Class[] types = _method.getParameterTypes();
219 for (int i = 0; i < types.length; ++i) {
220 SerializationHelper.write(types[i], _args[i], out);
221 }
222 }
223
224 /***
225 * Read a request from a stream.
226 * <p/>
227 * This method doesn't completely deserialize the request. On return from
228 * this, the caller is responsible for invoking {@link #readArgs} with the
229 * method corresponding to that returned by {@link #getMethodID}.
230 *
231 * @param in the stream to read from. This is responsible for its closure.
232 * @return the deserialized request
233 * @throws IOException for any I/O error
234 */
235 public static Request read(ObjectInput in) throws IOException {
236 ObjID objID = ObjID.read(in);
237 long methodID = in.readLong();
238 return new Request(null, objID, methodID, in);
239 }
240
241 }