diff options
author | Andreas L. Delmelle <adelmelle@apache.org> | 2007-07-07 20:13:41 +0000 |
---|---|---|
committer | Andreas L. Delmelle <adelmelle@apache.org> | 2007-07-07 20:13:41 +0000 |
commit | 50505cd29cf2acf34df427f9048a36337e8f1304 (patch) | |
tree | bd9494ca9caaada23d0954e718e2a76da62e8cd7 /src/java/org/apache/fop/fo/properties | |
parent | 7433301271f20e1b5483aee5f9134c69d894d011 (diff) | |
download | xmlgraphics-fop-50505cd29cf2acf34df427f9048a36337e8f1304.tar.gz xmlgraphics-fop-50505cd29cf2acf34df427f9048a36337e8f1304.zip |
Partial application of the patch in Bugzilla 41044:
* addition of a generic PropertyCache to be used by all Property
types that can be safely canonicalized
* modified EnumProperty, StringProperty, NumberProperty, EnumNumber
and FixedLength to make use of the cache infrastructure
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@554251 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/fo/properties')
9 files changed, 218 insertions, 53 deletions
diff --git a/src/java/org/apache/fop/fo/properties/EnumNumber.java b/src/java/org/apache/fop/fo/properties/EnumNumber.java index a5679cbcc..f8e940b01 100755 --- a/src/java/org/apache/fop/fo/properties/EnumNumber.java +++ b/src/java/org/apache/fop/fo/properties/EnumNumber.java @@ -19,30 +19,34 @@ package org.apache.fop.fo.properties; -import java.util.Map; -import java.util.WeakHashMap; - /** * A number quantity in XSL which is specified as an enum, such as "no-limit". */ public class EnumNumber extends NumberProperty { - private static final Map cache = new WeakHashMap(); + /** cache holding all canonical EnumNumber instances */ + private static final PropertyCache cache = new PropertyCache(); private final EnumProperty enumProperty; - private EnumNumber(EnumProperty enumProperty) { + /** + * Constructor + * @param enumProperty the base EnumProperty + */ + private EnumNumber(Property enumProperty) { super(null); - this.enumProperty = enumProperty; + this.enumProperty = (EnumProperty) enumProperty; } + /** + * Returns the canonical EnumNumber instance corresponding + * to the given Property + * @param enumProperty the base EnumProperty + * @return the canonical instance + */ public static EnumNumber getInstance(Property enumProperty) { - EnumNumber en = (EnumNumber)cache.get(enumProperty); - if (en == null) { - en = new EnumNumber((EnumProperty)enumProperty); - cache.put(enumProperty, en); - } - return en; + return (EnumNumber)cache.fetch( + new EnumNumber((EnumProperty) enumProperty)); } public int getEnum() { @@ -81,5 +85,22 @@ public class EnumNumber extends NumberProperty { return enumProperty.getObject(); } + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object obj) { + if (obj instanceof EnumNumber) { + return (((EnumNumber)obj).enumProperty == this.enumProperty); + } else { + return false; + } + } + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return enumProperty.hashCode(); + } + } diff --git a/src/java/org/apache/fop/fo/properties/EnumProperty.java b/src/java/org/apache/fop/fo/properties/EnumProperty.java index 533ebd64f..f9801e222 100644 --- a/src/java/org/apache/fop/fo/properties/EnumProperty.java +++ b/src/java/org/apache/fop/fo/properties/EnumProperty.java @@ -23,13 +23,13 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; -import java.util.Map; -import java.util.WeakHashMap; - /** * Superclass for properties that wrap an enumeration value */ public class EnumProperty extends Property { + + /** cache holding all canonical EnumProperty instances */ + private static final PropertyCache cache = new PropertyCache(); /** * Inner class for creating EnumProperty instances @@ -65,8 +65,6 @@ public class EnumProperty extends Property { } } - private static final Map propertyCache = new WeakHashMap(); - private final int value; private final String text; @@ -80,14 +78,8 @@ public class EnumProperty extends Property { } public static EnumProperty getInstance(int explicitValue, String text) { - EnumProperty ep = new EnumProperty(explicitValue, text); - EnumProperty cacheEntry = (EnumProperty)propertyCache.get(ep); - if (cacheEntry == null) { - propertyCache.put(ep, ep); - return ep; - } else { - return cacheEntry; - } + return (EnumProperty) cache.fetch( + new EnumProperty(explicitValue, text)); } /** @@ -119,6 +111,9 @@ public class EnumProperty extends Property { } } + /** + * @see java.lang.Object#hashCode() + */ public int hashCode() { return value + text.hashCode(); } diff --git a/src/java/org/apache/fop/fo/properties/FixedLength.java b/src/java/org/apache/fop/fo/properties/FixedLength.java index a043d803e..80016ba2e 100644 --- a/src/java/org/apache/fop/fo/properties/FixedLength.java +++ b/src/java/org/apache/fop/fo/properties/FixedLength.java @@ -25,26 +25,34 @@ import org.apache.fop.datatypes.PercentBaseContext; * An absolute length quantity in XSL */ public class FixedLength extends LengthProperty { + + /** cache holding all canonical FixedLength instances */ + private static final PropertyCache cache = new PropertyCache(); + private int millipoints; /** - * Set the length given - * @param numRelUnits the number of relative units - * @param iCurFontSize the current font size in base units. - */ - public FixedLength(double numRelUnits, int iCurFontSize) { - millipoints = (int) (numRelUnits * (double)iCurFontSize); - } - - /** * Set the length given a number of units and a unit name. * @param numUnits quantity of input units * @param units input unit specifier (in, cm, etc.) */ - public FixedLength(double numUnits, String units) { + private FixedLength(double numUnits, String units) { convert(numUnits, units); } - + + /** + * Return the canonical FixedLength instance corresponding + * to the computed value + * @param numUnits input units + * @param units unit specifier + * @return + */ + public static FixedLength getInstance(double numUnits, String units) { + return (FixedLength) cache.fetch( + new FixedLength(numUnits, units)); + + } + /** * @param baseUnits the length as a number of base units (millipoints) */ @@ -139,5 +147,22 @@ public class FixedLength extends LengthProperty { return millipoints + "mpt"; } + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object obj) { + if (obj instanceof EnumProperty) { + return (((FixedLength)obj).millipoints == this.millipoints); + } else { + return false; + } + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return millipoints; + } } diff --git a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java index 62263a02c..58cbc6402 100644 --- a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java +++ b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java @@ -86,7 +86,7 @@ public class FontFamilyProperty extends ListProperty { + tmpVal.substring(dblSpaceIndex + 1); dblSpaceIndex = tmpVal.indexOf(" "); } - prop.addProperty(new StringProperty(tmpVal)); + prop.addProperty(StringProperty.getInstance(tmpVal)); } } return prop; diff --git a/src/java/org/apache/fop/fo/properties/LengthProperty.java b/src/java/org/apache/fop/fo/properties/LengthProperty.java index 79f9cfba7..8b5565e68 100644 --- a/src/java/org/apache/fop/fo/properties/LengthProperty.java +++ b/src/java/org/apache/fop/fo/properties/LengthProperty.java @@ -59,7 +59,7 @@ public abstract class LengthProperty extends Property } if (p instanceof NumberProperty) { //Assume pixels (like in HTML) when there's no unit - return new FixedLength(p.getNumeric().getNumericValue(), "px"); + return FixedLength.getInstance(p.getNumeric().getNumericValue(), "px"); } Length val = p.getLength(); if (val != null) { diff --git a/src/java/org/apache/fop/fo/properties/NumberProperty.java b/src/java/org/apache/fop/fo/properties/NumberProperty.java index 21ffd32e7..55206cff7 100644 --- a/src/java/org/apache/fop/fo/properties/NumberProperty.java +++ b/src/java/org/apache/fop/fo/properties/NumberProperty.java @@ -69,13 +69,16 @@ public class NumberProperty extends Property implements Numeric { } - private Number number; + /** cache holding all canonical NumberProperty instances */ + private static final PropertyCache cache = new PropertyCache(); + + private final Number number; /** * Constructor for Number input * @param num Number object value for property */ - public NumberProperty(Number num) { + protected NumberProperty(Number num) { this.number = num; } @@ -83,7 +86,7 @@ public class NumberProperty extends Property implements Numeric { * Constructor for double input * @param num double numeric value for property */ - public NumberProperty(double num) { + protected NumberProperty(double num) { this.number = new Double(num); } @@ -91,11 +94,44 @@ public class NumberProperty extends Property implements Numeric { * Constructor for integer input * @param num integer numeric value for property */ - public NumberProperty(int num) { + protected NumberProperty(int num) { this.number = new Integer(num); } /** + * Returns the canonical NumberProperty instance + * corresponding to the given Number + * @param num the base Number + * @return the canonical NumberProperty + */ + public static NumberProperty getInstance(Number num) { + return (NumberProperty)cache.fetch( + new NumberProperty(num)); + } + + /** + * Returns the canonical NumberProperty instance + * corresponding to the given double + * @param num the base double value + * @return the canonical NumberProperty + */ + public static NumberProperty getInstance(double num) { + return (NumberProperty)cache.fetch( + new NumberProperty(num)); + } + + /** + * Returns the canonical NumberProperty instance + * corresponding to the given int + * @param num the base int value + * @return the canonical NumberProperty + */ + public static NumberProperty getInstance(int num) { + return (NumberProperty)cache.fetch( + new NumberProperty(num)); + } + + /** * Plain number always has a dimension of 0. * @return a dimension of 0. * @see Numeric#getDimension() @@ -172,7 +208,7 @@ public class NumberProperty extends Property implements Numeric { /** @see org.apache.fop.fo.properties.Property#getLength() */ public Length getLength() { //Assume pixels (like in HTML) when there's no unit - return new FixedLength(getNumericValue(), "px"); + return FixedLength.getInstance(getNumericValue(), "px"); } /** diff --git a/src/java/org/apache/fop/fo/properties/PropertyCache.java b/src/java/org/apache/fop/fo/properties/PropertyCache.java new file mode 100644 index 000000000..176cdd4aa --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/PropertyCache.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * Thin wrapper around a HashMap to implement the property caching idiom + * in which a new Property instance is created then tested against cached + * instances created previously. If an existing property is found, this is + * retained and the newly created one is instantly eligible for garbage + * collection. + */ +public class PropertyCache { + + private Map propCache = Collections.synchronizedMap(new WeakHashMap()); + + + /** + * Checks if the given property is present in the cache - if so, returns + * a reference to the cached value. Otherwise the given object is added + * to the cache and returned. + * @param obj + * @return the cached instance + */ + public Property fetch(Property prop) { + + Property cacheEntry = (Property) propCache.get(prop); + if (cacheEntry != null) { + return cacheEntry; + } else { + propCache.put(prop, prop); + return prop; + } + } +} diff --git a/src/java/org/apache/fop/fo/properties/StringProperty.java b/src/java/org/apache/fop/fo/properties/StringProperty.java index 1b1699c5a..691942d78 100644 --- a/src/java/org/apache/fop/fo/properties/StringProperty.java +++ b/src/java/org/apache/fop/fo/properties/StringProperty.java @@ -77,17 +77,31 @@ public class StringProperty extends Property { } // end String.Maker - private String str; + /** cache containing all canonical StringProperty instances */ + private static final PropertyCache cache = new PropertyCache(); + + private final String str; /** + * Constructor * @param str String value to place in this object */ - public StringProperty(String str) { + private StringProperty(String str) { this.str = str; - // log.debug("Set StringProperty: " + str); } /** + * Return the canonical StringProperty instance + * corresponding to the given string value + * @param str the base String + * @return the canonical instance + */ + public static StringProperty getInstance(String str) { + return (StringProperty)cache.fetch( + new StringProperty(str)); + } + + /** * @return the Object equivalent of this property */ public Object getObject() { @@ -101,4 +115,23 @@ public class StringProperty extends Property { return this.str; } + /** + * @see java.lang.Object#hashCode() + */ + public boolean equals(Object obj) { + if (obj instanceof StringProperty) { + StringProperty sp = (StringProperty)obj; + return (sp.str == this.str + || sp.str.equals(this.str)); + } else { + return false; + } + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return str.hashCode(); + } } diff --git a/src/java/org/apache/fop/fo/properties/TableBorderPrecedence.java b/src/java/org/apache/fop/fo/properties/TableBorderPrecedence.java index 9c094840e..dff9626a1 100644 --- a/src/java/org/apache/fop/fo/properties/TableBorderPrecedence.java +++ b/src/java/org/apache/fop/fo/properties/TableBorderPrecedence.java @@ -25,13 +25,13 @@ import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; public class TableBorderPrecedence extends NumberProperty.Maker{ - private static Property num0 = new NumberProperty(0); - private static Property num1 = new NumberProperty(1); - private static Property num2 = new NumberProperty(2); - private static Property num3 = new NumberProperty(3); - private static Property num4 = new NumberProperty(4); - private static Property num5 = new NumberProperty(5); - private static Property num6 = new NumberProperty(6); + private static Property num0 = NumberProperty.getInstance(0); + private static Property num1 = NumberProperty.getInstance(1); + private static Property num2 = NumberProperty.getInstance(2); + private static Property num3 = NumberProperty.getInstance(3); + private static Property num4 = NumberProperty.getInstance(4); + private static Property num5 = NumberProperty.getInstance(5); + private static Property num6 = NumberProperty.getInstance(6); public TableBorderPrecedence(int propId) { super(propId); |