1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.river.start;
20  
21  import java.io.BufferedInputStream;
22  import java.io.BufferedOutputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileOutputStream;
26  import java.io.IOException;
27  import java.io.InvalidObjectException;
28  import java.io.ObjectInputStream;
29  import java.io.ObjectOutputStream;
30  import java.io.ObjectStreamException;
31  import java.io.Serializable;
32  import java.rmi.MarshalledObject;
33  import java.rmi.activation.ActivationException;
34  import java.rmi.activation.ActivationGroupDesc;
35  import java.rmi.activation.ActivationGroupDesc.CommandEnvironment;
36  import java.rmi.activation.ActivationGroupID;
37  import java.rmi.activation.ActivationSystem;
38  import java.util.ArrayList;
39  import java.util.Arrays;
40  import java.util.Properties;
41  import java.util.logging.Logger;
42  import net.jini.config.Configuration;
43  import net.jini.io.MarshalledInstance;
44  import org.apache.river.api.io.AtomicSerial;
45  import org.apache.river.api.io.AtomicSerial.GetArg;
46  import org.apache.river.api.io.Valid;
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  @AtomicSerial
64  public class SharedActivationGroupDescriptor 
65      implements ServiceDescriptor, Serializable
66  {
67      private static final long serialVersionUID = 1L;
68  
69      
70      
71  
72  
73      private final String policy;
74      
75      
76  
77  
78  
79      private final String classpath;
80      
81      
82  
83  
84  
85      private final String log;
86      
87      
88      
89  
90  
91      private final String serverCommand;
92      
93      
94  
95  
96  
97      private final String[] serverOptions;
98      
99      
100 
101 
102 
103     private final Properties serverProperties;
104     
105     
106 
107 
108 
109     private final String host;
110     
111     
112 
113 
114 
115     private final int port;
116     
117     private static final String GROUP_COOKIE_FILE = "cookie";
118     
119     private static final Logger logger = ServiceStarter.logger;
120     
121 
122     
123 
124 
125 
126 
127 
128     public SharedActivationGroupDescriptor(
129 	
130 	String policy, String classpath, String log,
131 	
132 	String serverCommand, String[] serverOptions,
133 	String[] serverProperties)
134     {
135 	this(policy, classpath, log, serverCommand, serverOptions,
136 	     serverProperties, null, 
137 	     ServiceStarter.getActivationSystemPort());
138     }
139 
140     
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162     public SharedActivationGroupDescriptor(
163 	
164 	String policy, String classpath, String log,
165 	
166 	String serverCommand, String[] serverOptions, 
167 	String[] serverProperties, String host, int port)
168     {
169 	if (policy == null || classpath == null || log == null) {
170             throw new NullPointerException(
171 		"Policy, classpath, or log cannot be null");
172 	}
173 	this.policy = policy;
174 	this.classpath = classpath;
175 	this.log = log;
176 	this.serverCommand = serverCommand;
177 	this.serverOptions = 
178 	    customizeSharedGroupOptions(classpath, serverOptions);
179 	Properties props = 
180 	    convertToProperties(serverProperties);
181 	this.serverProperties = 
182 	    customizeSharedGroupProperties(policy, props);
183 	this.host = (host == null) ? "" : host;
184 	if (port <= 0) {
185 	    this.port = ServiceStarter.getActivationSystemPort(); 
186 	} else {
187 	    this.port = port;
188 	}
189     }
190     
191     SharedActivationGroupDescriptor(GetArg arg) 
192 	    throws IOException, ClassNotFoundException{
193 	this(
194 		Valid.notNull(arg.get("policy", null, String.class), "Policy cannot be null"),
195 		Valid.notNull(arg.get("classpath", null, String.class), "Classpath cannot be null"),
196 		Valid.notNull(arg.get("log",null, String.class), "log cannot be null"),
197 		arg.get("serverCommand", null, String.class),
198 		arg.get("serverOptions", null, String[].class),
199 		arg.get("serverProperties", null, String[].class),
200 		arg.get("host", null, String.class),
201 		arg.get("port", 0)
202 	);
203     }
204  
205     
206 
207 
208 
209 
210     final public String getPolicy() { return policy; }
211     
212     
213 
214 
215 
216 
217     final public String getClasspath() { return classpath; }
218     
219     
220 
221 
222 
223 
224     final public String getLog() { return log; }
225     
226     
227 
228 
229 
230 
231 
232     final public String getServerCommand() { return serverCommand; }
233     
234     
235 
236 
237 
238 
239     final public String[] getServerOptions() { 
240 	return (String[])serverOptions.clone(); 
241     }
242     
243     
244 
245 
246 
247 
248     final public Properties getServerProperties() { 
249 	return (Properties)serverProperties.clone(); 
250     }
251     
252     
253 
254 
255 
256 
257     final public String getActivationSystemHost() { return host; }
258     
259     
260 
261 
262 
263 
264     final public int getActivationSystemPort() { return port; } 
265     
266     private static String[] customizeSharedGroupOptions(
267         String classpath, String[] userOptions)
268     {
269         String[] customOpts = new String[] {"-cp", classpath};
270 	
271 	if (userOptions != null) {
272             String[] tmp = new String[customOpts.length + userOptions.length];
273             System.arraycopy(customOpts, 0, tmp, 0, customOpts.length);
274             System.arraycopy(userOptions, 0, tmp, customOpts.length,
275                              userOptions.length);
276             customOpts = tmp;
277         }
278         return customOpts;
279     }
280     
281     private static Properties convertToProperties(String[] propertyValues) 
282     {
283         Properties properties = new Properties();
284     
285 	if (propertyValues == null || propertyValues.length == 0)
286 	    return properties;
287 
288         if (propertyValues.length % 2 != 0) {
289             throw new IllegalArgumentException(
290                 "The service properties entry has an odd number of elements");
291         }
292         for (int i = 0; i < propertyValues.length; i += 2) {
293             properties.setProperty(propertyValues[i], propertyValues[i + 1]);
294         }
295 	return properties;
296     }
297 
298 
299     private static Properties customizeSharedGroupProperties(
300         String policy, Properties userProperties)
301     {
302         
303         if (userProperties == null) {
304             userProperties = new Properties();
305         }
306         userProperties.put("java.security.policy", policy);
307 
308 	return userProperties;
309     }
310     
311     
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
322 
323 
324 
325 
326 
327 
328 
329 
330 
331 
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 
342 
343 
344 
345 
346     public Object create(Configuration config) throws Exception {
347         ServiceStarter.ensureSecurityManager();
348         logger.entering(SharedActivationGroupDescriptor.class.getName(),
349 	    "create", new Object[] {config});
350 
351 	if (config == null) {
352 	   throw new NullPointerException(
353 	       "Configuration argument cannot be null");
354 	}
355 
356 
357 
358 
359     
360 	ActivationSystem sys = 
361 	    ServiceStarter.getActivationSystem(
362 	        getActivationSystemHost(),
363 		getActivationSystemPort(),
364 		config);
365 		
366 	CommandEnvironment cmdToExecute
367 	    = new CommandEnvironment(getServerCommand(), 
368 	                             getServerOptions());
369 	ActivationGroupID gid = null;
370         try {
371 	    gid = sys.registerGroup(
372                 new ActivationGroupDesc(getServerProperties(), 
373 		                        cmdToExecute));
374  	    storeGroupID(getLog(), gid);
375 	} catch (Exception e) {
376             try {
377                 if (gid != null) sys.unregisterGroup(gid);
378             } catch (Exception ee) {
379                 
380             }
381             if (e instanceof IOException) 
382 	        throw (IOException)e;
383 	    else if (e instanceof ActivationException)
384 	        throw (ActivationException)e;
385 	    else if (e instanceof ClassNotFoundException)
386 	        throw (ClassNotFoundException)e;
387 	    else 
388 	        throw new RuntimeException("Unexpected Exception", e);
389         }
390 
391         logger.exiting(SharedActivationGroupDescriptor.class.getName(), 
392 	    "create", gid);
393 	return gid;
394     }
395 
396     
397 
398 
399 
400     private static void storeGroupID(final String dir, 
401         final ActivationGroupID obj)
402         throws IOException
403     {
404 
405         File log = new File(dir);
406         String absDir = log.getAbsolutePath();
407         if (log.exists()) {
408             throw new IOException("Log " + absDir + " exists."
409                 + " Please delete or select another path");
410         }
411         if (!log.mkdir()) {
412             throw new IOException("Could not create directory: " + absDir);
413 
414         }
415 
416         File cookieFile = new File(log, GROUP_COOKIE_FILE);
417         ObjectOutputStream oos = null;
418         try {
419             oos = new ObjectOutputStream(
420                 new BufferedOutputStream(
421                     new FileOutputStream(cookieFile)));
422             oos.writeObject(new MarshalledInstance(obj).convertToMarshalledObject());
423             oos.flush();
424 
425 	} catch (IOException e) {
426             cookieFile.delete();
427             throw (IOException)e.fillInStackTrace();
428         } finally {
429             if (oos != null) oos.close();
430         }
431     }
432     
433     
434 
435 
436 
437     static ActivationGroupID restoreGroupID(final String dir)
438         throws IOException, ClassNotFoundException
439     {
440         File log = new File(dir);
441         String absDir = log.getAbsolutePath();
442         if (!log.exists() || !log.isDirectory()) {
443             throw new IOException("Log directory [" 
444 	    + absDir + "] does not exist.");
445         }
446 
447         File cookieFile = new File(log, GROUP_COOKIE_FILE);
448         ObjectInputStream ois = null;
449         ActivationGroupID obj = null;
450         try {
451 
452             ois = new ObjectInputStream(
453                       new BufferedInputStream(
454                          new FileInputStream(cookieFile)));
455             MarshalledObject mo = (MarshalledObject)ois.readObject();
456 	    obj = (ActivationGroupID) new MarshalledInstance(mo).get(false);
457         } finally {
458             if (ois != null) ois.close();
459         }
460         return obj;
461     }
462 
463     public String toString() {
464         ArrayList fields = new ArrayList(8);
465         fields.add(policy);
466         fields.add(classpath);
467         fields.add(log);
468         fields.add(serverCommand);
469         fields.add(Arrays.asList(serverOptions));
470         fields.add(serverProperties);
471         fields.add(host);
472         fields.add(Integer.valueOf(port));
473         return fields.toString();
474     }
475     
476     
477 
478 
479 
480     private void readObject(ObjectInputStream in) 
481         throws IOException, ClassNotFoundException 
482     {
483         in.defaultReadObject();
484 	
485 	if (policy == null) {
486 	    throw new InvalidObjectException("null policy");
487 	}
488 	if (classpath == null) {
489 	    throw new InvalidObjectException("null class path");
490 	}
491 	if (log == null) {
492 	    throw new InvalidObjectException("null log");
493 	}
494 	if (serverOptions == null) {
495 	    throw new InvalidObjectException("null server options");
496 	}
497 	if (serverProperties == null) {
498 	    throw new InvalidObjectException("null server properties");
499 	}
500 	if (host == null) {
501 	    throw new InvalidObjectException("null activation host name");
502 	}
503 	if (port <= 0) {
504 	    throw new InvalidObjectException("invalid activation port: " + port);
505 	}    
506     }
507     
508     
509 
510 
511     private void readObjectNoData() throws ObjectStreamException {
512 	throw new InvalidObjectException("no data");
513     }
514 
515 }
516 
517