[seam-commits] Seam SVN: r11235 - in branches/community/Seam_2_2/src/excel/org/jboss/seam/excel: exporter and 1 other directories.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Thu Jul 2 03:42:33 EDT 2009
Author: nickarls
Date: 2009-07-02 03:42:33 -0400 (Thu, 02 Jul 2009)
New Revision: 11235
Added:
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/CSSParser.java
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/StyleStringParser.java
Removed:
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/Parser.java
Modified:
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/exporter/ExcelExporter.java
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/jxl/JXLHelper.java
Log:
CSS parse refactoring, support of '' for escaping ; etc
Copied: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/CSSParser.java (from rev 11217, branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/Parser.java)
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/CSSParser.java (rev 0)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/CSSParser.java 2009-07-02 07:42:33 UTC (rev 11235)
@@ -0,0 +1,368 @@
+package org.jboss.seam.excel.css;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.excel.ExcelWorkbookException;
+import org.jboss.seam.excel.ui.UILink;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * CSS parser for the XLS-CSS
+ *
+ * @author Nicklas Karlsson (nickarls at gmail.com)
+ */
+public class CSSParser
+{
+ // Where to look for the style
+ private static final String STYLE_ATTRIBUTE = "style";
+
+ // Where to look for the style class
+ private static final String STYLE_CLASS_ATTRIBUTE = "styleClass";
+
+ // What separates multiple style class references
+ private static final String STYLE_SHORTHAND_SEPARATOR = " ";
+
+ // What starts a rule block in a CSS file
+ private static final String LEFT_BRACE = "{";
+
+ // What ends a rule block in a CSS file
+ private static final String RIGHT_BRACE = "}";
+
+ // The style classes that have been read in from e:link referenced, mapped on
+ // style class name
+ private Map<String, StyleMap> definedStyleClasses = new HashMap<String, StyleMap>();
+
+ // The registered property builders, mapped on attribute name
+ private Map<String, PropertyBuilder> propertyBuilders = new HashMap<String, PropertyBuilder>();
+
+ // A cache of previously parsed css, mapped on component
+ private Map<UIComponent, StyleMap> cellStyleCache = new HashMap<UIComponent, StyleMap>();
+
+ private Log log = Logging.getLog(CSSParser.class);
+
+ /**
+ * Constructor, initializes the property builders
+ */
+ public CSSParser()
+ {
+ initPropertyBuilders();
+ }
+
+ /**
+ * Constructor with stylesheets
+ *
+ * @param stylesheets The list of referenced stylesheets in UILink elements
+ * @throws MalformedURLException If the URL was bad
+ * @throws IOException If the URL could not be read
+ */
+ public CSSParser(List<UILink> stylesheets) throws MalformedURLException, IOException
+ {
+ initPropertyBuilders();
+ loadStylesheets(stylesheets);
+ }
+
+ /**
+ * Loads stylesheets (merging by class name)
+ *
+ * @param stylesheets The stylesheets to read/merge
+ * @throws MalformedURLException If the URL was bad
+ * @throws IOException If the URL could not be read
+ */
+ private void loadStylesheets(List<UILink> stylesheets) throws MalformedURLException, IOException
+ {
+ for (UILink stylesheet : stylesheets)
+ {
+ definedStyleClasses.putAll(parseStylesheet(stylesheet.getURL()));
+ }
+ }
+
+ /**
+ * Registers the property builders
+ */
+ private void initPropertyBuilders()
+ {
+ propertyBuilders.put(CSSNames.FONT_FAMILY, new PropertyBuilders.FontFamily());
+ propertyBuilders.put(CSSNames.FONT_SIZE, new PropertyBuilders.FontSize());
+ propertyBuilders.put(CSSNames.FONT_COLOR, new PropertyBuilders.FontColor());
+ propertyBuilders.put(CSSNames.FONT_ITALIC, new PropertyBuilders.FontItalic());
+ propertyBuilders.put(CSSNames.FONT_SCRIPT_STYLE, new PropertyBuilders.FontScriptStyle());
+ propertyBuilders.put(CSSNames.FONT_STRUCK_OUT, new PropertyBuilders.FontStruckOut());
+ propertyBuilders.put(CSSNames.FONT_UNDERLINE_STYLE, new PropertyBuilders.FontUnderlineStyle());
+ propertyBuilders.put(CSSNames.FONT_BOLD, new PropertyBuilders.FontBold());
+ propertyBuilders.put(CSSNames.FONT, new PropertyBuilders.FontShorthand());
+ propertyBuilders.put(CSSNames.BACKGROUND_PATTERN, new PropertyBuilders.BackgroundPattern());
+ propertyBuilders.put(CSSNames.BACKGROUND_COLOR, new PropertyBuilders.BackgroundColor());
+ propertyBuilders.put(CSSNames.BACKGROUND, new PropertyBuilders.BackgroundShorthand());
+ propertyBuilders.put(CSSNames.BORDER_LEFT_COLOR, new PropertyBuilders.BorderLeftColor());
+ propertyBuilders.put(CSSNames.BORDER_LEFT_LINE_STYLE, new PropertyBuilders.BorderLeftLineStyle());
+ propertyBuilders.put(CSSNames.BORDER_LEFT, new PropertyBuilders.BorderLeftShorthand());
+ propertyBuilders.put(CSSNames.BORDER_TOP_COLOR, new PropertyBuilders.BorderTopColor());
+ propertyBuilders.put(CSSNames.BORDER_TOP_LINE_STYLE, new PropertyBuilders.BorderTopLineStyle());
+ propertyBuilders.put(CSSNames.BORDER_TOP, new PropertyBuilders.BorderTopShorthand());
+ propertyBuilders.put(CSSNames.BORDER_RIGHT_COLOR, new PropertyBuilders.BorderRightColor());
+ propertyBuilders.put(CSSNames.BORDER_RIGHT_LINE_STYLE, new PropertyBuilders.BorderRightLineStyle());
+ propertyBuilders.put(CSSNames.BORDER_RIGHT, new PropertyBuilders.BorderRightShorthand());
+ propertyBuilders.put(CSSNames.BORDER_BOTTOM_COLOR, new PropertyBuilders.BorderBottomColor());
+ propertyBuilders.put(CSSNames.BORDER_BOTTOM_LINE_STYLE, new PropertyBuilders.BorderBottomLineStyle());
+ propertyBuilders.put(CSSNames.BORDER_BOTTOM, new PropertyBuilders.BorderBottomShorthand());
+ propertyBuilders.put(CSSNames.BORDER, new PropertyBuilders.BorderShorthand());
+ propertyBuilders.put(CSSNames.FORMAT_MASK, new PropertyBuilders.FormatMask());
+ propertyBuilders.put(CSSNames.ALIGNMENT, new PropertyBuilders.Alignment());
+ propertyBuilders.put(CSSNames.INDENTATION, new PropertyBuilders.Indentation());
+ propertyBuilders.put(CSSNames.ORIENTATION, new PropertyBuilders.Orientation());
+ propertyBuilders.put(CSSNames.LOCKED, new PropertyBuilders.Locked());
+ propertyBuilders.put(CSSNames.SHRINK_TO_FIT, new PropertyBuilders.ShrinkToFit());
+ propertyBuilders.put(CSSNames.WRAP, new PropertyBuilders.Wrap());
+ propertyBuilders.put(CSSNames.VERICAL_ALIGNMENT, new PropertyBuilders.VericalAlignment());
+ propertyBuilders.put(CSSNames.COLUMN_WIDTH, new PropertyBuilders.ColumnWidth());
+ propertyBuilders.put(CSSNames.COLUMN_AUTO_SIZE, new PropertyBuilders.ColumnAutoSize());
+ propertyBuilders.put(CSSNames.COLUMN_HIDDEN, new PropertyBuilders.ColumnHidden());
+ propertyBuilders.put(CSSNames.COLUMN_EXPORT, new PropertyBuilders.ColumnExport());
+ propertyBuilders.put(CSSNames.COLUMN_WIDTHS, new PropertyBuilders.ColumnWidths());
+ propertyBuilders.put(CSSNames.FORCE_TYPE, new PropertyBuilders.ForceType());
+ }
+
+ /**
+ * Reads data from an URL to a String
+ *
+ * @param url The URL to read
+ * @return The read data as a String
+ * @throws IOException If the stream could not be read
+ */
+ private static String readCSS(InputStream in) throws IOException
+ {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuffer buffer = new StringBuffer();
+ String line;
+ while ((line = reader.readLine()) != null)
+ {
+ buffer.append(line);
+ }
+ reader.close();
+ return buffer.toString();
+ }
+
+ /**
+ * Parses a style sheet. Really crude. Assumes data is nicely formatted on
+ * one line per entry
+ *
+ * @param urlString The URL to read
+ * @return A map of style class names mapped to StyleMaps
+ * @throws MalformedURLException
+ * @throws IOException
+ */
+ private Map<String, StyleMap> parseStylesheet(String urlString) throws MalformedURLException, IOException
+ {
+ Map<String, StyleMap> styleClasses = new HashMap<String, StyleMap>();
+ InputStream cssStream = null;
+ if (urlString.indexOf("://") < 0) {
+ cssStream = getClass().getResourceAsStream(urlString);
+ } else {
+ cssStream = new URL(urlString).openStream();
+ }
+ String css = readCSS(cssStream).toLowerCase();
+ int firstBrace = -1;
+ int secondBrace = -1;
+ while (!"".equals(css))
+ {
+ firstBrace = css.indexOf(LEFT_BRACE);
+ if (firstBrace >= 0)
+ {
+ secondBrace = css.indexOf(RIGHT_BRACE, firstBrace + 1);
+ }
+ if (firstBrace >= 0 && secondBrace >= 0 && firstBrace != secondBrace)
+ {
+ String styleName = css.substring(0, firstBrace).trim();
+ if (styleName.startsWith(".")) {
+ styleName = styleName.substring(1);
+ }
+ String styleString = css.substring(firstBrace + 1, secondBrace).trim();
+ StyleMap styleMap = StyleStringParser.of(styleString, propertyBuilders).parse();
+ styleClasses.put(styleName, styleMap);
+ css = css.substring(secondBrace + 1);
+ }
+ else
+ {
+ css = "";
+ }
+ }
+ return styleClasses;
+ }
+
+ /**
+ * Gets style from a component
+ *
+ * @param component The component to examine
+ * @return null if not found, otherwise style string
+ */
+ public static String getStyle(UIComponent component)
+ {
+ return getStyleProperty(component, STYLE_ATTRIBUTE);
+ }
+
+ /**
+ * Gets style class from a component
+ *
+ * @param component The component to examine
+ * @return null if not found, otherwise style class(es) string
+ */
+ public static String getStyleClass(UIComponent component)
+ {
+ return getStyleProperty(component, STYLE_CLASS_ATTRIBUTE);
+ }
+
+ /**
+ * Reads a property from a component
+ *
+ * @param component The component to examine
+ * @param field The field to read
+ * @return The value from the field
+ */
+ private static String getStyleProperty(UIComponent component, String field)
+ {
+ try
+ {
+ return (String) PropertyUtils.getProperty(component, field);
+ }
+ catch (NoSuchMethodException e)
+ {
+ // No panic, no property
+ return null;
+ }
+ catch (Exception e)
+ {
+ String message = Interpolator.instance().interpolate("Could not read field #0 of bean #1", field, component.getId());
+ throw new ExcelWorkbookException(message, e);
+ }
+ }
+
+ /**
+ * Cascades on parents, collecting them into list
+ *
+ * @param component The component to examine
+ * @param styleMaps The list of collected style maps
+ * @return The list of style maps
+ */
+ private List<StyleMap> cascadeStyleMap(UIComponent component, List<StyleMap> styleMaps)
+ {
+ styleMaps.add(getStyleMap(component));
+ if (component.getParent() != null)
+ {
+ cascadeStyleMap(component.getParent(), styleMaps);
+ }
+ return styleMaps;
+ }
+
+ /**
+ * Gets the cascaded style map for a component. Recurses on parents,
+ * collecting style maps. The reverses the list and merges the styles
+ *
+ * @param component The component to examine
+ * @return The merged style map
+ */
+ public StyleMap getCascadedStyleMap(UIComponent component)
+ {
+ List<StyleMap> styleMaps = cascadeStyleMap(component, new ArrayList<StyleMap>());
+ Collections.reverse(styleMaps);
+ StyleMap cascadedStyleMap = new StyleMap();
+ for (StyleMap styleMap : styleMaps)
+ {
+ cascadedStyleMap.putAll(styleMap);
+ }
+ return cascadedStyleMap;
+ }
+
+ /**
+ * Gets a style map for a component (from cache if available)
+ *
+ * @param component The component to examine
+ * @return The style map of the component
+ */
+ private StyleMap getStyleMap(UIComponent component)
+ {
+ if (cellStyleCache.containsKey(component))
+ {
+ return cellStyleCache.get(component);
+ }
+
+ StyleMap styleMap = new StyleMap();
+
+ String componentStyleClass = getStyleProperty(component, STYLE_CLASS_ATTRIBUTE);
+ if (componentStyleClass != null)
+ {
+ String[] styleClasses = StyleStringParser.trimArray(componentStyleClass.split(STYLE_SHORTHAND_SEPARATOR));
+ for (String styleClass : styleClasses)
+ {
+ if (!definedStyleClasses.containsKey(styleClass))
+ {
+ log.warn("Uknown style class #0", styleClass);
+ continue;
+ }
+ styleMap.putAll(definedStyleClasses.get(styleClass));
+ }
+ }
+
+ String componentStyle = getStyleProperty(component, STYLE_ATTRIBUTE);
+ if (componentStyle != null)
+ {
+ styleMap.putAll(StyleStringParser.of(componentStyle, propertyBuilders).parse());
+ }
+
+ cellStyleCache.put(component, styleMap);
+ return styleMap;
+ }
+
+// private StyleMap parseStyleString(String styleString)
+// {
+// StyleMap styleMap = new StyleMap();
+//
+// String[] styles = trimArray(styleString.split(STYLES_SEPARATOR));
+// for (String style : styles)
+// {
+// int breakpoint = style.indexOf(STYLE_NAME_VALUE_SEPARATOR);
+// if (breakpoint < 0) {
+// log.warn("Style component #0 should be of form <key>#1<value>", style, STYLE_NAME_VALUE_SEPARATOR);
+// continue;
+// }
+// String styleName = style.substring(0, breakpoint).toLowerCase().trim();
+// if (!propertyBuilders.containsKey(styleName))
+// {
+// log.warn("No property builder (unknown style) for property #0", styleName);
+// continue;
+// }
+// PropertyBuilder propertyBuilder = propertyBuilders.get(styleName);
+// String styleValue = style.substring(breakpoint + 1);
+// String[] styleValues = trimArray(styleValue.trim().split(STYLE_SHORTHAND_SEPARATOR));
+// styleMap.putAll(propertyBuilder.parseProperty(styleName, styleValues));
+// }
+//
+// return styleMap;
+// }
+
+ /**
+ * Setter for stylesheets. Loads them also.
+ *
+ * @param stylesheets The stylesheets to load
+ * @throws MalformedURLException If the URL is bad
+ * @throws IOException If the URL cannot be read
+ */
+ public void setStylesheets(List<UILink> stylesheets) throws MalformedURLException, IOException
+ {
+ loadStylesheets(stylesheets);
+ }
+}
Deleted: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/Parser.java
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/Parser.java 2009-07-01 22:32:40 UTC (rev 11234)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/Parser.java 2009-07-02 07:42:33 UTC (rev 11235)
@@ -1,399 +0,0 @@
-package org.jboss.seam.excel.css;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.faces.component.UIComponent;
-
-import org.apache.commons.beanutils.PropertyUtils;
-import org.jboss.seam.core.Interpolator;
-import org.jboss.seam.excel.ExcelWorkbookException;
-import org.jboss.seam.excel.ui.UILink;
-import org.jboss.seam.log.Log;
-import org.jboss.seam.log.Logging;
-
-/**
- * CSS parser for the XLS-CSS
- *
- * @author Nicklas Karlsson (nickarls at gmail.com)
- */
-public class Parser
-{
- // Where to look for the style
- private static final String STYLE_ATTRIBUTE = "style";
-
- // Where to look for the style class
- private static final String STYLE_CLASS_ATTRIBUTE = "styleClass";
-
- // What separates multiple XLS-CSS attributes in a style string
- private static final String STYLES_SEPARATOR = ";";
-
- // What separates the key and value in a XLS-CSS style
- private static final String STYLE_NAME_VALUE_SEPARATOR = ":";
-
- // What separates multiple style class references
- private static final String STYLE_SHORTHAND_SEPARATOR = " ";
-
- // What starts a rule block in a CSS file
- private static final String LEFT_BRACE = "{";
-
- // What ends a rule block in a CSS file
- private static final String RIGHT_BRACE = "}";
-
- // The style classes that have been read in from e:link referenced, mapped on
- // style class name
- private Map<String, StyleMap> definedStyleClasses = new HashMap<String, StyleMap>();
-
- // The registered property builders, mapped on attribute name
- private Map<String, PropertyBuilder> propertyBuilders = new HashMap<String, PropertyBuilder>();
-
- // A cache of previously parsed css, mapped on component
- private Map<UIComponent, StyleMap> cellStyleCache = new HashMap<UIComponent, StyleMap>();
-
- private Log log = Logging.getLog(Parser.class);
-
- /**
- * Constructor, initializes the property builders
- */
- public Parser()
- {
- initPropertyBuilders();
- }
-
- /**
- * Constructor with stylesheets
- *
- * @param stylesheets The list of referenced stylesheets in UILink elements
- * @throws MalformedURLException If the URL was bad
- * @throws IOException If the URL could not be read
- */
- public Parser(List<UILink> stylesheets) throws MalformedURLException, IOException
- {
- initPropertyBuilders();
- loadStylesheets(stylesheets);
- }
-
- /**
- * Loads stylesheets (merging by class name)
- *
- * @param stylesheets The stylesheets to read/merge
- * @throws MalformedURLException If the URL was bad
- * @throws IOException If the URL could not be read
- */
- private void loadStylesheets(List<UILink> stylesheets) throws MalformedURLException, IOException
- {
- for (UILink stylesheet : stylesheets)
- {
- definedStyleClasses.putAll(parseStylesheet(stylesheet.getURL()));
- }
- }
-
- /**
- * Registers the property builders
- */
- private void initPropertyBuilders()
- {
- propertyBuilders.put(CSSNames.FONT_FAMILY, new PropertyBuilders.FontFamily());
- propertyBuilders.put(CSSNames.FONT_SIZE, new PropertyBuilders.FontSize());
- propertyBuilders.put(CSSNames.FONT_COLOR, new PropertyBuilders.FontColor());
- propertyBuilders.put(CSSNames.FONT_ITALIC, new PropertyBuilders.FontItalic());
- propertyBuilders.put(CSSNames.FONT_SCRIPT_STYLE, new PropertyBuilders.FontScriptStyle());
- propertyBuilders.put(CSSNames.FONT_STRUCK_OUT, new PropertyBuilders.FontStruckOut());
- propertyBuilders.put(CSSNames.FONT_UNDERLINE_STYLE, new PropertyBuilders.FontUnderlineStyle());
- propertyBuilders.put(CSSNames.FONT_BOLD, new PropertyBuilders.FontBold());
- propertyBuilders.put(CSSNames.FONT, new PropertyBuilders.FontShorthand());
- propertyBuilders.put(CSSNames.BACKGROUND_PATTERN, new PropertyBuilders.BackgroundPattern());
- propertyBuilders.put(CSSNames.BACKGROUND_COLOR, new PropertyBuilders.BackgroundColor());
- propertyBuilders.put(CSSNames.BACKGROUND, new PropertyBuilders.BackgroundShorthand());
- propertyBuilders.put(CSSNames.BORDER_LEFT_COLOR, new PropertyBuilders.BorderLeftColor());
- propertyBuilders.put(CSSNames.BORDER_LEFT_LINE_STYLE, new PropertyBuilders.BorderLeftLineStyle());
- propertyBuilders.put(CSSNames.BORDER_LEFT, new PropertyBuilders.BorderLeftShorthand());
- propertyBuilders.put(CSSNames.BORDER_TOP_COLOR, new PropertyBuilders.BorderTopColor());
- propertyBuilders.put(CSSNames.BORDER_TOP_LINE_STYLE, new PropertyBuilders.BorderTopLineStyle());
- propertyBuilders.put(CSSNames.BORDER_TOP, new PropertyBuilders.BorderTopShorthand());
- propertyBuilders.put(CSSNames.BORDER_RIGHT_COLOR, new PropertyBuilders.BorderRightColor());
- propertyBuilders.put(CSSNames.BORDER_RIGHT_LINE_STYLE, new PropertyBuilders.BorderRightLineStyle());
- propertyBuilders.put(CSSNames.BORDER_RIGHT, new PropertyBuilders.BorderRightShorthand());
- propertyBuilders.put(CSSNames.BORDER_BOTTOM_COLOR, new PropertyBuilders.BorderBottomColor());
- propertyBuilders.put(CSSNames.BORDER_BOTTOM_LINE_STYLE, new PropertyBuilders.BorderBottomLineStyle());
- propertyBuilders.put(CSSNames.BORDER_BOTTOM, new PropertyBuilders.BorderBottomShorthand());
- propertyBuilders.put(CSSNames.BORDER, new PropertyBuilders.BorderShorthand());
- propertyBuilders.put(CSSNames.FORMAT_MASK, new PropertyBuilders.FormatMask());
- propertyBuilders.put(CSSNames.ALIGNMENT, new PropertyBuilders.Alignment());
- propertyBuilders.put(CSSNames.INDENTATION, new PropertyBuilders.Indentation());
- propertyBuilders.put(CSSNames.ORIENTATION, new PropertyBuilders.Orientation());
- propertyBuilders.put(CSSNames.LOCKED, new PropertyBuilders.Locked());
- propertyBuilders.put(CSSNames.SHRINK_TO_FIT, new PropertyBuilders.ShrinkToFit());
- propertyBuilders.put(CSSNames.WRAP, new PropertyBuilders.Wrap());
- propertyBuilders.put(CSSNames.VERICAL_ALIGNMENT, new PropertyBuilders.VericalAlignment());
- propertyBuilders.put(CSSNames.COLUMN_WIDTH, new PropertyBuilders.ColumnWidth());
- propertyBuilders.put(CSSNames.COLUMN_AUTO_SIZE, new PropertyBuilders.ColumnAutoSize());
- propertyBuilders.put(CSSNames.COLUMN_HIDDEN, new PropertyBuilders.ColumnHidden());
- propertyBuilders.put(CSSNames.COLUMN_EXPORT, new PropertyBuilders.ColumnExport());
- propertyBuilders.put(CSSNames.COLUMN_WIDTHS, new PropertyBuilders.ColumnWidths());
- propertyBuilders.put(CSSNames.FORCE_TYPE, new PropertyBuilders.ForceType());
- }
-
- /**
- * Reads data from an URL to a String
- *
- * @param url The URL to read
- * @return The read data as a String
- * @throws IOException If the stream could not be read
- */
- private static String readCSS(InputStream in) throws IOException
- {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- StringBuffer buffer = new StringBuffer();
- String line;
- while ((line = reader.readLine()) != null)
- {
- buffer.append(line);
- }
- reader.close();
- return buffer.toString();
- }
-
- /**
- * Parses a style sheet. Really crude. Assumes data is nicely formatted on
- * one line per entry
- *
- * @param urlString The URL to read
- * @return A map of style class names mapped to StyleMaps
- * @throws MalformedURLException
- * @throws IOException
- */
- private Map<String, StyleMap> parseStylesheet(String urlString) throws MalformedURLException, IOException
- {
- Map<String, StyleMap> styleClasses = new HashMap<String, StyleMap>();
- InputStream cssStream = null;
- if (urlString.indexOf("://") < 0) {
- cssStream = getClass().getResourceAsStream(urlString);
- } else {
- cssStream = new URL(urlString).openStream();
- }
- String css = readCSS(cssStream).toLowerCase();
- int firstBrace = -1;
- int secondBrace = -1;
- while (!"".equals(css))
- {
- firstBrace = css.indexOf(LEFT_BRACE);
- if (firstBrace >= 0)
- {
- secondBrace = css.indexOf(RIGHT_BRACE, firstBrace + 1);
- }
- if (firstBrace >= 0 && secondBrace >= 0 && firstBrace != secondBrace)
- {
- String styleName = css.substring(0, firstBrace).trim();
- if (styleName.startsWith(".")) {
- styleName = styleName.substring(1);
- }
- String styleString = css.substring(firstBrace + 1, secondBrace).trim();
- StyleMap styleMap = parseStyleString(styleString);
- styleClasses.put(styleName, styleMap);
- css = css.substring(secondBrace + 1);
- }
- else
- {
- css = "";
- }
- }
- return styleClasses;
- }
-
- /**
- * Gets style from a component
- *
- * @param component The component to examine
- * @return null if not found, otherwise style string
- */
- public static String getStyle(UIComponent component)
- {
- return getStyleProperty(component, STYLE_ATTRIBUTE);
- }
-
- /**
- * Gets style class from a component
- *
- * @param component The component to examine
- * @return null if not found, otherwise style class(es) string
- */
- public static String getStyleClass(UIComponent component)
- {
- return getStyleProperty(component, STYLE_CLASS_ATTRIBUTE);
- }
-
- /**
- * Reads a property from a component
- *
- * @param component The component to examine
- * @param field The field to read
- * @return The value from the field
- */
- private static String getStyleProperty(UIComponent component, String field)
- {
- try
- {
- return (String) PropertyUtils.getProperty(component, field);
- }
- catch (NoSuchMethodException e)
- {
- // No panic, no property
- return null;
- }
- catch (Exception e)
- {
- String message = Interpolator.instance().interpolate("Could not read field #0 of bean #1", field, component.getId());
- throw new ExcelWorkbookException(message, e);
- }
- }
-
- /**
- * Cascades on parents, collecting them into list
- *
- * @param component The component to examine
- * @param styleMaps The list of collected style maps
- * @return The list of style maps
- */
- private List<StyleMap> cascadeStyleMap(UIComponent component, List<StyleMap> styleMaps)
- {
- styleMaps.add(getStyleMap(component));
- if (component.getParent() != null)
- {
- cascadeStyleMap(component.getParent(), styleMaps);
- }
- return styleMaps;
- }
-
- /**
- * Gets the cascaded style map for a component. Recurses on parents,
- * collecting style maps. The reverses the list and merges the styles
- *
- * @param component The component to examine
- * @return The merged style map
- */
- public StyleMap getCascadedStyleMap(UIComponent component)
- {
- List<StyleMap> styleMaps = cascadeStyleMap(component, new ArrayList<StyleMap>());
- Collections.reverse(styleMaps);
- StyleMap cascadedStyleMap = new StyleMap();
- for (StyleMap styleMap : styleMaps)
- {
- cascadedStyleMap.putAll(styleMap);
- }
- return cascadedStyleMap;
- }
-
- /**
- * Gets a style map for a component (from cache if available)
- *
- * @param component The component to examine
- * @return The style map of the component
- */
- private StyleMap getStyleMap(UIComponent component)
- {
- if (cellStyleCache.containsKey(component))
- {
- return cellStyleCache.get(component);
- }
-
- StyleMap styleMap = new StyleMap();
-
- String componentStyleClass = getStyleProperty(component, STYLE_CLASS_ATTRIBUTE);
- if (componentStyleClass != null)
- {
- String[] styleClasses = trimArray(componentStyleClass.split(STYLE_SHORTHAND_SEPARATOR));
- for (String styleClass : styleClasses)
- {
- if (!definedStyleClasses.containsKey(styleClass))
- {
- log.warn("Uknown style class #0", styleClass);
- continue;
- }
- styleMap.putAll(definedStyleClasses.get(styleClass));
- }
- }
-
- String componentStyle = getStyleProperty(component, STYLE_ATTRIBUTE);
- if (componentStyle != null)
- {
- styleMap.putAll(parseStyleString(componentStyle));
- }
-
- cellStyleCache.put(component, styleMap);
- return styleMap;
- }
-
- /**
- * Parses a stringle style string
- *
- * @param styleString The string to parse
- * @return The parsed StyleMap
- */
- private StyleMap parseStyleString(String styleString)
- {
- StyleMap styleMap = new StyleMap();
-
- String[] styles = trimArray(styleString.split(STYLES_SEPARATOR));
- for (String style : styles)
- {
- int breakpoint = style.indexOf(STYLE_NAME_VALUE_SEPARATOR);
- if (breakpoint < 0) {
- log.warn("Style component #0 should be of form <key>#1<value>", style, STYLE_NAME_VALUE_SEPARATOR);
- continue;
- }
- String styleName = style.substring(0, breakpoint).toLowerCase().trim();
- if (!propertyBuilders.containsKey(styleName))
- {
- log.warn("No property builder (unknown style) for property #0", styleName);
- continue;
- }
- PropertyBuilder propertyBuilder = propertyBuilders.get(styleName);
- String styleValue = style.substring(breakpoint + 1);
- String[] styleValues = trimArray(styleValue.trim().split(STYLE_SHORTHAND_SEPARATOR));
- styleMap.putAll(propertyBuilder.parseProperty(styleName, styleValues));
- }
-
- return styleMap;
- }
-
- /**
- * Utility for trimming (lowercase & trim) an array of string values
- *
- * @param array The array to trim
- * @return The trimmed array
- */
- private String[] trimArray(String[] array)
- {
- List<String> validValues = new ArrayList<String>();
- for (int i = 0; i < array.length; i++)
- {
- if (!"".equals(array[i]) && !" ".equals(array[i]))
- {
- validValues.add(array[i].toLowerCase().trim());
- }
- }
- return validValues.toArray(new String[validValues.size()]);
- }
-
- /**
- * Setter for stylesheets. Loads them also.
- *
- * @param stylesheets The stylesheets to load
- * @throws MalformedURLException If the URL is bad
- * @throws IOException If the URL cannot be read
- */
- public void setStylesheets(List<UILink> stylesheets) throws MalformedURLException, IOException
- {
- loadStylesheets(stylesheets);
- }
-}
Added: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/StyleStringParser.java
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/StyleStringParser.java (rev 0)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/css/StyleStringParser.java 2009-07-02 07:42:33 UTC (rev 11235)
@@ -0,0 +1,103 @@
+package org.jboss.seam.excel.css;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+public class StyleStringParser
+{
+ private static final char STYLE_SEPARATOR = ';';
+ private static final String KEY_VALUE_SEPARATOR = ":";
+ private static final String STYLE_SHORTHAND_SEPARATOR = " ";
+ private static final char ESCAPE_CHAR = '\'';
+
+ private Log log = Logging.getLog(StyleStringParser.class);
+
+ private String styleString;
+ private Map<String, PropertyBuilder> propertyBuilderMap;
+ private StyleMap styleMap = new StyleMap();
+ private boolean escaping = false;
+
+ public static StyleStringParser of(String styleString, Map<String, PropertyBuilder> propertyBuilderMap)
+ {
+ return new StyleStringParser(styleString, propertyBuilderMap);
+ }
+
+ protected StyleStringParser(String styleString, Map<String, PropertyBuilder> propertyBuilderMap)
+ {
+ this.styleString = styleString;
+ this.propertyBuilderMap = propertyBuilderMap;
+ }
+
+ private void addStyle(StringBuilder styleBuilder)
+ {
+ String styleString = styleBuilder.toString();
+ int keyValueBreakpointIndex = styleString.indexOf(KEY_VALUE_SEPARATOR);
+ if (keyValueBreakpointIndex < 0)
+ {
+ log.warn("Key-value separator character #0 not found in style #1, dropping", KEY_VALUE_SEPARATOR + styleBuilder.toString());
+ return;
+ }
+ String styleName = styleString.substring(0, keyValueBreakpointIndex).toLowerCase().trim();
+ if (!propertyBuilderMap.containsKey(styleName))
+ {
+ log.warn("No property builder (unknown style) for property #0", styleName);
+ return;
+ }
+ PropertyBuilder propertyBuilder = propertyBuilderMap.get(styleName);
+ String styleValue = styleString.substring(keyValueBreakpointIndex + 1);
+ log.trace("Parsed style #0 to #1 => #2", styleString, styleName, styleValue);
+ String[] styleValues = trimArray(styleValue.trim().split(STYLE_SHORTHAND_SEPARATOR));
+ styleMap.putAll(propertyBuilder.parseProperty(styleName, styleValues));
+ }
+
+ public static String[] trimArray(String[] array)
+ {
+ List<String> validValues = new ArrayList<String>();
+ for (int i = 0; i < array.length; i++)
+ {
+ if (!"".equals(array[i]) && !" ".equals(array[i]))
+ {
+ validValues.add(array[i].toLowerCase().trim());
+ }
+ }
+ return validValues.toArray(new String[validValues.size()]);
+ }
+
+ public StyleMap parse()
+ {
+ CharacterIterator iterator = new StringCharacterIterator(styleString);
+ StringBuilder styleBuilder = new StringBuilder();
+ for (char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next())
+ {
+ if (ESCAPE_CHAR == c)
+ {
+ escaping = !escaping;
+ }
+ else if (STYLE_SEPARATOR == c && !escaping)
+ {
+ addStyle(styleBuilder);
+ styleBuilder = new StringBuilder();
+ }
+ else
+ {
+ styleBuilder.append(c);
+ }
+ }
+ if (styleBuilder.length() > 0)
+ {
+ addStyle(styleBuilder);
+ }
+
+ if (escaping)
+ {
+ log.warn("Unbalanced escape characters #0 in style #1", ESCAPE_CHAR, styleBuilder.toString());
+ }
+ return styleMap;
+ }
+}
Modified: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/exporter/ExcelExporter.java
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/exporter/ExcelExporter.java 2009-07-01 22:32:40 UTC (rev 11234)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/exporter/ExcelExporter.java 2009-07-02 07:42:33 UTC (rev 11235)
@@ -27,7 +27,7 @@
import org.jboss.seam.excel.ExcelWorkbookException;
import org.jboss.seam.excel.css.CSSNames;
import org.jboss.seam.excel.css.ColumnStyle;
-import org.jboss.seam.excel.css.Parser;
+import org.jboss.seam.excel.css.CSSParser;
import org.jboss.seam.excel.css.StyleMap;
import org.jboss.seam.excel.ui.ExcelComponent;
import org.jboss.seam.excel.ui.UICell;
@@ -78,7 +78,7 @@
{
excelWorkbook = ExcelFactory.instance().getExcelWorkbook(type);
- Parser parser = new Parser();
+ CSSParser parser = new CSSParser();
// Gets the datatable
UIData dataTable = (UIData) FacesContext.getCurrentInstance().getViewRoot().findComponent(dataTableId);
@@ -92,8 +92,8 @@
excelWorkbook.createWorkbook(uiWorkbook);
UIWorksheet uiWorksheet = new UIWorksheet();
uiWorkbook.getChildren().add(uiWorksheet);
- uiWorksheet.setStyle(Parser.getStyle(dataTable));
- uiWorksheet.setStyleClass(Parser.getStyleClass(dataTable));
+ uiWorksheet.setStyle(CSSParser.getStyle(dataTable));
+ uiWorksheet.setStyleClass(CSSParser.getStyleClass(dataTable));
excelWorkbook.createOrSelectWorksheet(uiWorksheet);
// Saves the datatable var
@@ -141,7 +141,7 @@
private Map<Integer, Integer> parseColumnWidths(UIWorksheet worksheet)
{
Map<Integer, Integer> columnWidths = new HashMap<Integer, Integer>();
- Parser parser = new Parser();
+ CSSParser parser = new CSSParser();
StyleMap styleMap = parser.getCascadedStyleMap(worksheet);
for (Map.Entry<String, Object> entry : styleMap.entrySet())
@@ -235,8 +235,8 @@
column.getChildren().add(cell);
cell.setId(output.getId());
cell.setValue(output.getValue());
- cell.setStyle(Parser.getStyle(output));
- cell.setStyleClass(Parser.getStyleClass(output));
+ cell.setStyle(CSSParser.getStyle(output));
+ cell.setStyleClass(CSSParser.getStyleClass(output));
excelWorkbook.addItem(cell);
}
Modified: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/jxl/JXLHelper.java
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/jxl/JXLHelper.java 2009-07-01 22:32:40 UTC (rev 11234)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/jxl/JXLHelper.java 2009-07-02 07:42:33 UTC (rev 11235)
@@ -32,7 +32,7 @@
import org.jboss.seam.excel.ExcelWorkbookException;
import org.jboss.seam.excel.css.CellStyle;
import org.jboss.seam.excel.css.ColumnStyle;
-import org.jboss.seam.excel.css.Parser;
+import org.jboss.seam.excel.css.CSSParser;
import org.jboss.seam.excel.ui.ExcelComponent;
import org.jboss.seam.excel.ui.UICell;
import org.jboss.seam.excel.ui.UICellBase;
@@ -67,7 +67,7 @@
private static Log log = Logging.getLog(JXLHelper.class);
// The CSS parser
- private Parser parser = new Parser();
+ private CSSParser parser = new CSSParser();
// A cache of cell info
private CellInfoCache cellInfoCache = new CellInfoCache();
More information about the seam-commits
mailing list