--- /dev/null
+/*
+ * Copyright 2004-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.area;
+
+/**
+ * Abstract base class for objects that are processed by the renderer outside
+ * of the actual document.
+ * This object can be handled by the renderer according to these
+ * possibilities: IMMEDIATELY, AFTER_PAGE, START_OF_DOC or END_OF_DOC.
+ */
+public abstract class AbstractOffDocumentItem implements OffDocumentItem {
+
+ /**
+ * Process this extension immediately when
+ * being handled by the area tree.
+ */
+ public static final int IMMEDIATELY = 0;
+
+ /**
+ * Process this extension after the next page is rendered
+ * or prepared when being handled by the area tree.
+ */
+ public static final int AFTER_PAGE = 1;
+
+ /**
+ * Process this extension at the end of the document once
+ * all pages have been fully rendered.
+ */
+ public static final int END_OF_DOC = 2;
+
+ /**
+ * Process this extension at the start of the document right
+ * before the first page-sequence is processed.
+ */
+ public static final int START_OF_DOC = 2;
+
+
+ /** Indicates in what phase the item should be processed. */
+ protected int whenToProcess = IMMEDIATELY;
+
+ /**
+ * Get an indicator of when this item should be processed
+ * @return int constant (IMMEDIATELY, AFTER_PAGE, START_OF_DOC, END_OF_DOC)
+ */
+ public int getWhenToProcess() {
+ return whenToProcess;
+ }
+
+ /**
+ * Return a human-readable name for this ODI (for error messages, etc.)
+ * @return String name of ODI
+ */
+ public abstract String getName();
+}
*/
/* $Id$ */
+
package org.apache.fop.area;
// Java
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FormattingResults;
import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.Root;
import org.apache.fop.fo.pagination.bookmarks.BookmarkTree;
}
}
+ /** @see org.apache.fop.fo.FOEventHandler */
+ public void startPageSequence(PageSequence pageSequence) {
+ rootFObj = pageSequence.getRoot();
+
+ //extension attachments from fo:root
+ wrapAndAddExtensionAttachments(rootFObj.getExtensionAttachments());
+ //extension attachments from fo:declarations
+ if (rootFObj.getDeclarations() != null) {
+ wrapAndAddExtensionAttachments(rootFObj.getDeclarations().getExtensionAttachments());
+ }
+ }
+
+ private void wrapAndAddExtensionAttachments(List list) {
+ Iterator i = list.iterator();
+ while (i.hasNext()) {
+ ExtensionAttachment attachment = (ExtensionAttachment)i.next();
+ addOffDocumentItem(new OffDocumentExtensionAttachment(attachment));
+ }
+ }
+
/**
* End the PageSequence.
* The PageSequence formats Pages and adds them to the AreaTree.
log.debug("Current heap size: " + (memoryNow / 1024L) + "Kb");
}
- rootFObj = pageSequence.getRoot();
-
// If no main flow, nothing to layout!
if (pageSequence.getMainFlow() != null) {
PageSequenceLayoutManager pageSLM;
}
}
+ /**
+ * Called by the PageSequenceLayoutManager when it is finished with a page-sequence.
+ * @param pageSequence the page-sequence just finished
+ * @param pageCount The number of pages generated for the page-sequence
+ */
public void notifyPageSequenceFinished(PageSequence pageSequence,
int pageCount) {
this.results.haveFormattedPageSequence(pageSequence,
/*
- * 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.
* its child bookmark-items, or a bookmark-item and the child
* child bookmark-items under it.
*/
-public class BookmarkData extends OffDocumentItem implements Resolvable {
+public class BookmarkData extends AbstractOffDocumentItem implements Resolvable {
private ArrayList subData = new ArrayList();
// bookmark-title for this fo:bookmark
--- /dev/null
+/*
+ * 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.area;
+
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+
+/**
+ * This class wraps ExtensionAttachments which cannot be transported inside the area tree but
+ * need to be handled in the AreaTreeHandler. These attachments are schedules for processing
+ * before the first page-sequence, i.e. at the start of the document.
+ */
+public class OffDocumentExtensionAttachment implements OffDocumentItem {
+
+ private ExtensionAttachment attachment;
+
+ /**
+ * Main constructor
+ * @param attachment the extension attachment to wrap.
+ */
+ public OffDocumentExtensionAttachment(ExtensionAttachment attachment) {
+ this.attachment = attachment;
+ }
+
+ /** @return the extension attachment. */
+ public ExtensionAttachment getAttachment() {
+ return this.attachment;
+ }
+
+ /** @see org.apache.fop.area.OffDocumentItem#getWhenToProcess() */
+ public int getWhenToProcess() {
+ return OffDocumentItem.IMMEDIATELY;
+ }
+
+ /** @see org.apache.fop.area.OffDocumentItem#getName() */
+ public String getName() {
+ return attachment.getCategory();
+ }
+
+}
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 2004-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.
package org.apache.fop.area;
/**
- * Abstract base class for objects that are processed by the renderer outside
+ * Interface for objects that are processed by the renderer outside
* of the actual document.
- * This object can be handled by the renderer according to three
- * possibilities, IMMEDIATELY, AFTER_PAGE, or END_OF_DOC.
+ * An object implementing this interface can be handled by the renderer according to these
+ * possibilities: IMMEDIATELY, AFTER_PAGE or END_OF_DOC.
*/
-public abstract class OffDocumentItem {
+public interface OffDocumentItem {
/**
* Process this extension immediately when
* being handled by the area tree.
*/
- public static final int IMMEDIATELY = 0;
+ int IMMEDIATELY = 0;
/**
* Process this extension after the next page is rendered
* or prepared when being handled by the area tree.
*/
- public static final int AFTER_PAGE = 1;
+ int AFTER_PAGE = 1;
/**
* Process this extension at the end of the document once
* all pages have been fully rendered.
*/
- public static final int END_OF_DOC = 2;
+ int END_OF_DOC = 2;
-
- protected int whenToProcess = IMMEDIATELY;
/**
* Get an indicator of when this item should be processed
* @return int constant (IMMEDIATELY, AFTER_PAGE, END_OF_DOC)
*/
- public int getWhenToProcess() {
- return whenToProcess;
- }
+ int getWhenToProcess();
/**
* Return a human-readable name for this ODI (for error messages, etc.)
* @return String name of ODI
*/
- public abstract String getName();
+ String getName();
+
}
* 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
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;
* 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
* @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);
protected Object clone() {
try {
return super.clone();
- } catch (CloneNotSupportedException e) { }
- return null;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
}
/**
}
}
+ /** @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.
* @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) : ""));
+ }
}
/**
* @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;
}
* 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)
}
/**
- *
- */
+ * 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
}
/**
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 + "\")";
+ }
}
/**
* (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);
}
/**
* @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);
}
/**
* @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);
}
* 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);
}
/**
* @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 {
* @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);
}
* @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();
}
}
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;
+ }
+
}
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);
package org.apache.fop.fo;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
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;
* 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.
// 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();
}
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
/**
* Create a default property list for this element.
+ * @see org.apache.fop.fo.FONode
*/
protected PropertyList createPropertyList(PropertyList parent,
FOEventHandler foEventHandler) throws FOPException {
* 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 {
}
* 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);
}
}
}
* @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);
}
}
* 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) {
* 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) {
* 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) {
* @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)));
}
/**
* @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)));
}
/**
* @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")));
}
/**
}
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;
+ }
+ }
+
}
if (propId < 1 || propId > Constants.PROPERTY_COUNT) {
return null;
} else {
- return FObj.propertyListTable[propId];
+ return FObj.getPropertyMakerFor(propId);
}
}
--- /dev/null
+/*
+ * 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();
+
+}
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);
+ }
+
}
/*
- * 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.
// Java
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import org.xml.sax.Locator;
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.
public class Declarations extends FObj {
private Map colorProfiles = null;
- private List external = null;
/**
* @param parent FONode that is the parent of this object
/**
* @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);
}
/**
- * 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) {
} 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.");
}
}
}
*/
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?)");
}
}
/**
* @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);
+ }
}
/**
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();
}
* @return the viewport inline area
*/
private Viewport getInlineArea() {
- XMLObj child = (XMLObj) fobj.childNodes.get(0);
+ XMLObj child = (XMLObj) fobj.getChildXMLObj();
// viewport size is determined by block-progression-dimension
// and inline-progression-dimension
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import java.io.LineNumberReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import org.apache.fop.area.Area;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.CTM;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.OffDocumentExtensionAttachment;
+import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait;
import org.apache.fop.datatypes.ColorType;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.image.EPSImage;
import org.apache.fop.image.XMLImage;
import org.apache.fop.render.AbstractPathOrientedRenderer;
import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.ps.extensions.PSSetupCode;
import org.apache.fop.util.CharUtilities;
import org.w3c.dom.Document;
private boolean ioTrouble = false;
private boolean inTextMode = false;
+ private boolean firstPageSequenceReceived = false;
+ /** Used to temporarily store PSSetupCode instance until they can be written. */
+ private List setupCodeList;
+
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
*/
gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS);
gen.writeDSCComment(DSCConstants.END_DEFAULTS);
- //Prolog
- gen.writeDSCComment(DSCConstants.BEGIN_PROLOG);
- PSProcSets.writeFOPStdProcSet(gen);
- PSProcSets.writeFOPEPSProcSet(gen);
- gen.writeDSCComment(DSCConstants.END_PROLOG);
-
- //Setup
- gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
- PSProcSets.writeFontDict(gen, fontInfo);
- gen.writeln("FOPFonts begin");
- gen.writeDSCComment(DSCConstants.END_SETUP);
+ //Prolog and Setup written right before the first page-sequence, see startPageSequence()
}
/**
gen.flush();
}
+ /** @see org.apache.fop.render.Renderer */
+ public void processOffDocumentItem(OffDocumentItem oDI) {
+ log.debug("Handling OffDocumentItem: " + oDI.getName());
+ if (oDI instanceof OffDocumentExtensionAttachment) {
+ ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment();
+ if (PSSetupCode.CATEGORY.equals(attachment.getCategory())) {
+ PSSetupCode setupCode = (PSSetupCode)attachment;
+ if (setupCodeList == null) {
+ setupCodeList = new java.util.ArrayList();
+ }
+ setupCodeList.add(setupCode);
+ }
+ }
+ super.processOffDocumentItem(oDI);
+ }
+
+ /** @see org.apache.fop.render.Renderer#startPageSequence(org.apache.fop.area.LineArea) */
+ public void startPageSequence(LineArea seqTitle) {
+ super.startPageSequence(seqTitle);
+ if (!firstPageSequenceReceived) {
+ //Do this only once, as soon as we have all the content for the Setup section!
+ try {
+ //Prolog
+ gen.writeDSCComment(DSCConstants.BEGIN_PROLOG);
+ PSProcSets.writeFOPStdProcSet(gen);
+ PSProcSets.writeFOPEPSProcSet(gen);
+ gen.writeDSCComment(DSCConstants.END_PROLOG);
+
+ //Setup
+ gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
+ writeSetupCodeList(setupCodeList, "SetupCode");
+ PSProcSets.writeFontDict(gen, fontInfo);
+ gen.writeln("FOPFonts begin");
+ gen.writeDSCComment(DSCConstants.END_SETUP);
+ } catch (IOException ioe) {
+ handleIOTrouble(ioe);
+ }
+
+ firstPageSequenceReceived = true;
+ }
+ }
+
+ /**
+ * Formats and writes a List of PSSetupCode instances to the output stream.
+ * @param setupCodeList a List of PSSetupCode instances
+ * @param type the type of code section
+ */
+ private void writeSetupCodeList(List setupCodeList, String type) throws IOException {
+ if (setupCodeList != null) {
+ Iterator i = setupCodeList.iterator();
+ while (i.hasNext()) {
+ PSSetupCode setupCode = (PSSetupCode)i.next();
+ gen.commentln("%FOPBegin" + type + ": ("
+ + (setupCode.getName() != null ? setupCode.getName() : "")
+ + ")");
+ LineNumberReader reader = new LineNumberReader(
+ new java.io.StringReader(setupCode.getContent()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ gen.writeln(line.trim());
+ }
+ }
+ gen.commentln("%FOPEnd" + type);
+ i.remove();
+ }
+ }
+ }
+
/**
* @see org.apache.fop.render.Renderer#renderPage(PageViewport)
*/
}
gen.writeDSCComment(DSCConstants.PAGE_RESOURCES,
new Object[] {PSGenerator.ATEND});
+ gen.commentln("%FOPSimplePageMaster: " + page.getSPM().getMasterName());
gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP);
+
+ //Handle PSSetupCode instances on simple-page-master
+ if (page.getSPM().getExtensionAttachments().size() > 0) {
+ List list = new java.util.ArrayList();
+ //Extract all PSSetupCode instances from the attachment list on the s-p-m
+ Iterator i = page.getSPM().getExtensionAttachments().iterator();
+ while (i.hasNext()) {
+ ExtensionAttachment attachment = (ExtensionAttachment)i.next();
+ if (PSSetupCode.CATEGORY.equals(attachment.getCategory())) {
+ list.add(attachment);
+ }
+ }
+ writeSetupCodeList(list, "PageSetupCode");
+ }
+
if (rotate) {
gen.writeln(Math.round(pspageheight) + " 0 translate");
gen.writeln("90 rotate");
+ Math.round(pspageheight) + "]");
gen.writeln("/ImagingBBox null");
gen.writeln(">> setpagedevice");
- //gen.writeln("0.001 0.001 scale");
concatMatrix(1, 0, 0, -1, 0, pageheight / 1000f);
gen.writeDSCComment(DSCConstants.END_PAGE_SETUP);
--- /dev/null
+/*
+ * 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.render.ps.extensions;
+
+// FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+/**
+ * Base class for the PostScript-specific extension elements.
+ */
+public abstract class AbstractPSExtensionObject extends FONode {
+
+ private PSSetupCode setupCode = new PSSetupCode();
+
+ /**
+ * @see org.apache.fop.fo.FONode#FONode(FONode)
+ */
+ public AbstractPSExtensionObject(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+ * here, blocks XSL FO's from having non-FO parents.
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI)) {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode */
+ protected void addCharacters(char[] data, int start, int length,
+ PropertyList pList, Locator locator) {
+ if (setupCode.getContent() != null) {
+ StringBuffer sb = new StringBuffer(setupCode.getContent());
+ sb.append(data, start, length - start);
+ setupCode.setContent(sb.toString());
+ } else {
+ setupCode.setContent(new String(data, start, length - start));
+ }
+ }
+
+ /** @see org.apache.fop.fo.XMLObj#getNameSpace() */
+ public String getNameSpace() {
+ return PSExtensionElementMapping.NAMESPACE;
+ }
+
+ /** @see org.apache.fop.fo.FONode#processNode */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList propertyList)
+ throws FOPException {
+ String name = attlist.getValue("name");
+ if (name != null && name.length() > 0) {
+ setupCode.setName(name);
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode#endOfNode() */
+ protected void endOfNode() throws FOPException {
+ super.endOfNode();
+ String s = setupCode.getContent();
+ if (s == null || s.length() == 0) {
+ missingChildElementError("#PCDATA");
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
+ public ExtensionAttachment getExtensionAttachment() {
+ return this.setupCode;
+ }
+}
+
--- /dev/null
+/*
+ * 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.render.ps.extensions;
+
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ElementMapping;
+
+/**
+ * This class provides the element mapping for the PostScript-specific extensions.
+ */
+public class PSExtensionElementMapping extends ElementMapping {
+
+ /** Namespace for the extension */
+ public static final String NAMESPACE = "http://xmlgraphics.apache.org/fop/postscript";
+
+ /** Main constructor */
+ public PSExtensionElementMapping() {
+ this.namespaceURI = NAMESPACE;
+ }
+
+ /** @see org.apache.fop.fo.ElementMapping#initialize() */
+ protected void initialize() {
+ if (foObjs == null) {
+ foObjs = new java.util.HashMap();
+ foObjs.put("ps-setup-code", new PSSetupCodeMaker());
+ foObjs.put("ps-page-setup-code", new PSPageSetupCodeMaker());
+ }
+ }
+
+ static class PSSetupCodeMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PSSetupCodeElement(parent);
+ }
+ }
+
+ static class PSPageSetupCodeMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PSPageSetupCodeElement(parent);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.render.ps.extensions;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * Extension element for fox:ps-page-setup-code.
+ */
+public class PSPageSetupCodeElement extends AbstractPSExtensionObject {
+
+ /**
+ * Main constructor
+ * @param parent parent FO node
+ */
+ public PSPageSetupCodeElement(FONode parent) {
+ super(parent);
+ }
+
+ /** @see org.apache.fop.fo.FONode#startOfNode() */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
+ throw new ValidationException(getName() + " must be a child of fo:simple-page-master.");
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode#getName() */
+ public String getName() {
+ return "fox:ps-page-setup-code";
+ }
+
+}
--- /dev/null
+/*
+ * 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.render.ps.extensions;
+
+import java.io.Serializable;
+
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+
+/**
+ * This is the pass-through value object for the PostScript extension.
+ */
+public class PSSetupCode implements ExtensionAttachment, Serializable {
+
+ /** The category URI for this extension attachment. */
+ public static final String CATEGORY = "apache:fop:extensions:postscript";
+
+ private String name;
+ private String content;
+
+ /**
+ * No-argument contructor.
+ */
+ public PSSetupCode() {
+ //nop
+ }
+
+ /**
+ * Default constructor.
+ * @param name the name of the setup code object, may be null
+ * @param content the content of the setup code object
+ */
+ public PSSetupCode(String name, String content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ /** @return the content */
+ public String getContent() {
+ return content;
+ }
+
+ /**
+ * Sets the content for the setup code object.
+ * @param content The content to set.
+ */
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ /** @return the name */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the setup code object.
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /** @see org.apache.fop.fo.extensions.ExtensionAttachment#getCategory() */
+ public String getCategory() {
+ return CATEGORY;
+ }
+
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return "PSSetupCode(name=" + getName() + ")";
+ }
+}
--- /dev/null
+/*
+ * 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.render.ps.extensions;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * Extension element for fox:ps-setup-code.
+ */
+public class PSSetupCodeElement extends AbstractPSExtensionObject {
+
+ /**
+ * Main constructor
+ * @param parent parent FO node
+ */
+ public PSSetupCodeElement(FONode parent) {
+ super(parent);
+ }
+
+ /** @see org.apache.fop.fo.FONode#startOfNode() */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ if (parent.getNameId() != Constants.FO_DECLARATIONS) {
+ throw new ValidationException(getName() + " must be a child of fo:declarations.");
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode#getName() */
+ public String getName() {
+ return "fox:ps-setup-code";
+ }
+
+}