KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > utils > synthetic > Class


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: Class.java,v 1.8 2004/02/17 04:23:24 minchau Exp $
18  */

19 package org.apache.xml.utils.synthetic;
20
21 import java.lang.reflect.Modifier JavaDoc;
22
23 import org.apache.xml.utils.synthetic.reflection.Constructor;
24 import org.apache.xml.utils.synthetic.reflection.Field;
25 import org.apache.xml.utils.synthetic.reflection.Method;
26
27 /* WORK NEEDED:
28     Factories/Libraries: We currently have forClass and
29     forName(request reified, complain if no real class),
30     and declareClass (request unreified, create unreified
31     if it doesn't exist). What about ther user expectations
32     -- should we have a full matrix, rather than asking
33     users to write wrappers?
34
35     Reflection doesn't tell us about deprecation. If we want
36     that info, MFC advises mousing our way into the bytecodes.
37     (Ugh). Should we at least model that for synthetics?
38 */

39
40 /**
41  * org.apache.xml.utils.synthetic.Class is a mutable equivalent of java.lang.Class.
42  * Instances represent classes and interfaces in a running Java
43  * application, or class descriptions under construction. In the
44  * former case, org.apache.xml.utils.synthetic.Class operates as a proxy for the
45  * "real" java.lang.Class object; in the latter, it consults
46  * data structures defined in the org.apache.xml.utils.synthetic.reflection.* package.
47  * <p>
48  * Unlike java.lang.Class, org.apache.xml.utils.synthetic.Class has a pair of factories
49  * (fromName and fromClass). It can also be switched from synthetic
50  * to proxy operation after construction, by setting the realClass
51  * property; this is intended to allow these definitions to be
52  * "compiled in place".
53  * <p>
54  * For convenient use, org.apache.xml.utils.synthetic.Class implements an extended
55  * version of the java.lang.Class API -- but is not a subclass
56  * thereof, since java.lang.Class is Final (presumably for
57  * security reasons).
58  * <p>
59  * DEVELOPMENT NOTE: Methods not yet implemented will throw
60  * IllegalStateException
61  * <p>
62  * I've added code to convert primitive names into their TYPEs,
63  * to accept foo[] as a synonym for [Lfoo, and to generate
64  * the right thing on output (getJava[Short]Name).
65  * Useful extension for code generation from Java-like
66  * source. We may want to factor these and toSource out, making
67  * org.apache.xml.utils.synthetic.Class addess only the JVM level and providing
68  * subclasses or access tools that handle language syntax
69  * (Java source, NetRexx source, etc.)
70  *
71  * @since 2000/2/10
72  * @xsl.usage internal
73  */

