summaryrefslogtreecommitdiff
path: root/reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java
diff options
context:
space:
mode:
Diffstat (limited to 'reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java')
-rw-r--r--reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java615
1 files changed, 615 insertions, 0 deletions
diff --git a/reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java b/reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java
new file mode 100644
index 000000000000..939583be8365
--- /dev/null
+++ b/reportbuilder/java/com/sun/star/report/pentaho/output/StyleUtilities.java
@@ -0,0 +1,615 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+package com.sun.star.report.pentaho.output;
+
+import com.sun.star.report.pentaho.OfficeNamespaces;
+import com.sun.star.report.pentaho.model.DataStyle;
+import com.sun.star.report.pentaho.model.FontFaceDeclsSection;
+import com.sun.star.report.pentaho.model.FontFaceElement;
+import com.sun.star.report.pentaho.model.OfficeStyle;
+import com.sun.star.report.pentaho.model.OfficeStyles;
+import com.sun.star.report.pentaho.model.OfficeStylesCollection;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.jfree.report.ReportProcessingException;
+import org.jfree.report.structure.Element;
+import org.jfree.report.structure.Section;
+import org.jfree.report.util.AttributeNameGenerator;
+
+
+/**
+ * Todo: Document me!
+ *
+ * @author Thomas Morgner
+ * @since 13.03.2007
+ */
+public class StyleUtilities
+{
+
+ private static final Log LOGGER = LogFactory.getLog(StyleUtilities.class);
+ private static final String STYLE = "style";
+
+ private StyleUtilities()
+ {
+ }
+
+ /**
+ * Copies the specififed style (keyed by its family and name) into the current styles collection. This copies the
+ * style and all inherited styles into the target collection. Inherited common styles will be always be added to the
+ * common collection (which will be written into the 'styles.xml' later).
+ * <p/>
+ * This method does nothing if the specified style already exists in the styles collection.
+ *
+ * @param styleFamily the family of the style to copy
+ * @param styleName the unique name of the style.
+ * @param stylesCollection the current styles collection
+ * @param commonCollection the global styles collection
+ * @param predefCollection the predefined styles from where to copy the styles.
+ * @throws ReportProcessingException if the style copying failed.
+ */
+ public static void copyStyle(final String styleFamily,
+ final String styleName,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection)
+ throws ReportProcessingException
+ {
+ copyStyle(styleFamily, styleName, stylesCollection,
+ commonCollection, predefCollection, new HashSet());
+ }
+
+ /**
+ * Copies the specififed style (keyed by its family and name) into the current styles collection. This copies the
+ * style and all inherited styles into the target collection. Inherited common styles will be always be added to the
+ * common collection (which will be written into the 'styles.xml' later).
+ * <p/>
+ * This method does nothing if the specified style already exists in the styles collection.
+ *
+ * @param styleFamily the family of the style to copy
+ * @param styleName the unique name of the style.
+ * @param stylesCollection the current styles collection
+ * @param commonCollection the global styles collection
+ * @param predefCollection the predefined styles from where to copy the styles.
+ * @param inheritanceTracker a collection of all styles that have been touched. This is used to prevent infinite
+ * loops and duplicates.
+ * @throws ReportProcessingException if the style copying failed.
+ */
+ private static void copyStyle(final String styleFamily,
+ final String styleName,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection,
+ final Set inheritanceTracker)
+ throws ReportProcessingException
+ {
+ if (inheritanceTracker.contains(styleName))
+ {
+ return;
+ }
+ inheritanceTracker.add(styleName);
+
+ if (stylesCollection.containsStyle(styleFamily, styleName) || commonCollection.getCommonStyles().containsStyle(styleFamily, styleName))
+ {
+ // fine, there's already a copy of the stylesheet.
+ return;
+ }
+
+ final OfficeStyle predefCommonStyle =
+ predefCollection.getCommonStyles().getStyle(styleFamily, styleName);
+ if (predefCommonStyle != null)
+ {
+ // so we have an style from the predefined collection.
+ // copy it an add it to the current stylescollection
+ final OfficeStyles commonStyles = commonCollection.getCommonStyles();
+
+ copyStyleInternal(predefCommonStyle, commonStyles, stylesCollection,
+ commonCollection, predefCollection, styleFamily, inheritanceTracker);
+ return;
+ }
+
+ final OfficeStyle predefAutoStyle =
+ predefCollection.getAutomaticStyles().getStyle(styleFamily, styleName);
+ if (predefAutoStyle != null)
+ {
+ // so we have an style from the predefined collection.
+ // copy it an add it to the current stylescollection
+ final OfficeStyles autoStyles = stylesCollection.getAutomaticStyles();
+ copyStyleInternal(predefAutoStyle, autoStyles, stylesCollection,
+ commonCollection, predefCollection, styleFamily, inheritanceTracker);
+ return;
+ }
+
+ // There is no automatic style either. Now this means that someone
+ // messed up the fileformat. Lets create a new empty style for this.
+ final OfficeStyle autostyle = new OfficeStyle();
+ autostyle.setNamespace(OfficeNamespaces.STYLE_NS);
+ autostyle.setType(STYLE);
+ autostyle.setStyleFamily(styleFamily);
+ autostyle.setStyleName(styleName);
+
+ final OfficeStyles autoStyles = stylesCollection.getAutomaticStyles();
+ autoStyles.addStyle(autostyle);
+ }
+
+ private static OfficeStyle copyStyleInternal(
+ final OfficeStyle predefCommonStyle,
+ final OfficeStyles styles,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection,
+ final String styleFamily,
+ final Set inheritanceTracker)
+ throws ReportProcessingException
+ {
+ try
+ {
+ final OfficeStyle preStyle = (OfficeStyle) predefCommonStyle.clone();
+ styles.addStyle(preStyle);
+ performFontFaceProcessing(preStyle, stylesCollection, predefCollection);
+ performDataStyleProcessing(preStyle, stylesCollection, predefCollection);
+
+ // Lookup the parent style ..
+ final String styleParent = preStyle.getStyleParent();
+ final OfficeStyle inherited =
+ stylesCollection.getStyle(styleFamily, styleParent);
+ if (inherited != null)
+ {
+ // OK, recurse (and hope that we dont run into an infinite loop) ..
+ copyStyle(styleFamily, styleParent, stylesCollection,
+ commonCollection, predefCollection, inheritanceTracker);
+ }
+ else if (styleParent != null)
+ {
+ LOGGER.warn("Inconsistent styles: " + styleFamily + ":" + styleParent + " does not exist.");
+ }
+ return preStyle;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new ReportProcessingException("Failed to derive a stylesheet", e);
+ }
+ }
+
+ private static void performFontFaceProcessing(final OfficeStyle style,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection predefCollection)
+ throws ReportProcessingException
+ {
+ final Element textProperties = style.getTextProperties();
+ if (textProperties == null)
+ {
+ return;
+ }
+
+ try
+ {
+ final FontFaceDeclsSection currentFonts = stylesCollection.getFontFaceDecls();
+ final FontFaceDeclsSection predefFonts = predefCollection.getFontFaceDecls();
+
+ final String fontName = (String) textProperties.getAttribute(OfficeNamespaces.STYLE_NS, "font-name");
+ if (fontName != null && !currentFonts.containsFont(fontName))
+ {
+ final FontFaceElement element = predefFonts.getFontFace(fontName);
+ if (element != null)
+ {
+ currentFonts.addFontFace((FontFaceElement) element.clone());
+ }
+ }
+
+ final String fontNameAsian = (String) textProperties.getAttribute(OfficeNamespaces.STYLE_NS,
+ "font-name-asian");
+ if (fontNameAsian != null && !currentFonts.containsFont(fontNameAsian))
+ {
+ final FontFaceElement element = predefFonts.getFontFace(
+ fontNameAsian);
+ if (element != null)
+ {
+ currentFonts.addFontFace((FontFaceElement) element.clone());
+ }
+ }
+
+ final String fontNameComplex = (String) textProperties.getAttribute(OfficeNamespaces.STYLE_NS,
+ "font-name-complex");
+ if (fontNameComplex != null && !currentFonts.containsFont(fontNameComplex))
+ {
+ final FontFaceElement element = predefFonts.getFontFace(
+ fontNameComplex);
+ if (element != null)
+ {
+ currentFonts.addFontFace((FontFaceElement) element.clone());
+ }
+ }
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new ReportProcessingException("Failed to clone font-face element");
+ }
+ }
+
+ private static void performDataStyleProcessing(final OfficeStyle style,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection predefCollection)
+ throws ReportProcessingException
+ {
+ final Section derivedStyle = performDataStyleProcessing(style, stylesCollection, predefCollection, "data-style-name");
+ if (derivedStyle != null)
+ {
+ try
+ {
+ final Section styleMap = (Section) derivedStyle.findFirstChild(OfficeNamespaces.STYLE_NS, "map");
+ if (styleMap != null)
+ {
+ performDataStyleProcessing(styleMap, stylesCollection, predefCollection, "apply-style-name");
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ private static Section performDataStyleProcessing(final Section style,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection predefCollection,
+ final String attributeName)
+ throws ReportProcessingException
+ {
+ final Object attribute = style.getAttribute(OfficeNamespaces.STYLE_NS, attributeName);
+ final DataStyle derivedStyle;
+ if (attribute != null)
+ {
+ final String styleName = String.valueOf(attribute);
+ if (!stylesCollection.getAutomaticStyles().containsDataStyle(styleName) && !stylesCollection.getCommonStyles().containsDataStyle(styleName))
+ {
+ try
+ {
+ final OfficeStyles automaticStyles = predefCollection.getAutomaticStyles();
+ final DataStyle autoDataStyle = automaticStyles.getDataStyle(styleName);
+ if (autoDataStyle != null)
+ {
+ derivedStyle = (DataStyle) autoDataStyle.clone();
+ stylesCollection.getAutomaticStyles().addDataStyle(derivedStyle);
+ }
+ else
+ {
+ final OfficeStyles commonStyles = predefCollection.getCommonStyles();
+ final DataStyle commonDataStyle = commonStyles.getDataStyle(styleName);
+ if (commonDataStyle != null)
+ {
+ derivedStyle = (DataStyle) commonDataStyle.clone();
+ stylesCollection.getCommonStyles().addDataStyle(derivedStyle);
+ }
+ else
+ {
+ LOGGER.warn("Dangling data style: " + styleName);
+ derivedStyle = null;
+ }
+ }
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new ReportProcessingException("Failed to copy style. This should not have happened.");
+ }
+ }
+ else
+ {
+ derivedStyle = null;
+ }
+ }
+ else
+ {
+ derivedStyle = null;
+ }
+ return derivedStyle;
+ }
+
+ /**
+ * Derives the named style. If the style is a common style, a new automatic style is generated and inserted into the
+ * given stylesCollection. If the named style is an automatic style, the style is copied and inserted as new automatic
+ * style.
+ * <p/>
+ * After the style has been created, the style's inheritance hierarchy will be copied as well.
+ * <p/>
+ * If there is no style with the given name and family, a new empty automatic style will be created.
+ *
+ * @param styleFamily the family of the style to copy
+ * @param styleName the unique name of the style.
+ * @param stylesCollection the current styles collection
+ * @param commonCollection the global styles collection
+ * @param predefCollection the predefined styles from where to copy the styles.
+ * @param generator the style-name-generator of the current report-target
+ * @return the derived style instance.
+ * @throws ReportProcessingException if the style copying failed.
+ */
+ public static OfficeStyle deriveStyle(final String styleFamily,
+ final String styleName,
+ final OfficeStylesCollection stylesCollection,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection,
+ final AttributeNameGenerator generator)
+ throws ReportProcessingException
+ {
+ if (styleFamily == null)
+ {
+ throw new NullPointerException("StyleFamily must not be null");
+ }
+ if (styleName != null)
+ {
+
+ final OfficeStyle currentAuto =
+ stylesCollection.getAutomaticStyles().getStyle(styleFamily,
+ styleName);
+ if (currentAuto != null)
+ {
+ // handle an automatic style ..
+ final OfficeStyle derivedStyle =
+ deriveAutomaticStyle(currentAuto, styleFamily, styleName,
+ generator, commonCollection, predefCollection);
+ stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+ return derivedStyle;
+ }
+
+ final OfficeStyle currentCommon =
+ stylesCollection.getCommonStyles().getStyle(styleFamily, styleName);
+ if (currentCommon != null)
+ {
+ // handle an common style ..
+ final OfficeStyle derivedStyle =
+ deriveCommonStyle(currentCommon, styleFamily, styleName,
+ generator, commonCollection, predefCollection);
+ stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+ return derivedStyle;
+ }
+
+// final OfficeStyle commonAuto =
+// commonCollection.getAutomaticStyles().getStyle(styleFamily,
+// styleName);
+// if (commonAuto != null)
+// {
+// // handle an automatic style ..
+// final OfficeStyle derivedStyle =
+// deriveAutomaticStyle(commonAuto, styleFamily, styleName,
+// generator, commonCollection, predefCollection);
+// stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+// return derivedStyle;
+// }
+
+ final OfficeStyle commonCommon =
+ commonCollection.getCommonStyles().getStyle(styleFamily, styleName);
+ if (commonCommon != null)
+ {
+ // handle an common style ..
+ final OfficeStyle derivedStyle =
+ deriveCommonStyle(commonCommon, styleFamily, styleName,
+ generator, commonCollection, predefCollection);
+ stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+ return derivedStyle;
+ }
+
+ final OfficeStyle predefAuto =
+ predefCollection.getAutomaticStyles().getStyle(styleFamily,
+ styleName);
+ if (predefAuto != null)
+ {
+ // handle an automatic style ..
+ final OfficeStyle derivedStyle =
+ deriveAutomaticStyle(predefAuto, styleFamily, styleName,
+ generator, commonCollection, predefCollection);
+ stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+ return derivedStyle;
+ }
+
+ final OfficeStyle predefCommon =
+ predefCollection.getCommonStyles().getStyle(styleFamily, styleName);
+ if (predefCommon != null)
+ {
+ // handle an common style ..
+ final OfficeStyle derivedStyle =
+ deriveCommonStyle(predefCommon, styleFamily, styleName,
+ generator, commonCollection, predefCollection);
+ stylesCollection.getAutomaticStyles().addStyle(derivedStyle);
+ return derivedStyle;
+ }
+ }
+
+ // No such style. Create a new one ..
+ final OfficeStyle autostyle = new OfficeStyle();
+ autostyle.setNamespace(OfficeNamespaces.STYLE_NS);
+ autostyle.setType(STYLE);
+ autostyle.setStyleFamily(styleFamily);
+ if (styleName != null)
+ {
+ autostyle.setStyleName(styleName);
+ }
+ else
+ {
+ autostyle.setStyleName(generator.generateName("derived_anonymous"));
+ }
+
+ final OfficeStyles autoStyles = stylesCollection.getAutomaticStyles();
+ autoStyles.addStyle(autostyle);
+ return autostyle;
+ }
+
+ private static OfficeStyle deriveCommonStyle(final OfficeStyle commonStyle,
+ final String styleFamily,
+ final String styleName,
+ final AttributeNameGenerator nameGenerator,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection)
+ throws ReportProcessingException
+ {
+ final OfficeStyle autostyle = new OfficeStyle();
+ autostyle.setNamespace(OfficeNamespaces.STYLE_NS);
+ autostyle.setType(STYLE);
+ autostyle.setStyleFamily(styleFamily);
+ autostyle.setStyleName(nameGenerator.generateName("derived_" + styleName));
+ autostyle.setStyleParent(styleName);
+
+ // now copy the common style ..
+ final OfficeStyles commonStyles = commonCollection.getCommonStyles();
+ if (!commonStyles.containsStyle(styleFamily, styleName))
+ {
+ copyStyleInternal(commonStyle, commonStyles,
+ commonCollection, commonCollection, predefCollection,
+ styleFamily, new HashSet());
+ }
+ return autostyle;
+ }
+
+ private static OfficeStyle deriveAutomaticStyle(final OfficeStyle commonStyle,
+ final String styleFamily,
+ final String styleName,
+ final AttributeNameGenerator nameGenerator,
+ final OfficeStylesCollection commonCollection,
+ final OfficeStylesCollection predefCollection)
+ throws ReportProcessingException
+ {
+ try
+ {
+ final OfficeStyle autostyle = (OfficeStyle) commonStyle.clone();
+ autostyle.setNamespace(OfficeNamespaces.STYLE_NS);
+ autostyle.setType(STYLE);
+ autostyle.setStyleFamily(styleFamily);
+ autostyle.setStyleName(nameGenerator.generateName("derived_auto_" + styleName));
+
+
+ final String parent = autostyle.getStyleParent();
+ if (parent != null)
+ {
+ copyStyle(styleFamily, parent, commonCollection, commonCollection,
+ predefCollection);
+ }
+ return autostyle;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new ReportProcessingException(
+ "Deriving the style failed. Clone error: ", e);
+ }
+ }
+
+ public static String queryStyle(final OfficeStylesCollection predefCollection,
+ final String styleFamily,
+ final String styleName,
+ final String sectionName,
+ final String propertyNamespace,
+ final String propertyName)
+ {
+ return queryStyle(predefCollection, styleFamily,
+ styleName, sectionName, propertyNamespace, propertyName, new HashSet());
+ }
+
+ public static OfficeStyle queryStyleByProperties(final OfficeStylesCollection predefCollection,
+ final String styleFamily,
+ final String sectionName,
+ final ArrayList propertyNamespace,
+ final ArrayList propertyName,
+ final ArrayList propertyValues)
+ {
+ if (propertyNamespace.size() != propertyName.size())
+ {
+ return null;
+ }
+ final OfficeStyle[] styles = predefCollection.getAutomaticStyles().getAllStyles();
+ for (int i = 0; i < styles.length; i++)
+ {
+ final OfficeStyle officeStyle = styles[i];
+ if (officeStyle.getStyleFamily().equals(styleFamily))
+ {
+ final Element section = officeStyle.findFirstChild(OfficeNamespaces.STYLE_NS, sectionName);
+ if (section != null)
+ {
+ int j = 0;
+ for (; j < propertyNamespace.size(); j++)
+ {
+ final String ns = (String) propertyNamespace.get(j);
+ final String prop = (String) propertyName.get(j);
+ final Object obj = section.getAttribute(ns, prop);
+ final Object value = propertyValues.get(j);
+ if (obj == null || value == null)
+ {
+ continue;
+ }
+ if (!propertyValues.get(j).equals(obj))
+ {
+ break;
+ }
+ }
+ if (j == propertyName.size())
+ {
+ return officeStyle;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String queryStyle(final OfficeStylesCollection predefCollection,
+ final String styleFamily,
+ final String styleName,
+ final String sectionName,
+ final String propertyNamespace,
+ final String propertyName,
+ final Set seenStyles)
+ {
+ if (seenStyles.contains(styleName))
+ {
+ return null;
+ }
+ seenStyles.add(styleName);
+
+ final OfficeStyle style = predefCollection.getStyle(styleFamily, styleName);
+ if (style == null)
+ {
+ return null; // no such style
+
+ }
+ final Element section = style.findFirstChild(OfficeNamespaces.STYLE_NS, sectionName);
+ if (section != null)
+ {
+ final Object attribute = section.getAttribute(propertyNamespace, propertyName);
+ if (attribute != null)
+ {
+ return String.valueOf(attribute);
+ }
+ }
+ final String parent = style.getStyleParent();
+ if (parent == null)
+ {
+ return null;
+ }
+ return queryStyle(predefCollection, styleFamily, parent, sectionName, propertyNamespace, propertyName, seenStyles);
+ }
+}