aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/fo
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-09-02 14:26:31 +0000
committerJeremias Maerki <jeremias@apache.org>2005-09-02 14:26:31 +0000
commit2daa1220f0331d560481ed48d5531ee1b6555793 (patch)
tree8ee289b54a62ce23c199c4b0c8cd349a12d8b53f /src/java/org/apache/fop/fo
parent7253134b2b9feac580724eea566a08ed8ac0fe7f (diff)
downloadxmlgraphics-fop-2daa1220f0331d560481ed48d5531ee1b6555793.tar.gz
xmlgraphics-fop-2daa1220f0331d560481ed48d5531ee1b6555793.zip
Initial work on enhancing the extension facilities to register special extensions which create so-called ExtensionAttachment objects which are attached to the formatting object they are attached to. These objects can be evaluated by standard or custom layout managers or simply passed through to the area tree (the latter is NYI). The AreaTreeHandler currently takes ExtensionAttachment objects from fo:root and fo:declarations and wraps them in OffDocumentItems that Renderers can react on to provide additional functionality on document-level (like PDF metadata or PostScript media dictionaries). Since the simple-page-master is available directly from the PageViewport the renderer can take ExtensionAttachment objects directly from there (see PSRenderer.renderPage()).
Extension Elements that provide ExtensionAttachments are not added as such to the child element list of a formatting object since they work a little differently and should free memory as soon as possible. The PostScript extension described in http://wiki.apache.org/xmlgraphics-fop/ExtensionsForPostScript are now fully implemented but under the namespace URI "http://xmlgraphics.apache.org/fop/postscript", not "http://xml.apache.org/fop/extensions". I'll need to look at namespaces again separately, later. The new PSExtensionElementMapping is currently hard-coded into FOTreeBuilder as are the other ElementMapping classes. OffDocumentItem is now an interface, AbstractOffDocumentItem now providing the base functionality of the former OffDocumentItem class. Lots of clean-up and javadocs while working through this, for example: FObj.childNodes is not public anymore. Instead a special method on fo.flow.InstreamForeignObject provides the child in the one case childNodes was directly accessed. PropertyMaker access in FObj is also done through a method now, propertyListTable is now private. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@267209 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/fo')
-rw-r--r--src/java/org/apache/fop/fo/FOElementMapping.java4
-rw-r--r--src/java/org/apache/fop/fo/FONode.java150
-rw-r--r--src/java/org/apache/fop/fo/FOTreeBuilder.java1
-rw-r--r--src/java/org/apache/fop/fo/FObj.java143
-rw-r--r--src/java/org/apache/fop/fo/PropertyList.java2
-rw-r--r--src/java/org/apache/fop/fo/extensions/ExtensionAttachment.java38
-rw-r--r--src/java/org/apache/fop/fo/flow/InstreamForeignObject.java6
-rw-r--r--src/java/org/apache/fop/fo/pagination/Declarations.java25
-rw-r--r--src/java/org/apache/fop/fo/pagination/SimplePageMaster.java37
9 files changed, 273 insertions, 133 deletions
diff --git a/src/java/org/apache/fop/fo/FOElementMapping.java b/src/java/org/apache/fop/fo/FOElementMapping.java
index cca493cdc..bf376de2a 100644
--- a/src/java/org/apache/fop/fo/FOElementMapping.java
+++ b/src/java/org/apache/fop/fo/FOElementMapping.java
@@ -25,7 +25,9 @@ import java.util.HashMap;
* Element mapping class for all XSL-FO elements.
*/
public class FOElementMapping extends ElementMapping {
- public static String URI = "http://www.w3.org/1999/XSL/Format";
+
+ /** The XSL-FO namespace URI */
+ public static final String URI = "http://www.w3.org/1999/XSL/Format";
/**
* Basic constructor; inititializes the namespace URI for the fo: namespace
diff --git a/src/java/org/apache/fop/fo/FONode.java b/src/java/org/apache/fop/fo/FONode.java
index 0e00b7006..86011004e 100644
--- a/src/java/org/apache/fop/fo/FONode.java
+++ b/src/java/org/apache/fop/fo/FONode.java
@@ -29,17 +29,19 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.svg.SVGElementMapping;
import org.apache.fop.fo.pagination.Root;
import org.apache.fop.util.CharUtilities;
/**
- * base class for nodes in the XML tree
+ * Base class for nodes in the XML tree
*/
public abstract class FONode implements Cloneable {
- protected static String FO_URI = FOElementMapping.URI;
+ /** the XSL-FO namespace URI */
+ protected static final String FO_URI = FOElementMapping.URI;
/** Parent FO node */
protected FONode parent;
@@ -50,10 +52,12 @@ public abstract class FONode implements Cloneable {
* information
*/
public Locator locator;
+ //TODO Make private or protected and access via getLocator()
/** Logger for fo-tree related messages **/
- private static Log log = LogFactory.getLog(FONode.class);
-
+ protected static Log log = LogFactory.getLog(FONode.class);
+ //TODO Remove getLogger() method!
+
/**
* Main constructor.
* @param parent parent of this node
@@ -68,9 +72,10 @@ public abstract class FONode implements Cloneable {
* @param parent the intended parent of the clone
* @param removeChildren if true, clean the list of child nodes
* @return the cloned FO node
+ * @throws FOPException if there's a problem while cloning the node
*/
public FONode clone(FONode parent, boolean removeChildren)
- throws FOPException {
+ throws FOPException {
FONode foNode = (FONode) clone();
foNode.parent = parent;
parent.addChildNode(foNode);
@@ -86,8 +91,9 @@ public abstract class FONode implements Cloneable {
protected Object clone() {
try {
return super.clone();
- } catch (CloneNotSupportedException e) { }
- return null;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
}
/**
@@ -100,6 +106,11 @@ public abstract class FONode implements Cloneable {
}
}
+ /** @return the location information for this element or null, if not available */
+ public Locator getLocator() {
+ return this.locator;
+ }
+
/**
* Recursively goes up the FOTree hierarchy until the fo:root is found,
* which returns the parent FOEventHandler.
@@ -132,11 +143,15 @@ public abstract class FONode implements Cloneable {
* @param elementName element name (e.g., "fo:block")
* @param locator Locator object (ignored by default)
* @param attlist Collection of attributes passed to us from the parser.
+ * @param parent the property list of the parent node
* @throws FOPException for errors or inconsistencies in the attributes
*/
public void processNode(String elementName, Locator locator,
Attributes attlist, PropertyList parent) throws FOPException {
- log.debug("name = " + elementName);
+ if (log.isDebugEnabled()) {
+ log.debug("Unhandled element: " + elementName
+ + (locator != null ? " at " + getLocatorString(locator) : ""));
+ }
}
/**
@@ -146,8 +161,10 @@ public abstract class FONode implements Cloneable {
* @param foEventHandler The FOEventHandler where the PropertyListMaker
* instance can be found.
* @return A new property list.
+ * @throws FOPException if there's a problem during processing
*/
- protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws FOPException {
+ protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler)
+ throws FOPException {
return null;
}
@@ -156,12 +173,15 @@ public abstract class FONode implements Cloneable {
* incoming node is valid for the this (parent) node (e.g., checking to
* see that fo:table is not an immediate child of fo:root)
* called within FObj constructor
+ * @param loc location in the FO source file
* @param namespaceURI namespace of incoming node
* @param localName (e.g. "table" for "fo:table")
* @throws ValidationException if incoming node not valid for parent
*/
protected void validateChildNode(Locator loc, String namespaceURI, String localName)
- throws ValidationException {}
+ throws ValidationException {
+ //nop
+ }
/**
* Adds characters (does nothing here)
@@ -179,25 +199,31 @@ public abstract class FONode implements Cloneable {
}
/**
- *
- */
+ * Called after processNode() is called. Subclasses can do additional processing.
+ * @throws FOPException if there's a problem during processing
+ */
protected void startOfNode() throws FOPException {
// do nothing by default
}
/**
- * Primarily used for making final content model validation checks
- * and/or informing the FOEventHandler that the end of this FO
- * has been reached.
+ * Primarily used for making final content model validation checks
+ * and/or informing the FOEventHandler that the end of this FO
+ * has been reached.
+ * @throws FOPException if there's a problem during processing
*/
protected void endOfNode() throws FOPException {
// do nothing by default
}
/**
+ * Adds a node as a child of this node. The default implementation of this method
+ * just ignores any child node being added.
* @param child child node to be added to the childNodes of this node
+ * @throws FOPException if there's a problem during processing
*/
protected void addChildNode(FONode child) throws FOPException {
+ // do nothing by default
}
/**
@@ -260,9 +286,10 @@ public abstract class FONode implements Cloneable {
return "fox:" + localName;
} else if (namespaceURI.equals(SVGElementMapping.URI)) {
return "svg:" + localName;
- } else
- return "(Namespace URI: \"" + namespaceURI + "\", " +
- "Local Name: \"" + localName + "\")";
+ } else {
+ return "(Namespace URI: \"" + namespaceURI + "\", "
+ + "Local Name: \"" + localName + "\")";
+ }
}
/**
@@ -270,11 +297,12 @@ public abstract class FONode implements Cloneable {
* (e.g., not specifying either an internal- or an external-destination
* property for an FO:link)
* @param problem text to display that indicates the problem
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void attributeError(String problem)
- throws ValidationException {
- throw new ValidationException(errorText(locator) + getName() + ", " +
- problem, locator);
+ throws ValidationException {
+ throw new ValidationException(errorText(locator) + getName()
+ + ", " + problem, locator);
}
/**
@@ -283,7 +311,7 @@ public abstract class FONode implements Cloneable {
* @param problem text to display that indicates the problem
*/
protected void attributeWarning(String problem) {
- getLogger().warn(errorText(locator) + getName() + ", " + problem);
+ log.warn(errorText(locator) + getName() + ", " + problem);
}
/**
@@ -292,11 +320,12 @@ public abstract class FONode implements Cloneable {
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param nsURI namespace URI of incoming invalid node
* @param lName local name (i.e., no prefix) of incoming node
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void tooManyNodesError(Locator loc, String nsURI, String lName)
- throws ValidationException {
- throw new ValidationException(errorText(loc) + "For " + getName() +
- ", only one " + getNodeString(nsURI, lName) + " may be declared.",
+ throws ValidationException {
+ throw new ValidationException(errorText(loc) + "For " + getName()
+ + ", only one " + getNodeString(nsURI, lName) + " may be declared.",
loc);
}
@@ -306,11 +335,12 @@ public abstract class FONode implements Cloneable {
* This overrloaded method helps make the caller code better self-documenting
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param offendingNode incoming node that would cause a duplication.
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void tooManyNodesError(Locator loc, String offendingNode)
- throws ValidationException {
- throw new ValidationException(errorText(loc) + "For " + getName() +
- ", only one " + offendingNode + " may be declared.", loc);
+ throws ValidationException {
+ throw new ValidationException(errorText(loc) + "For " + getName()
+ + ", only one " + offendingNode + " may be declared.", loc);
}
/**
@@ -319,6 +349,7 @@ public abstract class FONode implements Cloneable {
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param tooLateNode string name of node that should be earlier in document
* @param tooEarlyNode string name of node that should be later in document
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void nodesOutOfOrderError(Locator loc, String tooLateNode,
String tooEarlyNode) throws ValidationException {
@@ -332,9 +363,10 @@ public abstract class FONode implements Cloneable {
* @param loc org.xml.sax.Locator object of the error (*not* parent node)
* @param nsURI namespace URI of incoming invalid node
* @param lName local name (i.e., no prefix) of incoming node
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void invalidChildError(Locator loc, String nsURI, String lName)
- throws ValidationException {
+ throws ValidationException {
invalidChildError(loc, nsURI, lName, null);
}
@@ -345,62 +377,71 @@ public abstract class FONode implements Cloneable {
* @param nsURI namespace URI of incoming invalid node
* @param lName local name (i.e., no prefix) of incoming node
* @param ruleViolated text explanation of problem
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void invalidChildError(Locator loc, String nsURI, String lName,
- String ruleViolated)
- throws ValidationException {
- throw new ValidationException(errorText(loc) + getNodeString(nsURI, lName) +
- " is not a valid child element of " + getName()
+ String ruleViolated)
+ throws ValidationException {
+ throw new ValidationException(errorText(loc) + getNodeString(nsURI, lName)
+ + " is not a valid child element of " + getName()
+ ((ruleViolated != null) ? ": " + ruleViolated : "."), loc);
}
/**
* Helper function to throw an error caused by missing mandatory child elements.
* E.g., fo:layout-master-set not having any page-master child element.
- * @param contentModel The XSL Content Model for the fo: object or a similar description indicating the necessary child elements.
+ * @param contentModel The XSL Content Model for the fo: object or a similar description
+ * indicating the necessary child elements.
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void missingChildElementError(String contentModel)
- throws ValidationException {
- throw new ValidationException(errorText(locator) + getName() +
- " is missing child elements. \nRequired Content Model: "
+ throws ValidationException {
+ throw new ValidationException(errorText(locator) + getName()
+ + " is missing child elements. \nRequired Content Model: "
+ contentModel, locator);
}
/**
* Helper function to throw an error caused by missing mandatory properties
* @param propertyName the name of the missing property.
+ * @throws ValidationException the validation error provoked by the method call
*/
protected void missingPropertyError(String propertyName)
- throws ValidationException {
- throw new ValidationException(errorText(locator) + getName() +
- " is missing required \"" + propertyName + "\" property.", locator);
+ throws ValidationException {
+ throw new ValidationException(errorText(locator) + getName()
+ + " is missing required \"" + propertyName + "\" property.", locator);
}
/**
- * Helper function to return "Error (line#/column#)" string for
+ * Helper function to return "Error(line#/column#)" string for
* above exception messages
* @param loc org.xml.sax.Locator object
* @return String opening error text
*/
protected static String errorText(Locator loc) {
- if (loc == null) {
- return "Error(Unknown location): ";
- } else {
- return "Error(" + loc.getLineNumber() + "/" + loc.getColumnNumber() + "): ";
- }
+ return "Error(" + getLocatorString(loc) + "): ";
}
/**
- * Helper function to return "Warning (line#/column#)" string for
+ * Helper function to return "Warning(line#/column#)" string for
* warning messages
* @param loc org.xml.sax.Locator object
* @return String opening warning text
*/
protected static String warningText(Locator loc) {
+ return "Warning(" + getLocatorString(loc) + "): ";
+ }
+
+ /**
+ * Helper function to format a Locator instance.
+ * @param loc org.xml.sax.Locator object
+ * @return String the formatted text
+ */
+ protected static String getLocatorString(Locator loc) {
if (loc == null) {
- return "Warning(Unknown location): ";
+ return "Unknown location";
} else {
- return "Warning(" + loc.getLineNumber() + "/" + loc.getColumnNumber() + "): ";
+ return loc.getLineNumber() + "/" + loc.getColumnNumber();
}
}
@@ -429,5 +470,16 @@ public abstract class FONode implements Cloneable {
return Constants.FO_UNKNOWN_NODE;
}
+ /**
+ * This method is overridden by extension elements and allows the extension element
+ * to return a pass-through attachment which the parent formatting objects should simply
+ * carry with them but otherwise ignore. This mechanism is used to pass non-standard
+ * information from the FO tree through to the layout engine and the renderers.
+ * @return the extension attachment if one is created by the extension element, null otherwise.
+ */
+ public ExtensionAttachment getExtensionAttachment() {
+ return null;
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java
index 0aa4f4758..58942036f 100644
--- a/src/java/org/apache/fop/fo/FOTreeBuilder.java
+++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java
@@ -135,6 +135,7 @@ public class FOTreeBuilder extends DefaultHandler {
addElementMapping("org.apache.fop.fo.extensions.svg.SVGElementMapping");
addElementMapping("org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping");
addElementMapping("org.apache.fop.fo.extensions.ExtensionElementMapping");
+ addElementMapping("org.apache.fop.render.ps.extensions.PSExtensionElementMapping");
// add mappings from available services
Iterator providers = Service.providers(ElementMapping.class);
diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java
index 3e82c2911..c96c4ecc7 100644
--- a/src/java/org/apache/fop/fo/FObj.java
+++ b/src/java/org/apache/fop/fo/FObj.java
@@ -18,6 +18,7 @@
package org.apache.fop.fo;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -26,6 +27,7 @@ import java.util.Set;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.PercentBase;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fo.flow.Marker;
import org.apache.fop.fo.properties.PropertyMaker;
import org.xml.sax.Attributes;
@@ -35,11 +37,16 @@ import org.xml.sax.Locator;
* Base class for representation of formatting objects and their processing.
*/
public abstract class FObj extends FONode implements Constants {
- public static PropertyMaker[] propertyListTable = null;
+
+ /** the list of property makers */
+ private static PropertyMaker[] propertyListTable = null;
/** The immediate child nodes of this node. */
- public List childNodes = null;
+ protected List childNodes = null;
+ /** The list of extension attachments, null if none */
+ private List extensionAttachments = null;
+
/** Used to indicate if this FO is either an Out Of Line FO (see rec)
or a descendant of one. Used during validateChildNode() FO
validation.
@@ -64,7 +71,7 @@ public abstract class FObj extends FONode implements Constants {
// determine if isOutOfLineFODescendant should be set
if (parent != null && parent instanceof FObj) {
- if (((FObj)parent).getIsOutOfLineFODescendant() == true) {
+ if (((FObj)parent).getIsOutOfLineFODescendant()) {
isOutOfLineFODescendant = true;
} else {
int foID = getNameId();
@@ -97,6 +104,15 @@ public abstract class FObj extends FONode implements Constants {
}
return fobj;
}
+
+ /**
+ * Returns the PropertyMaker for a given property ID.
+ * @param propId the property ID
+ * @return the requested Property Maker
+ */
+ public static PropertyMaker getPropertyMakerFor(int propId) {
+ return propertyListTable[propId];
+ }
/**
* @see org.apache.fop.fo.FONode#processNode
@@ -111,6 +127,7 @@ public abstract class FObj extends FONode implements Constants {
/**
* Create a default property list for this element.
+ * @see org.apache.fop.fo.FONode
*/
protected PropertyList createPropertyList(PropertyList parent,
FOEventHandler foEventHandler) throws FOPException {
@@ -122,7 +139,7 @@ public abstract class FObj extends FONode implements Constants {
* Must be overridden in all FObj subclasses that have properties
* applying to it.
* @param pList the PropertyList where the properties can be found.
- * @throws FOPException
+ * @throws FOPException if there is a problem binding the values
*/
public void bind(PropertyList pList) throws FOPException {
}
@@ -132,16 +149,18 @@ public abstract class FObj extends FONode implements Constants {
* Most formatting objects can have an id that can be referenced.
* This methods checks that the id isn't already used by another
* fo and sets the id attribute of this object.
+ * @param id ID to check
+ * @throws ValidationException if the ID is already defined elsewhere
*/
- protected void checkId(String id) throws ValidationException {
+ protected void checkId(String id) throws ValidationException {
if (!id.equals("")) {
Set idrefs = getFOEventHandler().getIDReferences();
if (!idrefs.contains(id)) {
idrefs.add(id);
} else {
- throw new ValidationException("Property id \"" + id +
- "\" previously used; id values must be unique" +
- " in document.", locator);
+ throw new ValidationException("Property id \"" + id
+ + "\" previously used; id values must be unique"
+ + " in document.", locator);
}
}
}
@@ -158,14 +177,20 @@ public abstract class FObj extends FONode implements Constants {
* @see org.apache.fop.fo.FONode#addChildNode(FONode)
*/
protected void addChildNode(FONode child) throws FOPException {
- if (PropertySets.canHaveMarkers(getNameId()) &&
- child.getNameId() == FO_MARKER) {
- addMarker((Marker) child);
+ if (PropertySets.canHaveMarkers(getNameId()) && child.getNameId() == FO_MARKER) {
+ addMarker((Marker)child);
} else {
- if (childNodes == null) {
- childNodes = new java.util.ArrayList();
+ ExtensionAttachment attachment = child.getExtensionAttachment();
+ if (attachment != null) {
+ //This removes the element from the normal children, so no layout manager
+ //is being created for them as they are only additional information.
+ addExtensionAttachment(attachment);
+ } else {
+ if (childNodes == null) {
+ childNodes = new java.util.ArrayList();
+ }
+ childNodes.add(child);
}
- childNodes.add(child);
}
}
@@ -194,6 +219,7 @@ public abstract class FObj extends FONode implements Constants {
* Assign the size of a layout dimension to the key.
* @param key the Layout dimension, from PercentBase.
* @param dimension The layout length.
+ * TODO Remove when possible!
*/
public void setLayoutDimension(PercentBase.LayoutDimension key, int dimension) {
if (layoutDimension == null) {
@@ -206,6 +232,7 @@ public abstract class FObj extends FONode implements Constants {
* Assign the size of a layout dimension to the key.
* @param key the Layout dimension, from PercentBase.
* @param dimension The layout length.
+ * TODO Remove when possible!
*/
public void setLayoutDimension(PercentBase.LayoutDimension key, float dimension) {
if (layoutDimension == null) {
@@ -218,6 +245,7 @@ public abstract class FObj extends FONode implements Constants {
* Return the size associated with the key.
* @param key The layout dimension key.
* @return the length.
+ * TODO Remove when possible!
*/
public Number getLayoutDimension(PercentBase.LayoutDimension key) {
if (layoutDimension != null) {
@@ -349,14 +377,14 @@ public abstract class FObj extends FONode implements Constants {
* @return true if a member, false if not
*/
protected boolean isBlockItem(String nsURI, String lName) {
- return (FO_URI.equals(nsURI) &&
- (lName.equals("block")
- || lName.equals("table")
- || lName.equals("table-and-caption")
- || lName.equals("block-container")
- || lName.equals("list-block")
- || lName.equals("float")
- || isNeutralItem(nsURI, lName)));
+ return (FO_URI.equals(nsURI)
+ && (lName.equals("block")
+ || lName.equals("table")
+ || lName.equals("table-and-caption")
+ || lName.equals("block-container")
+ || lName.equals("list-block")
+ || lName.equals("float")
+ || isNeutralItem(nsURI, lName)));
}
/**
@@ -368,21 +396,22 @@ public abstract class FObj extends FONode implements Constants {
* @return true if a member, false if not
*/
protected boolean isInlineItem(String nsURI, String lName) {
- return (FO_URI.equals(nsURI) &&
- (lName.equals("bidi-override")
- || lName.equals("character")
- || lName.equals("external-graphic")
- || lName.equals("instream-foreign-object")
- || lName.equals("inline")
- || lName.equals("inline-container")
- || lName.equals("leader")
- || lName.equals("page-number")
- || lName.equals("page-number-citation")
- || lName.equals("basic-link")
- || (lName.equals("multi-toggle")
- && (getNameId() == FO_MULTI_CASE || findAncestor(FO_MULTI_CASE) > 0))
- || (lName.equals("footnote") && !isOutOfLineFODescendant)
- || isNeutralItem(nsURI, lName)));
+ return (FO_URI.equals(nsURI)
+ && (lName.equals("bidi-override")
+ || lName.equals("character")
+ || lName.equals("external-graphic")
+ || lName.equals("instream-foreign-object")
+ || lName.equals("inline")
+ || lName.equals("inline-container")
+ || lName.equals("leader")
+ || lName.equals("page-number")
+ || lName.equals("page-number-citation")
+ || lName.equals("basic-link")
+ || (lName.equals("multi-toggle")
+ && (getNameId() == FO_MULTI_CASE
+ || findAncestor(FO_MULTI_CASE) > 0))
+ || (lName.equals("footnote") && !isOutOfLineFODescendant)
+ || isNeutralItem(nsURI, lName)));
}
/**
@@ -406,12 +435,12 @@ public abstract class FObj extends FONode implements Constants {
* @return true if a member, false if not
*/
protected boolean isNeutralItem(String nsURI, String lName) {
- return (FO_URI.equals(nsURI) &&
- (lName.equals("multi-switch")
- || lName.equals("multi-properties")
- || lName.equals("wrapper")
- || (!isOutOfLineFODescendant && lName.equals("float"))
- || lName.equals("retrieve-marker")));
+ return (FO_URI.equals(nsURI)
+ && (lName.equals("multi-switch")
+ || lName.equals("multi-properties")
+ || lName.equals("wrapper")
+ || (!isOutOfLineFODescendant && lName.equals("float"))
+ || lName.equals("retrieve-marker")));
}
/**
@@ -433,5 +462,33 @@ public abstract class FObj extends FONode implements Constants {
}
return -1;
}
+
+ /**
+ * Add a new extension attachment to this FObj. See org.apache.fop.fo.FONode for details.
+ * @param attachment the attachment to add.
+ */
+ public void addExtensionAttachment(ExtensionAttachment attachment) {
+ if (attachment == null) {
+ throw new NullPointerException("Parameter attachment must not be null");
+ }
+ if (extensionAttachments == null) {
+ extensionAttachments = new java.util.ArrayList();
+ }
+ if (log.isDebugEnabled()) {
+ getLogger().debug("ExtensionAttachment of category " + attachment.getCategory()
+ + " added to " + getName() + ": " + attachment);
+ }
+ extensionAttachments.add(attachment);
+ }
+
+ /** @return the extension attachments of this FObj. */
+ public List getExtensionAttachments() {
+ if (extensionAttachments == null) {
+ return Collections.EMPTY_LIST;
+ } else {
+ return extensionAttachments;
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java
index 64553c156..09545055a 100644
--- a/src/java/org/apache/fop/fo/PropertyList.java
+++ b/src/java/org/apache/fop/fo/PropertyList.java
@@ -452,7 +452,7 @@ abstract public class PropertyList {
if (propId < 1 || propId > Constants.PROPERTY_COUNT) {
return null;
} else {
- return FObj.propertyListTable[propId];
+ return FObj.getPropertyMakerFor(propId);
}
}
diff --git a/src/java/org/apache/fop/fo/extensions/ExtensionAttachment.java b/src/java/org/apache/fop/fo/extensions/ExtensionAttachment.java
new file mode 100644
index 000000000..2a611f74e
--- /dev/null
+++ b/src/java/org/apache/fop/fo/extensions/ExtensionAttachment.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.fo.extensions;
+
+/**
+ * This interface is implemented by objects that are returned by special extension element
+ * through the FONode.getExtensionAttachment() method. Such objects are carried in the FO tree
+ * and made available to the layout managers that support processing extension attachments or
+ * support passing them on to the area tree where they can be picked up by renderers.
+ * <p>
+ * NOTE: Classes which implement this interface need to be Serializable!
+ */
+public interface ExtensionAttachment {
+
+ /**
+ * This method returns a category URI that allows a processor (layout manager or renderer)
+ * to determine if it supports this object.
+ * @return the category URI
+ */
+ String getCategory();
+
+}
diff --git a/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
index 62d9371e4..cfe90d07f 100644
--- a/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
+++ b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
@@ -327,4 +327,10 @@ public class InstreamForeignObject extends FObj {
protected void addChildNode(FONode child) throws FOPException {
super.addChildNode(child);
}
+
+ /** @return the XMLObj child node of the instream-foreign-object. */
+ public XMLObj getChildXMLObj() {
+ return (XMLObj) childNodes.get(0);
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/pagination/Declarations.java b/src/java/org/apache/fop/fo/pagination/Declarations.java
index 110f8e2a8..57f1fd825 100644
--- a/src/java/org/apache/fop/fo/pagination/Declarations.java
+++ b/src/java/org/apache/fop/fo/pagination/Declarations.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ package org.apache.fop.fo.pagination;
// Java
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import org.xml.sax.Locator;
@@ -30,8 +29,6 @@ import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
-import org.apache.fop.fo.XMLObj;
-
/**
* Declarations formatting object.
@@ -43,7 +40,6 @@ import org.apache.fop.fo.XMLObj;
public class Declarations extends FObj {
private Map colorProfiles = null;
- private List external = null;
/**
* @param parent FONode that is the parent of this object
@@ -62,11 +58,11 @@ public class Declarations extends FObj {
/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
- XSL 1.0: (color-profile)+ (and non-XSL NS nodes)
- FOP/XSL 1.1: (color-profile)* (and non-XSL NS nodes)
+ * XSL 1.0: (color-profile)+ (and non-XSL NS nodes)
+ * FOP/XSL 1.1: (color-profile)* (and non-XSL NS nodes)
*/
protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
+ throws ValidationException {
if (FO_URI.equals(nsURI)) {
if (!localName.equals("color-profile")) {
invalidChildError(loc, nsURI, localName);
@@ -75,8 +71,9 @@ public class Declarations extends FObj {
}
/**
- * At the end of this element sort out the child into
- * a hashmap of color profiles and a list of external xml.
+ * At the end of this element sort out the children into
+ * a hashmap of color profiles and a list of extension attachments.
+ * @see org.apache.fop.fo.FONode#endOfNode()
*/
protected void endOfNode() throws FOPException {
if (childNodes != null) {
@@ -97,13 +94,9 @@ public class Declarations extends FObj {
} else {
getLogger().warn("color-profile-name required for color profile");
}
- } else if (node instanceof XMLObj) {
- if (external == null) {
- external = new java.util.ArrayList();
- }
- external.add(node);
} else {
- getLogger().warn("invalid element " + node.getName() + " inside declarations");
+ getLogger().debug("Ignoring element " + node.getName()
+ + " inside fo:declarations.");
}
}
}
diff --git a/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java b/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java
index ee7bcce1c..47e7a1e53 100644
--- a/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java
+++ b/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java
@@ -106,8 +106,8 @@ public class SimplePageMaster extends FObj {
*/
protected void endOfNode() throws FOPException {
if (!hasRegionBody) {
- missingChildElementError("(region-body, region-before?," +
- " region-after?, region-start?, region-end?)");
+ missingChildElementError(
+ "(region-body, region-before?, region-after?, region-start?, region-end?)");
}
}
@@ -182,8 +182,12 @@ public class SimplePageMaster extends FObj {
/**
* @see org.apache.fop.fo.FONode#addChildNode(FONode)
*/
- protected void addChildNode(FONode child) {
- addRegion((Region)child);
+ protected void addChildNode(FONode child) throws FOPException {
+ if (child instanceof Region) {
+ addRegion((Region)child);
+ } else {
+ super.addChildNode(child);
+ }
}
/**
@@ -229,45 +233,32 @@ public class SimplePageMaster extends FObj {
return false;
}
- /**
- * Return the Common Margin Properties-Block.
- */
+ /** @return the Common Margin Properties-Block. */
public CommonMarginBlock getCommonMarginBlock() {
return commonMarginBlock;
}
- /**
- * Return "master-name" property.
- */
+ /** @return "master-name" property. */
public String getMasterName() {
return masterName;
}
- /**
- * Return the "page-width" property.
- */
+ /** @return the "page-width" property. */
public Length getPageWidth() {
return pageWidth;
}
- /**
- * Return the "page-height" property.
- */
+ /** @return the "page-height" property. */
public Length getPageHeight() {
return pageHeight;
}
-
- /**
- * Return the "writing-mode" property.
- */
+ /** @return the "writing-mode" property. */
public int getWritingMode() {
return writingMode;
}
- /**
- * Return the "reference-orientation" property.
- */
+ /** @return the "reference-orientation" property. */
public int getReferenceOrientation() {
return referenceOrientation.getValue();
}