diff options
author | Jeremias Maerki <jeremias@apache.org> | 2009-03-01 08:55:35 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2009-03-01 08:55:35 +0000 |
commit | dc201205b77460b582ef6df7b737fba405260b6a (patch) | |
tree | f981e1922874de2cc81e974b835ef3d5d8bf1ecd /src | |
parent | 7d5beca43a09ad988822dfb910f395e7d9f073f6 (diff) | |
download | xmlgraphics-fop-dc201205b77460b582ef6df7b737fba405260b6a.tar.gz xmlgraphics-fop-dc201205b77460b582ef6df7b737fba405260b6a.zip |
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
Diffstat (limited to 'src')
23 files changed, 384 insertions, 221 deletions
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();]]></source> </section> <section id="afp"> <title>AFP</title> - <warning>The AFP Renderer is a new addition (27-Apr-2006) to the sandbox and as such not yet fully tested or feature complete.</warning> <p> 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). </p> + <p> + The mapping of XSL-FO elements to the major MO:DCA structures is as follows: + </p> + <table> + <tr> + <th>XSL-FO element</th> + <th>MO:DCA-P object</th> + </tr> + <tr> + <td>fo:root</td> + <td>Document</td> + </tr> + <tr> + <td>fo:page-sequence</td> + <td>Page Group</td> + </tr> + <tr> + <td>fo:simple-page-master</td> + <td>Page</td> + </tr> + </table> + <p> + FOP creates exactly one Document per Printfile with an optional Resource Group at the + beginning. FOP does not create document indices. + </p> <section id="afp-references"> <title>References</title> <ul> @@ -687,7 +711,7 @@ out = proc.getOutputStream();]]></source> xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp"> ]]></source> <section id="afp-page-overlay"> - <title>Page Overlay Extension</title> + <title>Page Overlay (IPO) Extension</title> <p>The include-page-overlay extension element allows to define on a per simple-page-master basis a page overlay resource. Example:</p> <source><![CDATA[ <fo:layout-master-set> @@ -701,7 +725,7 @@ out = proc.getOutputStream();]]></source> must be known in the AFP processing environment.</p> </section> <section id="afp-page-segment"> - <title>Page Segment Extension</title> + <title>Page Segment (IPS) Extension</title> <p>The include-page-segment extension element allows to define resource substitution for fo:external-graphics elements. Example:</p> <source><![CDATA[ @@ -724,7 +748,7 @@ out = proc.getOutputStream();]]></source> </p> </section> <section id="afp-tag-logical-element"> - <title>Tag Logical Element Extension</title> + <title>Tag Logical Element (TLE) Extension</title> <p>The tag-logical-element extension element allows to injects TLEs into the AFP output stream. Example:</p> <source><![CDATA[ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" @@ -740,9 +764,14 @@ out = proc.getOutputStream();]]></source> Multiple tag-logical-element extension elements within a simple-page-master are allowed. The name and value attributes are mandatory. </p> + <note> + 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). + </note> </section> <section id="afp-no-operation"> - <title>No Operation Extension</title> + <title>No Operation (NOP) Extension</title> <p>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:</p> <source><![CDATA[ @@ -759,6 +788,29 @@ out = proc.getOutputStream();]]></source> The name attribute is mandatory. </p> </section> + <section id="afp-invoke-medium-map"> + <title>Invoke Medium Map (IMM) Extension</title> + <p> + The invoke-medium-map extension allows to generate IMM fields (Invoke Medium Map) in the + generated AFP output. Example: + </p> + <source><![CDATA[ + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp"> + [..] + <fo:page-sequence master-reference="normal"> + <afp:invoke-medium-map name="MYMAP"/> + <fo:flow flow-name="xsl-region-body"> + [..] +]]></source> + <p> + 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. + </p> + </section> </section> <section id="afp-foreign-attributes"> <title>Foreign Attributes</title> 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 @@ <xs:element name="page-sequence"> <xs:complexType> <xs:sequence> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:any namespace="##other" processContents="lax"/> + </xs:choice> <xs:element ref="mf:page" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" type="xs:ID"/> 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 @@ <message key="rule.childOfDeclarations">The element must be a child of fo:declarations.</message> <message key="rule.childOfSPMorDeclarations">The element must be a child of fo:declarations or fo:simple-page-master.</message> <message key="rule.childOfInstreamForeignObjectorExternalGraphic">The element must be a child of fo:instream-foreign-object or fo:external-graphic.</message> + <message key="rule.childOfPageSequence">The element must be a child of fo:page-sequence.</message> <message key="rule.wrapperInvalidChildForParent">An fo:wrapper is only permitted to have children that would be permitted for its parent.</message> <message key="org.apache.fop.fo.FOValidationEventProducer.tooManyNodes">For "{elementName}", only one "{offendingNode}" may be declared.{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.nodeOutOfOrder">For "{elementName}", "{tooLateNode}" must be declared before "{tooEarlyNode}"!{{locator}}</message> 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,12 +344,32 @@ 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 * * @param isStarting boolean indicating whether the markers qualify as 'starting' 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/*<String,String>*/pageSegmentMap = new java.util.HashMap/*<String,String>*/(); - 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/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/AFPElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java index 3104ced6f..99805edd4 100755..100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java @@ -22,37 +22,34 @@ 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. - * <p/> + * 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 AFPElement extends AbstractAFPExtensionObject { +public class AFPInvokeMediumMapElement extends AbstractAFPExtensionObject { /** - * Constructs an AFP object (called by Maker). - * + * Constructs the AFP extension 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); + public AFPInvokeMediumMapElement(FONode parent) { + super(parent, AFPElementMapping.INVOKE_MEDIUM_MAP); } /** {@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."); + if (parent.getNameId() != Constants.FO_PAGE_SEQUENCE) { + invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), + "rule.childOfPageSequence"); } } - /** {@inheritDoc} */ + /** {@inheritDoc} */ protected ExtensionAttachment instantiateExtensionAttachment() { - return new AFPPageSetup(getLocalName()); + 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 index d167a8d4b..0774913b5 100644..100755 --- 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. + * <p/> */ 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"); |