From 24cb4e43f972beee5a79ee35a4e45763017ca7d9 Mon Sep 17 00:00:00 2001 From: Glen Mazza Date: Wed, 2 Mar 2005 01:59:40 +0000 Subject: [PATCH] Flag added in FOUserAgent for strict/unstrict validation (see TableBody to see how used.) Validation added (only strict version) for TableFooter. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198463 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/FOUserAgent.java | 24 ++++++++ .../org/apache/fop/fo/flow/TableBody.java | 52 ++++++++++++++-- .../org/apache/fop/fo/flow/TableFooter.java | 59 ++++++++++++++++++- 3 files changed, 129 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index 2eec5a165..df263149c 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -79,6 +79,13 @@ public class FOUserAgent { /* user configuration */ private Configuration userConfig = null; private Log log = LogFactory.getLog("FOP"); + + /* FOP has the ability, for some FO's, to continue processing even if the + * input XSL violates that FO's content model. This is the default + * behavior for FOP. However, this flag, if set, provides the user the + * ability for FOP to halt on all content model violations if desired. + */ + private boolean strictValidation = false; /* Additional fo.ElementMapping subclasses set by user */ private ArrayList additionalElementMappings = null; @@ -175,6 +182,23 @@ public class FOUserAgent { return this.foEventHandlerOverride; } + /** + * Activates strict XSL content model validation for FOP + * Default is false (FOP will continue processing where it can) + * @param validateStrictly true to turn on strict validation + */ + public void setStrictValidation(boolean validateStrictly) { + this.strictValidation = validateStrictly; + } + + /** + * Returns whether FOP is strictly validating input XSL + * @return true of strict validation turned on, false otherwise + */ + public boolean validateStrictly() { + return strictValidation; + } + /** * Sets an explicit LayoutManagerMaker instance which overrides the one * defined by the AreaTreeHandler. diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java index fd3b42341..5b054e300 100644 --- a/src/java/org/apache/fop/fo/flow/TableBody.java +++ b/src/java/org/apache/fop/fo/flow/TableBody.java @@ -22,11 +22,14 @@ package org.apache.fop.fo.flow; import java.util.Iterator; import java.util.List; +import org.xml.sax.Locator; + import org.apache.fop.apps.FOPException; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.StaticPropertyList; +import org.apache.fop.fo.ValidationException; import org.apache.fop.fo.properties.CommonAccessibility; import org.apache.fop.fo.properties.CommonAural; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; @@ -34,7 +37,6 @@ import org.apache.fop.fo.properties.CommonRelativePosition; /** * Class modelling the fo:table-body object. - * @todo implement validateChildNode() */ public class TableBody extends FObj { // The value of properties relevant for fo:table-body. @@ -50,6 +52,9 @@ public class TableBody extends FObj { // End of property values private PropertyList savedPropertyList; + + private boolean tableRowsFound = false; + private boolean tableColumnsFound = false; /** * @param parent FONode that is the parent of the object @@ -88,14 +93,51 @@ public class TableBody extends FObj { */ protected void endOfNode() throws FOPException { getFOEventHandler().endBody(this); - if (childNodes == null || childNodes.size() == 0) { - getLogger().error("fo:table-body must not be empty. " - + "Expected: (table-row+|table-cell+)"); - getParent().removeChild(this); + if (!(tableRowsFound || tableColumnsFound)) { + if (getUserAgent().validateStrictly()) { + missingChildElementError("marker* (table-row+|table-cell+)"); + } else { + getLogger().error("fo:table-body must not be empty. " + + "Expected: marker* (table-row+|table-cell+)"); + getParent().removeChild(this); + } } convertCellsToRows(); } + /** + * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) + * XSL Content Model: marker* (table-row+|table-cell+) + */ + protected void validateChildNode(Locator loc, String nsURI, String localName) + throws ValidationException { + if (nsURI == FO_URI) { + if (localName.equals("marker")) { + if (tableRowsFound || tableColumnsFound) { + nodesOutOfOrderError(loc, "fo:marker", "(table-row+|table-cell+)"); + } + } else if (localName.equals("table-row")) { + tableRowsFound = true; + if (tableColumnsFound) { + invalidChildError(loc, nsURI, localName, "Either fo:table-rows" + + " or fo:table-columns may be children of an fo:table-body" + + " but not both"); + } + } else if (localName.equals("table-column")) { + tableColumnsFound = true; + if (tableRowsFound) { + invalidChildError(loc, nsURI, localName, "Either fo:table-rows" + + " or fo:table-columns may be children of an fo:table-body" + + " but not both"); + } + } else { + invalidChildError(loc, nsURI, localName); + } + } else { + invalidChildError(loc, nsURI, localName); + } + } + /** * If table-cells are used as direct children of a table-body|header|footer * they are replace in this method by proper table-rows. diff --git a/src/java/org/apache/fop/fo/flow/TableFooter.java b/src/java/org/apache/fop/fo/flow/TableFooter.java index c64f0590a..5b42bd810 100644 --- a/src/java/org/apache/fop/fo/flow/TableFooter.java +++ b/src/java/org/apache/fop/fo/flow/TableFooter.java @@ -21,9 +21,12 @@ package org.apache.fop.fo.flow; // FOP import org.apache.fop.fo.FONode; +import org.xml.sax.Locator; +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.ValidationException; + /** * Class modelling the fo:table-footer object. - * @todo implement validateChildNode() */ public class TableFooter extends TableBody { @@ -34,6 +37,60 @@ public class TableFooter extends TableBody { super(parent); } + private boolean tableRowsFound = false; + private boolean tableColumnsFound = false; + + /** + * @see org.apache.fop.fo.FONode#startOfNode + */ + protected void startOfNode() throws FOPException { +// getFOEventHandler().startBody(this); + } + + /** + * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) + * XSL Content Model: marker* (table-row+|table-cell+) + */ + protected void validateChildNode(Locator loc, String nsURI, String localName) + throws ValidationException { + if (nsURI == FO_URI) { + if (localName.equals("marker")) { + if (tableRowsFound || tableColumnsFound) { + nodesOutOfOrderError(loc, "fo:marker", "(table-row+|table-cell+)"); + } + } else if (localName.equals("table-row")) { + tableRowsFound = true; + if (tableColumnsFound) { + invalidChildError(loc, nsURI, localName, "Either fo:table-rows" + + " or fo:table-columns may be children of an fo:table-footer" + + " but not both"); + } + } else if (localName.equals("table-column")) { + tableColumnsFound = true; + if (tableRowsFound) { + invalidChildError(loc, nsURI, localName, "Either fo:table-rows" + + " or fo:table-columns may be children of an fo:table-footer" + + " but not both"); + } + } else { + invalidChildError(loc, nsURI, localName); + } + } else { + invalidChildError(loc, nsURI, localName); + } + } + + /** + * @see org.apache.fop.fo.FONode#endOfNode + */ + protected void endOfNode() throws FOPException { +// getFOEventHandler().endFooter(this); + if (!(tableRowsFound || tableColumnsFound)) { + missingChildElementError("marker* (table-row+|table-cell+)"); + } +// convertCellsToRows(); + } + /** * @see org.apache.fop.fo.FObj#getName() */ -- 2.39.5