You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2010/10/07 09:41:49 UTC
svn commit: r1005350 - in /xmlgraphics/fop/trunk: ./
src/documentation/content/xdocs/trunk/ src/java/org/apache/fop/afp/
src/java/org/apache/fop/afp/modca/ src/java/org/apache/fop/afp/parser/
src/java/org/apache/fop/afp/util/ src/java/org/apache/fop/re...
Author: jeremias
Date: Thu Oct 7 07:41:48 2010
New Revision: 1005350
URL: http://svn.apache.org/viewvc?rev=1005350&view=rev
Log:
Bugzilla #49379:
Added ability to embed an external AFP page segment resource file (AFP output only).
Submitted by: Peter Hancock <peter.hancock.at.gmail.com>
Changes to patch:
- Replaced AFP parsing code with a more universal MO:DCA parser (as discussed).
- AFPDocumentHandler: addressed a TODO (clearing of the page segment map was not necessary for each page)
- AFPDocumentHandler: merged pageSegmentMap and pageSegmentUriMap by creating a combined object: PageSegmentDescriptor
Added:
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java (with props)
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java (with props)
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java (with props)
Modified:
xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPResourceManager.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPStreamer.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/parser/MODCAParser.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/StructuredFieldReader.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java
xmlgraphics/fop/trunk/status.xml
Modified: xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml (original)
+++ xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml Thu Oct 7 07:41:48 2010
@@ -885,6 +885,13 @@ Note that the value of the encoding attr
segment in the generated file. Please also note that page segments cannot be scaled.
They are always rendered in their intrinsic size.
</p>
+ <p>
+ The include-page-segment extension element has the optional attribute
+ <i>resource-file</i>. The value of this is a URI to a resource containing a page
+ segment with the declared name. In this case FOP embeds the page segment into the
+ generated document so that the external resource does not have to be supplied in the
+ print job.
+ </p>
</section>
<section id="afp-tag-logical-element">
<title>Tag Logical Element (TLE) Extension</title>
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPResourceManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPResourceManager.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPResourceManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPResourceManager.java Thu Oct 7 07:41:48 2010
@@ -19,12 +19,15 @@
package org.apache.fop.afp;
+import java.io.BufferedInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,6 +41,7 @@ import org.apache.fop.afp.modca.PageSegm
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.ResourceObject;
+import org.apache.fop.afp.util.AFPResourceUtil;
import org.apache.fop.afp.util.ResourceAccessor;
/**
@@ -314,6 +318,57 @@ public class AFPResourceManager {
}
/**
+ * Creates an included resource extracting the named resource from an external source.
+ * @param resourceName the name of the resource
+ * @param uri the URI for the resource
+ * @param accessor resource accessor to access the resource with
+ * @throws IOException if an I/O error occurs while loading the resource
+ */
+ public void createIncludedResourceFromExternal(final String resourceName,
+ final URI uri, final ResourceAccessor accessor) throws IOException {
+
+ AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
+
+ AFPResourceInfo resourceInfo = new AFPResourceInfo();
+ resourceInfo.setLevel(resourceLevel);
+ resourceInfo.setName(resourceName);
+ resourceInfo.setUri(uri.toASCIIString());
+
+ String resource = (String)includeNameMap.get(resourceInfo);
+ if (resource == null) {
+
+ ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
+
+ //resourceObject delegates write commands to copyNamedResource()
+ //The included resource may already be wrapped in a resource object
+ AbstractNamedAFPObject resourceObject = new AbstractNamedAFPObject(null) {
+
+ protected void writeContent(OutputStream os) throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = accessor.createInputStream(uri);
+ BufferedInputStream bin = new BufferedInputStream(inputStream);
+ AFPResourceUtil.copyNamedResource(resourceName, bin, os);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
+ //bypass super.writeStart
+ protected void writeStart(OutputStream os) throws IOException { }
+ //bypass super.writeEnd
+ protected void writeEnd(OutputStream os) throws IOException { }
+ };
+
+ resourceGroup.addObject(resourceObject);
+
+ includeNameMap.put(resourceInfo, resourceName);
+
+ }
+ }
+
+
+ /**
* Sets resource level defaults. The existing defaults over merged with the ones passed in
* as parameter.
* @param defaults the new defaults
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPStreamer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPStreamer.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPStreamer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPStreamer.java Thu Oct 7 07:41:48 2010
@@ -158,7 +158,7 @@ public class AFPStreamer implements Stre
*/
// write out any external resource groups
public void close() throws IOException {
- Iterator it = pathResourceGroupMap.entrySet().iterator();
+ Iterator it = pathResourceGroupMap.values().iterator();
while (it.hasNext()) {
StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next();
resourceGroup.close();
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java Thu Oct 7 07:41:48 2010
@@ -26,6 +26,7 @@ import java.net.URI;
import org.apache.commons.io.IOUtils;
+import org.apache.fop.afp.util.AFPResourceUtil;
import org.apache.fop.afp.util.ResourceAccessor;
@@ -54,7 +55,7 @@ public class IncludedResourceObject exte
public void writeToStream(OutputStream os) throws IOException {
InputStream in = resourceAccessor.createInputStream(this.uri);
try {
- IOUtils.copy(in, os);
+ AFPResourceUtil.copyResourceFile(in, os);
} finally {
IOUtils.closeQuietly(in);
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/parser/MODCAParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/parser/MODCAParser.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/parser/MODCAParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/parser/MODCAParser.java Thu Oct 7 07:41:48 2010
@@ -29,6 +29,9 @@ import java.io.InputStream;
*/
public class MODCAParser {
+ /** The carriage control character (0x5A) used to indicate the start of a structured field. */
+ public static final byte CARRIAGE_CONTROL_CHAR = (byte)(0x5A & 0xFF);
+
private DataInputStream din;
/**
@@ -61,10 +64,11 @@ public class MODCAParser {
try {
while (true) {
byte b = din.readByte(); //Skip 0x5A character if necessary (ex. AFP)
- if (b == 0x0D || b == 0x0A) { //CR and LF may be used as field delimiters
+ if (b == 0x0D || b == 0x0A) {
+ //CR and LF may be used as field delimiters
continue;
- } else if (b == 0x5A) { //Carriage Control Character
- break;
+ } else if (b == CARRIAGE_CONTROL_CHAR) {
+ break; //Signals the start of a new structured field
}
}
} catch (EOFException eof) {
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java?rev=1005350&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java Thu Oct 7 07:41:48 2010
@@ -0,0 +1,214 @@
+/*
+ * 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.afp.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.afp.AFPConstants;
+import org.apache.fop.afp.modca.ResourceObject;
+import org.apache.fop.afp.modca.AbstractAFPObject.Category;
+import org.apache.fop.afp.parser.MODCAParser;
+import org.apache.fop.afp.parser.UnparsedStructuredField;
+
+/**
+ * TODO better docs
+ * Utility for AFP resource handling
+ *
+ *
+ * A utility class to read structured fields from a MO:DCA document. Each
+ * component of a mixed object document is explicitly defined and delimited
+ * in the data. This is accomplished through the use of MO:DCA data structures,
+ * called structured fields. Structured fields are used to envelop document
+ * components and to provide commands and information to applications using
+ * the data. Structured fields may contain one or more parameters. Each
+ * parameter provides one value from a set of values defined by the architecture.
+ * <p/>
+ * MO:DCA structured fields consist of two parts: an introducer that identifies
+ * the length and type of the structured field, and data that provides the
+ * structured field's effect. The data is contained in a set of parameters,
+ * which can consist of other data structures and data elements. The maximum
+ * length of a structured field is 32767 bytes.
+ * <p/>
+ */
+public final class AFPResourceUtil {
+
+ private static final byte TYPE_CODE_BEGIN = (byte)(0xA8 & 0xFF);
+ private static final byte TYPE_CODE_END = (byte)(0xA9 & 0xFF);
+
+ private static final Log LOG = LogFactory.getLog(AFPResourceUtil.class);
+
+ private AFPResourceUtil() {
+ //nop
+ }
+
+ /**
+ * Get the next structured field as identified by the identifier
+ * parameter (this must be a valid MO:DCA structured field).
+ * @param identifier the three byte identifier
+ * @param inputStream the inputStream
+ * @throws IOException if an I/O exception occurred
+ * @return the next structured field or null when there are no more
+ */
+ public static byte[] getNext(byte[] identifier, InputStream inputStream) throws IOException {
+ MODCAParser parser = new MODCAParser(inputStream);
+ while (true) {
+ UnparsedStructuredField field = parser.readNextStructuredField();
+ if (field == null) {
+ return null;
+ }
+ if (field.getSfClassCode() == identifier[0]
+ && field.getSfTypeCode() == identifier[1]
+ && field.getSfCategoryCode() == identifier[2]) {
+ return field.getCompleteFieldAsBytes();
+ }
+ }
+ }
+
+ private static String getResourceName(UnparsedStructuredField field)
+ throws UnsupportedEncodingException {
+ //The first 8 bytes of the field data represent the resource name
+ byte[] nameBytes = new byte[8];
+ System.arraycopy(field.getData(), 0, nameBytes, 0, 8);
+ String asciiName;
+ asciiName = new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
+ return asciiName;
+ }
+
+ /**
+ * Copy a complete resource file to a given {@link OutputStream}.
+ * @param in external resource input
+ * @param out output destination
+ * @throws IOException if an I/O error occurs
+ */
+ public static void copyResourceFile(final InputStream in, OutputStream out)
+ throws IOException {
+ MODCAParser parser = new MODCAParser(in);
+ while (true) {
+ UnparsedStructuredField field = parser.readNextStructuredField();
+ if (field == null) {
+ break;
+ }
+ out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
+ field.writeTo(out);
+ }
+ }
+
+ /**
+ * Copy a named resource to a given {@link OutputStream}. The MO:DCA fields read from the
+ * {@link InputStream} are scanned for the resource with the given name.
+ * @param name name of structured field
+ * @param in external resource input
+ * @param out output destination
+ * @throws IOException if an I/O error occurs
+ */
+ public static void copyNamedResource(String name,
+ final InputStream in, final OutputStream out) throws IOException {
+ final MODCAParser parser = new MODCAParser(in);
+ Collection resourceNames = new java.util.HashSet();
+
+ //Find matching "Begin" field
+ final UnparsedStructuredField fieldBegin;
+ while (true) {
+ UnparsedStructuredField field = parser.readNextStructuredField();
+ if (field == null) {
+ throw new IOException("Requested resource '" + name
+ + "' not found. Encountered resource names: " + resourceNames);
+ }
+
+ if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin
+ continue; //Not a "Begin" field
+ }
+ String resourceName = getResourceName(field);
+ resourceNames.add(resourceName);
+ if (resourceName.equals(name)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Start of requested structured field found:\n"
+ + field);
+ }
+ fieldBegin = field;
+ break; //Name doesn't match
+ }
+ }
+
+ //Decide whether the resource file has to be wrapped in a resource object
+ boolean wrapInResource;
+ if (fieldBegin.getSfCategoryCode() == Category.PAGE_SEGMENT) {
+ //A naked page segment must be wrapped in a resource object
+ wrapInResource = true;
+ } else if (fieldBegin.getSfCategoryCode() == Category.NAME_RESOURCE) {
+ //A resource object can be copied directly
+ wrapInResource = false;
+ } else {
+ throw new IOException("Cannot handle resource: " + fieldBegin);
+ }
+
+ //Copy structured fields (wrapped or as is)
+ if (wrapInResource) {
+ ResourceObject resourceObject = new ResourceObject(name) {
+ protected void writeContent(OutputStream os) throws IOException {
+ copyStructuredFields(name, fieldBegin, parser, out);
+ }
+ };
+ resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT);
+ resourceObject.writeToStream(out);
+ } else {
+ copyStructuredFields(name, fieldBegin, parser, out);
+ }
+ }
+
+ private static void copyStructuredFields(String name, UnparsedStructuredField fieldBegin,
+ MODCAParser parser, OutputStream out) throws IOException {
+ boolean inRequestedResource;
+
+ //The "Begin" field first
+ out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
+ fieldBegin.writeTo(out);
+ UnparsedStructuredField field;
+
+ //Then the rest of the fields until the corresponding "End" field
+ inRequestedResource = true;
+ do {
+ field = parser.readNextStructuredField();
+ if (field == null) {
+ break; //Unexpected EOF
+ }
+
+ if (field.getSfTypeCode() == TYPE_CODE_END) {
+ String resourceName = getResourceName(field);
+ if (resourceName.equals(name)) {
+ inRequestedResource = false; //Signal end of loop
+ }
+ }
+ out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
+ field.writeTo(out);
+ } while (inRequestedResource);
+ if (inRequestedResource) {
+ throw new IOException("Ending structured field not found for resource " + name);
+ }
+ }
+
+}
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/StructuredFieldReader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/StructuredFieldReader.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/StructuredFieldReader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/util/StructuredFieldReader.java Thu Oct 7 07:41:48 2010
@@ -54,80 +54,27 @@ public class StructuredFieldReader {
}
/**
- * Get the next structured field as identified by the identifer
- * parameter (this must be a valid MO:DCA structured field.
+ * Get the next structured field as identified by the identifier
+ * parameter (this must be a valid MO:DCA structured field).
+ * Note: The returned data does not include the field length and identifier!
* @param identifier the three byte identifier
* @throws IOException if an I/O exception occurred
* @return the next structured field or null when there are no more
*/
public byte[] getNext(byte[] identifier) throws IOException {
- int bufferPointer = 0;
- byte[] bufferData = new byte[identifier.length + 2];
- for (int x = 0; x < identifier.length; x++) {
- bufferData[x] = 0x00;
- }
-
- int c;
- while ((c = inputStream.read()) > -1) {
-
- bufferData[bufferPointer] = (byte) c;
-
- // Check the last characters in the buffer
- int index = 0;
- boolean found = true;
-
- for (int i = identifier.length - 1; i > -1; i--) {
-
- int p = bufferPointer - index;
- if (p < 0) {
- p = bufferData.length + p;
- }
-
- index++;
-
- if (identifier[i] != bufferData[p]) {
- found = false;
- break;
- }
-
- }
-
- if (found) {
-
- byte[] length = new byte[2];
-
- int a = bufferPointer - identifier.length;
- if (a < 0) {
- a = bufferData.length + a;
- }
-
- int b = bufferPointer - identifier.length - 1;
- if (b < 0) {
- b = bufferData.length + b;
- }
-
- length[0] = bufferData[b];
- length[1] = bufferData[a];
-
- int reclength = ((length[0] & 0xFF) << 8)
- + (length[1] & 0xFF) - identifier.length - 2;
-
- byte[] retval = new byte[reclength];
-
- inputStream.read(retval, 0, reclength);
-
- return retval;
-
- }
-
- bufferPointer++;
- if (bufferPointer >= bufferData.length) {
- bufferPointer = 0;
- }
+ byte[] bytes = AFPResourceUtil.getNext(identifier, this.inputStream);
+ if (bytes != null) {
+ //Users of this class expect the field data without length and identifier
+ int srcPos = 2 + identifier.length;
+ byte[] tmp = new byte[bytes.length - srcPos];
+ System.arraycopy(bytes, srcPos, tmp, 0, tmp.length);
+ bytes = tmp;
}
- return null;
+ return bytes;
+
}
+
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java Thu Oct 7 07:41:48 2010
@@ -47,6 +47,7 @@ import org.apache.fop.render.afp.extensi
import org.apache.fop.render.afp.extensions.AFPIncludeFormMap;
import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap;
import org.apache.fop.render.afp.extensions.AFPPageOverlay;
+import org.apache.fop.render.afp.extensions.AFPPageSegmentElement;
import org.apache.fop.render.afp.extensions.AFPPageSetup;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandler;
@@ -76,8 +77,8 @@ public class AFPDocumentHandler extends
private DataStream dataStream;
/** the map of page segments */
- private Map/*<String,String>*/pageSegmentMap
- = new java.util.HashMap/*<String,String>*/();
+ private Map/*<String,PageSegmentDescriptor>*/pageSegmentMap
+ = new java.util.HashMap/*<String,PageSegmentDescriptor>*/();
/** Medium Map referenced on previous page **/
private String lastMediumMap;
@@ -213,7 +214,6 @@ public class AFPDocumentHandler extends
throws IFException {
this.location = LOC_ELSEWHERE;
paintingState.clear();
- pageSegmentMap.clear();
AffineTransform baseTransform = getBaseTransform();
paintingState.concatenate(baseTransform);
@@ -288,9 +288,12 @@ public class AFPDocumentHandler extends
null);
}
if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(element)) {
- String name = aps.getName();
- String source = aps.getValue();
- pageSegmentMap.put(source, name);
+ AFPPageSegmentElement.AFPPageSegmentSetup apse
+ = (AFPPageSegmentElement.AFPPageSegmentSetup)aps;
+ String name = apse.getName();
+ String source = apse.getValue();
+ String uri = apse.getResourceSrc();
+ pageSegmentMap.put(source, new PageSegmentDescriptor(name, uri));
} else if (AFPElementMapping.NO_OPERATION.equals(element)) {
String content = aps.getContent();
if (content != null) {
@@ -392,13 +395,13 @@ public class AFPDocumentHandler extends
}
/**
- * Returns the page segment name for a given URI if it actually represents a page segment.
+ * Returns the page segment descriptor for a given URI if it actually represents a page segment.
* Otherwise, it just returns null.
* @param uri the URI that identifies the page segment
- * @return the page segment name or null if there's no page segment for the given URI
+ * @return the page segment descriptor or null if there's no page segment for the given URI
*/
- String getPageSegmentNameFor(String uri) {
- return (String)pageSegmentMap.get(uri);
+ PageSegmentDescriptor getPageSegmentNameFor(String uri) {
+ return (PageSegmentDescriptor)pageSegmentMap.get(uri);
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java Thu Oct 7 07:41:48 2010
@@ -26,6 +26,8 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Map;
import org.w3c.dom.Document;
@@ -48,6 +50,8 @@ import org.apache.fop.afp.modca.Abstract
import org.apache.fop.afp.modca.PresentationTextObject;
import org.apache.fop.afp.ptoca.PtocaBuilder;
import org.apache.fop.afp.ptoca.PtocaProducer;
+import org.apache.fop.afp.util.DefaultFOPResourceAccessor;
+import org.apache.fop.afp.util.ResourceAccessor;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
@@ -183,14 +187,34 @@ public class AFPPainter extends Abstract
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle rect) throws IFException {
- String name = documentHandler.getPageSegmentNameFor(uri);
- if (name != null) {
+ PageSegmentDescriptor pageSegment = documentHandler.getPageSegmentNameFor(uri);
+
+ if (pageSegment != null) {
float[] srcPts = {rect.x, rect.y};
int[] coords = unitConv.mpts2units(srcPts);
int width = Math.round(unitConv.mpt2units(rect.width));
int height = Math.round(unitConv.mpt2units(rect.height));
- getDataStream().createIncludePageSegment(name, coords[X], coords[Y], width, height);
+ getDataStream().createIncludePageSegment(pageSegment.getName(),
+ coords[X], coords[Y], width, height);
+
+ //Do we need to embed an external page segment?
+ if (pageSegment.getURI() != null) {
+ ResourceAccessor accessor = new DefaultFOPResourceAccessor (
+ documentHandler.getUserAgent(), null, null);
+ try {
+ URI resourceUri = new URI(pageSegment.getURI());
+ documentHandler.getResourceManager().createIncludedResourceFromExternal(
+ pageSegment.getName(), resourceUri, accessor);
+
+ } catch (URISyntaxException urie) {
+ throw new IFException("Could not handle resource url"
+ + pageSegment.getURI(), urie);
+ } catch (IOException ioe) {
+ throw new IFException("Could not handle resource" + pageSegment.getURI(), ioe);
+ }
+ }
+
} else {
drawImageUsingURI(uri, rect);
}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java?rev=1005350&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java Thu Oct 7 07:41:48 2010
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+/**
+ * Class holding information on a page segment.
+ */
+class PageSegmentDescriptor {
+
+ private String name;
+ private String uri;
+
+ /**
+ * Creates a new page segment descriptor.
+ * @param name the page segment name
+ * @param uri the URI identifying the external resource file (may be null if the page segment
+ * shall be referenced rather than embedded)
+ */
+ public PageSegmentDescriptor(String name, String uri) {
+ this.name = name;
+ this.uri = uri;
+ }
+
+ /**
+ * Returns the name of the page segment (usually 8 upper case letters).
+ * @return the name of the page segment
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Returns the URI of the external resource containing the page segment.
+ * @return the URI of the external resource (or null if the resource is not to be embedded)
+ */
+ public String getURI() {
+ return this.uri;
+ }
+
+}
\ No newline at end of file
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java Thu Oct 7 07:41:48 2010
@@ -103,7 +103,7 @@ public class AFPElementMapping extends E
static class AFPIncludePageSegmentMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new AFPPageSetupElement(parent, INCLUDE_PAGE_SEGMENT);
+ return new AFPPageSegmentElement(parent, INCLUDE_PAGE_SEGMENT);
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java Thu Oct 7 07:41:48 2010
@@ -29,6 +29,7 @@ import org.xml.sax.helpers.DefaultHandle
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.extensions.AFPPageSegmentElement.AFPPageSegmentSetup;
import org.apache.fop.util.ContentHandlerFactory;
import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener;
@@ -96,6 +97,30 @@ public class AFPExtensionHandler extends
if (name != null) {
returnedObject.setName(name);
}
+ } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(localName)) {
+ AFPPageSegmentSetup pageSetupExtn = null;
+
+ pageSetupExtn = new AFPPageSegmentSetup(localName);
+ this.returnedObject = pageSetupExtn;
+
+ String name = lastAttributes.getValue("name");
+ if (name != null) {
+ returnedObject.setName(name);
+ }
+ String value = lastAttributes.getValue("value");
+ if (value != null && pageSetupExtn != null) {
+ pageSetupExtn.setValue(value);
+ }
+
+ String resourceSrc = lastAttributes.getValue("resource-file");
+ if (resourceSrc != null && pageSetupExtn != null) {
+ pageSetupExtn.setResourceSrc(resourceSrc);
+ }
+
+ if (content.length() > 0 && pageSetupExtn != null) {
+ pageSetupExtn.setContent(content.toString());
+ content.setLength(0); //Reset text buffer (see characters())
+ }
} else {
AFPPageSetup pageSetupExtn = null;
if (AFPElementMapping.INVOKE_MEDIUM_MAP.equals(localName)) {
@@ -117,6 +142,7 @@ public class AFPExtensionHandler extends
content.setLength(0); //Reset text buffer (see characters())
}
}
+
}
}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java?rev=1005350&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java Thu Oct 7 07:41:48 2010
@@ -0,0 +1,149 @@
+/*
+ * 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.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+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/>
+ */
+public class AFPPageSegmentElement extends AFPPageSetupElement {
+
+ private static final String ATT_RESOURCE_SRC = "resource-file";
+
+ /**
+ * Constructs an AFP object (called by Maker).
+ *
+ * @param parent the parent formatting object
+ * @param name the name of the afp element
+ */
+ public AFPPageSegmentElement(FONode parent, String name) {
+ super(parent, name);
+ }
+
+
+ private AFPPageSegmentSetup getPageSetupAttachment() {
+ return (AFPPageSegmentSetup)getExtensionAttachment();
+ }
+
+
+ /** {@inheritDoc} */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList propertyList)
+ throws FOPException {
+
+ AFPPageSegmentSetup pageSetup = getPageSetupAttachment();
+ super.processNode(elementName, locator, attlist, propertyList);
+
+
+ String attr = attlist.getValue(ATT_RESOURCE_SRC);
+
+ if (attr != null && attr.length() > 0) {
+ pageSetup.setResourceSrc(attr);
+ }
+
+ }
+
+ /** {@inheritDoc} */
+ protected ExtensionAttachment instantiateExtensionAttachment() {
+ return new AFPPageSegmentSetup(getLocalName());
+ }
+
+ /**
+ * This is the pass-through value object for the AFP extension.
+ */
+ public static class AFPPageSegmentSetup extends AFPPageSetup {
+
+ private static final long serialVersionUID = 1L;
+
+ private String resourceSrc;
+
+ /**
+ * Default constructor.
+ *
+ * @param elementName the name of the setup code object, may be null
+ */
+ public AFPPageSegmentSetup(String elementName) {
+ super(elementName);
+ }
+
+ /**
+ * Returns the source URI for the page segment.
+ * @return the source URI
+ */
+ public String getResourceSrc() {
+ return resourceSrc;
+ }
+
+ /**
+ * Sets the source URI for the page segment.
+ * @param resourceSrc the source URI
+ */
+ public void setResourceSrc(String resourceSrc) {
+ this.resourceSrc = resourceSrc.trim();
+ }
+
+
+ /** {@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);
+ }
+
+ if (resourceSrc != null && resourceSrc.length() > 0) {
+ atts.addAttribute(null, ATT_RESOURCE_SRC, ATT_RESOURCE_SRC, "CDATA", resourceSrc);
+ }
+
+ 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 "AFPPageSegmentSetup(element-name=" + getElementName()
+ + " name=" + getName()
+ + " value=" + getValue()
+ + " resource=" + getResourceSrc() + ")";
+ }
+
+ }
+
+
+}
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=1005350&r1=1005349&r2=1005350&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Thu Oct 7 07:41:48 2010
@@ -58,6 +58,9 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Renderers" dev="JM" type="add" fixes-bug="49379" due-to="Peter Hancock">
+ Added ability to embed an external AFP page segment resource file (AFP output only).
+ </action>
<action context="Renderers" dev="JM" type="fix" fixes-bug="46360" due-to="Alexis Giotis">
Fixed a multi-threading issue when rendering SVG.
</action>
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org