KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > tools > enhancer > Enhancer


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.tools.enhancer;
13
14 import com.versant.core.common.config.ConfigInfo;
15 import com.versant.core.common.config.ConfigParser;
16 import com.versant.core.jdo.tools.enhancer.info.ClassInfo;
17 import com.versant.core.jdo.tools.enhancer.info.FieldInfo;
18 import com.versant.core.jdo.tools.enhancer.utils.MetaDataToInfoMapper;
19 import com.versant.core.jdo.tools.enhancer.utils.SwapFieldHelper;
20 import com.versant.core.metadata.ClassMetaData;
21 import com.versant.core.metadata.ModelMetaData;
22 import com.versant.core.storagemanager.StorageManagerFactory;
23 import com.versant.core.storagemanager.StorageManagerFactoryBuilder;
24 import com.versant.core.util.BeanUtils;
25
26 import java.io.File JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.*;
29
30 /**
31  * The Enhancer class is used for enhancing .class files,
32  * to implement the Persistence Capable interfase.
33  * It can also be used from the command line.
34  */

35 public class Enhancer {
36
37     private ClassEnhancer classEnhancer;
38     private FieldRefEnhancer fieldRefEnhancer;
39     private List classes = new ArrayList();
40     private HashMap classResourceMap = new HashMap(); // class name -> res name
41
private MetaDataToInfoMapper classInfoUtil;
42     private HashMap classMetaDataMap = new HashMap();
43     private ModelMetaData metaData = null;
44     protected Config cfg = new Config();
45
46     private Set scopeFiles = new HashSet();
47     private Set queriesFiles = new HashSet();
48     private File JavaDoc outputDirectory;
49     private ClassLoader JavaDoc classLoader;
50     private String JavaDoc propertiesResourceName;
51     private File JavaDoc propertiesFile;
52     private boolean genHyper = false;
53     private boolean makeFieldsPrivate = false;
54     private boolean detached = true;
55     private File JavaDoc hyperdriveDir;
56     private File JavaDoc srcOutDir;
57     private boolean genSrc;
58
59     public Enhancer() {}
60
61     public static class Config {
62
63         public String JavaDoc outputDir;
64         public String JavaDoc inputDir;
65         public boolean h = false;
66         public String JavaDoc hyperDir;
67         public boolean genSrc = false;
68         public String JavaDoc srcOutputDir;
69         public boolean d = true;
70
71
72         public static final String JavaDoc HELP_outputDir =
73                 "The output directory where the enhanced classes must be writen to " +
74                 "(If not set then the classes will be written where they are found).";
75         public static final String JavaDoc HELP_hyperDir =
76                 "The output directory where the hyperdrive classes must be writen to.";
77         public static final String JavaDoc HELP_inputDir =
78                 "The Persistence Aware files. " +
79                 "These are normal classes (i.e. NOT Persistence Capable classes) that " +
80                 "reference the persistence capable classes fields directly.";
81         public static final String JavaDoc HELP_h =
82                 "generate hyperdrive classes at compile time.";
83         public static final String JavaDoc HELP_srcOutputDir =
84                 "The place where the hyperdrive src files must be written to.";
85         public static final String JavaDoc HELP_d =
86                 "enhanced for detach (true by default).";
87         public static final String JavaDoc HELP_genSrc =
88                 "The directory where the hyperdrive src files must be written to.";
89
90
91     }
92
93     public static void main(String JavaDoc[] args) {
94         Enhancer server = new Enhancer();
95         BeanUtils.CmdLineResult res = null;
96         try {
97             res = BeanUtils.processCmdLine(args,
98                     server.getClass().getClassLoader(), server.cfg, null,
99                     "Enhancer", "The JDO class enhancer",
100                     true);
101         } catch (IllegalArgumentException JavaDoc e) {
102             // error message has already been printed
103
System.exit(1);
104         }
105         try {
106
107             ArrayList scopeFiles = new ArrayList();
108             if (server.cfg.inputDir != null) {
109                 StringTokenizer tokenizer = new StringTokenizer(server.cfg.inputDir,",",false);
110                 while(tokenizer.hasMoreTokens()){
111                     scopeFiles.add(new File JavaDoc(tokenizer.nextToken()));
112                 }
113             }
114
115             if (server.cfg.srcOutputDir != null){
116                 server.cfg.genSrc = true;
117             }
118
119             server.rumCommandLine(res.properties, server.cfg.outputDir, scopeFiles,
120                     null, server.cfg.h, false, server.cfg.d, server.cfg.hyperDir,
121                     server.cfg.genSrc, server.cfg.srcOutputDir);
122         } catch (Exception JavaDoc e) {
123             e.printStackTrace();
124             System.exit(1);
125         }
126     }
127
128
129     /**
130      * Gets the classloader
131      *
132      * @return
133      */

134     public ClassLoader JavaDoc getClassLoader() {
135         return classLoader;
136     }
137
138     /**
139      * Sets a classloader for loading all the files.
140      *
141      * @param classLoader
142      */

143     public void setClassLoader(ClassLoader JavaDoc classLoader) {
144         this.classLoader = classLoader;
145     }
146
147     /**
148      * Is the persistent capable classes enhanced for detached behavior.
149      *
150      * @return
151      */

152     public boolean isDetached() {
153         return detached;
154     }
155
156     /**
157      * Must the persistent capable classes be enhanced for detached behavior.
158      *
159      * @param detached
160      */

161     public void setDetached(boolean detached) {
162         this.detached = detached;
163     }
164
165     /**
166      * Is Hypedrive classes generated at enhancement time.
167      *
168      * @return
169      */

170     public boolean isGenHyper() {
171         return genHyper;
172     }
173
174     /**
175      * Must Hypedrive classes be generated at enhancement time.
176      *
177      * @param genHyper
178      */

179     public void setGenHyper(boolean genHyper) {
180         this.genHyper = genHyper;
181     }
182     /**
183      * Is Hypedrive src generated at enhancement time.
184      *
185      * @return
186      */

187     public boolean isGenSrc() {
188         return genSrc;
189     }
190     /**
191      * Must Hypedrive src be generated at enhancement time.
192      *
193      * @param genSrc
194      */

195     public void setGenSrc(boolean genSrc) {
196         this.genSrc = genSrc;
197     }
198
199     public File JavaDoc getSrcOutDir() {
200         return srcOutDir;
201     }
202
203     public void setSrcOutDir(File JavaDoc srcOutDir) {
204         this.srcOutDir = srcOutDir;
205     }
206
207     /**
208      * Is (public/protected/pakage) fields made private
209      * during enhancement.
210      *
211      * @return
212      */

213     public boolean isMakeFieldsPrivate() {
214         return makeFieldsPrivate;
215     }
216
217     /**
218      * Must (public/protected/pakage) fields be made private
219      * during enhancement.
220      *
221      * @param makeFieldsPrivate
222      */

223     public void setMakeFieldsPrivate(boolean makeFieldsPrivate) {
224         this.makeFieldsPrivate = makeFieldsPrivate;
225     }
226
227     /**
228      * Get the output directory where the enhanced classes are
229      * written to.
230      *
231      * @return
232      */

233     public File JavaDoc getOutputDir() {
234         return outputDirectory;
235     }
236
237     /**
238      * Set the output directory where the enhanced classes are
239      * written to.
240      *
241      * @param outputDir
242      */

243     public void setOutputDir(File JavaDoc outputDir) {
244         this.outputDirectory = outputDir;
245     }
246
247     /**
248      * Get the .jdogenie property file
249      *
250      * @return
251      */

252     public File JavaDoc getPropertiesFile() {
253         return propertiesFile;
254     }
255
256     /**
257      * Sets the *.jdogenie property as a file.
258      *
259      * @param propertiesFile
260      */

261     public void setPropertiesFile(File JavaDoc propertiesFile) {
262         this.propertiesFile = propertiesFile;
263     }
264
265     /**
266      * Gets the *.jdogenie property file resource name
267      *
268      * @return
269      */

270     public String JavaDoc getPropertiesResourceName() {
271         return propertiesResourceName;
272     }
273
274     /**
275      * Sets the *.jdogenie property filename as a resource.
276      *
277      * @param propertiesResourceName
278      */

279     public void setPropertiesResourceName(String JavaDoc propertiesResourceName) {
280         this.propertiesResourceName = propertiesResourceName;
281     }
282
283 // public Set getQueriesFiles() {
284
// return queriesFiles;
285
// }
286
//
287
// public void setQueriesFiles(Set queriesFiles) {
288
// this.queriesFiles = queriesFiles;
289
// }
290

291     /**
292      * Persistant Aware file set as Strings
293      *
294      * @return
295      */

296     public Set getPCAwareFiles() {
297         return scopeFiles;
298     }
299
300     /**
301      * Set of resource class file names as Strings i.e.
302      * "com/bla/model/Person.class" these classes are
303      * persistent aware file, i.e. these files are NOT
304      * Persistant Capable files, they are classes that
305      * use PC classes that have public fields.
306      *
307      * @param scopeFiles
308      */

309     public void setPCAwareFiles(Set scopeFiles) {
310         this.scopeFiles = scopeFiles;
311     }
312
313     public void setHyperdriveDir(File JavaDoc hyperdriveDir){
314         this.hyperdriveDir = hyperdriveDir;
315     }
316
317     /**
318      * Enhance the files and write them to the output
319      * directory
320      *
321      * @throws Exception
322      */

323     public void enhance() throws Exception JavaDoc {
324         if (propertiesFile == null && propertiesResourceName == null) {
325             throw new Exception JavaDoc(
326                     "Either the propertiesFile or propertiesResourceName is required.");
327         }
328
329         setClassLoader(getPrivateClassLoader());
330 // if (outputDirectory == null) {
331
// throw new Exception("Output directory is required.");
332
// }
333

334         if (propertiesFile != null) {
335             start(scopeFiles, queriesFiles, outputDirectory, classLoader,
336                     propertiesFile, genHyper, makeFieldsPrivate, detached,
337                     genSrc, srcOutDir);
338         } else {
339             start(scopeFiles, queriesFiles, outputDirectory, classLoader,
340                     propertiesResourceName, genHyper, makeFieldsPrivate,
341                     detached, genSrc, srcOutDir);
342         }
343
344     }
345
346     private void rumCommandLine(Properties props, String JavaDoc outputDir,
347             ArrayList scopeFiles, ArrayList queries, boolean genHyper,
348             boolean makeFieldsPrivate, boolean detached, String JavaDoc hyperdriveDir,
349             boolean genSrc, String JavaDoc hyperSrcDir) throws Exception JavaDoc {
350         ClassLoader JavaDoc callingClassLoader = Enhancer.class.getClassLoader();
351         GrepFile grepFile = null;
352
353         try {
354             grepFile = new GrepFile(scopeFiles);
355         } catch (IOException JavaDoc e) {
356             e.printStackTrace(); //To change body of catch statement use Options | File Templates.
357
}
358
359         if (outputDir != null){
360             this.outputDirectory = new File JavaDoc(outputDir);
361         }
362
363         if (hyperdriveDir != null) {
364             this.hyperdriveDir = new File JavaDoc(hyperdriveDir);
365         }
366
367         if (hyperSrcDir != null) {
368             this.srcOutDir = new File JavaDoc(hyperSrcDir);
369         }
370         this.genSrc = genSrc;
371
372         start(grepFile.getJdoFiles(), null, outputDirectory,
373                 callingClassLoader, props, genHyper,
374                 makeFieldsPrivate, detached, genSrc, srcOutDir);
375
376     }
377
378     private void start(Set scopeFiles, Set queriesFiles, File JavaDoc outputDir,
379             ClassLoader JavaDoc callingClassLoader,
380             File JavaDoc configFile, boolean genHyper, boolean makeFieldsPrivate,
381             boolean detached, boolean genSrc, File JavaDoc srcOutDir) throws Exception JavaDoc {
382         this.genHyper = genHyper;
383         metaData = getMetaData(configFile, callingClassLoader);
384         startImp(scopeFiles, queriesFiles, outputDir, callingClassLoader,
385                 genHyper, makeFieldsPrivate, detached, genSrc, srcOutDir);
386     }
387
388     private void start(Set scopeFiles, Set queriesFiles, File JavaDoc outputDir,
389                        ClassLoader JavaDoc callingClassLoader,
390                        Properties props, boolean genHyper, boolean makeFieldsPrivate,
391                        boolean detached, boolean genSrc, File JavaDoc srcOutDir) throws Exception JavaDoc {
392         this.genHyper = genHyper;
393         metaData = getMetaData(props, callingClassLoader);
394         startImp(scopeFiles, queriesFiles, outputDir, callingClassLoader,
395                 genHyper, makeFieldsPrivate, detached, genSrc, srcOutDir);
396     }
397
398     private void start(Set scopeFiles, Set queriesFiles, File JavaDoc outputDir,
399             ClassLoader JavaDoc callingClassLoader,
400             String JavaDoc configFilename, boolean genHyper, boolean makeFieldsPrivate,
401             boolean detached, boolean genSrc, File JavaDoc srcOutDir) throws Exception JavaDoc {
402         this.genHyper = genHyper;
403         metaData = getMetaData(configFilename, callingClassLoader);
404         startImp(scopeFiles, queriesFiles, outputDir, callingClassLoader,
405                 genHyper, makeFieldsPrivate, detached, genSrc, srcOutDir);
406
407     }
408
409     private void startImp(Set scopeFiles, Set queriesFiles, File JavaDoc outputDir,
410             ClassLoader JavaDoc callingClassLoader, boolean genHyper,
411             boolean makeFieldsPrivate, boolean detached, boolean genSrc, File JavaDoc srcOutDir)
412             throws Exception JavaDoc {
413         classEnhancer = new ClassEnhancer(outputDir, callingClassLoader);
414         fieldRefEnhancer = new FieldRefEnhancer(outputDir, callingClassLoader);
415         classInfoUtil = new MetaDataToInfoMapper(classResourceMap,
416                 callingClassLoader);
417         for (int k = 0; k < metaData.classes.length; k++) {
418             ClassMetaData classMetaData = metaData.classes[k];
419             classMetaDataMap.put(classMetaData.qname, classMetaData);
420             classInfoUtil.setClassInfo(classMetaData.jdoClass, classMetaData);
421         }
422
423         classes = classInfoUtil.getClassInfoList();
424         long start = System.currentTimeMillis();
425         classEnhancer.setGetAndSettersMap(getMapOfGetAndSetters(classes));
426         ListIterator classIter = classes.listIterator();
427         int classCount = 0;
428         while (classIter.hasNext()) {
429             ClassInfo classInfo = (ClassInfo)classIter.next();
430             fieldRefEnhancer.setPersistentCapable(classInfo.getClassName());
431 // javaToJdoqlParser.setPersistentCapable(classInfo.getClassName());
432
ClassMetaData classMeta = (ClassMetaData)classMetaDataMap.get(
433                     classInfo.getClassName());
434             if (classEnhancer.enhance(classInfo, classMeta, makeFieldsPrivate,
435                     detached)) {
436                 classCount++;
437             }
438         }
439
440         long end = System.currentTimeMillis();
441         long time = end - start;
442         System.out.println(
443                 "[Enhanced (" + classCount + ")] time = " + time + " ms");
444
445         start = System.currentTimeMillis();
446
447         classCount = classes.size();
448         fieldRefEnhancer.setFieldsToEnhanceMap(
449                 getNonPrivateMapOfGetAndSetters(classes));
450         fieldRefEnhancer.enhance(scopeFiles);
451
452         end = System.currentTimeMillis();
453         time = end - start;
454         System.out.println(
455                 "[Looked through " + scopeFiles.size() + " class files and found " + fieldRefEnhancer.getAwareNum() + " Persistence Aware Classes] time = " + time + " ms");
456
457 // start = System.currentTimeMillis();
458
// classCount = classes.size();
459
// JavaToJdoqlParser javaToJdoqlParser = new JavaToJdoqlParser(outputDir, callingClassLoader);
460
// javaToJdoqlParser.setMetaData(metaData);
461
// javaToJdoqlParser.enhance(queriesFiles);
462
// end = System.currentTimeMillis();
463
// time = end - start;
464
// System.out.println("[Looked through " + queriesFiles.size() + " class files and found " + javaToJdoqlParser.getQueryNum() + " JavaQuery Classes] time = " + time + " ms");
465
}
466
467     private ClassLoader JavaDoc getPrivateClassLoader() {
468         ClassLoader JavaDoc classLoader = getClassLoader();
469         if (classLoader != null) {
470             return classLoader;
471         }
472         ClassLoader JavaDoc taskClassLoader = getClass().getClassLoader();
473         if (taskClassLoader == null) {
474             taskClassLoader = ClassLoader.getSystemClassLoader();
475         }
476         return taskClassLoader;
477     }
478
479     ArrayList orderList = new ArrayList();
480
481     private void getOrder(ClassMetaData meta) {
482         orderList.add(meta.qname);
483         ClassMetaData[] mySub = meta.pcSubclasses;
484         if (mySub == null) {
485             return;
486         } else {
487             for (int j = 0; j < mySub.length; j++) {
488                 ClassMetaData data = mySub[j];
489                 getOrder(data);
490             }
491         }
492     }
493
494     ArrayList hierList = new ArrayList();
495
496     private void getHier(ClassMetaData meta) {
497         hierList.add(meta.qname);
498         ClassMetaData[] mySub = meta.pcSubclasses;
499         if (mySub == null) {
500             return;
501         } else {
502             for (int j = 0; j < mySub.length; j++) {
503                 ClassMetaData data = mySub[j];
504                 getHier(data);
505             }
506         }
507     }
508
509     private HashMap getMapOfGetAndSetters(List classes) {
510         HashMap map = new HashMap();
511
512         ClassMetaData[] allMetas = metaData.classes;
513         for (int i = 0; i < allMetas.length; i++) {
514             ClassMetaData meta = allMetas[i];
515             if (!meta.isInHeirachy()) {
516                 orderList.add(meta.qname);
517             } else if (meta.top.equals(meta)) {
518                 getOrder(meta);
519             }
520         }
521
522         for (Iterator iterator = orderList.iterator(); iterator.hasNext();) {
523             String JavaDoc s = (String JavaDoc)iterator.next();
524             Iterator classIter = classes.iterator();
525             while (classIter.hasNext()) {
526                 ClassInfo classInfo = (ClassInfo)classIter.next();
527                 String JavaDoc className = classInfo.getClassName();
528                 if (className.equals(s)) {
529                     Iterator iter = classInfo.getFieldList().iterator();
530                     while (iter.hasNext()) {
531                         FieldInfo fieldInfo = (FieldInfo)iter.next();
532                         String JavaDoc fieldName = fieldInfo.getFieldName();
533                         SwapFieldHelper helper = new SwapFieldHelper();
534                         helper.className = className;
535                         helper.fieldName = fieldName;
536                         helper.jdoGetName = fieldInfo.getJdoGetName();
537                         helper.jdoSetName = fieldInfo.getJdoSetName();
538                         helper.type = fieldInfo.getType();
539                         map.put(className + "|" + fieldName, helper);
540
541                         if (!fieldInfo.isPrivate()) {
542                             ClassMetaData clMeta = metaData.getClassMetaData(
543                                     className);
544                             hierList = new ArrayList();
545                             getHier(clMeta);
546                             for (Iterator iterator1 = hierList.iterator();
547                                  iterator1.hasNext();) {
548                                 String JavaDoc clName = (String JavaDoc)iterator1.next();
549                                 map.put(clName + "|" + fieldName, helper);
550                             }
551                         }
552                     }
553
554                 }
555             }
556
557         }
558         return map;
559     }
560
561     private HashMap getNonPrivateMapOfGetAndSetters(List classes) {
562         HashMap map = new HashMap();
563
564         for (Iterator iterator = orderList.iterator(); iterator.hasNext();) {
565             String JavaDoc s = (String JavaDoc)iterator.next();
566             Iterator classIter = classes.iterator();
567             while (classIter.hasNext()) {
568                 ClassInfo classInfo = (ClassInfo)classIter.next();
569                 String JavaDoc className = classInfo.getClassName();
570                 if (className.equals(s)) {
571                     Iterator iter = classInfo.getFieldList().iterator();
572                     while (iter.hasNext()) {
573                         FieldInfo fieldInfo = (FieldInfo)iter.next();
574                         if (fieldInfo.isPrivate()) continue;
575                         String JavaDoc fieldName = fieldInfo.getFieldName();
576                         SwapFieldHelper helper = new SwapFieldHelper();
577                         helper.className = className;
578                         helper.fieldName = fieldName;
579                         helper.jdoGetName = fieldInfo.getJdoGetName();
580                         helper.jdoSetName = fieldInfo.getJdoSetName();
581                         helper.type = fieldInfo.getType();
582                         map.put(className + "|" + fieldName, helper);
583
584                         ClassMetaData clMeta = metaData.getClassMetaData(
585                                 className);
586                         hierList = new ArrayList();
587                         getHier(clMeta);
588                         for (Iterator iterator1 = hierList.iterator();
589                              iterator1.hasNext();) {
590                             String JavaDoc clName = (String JavaDoc)iterator1.next();
591                             map.put(clName + "|" + fieldName, helper);
592                         }
593                     }
594                 }
595             }
596         }
597         return map;
598     }
599
600     private ModelMetaData getMetaData(File JavaDoc configFile, ClassLoader JavaDoc loader)
601             throws Exception JavaDoc {
602         // parse the config
603
ConfigInfo config = new ConfigParser().parseResource(configFile);
604         config.validate();
605         return getMetaDataImp(config, loader);
606     }
607
608     private ModelMetaData getMetaData(String JavaDoc configFilename, ClassLoader JavaDoc loader)
609             throws Exception JavaDoc {
610         // parse the config
611
ConfigInfo config = new ConfigParser().parseResource(configFilename,
612                 loader);
613         config.validate();
614         return getMetaDataImp(config, loader);
615     }
616
617     private ModelMetaData getMetaData(Properties props, ClassLoader JavaDoc loader)
618             throws Exception JavaDoc {
619         // parse the properties
620
ConfigInfo config = new ConfigParser().parse(props);
621         config.validate();
622         return getMetaDataImp(config, loader);
623     }
624
625     private ModelMetaData getMetaDataImp(ConfigInfo config, ClassLoader JavaDoc loader)
626             throws Exception JavaDoc {
627
628         if (srcOutDir != null) {
629             config.hyperdriveSrcDir = srcOutDir.toString();
630         }
631         if (hyperdriveDir != null) {
632             config.hyperdriveClassDir = hyperdriveDir.toString();
633         } else if (genHyper) {
634             config.hyperdriveClassDir = outputDirectory.toString();
635         }
636         config.hyperdrive = srcOutDir != null || hyperdriveDir != null;
637         if (this.genHyper && !config.hyperdrive){
638             config.hyperdrive = true;
639         }
640
641         StorageManagerFactoryBuilder b = new StorageManagerFactoryBuilder();
642         b.setConfig(config);
643         b.setLoader(loader);
644         b.setOnlyMetaData(true);
645         StorageManagerFactory smf = b.createStorageManagerFactory();
646         metaData = smf.getModelMetaData();
647
648         Thread.currentThread().setContextClassLoader(loader);
649         return metaData;
650     }
651
652 }
653
Popular Tags