001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.webcontainer.propertyrender;
031:
032: import java.util.Collections;
033: import java.util.HashMap;
034: import java.util.Map;
035:
036: import nextapp.echo2.app.Extent;
037: import nextapp.echo2.webrender.output.CssStyle;
038:
039: /**
040: * Utility class for rendering <code>nextapp.echo2.app.Extent</code>
041: * properties to CSS.
042: */
043: public class ExtentRender {
044:
045: private static final Map UNIT_NAMES_TO_VALUES;
046: static {
047: Map m = new HashMap();
048: m.put("cm", new Integer(Extent.CM));
049: m.put("em", new Integer(Extent.EM));
050: m.put("ex", new Integer(Extent.EX));
051: m.put("in", new Integer(Extent.IN));
052: m.put("mm", new Integer(Extent.MM));
053: m.put("pc", new Integer(Extent.PC));
054: m.put("%", new Integer(Extent.PERCENT));
055: m.put("pt", new Integer(Extent.PT));
056: m.put("px", new Integer(Extent.PX));
057: UNIT_NAMES_TO_VALUES = Collections.unmodifiableMap(m);
058: }
059:
060: /**
061: * Determines if the given <code>Extent</code> is of zero length.
062: * This method interprets null <code>Extent</code>s to be of zero
063: * length.
064: *
065: * @param extent the extent
066: * @return true if the extent is of zero length
067: */
068: public static boolean isZeroLength(Extent extent) {
069: return extent == null || extent.getValue() == 0;
070: }
071:
072: /**
073: * Attempts to render a given <code>Extent</code> to a pixel CSS attribute
074: * value. Returns null if the the extent can not be represented by a pixel
075: * value.
076: *
077: * @param extent the property value
078: * @return the CSS attribute value
079: */
080: public static final String renderCssAttributePixelValue(
081: Extent extent) {
082: return renderCssAttributePixelValue(extent, null);
083: }
084:
085: /**
086: * Attempts to render a given <code>Extent</code> to a pixel CSS attribute
087: * value. Returns the specified <code>invalidValue</code> if the specified
088: * <code>Extent</code> is not valid.
089: *
090: * @param extent the property value
091: * @return the CSS attribute value to return if the provided value is not a valid
092: * pixel value
093: * @return the CSS attribute value
094: */
095: public static final String renderCssAttributePixelValue(
096: Extent extent, String invalidValue) {
097: if (extent != null && extent.getUnits() == Extent.PX) {
098: return extent.getValue() + "px";
099: } else {
100: return invalidValue;
101: }
102: }
103:
104: /**
105: * Renders an <code>Extent</code> property value to a CSS dimensioned
106: * attribute value.
107: *
108: * @param extent the property value
109: * @return the CSS attribute value
110: */
111: public static final String renderCssAttributeValue(Extent extent) {
112: return extent.getValue() + renderUnits(extent.getUnits());
113: }
114:
115: /**
116: * Renders 1/2 the distance specified by an <code>Extent</code> property
117: * value to a CSS dimensioned attribute.
118: * For example, an extent that would normally render as "3px" would be
119: * rendered as "1.5px" by this method.
120: *
121: * @param extent the property value
122: * @return the CSS attribute value
123: */
124: public static final String renderCssAttributeValueHalf(Extent extent) {
125: if (extent.getValue() % 2 == 0) {
126: return (extent.getValue() / 2)
127: + renderUnits(extent.getUnits());
128: } else {
129: return (extent.getValue() / 2) + ".5"
130: + renderUnits(extent.getUnits());
131: }
132: }
133:
134: /**
135: * Renders an <code>Extent</code> property to the given CSS style.
136: * Null property values are ignored.
137: *
138: * @param cssStyle the target <code>CssStyle</code>
139: * @param cssAttribute the CSS attribute name, e.g., "width" or "height".
140: * @param extent the property value
141: */
142: public static final void renderToStyle(CssStyle cssStyle,
143: String cssAttribute, Extent extent) {
144: if (extent == null) {
145: return;
146: }
147: cssStyle.setAttribute(cssAttribute,
148: renderCssAttributeValue(extent));
149: }
150:
151: /**
152: * Renders the given <code>Extent</code> units constant into a CSS
153: * unit suffix.
154: *
155: * @param units the <code>Extent</code> units constant value
156: * @return the CSS unit suffix
157: */
158: public static final String renderUnits(int units) {
159: switch (units) {
160: case Extent.CM:
161: return "cm";
162: case Extent.EM:
163: return "em";
164: case Extent.EX:
165: return "ex";
166: case Extent.IN:
167: return "in";
168: case Extent.MM:
169: return "mm";
170: case Extent.PC:
171: return "pc";
172: case Extent.PERCENT:
173: return "%";
174: case Extent.PT:
175: return "pt";
176: case Extent.PX:
177: return "px";
178: default:
179: throw new IllegalArgumentException("Invalid extent.");
180: }
181: }
182:
183: private static int getUnitPosition(String s) {
184: int length = s.length();
185: for (int i = 0; i < length; ++i) {
186: char ch = s.charAt(i);
187: if (ch != '-' && (ch < '0' || ch > '9')) {
188: return i;
189: }
190: }
191: return -1;
192: }
193:
194: /**
195: * Creates an <code>Extent</code> from the given CSS dimensioned attribute
196: * value.
197: *
198: * @param extentString the CSS dimensioned attribute value
199: * @return an equivalent <code>Extent</code>, or null if the input
200: * is not valid.
201: */
202: public static final Extent toExtent(String extentString) {
203: try {
204: if (extentString == null) {
205: return null;
206: }
207: int unitPosition = getUnitPosition(extentString);
208: if (unitPosition == -1) {
209: return null;
210: }
211: String unitString = extentString.substring(unitPosition);
212: Integer unitInteger = (Integer) UNIT_NAMES_TO_VALUES
213: .get(unitString);
214: if (unitInteger == null) {
215: return null;
216: }
217: Extent extent = new Extent(Integer.parseInt(extentString
218: .substring(0, unitPosition)), unitInteger
219: .intValue());
220: return extent;
221: } catch (NumberFormatException ex) {
222: return null;
223: }
224: }
225:
226: /**
227: * Attempts to convert a given <code>Extent</code> to a pixel value.
228: * Returns <code>defaultPixels</code> if the conversion is not possible.
229: *
230: * @param extent the <code>Extent</code> to convert
231: * @param defaultPixels the pixel value to return if conversion is
232: * impossible.
233: * @return the value of the <code>extent</code> in pixels
234: */
235: public static final int toPixels(Extent extent, int defaultPixels) {
236: if (extent != null && extent.getUnits() == Extent.PX) {
237: return extent.getValue();
238: } else {
239: return defaultPixels;
240: }
241: }
242:
243: /** Non-instantiable class. */
244: private ExtentRender() {
245: }
246: }
|