Browse Source

Allow afp:no-operation to be added to fo:page-sequence (page group in AFP) and fo:declarations (document in AFP). Includes a test case.

Update QDox to avoid a bug with class private enums.
Connect some older test cases into the standard test suite.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1066078 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1old
Jeremias Maerki 13 years ago
parent
commit
941181b8e3

+ 1
- 0
build.xml View File

@@ -737,6 +737,7 @@ list of possible build targets.
<fileset dir="${test.dir}/java">
<include name="META-INF/**"/>
<include name="**/*.xml"/>
<include name="**/*.fo"/>
</fileset>
<fileset dir="${build.dir}/test-gensrc">
<include name="**/*.xml"/>

BIN
lib/build/qdox-1.12.jar View File


BIN
lib/build/qdox-1.6.3.jar View File


+ 7
- 8
src/codegen/java/org/apache/fop/tools/EventProducerCollector.java View File

@@ -21,7 +21,6 @@ package org.apache.fop.tools;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -47,10 +46,10 @@ import com.thoughtworks.qdox.model.Type;
class EventProducerCollector {

private static final String CLASSNAME_EVENT_PRODUCER = EventProducer.class.getName();
private static final Map PRIMITIVE_MAP;
private static final Map<String, Class<?>> PRIMITIVE_MAP;

static {
Map m = new java.util.HashMap();
Map <String, Class<?>> m = new java.util.HashMap<String, Class<?>>();
m.put("boolean", Boolean.class);
m.put("byte", Byte.class);
m.put("char", Character.class);
@@ -63,7 +62,7 @@ class EventProducerCollector {
}

private DocletTagFactory tagFactory;
private List models = new ArrayList();
private List<EventModel> models = new java.util.ArrayList<EventModel>();

/**
* Creates a new EventProducerCollector.
@@ -139,7 +138,7 @@ class EventProducerCollector {
throws EventConventionException, ClassNotFoundException {
JavaClass clazz = method.getParentClass();
//Check EventProducer conventions
if (!method.getReturns().isVoid()) {
if (!method.getReturnType().isVoid()) {
throw new EventConventionException("All methods of interface "
+ clazz.getFullyQualifiedName() + " must have return type 'void'!");
}
@@ -168,10 +167,10 @@ class EventProducerCollector {
if (params.length > 1) {
for (int j = 1, cj = params.length; j < cj; j++) {
JavaParameter p = params[j];
Class type;
Class<?> type;
JavaClass pClass = p.getType().getJavaClass();
if (p.getType().isPrimitive()) {
type = (Class)PRIMITIVE_MAP.get(pClass.getName());
type = PRIMITIVE_MAP.get(pClass.getName());
if (type == null) {
throw new UnsupportedOperationException(
"Primitive datatype not supported: " + pClass.getName());
@@ -197,7 +196,7 @@ class EventProducerCollector {
* Returns the event model that has been accumulated.
* @return the event model.
*/
public List getModels() {
public List<EventModel> getModels() {
return this.models;
}


+ 9
- 3
src/documentation/content/xdocs/trunk/output.xml View File

@@ -931,9 +931,15 @@ Note that the value of the encoding attribute in the example is the double-byte
</fo:simple-page-master>
</fo:layout-master-set>
]]></source>
<p>The no-operation extension element can only occur within a simple-page-master.
Multiple no-operation extension elements within a simple-page-master are allowed.
The name attribute is mandatory.
<p>The no-operation extension element can appear as child of
simple-page-master (appears after "Begin Page" BPG),
page-sequence (appears after "Begin Named Page Group" BNG
and declarations (appears after "Begin Document" BDT).
Multiple no-operation extension elements inside the same formatting object are allowed.
Each NOP will appear right after the respective "Begin" field indicated above even if it
is specified as the last child under its parent. However, the order inside the parent
will be maintained.
The name attribute is mandatory but will not appear inside the AFP stream.
</p>
</section>
<section id="afp-invoke-medium-map">

+ 8
- 2
src/java/org/apache/fop/afp/DataStream.java View File

@@ -595,7 +595,13 @@ public class DataStream {
* byte data
*/
public void createNoOperation(String content) {
currentPage.createNoOperation(content);
if (currentPage != null) {
currentPage.createNoOperation(content);
} else if (currentPageGroup != null) {
currentPageGroup.createNoOperation(content);
} else {
document.createNoOperation(content);
}
}

/**
@@ -639,9 +645,9 @@ public class DataStream {
currentPageGroup.endPageGroup();
tleSequence = currentPageGroup.getTleSequence();
document.addPageGroup(currentPageGroup);
document.writeToStream(outputStream);
currentPageGroup = null;
}
document.writeToStream(outputStream); //Flush objects
}

/**

+ 3
- 1
src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java View File

@@ -126,6 +126,7 @@ implements Streamable {
// }

/** {@inheritDoc} */
@Override
public void writeToStream(OutputStream os) throws IOException {
if (!started) {
writeStart(os);
@@ -140,6 +141,7 @@ implements Streamable {
}

/** {@inheritDoc} */
@Override
protected void writeObjects(Collection/*<AbstractAFPObject>*/ objects, OutputStream os)
throws IOException {
writeObjects(objects, os, false);
@@ -176,7 +178,7 @@ implements Streamable {
* @return true if this object can be written
*/
protected boolean canWrite(AbstractAFPObject obj) {
if (obj instanceof AbstractPageObject) {
if (obj instanceof Completable) {
return ((Completable)obj).isComplete();
}
else {

+ 19
- 2
src/java/org/apache/fop/afp/modca/NoOperation.java View File

@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.OutputStream;

import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.Completable;
import org.apache.fop.afp.util.BinaryUtils;

/**
@@ -35,7 +36,7 @@ import org.apache.fop.afp.util.BinaryUtils;
* No Operation structured fields, no semantics should be attached to
* the data carried by the No Operation structured field in interchange
*/
public class NoOperation extends AbstractAFPObject {
public class NoOperation extends AbstractAFPObject implements Completable {

/** Up to 32759 bytes of data with no architectural definition */
private static final int MAX_DATA_LEN = 32759;
@@ -81,7 +82,7 @@ public class NoOperation extends AbstractAFPObject {
data[1] = rl1[0];
data[2] = rl1[1];

// Structured field ID for a TLE
// Structured field ID for a NOP
data[3] = (byte) 0xD3;
data[4] = (byte) 0xEE;
data[5] = (byte) 0xEE;
@@ -97,4 +98,20 @@ public class NoOperation extends AbstractAFPObject {
os.write(data);
}

/** {@inheritDoc} */
public boolean isComplete() {
return true; //always complete
}

/** {@inheritDoc} */
public void setComplete(boolean complete) {
//ignore
}

/** {@inheritDoc} */
@Override
public String toString() {
return "NOP: " + content.substring(0, Math.min(64, content.length()));
}

}

+ 1
- 0
src/java/org/apache/fop/fo/FOValidationEventProducer.xml View File

@@ -9,6 +9,7 @@
<message key="rule.childOfSPM">The element must be a child of fo:simple-page-master.</message>
<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.childOfSPMorPSorDeclarations">The element must be a child of fo:declarations, fo:simple-page-master or fo:page-sequence.</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.childOfPageSequenceOrSPM">The element must be a child of fo:page-sequence or fo:simple-page-master.</message>

+ 55
- 25
src/java/org/apache/fop/render/afp/AFPDocumentHandler.java View File

@@ -77,17 +77,17 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
private DataStream dataStream;

/** the map of page segments */
private Map/*<String,PageSegmentDescriptor>*/pageSegmentMap
= new java.util.HashMap/*<String,PageSegmentDescriptor>*/();
private Map<String, PageSegmentDescriptor> pageSegmentMap
= new java.util.HashMap<String, PageSegmentDescriptor>();

/** Medium Map referenced on previous page **/
private String lastMediumMap;

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 static enum Location {
ELSEWHERE, IN_DOCUMENT_HEADER, FOLLOWING_PAGE_SEQUENCE, IN_PAGE_HEADER
}

private int location = LOC_ELSEWHERE;
private Location location = Location.ELSEWHERE;

/** the shading mode for filled rectangles */
private AFPShadingMode shadingMode = AFPShadingMode.COLOR;
@@ -117,6 +117,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}

/** {@inheritDoc} */
@Override
public void setDefaultFontInfo(FontInfo fontInfo) {
FontManager fontManager = getUserAgent().getFactory().getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
@@ -152,6 +153,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}

/** {@inheritDoc} */
@Override
public void startDocument() throws IFException {
super.startDocument();
try {
@@ -165,11 +167,23 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
}


/** {@inheritDoc} */
@Override
public void startDocumentHeader() throws IFException {
super.startDocumentHeader();
this.location = Location.IN_DOCUMENT_HEADER;
}

/** {@inheritDoc} */
@Override
public void endDocumentHeader() throws IFException {
super.endDocumentHeader();
this.location = Location.ELSEWHERE;
}

/** {@inheritDoc} */
@Override
public void endDocument() throws IFException {
try {
this.dataStream.endDocument();
@@ -189,7 +203,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
} catch (IOException ioe) {
throw new IFException("I/O error in startPageSequence()", ioe);
}
this.location = LOC_FOLLOWING_PAGE_SEQUENCE;
this.location = Location.FOLLOWING_PAGE_SEQUENCE;
}

/** {@inheritDoc} */
@@ -212,7 +226,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
/** {@inheritDoc} */
public void startPage(int index, String name, String pageMasterName, Dimension size)
throws IFException {
this.location = LOC_ELSEWHERE;
this.location = Location.ELSEWHERE;
paintingState.clear();

AffineTransform baseTransform = getBaseTransform();
@@ -232,14 +246,16 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}

/** {@inheritDoc} */
@Override
public void startPageHeader() throws IFException {
super.startPageHeader();
this.location = LOC_IN_PAGE_HEADER;
this.location = Location.IN_PAGE_HEADER;
}

/** {@inheritDoc} */
@Override
public void endPageHeader() throws IFException {
this.location = LOC_ELSEWHERE;
this.location = Location.ELSEWHERE;
super.endPageHeader();
}

@@ -272,17 +288,36 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
AFPPageSetup aps = (AFPPageSetup)extension;
String element = aps.getElementName();
if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(element)) {
if (this.location != LOC_IN_PAGE_HEADER
&& this.location != LOC_FOLLOWING_PAGE_SEQUENCE) {
switch (this.location) {
case FOLLOWING_PAGE_SEQUENCE:
case IN_PAGE_HEADER:
String name = aps.getName();
String value = aps.getValue();
dataStream.createTagLogicalElement(name, value);
break;
default:
throw new IFException(
"TLE extension must be in the page header or between page-sequence"
+ " and the first page: " + aps, null);
}
String name = aps.getName();
String value = aps.getValue();
dataStream.createTagLogicalElement(name, value);
} else if (AFPElementMapping.NO_OPERATION.equals(element)) {
switch (this.location) {
case IN_DOCUMENT_HEADER:
case FOLLOWING_PAGE_SEQUENCE:
case IN_PAGE_HEADER:
String content = aps.getContent();
if (content != null) {
dataStream.createNoOperation(content);
}
break;
default:
throw new IFException(
"NOP extension must be in the document header, the page header"
+ " or between page-sequence"
+ " and the first page: " + aps, null);
}
} else {
if (this.location != LOC_IN_PAGE_HEADER) {
if (this.location != Location.IN_PAGE_HEADER) {
throw new IFException(
"AFP page setup extension encountered outside the page header: " + aps,
null);
@@ -294,16 +329,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
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) {
dataStream.createNoOperation(content);
}
}
}
} else if (extension instanceof AFPPageOverlay) {
AFPPageOverlay ipo = (AFPPageOverlay)extension;
if (this.location != LOC_IN_PAGE_HEADER) {
if (this.location != Location.IN_PAGE_HEADER) {
throw new IFException(
"AFP page overlay extension encountered outside the page header: " + ipo,
null);
@@ -313,8 +343,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
dataStream.createIncludePageOverlay(overlay, ipo.getX(), ipo.getY());
}
} else if (extension instanceof AFPInvokeMediumMap) {
if (this.location != LOC_FOLLOWING_PAGE_SEQUENCE
&& this.location != LOC_IN_PAGE_HEADER) {
if (this.location != Location.FOLLOWING_PAGE_SEQUENCE
&& this.location != Location.IN_PAGE_HEADER) {

throw new IFException(
"AFP IMM extension must be between page-sequence"
@@ -401,7 +431,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
* @return the page segment descriptor or null if there's no page segment for the given URI
*/
PageSegmentDescriptor getPageSegmentNameFor(String uri) {
return (PageSegmentDescriptor)pageSegmentMap.get(uri);
return pageSegmentMap.get(uri);
}

}

+ 8
- 2
src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java View File

@@ -54,6 +54,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
}

/** {@inheritDoc} */
@Override
protected void startOfNode() throws FOPException {
super.startOfNode();
if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(getLocalName())) {
@@ -63,14 +64,17 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
"rule.childOfPageSequenceOrSPM");
}
} else {
if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER
&& parent.getNameId() != Constants.FO_PAGE_SEQUENCE
&& parent.getNameId() != Constants.FO_DECLARATIONS) {
invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
"rule.childOfSPM");
"rule.childOfSPMorPSorDeclarations");
}
}
}

/** {@inheritDoc} */
@Override
protected void characters(char[] data, int start, int length,
PropertyList pList, Locator locator) throws FOPException {
StringBuffer sb = new StringBuffer();
@@ -83,6 +87,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
}

/** {@inheritDoc} */
@Override
public void processNode(String elementName, Locator locator,
Attributes attlist, PropertyList propertyList)
throws FOPException {
@@ -106,6 +111,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
}

/** {@inheritDoc} */
@Override
protected ExtensionAttachment instantiateExtensionAttachment() {
return new AFPPageSetup(getLocalName());
}

+ 3
- 0
status.xml View File

@@ -59,6 +59,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">
Allow afp:no-operation to also appear under fo:page-sequence and fo:declarations.
</action>
<action context="Code" dev="AD" type="fix" fixes-bug="50635" due-to="mkoegler.AT.auto.tuwien.ac.at">
Bugfix: fix issue in RenderPagesModel.checkPreparedPages() where the same page-sequence
is potentially started multiple times.

+ 4
- 0
test/java/org/apache/fop/StandardTestSuite.java View File

@@ -26,12 +26,14 @@ import org.apache.fop.fonts.DejaVuLGCSerifTest;
import org.apache.fop.image.loader.batik.ImageLoaderTestCase;
import org.apache.fop.image.loader.batik.ImagePreloaderTestCase;
import org.apache.fop.intermediate.IFMimickingTestCase;
import org.apache.fop.render.afp.AFPTestSuite;
import org.apache.fop.render.extensions.prepress.PageBoundariesTest;
import org.apache.fop.render.extensions.prepress.PageScaleTest;
import org.apache.fop.render.pdf.PDFAConformanceTestCase;
import org.apache.fop.render.pdf.PDFCMapTestCase;
import org.apache.fop.render.pdf.PDFEncodingTestCase;
import org.apache.fop.render.pdf.PDFsRGBSettingsTestCase;
import org.apache.fop.render.ps.PSTestSuite;
import org.apache.fop.render.rtf.RichTextFormatTestSuite;
import org.apache.fop.traits.MinOptMaxTest;

@@ -54,6 +56,8 @@ public class StandardTestSuite {
suite.addTest(new TestSuite(PDFCMapTestCase.class));
suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class));
suite.addTest(new TestSuite(DejaVuLGCSerifTest.class));
suite.addTest(AFPTestSuite.suite());
suite.addTest(PSTestSuite.suite());
suite.addTest(RichTextFormatTestSuite.suite());
suite.addTest(new TestSuite(ImageLoaderTestCase.class));
suite.addTest(new TestSuite(ImagePreloaderTestCase.class));

+ 106
- 0
test/java/org/apache/fop/render/AbstractRenderingTestCase.java View File

@@ -0,0 +1,106 @@
/*
* 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;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.MissingResourceException;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import junit.framework.TestCase;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

/**
* Abstract base class for rendering (output) verification tests.
*/
public abstract class AbstractRenderingTestCase extends TestCase {

private static final Map<String, String> MIME_MAP = new java.util.HashMap<String, String>();

static {
MIME_MAP.put(MimeConstants.MIME_PDF, ".pdf");
MIME_MAP.put(MimeConstants.MIME_POSTSCRIPT, ".ps");
MIME_MAP.put(MimeConstants.MIME_AFP, ".afp");
}

/** the JAXP TransformerFactory */
protected TransformerFactory tFactory = TransformerFactory.newInstance();
/** the FopFactory */
protected FopFactory fopFactory = FopFactory.newInstance();

/**
* Renders a test file.
* @param ua the user agent (with override set!)
* @param resourceName the resource name for the FO file
* @param suffix a suffix for the output filename
* @param outputFormat MIME type of the requested output format
* @return the output file
* @throws Exception if an error occurs
*/
protected File renderFile(FOUserAgent ua, String resourceName, String suffix,
String outputFormat) throws Exception {
String extension = MIME_MAP.get(outputFormat);
assert extension != null;
File outputFile = new File("build/test-results/" + resourceName + suffix + extension);
File outputDir = outputFile.getParentFile();
FileUtils.forceMkdir(outputDir);

// Prepare input file
InputStream in = getClass().getResourceAsStream(resourceName);
if (in == null) {
throw new MissingResourceException(resourceName + " not found in resources",
getClass().getName(), null);
}
try {
Source src = new StreamSource(in);

// Create output file
OutputStream out = new java.io.FileOutputStream(outputFile);
out = new java.io.BufferedOutputStream(out);
try {
Fop fop = fopFactory.newFop(outputFormat, ua, out);
SAXResult res = new SAXResult(fop.getDefaultHandler());

Transformer transformer = tFactory.newTransformer();
transformer.transform(src, res);
} finally {
IOUtils.closeQuietly(out);
}
} finally {
IOUtils.closeQuietly(in);
}
return outputFile;
}

}

+ 42
- 0
test/java/org/apache/fop/render/afp/AFPTestSuite.java View File

@@ -0,0 +1,42 @@
/*
* 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;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
* Test suite for FOP's AFP output.
*/
public class AFPTestSuite {

/**
* Builds the test suite
* @return the test suite
*/
public static Test suite() {
TestSuite suite = new TestSuite(
"Test suite for AFP output");
//$JUnit-BEGIN$
suite.addTest(new TestSuite(NoOperationTestCase.class));
//$JUnit-END$
return suite;
}
}

+ 47
- 0
test/java/org/apache/fop/render/afp/AbstractAFPTestCase.java View File

@@ -0,0 +1,47 @@
/*
* 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;

import java.io.File;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.AbstractRenderingTestCase;

/**
* Abstract base class for AFP verification tests.
*/
abstract class AbstractAFPTestCase extends AbstractRenderingTestCase {

/**
* Renders a test file.
* @param ua the user agent (with override set!)
* @param resourceName the resource name for the FO file
* @param suffix a suffix for the output filename
* @return the output file
* @throws Exception if an error occurs
*/
protected File renderFile(FOUserAgent ua, String resourceName, String suffix)
throws Exception {
return renderFile(ua, resourceName, suffix, MimeConstants.MIME_AFP);
}


}

+ 123
- 0
test/java/org/apache/fop/render/afp/NoOperationTestCase.java View File

@@ -0,0 +1,123 @@
/*
* 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;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import junit.framework.Assert;

import org.apache.commons.io.IOUtils;

import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.parser.MODCAParser;
import org.apache.fop.afp.parser.UnparsedStructuredField;
import org.apache.fop.apps.FOUserAgent;

/**
* Tests generation of afp:no-operation (NOPs).
*/
public class NoOperationTestCase extends AbstractAFPTestCase {

/**
* Tests afp:no-operation.
* @throws Exception if an error occurs
*/
public void testNoOperation() throws Exception {
FOUserAgent ua = fopFactory.newFOUserAgent();
File outputFile = renderFile(ua, "nops.fo", "");

InputStream in = new java.io.FileInputStream(outputFile);
try {
MODCAParser parser = new MODCAParser(in);
UnparsedStructuredField field = skipTo(parser, 0xD3A8A8); //Begin Document

//NOP in fo:declarations
field = parser.readNextStructuredField();
assertEquals(0xD3EEEE, field.getSfTypeID());
assertEquals("fo:declarations", getNopText(field));

field = parser.readNextStructuredField();
assertEquals(0xD3A8AD, field.getSfTypeID()); //Begin Named Page Group

//NOPs in fo:page-sequence
field = parser.readNextStructuredField();
assertEquals(0xD3EEEE, field.getSfTypeID());
assertEquals("fo:page-sequence: start", getNopText(field));
field = parser.readNextStructuredField();
assertEquals(0xD3EEEE, field.getSfTypeID());
assertEquals("fo:page-sequence: end", getNopText(field));

field = parser.readNextStructuredField();
assertEquals(0xD3A8AF, field.getSfTypeID()); //Begin Page

field = skipTo(parser, 0xD3A9C9); //End Active Environment Group
field = parser.readNextStructuredField();
assertEquals(0xD3EEEE, field.getSfTypeID());
assertEquals("fo:simple-page-master: first", getNopText(field));

field = skipTo(parser, 0xD3A9C9); //End Active Environment Group
field = parser.readNextStructuredField();
assertEquals(0xD3EEEE, field.getSfTypeID());
assertEquals("fo:simple-page-master: rest", getNopText(field));
} finally {
IOUtils.closeQuietly(in);
}

int counter = 0;
in = new java.io.FileInputStream(outputFile);
try {
MODCAParser parser = new MODCAParser(in);
while (true) {
UnparsedStructuredField field = parser.readNextStructuredField();
if (field == null) {
break;
}
if (field.getSfTypeID() == 0xD3EEEE) {
counter++;
}
}
} finally {
IOUtils.closeQuietly(in);
}
assertEquals(6, counter); //decl, 2 * ps, 3 * page/spm
}

private String getNopText(UnparsedStructuredField field) throws UnsupportedEncodingException {
byte[] data = field.getData();
String text = new String(data, AFPConstants.EBCIDIC_ENCODING);
return text;
}

private UnparsedStructuredField skipTo(MODCAParser parser, int typeID) throws IOException {
UnparsedStructuredField field = null;
do {
field = parser.readNextStructuredField();
if (field.getSfTypeID() == typeID) {
return field;
}
} while (field != null);
Assert.fail("Structured field not found: " + Integer.toHexString(typeID));
return null;
}

}

+ 41
- 0
test/java/org/apache/fop/render/afp/nops.fo View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp">
<fo:layout-master-set>
<fo:simple-page-master master-name="first" page-height="10.5cm" page-width="14.85cm" margin="2cm">
<afp:no-operation name="spm">fo:simple-page-master: first</afp:no-operation>
<fo:region-body margin-top="2em "/>
<fo:region-before extent="2em"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="rest" page-height="10.5cm" page-width="14.85cm" margin="2cm">
<afp:no-operation name="spm">fo:simple-page-master: rest</afp:no-operation>
<fo:region-body margin-top="2em "/>
<fo:region-before extent="2em"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="main">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference master-reference="first" page-position="first"/>
<fo:conditional-page-master-reference master-reference="rest"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:declarations>
<afp:no-operation name="declarations">fo:declarations</afp:no-operation>
</fo:declarations>
<fo:page-sequence master-reference="main" id="doc1">
<afp:no-operation name="ps">fo:page-sequence: start</afp:no-operation>
<fo:flow flow-name="xsl-region-body">
<fo:block>Page 1</fo:block>
<fo:block>Page 1</fo:block>
<fo:block break-after="page"></fo:block>
<fo:block>Page 2</fo:block>
<fo:block>Page 2</fo:block>
<fo:block break-after="page"></fo:block>
<fo:block>Page 3</fo:block>
<fo:block>Page 3</fo:block>
</fo:flow>
<afp:no-operation name="ps">fo:page-sequence: end</afp:no-operation>
</fo:page-sequence>
</fo:root>

+ 3
- 51
test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java View File

@@ -21,20 +21,6 @@ package org.apache.fop.render.ps;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.MissingResourceException;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import junit.framework.TestCase;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.DSCException;
@@ -44,19 +30,13 @@ import org.apache.xmlgraphics.ps.dsc.events.DSCComment;
import org.apache.xmlgraphics.ps.dsc.events.DSCEvent;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.AbstractRenderingTestCase;

/**
* Abstract base class for PostScript verification tests.
*/
public abstract class AbstractPostScriptTestCase extends TestCase {

/** the JAXP TransformerFactory */
protected TransformerFactory tFactory = TransformerFactory.newInstance();
/** the FopFactory */
protected FopFactory fopFactory = FopFactory.newInstance();
public abstract class AbstractPostScriptTestCase extends AbstractRenderingTestCase {

/**
* Renders a test file.
@@ -68,35 +48,7 @@ public abstract class AbstractPostScriptTestCase extends TestCase {
*/
protected File renderFile(FOUserAgent ua, String resourceName, String suffix)
throws Exception {
File outputFile = new File("build/test-results/" + resourceName + suffix + ".ps");
File outputDir = outputFile.getParentFile();
FileUtils.forceMkdir(outputDir);

// Prepare input file
InputStream in = getClass().getResourceAsStream(resourceName);
if (in == null) {
throw new MissingResourceException(resourceName + " not found in resources",
getClass().getName(), null);
}
try {
Source src = new StreamSource(in);

// Create PostScript
OutputStream out = new java.io.FileOutputStream(outputFile);
out = new java.io.BufferedOutputStream(out);
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_POSTSCRIPT, ua, out);
SAXResult res = new SAXResult(fop.getDefaultHandler());

Transformer transformer = tFactory.newTransformer();
transformer.transform(src, res);
} finally {
IOUtils.closeQuietly(out);
}
} finally {
IOUtils.closeQuietly(in);
}
return outputFile;
return renderFile(ua, resourceName, suffix, MimeConstants.MIME_POSTSCRIPT);
}

/**

+ 1
- 0
test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java View File

@@ -86,6 +86,7 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase {
gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE);
gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE);
gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE);
gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE);

PSResource form2 = new PSResource(PSResource.TYPE_FORM, "FOPForm:2");
checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE, form2);

+ 43
- 0
test/java/org/apache/fop/render/ps/PSTestSuite.java View File

@@ -0,0 +1,43 @@
/*
* 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.ps;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
* Test suite for FOP's PostScript output.
*/
public class PSTestSuite {

/**
* Builds the test suite
* @return the test suite
*/
public static Test suite() {
TestSuite suite = new TestSuite(
"Test suite for PostScript output");
//$JUnit-BEGIN$
suite.addTest(new TestSuite(ImageHandlingTestCase.class));
suite.addTest(new TestSuite(ResourceOptimizationTestCase.class));
//$JUnit-END$
return suite;
}
}

+ 1
- 1
test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java View File

@@ -90,7 +90,7 @@ public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase {
= (DSCCommentDocumentSuppliedResources)gotoDSCComment(parser,
DSCConstants.DOCUMENT_SUPPLIED_RESOURCES);
Set resources = supplied.getResources();
assertEquals(4, resources.size());
assertEquals(5, resources.size());
assertTrue(resources.contains(form1));
assertTrue("Expected barcode.eps as supplied resource",
resources.contains(new PSResource(PSResource.TYPE_FILE,

Loading…
Cancel
Save