KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > lib > deployment > DeploymentLoader


1 /*
2  * CoadunationLib: The coaduntion implementation library.
3  * Copyright (C) 2006 Rift IT Contracting
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * XMLConfigurationException.java
20  *
21  * DeploymentLoader.java
22  *
23  * This class is reponsible for loading the Coaduncation jar files so that they
24  * can be deployed within Coadunation.
25  */

26
27 // package
28
package com.rift.coad.lib.deployment;
29
30 // class imports
31
import java.lang.ClassLoader JavaDoc;
32 import java.io.*;
33 import java.io.File JavaDoc;
34 import java.io.InputStream JavaDoc;
35 import java.io.OutputStream JavaDoc;
36 import java.io.FileInputStream JavaDoc;
37 import java.io.FileOutputStream JavaDoc;
38 import java.net.URL JavaDoc;
39 import java.net.URLClassLoader JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.Map JavaDoc;
43
44 // logging import
45
import org.apache.log4j.Logger;
46
47 // coadunation imports
48
import com.rift.coad.lib.common.ClassUtil;
49 import com.rift.coad.lib.common.FileUtil;
50 import com.rift.coad.lib.common.JarUtil;
51 import com.rift.coad.lib.common.RandomGuid;
52 import com.rift.coad.lib.common.ResourceReader;
53 import com.rift.coad.lib.configuration.Configuration;
54 import com.rift.coad.lib.configuration.ConfigurationFactory;
55 import com.rift.coad.lib.deployment.rmi.TieGenerator;
56 import com.rift.coad.lib.loader.MasterClassLoader;
57 import com.rift.coad.lib.thirdparty.ant.CopyFile;
58 import com.rift.coad.lib.thirdparty.ant.JAR;
59 import com.rift.coad.lib.thirdparty.ant.JavaC;
60 import com.rift.coad.lib.thirdparty.ant.RMIC;
61
62 /**
63  *
64  * @author Brett Chaldecott
65  */

