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 com.sun.org.apache.xml.internal.utils.synthetic;
  20. import java.lang.reflect.Modifier;
  21. import com.sun.org.apache.xml.internal.utils.synthetic.reflection.Constructor;
  22. import com.sun.org.apache.xml.internal.utils.synthetic.reflection.Field;
  23. import com.sun.org.apache.xml.internal.utils.synthetic.reflection.Method;
  24. /* WORK NEEDED:
  25. Factories/Libraries: We currently have forClass and
  26. forName(request reified, complain if no real class),
  27. and declareClass (request unreified, create unreified
  28. if it doesn't exist). What about ther user expectations
  29. -- should we have a full matrix, rather than asking
  30. users to write wrappers?
  31. Reflection doesn't tell us about deprecation. If we want
  32. that info, MFC advises mousing our way into the bytecodes.
  33. (Ugh). Should we at least model that for synthetics?
  34. */
  35. /**
  36. * com.sun.org.apache.xml.internal.utils.synthetic.Class is a mutable equivalent of java.lang.Class.
  37. * Instances represent classes and interfaces in a running Java
  38. * application, or class descriptions under construction. In the
  39. * former case, com.sun.org.apache.xml.internal.utils.synthetic.Class operates as a proxy for the
  40. * "real" java.lang.Class object; in the latter, it consults
  41. * data structures defined in the com.sun.org.apache.xml.internal.utils.synthetic.reflection.* package.
  42. * <p>
  43. * Unlike java.lang.Class, com.sun.org.apache.xml.internal.utils.synthetic.Class has a pair of factories
  44. * (fromName and fromClass). It can also be switched from synthetic
  45. * to proxy operation after construction, by setting the realClass
  46. * property; this is intended to allow these definitions to be
  47. * "compiled in place".
  48. * <p>
  49. * For convenient use, com.sun.org.apache.xml.internal.utils.synthetic.Class implements an extended
  50. * version of the java.lang.Class API -- but is not a subclass
  51. * thereof, since java.lang.Class is Final (presumably for
  52. * security reasons).
  53. * <p>
  54. * DEVELOPMENT NOTE: Methods not yet implemented will throw
  55. * IllegalStateException
  56. * <p>
  57. * I've added code to convert primitive names into their TYPEs,
  58. * to accept foo[] as a synonym for [Lfoo, and to generate
  59. * the right thing on output (getJava[Short]Name).
  60. * Useful extension for code generation from Java-like
  61. * source. We may want to factor these and toSource out, making
  62. * com.sun.org.apache.xml.internal.utils.synthetic.Class addess only the JVM level and providing
  63. * subclasses or access tools that handle language syntax
  64. * (Java source, NetRexx source, etc.)
  65. *
  66. * @since 2000/2/10
  67. * @xsl.usage internal
  68. */
  69. public class Class extends Object implements java.io.Serializable
  70. {
  71. /** Class descriptions currently existing. */
  72. private static java.util.Hashtable global_classtable =
  73. new java.util.Hashtable();
  74. /** fully-qualified path.classname.
  75. * @serial */
  76. private java.lang.String name;
  77. /**
  78. * Actual Java class object. When present, all interactions
  79. * are redirected to it. Allows our Class to function as a
  80. * wrapper for the Java version (in lieu of subclassing or
  81. * a shared Interface), and allows "in-place compilation"
  82. * to replace a generated description with an
  83. * directly runnable class.
  84. * @serial
  85. */
  86. private java.lang.Class realclass = null;
  87. /** Field modifiers: Java language modifiers for this class
  88. * or interface, encoded in an integer.
  89. * @serial
  90. */
  91. private int modifiers;
  92. /** Field isInterface: True if the Class object represents
  93. * an interface type.
  94. * @serial */
  95. private boolean isInterface = false;
  96. /** Field superclass: If this object represents the class
  97. * Object, this is null. Otherwise, the Class object that
  98. * represents the superclass of that class. In proxy mode this
  99. * is determined when needed. In synthesis mode it's explicitly
  100. * set by the user, and if null the superclass will be assumed
  101. * to be Object.
  102. * @serial */
  103. private Class superclass = null;
  104. /** Field declaringclass: If this object represents an inner class,
  105. * the Class object that represents the class that declared it.
  106. * Otherwise null.
  107. * @serial
  108. * */
  109. private Class declaringclass = null;
  110. /** Field interfaces: A list of all interfaces implemented by the class
  111. * or interface represented by this object.
  112. * @serial
  113. * */
  114. private Class[] interfaces = new Class[0];
  115. /** Field allclasses: an array containing Class objects representing all
  116. * the public classes and interfaces that are members of the class
  117. * represented by this Class object.
  118. * @serial
  119. */
  120. private Class[] allclasses = new Class[0];
  121. /** Field declaredclasses: an array of Class objects reflecting all the
  122. * classes and interfaces declared as members of the class represented
  123. * by this Class object. Excludes inherited classes and interfaces.
  124. * @serial
  125. */
  126. private Class[] declaredclasses = new Class[0];
  127. /** Field allconstructors: an array containing Constructor objects
  128. * reflecting all the constructors of the class represented
  129. * by this Class object. An array of length 0 is returned if the
  130. * class has no public constructors. In proxy mode only public
  131. * constructors will be displayed; in synthesis mode, all declared
  132. * constructors will be displayed.
  133. * @serial
  134. * */
  135. private Constructor[] allconstructors = new Constructor[0];
  136. /** Field declaredconstructors: an array of Constructor objects
  137. * reflecting all the constructors declared by the class
  138. * represented by this Class object. Includes non-public
  139. * constructors, but excludes inherited ones.
  140. * @serial
  141. * */
  142. private Constructor[] declaredconstructors = new Constructor[0];
  143. /** Field allmethods.
  144. * @serial */
  145. private Method[] allmethods = new Method[0];
  146. /** Field declaredmethods.
  147. * @serial */
  148. private Method[] declaredmethods = new Method[0];
  149. /** Field allfields.
  150. * @serial */
  151. private Field[] allfields = new Field[0];
  152. /** Field declaredfields.
  153. * @serial */
  154. private Field[] declaredfields = new Field[0];
  155. /** Field innerclasses.
  156. * @serial */
  157. private Class[] innerclasses = new Class[0];
  158. /**
  159. * Construct a synthetic class as proxy/wrapper for an existing
  160. * Java Class. Non-public; most folks should use
  161. * .forName and .forClass to request these wrappers, so they
  162. * get the shared instances.
  163. * <p>
  164. * Creation date: (12-25-99 12:16:15 PM)
  165. * @param realclass java.lang.Class
  166. */
  167. Class(java.lang.Class realclass)
  168. {
  169. this(realclass.getName());
  170. try
  171. {
  172. setRealClass(realclass);
  173. }
  174. catch (SynthesisException e)
  175. {
  176. e.printStackTrace();
  177. }
  178. }
  179. /**
  180. * Construct a named-but-empty synthetic Class object.
  181. * Non-public; most folks should use
  182. * .forName and .forClass to request these wrappers, so they
  183. * get the shared instances.
  184. * <p>
  185. * Creation date: (12-25-99 12:15:23 PM)
  186. *
  187. * @param fullname full name of the class that is synthetized.
  188. */
  189. Class(String fullname)
  190. {
  191. this.name = fullname;
  192. global_classtable.put(fullname, this);
  193. }
  194. /**
  195. * Returns the synthetic Class object associated with the "real"
  196. * class specified, creating one if it didn't already exist.
  197. * <p>
  198. * For example, the following code fragment returns
  199. * the runtime Class descriptor for the class named
  200. * mypackage.MyClass.
  201. * <code>
  202. * Class t =
  203. * Class.forName(java.lang.Class.forName("mypackage.MyClass"))
  204. * </code>
  205. * <p>
  206. * Note that if the user has manually created a com.sun.org.apache.xml.internal.utils.synthetic.Class
  207. * with the same name before this call is issued, that object
  208. * will be found instead. See also the declareClass call.
  209. * <p>
  210. * We need a better way to declare/define array classes,
  211. * given a class object (synthetic or not).
  212. *
  213. * @param cls the desired Java class.
  214. * @return the synthetic Class descriptor for the specified class.
  215. */
  216. public static Class forClass(java.lang.Class cls)
  217. {
  218. if (cls == null)
  219. return null;
  220. Class ret = (Class) (global_classtable.get(cls.getName()));
  221. if (null == ret)
  222. ret = new Class(cls);
  223. return ret;
  224. }
  225. /**
  226. * Like forName, but if the classname doesn't have a package
  227. * prefix we first attempt to look it up as one of our own
  228. * inner clases. As with forName, if this can not be resolved
  229. * we throw an exception.
  230. *
  231. * @param classname the full or partial class name.
  232. *
  233. * @return The Class name that matches the argument.
  234. *
  235. * @throws ClassNotFoundException
  236. */
  237. public Class forNameInContext(String classname)
  238. throws ClassNotFoundException
  239. {
  240. for (int i = innerclasses.length - 1; i >= 0; --i)
  241. {
  242. if (classname.equals(innerclasses[i].getShortName()))
  243. return innerclasses[i];
  244. }
  245. return forName(classname);
  246. }
  247. /**
  248. * Returns the synthetic Class object associated with the class
  249. * with the given fully-qualified name. If there isn't one, this
  250. * method attempts to locate, load and link the standard java Class.
  251. * If it succeeds, it returns a wrapped version of the Class object
  252. * representing the class. If it fails, the method throws a
  253. * ClassNotFoundException.
  254. * <p>
  255. * For example, the following code fragment returns
  256. * the runtime Class descriptor for the class named
  257. * mypackage.MyClass -- either as a synthetic or as
  258. * a standard Java class.
  259. * <code>
  260. * Class t =
  261. * Class.forName("mypackage.MyClass")
  262. * </code>
  263. * <p>
  264. * I've added support for arrays -- assuming any name
  265. * that ends with ']' is an array. It probably needs to be
  266. * made smarter, possibly via a subclass of com.sun.org.apache.xml.internal.utils.synthetic.Class.
  267. *
  268. * @param className the fully qualified name of the desired class.
  269. * @return the synthetic Class descriptor for the class with the specified name.
  270. * @throws ClassNotFoundException if the class could not be found.
  271. */
  272. public static Class forName(String className) throws ClassNotFoundException
  273. {
  274. // ***** Experimental support for array syntax expressed
  275. // per Java source rather than per JVM type formalism.
  276. // Simpleminded, asssumes balanced []'s.
  277. if (className.endsWith("]"))
  278. {
  279. StringBuffer arrayname = new StringBuffer();
  280. for (int i = className.indexOf('['); i != -1;
  281. i = className.indexOf('[', i + 1))
  282. {
  283. arrayname.append('[');
  284. }
  285. // Convert the classname to array-formalism
  286. // Primitives have letters; objects are Lname;
  287. // (Don't ask why long is spelled with a J and
  288. // object is spelled with an L...)
  289. String classname = className.substring(0, className.indexOf('['));
  290. if ("byte".equals(classname))
  291. arrayname.append('B');
  292. else if ("char".equals(classname))
  293. arrayname.append('C');
  294. else if ("double".equals(classname))
  295. arrayname.append('D');
  296. else if ("float".equals(classname))
  297. arrayname.append('F');
  298. else if ("int".equals(classname))
  299. arrayname.append('I');
  300. else if ("long".equals(classname))
  301. arrayname.append('J');
  302. else if ("short".equals(classname))
  303. arrayname.append('S');
  304. else if ("boolean".equals(classname))
  305. arrayname.append('Z');
  306. else
  307. arrayname.append('L').append(classname).append(';');
  308. // Tail-call.
  309. return forName(arrayname.toString());
  310. }
  311. Class ret = (Class) (global_classtable.get(className));
  312. if (null == ret)
  313. {
  314. // ***** Experimental support for Java primitives
  315. // Seems to me that mapping them into the "Type" is
  316. // probably most useful
  317. if ("boolean".equals(className))
  318. {
  319. ret = new Class(className);
  320. ret.realclass = java.lang.Boolean.TYPE;
  321. }
  322. else if ("byte".equals(className))
  323. {
  324. ret = new Class(className);
  325. ret.realclass = java.lang.Byte.TYPE;
  326. }
  327. else if ("char".equals(className))
  328. {
  329. ret = new Class(className);
  330. ret.realclass = java.lang.Character.TYPE;
  331. }
  332. else if ("short".equals(className))
  333. {
  334. ret = new Class(className);
  335. ret.realclass = java.lang.Short.TYPE;
  336. }
  337. else if ("int".equals(className))
  338. {
  339. ret = new Class(className);
  340. ret.realclass = java.lang.Integer.TYPE;
  341. }
  342. else if ("long".equals(className))
  343. {
  344. ret = new Class(className);
  345. ret.realclass = java.lang.Long.TYPE;
  346. }
  347. else if ("float".equals(className))
  348. {
  349. ret = new Class(className);
  350. ret.realclass = java.lang.Float.TYPE;
  351. }
  352. else if ("double".equals(className))
  353. {
  354. ret = new Class(className);
  355. ret.realclass = java.lang.Double.TYPE;
  356. }
  357. else if ("void".equals(className))
  358. {
  359. // ***** Void is an "absence of type". We might want to create
  360. // a special object to represent it. This is a placeholder.
  361. ret = new Class(className);
  362. ret.realclass = java.lang.Class.forName("java.lang.Object");
  363. }
  364. // Other classes are just wrappered. Unknown classes throw a
  365. // ClassNotFoundException; the user can switch to declareClass()
  366. // if they're sure that an unreified class is OK.
  367. else
  368. ret = new Class(java.lang.Class.forName(className));
  369. }
  370. return ret;
  371. }
  372. /**
  373. * Start to create a synthetic Class with the given fully-qualified
  374. * name. If a Class by that name already exists, and it is not
  375. * reified, it will be returned instead. If a reified Class _does_
  376. * exist, we throw a synthesis exception.
  377. *
  378. * @param className the fully qualified name of the desired class.
  379. * @return the synthetic Class descriptor for the class with the specified name.
  380. * @throws SynthesisException if the class has been reified.
  381. */
  382. public static Class declareClass(String className) throws SynthesisException
  383. {
  384. Class ret = (Class) (global_classtable.get(className));
  385. if (null == ret)
  386. ret = new Class(className);
  387. if (ret.realclass != null)
  388. throw new SynthesisException(SynthesisException.REIFIED);
  389. return ret;
  390. }
  391. /**
  392. * Start to create a synthetic Class with the given fully-qualified
  393. * name. If a Class by that name already exists,whether reified or
  394. * not, it will be removed from the table and replaced by the new synthesis.
  395. *
  396. * NOTE THAT the replacement will not affect classes which
  397. * have already refernced the old version. We could change that by
  398. * having everyone reference everyone else via an indirection table.
  399. *
  400. * @param className the fully qualified name of the desired class.
  401. * @return the synthetic Class descriptor for the class with the specified name.
  402. */
  403. public static Class reallyDeclareClass(String className)
  404. {
  405. Class ret = (Class) (global_classtable.get(className));
  406. if (null != ret)
  407. global_classtable.remove(ret);
  408. ret = new Class(className);
  409. return ret;
  410. }
  411. /**
  412. * Returns an array containing Class objects
  413. * representing all the public classes and interfaces
  414. * that are members of the class represented by this
  415. * Class object. This includes public class and
  416. * interface members inherited from superclasses and
  417. * public class and interface members declared by the
  418. * class. Returns an array of length 0 if the class has
  419. * no public member classes or interfaces, or if this
  420. * Class object represents a primitive type.
  421. * <p>
  422. * NOTE: In a significant number of existing Java environments,
  423. * this method is not implemented by the official Class object
  424. * and always returns an empty array. So if you don't get any
  425. * useful information from a proxied java.lang.Class, don't
  426. * be surprised. I'm not sure if someone decided it was a
  427. * potential security issue, or if Sun was lazy and everyone
  428. * else followed suit.
  429. * <p>
  430. * ALSO NOTE: The above spec, as taken from java.lang.Class,
  431. * doesn't provide any good way to distinguish the immediate
  432. * superclass from all other superclasses. That makes it only
  433. * marginally useful, which is no doubt one of the reasons folks
  434. * have declined to implement it.
  435. *
  436. * @return an array of classes.
  437. */
  438. public Class[] getClasses()
  439. {
  440. if (realclass != null && allclasses == null)
  441. {
  442. java.lang.Class[] realDE = realclass.getClasses();
  443. allclasses = new Class[realDE.length];
  444. for (int i = 0; i < realDE.length; ++i)
  445. {
  446. allclasses[i] = forClass(realDE[i]);
  447. }
  448. }
  449. return allclasses;
  450. }
  451. /**
  452. * Determines the class loader for the class.
  453. *
  454. * the class loader that created the class or
  455. * interface represented by this object, or null
  456. * if the com.sun.org.apache.xml.internal.utils.synthetic.Class was not created by a class loader.
  457. */
  458. public ClassLoader getClassLoader()
  459. {
  460. return (realclass == null) ? null : realclass.getClassLoader();
  461. }
  462. /**
  463. * If this class represents an array type, returns the
  464. * Class object representing the component type of
  465. * the array; otherwise returns null.
  466. * <p>
  467. * NOTE: Since com.sun.org.apache.xml.internal.utils.synthetic.Class doesn't yet attempt to model array
  468. * types, this will currently return false unless we are
  469. * proxying such a type.
  470. *
  471. * @return the Class object representing the component type of
  472. * the array, otherwise returns null.
  473. */
  474. public Class getComponentType()
  475. {
  476. return realclass == null ? null : new Class(realclass.getComponentType());
  477. }
  478. /**
  479. * Returns a Constructor object that reflects the
  480. * specified public constructor of the class
  481. * represented by this Class object. The
  482. * parameterTypes parameter is an array of Class
  483. * objects that identify the constructor's formal
  484. * parameter types, in declared order.
  485. * <p>
  486. * The constructor to reflect is located by searching
  487. * all the constructors of the class represented by this
  488. * Class object for a public constructor with the
  489. * exactly the same formal parameter types.
  490. *
  491. *
  492. * @param parameterTypes array of Class
  493. * objects that identify the constructor's formal
  494. * parameter types, in declared order.
  495. *
  496. * @return a Constructor object that reflects the
  497. * specified public constructor of the class
  498. * represented by this Class object.
  499. *
  500. * @throws NoSuchMethodException
  501. * if a matching method is not found.
  502. * @throws SecurityException
  503. * if access to the information is denied.
  504. * @throws SynthesisException
  505. */
  506. public Constructor getConstructor(Class parameterTypes[])
  507. throws NoSuchMethodException, SecurityException, SynthesisException
  508. {
  509. if (realclass == null)
  510. throw new SynthesisException(SynthesisException.UNREIFIED);
  511. java.lang.Class[] real = new java.lang.Class[parameterTypes.length];
  512. for (int i = 0; i < parameterTypes.length; ++i)
  513. {
  514. if ((real[i] = parameterTypes[i].getRealClass()) == null)
  515. throw new SynthesisException(SynthesisException.UNREIFIED);
  516. }
  517. return new Constructor(realclass.getConstructor(real), this);
  518. }
  519. /**
  520. * Returns an array containing Constructor objects
  521. * reflecting all the public constructors of the class
  522. * represented by this Class object. An array of length
  523. * 0 is returned if the class has no public
  524. * constructors.
  525. *
  526. *
  527. * @return an array containing Constructor objects
  528. * reflecting all the public constructors of the class
  529. * represented by this Class object.
  530. *
  531. * @throws SecurityException
  532. * if access to the information is denied.
  533. */
  534. public Constructor[] getConstructors() throws SecurityException
  535. {
  536. if (realclass != null && allconstructors == null)
  537. {
  538. java.lang.reflect.Constructor[] realDC = realclass.getConstructors();
  539. allconstructors = new Constructor[realDC.length];
  540. for (int i = 0; i < realDC.length; ++i)
  541. {
  542. allconstructors[i] = new Constructor(realDC[i], this);
  543. }
  544. }
  545. return allconstructors;
  546. }
  547. /**
  548. * This method is not implemented in VAJAVA 3.0
  549. * <p>
  550. * Returns an array of Class objects reflecting all the
  551. * classes and interfaces declared as members of the
  552. * class represented by this Class object. This
  553. * includes public, protected, default (package)
  554. * access, and private classes and interfaces declared
  555. * by the class, but excludes inherited classes and
  556. * interfaces. Returns an array of length 0 if the class
  557. * declares no classes or interfaces as members, or if
  558. * this Class object represents a primitive type.
  559. *
  560. *
  561. * @return an array of Class objects reflecting all the
  562. * classes and interfaces declared as members of the
  563. * class represented by this Class object.
  564. *
  565. * @throws SecurityException
  566. * if access to the information is denied.
  567. */
  568. public Class[] getDeclaredClasses() throws SecurityException
  569. {
  570. // ***** This should really be a single class plus declared interfaces.
  571. if (realclass != null && declaredclasses == null)
  572. {
  573. java.lang.Class[] realDE = realclass.getDeclaredClasses();
  574. declaredclasses = new Class[realDE.length];
  575. for (int i = 0; i < realDE.length; ++i)
  576. {
  577. declaredclasses[i] = forClass(realDE[i]);
  578. if (!realDE[i].isInterface())
  579. superclass = declaredclasses[i];
  580. }
  581. }
  582. return declaredclasses;
  583. }
  584. /**
  585. * Adds an "extends" description for the class or
  586. * interface represented by this Class object
  587. *
  588. * @param newclass The class that this class extends.
  589. * @throws SynthesisException
  590. * if the class has been reified.
  591. */
  592. public void addExtends(Class newclass) throws SynthesisException
  593. {
  594. if (realclass != null)
  595. throw new SynthesisException(SynthesisException.REIFIED);
  596. Class[] scratch = new Class[declaredclasses.length + 1];
  597. System.arraycopy(declaredclasses, 0, scratch, 0, declaredclasses.length);
  598. scratch[declaredclasses.length] = newclass;
  599. declaredclasses = scratch;
  600. }
  601. /**
  602. * Returns a Constructor object that reflects the
  603. * specified declared constructor of the class or
  604. * interface represented by this Class object. The
  605. * parameterTypes parameter is an array of Class
  606. * objects that identify the constructor's formal
  607. * parameter types, in declared order.
  608. *
  609. *
  610. * @param parameterTypes array of Class
  611. * objects that identify the constructor's formal
  612. * parameter types, in declared order.
  613. *
  614. * @return a Constructor object that reflects the
  615. * specified declared constructor of the class or
  616. * interface represented by this Class object.
  617. *
  618. * @throws NoSuchMethodException
  619. * if a matching method is not found.
  620. * @throws SecurityException
  621. * if access to the information is denied.
  622. */
  623. public Constructor getDeclaredConstructor(Class parameterTypes[])
  624. throws NoSuchMethodException, SecurityException
  625. {
  626. throw new java.lang.IllegalStateException();
  627. }
  628. /**
  629. * Adds a Constructor description for the class or
  630. * interface represented by this Class object
  631. *
  632. * @return The constructor object.
  633. *
  634. * @throws SynthesisException
  635. * if the class has been reified.
  636. */
  637. public Constructor declareConstructor() throws SynthesisException
  638. {
  639. if (realclass != null)
  640. throw new SynthesisException(SynthesisException.REIFIED);
  641. Constructor newctor = new Constructor(this);
  642. Constructor[] scratch = new Constructor[declaredconstructors.length + 1];
  643. System.arraycopy(declaredconstructors, 0, scratch, 0,
  644. declaredconstructors.length);
  645. scratch[declaredconstructors.length] = newctor;
  646. declaredconstructors = scratch;
  647. scratch = new Constructor[allconstructors.length + 1];
  648. System.arraycopy(allconstructors, 0, scratch, 0, allconstructors.length);
  649. scratch[allconstructors.length] = newctor;
  650. allconstructors = scratch;
  651. return newctor;
  652. }
  653. /**
  654. * State that this class implements a specified interface.
  655. * This does not yet update allMethods or otherwise
  656. * attempt to inherit data.
  657. *
  658. * @param newifce com.sun.org.apache.xml.internal.utils.synthetic.Class representing the interface we want to add.
  659. *
  660. * @return The new interface class.
  661. *
  662. * @throws com.sun.org.apache.xml.internal.utils.synthetic.SynthesisException if the Class isn't an interface
  663. */
  664. public Class declareInterface(Class newifce) throws SynthesisException
  665. {
  666. if (realclass != null)
  667. throw new SynthesisException(SynthesisException.REIFIED);
  668. if (!newifce.isInterface())
  669. throw new SynthesisException(SynthesisException.SYNTAX,
  670. newifce.getName() + " isn't an interface");
  671. Class[] scratch = new Class[interfaces.length + 1];
  672. System.arraycopy(interfaces, 0, scratch, 0, interfaces.length);
  673. scratch[interfaces.length] = newifce;
  674. interfaces = scratch;
  675. scratch = new Class[allclasses.length + 1];
  676. System.arraycopy(allclasses, 0, scratch, 0, allclasses.length);
  677. scratch[allclasses.length] = newifce;
  678. allclasses = scratch;
  679. return newifce;
  680. }
  681. /**
  682. * Returns an array of Constructor objects reflecting
  683. * all the constructors declared by the class
  684. * represented by this Class object. These are public,
  685. * protected, default (package) access, and private
  686. * constructors. Returns an array of length 0 if this
  687. * Class object represents an interface or a primitive
  688. * type.
  689. * <p>
  690. * See The Java Language Specification, section 8.2.
  691. *
  692. *
  693. * @return an array of Constructor objects reflecting
  694. * all the constructors declared by the class
  695. * represented by this Class object.
  696. *
  697. * @throws SecurityException
  698. * if access to the information is denied.
  699. */
  700. public Constructor[] getDeclaredConstructors() throws SecurityException
  701. {
  702. if (realclass != null && declaredconstructors == null)
  703. {
  704. java.lang.reflect.Constructor[] realDC =
  705. realclass.getDeclaredConstructors();
  706. declaredconstructors = new Constructor[realDC.length];
  707. for (int i = 0; i < realDC.length; ++i)
  708. {
  709. declaredconstructors[i] = new Constructor(realDC[i], this);
  710. }
  711. }
  712. return declaredconstructors;
  713. }
  714. /**
  715. * Returns a Field object that reflects the specified
  716. * declared field of the class or interface represented
  717. * by this Class object. The name parameter is a
  718. * String that specifies the simple name of the desired
  719. * field.
  720. *
  721. *
  722. * @param name String that specifies the simple name of the desired
  723. * field.
  724. *
  725. * @return a Field object that reflects the specified
  726. * declared field of the class or interface represented
  727. * by this Class object.
  728. *
  729. * @throws NoSuchFieldException
  730. * if a field with the specified name is not found.
  731. * @throws SecurityException
  732. * if access to the information is denied.
  733. */
  734. public Field getDeclaredField(String name)
  735. throws NoSuchFieldException, SecurityException
  736. {
  737. throw new java.lang.IllegalStateException();
  738. }
  739. /**
  740. * Adds a Field description for the class or
  741. * interface represented by this Class object
  742. *
  743. *
  744. * @param name The name of the field.
  745. *
  746. * @return The field description.
  747. *
  748. * @throws SynthesisException
  749. * if the class has been reified.
  750. */
  751. public Field declareField(String name) throws SynthesisException
  752. {
  753. if (realclass != null)
  754. throw new SynthesisException(SynthesisException.REIFIED);
  755. Field newfield = new Field(name, this);
  756. Field[] scratch = new Field[declaredfields.length + 1];
  757. System.arraycopy(declaredfields, 0, scratch, 0, declaredfields.length);
  758. scratch[declaredfields.length] = newfield;
  759. declaredfields = scratch;
  760. scratch = new Field[allfields.length + 1];
  761. System.arraycopy(allfields, 0, scratch, 0, allfields.length);
  762. scratch[allfields.length] = newfield;
  763. allfields = scratch;
  764. return newfield;
  765. }
  766. /**
  767. * Returns an array of Field objects reflecting all the
  768. * fields declared by the class or interface represented
  769. * by this Class object. This includes public,
  770. * protected, default (package) access, and private
  771. * fields, but excludes inherited fields. Returns an
  772. * array of length 0 if the class or interface declares
  773. * no fields, or if this Class object represents a
  774. * primitive type. See The Java Language
  775. * Specification, sections 8.2 and 8.3.
  776. *
  777. *
  778. * @return array of Field objects reflecting all the
  779. * fields declared by the class or interface represented
  780. * by this Class object.
  781. *
  782. * @throws SecurityException
  783. * if access to the information is denied.
  784. */
  785. public Field[] getDeclaredFields() throws SecurityException
  786. {
  787. if (realclass != null && declaredfields == null)
  788. {
  789. java.lang.reflect.Field[] realDF = realclass.getDeclaredFields();
  790. declaredfields = new Field[realDF.length];
  791. for (int i = 0; i < realDF.length; ++i)
  792. {
  793. declaredfields[i] = new Field(realDF[i], this);
  794. }
  795. }
  796. return declaredfields;
  797. }
  798. /**
  799. * Returns a Method object that reflects the specified
  800. * declared method of the class or interface
  801. * represented by this Class object. The name
  802. * parameter is a String that specifies the simple
  803. * name of the desired method, and the
  804. * parameterTypes parameter is an array of Class
  805. * objects that identify the method's formal parameter
  806. * types, in declared order.
  807. *
  808. *
  809. * @param name String that specifies the simple
  810. * name of the desired method.
  811. *
  812. * @param parameterTypes array of Class
  813. * objects that identify the method's formal parameter
  814. * types, in declared order.
  815. *
  816. * @return Method object that reflects the specified
  817. * declared method of the class or interface
  818. * represented by this Class object.
  819. *
  820. * @throws NoSuchMethodException
  821. * if a matching method is not found.
  822. * @throws SecurityException
  823. * if access to the information is denied.
  824. */
  825. public Method getDeclaredMethod(String name, Class parameterTypes[])
  826. throws NoSuchMethodException, SecurityException
  827. {
  828. throw new java.lang.IllegalStateException();
  829. }
  830. /**
  831. * Adds a Method description for the class or
  832. * interface represented by this Class object
  833. *
  834. *
  835. * @param name Name of method.
  836. *
  837. * @return The method object.
  838. *
  839. * @throws SynthesisException
  840. * if the class has been reified.
  841. */
  842. public Method declareMethod(String name) throws SynthesisException
  843. {
  844. if (realclass != null)
  845. throw new SynthesisException(SynthesisException.REIFIED);
  846. Method newMethod = new Method(name, this);
  847. Method[] scratch = new Method[declaredmethods.length + 1];
  848. System.arraycopy(declaredmethods, 0, scratch, 0, declaredmethods.length);
  849. scratch[declaredmethods.length] = newMethod;
  850. declaredmethods = scratch;
  851. scratch = new Method[allmethods.length + 1];
  852. System.arraycopy(allmethods, 0, scratch, 0, allmethods.length);
  853. scratch[allmethods.length] = newMethod;
  854. allmethods = scratch;
  855. return newMethod;
  856. }
  857. /**
  858. * Returns an array of Method objects reflecting all
  859. * the methods declared by the class or interface
  860. * represented by this Class object. This includes
  861. * public, protected, default (package) access, and
  862. * private methods, but excludes inherited methods.
  863. * Returns an array of length 0 if the class or interface
  864. * declares no methods, or if this Class object
  865. * represents a primitive type.
  866. * <p>
  867. * See The Java Language Specification, section 8.2.
  868. *
  869. * @return array of Method objects reflecting all
  870. * the methods declared by the class or interface
  871. * represented by this Class object.
  872. *
  873. * @throws SecurityException
  874. * if access to the information is denied.
  875. */
  876. public Method[] getDeclaredMethods() throws SecurityException
  877. {
  878. if (realclass != null && declaredmethods == null)
  879. {
  880. java.lang.reflect.Method[] realDM = realclass.getDeclaredMethods();
  881. declaredmethods = new Method[realDM.length];
  882. for (int i = 0; i < realDM.length; ++i)
  883. {
  884. declaredmethods[i] = new Method(realDM[i], this);
  885. }
  886. }
  887. return declaredmethods;
  888. }
  889. /**
  890. * This method is not implemented in VAJava 3.0
  891. * <p>
  892. * If the class or interface represented by this Class
  893. * object is a member of another class, returns the
  894. * Class object representing the class of which it is a
  895. * member (its declaring class). Returns null if this
  896. * class or interface is not a member of any other
  897. * class.
  898. *
  899. */
  900. public Class getDeclaringClass()
  901. {
  902. if (realclass != null && declaringclass == null)
  903. {
  904. java.lang.Class dc = realclass.getDeclaringClass();
  905. if (dc == null)
  906. declaringclass = null;
  907. else
  908. declaringclass = forClass(dc);
  909. }
  910. return declaringclass;
  911. }
  912. /**
  913. * Declare that this class is an inner class of another.
  914. *
  915. * @param newclass
  916. *
  917. * @throws SynthesisException
  918. */
  919. private void addInnerClass(Class newclass) throws SynthesisException
  920. {
  921. if (realclass != null)
  922. throw new SynthesisException(SynthesisException.REIFIED);
  923. if (newclass.getDeclaringClass() != this)
  924. throw new SynthesisException(SynthesisException.WRONG_OWNER);
  925. Class[] scratch = new Class[innerclasses.length + 1];
  926. System.arraycopy(innerclasses, 0, scratch, 0, innerclasses.length);
  927. scratch[innerclasses.length] = newclass;
  928. innerclasses = scratch;
  929. }
  930. /**
  931. * Declare a class contained within this class. This doesn't
  932. * address anonymous classes (those go inside method bodies
  933. * and similar code), just local classes.
  934. * <p>
  935. * ***** This requires lookup methods that operate in the
  936. * context of a specific class, and per-class registries!
  937. *
  938. * @param className Local name of inner class to create. This should _not_ be a
  939. * qualified name, unlike the normal forName() call. Its
  940. * hierarchy is established by the class within which it is
  941. * created.
  942. * @return com.sun.org.apache.xml.internal.utils.synthetic.Class object for the contained class.
  943. * @throws com.sun.org.apache.xml.internal.utils.synthetic.SynthesisException if class could not be created.
  944. * @since 2/2000
  945. *
  946. * @throws SynthesisException
  947. */
  948. public Class declareInnerClass(String className) throws SynthesisException
  949. {
  950. if (realclass != null)
  951. throw new SynthesisException(SynthesisException.REIFIED);
  952. String relativeName = getName() + "$" + className;
  953. Class newclass = (Class) (global_classtable.get(relativeName));
  954. if (newclass != null)
  955. throw new SynthesisException(SynthesisException.SYNTAX,
  956. "Inner class " + name + " already exists");
  957. newclass = new Class(className);
  958. newclass.declaringclass = this;
  959. Class[] scratch = new Class[innerclasses.length + 1];
  960. System.arraycopy(innerclasses, 0, scratch, 0, innerclasses.length);
  961. scratch[innerclasses.length] = newclass;
  962. innerclasses = scratch;
  963. return newclass;
  964. }
  965. /**
  966. * Fetch a list of classes contained within this class.
  967. * This doesn't address anonymous classes (those go
  968. * inside method bodies and similar code), just local classes.
  969. *
  970. * @return com.sun.org.apache.xml.internal.utils.synthetic.Class[] object for the contained classes.
  971. * This may be empty if none such exist, or if the class is
  972. * reified (since reflection doesn't report this information).
  973. * @since 3/2000
  974. */
  975. public Class[] getInnerClasses()
  976. {
  977. return innerclasses;
  978. }
  979. /**
  980. * Returns a Field object that reflects the specified
  981. * public member field of the class or interface
  982. * represented by this Class object. The name
  983. * parameter is a String specifying the simple name of
  984. * the desired field.
  985. * <p>
  986. * The field to be reflected is located by searching all
  987. * the member fields of the class or interface
  988. * represented by this Class object for a public field
  989. * with the specified name.
  990. * <p>
  991. * See The Java Language Specification, sections 8.2
  992. * and 8.3.
  993. *
  994. *
  995. * @param name
  996. *
  997. * @throws NoSuchFieldException
  998. * if a field with the specified name is not
  999. * found.
  1000. * @throws SecurityException
  1001. * if access to the information is denied.
  1002. */
  1003. public Field getField(String name)
  1004. throws NoSuchFieldException, SecurityException
  1005. {
  1006. throw new java.lang.IllegalStateException();
  1007. }
  1008. /**
  1009. * Returns an array containing Field objects
  1010. * reflecting all the accessible public fields of the
  1011. * class or interface represented by this Class object.
  1012. * Returns an array of length 0 if the class or interface
  1013. * has no accessible public fields, or if it represents
  1014. * an array type or a primitive type.
  1015. * <p>
  1016. * Specifically, if this Class object represents a class,
  1017. * returns the public fields of this class and of all its
  1018. * superclasses. If this Class object represents an
  1019. * interface, returns the fields of this interface and of
  1020. * all its superinterfaces. If this Class object
  1021. * represents an array type or a primitive type, returns
  1022. * an array of length 0.
  1023. * <p>
  1024. * The implicit length field for array types is not
  1025. * reflected by this method. User code should use the
  1026. * methods of class Array to manipulate arrays.
  1027. * <p>
  1028. * See The Java Language Specification, sections 8.2
  1029. * and 8.3.
  1030. *
  1031. *
  1032. * @throws SecurityException
  1033. * if access to the information is denied.
  1034. */
  1035. public Field[] getFields() throws SecurityException
  1036. {
  1037. if (realclass != null && allfields == null)
  1038. {
  1039. java.lang.reflect.Field[] realDF = realclass.getFields();
  1040. allfields = new Field[realDF.length];
  1041. for (int i = 0; i < realDF.length; ++i)
  1042. {
  1043. allfields[i] = new Field(realDF[i], this);
  1044. }
  1045. }
  1046. return allfields;
  1047. }
  1048. /**
  1049. * Determines the interfaces implemented by the
  1050. * class or interface represented by this object.
  1051. * <p>
  1052. * If this object represents a class, the return value is
  1053. * an array containing objects representing all
  1054. * interfaces implemented by the class. The order of
  1055. * the interface objects in the array corresponds to the
  1056. * order of the interface names in the implements
  1057. * clause of the declaration of the class represented by
  1058. * this object.
  1059. * <p>
  1060. * If this object represents an interface, the array
  1061. * contains objects representing all interfaces
  1062. * extended by the interface. The order of the
  1063. * interface objects in the array corresponds to the
  1064. * order of the interface names in the extends clause
  1065. * of the declaration of the interface represented by
  1066. * this object.
  1067. * <p>
  1068. * If the class or interface implements no interfaces,
  1069. * the method returns an array of length 0.
  1070. *
  1071. * an array of interfaces implemented by this
  1072. * class.
  1073. */
  1074. public Class[] getInterfaces()
  1075. {
  1076. if (realclass != null && interfaces == null)
  1077. {
  1078. java.lang.Class[] realI = realclass.getInterfaces();
  1079. interfaces = new Class[realI.length];
  1080. for (int i = 0; i < realI.length; ++i)
  1081. {
  1082. interfaces[i] = forClass(realI[i]);
  1083. }
  1084. }
  1085. return interfaces;
  1086. }
  1087. /**
  1088. * Adds an "implements" description for the class or
  1089. * interface represented by this Class object
  1090. *
  1091. *
  1092. * @param newclass
  1093. * @throws SynthesisException
  1094. * if the class has been reified.
  1095. */
  1096. public void addImplements(Class newclass) throws SynthesisException
  1097. {
  1098. if (realclass != null)
  1099. throw new SynthesisException(SynthesisException.REIFIED);
  1100. Class[] scratch = new Class[interfaces.length + 1];
  1101. System.arraycopy(interfaces, 0, scratch, 0, interfaces.length);
  1102. scratch[interfaces.length] = newclass;
  1103. interfaces = scratch;
  1104. }
  1105. /**
  1106. * Returns a Method object that reflects the specified
  1107. * public member method of the class or interface
  1108. * represented by this Class object. The name
  1109. * parameter is a String specifying the simple name
  1110. * the desired method, and the parameterTypes
  1111. * parameter is an array of Class objects that identify
  1112. * the method's formal parameter types, in declared
  1113. * order.
  1114. * <p>
  1115. * The method to reflect is located by searching all
  1116. * the member methods of the class or interface
  1117. * represented by this Class object for a public
  1118. * method with the specified name and exactly the
  1119. * same formal parameter types.
  1120. * <p>
  1121. * See The Java Language Specification, sections 8.2
  1122. * and 8.4.
  1123. *
  1124. *
  1125. * @param name
  1126. * @param parameterTypes
  1127. *
  1128. * @throws NoSuchMethodException
  1129. * if a matching method is not found.
  1130. * @throws SecurityException
  1131. * if access to the information is denied.
  1132. */
  1133. public Method getMethod(String name, Class parameterTypes[])
  1134. throws NoSuchMethodException, SecurityException
  1135. {
  1136. throw new java.lang.IllegalStateException();
  1137. }
  1138. /**
  1139. * Returns an array containing Method objects
  1140. * reflecting all the public member methods of the
  1141. * class or interface represented by this Class object,
  1142. * including those declared by the class or interface
  1143. * and and those inherited from superclasses and
  1144. * superinterfaces. Returns an array of length 0 if the
  1145. * class or interface has no public member methods.
  1146. * <p>
  1147. * See The Java Language Specification, sections 8.2
  1148. * and 8.4.
  1149. *
  1150. *
  1151. * @throws SecurityException
  1152. * if access to the information is denied.
  1153. */
  1154. public Method[] getMethods() throws SecurityException
  1155. {
  1156. if (realclass != null && allmethods == null)
  1157. {
  1158. java.lang.reflect.Method[] realDM = realclass.getMethods();
  1159. allmethods = new Method[realDM.length];
  1160. for (int i = 0; i < realDM.length; ++i)
  1161. {
  1162. allmethods[i] = new Method(realDM[i], this);
  1163. }
  1164. }
  1165. return allmethods;
  1166. }
  1167. /**
  1168. * Returns the Java language modifiers for this class
  1169. * or interface, encoded in an integer. The modifiers
  1170. * consist of the Java Virtual Machine's constants for
  1171. * public, protected, private, final, and interface; they
  1172. * should be decoded using the methods of class
  1173. * Modifier.
  1174. *
  1175. * The modifier encodings are defined in The Java
  1176. * Virtual Machine Specification, table 4.1.
  1177. *
  1178. * See Also:
  1179. * java.lang.reflect.Modifier
  1180. *
  1181. */
  1182. public int getModifiers()
  1183. {
  1184. return modifiers;
  1185. }
  1186. /**
  1187. * Set the Java language modifiers for this class
  1188. * or interface, encoded in an integer. The modifiers
  1189. * consist of the Java Virtual Machine's constants for
  1190. * public, protected, private, final, and interface; they
  1191. * should be decoded using the methods of class
  1192. * Modifier.
  1193. *
  1194. * The modifier encodings are defined in The Java
  1195. * Virtual Machine Specification, table 4.1.
  1196. *
  1197. * See Also:
  1198. * java.lang.reflect.Modifier
  1199. *
  1200. * @param modifiers
  1201. *
  1202. * @throws SynthesisException
  1203. */
  1204. public void setModifiers(int modifiers) throws SynthesisException
  1205. {
  1206. if (this.realclass != null)
  1207. throw new SynthesisException(SynthesisException.REIFIED);
  1208. this.modifiers = modifiers;
  1209. }
  1210. /**
  1211. * Retrieve the fully-qualified classname. If it's an array,
  1212. * it will be returned in JVM syntax, not Java syntax.
  1213. *
  1214. * @return java.lang.String
  1215. * @since 12/95
  1216. */
  1217. public java.lang.String getName()
  1218. {
  1219. return name;
  1220. }
  1221. /**
  1222. * Like getName, but back-convert array notation escapes.
  1223. * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
  1224. *
  1225. * @return java.lang.String
  1226. * @since 3/2000
  1227. */
  1228. public java.lang.String getJavaName()
  1229. {
  1230. if (name.charAt(0) != '[')
  1231. return name;
  1232. // Object array syntax is [Ltypename;
  1233. // add another [ for each level of array
  1234. int count = name.lastIndexOf('[');
  1235. StringBuffer jname = new StringBuffer(name.substring(count + 2));
  1236. // Trim the trailing ';'
  1237. jname.setLength(jname.length() - 1);
  1238. while (count-- >= 0)
  1239. {
  1240. jname.append("[]");
  1241. }
  1242. return jname.toString();
  1243. }
  1244. /**
  1245. * Extract just the local name of this class, minus the package
  1246. * prefix.
  1247. *
  1248. * ***** I don't think this handles array types properly yet.
  1249. *
  1250. * @return java.lang.String
  1251. * @since 12/99
  1252. */
  1253. public java.lang.String getShortName()
  1254. {
  1255. int start = name.lastIndexOf(".");
  1256. if (start != 0 || name.charAt(0) == '.')
  1257. ++start;
  1258. if (declaringclass != null)
  1259. {
  1260. int d = name.lastIndexOf('$', start);
  1261. if (d != 0)
  1262. start = d + 1;
  1263. }
  1264. return name.substring(start);
  1265. }
  1266. /**
  1267. * Like getShortName, but back-convert array notation escapes.
  1268. * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
  1269. *
  1270. * @return java.lang.String
  1271. * @since 3/2000
  1272. */
  1273. public java.lang.String getJavaShortName()
  1274. {
  1275. String shortname = getShortName();
  1276. if (shortname.charAt(0) != '[')
  1277. return shortname;
  1278. // Object array syntax is [Ltypename;
  1279. // add another [ for each level of array
  1280. int count = shortname.lastIndexOf('[');
  1281. StringBuffer jname = new StringBuffer(shortname.substring(count + 2));
  1282. // Trim the trailing ';'
  1283. jname.setLength(jname.length() - 1);
  1284. while (count-- >= 0)
  1285. {
  1286. jname.append("[]");
  1287. }
  1288. return jname.toString();
  1289. }
  1290. /**
  1291. * Extract the package name for this class.
  1292. * ***** I don't think this handles array classes properly yet.
  1293. *
  1294. * @return java.lang.String
  1295. * @since 12/95
  1296. */
  1297. public java.lang.String getPackageName()
  1298. {
  1299. int start = name.lastIndexOf(".");
  1300. return name.substring(0, start);
  1301. }
  1302. /**
  1303. * If this synthetic class is a wrapper for a "real"
  1304. * java.lang.Class -- either because it was instantiated as such
  1305. * or because it has been compiled -- this method will return
  1306. * that class. Otherwise it returns null.
  1307. * Creation date: (12-25-99 12:26:01 PM)
  1308. * @return com.sun.org.apache.xml.internal.utils.synthetic.Class
  1309. */
  1310. public java.lang.Class getRealClass()
  1311. {
  1312. return realclass;
  1313. }
  1314. /**
  1315. * This call is intended to allow an existing com.sun.org.apache.xml.internal.utils.synthetic.Class
  1316. * to be switched from purely descriptive mode to proxy mode
  1317. * ("reified").
  1318. * The primary intent is to allow a com.sun.org.apache.xml.internal.utils.synthetic.Class to be
  1319. * "compiled in place"
  1320. * <p>
  1321. * This should have the side-effect of limiting further mutation
  1322. * of the com.sun.org.apache.xml.internal.utils.synthetic.Class to things which can not be obtained
  1323. * from the real Class object, to avoid "lying" to the user
  1324. * <p>
  1325. * NOTE: Not all information defined by the Java libraries is
  1326. * in fact available in all Java environments. We assume the
  1327. * calls will work; if they return null or empty lists, there's
  1328. * nothing we can do about it. Note that this may mean that a
  1329. * reified class tells us less about itself than the
  1330. * synthetic description used to generate it.
  1331. * <p>
  1332. * Creation date: (12-25-99 12:26:01 PM)
  1333. * @param java.lang.class realclass nonsynthetic Class object to proxy
  1334. *
  1335. * @param realclass
  1336. *
  1337. * @throws SynthesisException
  1338. */
  1339. public void setRealClass(java.lang.Class realclass)
  1340. throws SynthesisException
  1341. {
  1342. if (this.realclass != null)
  1343. throw new SynthesisException(SynthesisException.REIFIED);
  1344. this.realclass = realclass;
  1345. this.modifiers = realclass.getModifiers();
  1346. this.isInterface = realclass.isInterface();
  1347. // DEFERRED -- set them null now, reconstruct when requested
  1348. this.declaringclass = null;
  1349. this.interfaces = null;
  1350. this.declaredconstructors = null;
  1351. this.allconstructors = null;
  1352. this.declaredmethods = null;
  1353. this.allmethods = null;
  1354. this.declaredfields = null;
  1355. this.allfields = null;
  1356. this.declaredclasses = null;
  1357. this.allclasses = null;
  1358. this.superclass = null;
  1359. }
  1360. /**
  1361. * Set the superclass for this synthetic class.
  1362. * Object is equivalent to Null.
  1363. * Creation date: (12-25-99 12:26:01 PM)
  1364. *
  1365. * @param superclass
  1366. * @return com.sun.org.apache.xml.internal.utils.synthetic.Class
  1367. *
  1368. * @throws SynthesisException
  1369. */
  1370. public void setSuperClass(Class superclass) throws SynthesisException
  1371. {
  1372. if (realclass != null)
  1373. throw new SynthesisException(SynthesisException.REIFIED);
  1374. this.superclass = superclass;
  1375. }
  1376. /**
  1377. * Set the superclass for this synthetic class.
  1378. * Creation date: (12-25-99 12:26:01 PM)
  1379. *
  1380. * @param superclass
  1381. * @return com.sun.org.apache.xml.internal.utils.synthetic.Class
  1382. *
  1383. * @throws ClassNotFoundException
  1384. * @throws SynthesisException
  1385. */
  1386. public void setSuperClass(java.lang.Class superclass)
  1387. throws ClassNotFoundException, SynthesisException
  1388. {
  1389. if (realclass != null)
  1390. throw new SynthesisException(SynthesisException.REIFIED);
  1391. this.superclass = Class.forClass(superclass);
  1392. }
  1393. /**
  1394. * Finds a resource with the specified name. The
  1395. * rules for searching for resources associated with a
  1396. * given class are implemented by the class loader of
  1397. * the class.
  1398. * <p>
  1399. * The Class methods delegate to ClassLoader
  1400. * methods, after applying a naming convention: if
  1401. * the resource name starts with "/", it is used as is.
  1402. * Otherwise, the name of the package is prepended,
  1403. * after converting "." to "/".
  1404. *
  1405. * @param
  1406. * name - the string representing the resource to
  1407. * be found.
  1408. * the URL object having the specified name, or
  1409. * null if no resource with the specified name
  1410. * is found.
  1411. */
  1412. public java.net.URL getResource(String name)
  1413. {
  1414. throw new java.lang.IllegalStateException();
  1415. }
  1416. /**
  1417. * Finds a resource with a given name. Will return
  1418. * null if no resource with this name is found. The
  1419. * rules for searching a resources associated with a
  1420. * given class are implemented by the ClassLoader of
  1421. * the class.
  1422. * <p>
  1423. * The Class methods delegate to ClassLoader
  1424. * methods, after applying a naming convention: if
  1425. * the resource name starts with "/", it is used as is.
  1426. * Otherwise, the name of the package is prepended,
  1427. * after converting "." to "/".
  1428. *
  1429. * @param
  1430. * name - the string representing the resource to
  1431. * be found
  1432. * the InputStream object having the
  1433. * specified name, or null if no resource with
  1434. * the specified name is found.
  1435. */
  1436. public java.io.InputStream getResourceAsStream(String name)
  1437. {
  1438. throw new java.lang.IllegalStateException();
  1439. }
  1440. /**
  1441. * Get the signers of this class.
  1442. *
  1443. */
  1444. public Object[] getSigners()
  1445. {
  1446. throw new java.lang.IllegalStateException();
  1447. }
  1448. /**
  1449. * If this object represents any class other than the
  1450. * class Object, then the object that represents the
  1451. * superclass of that class is returned.
  1452. * <p>
  1453. * If this object is the one that represents the class
  1454. * Object or this object represents an interface, null is
  1455. * returned.
  1456. *
  1457. * the superclass of the class represented by this
  1458. * object.
  1459. */
  1460. public Class getSuperclass()
  1461. {
  1462. if (realclass != null && superclass == null)
  1463. {
  1464. superclass = forClass(realclass.getSuperclass());
  1465. // getDeclaredClasses(); // Sets superclass as a side-effect
  1466. }
  1467. if (superclass == null)
  1468. superclass = forClass(Object.class);
  1469. return superclass;
  1470. }
  1471. /**
  1472. * If this Class object represents an array type, returns
  1473. * true, otherwise returns false.
  1474. *
  1475. */
  1476. public boolean isArray()
  1477. {
  1478. return realclass != null && realclass.isArray();
  1479. }
  1480. /**
  1481. * Determines if the class or interface represented by
  1482. * this Class object is either the same as, or is a
  1483. * superclass or superinterface of, the class or
  1484. * interface represented by the specified Class
  1485. * parameter. It returns true if so, false otherwise. If
  1486. * this Class object represents a primitive type,
  1487. * returns true if the specified Class parameter is
  1488. * exactly this Class object, false otherwise.
  1489. * <p>
  1490. * Specifically, this method tests whether the type
  1491. * represented by the specified Class parameter can
  1492. * be converted to the type represented by this Class
  1493. * object via an identity conversion or via a widening
  1494. * reference conversion. See The Java Language
  1495. * Specification, sections 5.1.1 and 5.1.4 , for details.
  1496. *
  1497. *
  1498. * @param cls
  1499. *
  1500. * @throws NullPointerException if the specified Class parameter is null.
  1501. */
  1502. public boolean isAssignableFrom(Class cls)
  1503. {
  1504. if (realclass != null && cls.realclass != null)
  1505. return realclass.isAssignableFrom(cls.realclass);
  1506. throw new java.lang.IllegalStateException();
  1507. }
  1508. /**
  1509. * Determines if the class or interface represented by
  1510. * this Class object is either the same as, or is a
  1511. * superclass or superinterface of, the class or
  1512. * interface represented by the specified Class
  1513. * parameter. It returns true if so, false otherwise. If
  1514. * this Class object represents a primitive type,
  1515. * returns true if the specified Class parameter is
  1516. * exactly this Class object, false otherwise.
  1517. * <p>
  1518. * Specifically, this method tests whether the type
  1519. * represented by the specified Class parameter can
  1520. * be converted to the type represented by this Class
  1521. * object via an identity conversion or via a widening
  1522. * reference conversion. See The Java Language
  1523. * Specification, sections 5.1.1 and 5.1.4 , for details.
  1524. *
  1525. *
  1526. * @param cls
  1527. *
  1528. * @throws NullPointerException if the specified Class parameter is null.
  1529. */
  1530. public boolean isAssignableFrom(java.lang.Class cls)
  1531. {
  1532. if (realclass != null)
  1533. return realclass.isAssignableFrom((java.lang.Class) cls);
  1534. throw new java.lang.IllegalStateException();
  1535. }
  1536. /**
  1537. * This method is the dynamic equivalent of the Java
  1538. * language instanceof operator. The method
  1539. * returns true if the specified Object argument is
  1540. * non-null and can be cast to the reference type
  1541. * represented by this Class object without raising a
  1542. * ClassCastException. It returns false otherwise.
  1543. * <p>
  1544. * Specifically, if this Class object represents a
  1545. * declared class, returns true if the specified Object
  1546. * argument is an instance of the represented class (or
  1547. * of any of its subclasses); false otherwise. If this
  1548. * Class object represents an array class, returns true
  1549. * if the specified Object argument can be converted
  1550. * to an object of the array type by an identity
  1551. * conversion or by a widening reference conversion;
  1552. * false otherwise. If this Class object represents an
  1553. * interface, returns true if the class or any superclass
  1554. * of the specified Object argument implements this
  1555. * interface; false otherwise. If this Class object
  1556. * represents a primitive type, returns false.
  1557. *
  1558. * @param obj The object to check
  1559. *
  1560. */
  1561. public boolean isInstance(Object obj)
  1562. {
  1563. if (realclass != null)
  1564. return realclass.isInstance(obj);
  1565. // Scan inheritances? (reliable).
  1566. // Check name? (not reliable).
  1567. throw new java.lang.IllegalStateException();
  1568. }
  1569. /**
  1570. * Determines if the specified Class object represents
  1571. * an interface type.
  1572. *
  1573. * true if this object represents an interface;
  1574. * false otherwise.
  1575. */
  1576. public boolean isInterface()
  1577. {
  1578. return (realclass != null) ? realclass.isInterface() : isInterface;
  1579. }
  1580. /**
  1581. * Assert that the specified Class object represents
  1582. * an interface type. Can't be changed after real class loaded.
  1583. *
  1584. * @param
  1585. * true if this object represents an interface;
  1586. * false otherwise.
  1587. *
  1588. * @param isInterface
  1589. *
  1590. * @throws SynthesisException
  1591. */
  1592. public void isInterface(boolean isInterface) throws SynthesisException
  1593. {
  1594. if (realclass == null)
  1595. this.isInterface = isInterface;
  1596. else if (realclass.isInterface() != isInterface)
  1597. throw new SynthesisException(SynthesisException.REIFIED);
  1598. }
  1599. /**
  1600. * Determines if the specified Class object represents
  1601. * a primitive Java type.
  1602. * <p>
  1603. * There are nine predefined Class objects to
  1604. * represent the eight primitive Java types and void.
  1605. * These are created by the Java Virtual Machine, and
  1606. * have the same names as the primitive types that
  1607. * they represent, namely boolean, byte, char, short,
  1608. * int, long, float, and double, and void.
  1609. * <p>
  1610. * These objects may only be accessed via the
  1611. * following public static final variables, and are the
  1612. * only Class objects for which this method returns
  1613. * true.
  1614. *
  1615. */
  1616. public boolean isPrimitive()
  1617. {
  1618. return realclass != null && realclass.isPrimitive();
  1619. }
  1620. /**
  1621. * Creates a new instance of a class.
  1622. *
  1623. * a newly allocated instance of the class
  1624. * represented by this object. This is done
  1625. * exactly as if by a new expression with an
  1626. * empty argument list.
  1627. * @throws IllegalAccessException
  1628. * if the class or initializer is not accessible.
  1629. * @throws InstantiationException
  1630. * if an application tries to instantiate an
  1631. * abstract class or an interface, or if the
  1632. * instantiation fails for some other reason.
  1633. */
  1634. public Object newInstance()
  1635. throws InstantiationException, IllegalAccessException
  1636. {
  1637. throw new java.lang.IllegalStateException();
  1638. }
  1639. /**
  1640. * Converts the object to a string. The string
  1641. * representation is the string "class" or
  1642. * "interface" followed by a space and then the
  1643. * fully qualified name of the class. If this Class
  1644. * object represents a primitive type, returns the
  1645. * name of the primitive type.
  1646. * <p>
  1647. * Should this say "synthetic" as well as "class" or
  1648. * "interface"? Or should that be gated on whether we're proxy
  1649. * to a realclass?
  1650. *
  1651. * @return a string representation of this class object.
  1652. */
  1653. public String toString()
  1654. {
  1655. if (realclass != null)
  1656. return realclass.toString();
  1657. else if (isInterface())
  1658. return "interface " + name;
  1659. else
  1660. return "class " + name;
  1661. }
  1662. /**
  1663. * Convenience for writing to, eg, System.out
  1664. *
  1665. * @param out
  1666. * @param depth
  1667. */
  1668. public void toSource(java.io.OutputStream out, int depth)
  1669. {
  1670. java.io.PrintWriter writer = new java.io.PrintWriter(out);
  1671. toSource(writer, depth);
  1672. }
  1673. /**
  1674. * Converts the object to a Java code stream. The string
  1675. * representation is as full a Java definition of the class
  1676. * as we are able to achieve. If this Class
  1677. * object represents a primitive type, returns the
  1678. * name of the primitive type.
  1679. *
  1680. * @param out
  1681. * @param depth
  1682. */
  1683. public void toSource(java.io.PrintWriter out, int depth)
  1684. {
  1685. String tab = tabset(depth);
  1686. if (realclass != null)
  1687. out.println(
  1688. tab
  1689. + "/** Code back-generated from a \"real\" Class; accuracy limited by reflection APIs. */");
  1690. else
  1691. out.println(
  1692. tab
  1693. + "/** Code generated via com.sun.org.apache.xml.internal.utils.synthetic.Class */");
  1694. /* Package should not be printed for inner classes */
  1695. if (getDeclaringClass() == null)
  1696. out.println(tab + "package " + getPackageName() + ";");
  1697. out.print(tab + Modifier.toString(getModifiers()));
  1698. if (isInterface())
  1699. out.print(" interface ");
  1700. else
  1701. out.print(" class ");
  1702. out.println(getJavaShortName());
  1703. if (superclass != null)
  1704. {
  1705. out.print('\n' + tab + " extends " + superclass.getJavaName());
  1706. }
  1707. Class[] ext = getInterfaces();
  1708. if (ext != null & ext.length > 0)
  1709. {
  1710. // Interfaces extend other interfaces,
  1711. // Classes implement interfaces.
  1712. out.print('\n' + tab + (isInterface ? " extends " : " implements ")
  1713. + ext[0].getName());
  1714. for (int i = 1; i < ext.length; ++i)
  1715. {
  1716. out.print(", " + ext[i].getJavaName());
  1717. }
  1718. out.print("\n");
  1719. }
  1720. out.print(tab + "{\n");
  1721. tab = tabset(++depth);
  1722. // Fields--------------------------------
  1723. Field[] fields = null;
  1724. try
  1725. {
  1726. fields = getDeclaredFields();
  1727. }
  1728. catch (SecurityException e)
  1729. {
  1730. out.println(tab + "//SecurityException retrieving fields");
  1731. }
  1732. if (fields != null)
  1733. {
  1734. for (int i = 0; i < fields.length; ++i)
  1735. {
  1736. out.println(tab + fields[i].toSource());
  1737. }
  1738. }
  1739. // Constructors--------------------------
  1740. Constructor[] ctors = null;
  1741. try
  1742. {
  1743. ctors = getDeclaredConstructors();
  1744. }
  1745. catch (SecurityException e)
  1746. {
  1747. out.println(tab + "//SecurityException retrieving ctors");
  1748. }
  1749. if (ctors != null)
  1750. {
  1751. for (int i = 0; i < ctors.length; ++i)
  1752. {
  1753. out.print(ctors[i].toSource(tab));
  1754. }
  1755. }
  1756. // Methods-------------------------------
  1757. Method[] methods = null;
  1758. try
  1759. {
  1760. methods = getDeclaredMethods();
  1761. }
  1762. catch (SecurityException e)
  1763. {
  1764. out.println(tab + "//SecurityException retrieving methods");
  1765. }
  1766. if (methods != null)
  1767. {
  1768. for (int i = 0; i < methods.length; ++i)
  1769. {
  1770. out.print('\n');
  1771. out.print(methods[i].toSource(tab));
  1772. }
  1773. }
  1774. // Inner classes --------------------------------
  1775. Class[] inners = getInnerClasses();
  1776. if (inners != null)
  1777. {
  1778. for (int i = 0; i < inners.length; ++i)
  1779. {
  1780. out.print('\n');
  1781. inners[i].toSource(out, depth);
  1782. }
  1783. }
  1784. // Done------------------------------
  1785. tab = tabset(--depth);
  1786. out.print(tab + "}\n");
  1787. out.flush();
  1788. }
  1789. /**
  1790. * Method tabset
  1791. *
  1792. *
  1793. * @param depth
  1794. *
  1795. * (tabset) @return
  1796. */
  1797. private String tabset(int depth)
  1798. {
  1799. StringBuffer t = new StringBuffer();
  1800. while (depth-- > 0)
  1801. {
  1802. t.append(" ");
  1803. }
  1804. return t.toString();
  1805. }
  1806. // Ignores any keywords we don't recognize
  1807. /** Field val */
  1808. static final int[] val = { Modifier.ABSTRACT, Modifier.FINAL,
  1809. Modifier.INTERFACE, Modifier.NATIVE,
  1810. Modifier.PRIVATE, Modifier.PROTECTED,
  1811. Modifier.PUBLIC, Modifier.STATIC,
  1812. Modifier.SYNCHRONIZED, Modifier.TRANSIENT,
  1813. Modifier.VOLATILE };
  1814. /** Field kwd */
  1815. static final String[] kwd = { "abstract", "final", "interface", "native",
  1816. "private", "protected", "public", "static",
  1817. "synchronized", "transient", "volatile" };
  1818. /**
  1819. * Method modifierFromString
  1820. *
  1821. *
  1822. * @param t
  1823. *
  1824. * (modifierFromString) @return
  1825. */
  1826. static public int modifierFromString(String t)
  1827. {
  1828. for (int i = 0; i < kwd.length; ++i)
  1829. {
  1830. if (kwd[i].equals(t))
  1831. return val[i];
  1832. }
  1833. return 0;
  1834. }
  1835. /**
  1836. * Method modifiersFromString
  1837. *
  1838. *
  1839. * @param s
  1840. *
  1841. * (modifiersFromString) @return
  1842. */
  1843. static public int modifiersFromString(String s)
  1844. {
  1845. int mods = 0;
  1846. java.util.StringTokenizer parts = new java.util.StringTokenizer(s);
  1847. while (parts.hasMoreTokens())
  1848. {
  1849. String t = parts.nextToken();
  1850. mods |= modifierFromString(t);
  1851. }
  1852. return mods;
  1853. }
  1854. }