74 public class Class extends Object JavaDoc implements java.io.Serializable JavaDoc
75 {
76
77   /** Class descriptions currently existing. */
78   private static java.util.Hashtable JavaDoc global_classtable =
79     new java.util.Hashtable JavaDoc();
80
81   /** fully-qualified path.classname.
82    * @serial */

83   private java.lang.String JavaDoc name;
84
85   /**
86    * Actual Java class object. When present, all interactions
87    * are redirected to it. Allows our Class to function as a
88    * wrapper for the Java version (in lieu of subclassing or
89    * a shared Interface), and allows "in-place compilation"
90    * to replace a generated description with an
91    * directly runnable class.
92    * @serial
93    */

94   private java.lang.Class JavaDoc realclass = null;
95
96   /** Field modifiers: Java language modifiers for this class
97    * or interface, encoded in an integer.
98    * @serial
99    */

100   private int modifiers;
101
102   /** Field isInterface: True if the Class object represents
103    * an interface type.
104    * @serial */

105   private boolean isInterface = false;
106
107   /** Field superclass: If this object represents the class
108    * Object, this is null. Otherwise, the Class object that
109    * represents the superclass of that class. In proxy mode this
110    * is determined when needed. In synthesis mode it's explicitly
111    * set by the user, and if null the superclass will be assumed
112    * to be Object.
113    * @serial */

114   private Class JavaDoc superclass = null;
115
116   /** Field declaringclass: If this object represents an inner class,
117    * the Class object that represents the class that declared it.
118    * Otherwise null.
119    * @serial
120    * */

121   private Class JavaDoc declaringclass = null;
122
123   /** Field interfaces: A list of all interfaces implemented by the class
124    * or interface represented by this object.
125    * @serial
126    * */

127   private Class JavaDoc[] interfaces = new Class JavaDoc[0];
128
129   /** Field allclasses: an array containing Class objects representing all
130    * the public classes and interfaces that are members of the class
131    * represented by this Class object.
132    * @serial
133    */

134   private Class JavaDoc[] allclasses = new Class JavaDoc[0];
135
136   /** Field declaredclasses: an array of Class objects reflecting all the
137    * classes and interfaces declared as members of the class represented
138    * by this Class object. Excludes inherited classes and interfaces.
139    * @serial
140    */

141   private Class JavaDoc[] declaredclasses = new Class JavaDoc[0];
142
143   /** Field allconstructors: an array containing Constructor objects
144    * reflecting all the constructors of the class represented
145    * by this Class object. An array of length 0 is returned if the
146    * class has no public constructors. In proxy mode only public
147    * constructors will be displayed; in synthesis mode, all declared
148    * constructors will be displayed.
149    * @serial
150    * */

151   private Constructor[] allconstructors = new Constructor[0];
152
153   /** Field declaredconstructors: an array of Constructor objects
154    * reflecting all the constructors declared by the class
155    * represented by this Class object. Includes non-public
156    * constructors, but excludes inherited ones.
157    * @serial
158    * */

159   private Constructor[] declaredconstructors = new Constructor[0];
160
161   /** Field allmethods.
162    * @serial */

163   private Method[] allmethods = new Method[0];
164
165   /** Field declaredmethods.
166    * @serial */

167   private Method[] declaredmethods = new Method[0];
168
169   /** Field allfields.
170    * @serial */

171   private Field[] allfields = new Field[0];
172
173   /** Field declaredfields.
174    * @serial */

175   private Field[] declaredfields = new Field[0];
176
177   /** Field innerclasses.
178    * @serial */

179   private Class JavaDoc[] innerclasses = new Class JavaDoc[0];
180
181   /**
182    * Construct a synthetic class as proxy/wrapper for an existing
183    * Java Class. Non-public; most folks should use
184    * .forName and .forClass to request these wrappers, so they
185    * get the shared instances.
186    * <p>
187    * Creation date: (12-25-99 12:16:15 PM)
188    * @param realclass java.lang.Class
189    */

190   Class(java.lang.Class JavaDoc realclass)
191   {
192
193     this(realclass.getName());
194
195     try
196     {
197       setRealClass(realclass);
198     }
199     catch (SynthesisException e)
200     {
201       e.printStackTrace();
202     }
203   }
204
205   /**
206    * Construct a named-but-empty synthetic Class object.
207    * Non-public; most folks should use
208    * .forName and .forClass to request these wrappers, so they
209    * get the shared instances.
210    * <p>
211    * Creation date: (12-25-99 12:15:23 PM)
212    *
213    * @param fullname full name of the class that is synthetized.
214    */

215   Class(String JavaDoc fullname)
216   {
217
218     this.name = fullname;
219
220     global_classtable.put(fullname, this);
221   }
222
223   /**
224    * Returns the synthetic Class object associated with the "real"
225    * class specified, creating one if it didn't already exist.
226    * <p>
227    * For example, the following code fragment returns
228    * the runtime Class descriptor for the class named
229    * mypackage.MyClass.
230    * <code>
231    * Class t =
232    * Class.forName(java.lang.Class.forName("mypackage.MyClass"))
233    * </code>
234    * <p>
235    * Note that if the user has manually created a org.apache.xml.utils.synthetic.Class
236    * with the same name before this call is issued, that object
237    * will be found instead. See also the declareClass call.
238    * <p>
239    * We need a better way to declare/define array classes,
240    * given a class object (synthetic or not).
241    *
242    * @param cls the desired Java class.
243    * @return the synthetic Class descriptor for the specified class.
244    */

245   public static Class JavaDoc forClass(java.lang.Class JavaDoc cls)
246   {
247
248     if (cls == null)
249       return null;
250
251     Class JavaDoc ret = (Class JavaDoc) (global_classtable.get(cls.getName()));
252
253     if (null == ret)
254       ret = new Class JavaDoc(cls);
255
256     return ret;
257   }
258
259   /**
260    * Like forName, but if the classname doesn't have a package
261    * prefix we first attempt to look it up as one of our own
262    * inner clases. As with forName, if this can not be resolved
263    * we throw an exception.
264    *
265    * @param classname the full or partial class name.
266    *
267    * @return The Class name that matches the argument.
268    *
269    * @throws ClassNotFoundException
270    */

271   public Class JavaDoc forNameInContext(String JavaDoc classname)
272           throws ClassNotFoundException JavaDoc
273   {
274
275     for (int i = innerclasses.length - 1; i >= 0; --i)
276     {
277       if (classname.equals(innerclasses[i].getShortName()))
278         return innerclasses[i];
279     }
280
281     return forName(classname);
282   }
283
284   /**
285    * Returns the synthetic Class object associated with the class
286    * with the given fully-qualified name. If there isn't one, this
287    * method attempts to locate, load and link the standard java Class.
288    * If it succeeds, it returns a wrapped version of the Class object
289    * representing the class. If it fails, the method throws a
290    * ClassNotFoundException.
291    * <p>
292    * For example, the following code fragment returns
293    * the runtime Class descriptor for the class named
294    * mypackage.MyClass -- either as a synthetic or as
295    * a standard Java class.
296    * <code>
297    * Class t =
298    * Class.forName("mypackage.MyClass")
299    * </code>
300    * <p>
301    * I've added support for arrays -- assuming any name
302    * that ends with ']' is an array. It probably needs to be
303    * made smarter, possibly via a subclass of org.apache.xml.utils.synthetic.Class.
304    *
305    * @param className the fully qualified name of the desired class.
306    * @return the synthetic Class descriptor for the class with the specified name.
307    * @throws ClassNotFoundException if the class could not be found.
308    */

309   public static Class JavaDoc forName(String JavaDoc className) throws ClassNotFoundException JavaDoc
310   {
311
312     // ***** Experimental support for array syntax expressed
313
// per Java source rather than per JVM type formalism.
314
// Simpleminded, asssumes balanced []'s.
315
if (className.endsWith("]"))
316     {
317       StringBuffer JavaDoc arrayname = new StringBuffer JavaDoc();
318
319       for (int i = className.indexOf('['); i != -1;
320               i = className.indexOf('[', i + 1))
321       {
322         arrayname.append('[');
323       }
324
325       // Convert the classname to array-formalism
326
// Primitives have letters; objects are Lname;
327
// (Don't ask why long is spelled with a J and
328
// object is spelled with an L...)
329
String JavaDoc classname = className.substring(0, className.indexOf('['));
330
331       if ("byte".equals(classname))
332         arrayname.append('B');
333       else if ("char".equals(classname))
334         arrayname.append('C');
335       else if ("double".equals(classname))
336         arrayname.append('D');
337       else if ("float".equals(classname))
338         arrayname.append('F');
339       else if ("int".equals(classname))
340         arrayname.append('I');
341       else if ("long".equals(classname))
342         arrayname.append('J');
343       else if ("short".equals(classname))
344         arrayname.append('S');
345       else if ("boolean".equals(classname))
346         arrayname.append('Z');
347       else
348         arrayname.append('L').append(classname).append(';');
349
350       // Tail-call.
351
return forName(arrayname.toString());
352     }
353
354     Class JavaDoc ret = (Class JavaDoc) (global_classtable.get(className));
355
356     if (null == ret)
357     {
358
359       // ***** Experimental support for Java primitives
360
// Seems to me that mapping them into the "Type" is
361
// probably most useful
362
if ("boolean".equals(className))
363       {
364         ret = new Class JavaDoc(className);
365         ret.realclass = java.lang.Boolean.TYPE;
366       }
367       else if ("byte".equals(className))
368       {
369         ret = new Class JavaDoc(className);
370         ret.realclass = java.lang.Byte.TYPE;
371       }
372       else if ("char".equals(className))
373       {
374         ret = new Class JavaDoc(className);
375         ret.realclass = java.lang.Character.TYPE;
376       }
377       else if ("short".equals(className))
378       {
379         ret = new Class JavaDoc(className);
380         ret.realclass = java.lang.Short.TYPE;
381       }
382       else if ("int".equals(className))
383       {
384         ret = new Class JavaDoc(className);
385         ret.realclass = java.lang.Integer.TYPE;
386       }
387       else if ("long".equals(className))
388       {
389         ret = new Class JavaDoc(className);
390         ret.realclass = java.lang.Long.TYPE;
391       }
392       else if ("float".equals(className))
393       {
394         ret = new Class JavaDoc(className);
395         ret.realclass = java.lang.Float.TYPE;
396       }
397       else if ("double".equals(className))
398       {
399         ret = new Class JavaDoc(className);
400         ret.realclass = java.lang.Double.TYPE;
401       }
402       else if ("void".equals(className))
403       {
404
405         // ***** Void is an "absence of type". We might want to create
406
// a special object to represent it. This is a placeholder.
407
ret = new Class JavaDoc(className);
408         ret.realclass = java.lang.Class.forName("java.lang.Object");
409       }
410
411       // Other classes are just wrappered. Unknown classes throw a
412
// ClassNotFoundException; the user can switch to declareClass()
413
// if they're sure that an unreified class is OK.
414
else
415         ret = new Class JavaDoc(java.lang.Class.forName(className));
416     }
417
418     return ret;
419   }
420
421   /**
422    * Start to create a synthetic Class with the given fully-qualified
423    * name. If a Class by that name already exists, and it is not
424    * reified, it will be returned instead. If a reified Class _does_
425    * exist, we throw a synthesis exception.
426    *
427    * @param className the fully qualified name of the desired class.
428    * @return the synthetic Class descriptor for the class with the specified name.
429    * @throws SynthesisException if the class has been reified.
430    */

431   public static Class JavaDoc declareClass(String JavaDoc className) throws SynthesisException
432   {
433
434     Class JavaDoc ret = (Class JavaDoc) (global_classtable.get(className));
435
436     if (null == ret)
437       ret = new Class JavaDoc(className);
438
439     if (ret.realclass != null)
440       throw new SynthesisException(SynthesisException.REIFIED);
441
442     return ret;
443   }
444
445   /**
446    * Start to create a synthetic Class with the given fully-qualified
447    * name. If a Class by that name already exists,whether reified or
448    * not, it will be removed from the table and replaced by the new synthesis.
449    *
450    * NOTE THAT the replacement will not affect classes which
451    * have already refernced the old version. We could change that by
452    * having everyone reference everyone else via an indirection table.
453    *
454    * @param className the fully qualified name of the desired class.
455    * @return the synthetic Class descriptor for the class with the specified name.
456    */

457   public static Class JavaDoc reallyDeclareClass(String JavaDoc className)
458   {
459
460     Class JavaDoc ret = (Class JavaDoc) (global_classtable.get(className));
461
462     if (null != ret)
463       global_classtable.remove(ret);
464
465     ret = new Class JavaDoc(className);
466
467     return ret;
468   }
469
470   /**
471    * Returns an array containing Class objects
472    * representing all the public classes and interfaces
473    * that are members of the class represented by this
474    * Class object. This includes public class and
475    * interface members inherited from superclasses and
476    * public class and interface members declared by the
477    * class. Returns an array of length 0 if the class has
478    * no public member classes or interfaces, or if this
479    * Class object represents a primitive type.
480    * <p>
481    * NOTE: In a significant number of existing Java environments,
482    * this method is not implemented by the official Class object
483    * and always returns an empty array. So if you don't get any
484    * useful information from a proxied java.lang.Class, don't
485    * be surprised. I'm not sure if someone decided it was a
486    * potential security issue, or if Sun was lazy and everyone
487    * else followed suit.
488    * <p>
489    * ALSO NOTE: The above spec, as taken from java.lang.Class,
490    * doesn't provide any good way to distinguish the immediate
491    * superclass from all other superclasses. That makes it only
492    * marginally useful, which is no doubt one of the reasons folks
493    * have declined to implement it.
494    *
495    * @return an array of classes.
496    */

497   public Class JavaDoc[] getClasses()
498   {
499
500     if (realclass != null && allclasses == null)
501     {
502       java.lang.Class JavaDoc[] realDE = realclass.getClasses();
503
504       allclasses = new Class JavaDoc[realDE.length];
505
506       for (int i = 0; i < realDE.length; ++i)
507       {
508         allclasses[i] = forClass(realDE[i]);
509       }
510     }
511
512     return allclasses;
513   }
514
515   /**
516    * Determines the class loader for the class.
517    *
518    * the class loader that created the class or
519    * interface represented by this object, or null
520    * if the org.apache.xml.utils.synthetic.Class was not created by a class loader.
521    */

522   public ClassLoader JavaDoc getClassLoader()
523   {
524     return (realclass == null) ? null : realclass.getClassLoader();
525   }
526
527   /**
528    * If this class represents an array type, returns the
529    * Class object representing the component type of
530    * the array; otherwise returns null.
531    * <p>
532    * NOTE: Since org.apache.xml.utils.synthetic.Class doesn't yet attempt to model array
533    * types, this will currently return false unless we are
534    * proxying such a type.
535    *
536    * @return the Class object representing the component type of
537    * the array, otherwise returns null.
538    */

539   public Class JavaDoc getComponentType()
540   {
541     return realclass == null ? null : new Class JavaDoc(realclass.getComponentType());
542   }
543
544   /**
545    * Returns a Constructor object that reflects the
546    * specified public constructor of the class
547    * represented by this Class object. The
548    * parameterTypes parameter is an array of Class
549    * objects that identify the constructor's formal
550    * parameter types, in declared order.
551    * <p>
552    * The constructor to reflect is located by searching
553    * all the constructors of the class represented by this
554    * Class object for a public constructor with the
555    * exactly the same formal parameter types.
556    *
557    *
558    * @param parameterTypes array of Class
559    * objects that identify the constructor's formal
560    * parameter types, in declared order.
561    *
562    * @return a Constructor object that reflects the
563    * specified public constructor of the class
564    * represented by this Class object.
565    *
566    * @throws NoSuchMethodException
567    * if a matching method is not found.
568    * @throws SecurityException
569    * if access to the information is denied.
570    * @throws SynthesisException
571    */

572   public Constructor getConstructor(Class JavaDoc parameterTypes[])
573           throws NoSuchMethodException JavaDoc, SecurityException JavaDoc, SynthesisException
574   {
575
576     if (realclass == null)
577       throw new SynthesisException(SynthesisException.UNREIFIED);
578
579     java.lang.Class JavaDoc[] real = new java.lang.Class JavaDoc[parameterTypes.length];
580
581     for (int i = 0; i < parameterTypes.length; ++i)
582     {
583       if ((real[i] = parameterTypes[i].getRealClass()) == null)
584         throw new SynthesisException(SynthesisException.UNREIFIED);
585     }
586
587     return new Constructor(realclass.getConstructor(real), this);
588   }
589
590   /**
591    * Returns an array containing Constructor objects
592    * reflecting all the public constructors of the class
593    * represented by this Class object. An array of length
594    * 0 is returned if the class has no public
595    * constructors.
596    *
597    *
598    * @return an array containing Constructor objects
599    * reflecting all the public constructors of the class
600    * represented by this Class object.
601    *
602    * @throws SecurityException
603    * if access to the information is denied.
604    */

605   public Constructor[] getConstructors() throws SecurityException JavaDoc
606   {
607
608     if (realclass != null && allconstructors == null)
609     {
610       java.lang.reflect.Constructor JavaDoc[] realDC = realclass.getConstructors();
611
612       allconstructors = new Constructor[realDC.length];
613
614       for (int i = 0; i < realDC.length; ++i)
615       {
616         allconstructors[i] = new Constructor(realDC[i], this);
617       }
618     }
619
620     return allconstructors;
621   }
622
623   /**
624    * This method is not implemented in VAJAVA 3.0
625    * <p>
626    * Returns an array of Class objects reflecting all the
627    * classes and interfaces declared as members of the
628    * class represented by this Class object. This
629    * includes public, protected, default (package)
630    * access, and private classes and interfaces declared
631    * by the class, but excludes inherited classes and
632    * interfaces. Returns an array of length 0 if the class
633    * declares no classes or interfaces as members, or if
634    * this Class object represents a primitive type.
635    *
636    *
637    * @return an array of Class objects reflecting all the
638    * classes and interfaces declared as members of the
639    * class represented by this Class object.
640    *
641    * @throws SecurityException
642    * if access to the information is denied.
643    */

644   public Class JavaDoc[] getDeclaredClasses() throws SecurityException JavaDoc
645   {
646
647     // ***** This should really be a single class plus declared interfaces.
648
if (realclass != null && declaredclasses == null)
649     {
650       java.lang.Class JavaDoc[] realDE = realclass.getDeclaredClasses();
651
652       declaredclasses = new Class JavaDoc[realDE.length];
653
654       for (int i = 0; i < realDE.length; ++i)
655       {
656         declaredclasses[i] = forClass(realDE[i]);
657
658         if (!realDE[i].isInterface())
659           superclass = declaredclasses[i];
660       }
661     }
662
663     return declaredclasses;
664   }
665
666   /**
667    * Adds an "extends" description for the class or
668    * interface represented by this Class object
669    *
670    * @param newclass The class that this class extends.
671    * @throws SynthesisException
672    * if the class has been reified.
673    */

674   public void addExtends(Class JavaDoc newclass) throws SynthesisException
675   {
676
677     if (realclass != null)
678       throw new SynthesisException(SynthesisException.REIFIED);
679
680     Class JavaDoc[] scratch = new Class JavaDoc[declaredclasses.length + 1];
681
682     System.arraycopy(declaredclasses, 0, scratch, 0, declaredclasses.length);
683
684     scratch[declaredclasses.length] = newclass;
685     declaredclasses = scratch;
686   }
687
688   /**
689    * Returns a Constructor object that reflects the
690    * specified declared constructor of the class or
691    * interface represented by this Class object. The
692    * parameterTypes parameter is an array of Class
693    * objects that identify the constructor's formal
694    * parameter types, in declared order.
695    *
696    *
697    * @param parameterTypes array of Class
698    * objects that identify the constructor's formal
699    * parameter types, in declared order.
700    *
701    * @return a Constructor object that reflects the
702    * specified declared constructor of the class or
703    * interface represented by this Class object.
704    *
705    * @throws NoSuchMethodException
706    * if a matching method is not found.
707    * @throws SecurityException
708    * if access to the information is denied.
709    */

710   public Constructor getDeclaredConstructor(Class JavaDoc parameterTypes[])
711           throws NoSuchMethodException JavaDoc, SecurityException JavaDoc
712   {
713     throw new java.lang.IllegalStateException JavaDoc();
714   }
715
716   /**
717    * Adds a Constructor description for the class or
718    * interface represented by this Class object
719    *
720    * @return The constructor object.
721    *
722    * @throws SynthesisException
723    * if the class has been reified.
724    */

725   public Constructor declareConstructor() throws SynthesisException
726   {
727
728     if (realclass != null)
729       throw new SynthesisException(SynthesisException.REIFIED);
730
731     Constructor newctor = new Constructor(this);
732     Constructor[] scratch = new Constructor[declaredconstructors.length + 1];
733
734     System.arraycopy(declaredconstructors, 0, scratch, 0,
735                      declaredconstructors.length);
736
737     scratch[declaredconstructors.length] = newctor;
738     declaredconstructors = scratch;
739     scratch = new Constructor[allconstructors.length + 1];
740
741     System.arraycopy(allconstructors, 0, scratch, 0, allconstructors.length);
742
743     scratch[allconstructors.length] = newctor;
744     allconstructors = scratch;
745
746     return newctor;
747   }
748
749   /**
750    * State that this class implements a specified interface.
751    * This does not yet update allMethods or otherwise
752    * attempt to inherit data.
753    *
754    * @param newifce org.apache.xml.utils.synthetic.Class representing the interface we want to add.
755    *
756    * @return The new interface class.
757    *
758    * @throws org.apache.xml.utils.synthetic.SynthesisException if the Class isn't an interface
759    */

760   public Class JavaDoc declareInterface(Class JavaDoc newifce) throws SynthesisException
761   {
762
763     if (realclass != null)
764       throw new SynthesisException(SynthesisException.REIFIED);
765
766     if (!newifce.isInterface())
767       throw new SynthesisException(SynthesisException.SYNTAX,
768                                    newifce.getName() + " isn't an interface");
769
770     Class JavaDoc[] scratch = new Class JavaDoc[interfaces.length + 1];
771
772     System.arraycopy(interfaces, 0, scratch, 0, interfaces.length);
773
774     scratch[interfaces.length] = newifce;
775     interfaces = scratch;
776     scratch = new Class JavaDoc[allclasses.length + 1];
777
778     System.arraycopy(allclasses, 0, scratch, 0, allclasses.length);
779
780     scratch[allclasses.length] = newifce;
781     allclasses = scratch;
782
783     return newifce;
784   }
785
786   /**
787    * Returns an array of Constructor objects reflecting
788    * all the constructors declared by the class
789    * represented by this Class object. These are public,
790    * protected, default (package) access, and private
791    * constructors. Returns an array of length 0 if this
792    * Class object represents an interface or a primitive
793    * type.
794    * <p>
795    * See The Java Language Specification, section 8.2.
796    *
797    *
798    * @return an array of Constructor objects reflecting
799    * all the constructors declared by the class
800    * represented by this Class object.
801    *
802    * @throws SecurityException
803    * if access to the information is denied.
804    */

805   public Constructor[] getDeclaredConstructors() throws SecurityException JavaDoc
806   {
807
808     if (realclass != null && declaredconstructors == null)
809     {
810       java.lang.reflect.Constructor JavaDoc[] realDC =
811         realclass.getDeclaredConstructors();
812
813       declaredconstructors = new Constructor[realDC.length];
814
815       for (int i = 0; i < realDC.length; ++i)
816       {
817         declaredconstructors[i] = new Constructor(realDC[i], this);
818       }
819     }
820
821     return declaredconstructors;
822   }
823
824   /**
825    * Returns a Field object that reflects the specified
826    * declared field of the class or interface represented
827    * by this Class object. The name parameter is a
828    * String that specifies the simple name of the desired
829    * field.
830    *
831    *
832    * @param name String that specifies the simple name of the desired
833    * field.
834    *
835    * @return a Field object that reflects the specified
836    * declared field of the class or interface represented
837    * by this Class object.
838    *
839    * @throws NoSuchFieldException
840    * if a field with the specified name is not found.
841    * @throws SecurityException
842    * if access to the information is denied.
843    */

844   public Field getDeclaredField(String JavaDoc name)
845           throws NoSuchFieldException JavaDoc, SecurityException JavaDoc
846   {
847     throw new java.lang.IllegalStateException JavaDoc();
848   }
849
850   /**
851    * Adds a Field description for the class or
852    * interface represented by this Class object
853    *
854    *
855    * @param name The name of the field.
856    *
857    * @return The field description.
858    *
859    * @throws SynthesisException
860    * if the class has been reified.
861    */

862   public Field declareField(String JavaDoc name) throws SynthesisException
863   {
864
865     if (realclass != null)
866       throw new SynthesisException(SynthesisException.REIFIED);
867
868     Field newfield = new Field(name, this);
869     Field[] scratch = new Field[declaredfields.length + 1];
870
871     System.arraycopy(declaredfields, 0, scratch, 0, declaredfields.length);
872
873     scratch[declaredfields.length] = newfield;
874     declaredfields = scratch;
875     scratch = new Field[allfields.length + 1];
876
877     System.arraycopy(allfields, 0, scratch, 0, allfields.length);
878
879     scratch[allfields.length] = newfield;
880     allfields = scratch;
881
882     return newfield;
883   }
884
885   /**
886    * Returns an array of Field objects reflecting all the
887    * fields declared by the class or interface represented
888    * by this Class object. This includes public,
889    * protected, default (package) access, and private
890    * fields, but excludes inherited fields. Returns an
891    * array of length 0 if the class or interface declares
892    * no fields, or if this Class object represents a
893    * primitive type. See The Java Language
894    * Specification, sections 8.2 and 8.3.
895    *
896    *
897    * @return array of Field objects reflecting all the
898    * fields declared by the class or interface represented
899    * by this Class object.
900    *
901    * @throws SecurityException
902    * if access to the information is denied.
903    */

904   public Field[] getDeclaredFields() throws SecurityException JavaDoc
905   {
906
907     if (realclass != null && declaredfields == null)
908     {
909       java.lang.reflect.Field JavaDoc[] realDF = realclass.getDeclaredFields();
910
911       declaredfields = new Field[realDF.length];
912
913       for (int i = 0; i < realDF.length; ++i)
914       {
915         declaredfields[i] = new Field(realDF[i], this);
916       }
917     }
918
919     return declaredfields;
920   }
921
922   /**
923    * Returns a Method object that reflects the specified
924    * declared method of the class or interface
925    * represented by this Class object. The name
926    * parameter is a String that specifies the simple
927    * name of the desired method, and the
928    * parameterTypes parameter is an array of Class
929    * objects that identify the method's formal parameter
930    * types, in declared order.
931    *
932    *
933    * @param name String that specifies the simple
934    * name of the desired method.
935    *
936    * @param parameterTypes array of Class
937    * objects that identify the method's formal parameter
938    * types, in declared order.
939    *
940    * @return Method object that reflects the specified
941    * declared method of the class or interface
942    * represented by this Class object.
943    *
944    * @throws NoSuchMethodException
945    * if a matching method is not found.
946    * @throws SecurityException
947    * if access to the information is denied.
948    */

949   public Method getDeclaredMethod(String JavaDoc name, Class JavaDoc parameterTypes[])
950           throws NoSuchMethodException JavaDoc, SecurityException JavaDoc
951   {
952     throw new java.lang.IllegalStateException JavaDoc();
953   }
954
955   /**
956    * Adds a Method description for the class or
957    * interface represented by this Class object
958    *
959    *
960    * @param name Name of method.
961    *
962    * @return The method object.
963    *
964    * @throws SynthesisException
965    * if the class has been reified.
966    */

967   public Method declareMethod(String JavaDoc name) throws SynthesisException
968   {
969
970     if (realclass != null)
971       throw new SynthesisException(SynthesisException.REIFIED);
972
973     Method newMethod = new Method(name, this);
974     Method[] scratch = new Method[declaredmethods.length + 1];
975
976     System.arraycopy(declaredmethods, 0, scratch, 0, declaredmethods.length);
977
978     scratch[declaredmethods.length] = newMethod;
979     declaredmethods = scratch;
980     scratch = new Method[allmethods.length + 1];
981
982     System.arraycopy(allmethods, 0, scratch, 0, allmethods.length);
983
984     scratch[allmethods.length] = newMethod;
985     allmethods = scratch;
986
987     return newMethod;
988   }
989
990   /**
991    * Returns an array of Method objects reflecting all
992    * the methods declared by the class or interface
993    * represented by this Class object. This includes
994    * public, protected, default (package) access, and
995    * private methods, but excludes inherited methods.
996    * Returns an array of length 0 if the class or interface
997    * declares no methods, or if this Class object
998    * represents a primitive type.
999    * <p>
1000   * See The Java Language Specification, section 8.2.
1001   *
1002   * @return array of Method objects reflecting all
1003   * the methods declared by the class or interface
1004   * represented by this Class object.
1005   *
1006   * @throws SecurityException
1007   * if access to the information is denied.
1008   */

1009  public Method[] getDeclaredMethods() throws SecurityException JavaDoc
1010  {
1011
1012    if (realclass != null && declaredmethods == null)
1013    {
1014      java.lang.reflect.Method JavaDoc[] realDM = realclass.getDeclaredMethods();
1015
1016      declaredmethods = new Method[realDM.length];
1017
1018      for (int i = 0; i < realDM.length; ++i)
1019      {
1020        declaredmethods[i] = new Method(realDM[i], this);
1021      }
1022    }
1023
1024    return declaredmethods;
1025  }
1026
1027  /**
1028   * This method is not implemented in VAJava 3.0
1029   * <p>
1030   * If the class or interface represented by this Class
1031   * object is a member of another class, returns the
1032   * Class object representing the class of which it is a
1033   * member (its declaring class). Returns null if this
1034   * class or interface is not a member of any other
1035   * class.
1036   *
1037   */

1038  public Class JavaDoc getDeclaringClass()
1039  {
1040
1041    if (realclass != null && declaringclass == null)
1042    {
1043      java.lang.Class JavaDoc dc = realclass.getDeclaringClass();
1044
1045      if (dc == null)
1046        declaringclass = null;
1047      else
1048        declaringclass = forClass(dc);
1049    }
1050
1051    return declaringclass;
1052  }
1053
1054  /**
1055   * Declare that this class is an inner class of another.
1056   *
1057   * @param newclass
1058   *
1059   * @throws SynthesisException
1060   */

1061  private void addInnerClass(Class JavaDoc newclass) throws SynthesisException
1062  {
1063
1064    if (realclass != null)
1065      throw new SynthesisException(SynthesisException.REIFIED);
1066
1067    if (newclass.getDeclaringClass() != this)
1068      throw new SynthesisException(SynthesisException.WRONG_OWNER);
1069
1070    Class JavaDoc[] scratch = new Class JavaDoc[innerclasses.length + 1];
1071
1072    System.arraycopy(innerclasses, 0, scratch, 0, innerclasses.length);
1073
1074    scratch[innerclasses.length] = newclass;
1075    innerclasses = scratch;
1076  }
1077
1078  /**
1079   * Declare a class contained within this class. This doesn't
1080   * address anonymous classes (those go inside method bodies
1081   * and similar code), just local classes.
1082   * <p>
1083   * ***** This requires lookup methods that operate in the
1084   * context of a specific class, and per-class registries!
1085   *
1086   * @param className Local name of inner class to create. This should _not_ be a
1087   * qualified name, unlike the normal forName() call. Its
1088   * hierarchy is established by the class within which it is
1089   * created.
1090   * @return org.apache.xml.utils.synthetic.Class object for the contained class.
1091   * @throws org.apache.xml.utils.synthetic.SynthesisException if class could not be created.
1092   * @since 2/2000
1093   *
1094   * @throws SynthesisException
1095   */

1096  public Class JavaDoc declareInnerClass(String JavaDoc className) throws SynthesisException
1097  {
1098
1099    if (realclass != null)
1100      throw new SynthesisException(SynthesisException.REIFIED);
1101
1102    String JavaDoc relativeName = getName() + "$" + className;
1103    Class JavaDoc newclass = (Class JavaDoc) (global_classtable.get(relativeName));
1104
1105    if (newclass != null)
1106      throw new SynthesisException(SynthesisException.SYNTAX,
1107                                   "Inner class " + name + " already exists");
1108
1109    newclass = new Class JavaDoc(className);
1110    newclass.declaringclass = this;
1111
1112    Class JavaDoc[] scratch = new Class JavaDoc[innerclasses.length + 1];
1113
1114    System.arraycopy(innerclasses, 0, scratch, 0, innerclasses.length);
1115
1116    scratch[innerclasses.length] = newclass;
1117    innerclasses = scratch;
1118
1119    return newclass;
1120  }
1121
1122  /**
1123   * Fetch a list of classes contained within this class.
1124   * This doesn't address anonymous classes (those go
1125   * inside method bodies and similar code), just local classes.
1126   *
1127   * @return org.apache.xml.utils.synthetic.Class[] object for the contained classes.
1128   * This may be empty if none such exist, or if the class is
1129   * reified (since reflection doesn't report this information).
1130   * @since 3/2000
1131   */

1132  public Class JavaDoc[] getInnerClasses()
1133  {
1134    return innerclasses;
1135  }
1136
1137  /**
1138   * Returns a Field object that reflects the specified
1139   * public member field of the class or interface
1140   * represented by this Class object. The name
1141   * parameter is a String specifying the simple name of
1142   * the desired field.
1143   * <p>
1144   * The field to be reflected is located by searching all
1145   * the member fields of the class or interface
1146   * represented by this Class object for a public field
1147   * with the specified name.
1148   * <p>
1149   * See The Java Language Specification, sections 8.2
1150   * and 8.3.
1151   *
1152   *
1153   * @param name
1154   *
1155   * @throws NoSuchFieldException
1156   * if a field with the specified name is not
1157   * found.
1158   * @throws SecurityException
1159   * if access to the information is denied.
1160   */

1161  public Field getField(String JavaDoc name)
1162          throws NoSuchFieldException JavaDoc, SecurityException JavaDoc
1163  {
1164    throw new java.lang.IllegalStateException JavaDoc();
1165  }
1166
1167  /**
1168   * Returns an array containing Field objects
1169   * reflecting all the accessible public fields of the
1170   * class or interface represented by this Class object.
1171   * Returns an array of length 0 if the class or interface
1172   * has no accessible public fields, or if it represents
1173   * an array type or a primitive type.
1174   * <p>
1175   * Specifically, if this Class object represents a class,
1176   * returns the public fields of this class and of all its
1177   * superclasses. If this Class object represents an
1178   * interface, returns the fields of this interface and of
1179   * all its superinterfaces. If this Class object
1180   * represents an array type or a primitive type, returns
1181   * an array of length 0.
1182   * <p>
1183   * The implicit length field for array types is not
1184   * reflected by this method. User code should use the
1185   * methods of class Array to manipulate arrays.
1186   * <p>
1187   * See The Java Language Specification, sections 8.2
1188   * and 8.3.
1189   *
1190   *
1191   * @throws SecurityException
1192   * if access to the information is denied.
1193   */

1194  public Field[] getFields() throws SecurityException JavaDoc
1195  {
1196
1197    if (realclass != null && allfields == null)
1198    {
1199      java.lang.reflect.Field JavaDoc[] realDF = realclass.getFields();
1200
1201      allfields = new Field[realDF.length];
1202
1203      for (int i = 0; i < realDF.length; ++i)
1204      {
1205        allfields[i] = new Field(realDF[i], this);
1206      }
1207    }
1208
1209    return allfields;
1210  }
1211
1212  /**
1213   * Determines the interfaces implemented by the
1214   * class or interface represented by this object.
1215   * <p>
1216   * If this object represents a class, the return value is
1217   * an array containing objects representing all
1218   * interfaces implemented by the class. The order of
1219   * the interface objects in the array corresponds to the
1220   * order of the interface names in the implements
1221   * clause of the declaration of the class represented by
1222   * this object.
1223   * <p>
1224   * If this object represents an interface, the array
1225   * contains objects representing all interfaces
1226   * extended by the interface. The order of the
1227   * interface objects in the array corresponds to the
1228   * order of the interface names in the extends clause
1229   * of the declaration of the interface represented by
1230   * this object.
1231   * <p>
1232   * If the class or interface implements no interfaces,
1233   * the method returns an array of length 0.
1234   *
1235   * an array of interfaces implemented by this
1236   * class.
1237   */

1238  public Class JavaDoc[] getInterfaces()
1239  {
1240
1241    if (realclass != null && interfaces == null)
1242    {
1243      java.lang.Class JavaDoc[] realI = realclass.getInterfaces();
1244
1245      interfaces = new Class JavaDoc[realI.length];
1246
1247      for (int i = 0; i < realI.length; ++i)
1248      {
1249        interfaces[i] = forClass(realI[i]);
1250      }
1251    }
1252
1253    return interfaces;
1254  }
1255
1256  /**
1257   * Adds an "implements" description for the class or
1258   * interface represented by this Class object
1259   *
1260   *
1261   * @param newclass
1262   * @throws SynthesisException
1263   * if the class has been reified.
1264   */

1265  public void addImplements(Class JavaDoc newclass) throws SynthesisException
1266  {
1267
1268    if (realclass != null)
1269      throw new SynthesisException(SynthesisException.REIFIED);
1270
1271    Class JavaDoc[] scratch = new Class JavaDoc[interfaces.length + 1];
1272
1273    System.arraycopy(interfaces, 0, scratch, 0, interfaces.length);
1274
1275    scratch[interfaces.length] = newclass;
1276    interfaces = scratch;
1277  }
1278
1279  /**
1280   * Returns a Method object that reflects the specified
1281   * public member method of the class or interface
1282   * represented by this Class object. The name
1283   * parameter is a String specifying the simple name
1284   * the desired method, and the parameterTypes
1285   * parameter is an array of Class objects that identify
1286   * the method's formal parameter types, in declared
1287   * order.
1288   * <p>
1289   * The method to reflect is located by searching all
1290   * the member methods of the class or interface
1291   * represented by this Class object for a public
1292   * method with the specified name and exactly the
1293   * same formal parameter types.
1294   * <p>
1295   * See The Java Language Specification, sections 8.2
1296   * and 8.4.
1297   *
1298   *
1299   * @param name
1300   * @param parameterTypes
1301   *
1302   * @throws NoSuchMethodException
1303   * if a matching method is not found.
1304   * @throws SecurityException
1305   * if access to the information is denied.
1306   */

1307  public Method getMethod(String JavaDoc name, Class JavaDoc parameterTypes[])
1308          throws NoSuchMethodException JavaDoc, SecurityException JavaDoc
1309  {
1310    throw new java.lang.IllegalStateException JavaDoc();
1311  }
1312
1313  /**
1314   * Returns an array containing Method objects
1315   * reflecting all the public member methods of the
1316   * class or interface represented by this Class object,
1317   * including those declared by the class or interface
1318   * and and those inherited from superclasses and
1319   * superinterfaces. Returns an array of length 0 if the
1320   * class or interface has no public member methods.
1321   * <p>
1322   * See The Java Language Specification, sections 8.2
1323   * and 8.4.
1324   *
1325   *
1326   * @throws SecurityException
1327   * if access to the information is denied.
1328   */

1329  public Method[] getMethods() throws SecurityException JavaDoc
1330  {
1331
1332    if (realclass != null && allmethods == null)
1333    {
1334      java.lang.reflect.Method JavaDoc[] realDM = realclass.getMethods();
1335
1336      allmethods = new Method[realDM.length];
1337
1338      for (int i = 0; i < realDM.length; ++i)
1339      {
1340        allmethods[i] = new Method(realDM[i], this);
1341      }
1342    }
1343
1344    return allmethods;
1345  }
1346
1347  /**
1348   * Returns the Java language modifiers for this class
1349   * or interface, encoded in an integer. The modifiers
1350   * consist of the Java Virtual Machine's constants for
1351   * public, protected, private, final, and interface; they
1352   * should be decoded using the methods of class
1353   * Modifier.
1354   *
1355   * The modifier encodings are defined in The Java
1356   * Virtual Machine Specification, table 4.1.
1357   *
1358   * See Also:
1359   * java.lang.reflect.Modifier
1360   *
1361   */

1362  public int getModifiers()
1363  {
1364    return modifiers;
1365  }
1366
1367  /**
1368   * Set the Java language modifiers for this class
1369   * or interface, encoded in an integer. The modifiers
1370   * consist of the Java Virtual Machine's constants for
1371   * public, protected, private, final, and interface; they
1372   * should be decoded using the methods of class
1373   * Modifier.
1374   *
1375   * The modifier encodings are defined in The Java
1376   * Virtual Machine Specification, table 4.1.
1377   *
1378   * See Also:
1379   * java.lang.reflect.Modifier
1380   *
1381   * @param modifiers
1382   *
1383   * @throws SynthesisException
1384   */

1385  public void setModifiers(int modifiers) throws SynthesisException
1386  {
1387
1388    if (this.realclass != null)
1389      throw new SynthesisException(SynthesisException.REIFIED);
1390
1391    this.modifiers = modifiers;
1392  }
1393
1394  /**
1395   * Retrieve the fully-qualified classname. If it's an array,
1396   * it will be returned in JVM syntax, not Java syntax.
1397   *
1398   * @return java.lang.String
1399   * @since 12/95
1400   */

1401  public java.lang.String JavaDoc getName()
1402  {
1403    return name;
1404  }
1405
1406  /**
1407   * Like getName, but back-convert array notation escapes.
1408   * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
1409   *
1410   * @return java.lang.String
1411   * @since 3/2000
1412   */

1413  public java.lang.String JavaDoc getJavaName()
1414  {
1415
1416    if (name.charAt(0) != '[')
1417      return name;
1418
1419    // Object array syntax is [Ltypename;
1420
// add another [ for each level of array
1421
int count = name.lastIndexOf('[');
1422    StringBuffer JavaDoc jname = new StringBuffer JavaDoc(name.substring(count + 2));
1423
1424    // Trim the trailing ';'
1425
jname.setLength(jname.length() - 1);
1426
1427    while (count-- >= 0)
1428    {
1429      jname.append("[]");
1430    }
1431
1432    return jname.toString();
1433  }
1434
1435  /**
1436   * Extract just the local name of this class, minus the package
1437   * prefix.
1438   *
1439   * ***** I don't think this handles array types properly yet.
1440   *
1441   * @return java.lang.String
1442   * @since 12/99
1443   */

1444  public java.lang.String JavaDoc getShortName()
1445  {
1446
1447    int start = name.lastIndexOf(".");
1448
1449    if (start != 0 || name.charAt(0) == '.')
1450      ++start;
1451
1452    if (declaringclass != null)
1453    {
1454      int d = name.lastIndexOf('$', start);
1455
1456      if (d != 0)
1457        start = d + 1;
1458    }
1459
1460    return name.substring(start);
1461  }
1462
1463  /**
1464   * Like getShortName, but back-convert array notation escapes.
1465   * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
1466   *
1467   * @return java.lang.String
1468   * @since 3/2000
1469   */

1470  public java.lang.String JavaDoc getJavaShortName()
1471  {
1472
1473    String JavaDoc shortname = getShortName();
1474
1475    if (shortname.charAt(0) != '[')
1476      return shortname;
1477
1478    // Object array syntax is [Ltypename;
1479
// add another [ for each level of array
1480
int count = shortname.lastIndexOf('[');
1481    StringBuffer JavaDoc jname = new StringBuffer JavaDoc(shortname.substring(count + 2));
1482
1483    // Trim the trailing ';'
1484
jname.setLength(jname.length() - 1);
1485
1486    while (count-- >= 0)
1487    {
1488      jname.append("[]");
1489    }
1490
1491    return jname.toString();
1492  }
1493
1494  /**
1495   * Extract the package name for this class.
1496   * ***** I don't think this handles array classes properly yet.
1497   *
1498   * @return java.lang.String
1499   * @since 12/95
1500   */

1501  public java.lang.String JavaDoc getPackageName()
1502  {
1503
1504    int start = name.lastIndexOf(".");
1505
1506    return name.substring(0, start);
1507  }
1508
1509  /**
1510   * If this synthetic class is a wrapper for a "real"
1511   * java.lang.Class -- either because it was instantiated as such
1512   * or because it has been compiled -- this method will return
1513   * that class. Otherwise it returns null.
1514   * Creation date: (12-25-99 12:26:01 PM)
1515   * @return org.apache.xml.utils.synthetic.Class
1516   */

1517  public java.lang.Class JavaDoc getRealClass()
1518  {
1519    return realclass;
1520  }
1521
1522  /**
1523   * This call is intended to allow an existing org.apache.xml.utils.synthetic.Class
1524   * to be switched from purely descriptive mode to proxy mode
1525   * ("reified").
1526   * The primary intent is to allow a org.apache.xml.utils.synthetic.Class to be
1527   * "compiled in place"
1528   * <p>
1529   * This should have the side-effect of limiting further mutation
1530   * of the org.apache.xml.utils.synthetic.Class to things which can not be obtained
1531   * from the real Class object, to avoid "lying" to the user
1532   * <p>
1533   * NOTE: Not all information defined by the Java libraries is
1534   * in fact available in all Java environments. We assume the
1535   * calls will work; if they return null or empty lists, there's
1536   * nothing we can do about it. Note that this may mean that a
1537   * reified class tells us less about itself than the
1538   * synthetic description used to generate it.
1539   * <p>
1540   * Creation date: (12-25-99 12:26:01 PM)
1541   * @param java.lang.class realclass nonsynthetic Class object to proxy
1542   *
1543   * @param realclass
1544   *
1545   * @throws SynthesisException
1546   */

1547  public void setRealClass(java.lang.Class JavaDoc realclass)
1548          throws SynthesisException
1549  {
1550
1551    if (this.realclass != null)
1552      throw new SynthesisException(SynthesisException.REIFIED);
1553
1554    this.realclass = realclass;
1555    this.modifiers = realclass.getModifiers();
1556    this.isInterface = realclass.isInterface();
1557
1558    // DEFERRED -- set them null now, reconstruct when requested
1559
this.declaringclass = null;
1560    this.interfaces = null;
1561    this.declaredconstructors = null;
1562    this.allconstructors = null;
1563    this.declaredmethods = null;
1564    this.allmethods = null;
1565    this.declaredfields = null;
1566    this.allfields = null;
1567    this.declaredclasses = null;
1568    this.allclasses = null;
1569    this.superclass = null;
1570  }
1571
1572  /**
1573   * Set the superclass for this synthetic class.
1574   * Object is equivalent to Null.
1575   * Creation date: (12-25-99 12:26:01 PM)
1576   *
1577   * @param superclass
1578   * @return org.apache.xml.utils.synthetic.Class
1579   *
1580   * @throws SynthesisException
1581   */

1582  public void setSuperClass(Class JavaDoc superclass) throws SynthesisException
1583  {
1584
1585    if (realclass != null)
1586      throw new SynthesisException(SynthesisException.REIFIED);
1587
1588    this.superclass = superclass;
1589  }
1590
1591  /**
1592   * Set the superclass for this synthetic class.
1593   * Creation date: (12-25-99 12:26:01 PM)
1594   *
1595   * @param superclass
1596   * @return org.apache.xml.utils.synthetic.Class
1597   *
1598   * @throws ClassNotFoundException
1599   * @throws SynthesisException
1600   */

1601  public void setSuperClass(java.lang.Class JavaDoc superclass)
1602          throws ClassNotFoundException JavaDoc, SynthesisException
1603  {
1604
1605    if (realclass != null)
1606      throw new SynthesisException(SynthesisException.REIFIED);
1607
1608    this.superclass = Class.forClass(superclass);
1609  }
1610
1611  /**
1612   * Finds a resource with the specified name. The
1613   * rules for searching for resources associated with a
1614   * given class are implemented by the class loader of
1615   * the class.
1616   * <p>
1617   * The Class methods delegate to ClassLoader
1618   * methods, after applying a naming convention: if
1619   * the resource name starts with "/", it is used as is.
1620   * Otherwise, the name of the package is prepended,
1621   * after converting "." to "/".
1622   *
1623   * @param
1624   * name - the string representing the resource to
1625   * be found.
1626   * the URL object having the specified name, or
1627   * null if no resource with the specified name
1628   * is found.
1629   */

1630  public java.net.URL JavaDoc getResource(String JavaDoc name)
1631  {
1632    throw new java.lang.IllegalStateException JavaDoc();
1633  }
1634
1635  /**
1636   * Finds a resource with a given name. Will return
1637   * null if no resource with this name is found. The
1638   * rules for searching a resources associated with a
1639   * given class are implemented by the ClassLoader of
1640   * the class.
1641   * <p>
1642   * The Class methods delegate to ClassLoader
1643   * methods, after applying a naming convention: if
1644   * the resource name starts with "/", it is used as is.
1645   * Otherwise, the name of the package is prepended,
1646   * after converting "." to "/".
1647   *
1648   * @param
1649   * name - the string representing the resource to
1650   * be found
1651   * the InputStream object having the
1652   * specified name, or null if no resource with
1653   * the specified name is found.
1654   */

1655  public java.io.InputStream JavaDoc getResourceAsStream(String JavaDoc name)
1656  {
1657    throw new java.lang.IllegalStateException JavaDoc();
1658  }
1659
1660  /**
1661   * Get the signers of this class.
1662   *
1663   */

1664  public Object JavaDoc[] getSigners()
1665  {
1666    throw new java.lang.IllegalStateException JavaDoc();
1667  }
1668
1669  /**
1670   * If this object represents any class other than the
1671   * class Object, then the object that represents the
1672   * superclass of that class is returned.
1673   * <p>
1674   * If this object is the one that represents the class
1675   * Object or this object represents an interface, null is
1676   * returned.
1677   *
1678   * the superclass of the class represented by this
1679   * object.
1680   */

1681  public Class JavaDoc getSuperclass()
1682  {
1683
1684    if (realclass != null && superclass == null)
1685    {
1686      superclass = forClass(realclass.getSuperclass());
1687
1688      // getDeclaredClasses(); // Sets superclass as a side-effect
1689
}
1690
1691    if (superclass == null)
1692      superclass = forClass(Object JavaDoc.class);
1693
1694    return superclass;
1695  }
1696
1697  /**
1698   * If this Class object represents an array type, returns
1699   * true, otherwise returns false.
1700   *
1701   */

1702  public boolean isArray()
1703  {
1704    return realclass != null && realclass.isArray();
1705  }
1706
1707  /**
1708   * Determines if the class or interface represented by
1709   * this Class object is either the same as, or is a
1710   * superclass or superinterface of, the class or
1711   * interface represented by the specified Class
1712   * parameter. It returns true if so, false otherwise. If
1713   * this Class object represents a primitive type,
1714   * returns true if the specified Class parameter is
1715   * exactly this Class object, false otherwise.
1716   * <p>
1717   * Specifically, this method tests whether the type
1718   * represented by the specified Class parameter can
1719   * be converted to the type represented by this Class
1720   * object via an identity conversion or via a widening
1721   * reference conversion. See The Java Language
1722   * Specification, sections 5.1.1 and 5.1.4 , for details.
1723   *
1724   *
1725   * @param cls
1726   *
1727   * @throws NullPointerException if the specified Class parameter is null.
1728   */

1729  public boolean isAssignableFrom(Class JavaDoc cls)
1730  {
1731
1732    if (realclass != null && cls.realclass != null)
1733      return realclass.isAssignableFrom(cls.realclass);
1734
1735    throw new java.lang.IllegalStateException JavaDoc();
1736  }
1737
1738  /**
1739   * Determines if the class or interface represented by
1740   * this Class object is either the same as, or is a
1741   * superclass or superinterface of, the class or
1742   * interface represented by the specified Class
1743   * parameter. It returns true if so, false otherwise. If
1744   * this Class object represents a primitive type,
1745   * returns true if the specified Class parameter is
1746   * exactly this Class object, false otherwise.
1747   * <p>
1748   * Specifically, this method tests whether the type
1749   * represented by the specified Class parameter can
1750   * be converted to the type represented by this Class
1751   * object via an identity conversion or via a widening
1752   * reference conversion. See The Java Language
1753   * Specification, sections 5.1.1 and 5.1.4 , for details.
1754   *
1755   *
1756   * @param cls
1757   *
1758   * @throws NullPointerException if the specified Class parameter is null.
1759   */

1760  public boolean isAssignableFrom(java.lang.Class JavaDoc cls)
1761  {
1762
1763    if (realclass != null)
1764      return realclass.isAssignableFrom((java.lang.Class JavaDoc) cls);
1765
1766    throw new java.lang.IllegalStateException JavaDoc();
1767  }
1768
1769  /**
1770   * This method is the dynamic equivalent of the Java
1771   * language instanceof operator. The method
1772   * returns true if the specified Object argument is
1773   * non-null and can be cast to the reference type
1774   * represented by this Class object without raising a
1775   * ClassCastException. It returns false otherwise.
1776   * <p>
1777   * Specifically, if this Class object represents a
1778   * declared class, returns true if the specified Object
1779   * argument is an instance of the represented class (or
1780   * of any of its subclasses); false otherwise. If this
1781   * Class object represents an array class, returns true
1782   * if the specified Object argument can be converted
1783   * to an object of the array type by an identity
1784   * conversion or by a widening reference conversion;
1785   * false otherwise. If this Class object represents an
1786   * interface, returns true if the class or any superclass
1787   * of the specified Object argument implements this
1788   * interface; false otherwise. If this Class object
1789   * represents a primitive type, returns false.
1790   *
1791   * @param obj The object to check
1792   *
1793   */

1794  public boolean isInstance(Object JavaDoc obj)
1795  {
1796
1797    if (realclass != null)
1798      return realclass.isInstance(obj);
1799
1800    // Scan inheritances? (reliable).
1801
// Check name? (not reliable).
1802
throw new java.lang.IllegalStateException JavaDoc();
1803  }
1804
1805  /**
1806   * Determines if the specified Class object represents
1807   * an interface type.
1808   *
1809   * true if this object represents an interface;
1810   * false otherwise.
1811   */

1812  public boolean isInterface()
1813  {
1814    return (realclass != null) ? realclass.isInterface() : isInterface;
1815  }
1816
1817  /**
1818   * Assert that the specified Class object represents
1819   * an interface type. Can't be changed after real class loaded.
1820   *
1821   * @param
1822   * true if this object represents an interface;
1823   * false otherwise.
1824   *
1825   * @param isInterface
1826   *
1827   * @throws SynthesisException
1828   */

1829  public void isInterface(boolean isInterface) throws SynthesisException
1830  {
1831
1832    if (realclass == null)
1833      this.isInterface = isInterface;
1834    else if (realclass.isInterface() != isInterface)
1835      throw new SynthesisException(SynthesisException.REIFIED);
1836  }
1837
1838  /**
1839   * Determines if the specified Class object represents
1840   * a primitive Java type.
1841   * <p>
1842   * There are nine predefined Class objects to
1843   * represent the eight primitive Java types and void.
1844   * These are created by the Java Virtual Machine, and
1845   * have the same names as the primitive types that
1846   * they represent, namely boolean, byte, char, short,
1847   * int, long, float, and double, and void.
1848   * <p>
1849   * These objects may only be accessed via the
1850   * following public static final variables, and are the
1851   * only Class objects for which this method returns
1852   * true.
1853   *
1854   */

1855  public boolean isPrimitive()
1856  {
1857    return realclass != null && realclass.isPrimitive();
1858  }
1859
1860  /**
1861   * Creates a new instance of a class.
1862   *
1863   * a newly allocated instance of the class
1864   * represented by this object. This is done
1865   * exactly as if by a new expression with an
1866   * empty argument list.
1867   * @throws IllegalAccessException
1868   * if the class or initializer is not accessible.
1869   * @throws InstantiationException
1870   * if an application tries to instantiate an
1871   * abstract class or an interface, or if the
1872   * instantiation fails for some other reason.
1873   */

1874  public Object JavaDoc newInstance()
1875          throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
1876  {
1877    throw new java.lang.IllegalStateException JavaDoc();
1878  }
1879
1880  /**
1881   * Converts the object to a string. The string
1882   * representation is the string "class" or
1883   * "interface" followed by a space and then the
1884   * fully qualified name of the class. If this Class
1885   * object represents a primitive type, returns the
1886   * name of the primitive type.
1887   * <p>
1888   * Should this say "synthetic" as well as "class" or
1889   * "interface"? Or should that be gated on whether we're proxy
1890   * to a realclass?
1891   *
1892   * @return a string representation of this class object.
1893   */

1894  public String JavaDoc toString()
1895  {
1896
1897    if (realclass != null)
1898      return realclass.toString();
1899    else if (isInterface())
1900      return "interface " + name;
1901    else
1902      return "class " + name;
1903  }
1904
1905  /**
1906   * Convenience for writing to, eg, System.out
1907   *
1908   * @param out
1909   * @param depth
1910   */

1911  public void toSource(java.io.OutputStream JavaDoc out, int depth)
1912  {
1913
1914    java.io.PrintWriter JavaDoc writer = new java.io.PrintWriter JavaDoc(out);
1915
1916    toSource(writer, depth);
1917  }
1918
1919  /**
1920   * Converts the object to a Java code stream. The string
1921   * representation is as full a Java definition of the class
1922   * as we are able to achieve. If this Class
1923   * object represents a primitive type, returns the
1924   * name of the primitive type.
1925   *
1926   * @param out
1927   * @param depth
1928   */

1929  public void toSource(java.io.PrintWriter JavaDoc out, int depth)
1930  {
1931
1932    String JavaDoc tab = tabset(depth);
1933
1934    if (realclass != null)
1935      out.println(
1936        tab
1937        + "/** Code back-generated from a \"real\" Class; accuracy limited by reflection APIs. */");
1938    else
1939      out.println(
1940        tab
1941        + "/** Code generated via org.apache.xml.utils.synthetic.Class */");
1942
1943    /* Package should not be printed for inner classes */
1944    if (getDeclaringClass() == null)
1945      out.println(tab + "package " + getPackageName() + ";");
1946
1947    out.print(tab + Modifier.toString(getModifiers()));
1948
1949    if (isInterface())
1950      out.print(" interface ");
1951    else
1952      out.print(" class ");
1953
1954    out.println(getJavaShortName());
1955
1956    if (superclass != null)
1957    {
1958      out.print('\n' + tab + " extends " + superclass.getJavaName());
1959    }
1960
1961    Class JavaDoc[] ext = getInterfaces();
1962
1963    if (ext != null & ext.length > 0)
1964    {
1965
1966      // Interfaces extend other interfaces,
1967
// Classes implement interfaces.
1968
out.print('\n' + tab + (isInterface ? " extends " : " implements ")
1969                + ext[0].getName());
1970
1971      for (int i = 1; i < ext.length; ++i)
1972      {
1973        out.print(", " + ext[i].getJavaName());
1974      }
1975
1976      out.print("\n");
1977    }
1978
1979    out.print(tab + "{\n");
1980
1981    tab = tabset(++depth);
1982
1983    // Fields--------------------------------
1984
Field[] fields = null;
1985
1986    try
1987    {
1988      fields = getDeclaredFields();
1989    }
1990    catch (SecurityException JavaDoc e)
1991    {
1992      out.println(tab + "//SecurityException retrieving fields");
1993    }
1994
1995    if (fields != null)
1996    {
1997      for (int i = 0; i < fields.length; ++i)
1998      {
1999        out.println(tab + fields[i].toSource());
2000      }
2001    }
2002
2003    // Constructors--------------------------
2004
Constructor[] ctors = null;
2005
2006    try
2007    {
2008      ctors = getDeclaredConstructors();
2009    }
2010    catch (SecurityException JavaDoc e)
2011    {
2012      out.println(tab + "//SecurityException retrieving ctors");
2013    }
2014
2015    if (ctors != null)
2016    {
2017      for (int i = 0; i < ctors.length; ++i)
2018      {
2019        out.print(ctors[i].toSource(tab));
2020      }
2021    }
2022
2023    // Methods-------------------------------
2024
Method[] methods = null;
2025
2026    try
2027    {
2028      methods = getDeclaredMethods();
2029    }
2030    catch (SecurityException JavaDoc e)
2031    {
2032      out.println(tab + "//SecurityException retrieving methods");
2033    }
2034
2035    if (methods != null)
2036    {
2037      for (int i = 0; i < methods.length; ++i)
2038      {
2039        out.print('\n');
2040        out.print(methods[i].toSource(tab));
2041      }
2042    }
2043
2044    // Inner classes --------------------------------
2045
Class JavaDoc[] inners = getInnerClasses();
2046
2047    if (inners != null)
2048    {
2049      for (int i = 0; i < inners.length; ++i)
2050      {
2051        out.print('\n');
2052        inners[i].toSource(out, depth);
2053      }
2054    }
2055
2056    // Done------------------------------
2057
tab = tabset(--depth);
2058
2059    out.print(tab + "}\n");
2060    out.flush();
2061  }
2062
2063  /**
2064   * Method tabset
2065   *
2066   *
2067   * @param depth
2068   *
2069   * (tabset) @return
2070   */

2071  private String JavaDoc tabset(int depth)
2072  {
2073
2074    StringBuffer JavaDoc t = new StringBuffer JavaDoc();
2075
2076    while (depth-- > 0)
2077    {
2078      t.append(" ");
2079    }
2080
2081    return t.toString();
2082  }
2083
2084  // Ignores any keywords we don't recognize
2085

2086  /** Field val */
2087  static final int[] val = { Modifier.ABSTRACT, Modifier.FINAL,
2088                             Modifier.INTERFACE, Modifier.NATIVE,
2089                             Modifier.PRIVATE, Modifier.PROTECTED,
2090                             Modifier.PUBLIC, Modifier.STATIC,
2091                             Modifier.SYNCHRONIZED, Modifier.TRANSIENT,
2092                             Modifier.VOLATILE };
2093
2094  /** Field kwd */
2095  static final String JavaDoc[] kwd = { "abstract", "final", "interface", "native",
2096                                "private", "protected", "public", "static",
2097                                "synchronized", "transient", "volatile" };
2098
2099  /**
2100   * Method modifierFromString
2101   *
2102   *
2103   * @param t
2104   *
2105   * (modifierFromString) @return
2106   */

2107  static public int modifierFromString(String JavaDoc t)
2108  {
2109
2110    for (int i = 0; i < kwd.length; ++i)
2111    {
2112      if (kwd[i].equals(t))
2113        return val[i];
2114    }
2115
2116    return 0;
2117  }
2118
2119  /**
2120   * Method modifiersFromString
2121   *
2122   *
2123   * @param s
2124   *
2125   * (modifiersFromString) @return
2126   */

2127  static public int modifiersFromString(String JavaDoc s)
2128  {
2129
2130    int mods = 0;
2131    java.util.StringTokenizer JavaDoc parts = new java.util.StringTokenizer JavaDoc(s);
2132
2133    while (parts.hasMoreTokens())
2134    {
2135      String JavaDoc t = parts.nextToken();
2136
2137      mods |= modifierFromString(t);
2138    }
2139
2140    return mods;
2141  }
2142}
2143
Popular Tags