From dc201205b77460b582ef6df7b737fba405260b6a Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Sun, 1 Mar 2009 08:55:35 +0000 Subject: Added support for adding extension elements and foreign attributes on fo:page-sequence. AFP: Added support for Invoke Medium Map (IMM). AFP: Fixed a bug adding TLEs in DataStream (TLEs were added to the page group instead of to the page). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@748981 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/trunk/output.xml | 62 ++++++++++++++-- .../fop-intermediate-format-ng.xsd | 3 + src/java/org/apache/fop/afp/DataStream.java | 6 +- src/java/org/apache/fop/area/AreaTreeParser.java | 10 ++- src/java/org/apache/fop/area/PageSequence.java | 2 +- src/java/org/apache/fop/events/EventFormatter.xml | 1 + .../org/apache/fop/fo/pagination/PageSequence.java | 2 +- .../fop/layoutmgr/AbstractLayoutManager.java | 46 +++++++++--- .../layoutmgr/ExternalDocumentLayoutManager.java | 4 +- .../fop/layoutmgr/PageSequenceLayoutManager.java | 1 + .../apache/fop/render/afp/AFPDocumentHandler.java | 26 +++++-- .../fop/render/afp/extensions/AFPElement.java | 58 --------------- .../render/afp/extensions/AFPElementMapping.java | 52 ++++---------- .../afp/extensions/AFPExtensionAttachment.java | 82 +++------------------- .../render/afp/extensions/AFPExtensionHandler.java | 11 +-- .../render/afp/extensions/AFPInvokeMediumMap.java | 54 ++++++++++++++ .../afp/extensions/AFPInvokeMediumMapElement.java | 55 +++++++++++++++ .../fop/render/afp/extensions/AFPPageSetup.java | 66 ++++++++++++++++- .../render/afp/extensions/AFPPageSetupElement.java | 68 +++++++++++++++--- .../afp/extensions/AbstractAFPExtensionObject.java | 54 +++----------- .../apache/fop/render/intermediate/IFParser.java | 3 + .../apache/fop/render/intermediate/IFRenderer.java | 22 ++++-- .../fop/render/intermediate/IFSerializer.java | 1 + .../org/apache/fop/render/xml/XMLRenderer.java | 2 + 24 files changed, 427 insertions(+), 264 deletions(-) delete mode 100755 src/java/org/apache/fop/render/afp/extensions/AFPElement.java create mode 100644 src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMap.java create mode 100644 src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java mode change 100644 => 100755 src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java (limited to 'src') diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml index 83e730de9..74e22ccf1 100644 --- a/src/documentation/content/xdocs/trunk/output.xml +++ b/src/documentation/content/xdocs/trunk/output.xml @@ -451,11 +451,35 @@ out = proc.getOutputStream();]]>
AFP - The AFP Renderer is a new addition (27-Apr-2006) to the sandbox and as such not yet fully tested or feature complete.

The FOP AFP Renderer deals with creating documents conforming to the IBM AFP document architecture also refered to as MO:DCA (Mixed Object Document Content Architecture).

+

+ The mapping of XSL-FO elements to the major MO:DCA structures is as follows: +

+ + + + + + + + + + + + + + + + + +
XSL-FO elementMO:DCA-P object
fo:rootDocument
fo:page-sequencePage Group
fo:simple-page-masterPage
+

+ FOP creates exactly one Document per Printfile with an optional Resource Group at the + beginning. FOP does not create document indices. +

