/** the XSL-FO namespace URI */
protected static final String FO_URI = FOElementMapping.URI;
+ /** FOP's proprietary extension namespace URI */
protected static final String FOX_URI = ExtensionElementMapping.URI;
/** Parent FO node */
/**
* Checks to make sure, during SAX processing of input document, that the
* 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
+ * see that <code>fo:table</code> is not an immediate child of <code>fo:root</code>)
+ * called from {@link FOTreeBuilder#startElement(String, String, String, Attributes)}
+ * before constructing the child {@link FObj}.
+ *
* @param loc location in the FO source file
* @param namespaceURI namespace of incoming node
- * @param localName (e.g. "table" for "fo:table")
+ * @param localName name of the incoming node (without namespace prefix)
* @throws ValidationException if incoming node not valid for parent
*/
protected void validateChildNode(Locator loc, String namespaceURI, String localName)
//nop
}
+ /**
+ * Static version of {@link FONode#validateChildNode(Locator, String, String)} that
+ * can be used by subclasses that need to validate children against a different node
+ * (for example: <code>fo:wrapper</code> needs to check if the incoming node is a
+ * valid child to its parent)
+ *
+ * @param fo the FONode to validate against
+ * @param loc location in the source file
+ * @param namespaceURI namespace of the incoming node
+ * @param localName name of the incoming node (without namespace prefix)
+ * @throws ValidationException if the incoming node is not a valid child for the given FO
+ */
+ protected static void validateChildNode(
+ FONode fo,
+ Locator loc,
+ String namespaceURI,
+ String localName)
+ throws ValidationException {
+ fo.validateChildNode(loc, namespaceURI, localName);
+ }
+
/**
* Adds characters (does nothing here)
* @param data array of characters containing text to be added
}
/**
- * Returns the Constants class integer value of this node
- * @return the integer enumeration of this FO (e.g., FO_ROOT)
+ * Returns the {@link Constants} class integer value of this node
+ * @return the integer enumeration of this FO (e.g. FO_ROOT)
* if a formatting object, FO_UNKNOWN_NODE otherwise
*/
public int getNameId() {
}
}
+ /**
+ * This method is used when adding child nodes to a FO that already
+ * contains at least one child. In this case, the new child becomes a
+ * sibling to the previous one
+ *
+ * @param precedingSibling the previous child
+ * @param followingSibling the new child
+ */
protected static void attachSiblings(FONode precedingSibling,
FONode followingSibling) {
if (precedingSibling.siblings == null) {
* @return the last node in the list
* @throws NoSuchElementException if the list is empty
*/
- public FONode lastNode();
+ public FONode lastNode();
}
}
// used for FO validation
private boolean blockOrInlineItemFound = false;
- private boolean isFlowChild = false;
+ private boolean inlineChildrenAllowed = false;
/**
* @param parent FONode that is the parent of this object
*/
public Wrapper(FONode parent) {
super(parent);
- /* Check if the fo:wrapper is a child of an fo:flow or fo:static-content
+ /* Check if the fo:wrapper is a child of a FO that allows mixed content
* (or a descendant in nested fo:wrapper sequence, the first of which
- * is a child of an fo:flow or fo:static-content */
+ * is a child of a FO that allows mixed content) */
FONode ancestor = this.parent;
- while (!(ancestor instanceof Flow)
- && ancestor instanceof Wrapper) {
+ while (ancestor instanceof Wrapper) {
ancestor = ancestor.getParent();
}
- if (ancestor instanceof Flow) {
- this.isFlowChild = true;
+ if (ancestor instanceof FObjMixed ) {
+ inlineChildrenAllowed = true;
}
}
/**
* {@inheritDoc}
- * XSL Content Model: marker* (#PCDATA|%inline;|%block;)*
- * Additionally (unimplemented): "An fo:wrapper that is a child of an
+ * <br>XSL Content Model: marker* (#PCDATA|%inline;|%block;)*
+ * <br><i>Additionally (unimplemented): "An fo:wrapper that is a child of an
* fo:multi-properties is only permitted to have children that would
- * be permitted in place of the fo:multi-properties."
+ * be permitted in place of the fo:multi-properties."</i>
*
*/
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
- if (FO_URI.equals(nsURI) && localName.equals("marker")) {
+ if (FO_URI.equals(nsURI) && "marker".equals(localName)) {
if (blockOrInlineItemFound) {
nodesOutOfOrderError(loc, "fo:marker",
"(#PCDATA|%inline;|%block;)");
}
} else if (isBlockOrInlineItem(nsURI, localName)) {
- if (isFlowChild
- && isInlineItem(nsURI, localName)
- && !isNeutralItem(nsURI, localName)) {
- invalidChildError(loc, nsURI, localName,
- "fo:" + localName + " not allowed as child of an fo:wrapper "
- + "that is a child of an fo:flow or fo:static-content");
- }
+ //delegate validation to parent
+ FONode.validateChildNode(this.parent, loc, nsURI, localName);
blockOrInlineItemFound = true;
} else {
invalidChildError(loc, nsURI, localName);
int end,
PropertyList pList,
Locator locator) throws FOPException {
- /* Only add text if the fo:wrapper is not a child of an fo:flow
- * or fo:static-content */
- if (!this.isFlowChild) {
+ /* Only add text if the fo:wrapper's parent allows inline children */
+ if (this.inlineChildrenAllowed) {
super.addCharacters(data, start, end, pList, locator);
}
}