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