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.reflection;
  58. import org.apache.xml.utils.synthetic.Class;
  59. import org.apache.xml.utils.synthetic.SynthesisException;
  60. /**
  61. * <meta name="usage" content="internal"/>
  62. * A Field provides information about, and dynamic access
  63. * to, a single field of a class or an interface. The reflected
  64. * field may be a class (static) field or an instance field.
  65. * <p>
  66. * A Field permits widening conversions to occur during a
  67. * get or set access operation, but throws an
  68. * IllegalArgumentException if a narrowing conversion
  69. * would occur.
  70. *
  71. */
  72. public class Field extends Object implements Member
  73. {
  74. /** Field name, initializer */
  75. public String name, initializer = null;
  76. /** Field modifiers */
  77. int modifiers;
  78. /** Field realfield */
  79. java.lang.reflect.Field realfield = null;
  80. /** Field declaringClass, type */
  81. Class declaringClass, type;
  82. /**
  83. * Proxy constructor
  84. *
  85. * @param realfield
  86. * @param declaringClass
  87. */
  88. public Field(java.lang.reflect.Field realfield,
  89. org.apache.xml.utils.synthetic.Class declaringClass)
  90. {
  91. this(realfield.getName(), declaringClass);
  92. this.realfield = realfield;
  93. this.type =
  94. org.apache.xml.utils.synthetic.Class.forClass(realfield.getType());
  95. }
  96. /**
  97. * Synthesis constructor
  98. *
  99. * @param name
  100. * @param declaringClass
  101. */
  102. public Field(String name,
  103. org.apache.xml.utils.synthetic.Class declaringClass)
  104. {
  105. this.name = name;
  106. this.declaringClass = declaringClass;
  107. }
  108. /**
  109. * Compares this Field against the specified object.
  110. * Returns true if the objects are the same. Two
  111. * Fields are the same if they were declared by the
  112. * same class and have the same name and type.
  113. *
  114. * @param obj
  115. *
  116. */
  117. public boolean equals(Object obj)
  118. {
  119. if (realfield != null)
  120. return realfield.equals(obj);
  121. else if (obj instanceof Field)
  122. {
  123. Field objf = (Field) obj;
  124. return (declaringClass.equals(objf.declaringClass)
  125. && name.equals(objf.name) && type.equals(objf.type));
  126. }
  127. else
  128. return false;
  129. }
  130. /**
  131. * Returns the value of the field represented by this
  132. * Field, on the specified object. The value is
  133. * automatically wrapped in an object if it has a
  134. * primitive type.
  135. * <p>
  136. * The underlying field's value is obtained as follows:
  137. * <p>
  138. * If the underlying field is a static field, the object
  139. * argument is ignored; it may be null.
  140. * <p>
  141. * Otherwise, the underlying field is an instance
  142. * field. If the specified object argument is null, the
  143. * method throws a NullPointerException. If the
  144. * specified object is not an instance of the class or
  145. * interface declaring the underlying field, the
  146. * method throws an IllegalArgumentException.
  147. * <p>
  148. * If this Field object enforces Java language access
  149. * control, and the underlying field is inaccessible,
  150. * the method throws an IllegalAccessException.
  151. * <p>
  152. * Otherwise, the value is retrieved from the
  153. * underlying instance or static field. If the field has a
  154. * primitive type, the value is wrapped in an object
  155. * before being returned, otherwise it is returned as
  156. * is.
  157. *
  158. *
  159. * @param obj
  160. *
  161. * @throws IllegalAccessException
  162. * if the underlying constructor is inaccessible.
  163. * @throws IllegalArgumentException
  164. * if the specified object is not an instance of
  165. * the class or interface declaring the
  166. * underlying field.
  167. * @throws NullPointerException
  168. * if the specified object is null.
  169. */
  170. public Object get(Object obj)
  171. throws IllegalArgumentException, IllegalAccessException
  172. {
  173. if (realfield != null)
  174. return realfield.get(obj);
  175. throw new java.lang.IllegalStateException();
  176. }
  177. /**
  178. * Get the value of a field as a boolean on specified
  179. * object.
  180. *
  181. *
  182. * @param obj
  183. *
  184. * @throws IllegalAccessException
  185. * if the underlying constructor is inaccessible.
  186. * @throws IllegalArgumentException
  187. * if the field value cannot be converted to the
  188. * return type by a widening conversion.
  189. */
  190. public boolean getBoolean(Object obj)
  191. throws IllegalArgumentException, IllegalAccessException
  192. {
  193. if (realfield != null)
  194. return realfield.getBoolean(obj);
  195. throw new java.lang.IllegalStateException();
  196. }
  197. /**
  198. * Get the value of a field as a byte on specified
  199. * object.
  200. *
  201. *
  202. * @param obj
  203. *
  204. * @throws IllegalAccessException
  205. * if the underlying constructor is inaccessible.
  206. * @throws IllegalArgumentException
  207. * if the field value cannot be converted to the
  208. * return type by a widening conversion.
  209. */
  210. public byte getByte(Object obj)
  211. throws IllegalArgumentException, IllegalAccessException
  212. {
  213. if (realfield != null)
  214. return realfield.getByte(obj);
  215. throw new java.lang.IllegalStateException();
  216. }
  217. /**
  218. * Get the value of a field as a char on specified
  219. * object.
  220. *
  221. *
  222. * @param obj
  223. *
  224. * @throws IllegalAccessException
  225. * if the underlying constructor is inaccessible.
  226. * @throws IllegalArgumentException
  227. * if the field value cannot be converted to the
  228. * return type by a widening conversion.
  229. */
  230. public char getChar(Object obj)
  231. throws IllegalArgumentException, IllegalAccessException
  232. {
  233. if (realfield != null)
  234. return realfield.getChar(obj);
  235. throw new java.lang.IllegalStateException();
  236. }
  237. /**
  238. * Returns the Class object representing the class or
  239. * interface that declares the field represented by this
  240. * Field object.
  241. *
  242. */
  243. public org.apache.xml.utils.synthetic.Class getDeclaringClass()
  244. {
  245. if (realfield != null)
  246. return org.apache.xml.utils.synthetic.Class.forClass(
  247. realfield.getDeclaringClass());
  248. throw new java.lang.IllegalStateException();
  249. }
  250. /**
  251. * Get the value of a field as a double on specified
  252. * object.
  253. *
  254. *
  255. * @param obj
  256. *
  257. * @throws IllegalAccessException
  258. * if the underlying constructor is inaccessible.
  259. * @throws IllegalArgumentException
  260. * if the field value cannot be converted to the
  261. * return type by a widening conversion.
  262. */
  263. public double getDouble(Object obj)
  264. throws IllegalArgumentException, IllegalAccessException
  265. {
  266. if (realfield != null)
  267. return realfield.getDouble(obj);
  268. throw new java.lang.IllegalStateException();
  269. }
  270. /**
  271. * Get the value of a field as a float on specified
  272. * object.
  273. *
  274. *
  275. * @param obj
  276. *
  277. * @throws IllegalAccessException
  278. * if the underlying constructor is inaccessible.
  279. * @throws IllegalArgumentException
  280. * if the field value cannot be converted to the
  281. * return type by a widening conversion.
  282. */
  283. public float getFloat(Object obj)
  284. throws IllegalArgumentException, IllegalAccessException
  285. {
  286. if (realfield != null)
  287. return realfield.getFloat(obj);
  288. throw new java.lang.IllegalStateException();
  289. }
  290. /**
  291. * Get the value of a field as a int on specified object.
  292. *
  293. *
  294. * @param obj
  295. *
  296. * @throws IllegalAccessException
  297. * if the underlying constructor is inaccessible.
  298. * @throws IllegalArgumentException
  299. * if the field value cannot be converted to the
  300. * return type by a widening conversion.
  301. */
  302. public int getInt(Object obj)
  303. throws IllegalArgumentException, IllegalAccessException
  304. {
  305. if (realfield != null)
  306. return realfield.getInt(obj);
  307. throw new java.lang.IllegalStateException();
  308. }
  309. /**
  310. * Get the value of a field as a long on specified
  311. * object.
  312. *
  313. *
  314. * @param obj
  315. *
  316. * @throws IllegalAccessException
  317. * if the underlying constructor is inaccessible.
  318. * @throws IllegalArgumentException
  319. * if the field value cannot be converted to the
  320. * return type by a widening conversion.
  321. */
  322. public long getLong(Object obj)
  323. throws IllegalArgumentException, IllegalAccessException
  324. {
  325. if (realfield != null)
  326. return realfield.getLong(obj);
  327. throw new java.lang.IllegalStateException();
  328. }
  329. /**
  330. * Returns the Java language modifiers for the field
  331. * represented by this Field object, as an integer. The
  332. * Modifier class should be used to decode the
  333. * modifiers.
  334. *
  335. */
  336. public int getModifiers()
  337. {
  338. if (realfield != null)
  339. modifiers = realfield.getModifiers();
  340. return modifiers;
  341. }
  342. /**
  343. * Method getInitializer
  344. *
  345. *
  346. * (getInitializer) @return
  347. */
  348. public String getInitializer()
  349. {
  350. return initializer;
  351. }
  352. /**
  353. * Method setInitializer
  354. *
  355. *
  356. * @param i
  357. *
  358. * @throws SynthesisException
  359. */
  360. public void setInitializer(String i) throws SynthesisException
  361. {
  362. if (realfield != null)
  363. throw new SynthesisException(SynthesisException.REIFIED);
  364. initializer = i;
  365. }
  366. /**
  367. * Insert the method's description here.
  368. * Creation date: (12-25-99 2:02:26 PM)
  369. * @return java.lang.String
  370. */
  371. public java.lang.String getName()
  372. {
  373. return name;
  374. }
  375. /**
  376. * Get the value of a field as a short on specified
  377. * object.
  378. *
  379. *
  380. * @param obj
  381. *
  382. * @throws IllegalAccessException
  383. * if the underlying constructor is inaccessible.
  384. * @throws IllegalArgumentException
  385. * if the field value cannot be converted to the
  386. * return type by a widening conversion.
  387. */
  388. public short getShort(Object obj)
  389. throws IllegalArgumentException, IllegalAccessException
  390. {
  391. if (realfield != null)
  392. return realfield.getShort(obj);
  393. throw new java.lang.IllegalStateException();
  394. }
  395. /**
  396. * Returns a Class object that identifies the declared
  397. * type for the field represented by this Field object.
  398. *
  399. */
  400. public Class getType()
  401. {
  402. if (realfield != null)
  403. type = Class.forClass(realfield.getType());
  404. return type;
  405. }
  406. /**
  407. * Method setType
  408. *
  409. *
  410. * @param type
  411. *
  412. * @throws SynthesisException
  413. */
  414. public void setType(org.apache.xml.utils.synthetic.Class type)
  415. throws SynthesisException
  416. {
  417. if (realfield != null)
  418. throw new SynthesisException(SynthesisException.REIFIED);
  419. this.type = type;
  420. }
  421. /**
  422. * Returns a hashcode for this Field. This is
  423. * computed as the exclusive-or of the hashcodes for
  424. * the underlying field's declaring class name and its
  425. * name.
  426. *
  427. */
  428. public int hashCode()
  429. {
  430. if (realfield != null)
  431. return realfield.hashCode();
  432. else
  433. return declaringClass.getName().hashCode() ^ name.hashCode();
  434. }
  435. /**
  436. * Sets the field represented by this Field object on
  437. * the specified object argument to the specified new
  438. * value. The new value is automatically unwrapped
  439. * if the underlying field has a primitive type.
  440. *
  441. * The operation proceeds as follows:
  442. *
  443. * If the underlying field is static, the object
  444. * argument is ignored; it may be null.
  445. *
  446. * Otherwise the underlying field is an instance field.
  447. * If the specified object argument is null, the
  448. * method throws a NullPointerException. If the
  449. * specified object argument is not an instance of the
  450. * class or interface declaring the underlying field,
  451. * the method throws an IllegalArgumentException.
  452. *
  453. * If this Field object enforces Java language access
  454. * control, and the underlying field is inaccessible,
  455. * the method throws an IllegalAccessException.
  456. *
  457. * If the underlying field is final, the method throws
  458. * an IllegalAccessException.
  459. *
  460. * If the underlying field is of a primitive type, an
  461. * unwrapping conversion is attempted to convert the
  462. * new value to a value of a primitive type. If this
  463. * attempt fails, the method throws an
  464. * IllegalArgumentException.
  465. *
  466. * If, after possible unwrapping, the new value
  467. * cannot be converted to the type of the underlying
  468. * field by an identity or widening conversion, the
  469. * method throws an IllegalArgumentException.
  470. *
  471. * The field is set to the possibly unwrapped and
  472. * widened new value.
  473. *
  474. *
  475. * @param obj
  476. * @param value
  477. * @throws IllegalAccessException
  478. * if the underlying constructor is inaccessible.
  479. * @throws IllegalArgumentException
  480. * if the specified object is not an instance of
  481. * the class or interface declaring the
  482. * underlying field, or if an unwrapping
  483. * conversion fails.
  484. * @throws NullPointerException
  485. * if the specified object is null.
  486. */
  487. public void set(Object obj, Object value)
  488. throws IllegalArgumentException, IllegalAccessException
  489. {
  490. if (realfield != null)
  491. realfield.set(obj, value);
  492. throw new java.lang.IllegalStateException();
  493. }
  494. /**
  495. * Set the value of a field as a boolean on specified
  496. * object.
  497. *
  498. *
  499. * @param obj
  500. * @param z
  501. * @throws IllegalAccessException
  502. * if the underlying constructor is inaccessible.
  503. * @throws IllegalArgumentException
  504. * if the specified object is not an instance of
  505. * the class or interface declaring the
  506. * underlying field, or if an unwrapping
  507. * conversion fails.
  508. */
  509. public void setBoolean(Object obj, boolean z)
  510. throws IllegalArgumentException, IllegalAccessException
  511. {
  512. if (realfield != null)
  513. realfield.setBoolean(obj, z);
  514. throw new java.lang.IllegalStateException();
  515. }
  516. /**
  517. * Set the value of a field as a byte on specified
  518. * object.
  519. *
  520. *
  521. * @param obj
  522. * @param b
  523. * @throws IllegalAccessException
  524. * if the underlying constructor is inaccessible.
  525. * @throws IllegalArgumentException
  526. * if the specified object is not an instance of
  527. * the class or interface declaring the
  528. * underlying field, or if an unwrapping
  529. * conversion fails.
  530. */
  531. public void setByte(Object obj, byte b)
  532. throws IllegalArgumentException, IllegalAccessException
  533. {
  534. if (realfield != null)
  535. realfield.setByte(obj, b);
  536. throw new java.lang.IllegalStateException();
  537. }
  538. /**
  539. * Set the value of a field as a char on specified
  540. * object.
  541. *
  542. *
  543. * @param obj
  544. * @param c
  545. * @throws IllegalAccessException
  546. * if the underlying constructor is inaccessible.
  547. * @throws IllegalArgumentException
  548. * if the specified object is not an instance of
  549. * the class or interface declaring the
  550. * underlying field, or if an unwrapping
  551. * conversion fails.
  552. */
  553. public void setChar(Object obj, char c)
  554. throws IllegalArgumentException, IllegalAccessException
  555. {
  556. if (realfield != null)
  557. realfield.setChar(obj, c);
  558. throw new java.lang.IllegalStateException();
  559. }
  560. /**
  561. * Returns the Class object representing the class that
  562. * declares the constructor represented by this
  563. * Constructor object.
  564. *
  565. * @param declaringClass
  566. */
  567. public void setDeclaringClass(
  568. org.apache.xml.utils.synthetic.Class declaringClass)
  569. {
  570. this.declaringClass = declaringClass;
  571. }
  572. /**
  573. * Set the value of a field as a double on specified
  574. * object.
  575. *
  576. *
  577. * @param obj
  578. * @param d
  579. * @throws IllegalAccessException
  580. * if the underlying constructor is inaccessible.
  581. * @throws IllegalArgumentException
  582. * if the specified object is not an instance of
  583. * the class or interface declaring the
  584. * underlying field, or if an unwrapping
  585. * conversion fails.
  586. */
  587. public void setDouble(Object obj, double d)
  588. throws IllegalArgumentException, IllegalAccessException
  589. {
  590. if (realfield != null)
  591. realfield.setDouble(obj, d);
  592. throw new java.lang.IllegalStateException();
  593. }
  594. /**
  595. * Set the value of a field as a float on specified
  596. * object.
  597. *
  598. *
  599. * @param obj
  600. * @param f
  601. * @throws IllegalAccessException
  602. * if the underlying constructor is inaccessible.
  603. * @throws IllegalArgumentException
  604. * if the specified object is not an instance of
  605. * the class or interface declaring the
  606. * underlying field, or if an unwrapping
  607. * conversion fails.
  608. */
  609. public void setFloat(Object obj, float f)
  610. throws IllegalArgumentException, IllegalAccessException
  611. {
  612. if (realfield != null)
  613. realfield.setFloat(obj, f);
  614. throw new java.lang.IllegalStateException();
  615. }
  616. /**
  617. * Set the value of a field as an int on specified
  618. * object.
  619. *
  620. *
  621. * @param obj
  622. * @param i
  623. * @throws IllegalAccessException
  624. * if the underlying constructor is inaccessible.
  625. * @throws IllegalArgumentException
  626. * if the specified object is not an instance of
  627. * the class or interface declaring the
  628. * underlying field, or if an unwrapping
  629. * conversion fails.
  630. */
  631. public void setInt(Object obj, int i)
  632. throws IllegalArgumentException, IllegalAccessException
  633. {
  634. if (realfield != null)
  635. realfield.setInt(obj, i);
  636. throw new java.lang.IllegalStateException();
  637. }
  638. /**
  639. * Set the value of a field as a long on specified
  640. * object.
  641. *
  642. *
  643. * @param obj
  644. * @param l
  645. * @throws IllegalAccessException
  646. * if the underlying constructor is inaccessible.
  647. * @throws IllegalArgumentException
  648. * if the specified object is not an instance of
  649. * the class or interface declaring the
  650. * underlying field, or if an unwrapping
  651. * conversion fails.
  652. */
  653. public void setLong(Object obj, long l)
  654. throws IllegalArgumentException, IllegalAccessException
  655. {
  656. if (realfield != null)
  657. realfield.setLong(obj, l);
  658. throw new java.lang.IllegalStateException();
  659. }
  660. /**
  661. * Insert the method's description here.
  662. * Creation date: (12-25-99 1:28:28 PM)
  663. * @return int
  664. * @param modifiers int
  665. *
  666. * @throws SynthesisException
  667. */
  668. public void setModifiers(int modifiers) throws SynthesisException
  669. {
  670. if (realfield != null)
  671. throw new SynthesisException(SynthesisException.REIFIED);
  672. this.modifiers = modifiers;
  673. }
  674. /**
  675. * Set the value of a field as a short on specified
  676. * object.
  677. *
  678. *
  679. * @param obj
  680. * @param s
  681. * @throws IllegalAccessException
  682. * if the underlying constructor is inaccessible.
  683. * @throws IllegalArgumentException
  684. * if the specified object is not an instance of
  685. * the class or interface declaring the
  686. * underlying field, or if an unwrapping
  687. * conversion fails.
  688. */
  689. public void setShort(Object obj, short s)
  690. throws IllegalArgumentException, IllegalAccessException
  691. {
  692. if (realfield != null)
  693. realfield.setShort(obj, s);
  694. throw new java.lang.IllegalStateException();
  695. }
  696. /**
  697. * Return a string describing this Field. The format is
  698. * the access modifiers for the field, if any, followed
  699. * by the field type, followed by a space, followed by
  700. * the fully-qualified name of the class declaring the
  701. * field, followed by a period, followed by the name
  702. * of the field. For example:
  703. * <code>
  704. * public static final int java.lang.Thread.MIN_PRIORITY
  705. * private int java.io.FileDescriptor.fd
  706. * </code>
  707. *
  708. * The modifiers are placed in canonical order as
  709. * specified by "The Java Language Specification".
  710. * This is public, protected or private first,
  711. * and then other modifiers in the following order:
  712. * static, final, transient, volatile.
  713. *
  714. */
  715. public String toString()
  716. {
  717. if (realfield != null)
  718. return realfield.toString();
  719. throw new java.lang.IllegalStateException();
  720. }
  721. /**
  722. * Output the Field as Java sourcecode
  723. *
  724. */
  725. public String toSource()
  726. {
  727. StringBuffer sb = new StringBuffer(
  728. java.lang.reflect.Modifier.toString(getModifiers())).append(' ').append(
  729. getType().getJavaName()).append(' ').append(getName());
  730. String i = getInitializer();
  731. if (i != null && i.length() > 0)
  732. sb.append('=').append(i);
  733. sb.append(';');
  734. return sb.toString();
  735. }
  736. }