KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > enhancer > impl > EnhancerControl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24
25 package com.sun.jdo.api.persistence.enhancer.impl;
26
27 import java.util.Map JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.HashMap JavaDoc;
33
34 //@olsen: added general support
35
import com.sun.jdo.api.persistence.enhancer.util.Support;
36
37 import com.sun.jdo.api.persistence.enhancer.util.ClassFileSource;
38
39 //@olsen: disabled feature
40
/*
41 import com.sun.jdo.api.persistence.enhancer.classfile.ClassFile;
42 */

43
44 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaData;
45
46 import com.sun.jdo.api.persistence.enhancer.impl.ClassControl;
47 import com.sun.jdo.api.persistence.enhancer.impl.Environment;
48 //@olsen: disabled feature
49
/*
50 import com.sun.jdo.api.persistence.enhancer.impl.FieldMap;
51 */

52
53 //lars: made the class public to access it from the root package
54
//lars: moved from root package into impl-subpackage
55
//@olsen: cosmetics
56
//@olsen: subst: [iI]Persistent -> [pP]ersistenceCapable
57
//@olsen: subst: /* ... */ -> // ...
58
//@olsen: moved: class FilterError -> package util
59
//@olsen: moved: OSCFP.addClass(ClassControl) -> impl.Environment
60
//@olsen: subst: filterEnv.classMap.elements() -> filterEnv.getClasses()
61
//@olsen: subst: filterEnv.classMap.get(name) -> filterEnv.getClass(name)
62
//@olsen: subst: filterEnv.translations -> filterEnv.translations()
63
//@olsen: subst: OSCFP -> Main
64
//@olsen: subst: filterEnv -> env
65
//@olsen: subst: FilterEnv -> Environment
66
//@olsen: dropped parameter 'Environment env', use association instead
67
//@olsen: subst: augment -> closeOver
68
//@olsen: subst: collectAllClasses -> collectClasses
69
//@olsen: subst: Vector -> Collection, List, ArrayList
70
//@olsen: subst: Hashtable -> Map, HashMap
71
//@olsen: subst: Enumeration,... -> Iterator, hasNext(), next()
72
//@olsen: removed: proprietary support for IndexableField
73

74
75 /**
76  * Main is the starting point for the persistent filter tool.
77  */