66 public class DeploymentLoader {
67     
68     /**
69      * This class is responsible for supplying a lookup mechanism for stub code
70      * files based on the class loader that loaded them.
71      */

72     public static class ClassLoaderLookup {
73         // the class singleton
74
private static ClassLoaderLookup singleton = null;
75         
76         // private member variables
77
private Map JavaDoc lookupMap = new HashMap JavaDoc();
78         
79         /**
80          * The constructor of the class loader lookup
81          */

82         private ClassLoaderLookup() {
83             
84         }
85         
86         
87         /**
88          * This method returns a singleton reference and creates one if it does
89          * not exist.
90          *
91          * @return a reference to the class loader lookup singleton.
92          */

93         public static synchronized ClassLoaderLookup getInstance() {
94             if (singleton == null) {
95                 singleton = new ClassLoaderLookup();
96             }
97             return singleton;
98         }
99         
100         
101         /**
102          * This method adds a class loader to the list.
103          *
104          * @param loader The reference to the loader to add.
105          */

106         protected void addClassLoader(DeploymentLoader loader) {
107             lookupMap.put(loader.getClassLoader(),
108                     loader.getClientStubCodeName());
109         }
110         
111         
112         /**
113          * This method removes an entry from the class loader map.
114          *
115          * @param loader The loader to remove.
116          */

117         protected void removeClassLoader(DeploymentLoader loader) {
118             lookupMap.remove(loader.getClassLoader());
119         }
120         
121         
122         /**
123          * This method returns the stub code name for the supplied loader.
124          *
125          * @return The name of stub code file for the supplied loader.
126          * @param loader The name of the loader.
127          */

128         public String JavaDoc getStubCodeForLoader(ClassLoader JavaDoc loader) {
129             return (String JavaDoc)lookupMap.get(loader);
130         }
131         
132     }
133
134     // the class constants
135
public static final String JavaDoc META_FILE = "META-INF/coadunation.xml";
136     public static final String JavaDoc TEMP_DIRECTORY = "temp_dir";
137     private static final String JavaDoc PREFIX = "tmp";
138     private static final String JavaDoc SUFFIX = ".jar";
139     private static final String JavaDoc CLIENT_STUB = "Client_Stub";
140     private static final String JavaDoc SUB_SUFFIX = "_Stub" + SUFFIX;
141     
142     // the class log variable
143
protected Logger log =
144             Logger.getLogger(DeploymentLoader.class.getName());
145     
146     // The classes member variabable
147
private Configuration config = null;
148     private File JavaDoc file = null;
149     private File JavaDoc tmpDir = null;
150     private URLClassLoader JavaDoc classLoader = null;
151     private DeploymentInfo deploymentInfo = null;
152     private long lastModified = 0;
153     private boolean successful = false;
154     private String JavaDoc clientStubCodeName = null;
155     
156     /**
157      * Creates a new instance of DeploymentLoader
158      *
159      * @param file The file to load.
160      * @exception DeploymentException
161      */

162     public DeploymentLoader(File JavaDoc file) throws DeploymentException {
163         try {
164             // instanciate the URLClass loader
165
this.file = file;
166             lastModified = file.lastModified();
167             
168             // retrieve the configuration
169
config = ConfigurationFactory.getInstance().
170                     getConfig(this.getClass());
171             
172             // create the temporary file
173
tmpDir = createTmpDir(file);
174             
175             // create stubs
176
createStubs(tmpDir);
177             
178             // list the contents of the directory
179
File JavaDoc[] jars = FileUtil.filter(tmpDir.listFiles(),".jar");
180             
181             // url load list
182
URL JavaDoc[] urlList = new URL JavaDoc[jars.length + 1];
183             urlList[0] = tmpDir.toURL();
184             log.info("Load url :" + tmpDir.toURL());
185             for (int index = 0; index < jars.length; index++) {
186                 log.info("Load url :" + jars[index].toURL().toString());
187                 urlList[index + 1] = jars[index].toURL();
188             }
189             
190             // load the temporary file
191
classLoader = new URLClassLoader JavaDoc(urlList,
192                     MasterClassLoader.getInstance().getLoader());
193             
194             // retrieve the coadunation.xml file from the meta base directory
195
String JavaDoc xmlSource = new ResourceReader(META_FILE,classLoader)
196             .getDocument();
197             
198             // parse the coadunation file
199
CoadunationParser xmlParser = new CoadunationParser(xmlSource);
200             deploymentInfo = xmlParser.getDeploymentInfo();
201             
202             // set the successful flag appropriatly
203
successful = true;
204             
205             // add a reference to the class loader lookup
206
ClassLoaderLookup.getInstance().addClassLoader(this);
207         } catch (Exception JavaDoc ex) {
208             log.error("Failed to load the file [" +
209                     file.toString() + "] :" + ex.getMessage(),ex);
210         }
211     }
212     
213     
214     /**
215      * The getter method for the file object.
216      *
217      * @return The file of the deployment loader.
218      */

219     public File JavaDoc getFile() {
220         return file;
221     }
222     
223     
224     /**
225      * This method returns the temporary directory loaded by this object.
226      *
227      * @return The temporary file object loaded by this object.
228      */

229     public File JavaDoc getTmpDir() {
230         return tmpDir;
231     }
232     
233     
234     /**
235      * This method will retrieve the stored last modified time.
236      *
237      * @return The long containing the last modified time of the file when it
238      * was loaded into memory.
239      */

240     public long getLastModified() {
241         return lastModified;
242     }
243     
244     
245     /**
246      * Retrieve the deployment information for this bean.
247      *
248      * @return The reference to the deployment information for this jar.
249      */

250     public DeploymentInfo getDeploymentInfo() {
251         return deploymentInfo;
252     }
253     
254     
255     /**
256      * This method will return a reference to the requested class.
257      *
258      * @return The reference to the loaded class.
259      * @param className The name of the class to load into memory.
260      * @exception DeploymentException
261      */

262     public Class JavaDoc getClass(String JavaDoc className) throws DeploymentException {
263         try {
264             return classLoader.loadClass(className);
265         } catch (Exception JavaDoc ex) {
266             throw new DeploymentException("Failed to load the class : " +
267                     className,ex);
268         }
269     }
270     
271     
272     /**
273      * The method to retrieve the class loader.
274      *
275      * @return The reference to the class loader.
276      */

277     public ClassLoader JavaDoc getClassLoader() {
278         return classLoader;
279     }
280     
281     
282     /**
283      * This method returns true if this object has been sucessfully loaded.
284      *
285      * @return TRUE if successfully loaded FALSE if not.
286      */

287     public boolean getSuccessful() {
288         return successful;
289     }
290     
291     /**
292      * This method returns the name of the client stub code file.
293      *
294      * @return The string containing the name of the client stub code file.
295      */

296     public String JavaDoc getClientStubCodeName() {
297         return clientStubCodeName;
298     }
299     
300     
301     /**
302      * This method returns the hash code for this object which is based on the
303      * file path.
304      *
305      * @return The hash code for this object based on the file path.
306      */

307     public int hashCode() {
308         return file.getPath().hashCode();
309     }
310     
311     
312     /**
313      * This method determines if the deployment loader contains the same values.
314      *
315      * @return TRUE if they point at the same file, FALSE if not.
316      * @param obj The object to perform the comparison on.
317      */

318     public boolean equals(Object JavaDoc obj) {
319         if (!(obj instanceof DeploymentLoader)) {
320             return false;
321         }
322         DeploymentLoader loader = (DeploymentLoader)obj;
323         if (null == loader) {
324             return false;
325         }
326         if (loader.getFile().getPath().equals(file.getPath())) {
327             return true;
328         }
329         return false;
330     }
331     
332     
333     /**
334      * This method will generate a temporary file using the source file.
335      *
336      * @return The path to the newly created temporary file.
337      */

338     private File JavaDoc createTmpDir(File JavaDoc source) throws DeploymentException {
339         try {
340             File JavaDoc tmpDir = new File JavaDoc(config.getString(TEMP_DIRECTORY),
341                     RandomGuid.getInstance().getGuid());
342             if (tmpDir.mkdirs() == false) {
343                 throw new DeploymentException("Failed to create the director ["
344                         + tmpDir.getAbsolutePath() + "]");
345             }
346             JarUtil.extract(source,tmpDir);
347             return tmpDir;
348         } catch (DeploymentException ex) {
349             throw ex;
350         } catch (Exception JavaDoc ex) {
351             log.error("Failed to create the temporary directory : " +
352                     ex.getMessage(),ex);
353             throw new DeploymentException(
354                     "Failed to create the temporary directory : " +
355                     ex.getMessage(), ex);
356         }
357     }
358     
359     
360     /**
361      * This method creates the stub code for the deployment loader.
362      *
363      * @param tmpDir The directory in which all the class from which the stub
364      * code is required can be found
365      * @exception DeploymentException
366      */

367     private void createStubs(File JavaDoc tmpDir) throws DeploymentException {
368         try {
369             File JavaDoc stubDir = new File JavaDoc(tmpDir,
370                     RandomGuid.getInstance().getGuid());
371             if (stubDir.mkdirs() == false) {
372                 throw new DeploymentException("Failed to create the stub " +
373                         "directory [" + stubDir.getAbsolutePath() + "]");
374             }
375             
376             // jars
377
File JavaDoc[] jars = FileUtil.filter(tmpDir.listFiles(),".jar");
378             
379             // url load list
380
File JavaDoc[] classPath = new File JavaDoc[jars.length + 2];
381             classPath[0] = tmpDir;
382             for (int index = 0; index < jars.length; index++) {
383                 classPath[index + 1] = jars[index];
384             }
385             classPath[classPath.length - 1] = stubDir;
386             
387             createTies(tmpDir,tmpDir,stubDir);
388             
389             /*
390             This is not required as the RMI class loader will take car of it.
391             // list the contents of the directory
392             for (int index = 0; index < jars.length; index++) {
393                 createTies(tmpDir,jars[index],stubDir);
394             }*/

395             
396             // compile the ties
397
JavaC javaC = new JavaC(classPath,stubDir,stubDir);
398             javaC.compileClasses();
399             
400             // create the RMI stubs
401
RMIC rmic = new RMIC(classPath,stubDir,"**/*.class",stubDir);
402             rmic.parse();
403             
404             // create the jar
405
String JavaDoc clientFileName = file.getName();
406             clientFileName = clientFileName.substring(0,
407                     clientFileName.indexOf('.')) + SUB_SUFFIX;
408             File JavaDoc stubJar = new File JavaDoc(tmpDir.getPath() +
409                     File.separator + clientFileName);
410             JAR jar = new JAR(stubDir,stubJar);
411             jar.archive();
412             
413             File JavaDoc clientStubJar = new File JavaDoc(config.getString(CLIENT_STUB) +
414                     File.separator + clientFileName);
415             CopyFile copyFile = new CopyFile(stubJar,clientStubJar);
416             copyFile.copy();
417             clientStubCodeName = clientFileName;
418         } catch (Exception JavaDoc ex) {
419             log.error("Failed to create the stub : " + ex.getMessage(),
420                     ex);
421             throw new DeploymentException(
422                     "Failed to create the stub : " + ex.getMessage(),
423                     ex);
424         }
425     }
426     
427     
428     /**
429      * This method creates stub for the given path in a the supplied stub dir.
430      *
431      * @param tmpDir The temporary directory.
432      * @param path The path to use to create the entry from.
433      * @param stubDir The stub directory to use.
434      * @exception DeploymentException
435      */

436     private void createTies(File JavaDoc tmpDir, File JavaDoc path,
437             File JavaDoc stubDir) throws DeploymentException {
438         try {
439             // load the temporary file
440
URLClassLoader JavaDoc classLoader = new URLClassLoader JavaDoc(new URL JavaDoc[]
441                     {path.toURL()},MasterClassLoader.getInstance().getLoader());
442             
443             // perform the check
444
if (classLoader.getResource(META_FILE) == null) {
445                 // this is not a coadunation entry ignore
446
return;
447             }
448             
449             // retrieve the coadunation.xml file from the meta base directory
450
String JavaDoc xmlSource = new ResourceReader(META_FILE,classLoader).
451                     getDocument();
452             
453             // parse the coadunation file
454
CoadunationParser xmlParser = new CoadunationParser(xmlSource);
455             DeploymentInfo deploymentInfo = xmlParser.getDeploymentInfo();
456             
457             // loop through the entry set
458
Map JavaDoc beans = deploymentInfo.getBeans();
459             Iterator JavaDoc iter = beans.keySet().iterator();
460             while(iter.hasNext()) {
461                 BeanInfo beanInfo = (BeanInfo)beans.get(iter.next());
462                 TieGenerator tieGenerator = new TieGenerator(tmpDir,stubDir,
463                         beanInfo);
464                 tieGenerator.generate();
465             }
466             
467             beans = deploymentInfo.getJmxBeans();
468             iter = beans.keySet().iterator();
469             while(iter.hasNext()) {
470                 JMXBeanInfo beanInfo = (JMXBeanInfo)beans.get(iter.next());
471                 TieGenerator tieGenerator = new TieGenerator(tmpDir,stubDir,
472                         beanInfo);
473                 tieGenerator.generate();
474             }
475             
476         } catch (Exception JavaDoc ex) {
477             log.error("Failed to create the ties for [" + path.getPath()
478                     + "] because : " + ex.getMessage(), ex);
479             throw new DeploymentException(
480                     "Failed to create the ties for [" + path.getPath()
481                     + "] because : " + ex.getMessage(), ex);
482         }
483     }
484     
485 }
486
Popular Tags