--- /dev/null
+package org.apache.fop.datatypes;
+
+import org.apache.fop.datatypes.IndirectValue;
+import org.apache.fop.fo.expr.PropertyValue;
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.Properties;
+import org.apache.fop.fo.FONode;
+
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+/**
+ * A pseudo-class to represent a call to the core function
+ * from-nearest-specified-value().
+ * Used <i>only</i> in the cases where the property
+ * assigned to is identical to the <tt>NCName</tt> argument, and this is a
+ * shorthand.
+ * <p>Further, the function call must be the only component of the expression
+ * in which it occurs. (See Rec. Section 5.10.4 Property Value Functions.)
+ * In these circumstances, the function call resolves to a
+ * from-nearest-specified-value() function call on each of the properties to
+ * which the shorthand resolves.
+ * <p>The use of the pseudo-type should ensure that the function call is not
+ * involved in any arithmetic components of a more complex expression. I.e,
+ * the function evaluator in the parser must check to see whether the
+ * property for which the from-nearest-specified-value() function is being
+ * evaluated is a shorthand. If not, the function is normally evaluated.
+ * If so, the parser must further check that the property assigned to (i.e.
+ * the property against which this function is being evaluated) is the same
+ * as the <tt>NCName</tt> argument. If not, it is an error. If so, the
+ * property evaluates to an instance of this class. The value must itself
+ * be later resolved before the property value can be utilised in the fo
+ * node, but, in the meantime, any attempt to involve the function call in
+ * any more complex expression will throw an exception.
+ * <p>This mechanism ensures, without greatly complicating the parser,
+ * that the constraint on the from-nearest-specified-value() function, with
+ * respect to shorthands, is met.
+ * <p>This pseudo-datatype is also used as the first stage of shorthand
+ * expansion. After a shorthand's expression is parsed, the next stage of
+ * resolution will generate a FromNearestSpecified object for each property
+ * in the expansion of the shorthand.
+ * <p>Once created, this class acts as an <tt>IndirectValue</tt> in the
+ * event that it cannot immediately be resolved. This association exists
+ * simply to save creating another object.
+ *
+ * @see FromParent
+ * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
+ * @version $Revision$ $Name$
+ */
+
+public class FromNearestSpecified extends IndirectValue {
+
+ private static final String tag = "$Name$";
+ private static final String revision = "$Revision$";
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined. In this case, a shorthand property.
+ * @exception PropertyException
+ */
+ public FromNearestSpecified(int property)
+ throws PropertyException
+ {
+ super(property, PropertyValue.FROM_NEAREST_SPECIFIED);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined. In this case, a shorthand property.
+ * @exception PropertyException
+ */
+ public FromNearestSpecified(String propertyName)
+ throws PropertyException
+ {
+ super(propertyName, PropertyValue.FROM_NEAREST_SPECIFIED);
+ }
+
+ /**
+ * Attempt to resolve this object into a "real" property value. If the
+ * object has no <i>inheritedTriplet</i>, obtain and set one. The
+ * obtained triplet is from the nearest ancestor node on which a value
+ * has been specified.
+ * Then invoke the superclass' <i>resolve()</i> method.
+ * @param node - the <tt>FONode</tt> with which this object is associated.
+ * @return the resulting <tt>PropertyValue</tt>. Either a resolved value
+ * or <i>this</i>, if bequeathing triplet has no resolved computed value.
+ */
+ public PropertyValue resolve(FONode node) throws PropertyException {
+ if (inheritedValue == null) {
+ inheritedValue = node.getNearestSpecifiedTriplet(sourceProperty);
+ }
+ return super.resolve(node);
+ }
+
+ /**
+ * validate the <i>FromNearestSpecified</i> against the associated
+ * property.
+ */
+ public void validate() throws PropertyException {
+ super.validate(Properties.SHORTHAND);
+ }
+
+}
--- /dev/null
+package org.apache.fop.datatypes;
+
+import org.apache.fop.datatypes.IndirectValue;
+import org.apache.fop.fo.expr.PropertyValue;
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.Properties;
+
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+/**
+ * A pseudo-class to represent a call to the core function from-parent().
+ * Used <i>only</i> in the cases where the property assigned to
+ * is identical to the <tt>NCName</tt> argument, and this is a shorthand.
+ * <p>Further, the function call must be the only component of the expression
+ * in which it occurs. (See Rec. Section 5.10.4 Property Value Functions.)
+ * In these circumstances, the function call resolves to a
+ * from-parent() function call on each of the properties to
+ * which the shorthand resolves.
+ * <p>The use of the pseudo-type should ensure that the function call is not
+ * involved in any arithmetic components of a more complex expression. I.e,
+ * the function evaluator in the parser must check to see whether the
+ * property for which the from-parent() function is being
+ * evaluated is a shorthand. If not, the function is normally evaluated.
+ * If so, the parser must further check that the property assigned to (i.e.
+ * the property against which this function is being evaluated) is the same
+ * as the <tt>NCName</tt> argument. If not, it is an error. If so, the
+ * property evaluates to an instance of this class. The value must itself
+ * be later resolved before the property value can be utilised in the fo
+ * node, but, in the meantime, any attempt to involve the function call in
+ * any more complex expression will throw an exception.
+ * <p>This mechanism ensures, without greatly complicating the parser,
+ * that the constraint on the from-parent() function, with
+ * respect to shorthands, is met.
+ * <p>This pseudo-datatype is also used as the first stage of shorthand
+ * expansion. After a shorthand's expression is parsed, the next stage of
+ * resolution will generate a FromParent object for each property
+ * in the expansion of the shorthand.
+ * <p>Once created, this class acts as an <tt>IndirectValue</tt> in the
+ * event that it cannot immediately be resolved. This association exists
+ * simply to save creating another object.
+ *
+ * @see FromNearestSpecified
+ * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
+ * @version $Revision$ $Name$
+ */
+
+public class FromParent extends IndirectValue {
+
+ private static final String tag = "$Name$";
+ private static final String revision = "$Revision$";
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined. In this case, a shorthand property.
+ * @exception PropertyException
+ */
+ public FromParent(int property)
+ throws PropertyException
+ {
+ super(property, PropertyValue.FROM_PARENT);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined. In this case, a shorthand property.
+ * @exception PropertyException
+ */
+ public FromParent(String propertyName)
+ throws PropertyException
+ {
+ super(propertyName, PropertyValue.FROM_PARENT);
+ }
+
+ /**
+ * validate the <i>FromParent</i> against the associated property.
+ */
+ public void validate() throws PropertyException {
+ super.validate(Properties.SHORTHAND);
+ }
+
+}
--- /dev/null
+package org.apache.fop.datatypes;
+
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.expr.AbstractPropertyValue;
+import org.apache.fop.fo.expr.PropertyValue;
+import org.apache.fop.fo.expr.PropertyTriplet;
+import org.apache.fop.fo.Properties;
+import org.apache.fop.fo.PropertyConsts;
+import org.apache.fop.fo.FONode;
+
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
+ * @version $Revision$ $Name$
+ */
+/**
+ * A superclass for objects which may have deferred <tt>PropertyValue</tt>
+ * resolution. This is because their value is taken from
+ * another <tt>PropertyValue</tt> object defined earlier in the FO tree.
+ * These include <tt>Inherit</tt>, <tt>FromParent</tt> and
+ * <tt>FromNearestSpecified</tt> objects. If an <tt>InheritedValue</tt>
+ * object is defined, it will also extend this class.
+ * <p>The required value is usually the computed field of the
+ * <tt>PropertyTriplet</tt> for the source property on the source node. This
+ * property may be different from the property of this object. This class
+ * provides accessors for the referenced <tt>PropertyTriplet</tt> and the
+ * computed value of that triplet. In some cases, the specified value is
+ * required. It is the responsibility of the subclass to determine and
+ * act upon these cases. At the time of writing, the only such exception is
+ * when a <i>line-height</i> is defined as a <number>.
+ */
+
+public class IndirectValue extends AbstractPropertyValue {
+
+ private static final String tag = "$Name$";
+ private static final String revision = "$Revision$";
+
+ /**
+ * The property from which the inherited value is to be derived. This
+ * may be different from the target property.
+ */
+ protected int sourceProperty;
+
+ /**
+ * The <tt>PropertyTriplet</tt> from which this object is being
+ * inherited. Set when the inheritance cannot be immediately resolved,
+ * e.g. when the specified value is a percentage.
+ */
+ protected PropertyTriplet inheritedValue = null;
+
+ /**
+ * @param property - the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @param type - the type of <tt>PropertyValue</tt>.
+ * @param sourceProperty - the <tt>int</tt> index of the property from
+ * which the inherited value is derived.
+ * @exception PropertyException
+ */
+ protected IndirectValue(int property, int type, int sourceProperty)
+ throws PropertyException
+ {
+ super(property, type);
+ this.sourceProperty = sourceProperty;
+ }
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @param type - the type of <tt>PropertyValue</tt>.
+ * @exception PropertyException
+ */
+ protected IndirectValue(int property, int type)
+ throws PropertyException
+ {
+ this(property, type, property);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @param type - the type of <tt>PropertyValue</tt>.
+ * @param sourcePropertyName the <tt>String</tt> name of the property
+ * from which the inherited value is derived.
+ * @exception PropertyException
+ */
+ protected IndirectValue
+ (String propertyName, int type, String sourcePropertyName)
+ throws PropertyException
+ {
+ super(propertyName, type);
+ sourceProperty = PropertyConsts.getPropertyIndex(sourcePropertyName);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @param type - the type of <tt>PropertyValue</tt>.
+ * @exception PropertyException
+ */
+ protected IndirectValue(String propertyName, int type)
+ throws PropertyException
+ {
+ this(propertyName, type, propertyName);
+ }
+
+ /**
+ * @return <tt>int</tt> containing the source property index.
+ */
+ public int getSourceProperty() {
+ return sourceProperty;
+ }
+
+ /**
+ * @return <tt>PropertyTriplet</tt> which contains or will contain the
+ * the computed value being inherited. This field will be null except
+ * when an unresolved computed value is being inherited. If so,
+ * a null value will be returned. N.B. This triplet will have a
+ * property value different from this <i>IndirectValue</i> object.
+ */
+ public PropertyTriplet getInheritedTriplet() {
+ return inheritedValue;
+ }
+
+ /**
+ * @return computed <tt>PropertyValue</tt> field from the
+ * <tt>PropertyTriplet</tt> from which this object is inherting.
+ * If the <i>inheritedValue</i> field is null, no resolution of the
+ * inheritance has yet been attempted, and a null value is returned.
+ * If the <i>inheritedValue</i> field is not null, return the
+ * <i>computed</i> field, which may be null. N.B. This
+ * <tt>PropertyValue</tt> may have a property field different from
+ * this <i>IndirectValue</i> object. The source property field is held in
+ * the <i>sourceProperty</i> field.
+ */
+ public PropertyValue getInheritedValue() {
+ if (inheritedValue != null) return inheritedValue.getComputed();
+ return null;
+ }
+
+ /**
+ * Set the reference to the <tt>PropertyTriplet</tt> from which the
+ * value is being inherited.
+ * @param bequeathed - the <tt>PropertyTriplet</tt> which contains
+ * or will contain the the computed value of the percentage being
+ * inherited.
+ */
+ public void setInheritedTriplet(PropertyTriplet bequeathed) {
+ inheritedValue = bequeathed;
+ }
+
+ /**
+ * Attempt to resolve the <tt>IndirectValue</tt> object.
+ * If no bequeathing <tt>PropertyTriplet</tt>, assume that the
+ * bequeathing node is the parent node. This is true for the
+ * <tt>Inherit</tt>, <tt>InheritedValue</tt> and <tt>FromParent</tt>
+ * objects. <tt>FromNearestSpecified</tt> objects must override this
+ * method to ensure that resolution is carried out against the correct
+ * triplet.
+ * <p>If the computed value of that triplet is
+ * null, return this object. If not, return the computed value.
+ * @param node - the <tt>FONode</tt> with which this object is associated.
+ * @return - a <tt>PropertyValue</tt> as described above. A return of
+ * the same <tt>IndirectValue</tt> object implies that the inherited
+ * computed value has not yet been resolved in the ancestor.
+ */
+ protected PropertyValue resolve(FONode node) throws PropertyException {
+ PropertyValue pv;
+ if (inheritedValue == null)
+ inheritedValue = node.getParentTriplet(sourceProperty);
+ if ((pv = inheritedValue.getComputed()) == null)
+ return this;
+ // Check that the property is the same
+ if (property != pv.getProperty()) {
+ try {
+ pv = (PropertyValue)(pv.clone());
+ } catch (CloneNotSupportedException e) {
+ throw new PropertyException(e.getMessage());
+ }
+ }
+ return pv;
+ }
+
+ // N.B. no validation on this class - subclasses will validate
+ // against the interface-defined validate(int) method in the
+ // superclass.
+}
--- /dev/null
+package org.apache.fop.datatypes;
+
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.expr.PropertyValue;
+import org.apache.fop.fo.expr.PropertyTriplet;
+import org.apache.fop.fo.Properties;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.datatypes.IndirectValue;
+
+/*
+ * Inherit.java
+ * $Id$
+ *
+ * Created: Tue Nov 20 22:18:11 2001
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
+ * @version $Revision$ $Name$
+ */
+/**
+ * A class representing the <tt>inherit</tt> keyword. This keyword is
+ * regarded as a property value which is always equivalent to the computed
+ * value of the parent. It cannot refer to a value defined on any other
+ * property.
+ */
+
+public class Inherit extends IndirectValue {
+
+ private static final String tag = "$Name$";
+ private static final String revision = "$Revision$";
+
+ /**
+ * Override the dual-property constructor of <tt>IndirectValue</tt>.
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @param sourceProperty the <tt>int</tt> index of the property from
+ * which the inherited value is derived.
+ * @exception PropertyException
+ */
+ public Inherit(int property, int sourceProperty)
+ throws PropertyException
+ {
+ super(property, PropertyValue.INHERIT, sourceProperty);
+ }
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @exception PropertyException
+ */
+ public Inherit(int property)
+ throws PropertyException
+ {
+ this(property, property);
+ }
+
+ /**
+ * Override the dual-property constructor of <tt>IndirectValue</tt>.
+ * <i>'inherit'</i> cannot draw a value from a different property from
+ * the one on which it was defined, so this constructor is private.
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @param sourcePropertyName the <tt>String</tt> name of the property
+ * from which the inherited value is derived.
+ * @exception PropertyException
+ */
+ private Inherit(String propertyName, String sourcePropertyName)
+ throws PropertyException
+ {
+ super(propertyName, PropertyValue.INHERIT, sourcePropertyName);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @exception PropertyException
+ */
+ public Inherit(String propertyName)
+ throws PropertyException
+ {
+ this(propertyName, propertyName);
+ }
+
+ /**
+ * validate the <i>Inherit</i> against the associated property.
+ */
+ public void validate() throws PropertyException {
+ super.validate(getSourceProperty(), Properties.INHERIT);
+ }
+
+}
--- /dev/null
+package org.apache.fop.datatypes;
+
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.expr.PropertyValue;
+import org.apache.fop.fo.expr.PropertyTriplet;
+import org.apache.fop.fo.Properties;
+import org.apache.fop.fo.PropNames;
+import org.apache.fop.fo.PropertyConsts;
+import org.apache.fop.datatypes.IndirectValue;
+
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
+ * @version $Revision$ $Name$
+ */
+/**
+ * A class representing an unresolved inherited value. It may be created as
+ * in the process of resolving "normal" default inheritance, when no value is
+ * specified for an inheritable property, or it may be created in the process
+ * of resolving a call to the core function
+ * <tt>inherited-property-value()</tt>. In both cases, it will only be
+ * necessary when the inherited property cannot otherwise be resolved into a
+ * <tt>PropertyValue<tt> immediately.
+ * <p>Strictly speaking, a distinction should be made between these two
+ * cases, because the latter may derive from a property other than the
+ * target property whose value ist is resolving. This is never true of
+ * default inheritance.
+ * <p><tt>InheritedValue</tt> differs from <tt>Inherit</tt> in that it only
+ * applies to properties which support default inheritance, and there is at
+ * least one case - that of <i>line-height</i> defined as a <number> -
+ * in which the specified value is inherited.
+ */
+
+public class InheritedValue extends IndirectValue {
+
+ private static final String tag = "$Name$";
+ private static final String revision = "$Revision$";
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @param sourceProperty the <tt>int</tt> index of the property from
+ * which the inherited value is derived.
+ * @exception PropertyException
+ */
+ public InheritedValue(int property, int sourceProperty)
+ throws PropertyException
+ {
+ super(property, PropertyValue.INHERIT, sourceProperty);
+ }
+
+ /**
+ * @param property the <tt>int</tt> index of the property on which
+ * this value is being defined.
+ * @exception PropertyException
+ */
+ public InheritedValue(int property)
+ throws PropertyException
+ {
+ this(property, property);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @param sourcePropertyName the <tt>String</tt> name of the property
+ * from which the inherited value is derived.
+ * @exception PropertyException
+ */
+ public InheritedValue(String propertyName, String sourcePropertyName)
+ throws PropertyException
+ {
+ super(propertyName, PropertyValue.INHERIT, sourcePropertyName);
+ }
+
+ /**
+ * @param propertyName the <tt>String</tt> name of the property on which
+ * this value is being defined.
+ * @exception PropertyException
+ */
+ public InheritedValue(String propertyName)
+ throws PropertyException
+ {
+ this(propertyName, propertyName);
+ }
+
+ /**
+ * validate the <i>InheritedValue</i> against the associated property.
+ * TODO: validate is a total mess. It will all require a rethink
+ * when the expression parsing is being finalised.
+ * @param type - an <tt>int</tt> bitmap of datatypes. Irrelevant here.
+ */
+ public void validate(int type) throws PropertyException {
+ String propStr = "Unknown";
+ String spropStr = "Unknown";
+ // Property must be inheritable
+ if (PropertyConsts.inheritance(sourceProperty) == Properties.NO) {
+ try {
+ propStr = PropNames.getPropertyName(property);
+ spropStr = PropNames.getPropertyName(sourceProperty);
+ } catch (PropertyException e) {}
+ throw new PropertyException
+ ("Source property " + sourceProperty + " (" + spropStr
+ + ") for " + this.property + " (" + propStr
+ + ") is not inheritable.");
+ }
+ }
+
+ /**
+ * validate the <i>InheritedValue</i> against the <i>source</i> property.
+ */
+ public void validate() throws PropertyException {
+ validate(Properties.ANY_TYPE);
+ }
+
+}