78 //@olsen: added local class
79
public class EnhancerControl
80 //extends Support
81
{
82
83     /* Central repository for the options selected by
84      * the user and the current state of the Filter execution */

85     private Environment env;
86
87     /**
88      * Create an instance.
89      */

90     public EnhancerControl(Environment env) {
91         this.env = env;
92     }
93
94     /**
95      * Extend the class map so that persistent classes are closed over
96      */

97 //@olsen: inlined method
98
/*
99     //@olsen: moved: Main.closeOverClasses() -> EnhancerControl
100     //@olsen: made public
101     public void closeOverClasses() {
102         ArrayList v = env.collectClasses(ClassControl.PersistCapable);
103         for (Iterator e = v.iterator(); e.hasNext();) {
104             ClassControl cc = (ClassControl)e.next();
105             closeOverClass(cc);
106         }
107     }
108 */

109
110     /**
111      * Extend the class map so that all base classes of the specified
112      * class are included, if possible. The specified class is assumed
113      * to already be on the persistent class list.
114      */

115 //@olsen: disabled feature
116
/*
117     //@olsen: moved: Main.closeOverClass(ClassControl startCC) -> EnhancerControl
118     //@olsen: made public
119     public void closeOverClass(ClassControl startCC) {
120         final JDOMetaData jdoMetaData = env.getJDOMetaData();
121         String className = startCC.classFile().className().asString();
122         String baseClassName = startCC.classFile().superName().asString();
123         while (true) {
124             //@olsen: added final
125             final ClassControl cc = env.findClass(baseClassName);
126
127             if (cc == null) {
128                 // We can't find the class file
129                 // perhaps a mechanism to only produce the error would be nice
130                 env.error("Unable to locate class " +
131                           ClassControl.userClassFromVMClass(baseClassName));
132                 return;
133             }
134
135             if (baseClassName.equals("java/lang/Object"))
136                 //@olsen: subst: break -> return
137                 return;
138
139 //@olsen: disabled feature
140 ///
141             //@olsen: not used
142             //String ccPkg = cc.pkg();
143             if (baseClassName.startsWith("java/") &&
144                 !cc.implementsPersistenceCapable() &&
145                 !env.modifyJavaClasses()) {
146                 env.error("Sorry, java types can not be made persistent. " +
147                           "Class " +
148                           ClassControl.userClassFromVMClass(className) +
149                           " extends " +
150                           ClassControl.userClassFromVMClass(baseClassName) +
151                           ". See the -modifyjava option if you really " +
152                           "want to do this.");
153                 return;
154             }
155
156             if (baseClassName.startsWith("com/ms/com/")) {
157                 env.error("Sorry, Microsoft COM types can not be made persistent. " +
158                           "Class " +
159                           ClassControl.userClassFromVMClass(className) +
160                           " extends " +
161                           ClassControl.userClassFromVMClass(baseClassName) +
162                           ".");
163                 return;
164             }
165 ///
166
167             //cc.setPersistType(ClassControl.PersistCapable);
168
169             //@olsen: set persisence type of class by JDO meta-data
170             if (jdoMetaData.isPersistenceCapableClass(baseClassName)) {
171                 //cc.setPersistType(ClassControl.PersistCapable);
172                 cc.setInitialPersistType(ClassControl.PersistCapable);
173
174                 //@olsen: impose limitation
175                 env.error("Sorry, in this release a persistent class cannot have a persistent super-class. " +
176                           "Persistent class " +
177                           ClassControl.userClassFromVMClass(className) +
178                           " (indirectly) extends persistent class " +
179                           ClassControl.userClassFromVMClass(baseClassName) +
180                           ".");
181                 return;
182             } else if (baseClassName.startsWith("java/")) {
183                 //cc.setPersistType(ClassControl.TransientOnly);
184                 cc.setInitialPersistType(ClassControl.TransientOnly);
185
186                 // may stop when transient root class found
187                 return;
188             }
189
190 //@olsen: disabled feature
191 ///
192             if (cc.persistType() == ClassControl.PersistCapable) {
193                 // The base class is already on the persistent-capable list
194                 // so we're all done here
195                 return;
196             }
197             if (cc.implementsPersistenceCapable()) {
198                 // The class already inherits from Persistent. It's probably
199                 // ok to update if necessary
200                 env.message("Promoting " + cc.userClassName() +
201                             " to persistence-capable.");
202                 cc.setPersistType(ClassControl.PersistCapable);
203                 cc.setImplicitlyPersistent(true);
204             } else if (cc.persistType() == ClassControl.PersistUnknown) {
205                 if (cc.pkg().equals(startCC.pkg())) {
206                     // It's ok to make this base class persistent too.
207                     env.message("Including class " + cc.userClassName() +
208                                 " as a persistence capable class.");
209                     cc.setPersistType(ClassControl.PersistCapable);
210                     cc.setImplicitlyPersistent(true);
211                 } else {
212                     // Ought to be more clever here as this class may be
213                     // pulled in through another persistence path later on
214                     env.error("Class " + cc.userClassName() +
215                               " must be persistent to allow " +
216                               startCC.userClassName() +
217                               " to be persistent.");
218                     return;
219                 }
220             } else {
221                 // Ought to be more clever here as this class may be pulled in
222                 // through another persistence path later on
223                 env.error("Class " + cc.userClassName() +
224                           " must be persistent to allow " +
225                           startCC.userClassName() +
226                           " to be persistent.");
227                 return;
228             }
229 ///
230
231             // Move on to the next base class
232             baseClassName = cc.classFile().superName().asString();
233         }
234     }
235 */

236
237     /**
238      * Dumps a class' signature and byte-code.
239      */

240     //@olsen: added method for debugging
241
static protected void dumpClass(ClassControl cc) {
242         final String JavaDoc name = cc.userClassName();
243         System.out.println();
244         System.out.println("dumping class " + name + " {");//NOI18N
245
cc.classFile().print(System.out);
246         System.out.println("} // end of class " + name);
247         System.out.println();
248     }
249
250
251     /**
252      * Determine what modifications are needed and perform them
253      */

254     //@olsen: moved: Main.modifyClasses() -> EnhancerControl
255
//@olsen: made public
256
//@olsen: improved output
257
public void modifyClasses() {
258         //@olsen: added support for timing statistics
259
try{
260             if (env.doTimingStatistics()) {
261                 Support.timer.push("EnhancerControl.modifyClasses()");//NOI18N
262
}
263             final ArrayList JavaDoc classes = env.collectClasses();
264
265             if (classes.size() > 1) {
266                 env.messageNL("scanning classes");//NOI18N
267
}
268
269             // First examine the classes, noting the class characteristics
270
for (Iterator JavaDoc e = classes.iterator(); e.hasNext();) {
271                 ClassControl cc = (ClassControl)e.next();
272                 cc.scan1();
273
274                 if (false) {
275                     dumpClass(cc);
276                 }
277             }
278
279 //@olsen: disabled feature
280
/*
281             // Possibly update package names
282             retargetClasses();
283 */

284
285             if (env.errorCount() > 0)
286                 return;
287
288             if (classes.size() > 1) {
289                 env.messageNL("augmenting classes");//NOI18N
290
}
291
292             // Change class inheritance
293
for (Iterator JavaDoc e = classes.iterator(); e.hasNext();) {
294                 ClassControl cc = (ClassControl)e.next();
295                 //@olsen: subst: augmentInterfaces -> augment
296
cc.augment();
297
298                 if (false) {
299                     dumpClass(cc);
300                 }
301             }
302
303             if (env.errorCount() > 0)
304                 return;
305
306             if (classes.size() > 1) {
307                 env.messageNL("annotating classes");//NOI18N
308
}
309
310             // Then perform the annotation actions
311
for (Iterator JavaDoc e = classes.iterator(); e.hasNext();) {
312                 ClassControl cc = (ClassControl)e.next();
313                 cc.annotate();
314
315                 if (false) {
316                     dumpClass(cc);
317                 }
318             }
319         } finally {
320             if (env.doTimingStatistics()) {
321                 Support.timer.pop();
322             }
323         }
324     }
325
326     /**
327      * Build a ArrayList of strings which are the names of the
328      * persistent classes in this enhancer's run.
329      */

330 //@olsen: disabled feature
331
/*
332     private ArrayList computePersistentClasses() {
333         ArrayList v = new ArrayList();
334         Iterator allClasses = env.getClasses();
335         while (allClasses.hasNext()) {
336             ClassControl cc = (ClassControl)allClasses.next();
337             if (cc.isExplicitlyNamed() && cc.persistCapable())
338                 v.add(cc.userClassName());
339         }
340         return v;
341     }
342 */

343
344     /**
345      * For each class in the class map which isn't transient-only,
346      * apply package name translations to update class references
347      */

348 //@olsen: disabled feature
349
/*
350     //@olsen: moved: Main.retargetClasses() -> EnhancerControl
351     private void retargetClasses() {
352
353         if (env.translations().size() == 0)
354             return;
355
356         locateTranslatedClasses();
357
358         //@olsen: made classMap local in Environment
359         //if (env.classMap.size() > 0) {
360         {
361             ArrayList translatable = new ArrayList();
362             Map classTranslations = new HashMap();
363
364             // Compute the full set of class translations
365             for (Iterator e = env.getClasses(); e.hasNext();) {
366                 ClassControl cc = (ClassControl)e.next();
367                 String pkg = cc.pkg();
368                 String xlat = (String)env.translations().get(pkg);
369                 if (xlat != null || cc.annotateable()) {
370                     translatable.add(cc);
371
372                     if (xlat != null) {
373                         String newName;
374                         if (xlat.length() == 0)
375                             newName = cc.unpackagedName();
376                         else
377                             newName = xlat + "/" + cc.unpackagedName();
378                         if (!newName.equals(cc.className())) {
379                             ClassControl existingCC =
380                                 (ClassControl)env.getClass(newName);
381
382                             if (existingCC != null) {
383                                 env.error("The package translations specified would " +
384                                           "cause " + cc.userClassName() +
385                                           " to be translated to " +
386                                           existingCC.userClassName() +
387                                           " which already exists.");
388                             } else
389                                 classTranslations.put(cc.className(), newName);
390                         }
391                     }
392                 }
393             }
394
395             if (env.errorCount() > 0)
396                 return;
397
398             if (classTranslations.size() == 0) {
399                 env.warning("No package name translations are being applied");
400             }
401             else {
402                 env.message();
403                 env.message("doing package name translations");
404
405                 for (Iterator e = translatable.iterator(); e.hasNext();) {
406                     final ClassControl cc = (ClassControl)e.next();
407                     final String className = cc.className();
408                     cc.retarget(classTranslations);
409
410                     //@olsen: use added method
411                     env.renameClass(className);
412 //
413                     // Add the modified name to the class map if the class
414                     // name has changed.
415                     String newClassName = cc.className();
416                     env.classMap.remove(className);
417                     env.renamedMap.put(className, cc);
418                     env.classMap.put(newClassName, cc);
419 //
420                 }
421             }
422         }
423     }
424 */

425
426     /**
427      * For each package name translation selected, find all classes in the
428      * package and add to the class map.
429      */

430 //@olsen: disabled feature
431
/*
432     //@olsen: moved: Main.locateTranslatedClasses() -> EnhancerControl
433     private void locateTranslatedClasses() {
434         // Compute the full set of class translations
435         for (Iterator e = env.translations().keySet().iterator();
436              e.hasNext();) {
437             String pkg = (String)e.next();
438
439             for (Enumeration pe = env.classPathOption().classesInPackage(pkg);
440                  pe.hasMoreElements();) {
441                 String className = (String)pe.nextElement();
442                 env.findClass(className);
443             }
444         }
445     }
446 */

447 }
448
Popular Tags