KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > applications > types > JavasType


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.applications.types;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.struts.action.ActionForward;
35 import org.apache.struts.action.ActionMapping;
36 import org.jdom.Element;
37
38 import com.sslexplorer.applications.ApplicationLauncherType;
39 import com.sslexplorer.applications.ApplicationShortcut;
40 import com.sslexplorer.applications.server.ApplicationServerType;
41 import com.sslexplorer.applications.server.ProcessMonitor;
42 import com.sslexplorer.applications.server.ServerApplicationLauncher;
43 import com.sslexplorer.applications.server.ServerLauncher;
44 import com.sslexplorer.applications.server.ServerLauncherEvents;
45 import com.sslexplorer.boot.XMLElement;
46 import com.sslexplorer.extensions.ExtensionDescriptor;
47 import com.sslexplorer.extensions.ExtensionException;
48 import com.sslexplorer.policyframework.LaunchSession;
49 import com.sslexplorer.security.SessionInfo;
50
51 /**
52  * Implementation of an
53  * {@link com.sslexplorer.applications.ApplicationLauncherType} that allows
54  * execution of Java applications using a running VPN client.
55  * <p>
56  * This launcher will provide links to launch the VPN client if it is not
57  * running before launching the applicaiton itself.
58  *
59  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
60  */

