You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IndirectValue.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * $Id$
  3. *
  4. *
  5. *
  6. * Copyright 1999-2003 The Apache Software Foundation.
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. *
  21. * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
  22. * @version $Revision$ $Name$
  23. */
  24. package org.apache.fop.datatypes.indirect;
  25. import org.apache.fop.datatypes.AbstractPropertyValue;
  26. import org.apache.fop.datatypes.Numeric;
  27. import org.apache.fop.datatypes.PropertyValue;
  28. import org.apache.fop.fo.FONode;
  29. import org.apache.fop.fo.PropNames;
  30. import org.apache.fop.fo.expr.PropertyException;
  31. /**
  32. * A superclass for objects which may have deferred <tt>PropertyValue</tt>
  33. * resolution. This is because their value is taken from
  34. * another <tt>PropertyValue</tt> object defined earlier in the FO tree.
  35. * These include <tt>Inherit</tt>, <tt>FromParent</tt> and
  36. * <tt>FromNearestSpecified</tt> objects. If an <tt>InheritedValue</tt>
  37. * object is defined, it will also extend this class.
  38. * <p>The required value is usually the computed value of the
  39. * <tt>PropertyValue</tt> of the source property on the source node. This
  40. * property may be different from the property of this object. This class
  41. * provides accessors for the referenced <tt>PropertyValue</tt>.
  42. * In some cases, the specified value is
  43. * required. It is the responsibility of the subclass to determine and
  44. * act upon these cases. At the time of writing, the only such exception is
  45. * when a <i>line-height</i> is defined as a &lt;number&gt;.
  46. */
  47. public class IndirectValue extends AbstractPropertyValue {
  48. private static final String tag = "$Name$";
  49. private static final String revision = "$Revision$";
  50. /**
  51. * The property from which the inherited value is to be derived. This
  52. * may be different from the target property.
  53. */
  54. protected int sourceProperty;
  55. /**
  56. * The <tt>PropertyValue</tt> from which this object is being
  57. * inherited. Set when the inheritance cannot be immediately resolved,
  58. * e.g. when the specified value is a percentage.
  59. */
  60. protected PropertyValue inheritedValue = null;
  61. /**
  62. * @param property - the <tt>int</tt> index of the property on which
  63. * this value is being defined.
  64. * @param type - the type of <tt>PropertyValue</tt>.
  65. * @param sourceProperty - the <tt>int</tt> index of the property from
  66. * which the inherited value is derived.
  67. * @exception PropertyException
  68. */
  69. protected IndirectValue(int property, int type, int sourceProperty)
  70. throws PropertyException
  71. {
  72. super(property, type);
  73. this.sourceProperty = sourceProperty;
  74. }
  75. /**
  76. * @param property the <tt>int</tt> index of the property on which
  77. * this value is being defined.
  78. * @param type - the type of <tt>PropertyValue</tt>.
  79. * @exception PropertyException
  80. */
  81. protected IndirectValue(int property, int type)
  82. throws PropertyException
  83. {
  84. this(property, type, property);
  85. }
  86. /**
  87. * @param propertyName the <tt>String</tt> name of the property on which
  88. * this value is being defined.
  89. * @param type - the type of <tt>PropertyValue</tt>.
  90. * @param sourcePropertyName the <tt>String</tt> name of the property
  91. * from which the inherited value is derived.
  92. * @exception PropertyException
  93. */
  94. protected IndirectValue
  95. (String propertyName, int type, String sourcePropertyName)
  96. throws PropertyException
  97. {
  98. super(propertyName, type);
  99. sourceProperty = PropNames.getPropertyIndex(sourcePropertyName);
  100. }
  101. /**
  102. * @param propertyName the <tt>String</tt> name of the property on which
  103. * this value is being defined.
  104. * @param type - the type of <tt>PropertyValue</tt>.
  105. * @exception PropertyException
  106. */
  107. protected IndirectValue(String propertyName, int type)
  108. throws PropertyException
  109. {
  110. this(propertyName, type, propertyName);
  111. }
  112. /**
  113. * @return <tt>int</tt> containing the source property index.
  114. */
  115. public int getSourceProperty() {
  116. return sourceProperty;
  117. }
  118. /**
  119. * @return <tt>PropertyValue</tt> which contains or will contain the
  120. * the computed value being inherited. This field will be null except
  121. * when an unresolved computed value is being inherited. If so,
  122. * a null value will be returned. N.B. This
  123. * <tt>PropertyValue</tt> may have a property field different from
  124. * this <i>IndirectValue</i> object. The source property field is held in
  125. * the <i>sourceProperty</i> field.
  126. */
  127. public PropertyValue getInheritedValue() {
  128. return inheritedValue;
  129. }
  130. /**
  131. * Set the reference to the <tt>PropertyValue</tt> from which the
  132. * value is being inherited.
  133. * @param bequeathed - the <tt>PropertyValue</tt> which contains
  134. * or will contain the the computed value of the percentage being
  135. * inherited.
  136. */
  137. public void setInheritedValue(PropertyValue bequeathed) {
  138. inheritedValue = bequeathed;
  139. }
  140. /**
  141. * Attempt to resolve the <tt>IndirectValue</tt> object.
  142. * If no bequeathing <tt>PropertyValue</tt>, assume that the
  143. * bequeathing node is the parent node. This is true for the
  144. * <tt>Inherit</tt>, <tt>InheritedValue</tt> and <tt>FromParent</tt>
  145. * objects. <tt>FromNearestSpecified</tt> objects must override this
  146. * method to ensure that resolution is carried out against the correct
  147. * property value.
  148. * <p>If the computed value is
  149. * null, return this object. If not, return the computed value.
  150. * @param node - the <tt>FONode</tt> with which this object is associated.
  151. * @return - a <tt>PropertyValue</tt> as described above. A return of
  152. * the same <tt>IndirectValue</tt> object implies that the inherited
  153. * computed value has not yet been resolved in the ancestor.
  154. */
  155. public PropertyValue resolve(FONode node) throws PropertyException {
  156. PropertyValue pv;
  157. if (inheritedValue == null)
  158. inheritedValue = node.fromParent(sourceProperty);
  159. if (isUnresolved(inheritedValue))
  160. return this;
  161. pv = inheritedValue;
  162. // Check that the property is the same
  163. if (property != pv.getProperty()) {
  164. // Don't clone if it's another indirect value - just keep this one
  165. // When the value finally resolves into a length, we will clone.
  166. if (pv instanceof IndirectValue) return this;
  167. try {
  168. pv = (PropertyValue)(pv.clone());
  169. } catch (CloneNotSupportedException e) {
  170. throw new PropertyException(e.getMessage());
  171. }
  172. }
  173. return pv;
  174. }
  175. public static boolean isUnresolved(PropertyValue value) {
  176. return (value.getType() == PropertyValue.NUMERIC
  177. && ((Numeric)(value)).isPercentage());
  178. }
  179. public static PropertyValue adjustedPropertyValue(PropertyValue value)
  180. throws PropertyException
  181. {
  182. if (isUnresolved(value)) {
  183. Inherit inherit = new Inherit(value.getProperty());
  184. inherit.setInheritedValue(value);
  185. return inherit;
  186. }
  187. return value;
  188. }
  189. // N.B. no validation on this class - subclasses will validate
  190. // against the interface-defined validate(int) method in the
  191. // superclass.
  192. }