blob: 09480fec437a683246709a163fdf5ae1b9b31f51 [file] [log] [blame]
/**************************************************************
*
* 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());
}
}