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