61 public class JavasType implements ApplicationLauncherType,
62         ApplicationServerType {
63
64     final static Log log = LogFactory.getLog(JavasType.class);
65
66     /**
67      * Type name
68      */

69     public final static String JavaDoc TYPE = "javas";
70
71     // Private instance variables
72
private String JavaDoc jre;
73
74     private ExtensionDescriptor descriptor;
75
76     private String JavaDoc classpath = "";
77
78     private String JavaDoc mainclass;
79
80     private File JavaDoc workingDir;
81
82     private String JavaDoc[] jvm;
83
84     private List JavaDoc<String JavaDoc> programArgs = new ArrayList JavaDoc<String JavaDoc>();
85
86     private List JavaDoc<String JavaDoc> jvmArgs = new ArrayList JavaDoc<String JavaDoc>();
87
88     private ProcessMonitor process;
89
90     private String JavaDoc javaLibraryPath = "";
91
92     protected ServerLauncherEvents events;
93
94     protected ServerLauncher launcher;
95
96     /*
97      * (non-Javadoc)
98      *
99      * @see com.sslexplorer.extensions.ExtensionType#start(com.sslexplorer.extensions.ExtensionDescriptor,
100      * org.jdom.Element)
101      */

102     public void start(ExtensionDescriptor descriptor, Element element)
103             throws ExtensionException {
104         this.descriptor = descriptor;
105         if (element.getName().equals(TYPE)) {
106
107             jre = element.getAttribute("jre").getValue();
108
109             if (jre == null) {
110                 throw new ExtensionException(
111                         ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
112                         "<application> element requires attribute 'jre'");
113             }
114
115             try {
116                 ExtensionDescriptor.getVersion(jre);
117             } catch (Throwable JavaDoc ex) {
118                 throw new ExtensionException(
119                         ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
120                         "Invalid value '" + jre
121                                 + "' specified for 'jre' attribute");
122             }
123
124             for (Iterator JavaDoc it = element.getChildren().iterator(); it.hasNext();) {
125                 Element e = (Element) it.next();
126
127                 if (e.getName().equalsIgnoreCase("classpath")) {
128                     verifyClasspath(e);
129                 } else if (e.getName().equalsIgnoreCase("main")) {
130                     verifyMain(e);
131                 } else {
132                     throw new ExtensionException(
133                             ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
134                             "Unexpected element <" + e.getName()
135                                     + "> found in <application>");
136                 }
137             }
138
139         }
140
141     }
142
143     /*
144      * (non-Javadoc)
145      *
146      * @see com.sslexplorer.extensions.ExtensionType#verifyRequiredElements()
147      */

148     public void verifyRequiredElements() throws ExtensionException {
149     }
150
151     /*
152      * (non-Javadoc)
153      *
154      * @see com.sslexplorer.extensions.ExtensionType#isHidden()
155      */

156     public boolean isHidden() {
157         return false;
158     }
159
160     /*
161      * (non-Javadoc)
162      *
163      * @see com.sslexplorer.extensions.ExtensionType#getType()
164      */

165     public String JavaDoc getType() {
166         return TYPE;
167     }
168
169     /*
170      * (non-Javadoc)
171      *
172      * @see com.sslexplorer.applications.server.ApplicationServerType#prepare(com.sslexplorer.applications.server.ServerLauncher,
173      * com.sslexplorer.applications.server.ServerLauncherEvents,
174      * com.sslexplorer.boot.XMLElement)
175      */

176     public void prepare(ServerLauncher launcher, ServerLauncherEvents events,
177             XMLElement element) throws IOException JavaDoc {
178
179         if (events != null)
180             events.debug("Processing <" + element.getName()
181                     + "> for java application type");
182
183         this.launcher = launcher;
184         this.events = events;
185
186         if (element.getName().equals("java")) {
187
188             String JavaDoc jre = (String JavaDoc) element.getAttribute("jre");
189
190             if (events != null)
191                 events
192                         .debug("Checking our version against the required application version "
193                                 + jre);
194
195             if (!ServerLauncher.checkVersion(jre)) {
196                 throw new IOException JavaDoc(
197                         "Application requires Java Runtime Environment " + jre);
198             }
199
200             /**
201              * LDP - Don't reset the classpath as this stops extended extensions
202              * (such as the agent extension itself) from adding addtional
203              * classpath entries.
204              */

205             if (System.getProperty("java.version").startsWith("1.1")
206                     && !System.getProperty("java.vendor").startsWith(
207                             "Microsoft"))
208                 classpath = System.getProperty("java.home")
209                         + File.pathSeparator + "lib" + File.pathSeparator
210                         + "classes.zip";
211
212             Enumeration JavaDoc e = element.enumerateChildren();
213
214             while (e.hasMoreElements()) {
215                 XMLElement el = (XMLElement) e.nextElement();
216
217                 if (el.getName().equalsIgnoreCase("classpath")) {
218                     buildClassPath(el);
219                 } else if (el.getName().equalsIgnoreCase("main")) {
220                     mainclass = (String JavaDoc) el.getAttribute("class");
221                     if (events != null)
222                         events.debug("Main class is " + mainclass);
223                     String JavaDoc dir = (String JavaDoc) el.getAttribute("dir");
224                     if (events != null)
225                         events.debug("Dir is " + dir);
226                     if (dir != null) {
227                         workingDir = new File JavaDoc(launcher.replaceTokens(dir));
228                     } else {
229                         workingDir = null;
230                     }
231                     buildProgramArguments(el);
232                 }
233             }
234
235             if (events != null)
236                 events.debug("Finished preparing application descriptor.");
237         } else {
238             if (events != null)
239                 events.debug("Ignoring <" + element.getName()
240                         + "> tag as it is not a java application tag");
241         }
242
243     }
244
245     /*
246      * (non-Javadoc)
247      *
248      * @see com.sslexplorer.applications.server.ApplicationServerType#start()
249      */

250     public void start() {
251         execute(classpath, mainclass, workingDir);
252     }
253
254     /*
255      * (non-Javadoc)
256      *
257      * @see com.sslexplorer.vpn.util.ApplicationType#checkFileCondition(com.sslexplorer.vpn.util.XMLElement)
258      */

259     public boolean checkFileCondition(XMLElement el) throws IOException JavaDoc,
260             IllegalArgumentException JavaDoc {
261         String JavaDoc jre = (String JavaDoc) el.getAttribute("jre");
262         if (jre == null) {
263             throw new IllegalArgumentException JavaDoc(
264                     "No supported attributes in condition.");
265         } else {
266             return isSupportedJRE(jre);
267         }
268     }
269
270     /*
271      * (non-Javadoc)
272      *
273      * @see com.sslexplorer.vpn.util.ApplicationType#getProcessMonitor()
274      */

275     public ProcessMonitor getProcessMonitor() {
276         return process;
277     }
278
279     /*
280      * (non-Javadoc)
281      *
282      * @see com.sslexplorer.extensions.ExtensionType#stop()
283      */

284     public void stop() throws ExtensionException {
285     }
286
287     /*
288      * (non-Javadoc)
289      *
290      * @see com.sslexplorer.extensions.ExtensionType#activate()
291      */

292     public void activate() throws ExtensionException {
293     }
294
295     /*
296      * (non-Javadoc)
297      *
298      * @see com.sslexplorer.extensions.ExtensionType#canStop()
299      */

300     public boolean canStop() throws ExtensionException {
301         return true;
302     }
303
304     /*
305      * (non-Javadoc)
306      *
307      * @see com.sslexplorer.applications.ApplicationLauncherType#launch(java.util.Map,
308      * com.sslexplorer.extensions.ExtensionDescriptor,
309      * com.sslexplorer.applications.ApplicationShortcut,
310      * org.apache.struts.action.ActionMapping,
311      * com.sslexplorer.policyframework.LaunchSession, java.lang.String,
312      * javax.servlet.http.HttpServletRequest)
313      */

314     public ActionForward launch(Map JavaDoc<String JavaDoc, String JavaDoc> parameters,
315             ExtensionDescriptor descriptor, ApplicationShortcut shortcut,
316             ActionMapping mapping, LaunchSession launchSession,
317             String JavaDoc returnTo, HttpServletRequest JavaDoc request)
318             throws ExtensionException {
319         if (log.isInfoEnabled())
320             log.info("Starting Java server application "
321                     + shortcut.getResourceName());
322
323         ServerApplicationLauncher app;
324         try {
325             app = new ServerApplicationLauncher(parameters, shortcut
326                     .getApplication(), launchSession.getSession(), shortcut);
327             app.start();
328         } catch (Exception JavaDoc e) {
329             throw new ExtensionException(ExtensionException.FAILED_TO_LAUNCH, e);
330         }
331
332         return null;
333     }
334
335     /*
336      * (non-Javadoc)
337      *
338      * @see com.sslexplorer.applications.ApplicationLauncherType#isAgentRequired(com.sslexplorer.applications.ApplicationShortcut,
339      * com.sslexplorer.extensions.ExtensionDescriptor)
340      */

341     public boolean isAgentRequired(ApplicationShortcut shortcut,
342             ExtensionDescriptor descriptor) {
343         return false;
344     }
345
346     protected void addClasspathEntry(XMLElement e) throws IOException JavaDoc {
347         addClasspathEntry(e, null);
348     }
349
350     protected void addClasspathEntry(XMLElement e, String JavaDoc app)
351             throws IOException JavaDoc {
352
353         events.debug("Adding "
354                 + launcher.getInstallDir()
355                 + (e.getContent() != null ? File.separatorChar + e.getContent()
356                         : "") + " to CLASSPATH");
357
358         classpath += (!classpath.equals("") ? File.pathSeparator : "")
359                 + launcher.getInstallDir()
360                 + (e.getContent() != null ? File.separatorChar + e.getContent()
361                         : "");
362     }
363
364     protected void buildClassPath(XMLElement element) throws IOException JavaDoc {
365         buildClassPath(element, null);
366     }
367
368     protected void buildClassPath(XMLElement element, String JavaDoc app)
369             throws IOException JavaDoc {
370
371         if (events != null)
372             events.debug("Building classpath");
373         Enumeration JavaDoc en = element.enumerateChildren();
374         XMLElement e;
375
376         while (en.hasMoreElements()) {
377             e = (XMLElement) en.nextElement();
378             if (e.getName().equalsIgnoreCase("jar")) {
379                 addClasspathEntry(e, app);
380             } else if (e.getName().equals("if")) {
381
382                 String JavaDoc jre = (String JavaDoc) e.getAttribute("jre");
383                 if (jre == null) {
384                     String JavaDoc parameter = (String JavaDoc) e.getAttribute("parameter");
385
386                     if (parameter != null) {
387                         String JavaDoc requiredValue = (String JavaDoc) e.getAttribute("value");
388                         boolean not = "true".equalsIgnoreCase(((String JavaDoc) e
389                                 .getAttribute("not")));
390
391                         // Check the parameter
392
String JavaDoc value = (String JavaDoc) launcher.getDescriptorParams()
393                                 .get(parameter);
394
395                         if ((!not && requiredValue.equalsIgnoreCase(value))
396                                 || (not && !requiredValue
397                                         .equalsIgnoreCase(value))) {
398                             buildClassPath(e, app);
399                         }
400
401                     } else
402                         throw new IOException JavaDoc(
403                                 "<if> element requires jre or parameter attribute");
404                 } else {
405
406                     if (isSupportedJRE(jre)) {
407                         buildClassPath(e, app);
408                     }
409                 }
410             } else
411                 throw new IOException JavaDoc("Invalid element <" + e.getName()
412                         + "> found in <classpath>");
413         }
414
415     }
416
417     private boolean isSupportedJRE(String JavaDoc jre) {
418
419         int[] ourVersion = ServerLauncher.getVersion(System
420                 .getProperty("java.version"));
421
422         if (jre.startsWith(">")) {
423
424             // Our JRE must be greater than the value specified
425
int[] requiredVersion = ServerLauncher.getVersion(jre.substring(1));
426             for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) {
427                 if (ourVersion[i] < requiredVersion[i])
428                     return false;
429             }
430             return true;
431
432         } else if (jre.startsWith("<")) {
433             // Our JRE must be less than the value specified
434
int[] requiredVersion = ServerLauncher.getVersion(jre.substring(1));
435             for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) {
436                 if (ourVersion[i] > requiredVersion[i])
437                     return false;
438             }
439             return true;
440
441         } else {
442             // Direct comparison
443
int[] requiredVersion = ServerLauncher.getVersion(jre);
444             for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) {
445                 if (ourVersion[i] != requiredVersion[i])
446                     return false;
447             }
448             return true;
449
450         }
451
452     }
453
454     protected void addArgument(String JavaDoc arg) {
455         if (arg != null)
456             programArgs.add(launcher.replaceTokens(arg));
457     }
458
459     protected void addJVMArgument(String JavaDoc arg) {
460         if (arg != null) {
461
462             if (arg.startsWith("java.library.path")) {
463                 int idx = arg.indexOf('=');
464
465                 if (idx > -1) {
466                     String JavaDoc val = arg.substring(idx + 1).replace('/',
467                             File.separatorChar);
468                     javaLibraryPath += (javaLibraryPath.equals("") ? val
469                             : System.getProperty("path.separator") + val);
470
471                     if (events != null)
472                         events
473                                 .debug(val
474                                         + " has been appened to system property java.library.path");
475                 } else if (events != null)
476                     events.debug("Invalid java.library.path system property: "
477                             + arg);
478
479             } else
480                 jvmArgs.add(launcher.replaceTokens(arg));
481         }
482     }
483
484     private void addArgument(XMLElement e) throws IOException JavaDoc {
485         if (e.getName().equalsIgnoreCase("arg"))
486             addArgument(e.getContent());
487         else if (e.getName().equalsIgnoreCase("jvm")) {
488             addJVMArgument(e.getContent());
489         } else {
490             throw new IOException JavaDoc("Unexpected element <" + e.getName()
491                     + "> found");
492         }
493     }
494
495     private void buildProgramArguments(XMLElement element) throws IOException JavaDoc {
496
497         Enumeration JavaDoc en = element.enumerateChildren();
498
499         while (en.hasMoreElements()) {
500
501             XMLElement e = (XMLElement) en.nextElement();
502             if (e.getName().equalsIgnoreCase("arg"))
503                 addArgument(e);
504             else if (e.getName().equalsIgnoreCase("jvm")) {
505                 addArgument(e);
506             } else if (e.getName().equalsIgnoreCase("if")) {
507
508                 String JavaDoc jre = (String JavaDoc) e.getAttribute("jre");
509                 if (jre == null) {
510                     String JavaDoc parameter = (String JavaDoc) e.getAttribute("parameter");
511                     boolean not = "true".equalsIgnoreCase((String JavaDoc) e
512                             .getAttribute("not"));
513
514                     if (parameter != null) {
515                         String JavaDoc requiredValue = (String JavaDoc) e.getAttribute("value");
516
517                         // Check the parameter
518
String JavaDoc value = (String JavaDoc) launcher.getDescriptorParams()
519                                 .get(parameter);
520
521                         if ((!not && requiredValue.equalsIgnoreCase(value))
522                                 || (not && !requiredValue
523                                         .equalsIgnoreCase(value))) {
524                             buildProgramArguments(e);
525                         }
526
527                     } else
528                         throw new IOException JavaDoc(
529                                 "<if> element requires jre or parameter attribute");
530                 } else {
531                     // Check the jre
532
if (isSupportedJRE(jre)) {
533                         buildProgramArguments(e);
534                     }
535
536                 }
537
538             } else
539                 throw new IOException JavaDoc("Unexpected element <" + e.getName()
540                         + "> found in <main>");
541         }
542
543     }
544
545     private void execute(String JavaDoc classpath, String JavaDoc mainclass, File JavaDoc workingDir) {
546
547         String JavaDoc[] args = new String JavaDoc[programArgs.size()];
548         programArgs.toArray(args);
549
550         if (!javaLibraryPath.equals(""))
551             jvmArgs.add("java.library.path="
552                     + launcher.replaceTokens(javaLibraryPath));
553
554         jvm = new String JavaDoc[jvmArgs.size()];
555         jvmArgs.toArray(jvm);
556
557         String JavaDoc[] cmdargs = new String JavaDoc[jvm.length + args.length + 4];
558         /**
559          * Setup the command line in the format expected by Sun Microsystems
560          * java command line interpreter
561          */

562         cmdargs[0] = System.getProperty("java.home") + File.separator + "bin"
563                 + File.separator + "java";
564         cmdargs[1] = "-classpath";
565         cmdargs[2] = classpath;
566
567         for (int i = 0; i < jvm.length; i++) {
568             cmdargs[3 + i] = "-D" + jvm[i];
569         }
570
571         cmdargs[jvm.length + 3] = mainclass;
572
573         System.arraycopy(args, 0, cmdargs, jvm.length + 4, args.length);
574
575         String JavaDoc cmdline = "";
576         for (int i = 0; i < cmdargs.length; i++)
577             cmdline += " " + cmdargs[i];
578
579         if (events != null)
580             events.debug("Executing command: " + cmdline);
581
582         try {
583
584             if (events != null)
585                 events.executingApplication(launcher.getName(), cmdline.trim());
586
587             // Can we change the working directory of the process?
588
Process JavaDoc prc = Runtime.getRuntime().exec(cmdargs, null, workingDir);
589             process = new ProcessMonitor(launcher.getName(), prc);
590         } catch (IOException JavaDoc ex) {
591             if (events != null)
592                 events.debug("Process execution failed: " + ex.getMessage());
593         }
594
595     }
596
597     private void verifyClasspath(Element element) throws ExtensionException {
598         for (Iterator JavaDoc it = element.getChildren().iterator(); it.hasNext();) {
599             Element e = (Element) it.next();
600
601             if (e.getName().equalsIgnoreCase("jar")) {
602                 descriptor.processFile(e);
603             } else if (e.getName().equals("if")) {
604                 verifyClasspath(e);
605             } else {
606                 throw new ExtensionException(
607                         ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
608                         "Invalid element <" + e.getName()
609                                 + "> found in <classpath>");
610             }
611         }
612     }
613
614     private void verifyMain(Element element) throws ExtensionException {
615         for (Iterator JavaDoc it = element.getChildren().iterator(); it.hasNext();) {
616             Element e = (Element) it.next();
617             if (e.getName().equalsIgnoreCase("if")) {
618                 verifyMain(e);
619             } else if (!e.getName().equalsIgnoreCase("arg")
620                     && !e.getName().equalsIgnoreCase("jvm")) {
621                 throw new ExtensionException(
622                         ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
623                         "Unexpected element <" + e.getName()
624                                 + "> found in <main>");
625             }
626         }
627     }
628
629     /*
630      * (non-Javadoc)
631      *
632      * @see com.sslexplorer.extensions.ExtensionType#descriptorCreated(org.jdom.Element)
633      */

634     public void descriptorCreated(Element element, SessionInfo session)
635             throws IOException JavaDoc {
636     }
637
638     /*
639      * (non-Javadoc)
640      *
641      * @see com.sslexplorer.extensions.ExtensionType#getTypeBundle()
642      */

643     public String JavaDoc getTypeBundle() {
644         return "applications";
645     }
646
647     /*
648      * (non-Javadoc)
649      *
650      * @see com.sslexplorer.applications.ApplicationLauncherType#isServiceSide()
651      */

652     public boolean isServerSide() {
653         return true;
654     }
655 }
Popular Tags