blob: a36274168513aecd939be0f46a47d88b5ea214c9 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.rmi.activation;
27
28import java.io.IOException;
29import java.io.ObjectInputStream;
30import java.io.Serializable;
31import java.rmi.MarshalledObject;
32import java.util.Arrays;
33import java.util.Properties;
34
35/**
36 * An activation group descriptor contains the information necessary to
37 * create/recreate an activation group in which to activate objects.
38 * Such a descriptor contains: <ul>
39 * <li> the group's class name,
40 * <li> the group's code location (the location of the group's class), and
41 * <li> a "marshalled" object that can contain group specific
42 * initialization data. </ul> <p>
43 *
44 * The group's class must be a concrete subclass of
45 * <code>ActivationGroup</code>. A subclass of
46 * <code>ActivationGroup</code> is created/recreated via the
47 * <code>ActivationGroup.createGroup</code> static method that invokes
48 * a special constructor that takes two arguments: <ul>
49 *
50 * <li> the group's <code>ActivationGroupID</code>, and
51 * <li> the group's initialization data (in a
52 * <code>java.rmi.MarshalledObject</code>)</ul><p>
53 *
54 * @author Ann Wollrath
55 * @since 1.2
56 * @see ActivationGroup
57 * @see ActivationGroupID
58 */
59public final class ActivationGroupDesc implements Serializable {
60
61 /**
62 * @serial The group's fully package qualified class name.
63 */
64 private String className;
65
66 /**
67 * @serial The location from where to load the group's class.
68 */
69 private String location;
70
71 /**
72 * @serial The group's initialization data.
73 */
74 private MarshalledObject<?> data;
75
76 /**
77 * @serial The controlling options for executing the VM in
78 * another process.
79 */
80 private CommandEnvironment env;
81
82 /**
83 * @serial A properties map which will override those set
84 * by default in the subprocess environment.
85 */
86 private Properties props;
87
88 /** indicate compatibility with the Java 2 SDK v1.2 version of class */
89 private static final long serialVersionUID = -4936225423168276595L;
90
91 /**
92 * Constructs a group descriptor that uses the system defaults for group
93 * implementation and code location. Properties specify Java
94 * environment overrides (which will override system properties in
95 * the group implementation's VM). The command
96 * environment can control the exact command/options used in
97 * starting the child VM, or can be <code>null</code> to accept
98 * rmid's default.
99 *
100 * <p>This constructor will create an <code>ActivationGroupDesc</code>
101 * with a <code>null</code> group class name, which indicates the system's
102 * default <code>ActivationGroup</code> implementation.
103 *
104 * @param overrides the set of properties to set when the group is
105 * recreated.
106 * @param cmd the controlling options for executing the VM in
107 * another process (or <code>null</code>).
108 * @since 1.2
109 */
110 public ActivationGroupDesc(Properties overrides,
111 CommandEnvironment cmd)
112 {
113 this(null, null, null, overrides, cmd);
114 }
115
116 /**
117 * Specifies an alternate group implementation and execution
118 * environment to be used for the group.
119 *
120 * @param className the group's package qualified class name or
121 * <code>null</code>. A <code>null</code> group class name indicates
122 * the system's default <code>ActivationGroup</code> implementation.
123 * @param location the location from where to load the group's
124 * class
125 * @param data the group's initialization data contained in
126 * marshalled form (could contain properties, for example)
127 * @param overrides a properties map which will override those set
128 * by default in the subprocess environment (will be translated
129 * into <code>-D</code> options), or <code>null</code>.
130 * @param cmd the controlling options for executing the VM in
131 * another process (or <code>null</code>).
132 * @since 1.2
133 */
134 public ActivationGroupDesc(String className,
135 String location,
136 MarshalledObject<?> data,
137 Properties overrides,
138 CommandEnvironment cmd)
139 {
140 this.props = overrides;
141 this.env = cmd;
142 this.data = data;
143 this.location = location;
144 this.className = className;
145 }
146
147 /**
148 * Returns the group's class name (possibly <code>null</code>). A
149 * <code>null</code> group class name indicates the system's default
150 * <code>ActivationGroup</code> implementation.
151 * @return the group's class name
152 * @since 1.2
153 */
154 public String getClassName() {
155 return className;
156 }
157
158 /**
159 * Returns the group's code location.
160 * @return the group's code location
161 * @since 1.2
162 */
163 public String getLocation() {
164 return location;
165 }
166
167 /**
168 * Returns the group's initialization data.
169 * @return the group's initialization data
170 * @since 1.2
171 */
172 public MarshalledObject<?> getData() {
173 return data;
174 }
175
176 /**
177 * Returns the group's property-override list.
178 * @return the property-override list, or <code>null</code>
179 * @since 1.2
180 */
181 public Properties getPropertyOverrides() {
182 return (props != null) ? (Properties) props.clone() : null;
183 }
184
185 /**
186 * Returns the group's command-environment control object.
187 * @return the command-environment object, or <code>null</code>
188 * @since 1.2
189 */
190 public CommandEnvironment getCommandEnvironment() {
191 return this.env;
192 }
193
194
195 /**
196 * Startup options for ActivationGroup implementations.
197 *
198 * This class allows overriding default system properties and
199 * specifying implementation-defined options for ActivationGroups.
200 * @since 1.2
201 */
202 public static class CommandEnvironment implements Serializable {
203 private static final long serialVersionUID = 6165754737887770191L;
204
205 /**
206 * @serial
207 */
208 private String command;
209
210 /**
211 * @serial
212 */
213 private String[] options;
214
215 /**
216 * Create a CommandEnvironment with all the necessary
217 * information.
218 *
219 * @param cmdpath the name of the java executable, including
220 * the full path, or <code>null</code>, meaning "use rmid's default".
221 * The named program <em>must</em> be able to accept multiple
222 * <code>-Dpropname=value</code> options (as documented for the
223 * "java" tool)
224 *
225 * @param argv extra options which will be used in creating the
226 * ActivationGroup. Null has the same effect as an empty
227 * list.
228 * @since 1.2
229 */
230 public CommandEnvironment(String cmdpath,
231 String[] argv)
232 {
233 this.command = cmdpath; // might be null
234
235 // Hold a safe copy of argv in this.options
236 if (argv == null) {
237 this.options = new String[0];
238 } else {
239 this.options = new String[argv.length];
240 System.arraycopy(argv, 0, this.options, 0, argv.length);
241 }
242 }
243
244 /**
245 * Fetch the configured path-qualified java command name.
246 *
247 * @return the configured name, or <code>null</code> if configured to
248 * accept the default
249 * @since 1.2
250 */
251 public String getCommandPath() {
252 return (this.command);
253 }
254
255 /**
256 * Fetch the configured java command options.
257 *
258 * @return An array of the command options which will be passed
259 * to the new child command by rmid.
260 * Note that rmid may add other options before or after these
261 * options, or both.
262 * Never returns <code>null</code>.
263 * @since 1.2
264 */
265 public String[] getCommandOptions() {
266 return (String[]) options.clone();
267 }
268
269 /**
270 * Compares two command environments for content equality.
271 *
272 * @param obj the Object to compare with
273 * @return true if these Objects are equal; false otherwise.
274 * @see java.util.Hashtable
275 * @since 1.2
276 */
277 public boolean equals(Object obj) {
278
279 if (obj instanceof CommandEnvironment) {
280 CommandEnvironment env = (CommandEnvironment) obj;
281 return
282 ((command == null ? env.command == null :
283 command.equals(env.command)) &&
284 Arrays.equals(options, env.options));
285 } else {
286 return false;
287 }
288 }
289
290 /**
291 * Return identical values for similar
292 * <code>CommandEnvironment</code>s.
293 * @return an integer
294 * @see java.util.Hashtable
295 */
296 public int hashCode()
297 {
298 // hash command and ignore possibly expensive options
299 return (command == null ? 0 : command.hashCode());
300 }
301
302 /**
303 * <code>readObject</code> for custom serialization.
304 *
305 * <p>This method reads this object's serialized form for this
306 * class as follows:
307 *
308 * <p>This method first invokes <code>defaultReadObject</code> on
309 * the specified object input stream, and if <code>options</code>
310 * is <code>null</code>, then <code>options</code> is set to a
311 * zero-length array of <code>String</code>.
312 */
313 private void readObject(ObjectInputStream in)
314 throws IOException, ClassNotFoundException
315 {
316 in.defaultReadObject();
317 if (options == null) {
318 options = new String[0];
319 }
320 }
321 }
322
323 /**
324 * Compares two activation group descriptors for content equality.
325 *
326 * @param obj the Object to compare with
327 * @return true if these Objects are equal; false otherwise.
328 * @see java.util.Hashtable
329 * @since 1.2
330 */
331 public boolean equals(Object obj) {
332
333 if (obj instanceof ActivationGroupDesc) {
334 ActivationGroupDesc desc = (ActivationGroupDesc) obj;
335 return
336 ((className == null ? desc.className == null :
337 className.equals(desc.className)) &&
338 (location == null ? desc.location == null :
339 location.equals(desc.location)) &&
340 (data == null ? desc.data == null : data.equals(desc.data)) &&
341 (env == null ? desc.env == null : env.equals(desc.env)) &&
342 (props == null ? desc.props == null :
343 props.equals(desc.props)));
344 } else {
345 return false;
346 }
347 }
348
349 /**
350 * Produce identical numbers for similar <code>ActivationGroupDesc</code>s.
351 * @return an integer
352 * @see java.util.Hashtable
353 */
354 public int hashCode() {
355 // hash location, className, data, and env
356 // but omit props (may be expensive)
357 return ((location == null
358 ? 0
359 : location.hashCode() << 24) ^
360 (env == null
361 ? 0
362 : env.hashCode() << 16) ^
363 (className == null
364 ? 0
365 : className.hashCode() << 8) ^
366 (data == null
367 ? 0
368 : data.hashCode()));
369 }
370}