1. /*
  2. * @(#)Expression.java 1.13 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.beans;
  8. /**
  9. * An <code>Expression</code> object represents a primitive expression
  10. * in which a single method is applied to a target and a set of
  11. * arguments to return a result - as in <code>"a.getFoo()"</code>.
  12. * <p>
  13. * In addition to the properties of the super class, the
  14. * <code>Expression</code> object provides a <em>value</em> which
  15. * is the object returned when this expression is evaluated.
  16. * The return value is typically not provided by the caller and
  17. * is instead computed by dynamically finding the method and invoking
  18. * it when the first call to <code>getValue</code> is made.
  19. *
  20. * @see #getValue
  21. * @see #setValue
  22. *
  23. * @since 1.4
  24. *
  25. * @version 1.3 11/15/00
  26. * @author Philip Milne
  27. */
  28. public class Expression extends Statement {
  29. private static Object unbound = new Object();
  30. private Object value = unbound;
  31. /**
  32. * Creates a new <code>Statement</code> object with a <code>target</code>,
  33. * <code>methodName</code> and <code>arguments</code> as per the parameters.
  34. *
  35. * @param target The target of this expression.
  36. * @param methodName The methodName of this expression.
  37. * @param arguments The arguments of this expression. If <code>null</code> then an empty array will be used.
  38. *
  39. * @see #getValue
  40. */
  41. public Expression(Object target, String methodName, Object[] arguments) {
  42. super(target, methodName, arguments);
  43. }
  44. /**
  45. * Creates a new <code>Expression</code> object for a method
  46. * that returns a result. The result will never be calculated
  47. * however, since this constructor uses the <code>value</code>
  48. * parameter to set the value property by calling the
  49. * <code>setValue</code> method.
  50. *
  51. * @param value The value of this expression.
  52. * @param target The target of this expression.
  53. * @param methodName The methodName of this expression.
  54. * @param arguments The arguments of this expression. If <code>null</code> then an empty array will be used.
  55. *
  56. * @see #setValue
  57. */
  58. public Expression(Object value, Object target, String methodName, Object[] arguments) {
  59. this(target, methodName, arguments);
  60. setValue(value);
  61. }
  62. /**
  63. * If the value property of this instance is not already set,
  64. * this method dynamically finds the method with the specified
  65. * methodName on this target with these arguments and calls it.
  66. * The result of the method invocation is first copied
  67. * into the value property of this expression and then returned
  68. * as the result of <code>getValue</code>. If the value property
  69. * was already set, either by a call to <code>setValue</code>
  70. * or a previous call to <code>getValue</code> then the value
  71. * property is returned without either looking up or calling the method.
  72. * <p>
  73. * The value property of an <code>Expression</code> is set to
  74. * a unique private (non-<code>null</code>) value by default and
  75. * this value is used as an internal indication that the method
  76. * has not yet been called. A return value of <code>null</code>
  77. * replaces this default value in the same way that any other value
  78. * would, ensuring that expressions are never evaluated more than once.
  79. * <p>
  80. * See the <code>excecute<code> method for details on how
  81. * methods are chosen using the dynamic types of the target
  82. * and arguments.
  83. *
  84. * @see Statement#execute
  85. * @see #setValue
  86. *
  87. * @return The result of applying this method to these arguments.
  88. */
  89. public Object getValue() throws Exception {
  90. if (value == unbound) {
  91. setValue(invoke());
  92. }
  93. return value;
  94. }
  95. /**
  96. * Sets the value of this expression to <code>value</code>.
  97. * This value will be returned by the getValue method
  98. * without calling the method associated with this
  99. * expression.
  100. *
  101. * @param value The value of this expression.
  102. *
  103. * @see #getValue
  104. */
  105. public void setValue(Object value) {
  106. this.value = value;
  107. }
  108. /*pp*/ String instanceName(Object instance) {
  109. return instance == unbound ? "<unbound>" : super.instanceName(instance);
  110. }
  111. /**
  112. * Prints the value of this expression using a Java-style syntax.
  113. */
  114. public String toString() {
  115. return instanceName(value) + "=" + super.toString();
  116. }
  117. }