123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- /*
- * $Id: Property.java,v 1.22 2003/03/05 21:48:02 jeremias Exp $
- * ============================================================================
- * The Apache Software License, Version 1.1
- * ============================================================================
- *
- * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modifica-
- * tion, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- * include the following acknowledgment: "This product includes software
- * developed by the Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself, if
- * and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "FOP" and "Apache Software Foundation" must not be used to
- * endorse or promote products derived from this software without prior
- * written permission. For written permission, please contact
- * apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache", nor may
- * "Apache" appear in their name, without prior written permission of the
- * Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ============================================================================
- *
- * This software consists of voluntary contributions made by many individuals
- * on behalf of the Apache Software Foundation and was originally created by
- * James Tauber <jtauber@jtauber.com>. For more information on the Apache
- * Software Foundation, please see <http://www.apache.org/>.
- */
- package org.apache.fop.fo;
-
- import org.apache.fop.datatypes.ColorType;
- import org.apache.fop.datatypes.CondLength;
- import org.apache.fop.datatypes.CompoundDatatype;
- import org.apache.fop.datatypes.Keep;
- import org.apache.fop.datatypes.Length;
- import org.apache.fop.datatypes.LengthPair;
- import org.apache.fop.datatypes.LengthRange;
- import org.apache.fop.datatypes.PercentBase;
- import org.apache.fop.datatypes.LengthBase;
- import org.apache.fop.datatypes.Space;
- import org.apache.fop.fo.expr.Numeric;
- import org.apache.fop.fo.expr.PropertyParser;
- import org.apache.fop.fo.expr.PropertyInfo;
- import org.apache.fop.apps.FOPException;
- import java.util.Vector;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * Base class for all property objects
- * @author unascribed
- */
- public class Property {
-
- /**
- * Base class for all property makers
- * @author unascribed
- */
- public static class Maker implements Cloneable {
- protected int propId;
- private boolean inherited = true;
- private Map enums = null;
- private Map keywords = null;
- protected String defaultValue = null;
- protected boolean contextDep = false;
- protected boolean setByShorthand = false;
- private int percentBase = -1;
- private Property.Maker[] shorthands = null;
- private ShorthandParser datatypeParser;
-
- protected Property defaultProperty;
- protected CorrespondingPropertyMaker corresponding;
-
- /**
- * @return the name of the property for this Maker
- */
- protected int getPropId() {
- return propId;
- }
-
- /**
- * Construct an instance of a Property.Maker for the given property.
- * @param propId The Constant ID of the property to be made.
- */
- public Maker(int propId) {
- this.propId = propId;
- }
-
- /**
- * Copy all the values from the generic maker to this maker.
- * @param generic a generic property maker.
- */
- public void useGeneric(Property.Maker generic) {
- contextDep = generic.contextDep;
- inherited = generic.inherited;
- defaultValue = generic.defaultValue;
- percentBase = generic.percentBase;
- if (generic.shorthands != null) {
- shorthands = new Property.Maker[generic.shorthands.length];
- System.arraycopy(shorthands, 0, generic.shorthands, 0, shorthands.length);
- }
- if (generic.enums != null) {
- enums = new HashMap(generic.enums);
- }
- if (generic.keywords != null) {
- keywords = new HashMap(generic.keywords);
- }
- }
-
- /**
- * Set the inherited flag.
- * @param inherited
- */
- public void setInherited(boolean inherited) {
- this.inherited = inherited;
- }
-
- /**
- * Add a keyword-equiv to the maker.
- * @param keyword
- * @param value
- */
- public void addKeyword(String keyword, String value) {
- if (keywords == null) {
- keywords = new HashMap();
- }
- keywords.put(keyword, value);
- }
-
- /**
- * Add a enum constant.
- * @param constant
- * @param value
- */
- public void addEnum(String constant, Property value) {
- if (enums == null) {
- enums = new HashMap();
- }
- enums.put(constant, value);
- }
-
- /**
- * Add a subproperty to this maker.
- * @param subproperty
- */
- public void addSubpropMaker(Property.Maker subproperty) {
- throw new RuntimeException("Unable to add subproperties " + getClass());
- }
-
- /**
- * Return a subproperty maker for the subpropId.
- * @param subpropId The subpropId of the maker.
- * @return The subproperty maker.
- */
- public Property.Maker getSubpropMaker(int subpropId) {
- throw new RuntimeException("Unable to add subproperties");
- }
-
- /**
- * Add a shorthand to this maker. Only an Integer is added to the
- * shorthands list. Later the Integers are replaced with references
- * to the actual shorthand property makers.
- * @param shorthand a property maker thar is that is checked for
- * shorthand values.
- */
- public void addShorthand(Property.Maker shorthand) {
- if (shorthands == null) {
- shorthands = new Property.Maker[3];
- }
- for (int i = 0; i < shorthands.length; i++) {
- if (shorthands[i] == null) {
- shorthands[i] = shorthand;
- break;
- }
- }
- }
-
- /**
- * Set the shorthand datatype parser.
- * @param subproperty
- */
- public void setDatatypeParser(ShorthandParser parser) {
- datatypeParser = parser;
- }
-
- /**
- * Set the default value for this maker.
- * @param defaultValue the default value.
- */
- public void setDefault(String defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- /**
- * Set the default value for this maker.
- * @param defaultValue
- * @param contextDep true when the value context dependent and
- * must not be cached.
- */
- public void setDefault(String defaultValue, boolean contextDep) {
- this.defaultValue = defaultValue;
- this.contextDep = contextDep;
- }
-
- /**
- * Set the percent base identifier for this maker.
- * @param percentBase
- */
- public void setPercentBase(int percentBase) {
- this.percentBase = percentBase;
- }
-
- /**
- * Set the byShorthand flag which only is applicable for subproperty
- * makers. It should be true for the subproperties which must be
- * assigned a value when the base property is assigned a attribute
- * value directly.
- * @param defaultValue
- */
- public void setByShorthand(boolean setByShorthand) {
- this.setByShorthand = setByShorthand;
- }
-
- /**
- * Set the correspoding property information.
- * @param corresponding a corresponding maker where the
- * isForcedCorresponding and compute methods are delegated to.
- */
- public void setCorresponding(CorrespondingPropertyMaker corresponding) {
- this.corresponding = corresponding;
- }
-
- /**
- * Create a new empty property. Must be overriden in compound
- * subclasses.
- * @return a new instance of the Property for which this is a maker.
- */
- public Property makeNewProperty() {
- return null;
- }
-
- /*
- * If the property is a relative property with a corresponding absolute
- * value specified, the absolute value is used. This is also true of
- * the inheritance priority (I think...)
- * If the property is an "absolute" property and it isn't specified, then
- * we try to compute it from the corresponding relative property: this
- * happens in computeProperty.
- */
- protected Property findProperty(PropertyList propertyList,
- boolean bTryInherit)
- throws FOPException
- {
- Property p = null;
-
- if (corresponding != null && corresponding.isCorrespondingForced(propertyList)) {
- p = corresponding.compute(propertyList);
- } else {
- p = propertyList.getExplicitBaseProp(propId);
- if (p == null) {
- p = this.compute(propertyList);
- }
- if (p == null) { // check for shorthand specification
- p = getShorthand(propertyList);
- }
- if (p == null && bTryInherit) {
- // else inherit (if has parent and is inheritable)
- PropertyList parentPropertyList = propertyList.getParentPropertyList();
- if (parentPropertyList != null && isInherited()) {
- p = findProperty(parentPropertyList, true);
- }
- }
- }
- return p;
- }
-
- /**
- * Return the property on the current FlowObject. Depending on the passed flags,
- * this will try to compute it based on other properties, or if it is
- * inheritable, to return the inherited value. If all else fails, it returns
- * the default value.
- * @param subpropId The subproperty id of the property being retrieved.
- * Is 0 when retriving a base property.
- * @param propertylist The PropertyList object being built for this FO.
- * @param bTryInherit true if inherited properties should be examined.
- * @param bTryDefault true if the default value should be returned.
- */
- public Property get(int subpropId, PropertyList propertyList,
- boolean bTryInherit, boolean bTryDefault)
- throws FOPException
- {
- Property p = findProperty(propertyList, bTryInherit);
- if (p == null && bTryDefault) { // default value for this FO!
- try {
- p = make(propertyList);
- } catch (FOPException e) {
- // don't know what to do here
- }
- }
- return p;
- }
-
- /**
- * Default implementation of isInherited.
- * @return A boolean indicating whether this property is inherited.
- */
- public boolean isInherited() {
- return inherited;
- }
-
- /**
- * This is used to handle properties specified as a percentage of
- * some "base length", such as the content width of their containing
- * box.
- * Overridden by subclasses which allow percent specifications. See
- * the documentation on properties.xsl for details.
- * @param fo the FObj containing the PercentBase
- * @param pl the PropertyList containing the property. (TODO: explain
- * what this is used for, or remove it from the signature.)
- * @return an object implementing the PercentBase interface.
- */
- public PercentBase getPercentBase(FObj fo, PropertyList pl) {
- if (percentBase == -1)
- return null;
- return new LengthBase(fo, pl, percentBase);
- }
-
- /**
- * Return a property value for the given component of a compound
- * property.
- * @param p A property value for a compound property type such as
- * SpaceProperty.
- * @param subprop The Constants ID of the component whose value is to be
- * returned.
- * NOTE: this is only to ease porting when calls are made to
- * PropertyList.get() using a component name of a compound property,
- * such as get("space.optimum"). The recommended technique is:
- * get("space").getOptimum().
- * Overridden by property maker subclasses which handle
- * compound properties.
- * @return the Property containing the subproperty
- */
- public Property getSubprop(Property p, int subpropId) {
- CompoundDatatype val = (CompoundDatatype) p.getObject();
- return val.getComponent(subpropId);
- }
-
- /**
- * Set a component in a compound property and return the modified
- * compound property object.
- * This default implementation returns the original base property
- * without modifying it.
- * It is overridden by property maker subclasses which handle
- * compound properties.
- * @param baseProp The Property object representing the compound property,
- * such as SpaceProperty.
- * @param partId The ID of the component whose value is specified.
- * @param subProp A Property object holding the specified value of the
- * component to be set.
- * @return The modified compound property object.
- */
- protected Property setSubprop(Property baseProp, int partId,
- Property subProp) {
- CompoundDatatype val = (CompoundDatatype) baseProp.getObject();
- val.setComponent(partId, subProp, false);
- return baseProp;
- }
-
- /**
- * Return the default value.
- * @param propertyList The PropertyList object being built for this FO.
- * @return the Property object corresponding to the parameters
- * @throws FOPException for invalid or inconsisten FO input
- */
- public Property make(PropertyList propertyList) throws FOPException {
- if (defaultProperty != null) {
- return defaultProperty;
- }
- Property p = make(propertyList, defaultValue, propertyList.getParentFObj());
- if (!contextDep) {
- defaultProperty = p;
- }
- return p;
- }
-
- /**
- * Create a Property object from an attribute specification.
- * @param propertyList The PropertyList object being built for this FO.
- * @param value The attribute value.
- * @param fo The current FO whose properties are being set.
- * @return The initialized Property object.
- * @throws FOPException for invalid or inconsistent FO input
- */
- public Property make(PropertyList propertyList, String value,
- FObj fo) throws FOPException {
- try {
- Property newProp = null;
- String pvalue = value;
- if ("inherit".equals(value)) {
- newProp = propertyList.getFromParent(this.propId);
- } else {
- newProp = checkEnumValues(value);
- }
- if (newProp == null) {
- /* Check for keyword shorthand values to be substituted. */
- pvalue = checkValueKeywords(value);
- // Override parsePropertyValue in each subclass of Property.Maker
- Property p = PropertyParser.parse(pvalue,
- new PropertyInfo(this,
- propertyList, fo));
- newProp = convertProperty(p, propertyList, fo);
- }
- if (newProp == null) {
- throw new org.apache.fop.fo.expr.PropertyException("No conversion defined");
- }
- return newProp;
- } catch (org.apache.fop.fo.expr.PropertyException propEx) {
- String propName = FOPropertyMapping.getPropertyName(this.propId);
- throw new FOPException("Error in " + propName
- + " property value '" + value + "': "
- + propEx);
- }
- }
-
- /**
- * Make a property value for a compound property. If the property
- * value is already partially initialized, this method will modify it.
- * @param baseProp The Property object representing the compound property,
- * for example: SpaceProperty.
- * @param subpropId The Constants ID of the subproperty (component)
- * whose value is specified.
- * @param propertyList The propertyList being built.
- * @param fo The FO whose properties are being set.
- * @param value the value of the
- * @return baseProp (or if null, a new compound property object) with
- * the new subproperty added
- * @throws FOPException for invalid or inconsistent FO input
- */
- public Property make(Property baseProp, int subpropId,
- PropertyList propertyList, String value,
- FObj fo) throws FOPException {
- //getLogger().error("compound property component "
- // + partName + " unknown.");
- return baseProp;
- }
-
- public Property convertShorthandProperty(PropertyList propertyList,
- Property prop, FObj fo) {
- Property pret = null;
- try {
- pret = convertProperty(prop, propertyList, fo);
- if (pret == null) {
- // If value is a name token, may be keyword or Enum
- String sval = prop.getNCname();
- if (sval != null) {
- // System.err.println("Convert shorthand ncname " + sval);
- pret = checkEnumValues(sval);
- if (pret == null) {
- /* Check for keyword shorthand values to be substituted. */
- String pvalue = checkValueKeywords(sval);
- if (!pvalue.equals(sval)) {
- // System.err.println("Convert shorthand keyword" + pvalue);
- // Substituted a value: must parse it
- Property p =
- PropertyParser.parse(pvalue,
- new PropertyInfo(this,
- propertyList,
- fo));
- pret = convertProperty(p, propertyList, fo);
- }
- }
- }
- }
- } catch (FOPException e) {
-
- //getLogger().error("convertShorthandProperty caught FOPException "
- // + e);
- } catch (org.apache.fop.fo.expr.PropertyException propEx) {
- //getLogger().error("convertShorthandProperty caught PropertyException "
- // + propEx);
- }
- if (pret != null) {
- /*
- * System.err.println("Return shorthand value " + pret.getString() +
- * " for " + getPropName());
- */
- }
- return pret;
- }
-
- /**
- * For properties that contain enumerated values.
- * This method should be overridden by subclasses.
- * @param value the string containing the property value
- * @return the Property encapsulating the enumerated equivalent of the
- * input value
- */
- protected Property checkEnumValues(String value) {
- if (enums != null) {
- return (Property) enums.get(value);
- }
- return null;
- }
-
- /**
- * Return a String to be parsed if the passed value corresponds to
- * a keyword which can be parsed and used to initialize the property.
- * For example, the border-width family of properties can have the
- * initializers "thin", "medium", or "thick". The FOPropertyMapping
- * file specifies a length value equivalent for these keywords,
- * such as "0.5pt" for "thin".
- * @param value The string value of property attribute.
- * @return A String containging a parseable equivalent or null if
- * the passed value isn't a keyword initializer for this Property.
- */
- protected String checkValueKeywords(String keyword) {
- if (keywords != null) {
- String value = (String)keywords.get(keyword);
- if (value != null) {
- return value;
- }
- }
- return keyword;
- }
-
- /**
- * Return a Property object based on the passed Property object.
- * This method is called if the Property object built by the parser
- * isn't the right type for this property.
- * It is overridden by subclasses.
- * @param p The Property object return by the expression parser
- * @param propertyList The PropertyList object being built for this FO.
- * @param fo The current FO whose properties are being set.
- * @return A Property of the correct type or null if the parsed value
- * can't be converted to the correct type.
- * @throws FOPException for invalid or inconsistent FO input
- */
- protected Property convertProperty(Property p,
- PropertyList propertyList,
- FObj fo) throws FOPException {
- return null;
- }
-
- /**
- * For properties that have more than one legal way to be specified,
- * this routine should be overridden to attempt to set them based upon
- * the other methods. For example, colors may be specified using an RGB
- * model, or they may be specified using an NCname.
- * @param p property whose datatype should be converted
- * @param propertyList collection of properties. (TODO: explain why
- * this is needed, or remove it from the signature.)
- * @param fo the FObj to which this property is attached. (TODO: explain
- * why this is needed, or remove it from the signature).
- * @return an Property with the appropriate datatype used
- */
- protected Property convertPropertyDatatype(Property p,
- PropertyList propertyList,
- FObj fo) {
- return null;
- }
-
- /**
- * Return a Property object representing the value of this property,
- * based on other property values for this FO.
- * A special case is properties which inherit the specified value,
- * rather than the computed value.
- * @param propertyList The PropertyList for the FO.
- * @return Property A computed Property value or null if no rules
- * are specified to compute the value.
- * @throws FOPException for invalid or inconsistent FO input
- */
- protected Property compute(PropertyList propertyList)
- throws FOPException {
- if (corresponding != null) {
- return corresponding.compute(propertyList);
- }
- return null; // standard
- }
-
- /**
- * For properties that can be set by shorthand properties, this method
- * should return the Property, if any, that is parsed from any
- * shorthand properties that affect this property.
- * This method expects to be overridden by subclasses.
- * For example, the border-right-width property could be set implicitly
- * from the border shorthand property, the border-width shorthand
- * property, or the border-right shorthand property. This method should
- * be overridden in the appropriate subclass to check each of these, and
- * return an appropriate border-right-width Property object.
- * @param propertyList the collection of properties to be considered
- * @return the Property, if found, the correspons, otherwise, null
- */
- protected Property getShorthand(PropertyList propertyList) {
- if (shorthands == null) {
- return null;
- }
- ListProperty listprop;
- int n = shorthands.length;
- for (int i = 0; i < n; i++) {
- Property.Maker shorthand = shorthands[i];
- listprop = (ListProperty)propertyList.getExplicit(shorthand.propId);
- if (listprop != null) {
- ShorthandParser parser = shorthand.datatypeParser;
- Property p = parser.getValueForProperty(getPropId(),
- listprop, this, propertyList);
- if (p != null) {
- return p;
- }
- }
- }
- return null;
- }
-
- /**
- * Return a clone of the makers. Used by useGeneric() to clone the
- * subproperty makers of the generic compound makers.
- */
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException exc) {
- return null;
- }
- }
- } // end of nested Maker class
-
- /**
- * The original specified value for properties which inherit
- * specified values.
- */
- private String specVal;
-
- /**
- * Set the original value specified for the property attribute.
- * @param specVal The specified value.
- */
- public void setSpecifiedValue(String specVal) {
- this.specVal = specVal;
- }
-
- /**
- * Return the original value specified for the property attribute.
- * @return The specified value as a String.
- */
- public String getSpecifiedValue() {
- return specVal;
- }
-
- /*
- * This section contains accessor functions for all possible Property datatypes
- */
-
-
- /**
- * This method expects to be overridden by subclasses
- * @return Length property value
- */
- public Length getLength() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return ColorType property value
- */
- public ColorType getColorType() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return CondLength property value
- */
- public CondLength getCondLength() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return LenghtRange property value
- */
- public LengthRange getLengthRange() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return LengthPair property value
- */
- public LengthPair getLengthPair() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return Space property value
- */
- public Space getSpace() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return Keep property value
- */
- public Keep getKeep() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return integer equivalent of enumerated property value
- */
- public int getEnum() {
- return 0;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return char property value
- */
- public char getCharacter() {
- return 0;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return collection of other property (sub-property) objects
- */
- public Vector getList() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return Number property value
- */
- public Number getNumber() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return Numeric property value
- */
- public Numeric getNumeric() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return NCname property value
- */
- public String getNCname() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses
- * @return Object property value
- */
- public Object getObject() {
- return null;
- }
-
- /**
- * This method expects to be overridden by subclasses.
- * @return String property value
- */
- public String getString() {
- Object o = getObject();
- return (o == null) ? null : o.toString();
- }
-
- /**
- * Return a string representation of the property value. Only used
- * for debugging.
- */
- public String toString() {
- return getString();
- }
- }
|