References
    @@ -687,7 +711,7 @@ out = proc.getOutputStream();]]> xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp"> ]]>
    - Page Overlay Extension + Page Overlay (IPO) Extension

    The include-page-overlay extension element allows to define on a per simple-page-master basis a page overlay resource. Example:

    @@ -701,7 +725,7 @@ out = proc.getOutputStream();]]> must be known in the AFP processing environment.

    - Page Segment Extension + Page Segment (IPS) Extension

    The include-page-segment extension element allows to define resource substitution for fo:external-graphics elements. Example:

    - Tag Logical Element Extension + Tag Logical Element (TLE) Extension

    The tag-logical-element extension element allows to injects TLEs into the AFP output stream. Example:

    Multiple tag-logical-element extension elements within a simple-page-master are allowed. The name and value attributes are mandatory.

    + + Currently, TLEs are only possible inside simple-page-master (i.e. on page leve). + At this time, it is not possible to add TLE's at page-group level (i.e. as direct child + of fo:page-sequence). +
    - No Operation Extension + No Operation (NOP) Extension

    The no-operation extension provides the ability to carry up to 32K of comments or any other type of unarchitected data into the AFP output stream. Example:

    The name attribute is mandatory.

    +
    + Invoke Medium Map (IMM) Extension +

    + The invoke-medium-map extension allows to generate IMM fields (Invoke Medium Map) in the + generated AFP output. Example: +

    + + [..] + + + + [..] +]]> +

    + The invoke-medium-map element is allowed as child of fo:page-sequence (page group + level). It is NOT supported on document level (fo:root), yet. FOP also doesn't support + specifying medium maps inside XML (using BMM/EMM). It can only reference an existing + medium map by name. The medium map has to be constructed through different means and + available on the target platform. +

    +
