KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ve > luz > ica > jackass > tools > Preprocessor


1 /*
2  * Copyright (c) 2003 by The Jackass Team
3  * Licensed under the Open Software License version 2.0
4  */

5 package ve.luz.ica.jackass.tools;
6
7 import java.io.*;
8 import java.util.HashSet JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.Set JavaDoc;
11 import java.util.zip.ZipEntry JavaDoc;
12 import java.util.zip.ZipFile JavaDoc;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16
17 import ve.luz.ica.jackass.deploy.util.Application;
18 import ve.luz.ica.jackass.deploy.util.Component;
19 import ve.luz.ica.jackass.deploy.descriptor.ica.IcaJackassApplication;
20 import ve.luz.ica.jackass.deploy.descriptor.standard.JackassApplication;
21 import ve.luz.ica.util.ZipUtil;
22
23 /**
24  * The preprocessor processes the Jackass application file to generate
25  * the application server side stubs
26  * @author carlos
27  */

28 public final class Preprocessor
29 {
30     private static final Log LOG = LogFactory.getLog(Preprocessor.class);
31
32     private static final String JavaDoc JAR_FILE_PREFIX = "jackass-";
33     private static final String JavaDoc JAR_EXTENSION = ".jar";
34     private static final String JavaDoc PREPROCESSOR_DIRECTORY = "jackass-preprocessor";
35     private static final String JavaDoc TEMP_DIR_PROPERTY = "java.io.tmpdir";
36     private static final char PERIOD = '.';
37     private static final char SLASH = '/';
38     private static final String JavaDoc PERIOD_STRING = ".";
39     private static final String JavaDoc SLASH_STRING = "/";
40
41     private static final String JavaDoc PUBLIC_VOID_DELEGATE = "public void _delegate";
42     private static final String JavaDoc PUBLIC_KEYWORD = "public ";
43     private static final String JavaDoc PROXY_SUFFIX = "Proxy";
44     private static final String JavaDoc POATIE_SUFFIX = "POATie";
45     private static final String JavaDoc OPERATIONS_SUFFIX = "Operations";
46     //private static final String IDL_INTERFACE_SUFFIX = ":1.0";
47
private static final String JavaDoc PROXY_FILE_SUFFIX = "Proxy.java";
48     private static final String JavaDoc POATIE_FILE_SUFFIX = "POATie.java";
49     //private static final String IDL_INTERFACE_PREFIX = "IDL:";
50

51     private static final String JavaDoc BIN_DIR = "bin";
52     private static final String JavaDoc IDL_DIR = "idl";
53
54     private static final String JavaDoc IDL_COMPILER_COMMAND1 = "idlj -fall -td ";
55     private static final String JavaDoc IDL_COMPILER_COMMAND2 = "idlj -fserverTIE -td ";
56     private static final String JavaDoc JAR_COMMAND = "jar -cf ";
57     private static final String JavaDoc ZIP_UPDATE_COMMAND = "jar -uMf ";
58
59     private static String JavaDoc[] javacCommand = {
60         File.separator.equals(SLASH_STRING) ? "sh" : "cmd",
61         File.separator.equals(SLASH_STRING) ? "-c" : "/C",
62         "javac -classpath " + System.getProperty("java.class.path", PERIOD_STRING) + " -d ",
63     };
64
65     private String JavaDoc preprocessorDir = null;
66     private String JavaDoc zipFileName = null;
67     private Runtime JavaDoc runtime = null;
68
69     /**
70      * Deploys an application
71      * @param args the command line parameters
72      */

73     public static void main(String JavaDoc[] args)
74     {
75         try
76         {
77             if (args.length < 1)
78             {
79                 System.out.println("Usage: preprocessor <deployment file name>");
80                 return;
81             }
82
83             if (LOG.isDebugEnabled()) LOG.info("Preprocessing " + args[0]);
84
85             String JavaDoc tempDir = System.getProperty(TEMP_DIR_PROPERTY);
86             if (LOG.isDebugEnabled()) LOG.debug("Temp.dir "+tempDir);
87             File JavaDoc tempDirFile = new File JavaDoc(tempDir, PREPROCESSOR_DIRECTORY);
88             tempDirFile.mkdir();
89             tempDirFile.deleteOnExit();
90             Preprocessor pr = new Preprocessor(tempDirFile.getPath(), args[0]);
91             pr.process();
92             deleteFile(tempDirFile);
93
94             if (LOG.isDebugEnabled()) LOG.info("Preprocessing complete");
95         }
96         catch (Exception JavaDoc e)
97         {
98             if (LOG.isDebugEnabled())
99             {
100                 LOG.error("Error ", e);
101             }
102             else
103             {
104                 LOG.error("Error processing the file", e);
105             }
106         }
107
108     }
109
110     /**
111      * Recursively delete the temporary working directory
112      * @param file the file representing the temporary directory
113      */

114     private static void deleteFile(File JavaDoc file)
115     {
116         if (file.isDirectory())
117         {
118             File JavaDoc[] fileList = file.listFiles();
119             for (int i = 0; i<fileList.length; ++i)
120             {
121                 deleteFile(fileList[i]);
122             }
123         }
124         file.delete();
125     }
126
127     /**
128      * Class constructor
129      * @param workingDir the path string for the temporary directory
130      * @param zipFile the application zip file path
131      */

132     private Preprocessor(String JavaDoc workingDir, String JavaDoc zipFile)
133     {
134         this.preprocessorDir = workingDir;
135         this.zipFileName = zipFile;
136         runtime = Runtime.getRuntime();
137     }
138
139     /**
140      * This method does the preprocessor work
141      */

142     private void process()
143     {
144         try
145         {
146             ZipFile JavaDoc zip = new ZipFile JavaDoc(zipFileName);
147
148             // parse deployment descriptor
149
ZipEntry JavaDoc entry = zip.getEntry(Application.STANDARD_DESCRIPTOR_NAME);
150             if (entry == null)
151             {
152                 System.out.println("No standard deployment descriptor present: deployment.xml");
153                 return;
154             }
155             InputStream sis = new BufferedInputStream(zip.getInputStream(entry));
156             entry = zip.getEntry(Application.ICA_DESCRIPTOR_NAME);
157             if (entry == null)
158             {
159                 System.out.println("No ica deployment descriptor present: ica.xml");
160                 return;
161             }
162             InputStream iis = new BufferedInputStream(zip.getInputStream(entry));
163
164             Reader standardReader = new InputStreamReader(sis);
165             Reader icaReader = new InputStreamReader(iis);
166             JackassApplication jackApp = JackassApplication.unmarshal(standardReader);
167             IcaJackassApplication icaApp = IcaJackassApplication.unmarshal(icaReader);
168             Application app = new Application(jackApp, icaApp);
169
170             // extract and compile idl files
171
this.compileIdlFiles(zip);
172             Set JavaDoc javaPathSet = this.generateProxies(app);
173             File JavaDoc binDirFile = new File JavaDoc(preprocessorDir, BIN_DIR);
174             this.compileJavaFiles(javaPathSet, binDirFile);
175             String JavaDoc jarFileName = this.generateJarFile(app, binDirFile);
176             this.addJarToZip(jarFileName);
177         }
178         catch (Exception JavaDoc e)
179         {
180             System.out.println(e.getMessage());
181             if (LOG.isDebugEnabled()) LOG.debug(e);
182         }
183     }
184
185     /**
186      * This method extracts and compiles the Corba IDL files stored
187      * in the idl directory within the zip file
188      * @param zip the application zip file
189      * @throws IOException thrown if there is an IO problem
190      */

191     void compileIdlFiles(ZipFile JavaDoc zip) throws Exception JavaDoc
192     {
193         // verify that there is an idl directory
194
ZipEntry JavaDoc entry = zip.getEntry(IDL_DIR);
195         if (entry == null)
196         {
197             throw new Exception JavaDoc("No idl directory present");
198         }
199
200         File JavaDoc idlDirFile = new File JavaDoc(preprocessorDir, IDL_DIR);
201         File JavaDoc preprocessorFile = new File JavaDoc(preprocessorDir);
202
203         // extract the idl files from the zip file
204
ZipUtil.extractFiles(zip, preprocessorFile, IDL_DIR);
205         File JavaDoc[] idlFiles = idlDirFile.listFiles();
206
207         // verify that there is at least one idl file
208
if (idlFiles.length == 0)
209         {
210             throw new Exception JavaDoc("No IDL files present");
211         }
212
213         // compile the idl files
214
for (int i = 0; i<idlFiles.length; ++i)
215         {
216             String JavaDoc idlFile = idlFiles[i].getPath();
217
218             if (LOG.isDebugEnabled()) LOG.debug(idlFile);
219
220             // compile the idl files
221
String JavaDoc line = null;
222             Process JavaDoc p = runtime.exec(IDL_COMPILER_COMMAND1 + preprocessorDir + " " + idlFile);
223             BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
224             while ((line = input.readLine()) != null)
225             {
226                 System.out.println(line);
227             }
228
229             input.close();
230
231             // compile the idl files again to generate the tie classes
232
p = runtime.exec(IDL_COMPILER_COMMAND2 + preprocessorDir + " " + idlFile);
233             input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
234             while ((line = input.readLine()) != null)
235             {
236                 System.out.println(line);
237             }
238
239             input.close();
240         }
241     }
242
243     /**
244      * Generate the proxy classes for each component
245      * @param app an object containing the application data stored in the XML deployment
246      * descriptor
247      * @return A set of path names for every directory containing java files
248      * that must later be compiled with the java compiler
249      * @throws IOException thrown if there is an IO problem
250      */

251     private Set JavaDoc generateProxies(Application app) throws Exception JavaDoc
252     {
253         Set JavaDoc javaPathSet = new HashSet JavaDoc();
254
255         // For each component generate a proxy class
256
Iterator JavaDoc components = app.getComponents();
257         while (components.hasNext())
258         {
259             Component comp = (Component) components.next();
260             String JavaDoc interfaceName = comp.getInterface();
261             String JavaDoc interfacePath = preprocessorDir+File.separator+interfaceName.replace(PERIOD, SLASH);
262             String JavaDoc interfaceFileName = interfacePath.substring(interfacePath.lastIndexOf(SLASH)+1);
263             interfacePath = interfacePath.substring(0, interfacePath.lastIndexOf(SLASH));
264
265             // add path to path set for later compilation with javac
266
javaPathSet.add(interfacePath);
267
268             //String fn = fileName.substring(fileName.lastIndexOf(File.separator)+1);
269
File JavaDoc tieFile = new File JavaDoc(interfacePath, interfaceFileName + POATIE_FILE_SUFFIX);
270             if (!tieFile.exists())
271             {
272                 throw new Exception JavaDoc("File " + interfaceFileName + POATIE_FILE_SUFFIX + " not found");
273             }
274             FileReader fr = new FileReader(tieFile);
275             LineNumberReader lr = new LineNumberReader(fr);
276
277             // generate proxy class source file
278
File JavaDoc proxyFile = new File JavaDoc(interfacePath, interfaceFileName + PROXY_FILE_SUFFIX);
279             FileWriter fw = new FileWriter(proxyFile);
280             PrintWriter pw = new PrintWriter(fw);
281             if (LOG.isDebugEnabled())
282             {
283                 LOG.debug("Generating proxy file " + proxyFile.getPath());
284                 LOG.debug("Interface name " + interfaceName);
285             }
286             this.generateProxy(lr, pw, interfaceName, interfaceFileName);
287         }
288         return javaPathSet;
289     }
290
291     /**
292      * Generate the source code for a component's proxy class
293      * @param input an input stream on the source file for the TIE class
294      * generated by the IDL compiler for the component
295      * @param output an output stream on the source file for the generated
296      * proxy class
297      * @param qualifiedInterfaceName the fully qualified component interface name
298      * @param interfaceName the component interface name
299      * @throws IOException if there is an IO error
300      */

301     private void generateProxy(LineNumberReader input, PrintWriter output, String JavaDoc qualifiedInterfaceName,
302             String JavaDoc interfaceName) throws IOException
303     {
304         String JavaDoc interfaceOperations = qualifiedInterfaceName + OPERATIONS_SUFFIX;
305         String JavaDoc tieClass = interfaceName + POATIE_SUFFIX;
306         String JavaDoc proxyClass = interfaceName + PROXY_SUFFIX;
307         if (LOG.isDebugEnabled())
308         {
309             LOG.debug(interfaceOperations);
310             LOG.debug(tieClass);
311         }
312         boolean constructorGenerated = false;
313         boolean setMethodGenerated = false;
314         String JavaDoc line = input.readLine();
315         while (line != null)
316         {
317             String JavaDoc processedLine = null;
318             int index = 0;
319
320             // generate a constructor that takes a generic corba Object parameter
321
// and narrows it to the proper type
322
if (!constructorGenerated)
323             {
324                 index = line.indexOf(PUBLIC_KEYWORD + tieClass);
325                 if (index != -1)
326                 {
327                     output.println(" public " + proxyClass + "(org.omg.CORBA.Object delegate) {");
328                     output.println(" this._impl = " + qualifiedInterfaceName + "Helper.narrow(delegate);");
329                     output.println(" }");
330                     constructorGenerated = true;
331                 }
332             }
333
334             // generate a set method that takes a generic corba Object parameter
335
// and narrows it to the proper type
336
if (!setMethodGenerated)
337             {
338                 index = line.indexOf(PUBLIC_VOID_DELEGATE);
339                 if (index != -1)
340                 {
341                     output.println(" public void _delegate(org.omg.CORBA.Object delegate) {");
342                     output.println(" this._impl = " + qualifiedInterfaceName + "Helper.narrow(delegate);");
343                     output.println(" }");
344                     setMethodGenerated = true;
345                 }
346             }
347
348             // substitute the java Operations interface for the corba interface
349
index = line.indexOf(interfaceOperations);
350             if (index == -1)
351             {
352                 processedLine = line;
353             }
354             else
355             {
356                 processedLine = line.substring(0, index) + qualifiedInterfaceName +
357                         line.substring(index+interfaceOperations.length());
358             }
359
360             // change the class name sufix from "POATie" to "Proxy"
361
index = processedLine.indexOf(tieClass);
362             if (index != -1)
363             {
364                 processedLine = processedLine.substring(0, index) +
365                         proxyClass + processedLine.substring(index+tieClass.length());
366             }
367             output.println(processedLine);
368             line = input.readLine();
369         }
370         input.close();
371         output.close();
372     }
373
374     /**
375      * Compile the stub java files
376      * @param javaPathSet a set containing a string representing the path
377      * name for every directory containing java source files
378      * that must be compiled
379      * @param binDirFile a File object representing the directory where the
380      * binary class files will be stored
381      * @throws IOException thrown if there is an IO problem
382      */

383     void compileJavaFiles(Set JavaDoc javaPathSet, File JavaDoc binDirFile) throws IOException
384     {
385         binDirFile.mkdir();
386         Iterator JavaDoc sourcePaths = javaPathSet.iterator();
387         while (sourcePaths.hasNext())
388         {
389             // compile with javac
390
String JavaDoc sourcePath = (String JavaDoc) sourcePaths.next();
391             javacCommand[2] = javacCommand[2] + binDirFile.getPath() + " " +sourcePath + "/*.java";
392             if (LOG.isDebugEnabled()) LOG.debug("Compiling " + javacCommand[2]);
393             String JavaDoc line = null;
394             Process JavaDoc p = runtime.exec(javacCommand);
395             BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
396             while ((line = input.readLine()) != null)
397             {
398                 System.out.println(line);
399             }
400             input.close();
401         }
402     }
403
404     /**
405      * Generates a jar file containing the compiled stub classes
406      * @param app an object containing the application's deployemnt data
407      * @param binDirFile the directory containing the binary class files
408      * @return the path to the generated jar file
409      * @throws IOException thrown if there is an IO problem
410      */

411     private String JavaDoc generateJarFile(Application app, File JavaDoc binDirFile) throws IOException
412     {
413         // generate jar file
414
String JavaDoc jarFileName = JAR_FILE_PREFIX + app.getName() + JAR_EXTENSION;
415         File JavaDoc jarFile = new File JavaDoc(preprocessorDir, jarFileName);
416         String JavaDoc jarFilePath = jarFile.getPath();
417         String JavaDoc jarCommand = JAR_COMMAND + jarFilePath + " -C " + binDirFile.getPath();
418         String JavaDoc[] jarList = binDirFile.list();
419         for (int i = 0; i<jarList.length; ++i)
420         {
421             jarCommand = jarCommand + " " + jarList[i];
422         }
423         if (LOG.isDebugEnabled())
424         {
425             LOG.debug("Command: " + jarCommand);
426         }
427         String JavaDoc line = null;
428         Process JavaDoc p = runtime.exec(jarCommand);
429         BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
430         while ((line = input.readLine()) != null)
431         {
432             System.out.println(line);
433         }
434         input.close();
435         return jarFileName;
436     }
437
438     /**
439      * Add the generated stub jar file to the application zip file
440      * @param jarFileName the jar file name
441      * @throws IOException thrown if there is an IO problem
442      */

443     private void addJarToZip(String JavaDoc jarFileName) throws IOException
444     {
445         // put jar file in the application zip file
446
String JavaDoc line = null;
447         String JavaDoc zipCommand = ZIP_UPDATE_COMMAND + zipFileName + " -C " + preprocessorDir + " " + jarFileName;
448         Process JavaDoc p = runtime.exec(zipCommand);
449         BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
450         while ((line = input.readLine()) != null)
451         {
452             System.out.println(line);
453         }
454         input.close();
455     }
456 }
457
Popular Tags