/* * 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. */ /* $Id$ */ package org.apache.fop.apps; import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.avalon.framework.configuration.Configuration; import org.apache.xmlgraphics.image.loader.ImageContext; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.fop.apps.io.ResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.fonts.FontManager; import org.apache.fop.layoutmgr.LayoutManagerMaker; /** * This is the builder class for {@link FopFactory}. Setters can be chained to * make building a {@link FopFactory} object more concise and intuitive e.g. * *
 * {@code
 * FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder()
 *                                                  .setURIResolver()
 *                                                  .setPageHeight()
 *                                                  .setPageWidth()
 *                                                  .setStrictUserConfigValidation()
 *                                                    ... etc ...
 * FopFactory fopFactory = fopFactoryBuilder.build();
 * }
 * 
*/ public final class FopFactoryBuilder { private final FopFactoryConfig config; private FopFactoryConfigBuilder fopFactoryConfigBuilder; /** * A builder class for {@link FopFactory} which can be used for setting configuration. This is * a helper constructor that uses the default URI resolver implementation that FOP packages * provide ({@link DefaultResourceResolver}). * * @param defaultBaseURI the default base URI for resolving URIs against */ public FopFactoryBuilder(URI defaultBaseURI) { this(defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver()); } /** * A builder class for {@link FopFactory} which can be used for setting configuration. * * @param defaultBaseURI the default base URI for resolving URIs against * @param resourceResolver the URI resolver */ public FopFactoryBuilder(URI defaultBaseURI, ResourceResolver resourceResolver) { this(EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver)); } /** * A builder class for {@link FopFactory} which can be used for setting configuration. * * @param enviro the profile of the FOP deployment environment */ public FopFactoryBuilder(EnvironmentProfile enviro) { config = new FopFactoryConfigImpl(enviro); fopFactoryConfigBuilder = new ActiveFopFactoryConfigBuilder((FopFactoryConfigImpl) config); } /** * Returns the {@link FopFactoryConfig} which is needed to get an instance of * {@link FopFactory}. * * @return build the {@link FopFactoryConfig} * @deprecated Exposing the {@link FopFactoryConfig} is only to maintain backwards compatibility */ public FopFactoryConfig buildConfig() { return buildConfiguration(); } /** * Builds the configuration object used by the FopFactory. * * @return the config for the {@link FopFactory} */ // The {@link FopFactoryConfig} doesn't need to be exposed in the "public" API, this method // should remain package private. FopFactoryConfig buildConfiguration() { fopFactoryConfigBuilder = CompletedFopFactoryConfigBuilder.INSTANCE; return config; } /** * Builds an instance of the the {@link FopFactory}. * * @return the FopFactory instance */ public FopFactory build() { return FopFactory.newInstance(buildConfiguration()); } /** * Gets the base URI used to resolve all URIs within FOP. * * @return the base URI */ URI getBaseURI() { return config.getBaseURI(); } /** * Returns the {@link FontManager} used for managing the fonts within FOP. * * @return the font managing object */ public FontManager getFontManager() { return config.getFontManager(); } /** * Return the {@link ImageManager} used for handling images through out FOP. * * @return the image manager */ public ImageManager getImageManager() { return config.getImageManager(); } /** * Sets whether to include accessibility features in document creation. * * @param enableAccessibility true to set accessibility on * @return this */ public FopFactoryBuilder setAccessibility(boolean enableAccessibility) { fopFactoryConfigBuilder.setAccessibility(enableAccessibility); return this; } /** * Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates * {@link LayoutManager}s. * * @param lmMaker he layout manager maker * @return this */ public FopFactoryBuilder setLayoutManagerMakerOverride( LayoutManagerMaker lmMaker) { fopFactoryConfigBuilder.setLayoutManagerMakerOverride(lmMaker); return this; } /** * Sets the base URI, this will be used for resolving all URIs given to FOP. * * @param baseURI the base URI * @return this */ public FopFactoryBuilder setBaseURI(URI baseURI) { fopFactoryConfigBuilder.setBaseURI(baseURI); return this; } /** * Sets whether to perform strict validation on the FO used. * * @param validateStrictly true if the FO is to be strictly validated * @return this */ public FopFactoryBuilder setStrictFOValidation(boolean validateStrictly) { fopFactoryConfigBuilder.setStrictFOValidation(validateStrictly); return this; } /** * Sets whether to perform strict alidation on the user-configuration. * * @param validateStrictly true if the fop conf is to be strictly validated * @return this */ public FopFactoryBuilder setStrictUserConfigValidation( boolean validateStrictly) { fopFactoryConfigBuilder.setStrictUserConfigValidation(validateStrictly); return this; } /** * Sets whether the indent inheritance should be broken when crossing reference area boundaries. * * @param value true to break inheritance when crossing reference area boundaries * @return this */ public FopFactoryBuilder setBreakIndentInheritanceOnReferenceAreaBoundary( boolean value) { fopFactoryConfigBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(value); return this; } /** * Sets the resolution of resolution-dependent input. * * @param dpi the source resolution * @return this */ public FopFactoryBuilder setSourceResolution(float dpi) { fopFactoryConfigBuilder.setSourceResolution(dpi); return this; } /** * Sets the resolution of resolution-dependent output. * * @param dpi the target resolution * @return this */ public FopFactoryBuilder setTargetResolution(float dpi) { fopFactoryConfigBuilder.setTargetResolution(dpi); return this; } /** * Sets the page height of the paginated output. * * @param pageHeight the page height * @return this */ public FopFactoryBuilder setPageHeight(String pageHeight) { fopFactoryConfigBuilder.setPageHeight(pageHeight); return this; } /** * Sets the page width of the paginated output. * * @param pageWidth the page width * @return this */ public FopFactoryBuilder setPageWidth(String pageWidth) { fopFactoryConfigBuilder.setPageWidth(pageWidth); return this; } /** * FOP will ignore the specified XML element namespace. * * @param namespaceURI the namespace URI to ignore * @return this */ public FopFactoryBuilder ignoreNamespace(String namespaceURI) { fopFactoryConfigBuilder.ignoreNamespace(namespaceURI); return this; } /** * FOP will ignore the colletion of XML element namespaces. * * @param namespaceURIs a collection of namespace URIs to ignore * @return this */ public FopFactoryBuilder ignoreNamespaces(Collection namespaceURIs) { fopFactoryConfigBuilder.ignoreNamespaces(namespaceURIs); return this; } /** * Sets the Avalon configuration if a FOP conf is used. * * @param cfg the fop conf configuration * @return this */ public FopFactoryBuilder setConfiguration(Configuration cfg) { fopFactoryConfigBuilder.setConfiguration(cfg); return this; } /** * Sets whether to chose a {@link Renderer} in preference to an * {@link org.apache.fop.render.intermediate.IFDocumentHandler}. * * @see {@link RendererFactory} * @param preferRenderer true to prefer {@link Renderer} * @return this */ public FopFactoryBuilder setPreferRenderer(boolean preferRenderer) { fopFactoryConfigBuilder.setPreferRenderer(preferRenderer); return this; } public FopFactoryBuilder setComplexScriptFeatures(boolean csf) { fopFactoryConfigBuilder.setComplexScriptFeaturesEnabled(csf); return this; } public FopFactoryBuilder setHyphPatNames(Map hyphPatNames) { fopFactoryConfigBuilder.setHyphPatNames(hyphPatNames); return this; } public static class FopFactoryConfigImpl implements FopFactoryConfig { private final EnvironmentProfile enviro; private final ImageManager imageManager; private boolean accessibility; private LayoutManagerMaker layoutManagerMaker; private URI baseURI; private boolean hasStrictFOValidation = true; private boolean hasStrictUserValidation = FopFactoryConfig.DEFAULT_STRICT_USERCONFIG_VALIDATION; private boolean breakIndentInheritanceOnReferenceBoundary = FopFactoryConfig.DEFAULT_BREAK_INDENT_INHERITANCE; private float sourceResolution = FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION; private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION; private String pageHeight = FopFactoryConfig.DEFAULT_PAGE_HEIGHT; private String pageWidth = FopFactoryConfig.DEFAULT_PAGE_WIDTH; private Set ignoredNamespaces = new HashSet(); private Configuration cfg; private boolean preferRenderer; private boolean isComplexScript = true; private Map hyphPatNames; private static final class ImageContextImpl implements ImageContext { private final FopFactoryConfig config; ImageContextImpl(FopFactoryConfig config) { this.config = config; } public float getSourceResolution() { return config.getSourceResolution(); } } FopFactoryConfigImpl(EnvironmentProfile enviro) { this.enviro = enviro; this.baseURI = enviro.getDefaultBaseURI(); this.imageManager = new ImageManager(new ImageContextImpl(this)); } /** {@inheritDoc} */ public boolean isAccessibilityEnabled() { return accessibility; } /** {@inheritDoc} */ public LayoutManagerMaker getLayoutManagerMakerOverride() { return layoutManagerMaker; } /** {@inheritDoc} */ public ResourceResolver getResourceResolver() { return enviro.getResourceResolver(); } /** {@inheritDoc} */ public URI getBaseURI() { return baseURI; } /** {@inheritDoc} */ public boolean validateStrictly() { return hasStrictFOValidation; } /** {@inheritDoc} */ public boolean validateUserConfigStrictly() { return hasStrictUserValidation; } /** {@inheritDoc} */ public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() { return breakIndentInheritanceOnReferenceBoundary; } /** {@inheritDoc} */ public float getSourceResolution() { return sourceResolution; } /** {@inheritDoc} */ public float getTargetResolution() { return targetResolution; } /** {@inheritDoc} */ public String getPageHeight() { return pageHeight; } /** {@inheritDoc} */ public String getPageWidth() { return pageWidth; } /** {@inheritDoc} */ public Set getIgnoredNamespaces() { return Collections.unmodifiableSet(ignoredNamespaces); } /** {@inheritDoc} */ public boolean isNamespaceIgnored(String namespace) { return ignoredNamespaces.contains(namespace); } /** {@inheritDoc} */ public Configuration getUserConfig() { return cfg; } /** {@inheritDoc} */ public boolean preferRenderer() { return preferRenderer; } /** {@inheritDoc} */ public FontManager getFontManager() { return enviro.getFontManager(); } /** {@inheritDoc} */ public ImageManager getImageManager() { return imageManager; } public boolean isComplexScriptFeaturesEnabled() { return isComplexScript; } public Map getHyphenationPatternNames() { return hyphPatNames; } } private interface FopFactoryConfigBuilder { void setAccessibility(boolean enableAccessibility); void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker); void setBaseURI(URI baseURI); void setStrictFOValidation(boolean validateStrictly); void setStrictUserConfigValidation(boolean validateStrictly); void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value); void setSourceResolution(float dpi); void setTargetResolution(float dpi); void setPageHeight(String pageHeight); void setPageWidth(String pageWidth); void ignoreNamespace(String namespaceURI); void ignoreNamespaces(Collection namespaceURIs); void setConfiguration(Configuration cfg); void setPreferRenderer(boolean preferRenderer); void setComplexScriptFeaturesEnabled(boolean csf); void setHyphPatNames(Map hyphPatNames); } private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder { private static final CompletedFopFactoryConfigBuilder INSTANCE = new CompletedFopFactoryConfigBuilder(); private void throwIllegalStateException() { throw new IllegalStateException("The final FOP Factory configuration has already been built"); } public void setAccessibility(boolean enableAccessibility) { throwIllegalStateException(); } public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) { throwIllegalStateException(); } public void setBaseURI(URI baseURI) { throwIllegalStateException(); } public void setStrictFOValidation(boolean validateStrictly) { throwIllegalStateException(); } public void setStrictUserConfigValidation(boolean validateStrictly) { throwIllegalStateException(); } public void setBreakIndentInheritanceOnReferenceAreaBoundary( boolean value) { throwIllegalStateException(); } public void setSourceResolution(float dpi) { throwIllegalStateException(); } public void setTargetResolution(float dpi) { throwIllegalStateException(); } public void setPageHeight(String pageHeight) { throwIllegalStateException(); } public void setPageWidth(String pageWidth) { throwIllegalStateException(); } public void ignoreNamespace(String namespaceURI) { throwIllegalStateException(); } public void ignoreNamespaces(Collection namespaceURIs) { throwIllegalStateException(); } public void setConfiguration(Configuration cfg) { throwIllegalStateException(); } public void setPreferRenderer(boolean preferRenderer) { throwIllegalStateException(); } public void setComplexScriptFeaturesEnabled(boolean csf) { throwIllegalStateException(); } public void setHyphPatNames(Map hyphPatNames) { throwIllegalStateException(); } } private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder { private final FopFactoryConfigImpl config; private ActiveFopFactoryConfigBuilder(FopFactoryConfigImpl config) { this.config = config; } public void setAccessibility(boolean enableAccessibility) { config.accessibility = enableAccessibility; } public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) { config.layoutManagerMaker = lmMaker; } public void setBaseURI(URI baseURI) { config.baseURI = baseURI; } public void setStrictFOValidation(boolean validateStrictly) { config.hasStrictFOValidation = validateStrictly; } public void setStrictUserConfigValidation( boolean validateStrictly) { config.hasStrictUserValidation = validateStrictly; } public void setBreakIndentInheritanceOnReferenceAreaBoundary( boolean value) { config.breakIndentInheritanceOnReferenceBoundary = value; } public void setSourceResolution(float dpi) { config.sourceResolution = dpi; } public void setTargetResolution(float dpi) { config.targetResolution = dpi; } public void setPageHeight(String pageHeight) { config.pageHeight = pageHeight; } public void setPageWidth(String pageWidth) { config.pageWidth = pageWidth; } public void ignoreNamespace(String namespaceURI) { config.ignoredNamespaces.add(namespaceURI); } public void ignoreNamespaces( Collection namespaceURIs) { config.ignoredNamespaces.addAll(namespaceURIs); } public void setConfiguration(Configuration cfg) { config.cfg = cfg; } public void setPreferRenderer(boolean preferRenderer) { config.preferRenderer = preferRenderer; } public void setComplexScriptFeaturesEnabled(boolean csf) { config.isComplexScript = csf; } public void setHyphPatNames(Map hyphPatNames) { config.hyphPatNames = hyphPatNames; } } }