Foreign Attributes diff --git a/src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd b/src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd index 483935c16..93aacb62d 100644 --- a/src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd +++ b/src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd @@ -55,6 +55,9 @@ + + + diff --git a/src/java/org/apache/fop/afp/DataStream.java b/src/java/org/apache/fop/afp/DataStream.java index 492669311..b1ff96859 100644 --- a/src/java/org/apache/fop/afp/DataStream.java +++ b/src/java/org/apache/fop/afp/DataStream.java @@ -486,10 +486,10 @@ public class DataStream { * The tag value */ public void createTagLogicalElement(String name, String value) { - if (currentPageGroup != null) { - currentPageGroup.createTagLogicalElement(name, value); - } else { + if (currentPage != null) { currentPage.createTagLogicalElement(name, value, tleSequence++); + } else { + currentPageGroup.createTagLogicalElement(name, value); } } diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index 7269bdf10..8a6198cb6 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -356,6 +356,7 @@ public class AreaTreeParser { pageSequence.setLanguage(lang); String country = attributes.getValue("country"); pageSequence.setCountry(country); + transferForeignObjects(attributes, pageSequence); areaStack.push(pageSequence); } } @@ -970,7 +971,14 @@ public class AreaTreeParser { this.currentPageViewport.addExtensionAttachment(attachment); } } else { - log.warn("Don't know how to handle externally generated object: " + obj); + Object o = areaStack.peek(); + if (o instanceof AreaTreeObject && obj instanceof ExtensionAttachment) { + AreaTreeObject ato = (AreaTreeObject)o; + ExtensionAttachment attachment = (ExtensionAttachment)obj; + ato.addExtensionAttachment(attachment); + } else { + log.warn("Don't know how to handle externally generated object: " + obj); + } } } diff --git a/src/java/org/apache/fop/area/PageSequence.java b/src/java/org/apache/fop/area/PageSequence.java index 887fdb43d..8fd3cd571 100644 --- a/src/java/org/apache/fop/area/PageSequence.java +++ b/src/java/org/apache/fop/area/PageSequence.java @@ -24,7 +24,7 @@ import java.util.List; /** * Represents a page sequence in the area tree. */ -public class PageSequence { +public class PageSequence extends AreaTreeObject { private List pages = new java.util.ArrayList(); private LineArea title; diff --git a/src/java/org/apache/fop/events/EventFormatter.xml b/src/java/org/apache/fop/events/EventFormatter.xml index 9bd30609f..c79105f77 100644 --- a/src/java/org/apache/fop/events/EventFormatter.xml +++ b/src/java/org/apache/fop/events/EventFormatter.xml @@ -27,6 +27,7 @@ The element must be a child of fo:declarations. The element must be a child of fo:declarations or fo:simple-page-master. The element must be a child of fo:instream-foreign-object or fo:external-graphic. + The element must be a child of fo:page-sequence. An fo:wrapper is only permitted to have children that would be permitted for its parent. For "{elementName}", only one "{offendingNode}" may be declared.{{locator}} For "{elementName}", "{tooLateNode}" must be declared before "{tooEarlyNode}"!{{locator}} diff --git a/src/java/org/apache/fop/fo/pagination/PageSequence.java b/src/java/org/apache/fop/fo/pagination/PageSequence.java index d41ac86ab..1d3937ec6 100644 --- a/src/java/org/apache/fop/fo/pagination/PageSequence.java +++ b/src/java/org/apache/fop/fo/pagination/PageSequence.java @@ -170,7 +170,7 @@ public class PageSequence extends AbstractPageSequence { flowMap.put(((StaticContent)child).getFlowName(), child); break; default: - assert false; + super.addChildNode(child); } } diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index a5393ced2..8dca1c749 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -26,7 +26,9 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.area.Area; +import org.apache.fop.area.AreaTreeObject; import org.apache.fop.area.PageViewport; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; @@ -266,8 +268,10 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager childLMs = new java.util.ArrayList(10); } childLMs.add(lm); - log.trace(this.getClass().getName() - + ": Adding child LM " + lm.getClass().getName()); + if (log.isTraceEnabled()) { + log.trace(this.getClass().getName() + + ": Adding child LM " + lm.getClass().getName()); + } } /** @@ -300,6 +304,13 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager return pos; } + private void verifyNonNullPosition(Position pos) { + if (pos == null || pos.getIndex() < 0) { + throw new IllegalArgumentException( + "Only non-null Positions with an index can be checked"); + } + } + /** * Indicates whether the given Position is the first area-generating Position of this LM. * @param pos the Position (must be one with a position index) @@ -307,9 +318,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager */ public boolean isFirst(Position pos) { //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos); - if (pos == null || pos.getIndex() < 0) { - throw new IllegalArgumentException("Only non-null Positions with an index can be checked"); - } + verifyNonNullPosition(pos); if (pos.getIndex() == this.smallestPosNumberChecked) { return true; } else if (pos.getIndex() < this.smallestPosNumberChecked) { @@ -326,10 +335,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * @return True if it is the last Position */ public boolean isLast(Position pos) { - //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos); - if (pos == null || pos.getIndex() < 0) { - throw new IllegalArgumentException("Only non-null Positions with an index can be checked"); - } + verifyNonNullPosition(pos); return (pos.getIndex() == this.lastGeneratedPosition && isFinished()); } @@ -338,11 +344,31 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager * Transfers foreign attributes from the formatting object to the area. * @param targetArea the area to set the attributes on */ - protected void transferForeignAttributes(Area targetArea) { + protected void transferForeignAttributes(AreaTreeObject targetArea) { Map atts = fobj.getForeignAttributes(); targetArea.setForeignAttributes(atts); } + /** + * Transfers extension attachments from the formatting object to the area. + * @param targetArea the area to set the extensions on + */ + protected void transferExtensionAttachments(AreaTreeObject targetArea) { + if (fobj.hasExtensionAttachments()) { + targetArea.setExtensionAttachments(fobj.getExtensionAttachments()); + } + } + + /** + * Transfers extensions (foreign attributes and extension attachments) from + * the formatting object to the area. + * @param targetArea the area to set the extensions on + */ + protected void transferExtensions(AreaTreeObject targetArea) { + transferForeignAttributes(targetArea); + transferExtensionAttachments(targetArea); + } + /** * Registers the FO's markers on the current PageViewport * diff --git a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java index 4dcb5e14c..d6c727f68 100644 --- a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java @@ -105,7 +105,9 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan Dimension intrinsicSize = info.getSize().getDimensionMpt(); ImageLayout layout = new ImageLayout(getExternalDocument(), this, intrinsicSize); - areaTreeHandler.getAreaTreeModel().startPageSequence(new PageSequence(null)); + PageSequence pageSequence = new PageSequence(null); + transferExtensions(pageSequence); + areaTreeHandler.getAreaTreeModel().startPageSequence(pageSequence); if (log.isDebugEnabled()) { log.debug("Starting layout"); } diff --git a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java index f9517554f..67c41ccf0 100644 --- a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java @@ -92,6 +92,7 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager AreaTreeModel areaTreeModel = areaTreeHandler.getAreaTreeModel(); org.apache.fop.area.PageSequence pageSequenceAreaObject = new org.apache.fop.area.PageSequence(title); + transferExtensions(pageSequenceAreaObject); pageSequenceAreaObject.setLanguage(getPageSequence().getLanguage()); pageSequenceAreaObject.setCountry(getPageSequence().getCountry()); areaTreeModel.startPageSequence(pageSequenceAreaObject); diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index 93ad759c4..1e08b917e 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -38,6 +38,7 @@ import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontManager; import org.apache.fop.render.afp.extensions.AFPElementMapping; +import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap; import org.apache.fop.render.afp.extensions.AFPPageSetup; import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler; import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; @@ -69,7 +70,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler private Map/**/pageSegmentMap = new java.util.HashMap/**/(); - private boolean inPageHeader; + private static final int LOC_ELSEWHERE = 0; + private static final int LOC_FOLLOWING_PAGE_SEQUENCE = 1; + private static final int LOC_IN_PAGE_HEADER = 2; + + private int location = LOC_ELSEWHERE; /** * Default constructor. @@ -158,6 +163,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } catch (IOException ioe) { throw new IFException("I/O error in startPageSequence()", ioe); } + this.location = LOC_FOLLOWING_PAGE_SEQUENCE; } /** {@inheritDoc} */ @@ -180,6 +186,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler /** {@inheritDoc} */ public void startPage(int index, String name, String pageMasterName, Dimension size) throws IFException { + this.location = LOC_ELSEWHERE; paintingState.clear(); pageSegmentMap.clear(); @@ -202,12 +209,12 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler /** {@inheritDoc} */ public void startPageHeader() throws IFException { super.startPageHeader(); - this.inPageHeader = true; + this.location = LOC_IN_PAGE_HEADER; } /** {@inheritDoc} */ public void endPageHeader() throws IFException { - this.inPageHeader = false; + this.location = LOC_ELSEWHERE; super.endPageHeader(); } @@ -238,7 +245,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler public void handleExtensionObject(Object extension) throws IFException { if (extension instanceof AFPPageSetup) { AFPPageSetup aps = (AFPPageSetup)extension; - if (!inPageHeader) { + if (this.location != LOC_IN_PAGE_HEADER) { throw new IFException( "AFP page setup extension encountered outside the page header: " + aps, null); } @@ -262,6 +269,17 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler dataStream.createNoOperation(content); } } + } else if (extension instanceof AFPInvokeMediumMap) { + if (this.location != LOC_FOLLOWING_PAGE_SEQUENCE) { + throw new IFException( + "AFP IMM extension must be between page-sequence and the first page: " + + extension, null); + } + AFPInvokeMediumMap imm = (AFPInvokeMediumMap)extension; + String mediumMap = imm.getName(); + if (mediumMap != null) { + dataStream.createInvokeMediumMap(mediumMap); + } } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPElement.java deleted file mode 100755 index 3104ced6f..000000000 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.render.afp.extensions; - -import org.apache.fop.apps.FOPException; -import org.apache.fop.fo.Constants; -import org.apache.fop.fo.FONode; -import org.apache.fop.fo.ValidationException; -import org.apache.fop.fo.extensions.ExtensionAttachment; - -/** - * This class extends the org.apache.fop.extensions.ExtensionObj class. The - * object faciliates extraction of elements from formatted objects based on - * the static list as defined in the AFPElementMapping implementation. - *

- */ -public class AFPElement extends AbstractAFPExtensionObject { - - /** - * Constructs an AFP object (called by Maker). - * - * @param parent the parent formatting object - * @param name the name of the afp element - */ - public AFPElement(FONode parent, String name) { - super(parent, name); - } - - /** {@inheritDoc} */ - protected void startOfNode() throws FOPException { - super.startOfNode(); - if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { - throw new ValidationException(getName() + " must be a child of fo:simple-page-master."); - } - } - - /** {@inheritDoc} */ - protected ExtensionAttachment instantiateExtensionAttachment() { - return new AFPPageSetup(getLocalName()); - } -} diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java index c3ba2c43b..83615b75d 100755 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java @@ -33,12 +33,6 @@ import org.apache.fop.fo.FONode; */ public class AFPElementMapping extends ElementMapping { - /** page element */ - public static final String PAGE = "page"; - - /** page group element */ -// public static final String PAGE_GROUP = "page-group"; - /** tag logical element */ public static final String TAG_LOGICAL_ELEMENT = "tag-logical-element"; @@ -51,8 +45,8 @@ public class AFPElementMapping extends ElementMapping { /** NOP */ public static final String NO_OPERATION = "no-operation"; - /** resource information (name, level, dest) */ -// public static final String RESOURCE_INFO = "resource-info"; + /** IMM: Invoke Medium Map (on fo:page-sequence) */ + public static final String INVOKE_MEDIUM_MAP = "invoke-medium-map"; /** * The namespace used for AFP extensions @@ -77,11 +71,6 @@ public class AFPElementMapping extends ElementMapping { if (foObjs == null) { super.foObjs = new java.util.HashMap(); - foObjs.put(PAGE, new AFPPageSetupMaker()); -// foObjs.put( -// PAGE_GROUP, -// new AFPPageGroupMaker() -// ); foObjs.put( TAG_LOGICAL_ELEMENT, new AFPTagLogicalElementMaker()); @@ -94,51 +83,40 @@ public class AFPElementMapping extends ElementMapping { foObjs.put( NO_OPERATION, new AFPNoOperationMaker()); -// foObjs.put( -// RESOURCE_INFO, -// new AFPResourceInfoMaker()); - } - } - - static class AFPPageSetupMaker extends ElementMapping.Maker { - public FONode make(FONode parent) { - return new AFPPageSetupElement(parent); + foObjs.put( + INVOKE_MEDIUM_MAP, + new AFPInvokeMediumMapMaker()); } } static class AFPIncludePageOverlayMaker extends ElementMapping.Maker { public FONode make(FONode parent) { - return new AFPElement(parent, INCLUDE_PAGE_OVERLAY); + return new AFPPageSetupElement(parent, INCLUDE_PAGE_OVERLAY); } } static class AFPIncludePageSegmentMaker extends ElementMapping.Maker { public FONode make(FONode parent) { - return new AFPElement(parent, INCLUDE_PAGE_SEGMENT); + return new AFPPageSetupElement(parent, INCLUDE_PAGE_SEGMENT); } } static class AFPTagLogicalElementMaker extends ElementMapping.Maker { public FONode make(FONode parent) { - return new AFPElement(parent, TAG_LOGICAL_ELEMENT); + return new AFPPageSetupElement(parent, TAG_LOGICAL_ELEMENT); } } static class AFPNoOperationMaker extends ElementMapping.Maker { public FONode make(FONode parent) { - return new AFPElement(parent, NO_OPERATION); + return new AFPPageSetupElement(parent, NO_OPERATION); + } + } + + static class AFPInvokeMediumMapMaker extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new AFPInvokeMediumMapElement(parent); } } -// static class AFPResourceInfoMaker extends ElementMapping.Maker { -// public FONode make(FONode parent) { -// return new AFPResourceInfoElement(parent); -// } -// } - -// static class AFPPageGroupMaker extends ElementMapping.Maker { -// public FONode make(FONode parent) { -// return new AFPElement(parent, PAGE_GROUP); -// } -// } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java index 9a8429b00..e027e7f32 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java @@ -5,9 +5,9 @@ * 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. @@ -21,45 +21,37 @@ package org.apache.fop.render.afp.extensions; import java.io.Serializable; -import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.xmlgraphics.util.XMLizable; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.fo.extensions.ExtensionAttachment; /** * This is the pass-through value object for the AFP extension. */ public abstract class AFPExtensionAttachment implements ExtensionAttachment, Serializable, XMLizable { + private static final long serialVersionUID = 7190606822558332901L; /** The category URI for this extension attachment. */ public static final String CATEGORY = "apache:fop:extensions:afp"; + /** name attribute */ + protected static final String ATT_NAME = "name"; + /** * the extension element name */ protected String elementName; - /** - * the extension content - */ - protected String content; - /** * the extension name attribute */ protected String name; - /** - * the extension value attribute - */ - protected String value; - /** * Default constructor. - * + * * @param elementName the name of the afp extension attachment, may be null */ public AFPExtensionAttachment(String elementName) { @@ -91,65 +83,9 @@ public abstract class AFPExtensionAttachment this.name = name; } - /** - * @return the value - */ - public String getValue() { - return value; - } - - /** - * Sets the value - * @param source The value name to set. - */ - public void setValue(String source) { - this.value = source; - } - /** {@inheritDoc} */ public String getCategory() { return CATEGORY; } - /** - * @return the data - */ - public String getContent() { - return content; - } - - /** - * Sets the data - * @param content The byte data to set. - */ - public void setContent(String content) { - this.content = content; - } - - /** - * name attribute - */ - protected static final String ATT_NAME = "name"; - - /** - * value attribute - */ - protected static final String ATT_VALUE = "value"; - - /** {@inheritDoc} */ - public void toSAX(ContentHandler handler) throws SAXException { - AttributesImpl atts = new AttributesImpl(); - if (name != null && name.length() > 0) { - atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); - } - if (value != null && value.length() > 0) { - atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value); - } - handler.startElement(CATEGORY, elementName, elementName, atts); - if (content != null && content.length() > 0) { - char[] chars = content.toCharArray(); - handler.characters(chars, 0, chars.length); - } - handler.endElement(CATEGORY, elementName, elementName); - } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java index 08989c03c..1c45911a9 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java @@ -19,13 +19,15 @@ package org.apache.fop.render.afp.extensions; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.util.ContentHandlerFactory; import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; /** * ContentHandler (parser) for restoring AFPExtension objects from XML. @@ -53,8 +55,7 @@ public class AFPExtensionHandler extends DefaultHandler || localName.equals(AFPElementMapping.TAG_LOGICAL_ELEMENT) || localName.equals(AFPElementMapping.INCLUDE_PAGE_OVERLAY) || localName.equals(AFPElementMapping.INCLUDE_PAGE_SEGMENT) - || localName.equals(AFPElementMapping.PAGE) - /*|| localName.equals(AFPElementMapping.PAGE_GROUP)*/) { + || localName.equals(AFPElementMapping.INVOKE_MEDIUM_MAP)) { //handled in endElement } else { handled = false; diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMap.java b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMap.java new file mode 100644 index 000000000..83c5325aa --- /dev/null +++ b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMap.java @@ -0,0 +1,54 @@ +/* + * 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.render.afp.extensions; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * This is the pass-through value object for the AFP extension. + */ +public class AFPInvokeMediumMap extends AFPExtensionAttachment { + + private static final long serialVersionUID = -7493160084509249309L; + + /** + * Default constructor. + */ + public AFPInvokeMediumMap() { + super(AFPElementMapping.INVOKE_MEDIUM_MAP); + } + + /** {@inheritDoc} */ + public void toSAX(ContentHandler handler) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + if (name != null && name.length() > 0) { + atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); + } + handler.startElement(CATEGORY, elementName, elementName, atts); + handler.endElement(CATEGORY, elementName, elementName); + } + + /** {@inheritDoc} */ + public String toString() { + return "AFPInvokeMediumMap(name=" + getName() + ")"; + } +} diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java new file mode 100644 index 000000000..99805edd4 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java @@ -0,0 +1,55 @@ +/* + * 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.render.afp.extensions; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.extensions.ExtensionAttachment; + +/** + * This class represents an AFP-specific extension element to embed Invoke Medium Map (IMM) + * fields at the beginning of a page group. The element is optional and expected as a direct child + * of an fo:page-sequence. + */ +public class AFPInvokeMediumMapElement extends AbstractAFPExtensionObject { + + /** + * Constructs the AFP extension object (called by Maker). + * @param parent the parent formatting object + */ + public AFPInvokeMediumMapElement(FONode parent) { + super(parent, AFPElementMapping.INVOKE_MEDIUM_MAP); + } + + /** {@inheritDoc} */ + protected void startOfNode() throws FOPException { + super.startOfNode(); + if (parent.getNameId() != Constants.FO_PAGE_SEQUENCE) { + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfPageSequence"); + } + } + + /** {@inheritDoc} */ + protected ExtensionAttachment instantiateExtensionAttachment() { + return new AFPInvokeMediumMap(); + } +} diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java index d4b8e8a59..b72a30c84 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java @@ -19,11 +19,28 @@ package org.apache.fop.render.afp.extensions; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + /** * This is the pass-through value object for the AFP extension. */ public class AFPPageSetup extends AFPExtensionAttachment { + /** value attribute */ + protected static final String ATT_VALUE = "value"; + + /** + * the extension content + */ + protected String content; + + /** + * the extension value attribute + */ + protected String value; + /** * Default constructor. * @@ -36,8 +53,55 @@ public class AFPPageSetup extends AFPExtensionAttachment { private static final long serialVersionUID = -549941295384013190L; /** - * {@inheritDoc} + * Returns the value of the extension. + * @return the value + */ + public String getValue() { + return value; + } + + /** + * Sets the value + * @param source The value name to set. */ + public void setValue(String source) { + this.value = source; + } + + /** + * Returns the content of the extension. + * @return the data + */ + public String getContent() { + return content; + } + + /** + * Sets the data + * @param content The byte data to set. + */ + public void setContent(String content) { + this.content = content; + } + + /** {@inheritDoc} */ + public void toSAX(ContentHandler handler) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + if (name != null && name.length() > 0) { + atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); + } + if (value != null && value.length() > 0) { + atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value); + } + handler.startElement(CATEGORY, elementName, elementName, atts); + if (content != null && content.length() > 0) { + char[] chars = content.toCharArray(); + handler.characters(chars, 0, chars.length); + } + handler.endElement(CATEGORY, elementName, elementName); + } + + /** {@inheritDoc} */ public String toString() { return "AFPPageSetup(element-name=" + getElementName() + " name=" + getName() + " value=" + getValue() + ")"; diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java old mode 100644 new mode 100755 index d167a8d4b..0774913b5 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java @@ -19,37 +19,83 @@ package org.apache.fop.render.afp.extensions; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; -import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.extensions.ExtensionAttachment; /** - * Extension element for afp:ps-page-setup-code. + * This class extends the org.apache.fop.extensions.ExtensionObj class. The + * object faciliates extraction of elements from formatted objects based on + * the static list as defined in the AFPElementMapping implementation. + *

*/ public class AFPPageSetupElement extends AbstractAFPExtensionObject { /** - * Main constructor - * @param parent parent FO node + * Constructs an AFP object (called by Maker). + * + * @param parent the parent formatting object + * @param name the name of the afp element */ - public AFPPageSetupElement(FONode parent) { - super(parent, "page"); + public AFPPageSetupElement(FONode parent, String name) { + super(parent, name); + } + + private AFPPageSetup getPageSetupAttachment() { + return (AFPPageSetup)getExtensionAttachment(); } /** {@inheritDoc} */ protected void startOfNode() throws FOPException { super.startOfNode(); if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { - throw new ValidationException(getName() + " must be a child of fo:simple-page-master."); + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfSPM"); } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + protected void characters(char[] data, int start, int length, + PropertyList pList, Locator locator) throws FOPException { + StringBuffer sb = new StringBuffer(); + AFPPageSetup pageSetup = getPageSetupAttachment(); + if (pageSetup.getContent() != null) { + sb.append(pageSetup.getContent()); + } + sb.append(data, start, length); + pageSetup.setContent(sb.toString()); + } + + /** {@inheritDoc} */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList propertyList) + throws FOPException { + super.processNode(elementName, locator, attlist, propertyList); + AFPPageSetup pageSetup = getPageSetupAttachment(); + if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) { + String attr = attlist.getValue("src"); + if (attr != null && attr.length() > 0) { + pageSetup.setValue(attr); + } else { + throw new FOPException(elementName + " must have a src attribute."); + } + } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) { + String attr = attlist.getValue("value"); + if (attr != null && attr.length() > 0) { + pageSetup.setValue(attr); + } else { + throw new FOPException(elementName + " must have a value attribute."); + } + } + } + + /** {@inheritDoc} */ protected ExtensionAttachment instantiateExtensionAttachment() { - return new AFPPageSetup(this.name); + return new AFPPageSetup(getLocalName()); } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java index c0e9c2c89..e35a13ec6 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java +++ b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java @@ -54,9 +54,7 @@ public abstract class AbstractAFPExtensionObject extends FONode { this.name = name; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { @@ -64,32 +62,17 @@ public abstract class AbstractAFPExtensionObject extends FONode { } } - /** - * {@inheritDoc} - */ - protected void characters(char[] data, int start, int length, - PropertyList pList, Locator locator) throws FOPException { - ((AFPExtensionAttachment)getExtensionAttachment()).setContent( - new String(data, start, length)); - } - - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String getNamespaceURI() { return AFPElementMapping.NAMESPACE; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String getNormalNamespacePrefix() { return AFPElementMapping.NAMESPACE_PREFIX; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList propertyList) throws FOPException { @@ -100,26 +83,9 @@ public abstract class AbstractAFPExtensionObject extends FONode { } else { throw new FOPException(elementName + " must have a name attribute."); } - if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) { - attr = attlist.getValue("src"); - if (attr != null && attr.length() > 0) { - extensionAttachment.setValue(attr); - } else { - throw new FOPException(elementName + " must have a src attribute."); - } - } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) { - attr = attlist.getValue("value"); - if (attr != null && attr.length() > 0) { - extensionAttachment.setValue(attr); - } else { - throw new FOPException(elementName + " must have a value attribute."); - } - } } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ protected void endOfNode() throws FOPException { super.endOfNode(); } @@ -130,9 +96,7 @@ public abstract class AbstractAFPExtensionObject extends FONode { */ protected abstract ExtensionAttachment instantiateExtensionAttachment(); - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public ExtensionAttachment getExtensionAttachment() { if (extensionAttachment == null) { this.extensionAttachment = (AFPExtensionAttachment)instantiateExtensionAttachment(); @@ -140,9 +104,7 @@ public abstract class AbstractAFPExtensionObject extends FONode { return this.extensionAttachment; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String getLocalName() { return name; } diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java index 92e71d105..fb9d54d88 100644 --- a/src/java/org/apache/fop/render/intermediate/IFParser.java +++ b/src/java/org/apache/fop/render/intermediate/IFParser.java @@ -352,7 +352,10 @@ public class IFParser implements IFConstants { public void startElement(Attributes attributes) throws IFException { String id = attributes.getValue("id"); + Map foreignAttributes = getForeignAttributes(lastAttributes); + establishForeignAttributes(foreignAttributes); documentHandler.startPageSequence(id); + resetForeignAttributes(); } public void endElement() throws IFException { diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java index 558ddfab8..270161dbd 100644 --- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java +++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java @@ -53,6 +53,7 @@ import org.apache.fop.Version; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.Area; +import org.apache.fop.area.AreaTreeObject; import org.apache.fop.area.Block; import org.apache.fop.area.BlockViewport; import org.apache.fop.area.BookmarkData; @@ -500,7 +501,10 @@ public class IFRenderer extends AbstractPathOrientedRenderer { documentHandler.endDocumentHeader(); this.inPageSequence = true; } + establishForeignAttributes(pageSequence.getForeignAttributes()); documentHandler.startPageSequence(null); + resetForeignAttributes(); + processExtensionAttachments(pageSequence); } catch (IFException e) { handleIFException(e); } @@ -557,13 +561,7 @@ public class IFRenderer extends AbstractPathOrientedRenderer { documentHandler.startPageHeader(); //Add page attachments to page header - if (page.hasExtensionAttachments()) { - for (Iterator iter = page.getExtensionAttachments().iterator(); - iter.hasNext();) { - ExtensionAttachment attachment = (ExtensionAttachment) iter.next(); - this.documentHandler.handleExtensionObject(attachment); - } - } + processExtensionAttachments(page); documentHandler.endPageHeader(); this.painter = documentHandler.startPageContent(); @@ -590,6 +588,16 @@ public class IFRenderer extends AbstractPathOrientedRenderer { } } + private void processExtensionAttachments(AreaTreeObject area) throws IFException { + if (area.hasExtensionAttachments()) { + for (Iterator iter = area.getExtensionAttachments().iterator(); + iter.hasNext();) { + ExtensionAttachment attachment = (ExtensionAttachment) iter.next(); + this.documentHandler.handleExtensionObject(attachment); + } + } + } + private void establishForeignAttributes(Map foreignAttributes) { documentHandler.getContext().setForeignAttributes(foreignAttributes); } diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java index 5076a089f..695514776 100644 --- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java +++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java @@ -210,6 +210,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler if (id != null) { atts.addAttribute(XML_NAMESPACE, "id", "xml:id", XMLUtil.CDATA, id); } + addForeignAttributes(atts); handler.startElement(EL_PAGE_SEQUENCE, atts); } catch (SAXException e) { throw new IFException("SAX error in startPageSequence()", e); diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index 6e03d68dd..8e8ae3f1d 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -438,7 +438,9 @@ public class XMLRenderer extends AbstractXMLRenderer { if (pageSequence.getCountry() != null) { addAttribute("country", pageSequence.getCountry()); } + transferForeignObjects(pageSequence); startElement("pageSequence", atts); + handleExtensionAttachments(pageSequence.getExtensionAttachments()); LineArea seqTitle = pageSequence.getTitle(); if (seqTitle != null) { startElement("title"); -- cgit v1.2.3