| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| package com.sun.star.report.pentaho.output.text; |
| |
| import com.sun.star.report.pentaho.OfficeNamespaces; |
| import com.sun.star.report.pentaho.model.OfficeMasterPage; |
| import com.sun.star.report.pentaho.model.OfficeMasterStyles; |
| import com.sun.star.report.pentaho.model.OfficeStyles; |
| import com.sun.star.report.pentaho.model.PageLayout; |
| import com.sun.star.report.pentaho.model.RawText; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.jfree.layouting.input.style.values.CSSNumericValue; |
| 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 14.03.2007 |
| */ |
| public class MasterPageFactory |
| { |
| |
| private static class MasterPageFactoryKey |
| { |
| |
| private final String template; |
| private final String pageHeader; |
| private final String pageFooter; |
| |
| public MasterPageFactoryKey(final String template, |
| final String pageHeader, |
| final String pageFooter) |
| { |
| this.template = template; |
| this.pageHeader = pageHeader; |
| this.pageFooter = pageFooter; |
| } |
| |
| public boolean equals(final Object o) |
| { |
| if (this != o) |
| { |
| if (o == null || getClass() != o.getClass()) |
| { |
| return false; |
| } |
| |
| final MasterPageFactoryKey that = (MasterPageFactoryKey) o; |
| |
| if (pageFooter != null ? !pageFooter.equals( |
| that.pageFooter) : that.pageFooter != null) |
| { |
| return false; |
| } |
| if (pageHeader != null ? !pageHeader.equals( |
| that.pageHeader) : that.pageHeader != null) |
| { |
| return false; |
| } |
| if (template != null ? !template.equals( |
| that.template) : that.template != null) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| public int hashCode() |
| { |
| int result = (template != null ? template.hashCode() : 0); |
| result = 31 * result + (pageHeader != null ? pageHeader.hashCode() : 0); |
| result = 31 * result + (pageFooter != null ? pageFooter.hashCode() : 0); |
| return result; |
| } |
| |
| public String getTemplate() |
| { |
| return template; |
| } |
| |
| public String getPageHeader() |
| { |
| return pageHeader; |
| } |
| |
| public String getPageFooter() |
| { |
| return pageFooter; |
| } |
| } |
| |
| private static class PageLayoutKey |
| { |
| |
| private final String templateName; |
| private final CSSNumericValue headerHeight; |
| private final CSSNumericValue footerHeight; |
| |
| public PageLayoutKey(final String templateName, |
| final CSSNumericValue headerHeight, |
| final CSSNumericValue footerHeight) |
| { |
| this.templateName = templateName; |
| this.headerHeight = headerHeight; |
| this.footerHeight = footerHeight; |
| } |
| |
| public String getTemplateName() |
| { |
| return templateName; |
| } |
| |
| public CSSNumericValue getHeaderHeight() |
| { |
| return headerHeight; |
| } |
| |
| public CSSNumericValue getFooterHeight() |
| { |
| return footerHeight; |
| } |
| |
| public boolean equals(final Object o) |
| { |
| if (this == o) |
| { |
| return true; |
| } |
| if (o == null || getClass() != o.getClass()) |
| { |
| return false; |
| } |
| |
| final PageLayoutKey key = (PageLayoutKey) o; |
| |
| if (footerHeight != null ? !footerHeight.equals( |
| key.footerHeight) : key.footerHeight != null) |
| { |
| return false; |
| } |
| if (headerHeight != null ? !headerHeight.equals( |
| key.headerHeight) : key.headerHeight != null) |
| { |
| return false; |
| } |
| return !(templateName != null ? !templateName.equals( |
| key.templateName) : key.templateName != null); |
| |
| } |
| |
| public int hashCode() |
| { |
| int result; |
| result = (templateName != null ? templateName.hashCode() : 0); |
| result = 31 * result + (headerHeight != null ? headerHeight.hashCode() : 0); |
| result = 31 * result + (footerHeight != null ? footerHeight.hashCode() : 0); |
| return result; |
| } |
| } |
| // todo: Patch the page-layout ... |
| private static final String DEFAULT_PAGE_NAME = "Default"; |
| private final OfficeMasterStyles predefinedStyles; |
| private final AttributeNameGenerator masterPageNameGenerator; |
| private final Map masterPages; |
| private final AttributeNameGenerator pageLayoutNameGenerator; |
| private final Map pageLayouts; |
| |
| public MasterPageFactory(final OfficeMasterStyles predefinedStyles) |
| { |
| this.predefinedStyles = predefinedStyles; |
| this.masterPages = new HashMap(); |
| this.masterPageNameGenerator = new AttributeNameGenerator(); |
| this.pageLayouts = new HashMap(); |
| this.pageLayoutNameGenerator = new AttributeNameGenerator(); |
| } |
| |
| public OfficeMasterPage getMasterPage(final String template, |
| final String pageHeader, |
| final String pageFooter) |
| { |
| final MasterPageFactoryKey key = |
| new MasterPageFactoryKey(template, pageHeader, pageFooter); |
| return (OfficeMasterPage) masterPages.get(key); |
| } |
| |
| public boolean containsMasterPage(final String template, |
| final String pageHeader, |
| final String pageFooter) |
| { |
| final MasterPageFactoryKey key = |
| new MasterPageFactoryKey(template, pageHeader, pageFooter); |
| return masterPages.containsKey(key); |
| } |
| |
| public OfficeMasterPage createMasterPage(final String template, |
| final String pageHeader, |
| final String pageFooter) |
| { |
| final MasterPageFactoryKey key = |
| new MasterPageFactoryKey(template, pageHeader, pageFooter); |
| final OfficeMasterPage cached = (OfficeMasterPage) masterPages.get(key); |
| if (cached != null) |
| { |
| return cached; |
| } |
| |
| final String targetName = (masterPages.isEmpty()) ? "Standard" : template; |
| |
| OfficeMasterPage predef = predefinedStyles.getMasterPage(template); |
| if (predef == null) |
| { |
| // This is a 'magic' name .. |
| // todo: It could be that this should be called 'Standard' instead |
| predef = predefinedStyles.getMasterPage(MasterPageFactory.DEFAULT_PAGE_NAME); |
| } |
| |
| if (predef != null) |
| { |
| try |
| { |
| // derive |
| final OfficeMasterPage derived = (OfficeMasterPage) predef.clone(); |
| return setupMasterPage(derived, targetName, pageHeader, pageFooter, |
| key); |
| } |
| catch (CloneNotSupportedException cne) |
| { |
| throw new IllegalStateException("Implementation error: Unable to derive page", cne); |
| } |
| } |
| |
| final OfficeMasterPage masterPage = new OfficeMasterPage(); |
| masterPage.setNamespace(OfficeNamespaces.STYLE_NS); |
| masterPage.setType("master-page"); |
| return setupMasterPage(masterPage, targetName, pageHeader, pageFooter, key); |
| } |
| |
| private OfficeMasterPage setupMasterPage(final OfficeMasterPage derived, |
| final String targetName, |
| final String pageHeader, |
| final String pageFooter, |
| final MasterPageFactoryKey key) |
| { |
| derived.setStyleName(masterPageNameGenerator.generateName(targetName)); |
| masterPages.put(key, derived); |
| |
| if (pageHeader != null) |
| { |
| final Section header = new Section(); |
| header.setNamespace(OfficeNamespaces.STYLE_NS); |
| header.setType("header"); |
| header.addNode(new RawText(pageHeader)); |
| derived.addNode(header); |
| } |
| |
| if (pageFooter != null) |
| { |
| final Section footer = new Section(); |
| footer.setNamespace(OfficeNamespaces.STYLE_NS); |
| footer.setType("footer"); |
| footer.addNode(new RawText(pageFooter)); |
| derived.addNode(footer); |
| } |
| |
| return derived; |
| } |
| |
| public String createPageStyle(final OfficeStyles commonStyles, |
| final CSSNumericValue headerHeight, |
| final CSSNumericValue footerHeight) |
| { |
| final PageLayoutKey key = |
| new PageLayoutKey(null, headerHeight, footerHeight); |
| final PageLayout derived = new PageLayout(); |
| final String name = pageLayoutNameGenerator.generateName("autogenerated"); |
| derived.setStyleName(name); |
| commonStyles.addPageStyle(derived); |
| |
| if (headerHeight != null) |
| { |
| final Section headerStyle = new Section(); |
| headerStyle.setNamespace(OfficeNamespaces.STYLE_NS); |
| headerStyle.setType("header-style"); |
| derived.addNode(headerStyle); |
| MasterPageFactory.applyHeaderFooterHeight(headerStyle, headerHeight); |
| } |
| |
| if (footerHeight != null) |
| { |
| final Section footerStyle = new Section(); |
| footerStyle.setNamespace(OfficeNamespaces.STYLE_NS); |
| footerStyle.setType("footer-style"); |
| derived.addNode(footerStyle); |
| MasterPageFactory.applyHeaderFooterHeight(footerStyle, footerHeight); |
| } |
| pageLayouts.put(key, name); |
| return name; |
| } |
| |
| public String derivePageStyle(final String pageStyleTemplate, |
| final OfficeStyles predefined, |
| final OfficeStyles commonStyles, |
| final CSSNumericValue headerHeight, |
| final CSSNumericValue footerHeight) |
| throws ReportProcessingException |
| { |
| if (pageStyleTemplate == null) |
| { |
| throw new NullPointerException("A style-name must be given"); |
| } |
| |
| final PageLayoutKey key = |
| new PageLayoutKey(pageStyleTemplate, headerHeight, footerHeight); |
| final String pageLayoutName = (String) pageLayouts.get(key); |
| if (pageLayoutName != null) |
| { |
| // there's already a suitable version included. |
| return pageLayoutName; |
| } |
| |
| final PageLayout original = predefined.getPageStyle(pageStyleTemplate); |
| if (original == null) |
| { |
| throw new ReportProcessingException("Invalid page-layout '" + pageStyleTemplate + "', will not continue."); |
| } |
| |
| try |
| { |
| final PageLayout derived = (PageLayout) original.clone(); |
| final String name = pageLayoutNameGenerator.generateName( |
| pageStyleTemplate); |
| derived.setStyleName(name); |
| commonStyles.addPageStyle(derived); |
| |
| if (headerHeight != null) |
| { |
| Section headerStyle = derived.getHeaderStyle(); |
| if (headerStyle == null) |
| { |
| headerStyle = new Section(); |
| headerStyle.setNamespace(OfficeNamespaces.STYLE_NS); |
| headerStyle.setType("header-style"); |
| derived.addNode(headerStyle); |
| } |
| MasterPageFactory.applyHeaderFooterHeight(headerStyle, headerHeight); |
| } |
| |
| if (footerHeight != null) |
| { |
| Section footerStyle = derived.getFooterStyle(); |
| if (footerStyle == null) |
| { |
| footerStyle = new Section(); |
| footerStyle.setNamespace(OfficeNamespaces.STYLE_NS); |
| footerStyle.setType("footer-style"); |
| derived.addNode(footerStyle); |
| } |
| |
| MasterPageFactory.applyHeaderFooterHeight(footerStyle, footerHeight); |
| } |
| pageLayouts.put(key, name); |
| return name; |
| } |
| catch (CloneNotSupportedException e) |
| { |
| throw new IllegalStateException("Clone failed.", e); |
| } |
| } |
| |
| private static void applyHeaderFooterHeight(final Section headerFooterStyle, |
| final CSSNumericValue style) |
| { |
| Element headerFooterProps = headerFooterStyle.findFirstChild(OfficeNamespaces.STYLE_NS, "header-footer-properties"); |
| if (headerFooterProps == null) |
| { |
| headerFooterProps = new Section(); |
| headerFooterProps.setNamespace(OfficeNamespaces.STYLE_NS); |
| headerFooterProps.setType("header-footer-properties"); |
| headerFooterStyle.addNode(headerFooterProps); |
| } |
| headerFooterProps.setAttribute(OfficeNamespaces.SVG_NS, "height", style.getValue() + style.getType().getType()); |
| } |
| } |