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