KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > rtti > ClassRepository


1 /*
2   Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>,
3                           Laurent Martelli <laurent@aopsys.com>
4   
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as
7   published by the Free Software Foundation; either version 2 of the
8   License, or (at your option) any later version.
9
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 Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

18
19 package org.objectweb.jac.core.rtti;
20
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.Modifier JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Vector JavaDoc;
33 import org.apache.log4j.Logger;
34 import org.objectweb.jac.util.Classes;
35 import org.objectweb.jac.util.Strings;
36
37 /**
38  * This class defines the class repository of the rtti aspect.<p>
39  *
40  * It contains class items that are field and method items
41  * agregates.<p>
42  *
43  * @see ClassItem
44  * @see MethodItem
45  * @see FieldItem
46  * @see CollectionItem
47  *
48  * @author Renaud Pawlak
49  * @author Laurent Martelli
50  */

51
52 public class ClassRepository implements LoadtimeRTTI {
53     static Logger logger = Logger.getLogger("rtti.repository");
54     static Logger loggerlt = Logger.getLogger("rtti.lt");
55
56     Map JavaDoc ltClassInfos = new Hashtable JavaDoc();
57
58     public ClassInfo getClassInfo(String JavaDoc className) {
59         ClassInfo classinfo=(ClassInfo)ltClassInfos.get(className);
60         if (classinfo==null) {
61             classinfo=new ClassInfo();
62             ltClassInfos.put(className,classinfo);
63         }
64         return classinfo;
65     }
66
67     public void setClassInfo(String JavaDoc className, ClassInfo classInfo) {
68         ltClassInfos.put(className,classInfo);
69     }
70
71     public MethodInfo getMethodInfo(String JavaDoc className, String JavaDoc method) {
72         return getClassInfo(className).getMethodInfo(method);
73     }
74
75     /**
76      * Adds a modified field for a given method.
77      *
78      * <p>This method is automatically called at load-time by the JAC
79      * classloader through bytecode analysis.
80      *
81      * @param methodSign the method signature of the form
82      * <code>packagepath.classname.methodname</code>
83      * @param fieldName the name of the field that is modified by the
84      * method */

85
86     public void addltModifiedField(String JavaDoc className, String JavaDoc methodSign,
87                                    String JavaDoc fieldName) {
88         getClassInfo(className).addModifiedField(methodSign,fieldName);
89     }
90
91     public void addltSetField(String JavaDoc className, String JavaDoc methodSign,
92                               String JavaDoc fieldName) {
93         getClassInfo(className).addSetField(methodSign,fieldName);
94     }
95
96     /**
97      * Adds an accessed field for a given method.
98      *
99      * <p>This method is automatically called at load-time by the JAC
100      * classloader through bytecode analysis.
101      *
102      * @param methodSign the method signature of the form
103      * <code>packagepath.classname.methodname</code>
104      * @param fieldName the name of the field that is accessed by the
105      * method */

106
107     public void addltAccessedField(String JavaDoc className, String JavaDoc methodSign,
108                                    String JavaDoc fieldName) {
109         getClassInfo(className).addAccessedField(methodSign,fieldName);
110     }
111
112     public void addltReturnedField(String JavaDoc className, String JavaDoc methodSign,
113                                    String JavaDoc fieldName) {
114         getClassInfo(className).setReturnedField(methodSign,fieldName);
115     }
116
117     public void setltIsGetter(String JavaDoc className, String JavaDoc methodSign,
118                               boolean isGetter) {
119         getClassInfo(className).setIsGetter(methodSign,isGetter);
120     }
121
122     public void addltAddedCollection(String JavaDoc className, String JavaDoc methodSign,
123                                      String JavaDoc fieldName) {
124         getClassInfo(className).addAddedCollection(methodSign,fieldName);
125     }
126
127     public void addltRemovedCollection(String JavaDoc className, String JavaDoc methodSign,
128                                        String JavaDoc fieldName) {
129         getClassInfo(className).addRemovedCollection(methodSign,fieldName);
130     }
131
132     public void addltModifiedCollection(String JavaDoc className, String JavaDoc methodSign,
133                                         String JavaDoc fieldName) {
134         getClassInfo(className).addModifiedCollection(methodSign,fieldName);
135     }
136
137     public void setCollectionIndexArgument(String JavaDoc className, String JavaDoc methodSign,
138                                            int argument) {
139         getClassInfo(className).setCollectionIndexArgument(methodSign,argument);
140     }
141
142     public void setCollectionItemArgument(String JavaDoc className, String JavaDoc methodSign,
143                                           int argument) {
144         getClassInfo(className).setCollectionItemArgument(methodSign,argument);
145     }
146
147     public void addInvokedMethod(String JavaDoc className, String JavaDoc methodSign,
148                                  InvokeInfo invokeInfo) {
149         getClassInfo(className).addInvokedMethod(methodSign,invokeInfo);
150     }
151
152     public void setCallSuper(String JavaDoc className, String JavaDoc method) {
153         getMethodInfo(className,method).callSuper = true;
154     }
155
156     /**
157      * Get the sole instance of class repository.<p>
158      *
159      * @return the class repository */

160    
161     public static ClassRepository get() {
162         if ( classRepository == null ) {
163             classRepository = new ClassRepository();
164         }
165         return classRepository;
166     }
167    
168     /**
169      * Store the sole instance of class repository. */

170
171     protected static transient ClassRepository classRepository = null;
172
173     /** Stores the Jac objects root class. */
174     //public static Class jacObjectClass;
175
/** Stores the Wrappee class. */
176     public static Class JavaDoc wrappeeClass;
177     static {
178         try {
179             //jacObjectClass = Class.forName( "org.objectweb.jac.core.JacObject" );
180
wrappeeClass = Class.forName("org.objectweb.jac.core.Wrappee");
181         } catch(Exception JavaDoc e) {
182             e.printStackTrace();
183             System.exit( -1 );
184         }
185     }
186
187     /**
188      * Store direct access to the methods of all the classes by name on
189      * optimization purpose. */

190     transient static Hashtable JavaDoc directMethodAccess = new Hashtable JavaDoc();
191
192     /**
193      * Store direct access to the fields of all the classes by name on
194      * optimization purpose. */

195     transient static Hashtable JavaDoc directFieldAccess = new Hashtable JavaDoc();
196
197     /**
198      * Fill the direct access to methods hashtable for a given class.
199      *
200      * <p>This is used to optimize the method calls when you only have
201      * the method name.
202      *
203      * @param cl the class to treat.
204      *
205      * @see #getDirectMethodAccess(Class,String) */

206
207     public static Hashtable JavaDoc fillDirectMethodAccess(final Class JavaDoc cl) {
208         if( cl == null ) return null;
209         if ( directMethodAccess == null ) directMethodAccess = new Hashtable JavaDoc();
210         Hashtable JavaDoc methods = new Hashtable JavaDoc();
211         final Method JavaDoc[] meths = cl.getMethods();
212         // AccessibleObject.setAccessible( meths, true );
213
for (int i=meths.length-1; i>=0; i--) {
214             meths[i].setAccessible(true);
215             if ( methods.containsKey(meths[i].getName()) ) {
216                 Method JavaDoc[] oldms = (Method JavaDoc[]) methods.get( meths[i].getName() );
217                 Method JavaDoc[] newms = new Method JavaDoc[oldms.length+1];
218                 System.arraycopy( oldms, 0, newms, 0, oldms.length );
219                 newms[oldms.length] = meths[i];
220                 methods.remove( meths[i].getName() );
221                 methods.put( meths[i].getName(), newms );
222             } else {
223                 methods.put( meths[i].getName(), new Method JavaDoc[] { meths[i] } );
224             }
225         }
226         directMethodAccess.put(cl,methods);
227         return methods;
228     }
229
230     /**
231      * Fill the direct access to fields hashtable for a given class.
232      *
233      * <p>This is used to optimize the access of protected and private
234      * fields.
235      *
236      * @param cl the class to treat. */

237
238     public static void fillDirectFieldAccess(final Class JavaDoc cl) {
239         if (cl==null || cl==Object JavaDoc.class)
240             return;
241         if (directFieldAccess == null )
242             directFieldAccess = new Hashtable JavaDoc();
243         if (directFieldAccess.containsKey(cl))
244             return;
245         Hashtable JavaDoc fields = new Hashtable JavaDoc();
246         Class JavaDoc superClass = cl.getSuperclass();
247         if (superClass!=Object JavaDoc.class && superClass!=null) {
248             fillDirectFieldAccess(superClass);
249             Map JavaDoc inheritedFields = (Map JavaDoc)directFieldAccess.get(superClass);
250             if (inheritedFields!=null)
251                 fields.putAll(inheritedFields);
252         }
253         final Field JavaDoc[] fs = cl.getDeclaredFields();
254         // AccessibleObject.setAccessible( fs, true );
255
for (int i = 0; i<fs.length; i++) {
256             if (!isJacField(fs[i].getName()) && !isSystemField(fs[i].getName())) {
257                 fs[i].setAccessible(true);
258                 fields.put(fs[i].getName(),fs[i]);
259             }
260         }
261         directFieldAccess.put(cl,fields);
262     }
263
264     /**
265      * Returns a Hashtable that maps fields with their names.
266      *
267      * <p>For efficiency, the programmer should use this method instead
268      * of using the Java refection API to retrives values of protected
269      * or private fields within a class and all its superclasses.
270      *
271      * @param cl the class
272      * @return a Map (String(field name) -> Field)
273      *
274      * @see #fillDirectFieldAccess(Class) */

275
276     public static Hashtable JavaDoc getDirectFieldAccess(Class JavaDoc cl) {
277         fillDirectFieldAccess(cl);
278         return ((Hashtable JavaDoc)directFieldAccess.get(cl));
279     }
280
281     /**
282      * Call a directly acceded method.
283      *
284      * @param cl the class that supports the method
285      * @param methodName the method to call
286      * @param o the object to call the method on
287      * @param params the arguments
288      *
289      * @see #getDirectMethodAccess(Class,String)
290      */

291     public static Object JavaDoc invokeDirect(Class JavaDoc cl,
292                                       String JavaDoc methodName,
293                                       Object JavaDoc o,
294                                       Object JavaDoc[] params)
295         throws java.lang.NoSuchMethodException JavaDoc,
296         InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
297     {
298         Method JavaDoc[] directMethods = getDirectMethodAccess(cl,methodName);
299         logger.debug("direct invocation of "+methodName+" => "+
300                      java.util.Arrays.asList(directMethods));
301         boolean ok = false;
302         boolean lengthOk = false;
303         Object JavaDoc ret = null;
304         for (int i=0; i<directMethods.length; i++) {
305             if (directMethods[i].getParameterTypes().length==params.length) {
306                 lengthOk = true;
307                 try {
308                     ret = directMethods[i].invoke(o, params);
309                     ok = true;
310                 } catch (IllegalArgumentException JavaDoc e1) {
311                 }
312             }
313         }
314         if (!ok) {
315             if (lengthOk) {
316                 logger.error("No such method "+cl.getName()+"."+methodName+Arrays.asList(params));
317             } else {
318                 logger.error("Wrong number of parameters for "+cl.getName()+"."+methodName+Arrays.asList(params));
319             }
320             throw new java.lang.NoSuchMethodException JavaDoc();
321         }
322         return ret;
323     }
324
325     /**
326      * Return an array of methods that correspond to the given class
327      * and given method name.
328      *
329      * <p>For efficiency, the programmer should use this method instead
330      * of using the Java refection API.
331      *
332      * @param cl the class where the method is supposed to be
333      * @param name the method name
334      * @return an array containing the matching methods (homonyms), a
335      * one array element with <code>null</code> inside if none method
336      * matched (this ugly result was introduced for backward
337      * compatibility)
338      *
339      * @see #fillDirectMethodAccess(Class)
340      */

341     public static Method JavaDoc[] getDirectMethodAccess(Class JavaDoc cl, String JavaDoc name) {
342         Hashtable JavaDoc methods = (Hashtable JavaDoc)directMethodAccess.get(cl);
343         if (methods==null)
344             methods = fillDirectMethodAccess(cl);
345         Method JavaDoc[] ret = (Method JavaDoc[]) methods.get(name);
346         if (ret == null ) {
347             return new Method JavaDoc[] { };
348         } else {
349             return ret;
350         }
351     }
352
353     /**
354      * Returns true is this class defautlt constructor (the one with no
355      * parameter) has been added by JAC at class load-time.
356      *
357      * @param cl the class to test
358      * @return true if added, false if programmer defined
359      */

360     public static boolean isDefaultConstructorAdded(Class JavaDoc cl) {
361         try {
362             cl.getField("__JAC_ADDED_DEFAULT_CONSTRUCTOR");
363         } catch (Exception JavaDoc e) {
364             return false;
365         }
366         return true;
367     }
368
369     /**
370      * Return true if the method is added by JAC at class load-time.
371      *
372      * @param methodName the method to check
373      * @return true if added at load-time
374      */

375     public static boolean isJacMethod (String JavaDoc methodName) {
376         if (methodName.startsWith("_"))
377             return true;
378         return false;
379     }
380
381     /**
382      * Return true if the field is added by JAC at class load-time.
383      * @param fieldName name of the field
384      */

385     public static boolean isJacField (String JavaDoc fieldName) {
386         return
387             fieldName.startsWith("__JAC_") ||
388             fieldName.equals("JUST4LOG_OPTIMIZED");
389     }
390
391     /**
392      * Tells if the field is a "system" field, such as a field added by
393      * the compiler for class objects.
394      * @param fieldName name of the field
395      */

396     public static boolean isSystemField(String JavaDoc fieldName) {
397         return fieldName.indexOf('$')!=-1;
398     }
399
400     /**
401      * Gets the method names of a class
402      *
403      * @param cl the class
404      * @return the method names as an array of strings
405      */

406     public static String JavaDoc[] getMethodsName(Class JavaDoc cl) {
407    
408         String JavaDoc[] methodNames = null;
409         Vector JavaDoc tmp = new Vector JavaDoc();
410       
411         try {
412       
413             Method JavaDoc[] methods = cl.getMethods();
414
415             for (int i=0; i<methods.length; i++) {
416                 if ( ! ( Modifier.isStatic(methods[i].getModifiers()) ||
417                          isJacMethod(methods[i].getName()) ) ) {
418                     tmp.add (methods[i].getName());
419                 }
420             }
421
422             methodNames = new String JavaDoc[tmp.size()];
423
424             for (int i=0 ; i<tmp.size(); i++) {
425                 methodNames[i] = (String JavaDoc)tmp.get(i);
426             }
427
428         } catch(Exception JavaDoc e) {
429             logger.error("getMethodsName "+cl.getName()+" failed",e);
430         }
431       
432         return methodNames;
433     }
434
435     /**
436      * Get modifiers names.
437      *
438      * @param cl the class
439      * @return the modifiers method names as an array of strings
440      */

441     public static String JavaDoc[] getModifiersNames(Class JavaDoc cl) {
442    
443         ClassItem cli = ClassRepository.get().getClass(cl);
444         Collection JavaDoc modifiers = cli.getAllModifiers();
445       
446         String JavaDoc[] methodNames = new String JavaDoc[modifiers.size()];
447
448         Iterator JavaDoc it = modifiers.iterator();
449         for( int i=0; i<methodNames.length; i++ ) {
450             methodNames[i]=((MethodItem)it.next()).getName();
451         }
452         return methodNames;
453     }
454
455     /**
456      * Get getter names.
457      *
458      * @param cl the class
459      * @return the modifiers names as an array of strings
460      */

461     public static String JavaDoc[] getGettersNames(Class JavaDoc cl) {
462    
463         ClassItem cli = ClassRepository.get().getClass(cl);
464         Collection JavaDoc getters = cli.getAllGetters();
465       
466         String JavaDoc[] methodNames = new String JavaDoc[getters.size()];
467
468         Iterator JavaDoc it = getters.iterator();
469         for( int i=0; i<methodNames.length; i++ ) {
470             methodNames[i]=((MethodItem)it.next()).getName();
471         }
472         return methodNames;
473     }
474
475     /**
476      * Adds a set of written fields to a method.<p>
477      *
478      * This method shortcuts the writting of RTTI aspects for
479      * programs. Equivalent effects can be achieved by using the RTTI
480      * aspect API.<p>
481      *
482      * @param cl the involved class
483      * @param methodName the method name
484      * @param fieldNames the set of fields that are written by this
485      * method
486      * @see MethodItem#addWrittenField(FieldItem)
487      */

488     public static void addWrittenFields(Class JavaDoc cl,
489                                         String JavaDoc methodName,
490                                         String JavaDoc[] fieldNames)
491     {
492         ClassItem cli = ((ClassRepository)ClassRepository.get()).getClass(cl);
493         MethodItem[] mis = cli.getMethods(methodName);
494
495         if ( mis != null ) {
496             for ( int i = 0; i < mis.length; i++ ) {
497                 for ( int j = 0; j < fieldNames.length; j++ ) {
498                     FieldItem fi = cli.getField( fieldNames[j] );
499                     if ( fi != null ) {
500                         mis[i].addWrittenField(fi);
501                     }
502                 }
503             }
504         }
505       
506     }
507
508     /**
509      * Adds a set of accessed fields to a method.<p>
510      *
511      * This method shortcuts the writting of RTTI aspects for
512      * programs. Equivalent effects can be achieved by using the RTTI
513      * aspect API.<p>
514      *
515      * @param cl the involved class
516      * @param methodName the method name
517      * @param fieldNames the set of fields that are accessed by this
518      * method
519      * @see MethodItem#addAccessedField(FieldItem)
520      */

521     public static void addAccessedFields(Class JavaDoc cl,
522                                          String JavaDoc methodName,
523                                          String JavaDoc[] fieldNames) {
524       
525         ClassItem cli = ClassRepository.get().getClass(cl);
526         MethodItem[] mis = cli.getMethods(methodName);
527
528         if ( mis != null ) {
529             for ( int i = 0; i < mis.length; i++ ) {
530                 for ( int j = 0; j < fieldNames.length; j++ ) {
531                     FieldItem fi = cli.getField( fieldNames[j] );
532                     if ( fi != null ) {
533                         mis[i].addAccessedField(fi);
534                     }
535                 }
536             }
537         }
538       
539     }
540
541     /**
542      * Adds a set of added collections to a method.<p>
543      *
544      * This method shortcuts the writting of RTTI aspects for
545      * programs. Equivalent effects can be achieved by using the RTTI
546      * aspect API.<p>
547      *
548      * @param cl the involved class
549      * @param methodName the method name
550      * @param collectionNames the set of collections that are added by this
551      * method
552      * @see MethodItem#addAddedCollection(CollectionItem)
553      */

554     public static void addAddedCollections(Class JavaDoc cl,
555                                            String JavaDoc methodName,
556                                            String JavaDoc[] collectionNames) {
557       
558         ClassItem cli = ClassRepository.get().getClass(cl);
559         MethodItem[] mis = cli.getMethods(methodName);
560
561         if ( mis != null ) {
562             for ( int i = 0; i < mis.length; i++ ) {
563                 for ( int j = 0; j < collectionNames.length; j++ ) {
564                     CollectionItem ci = (CollectionItem)cli.getField(collectionNames[j]);
565                     if ( ci != null ) {
566                         mis[i].addAddedCollection(ci);
567                     }
568                 }
569             }
570         }
571       
572     }
573
574     /**
575      * Adds a set of removed collections to a method.<p>
576      *
577      * This method shortcuts the writting of RTTI aspects for
578      * programs. Equivalent effects can be achieved by using the RTTI
579      * aspect API.<p>
580      *
581      * @param cl the involved class
582      * @param methodName the method name
583      * @param collectionNames the set of collections that are removed by this
584      * method
585      * @see MethodItem#addRemovedCollection(CollectionItem)
586      */

587     public static void addRemovedCollections(Class JavaDoc cl,
588                                              String JavaDoc methodName,
589                                              String JavaDoc[] collectionNames) {
590       
591         ClassItem cli = ClassRepository.get().getClass(cl);
592         MethodItem[] mis = cli.getMethods(methodName);
593
594         if (mis != null) {
595             for (int i=0; i<mis.length; i++) {
596                 for (int j=0; j<collectionNames.length; j++) {
597                     CollectionItem ci = (CollectionItem)cli.getField(collectionNames[j]);
598                     if (ci != null) {
599                         mis[i].addRemovedCollection(ci);
600                     }
601                 }
602             }
603         }
604       
605     }
606
607     /**
608      * The default constructor will set the classRepository field to
609      * the right value (singleton pattern). */

610
611     public ClassRepository () {
612         classRepository = this;
613     }
614
615     /**
616      * This method returns an existing class from its name.
617      *
618      * <p>If the class is not registered yet, the class repository
619      * automatically builds default runtime informations (using naming
620      * conventions), and seamlessly registers the new
621      * <code>ClassItem</code> instance into the class repository.
622      *
623      * <p>Note: in case of manual class registrations, a class must be
624      * registered with its full name to avoid name conflicts.<p>
625      *
626      * @param name the name of the class to get
627      * @return the class if exist, null otherwise
628      *
629      * @see #getVirtualClass(String)
630      */

631     public ClassItem getClass(String JavaDoc name)
632     {
633         String JavaDoc wrappedName = Classes.getPrimitiveTypeWrapper(name);
634         MetaItem res = (MetaItem)getObject(wrappedName);
635         if (res == null) {
636             try {
637                 res = getClass(Class.forName(name));
638             } catch (ClassNotFoundException JavaDoc e) {
639                 throw new NoSuchClassException(name);
640             }
641         }
642         if (res!=null && res instanceof ClassItem)
643             return (ClassItem)res;
644         else
645             throw new NoSuchClassException(name);
646     }
647
648     /**
649      * Returns a ClassItem or a VirtualClassItem from its name. It
650      * first tries to find a ClassItem, and if it fails, it returns a
651      * VirtualClassItem.
652      *
653      * @param name the name of the class to find
654      * @return a ClassItem or a VirtualClassItem
655      *
656      * @see #getClass(String)
657      * @see #getVirtualClassStrict(String)
658      */

659
660     public MetaItem getVirtualClass(String JavaDoc name)
661     {
662         MetaItem ret;
663         try {
664             ret = getClass(name);
665         } catch (NoSuchClassException e) {
666             ret = (MetaItem)getObject(name);
667             if (ret == null)
668                 throw e;
669         }
670         return ret;
671     }
672
673     /**
674      * Returns a VirtualClassItem from its name.
675      * @param name the name of the class to find
676      * @return the VirtualClassItem with the requested name
677      * @see #getClass(String)
678      * @see #getVirtualClass(String)
679      */

680     public VirtualClassItem getVirtualClassStrict(String JavaDoc name)
681     {
682         MetaItem ret;
683         ret = (MetaItem)getObject(name);
684         if (ret == null || !(ret instanceof VirtualClassItem))
685             throw new NoSuchClassException(name);
686         return (VirtualClassItem)ret;
687     }
688
689     /**
690      * This method returns the class item that corresponds to the given
691      * object class.<p>
692      *
693      * @param object the object to get the class item
694      * @return the class item
695      * @see #getClass(String) */

696
697     public ClassItem getClass(Object JavaDoc object) {
698         return getNonPrimitiveClass(object.getClass().getName());
699     }
700     /**
701      * This method returns the class item that corresponds to the given
702      * class.<p>
703      *
704      * @param cl the class to get the class item of
705      * @return the class item
706      * @see #getClass(String)
707      */

708     public ClassItem getClass(Class JavaDoc cl) {
709         String JavaDoc wrappedName = Classes.getPrimitiveTypeWrapper(cl.getName());
710         MetaItem res = (MetaItem)getObject(wrappedName);
711         if (res == null) {
712             res = buildDefaultRTTI(cl);
713             if (res != null)
714                 register(wrappedName, res);
715         }
716         if (res!=null && res instanceof ClassItem)
717             return (ClassItem)res;
718         else
719             throw new NoSuchClassException(cl.getName());
720         /* return getClass(cl.getName()); */
721     }
722
723     public ClassItem getNonPrimitiveClass(String JavaDoc className) {
724         try {
725             // !!! Class.forName() can trigger the instantiation of
726
// !!! the ClassItem
727
Class JavaDoc cl = Class.forName(className);
728             MetaItem res = (MetaItem)getObject(className);
729             if (res == null) {
730                 try {
731                     res = buildDefaultRTTI(cl);
732                 } catch(Exception JavaDoc e) {
733                     throw new NoSuchClassException(className);
734                 }
735                 if (res != null) {
736                     register(className, res);
737                     return (ClassItem)res;
738                 }
739             } else {
740                 return (ClassItem)res;
741             }
742             throw new NoSuchClassException(className);
743         } catch(ClassNotFoundException JavaDoc e) {
744             throw new NoSuchClassException(className);
745         }
746     }
747
748     String JavaDoc ignoreFields = null;
749     public void ignoreFields(String JavaDoc packageExpr) {
750         ignoreFields = packageExpr;