if (childNodes == null) {
missingChildElementError("(simple-page-master|page-sequence-master)+");
}
+ checkRegionNames();
+ }
+
+ /**
+ * Section 7.25.7: check to see that if a region-name is a
+ * duplicate, that it maps to the same fo region-class.
+ * @throws SAXParseException if there's a name duplication
+ */
+ private void checkRegionNames() throws SAXParseException {
+ // (user-entered) region-name to default region map.
+ Map allRegions = new java.util.HashMap();
+ for (Iterator spm = simplePageMasters.values().iterator();
+ spm.hasNext();) {
+ SimplePageMaster simplePageMaster =
+ (SimplePageMaster)spm.next();
+ Map spmRegions = simplePageMaster.getRegions();
+ for (Iterator e = spmRegions.values().iterator();
+ e.hasNext();) {
+ Region region = (Region) e.next();
+ if (allRegions.containsKey(region.getRegionName())) {
+ String defaultRegionName =
+ (String) allRegions.get(region.getRegionName());
+ if (!defaultRegionName.equals(region.getDefaultRegionName())) {
+ throw new SAXParseException("Region-name ("
+ + region.getRegionName()
+ + ") is being mapped to multiple "
+ + "region-classes ("
+ + defaultRegionName + " and "
+ + region.getDefaultRegionName()
+ + ")", locator);
+ }
+ }
+ allRegions.put(region.getRegionName(),
+ region.getDefaultRegionName());
+ }
+ }
}
/**
return (PageSequenceMaster)this.pageSequenceMasters.get(masterName);
}
- /**
- * Section 7.25.7: check to see that if a region-name is a
- * duplicate, that it maps to the same fo region-class.
- * @throws SAXParseException if there's a name duplication
- */
- public void checkRegionNames() throws SAXParseException {
- // (user-entered) region-name to default region map.
- Map allRegions = new java.util.HashMap();
- for (Iterator spm = simplePageMasters.values().iterator();
- spm.hasNext();) {
- SimplePageMaster simplePageMaster =
- (SimplePageMaster)spm.next();
- Map spmRegions = simplePageMaster.getRegions();
- for (Iterator e = spmRegions.values().iterator();
- e.hasNext();) {
- Region region = (Region) e.next();
- if (allRegions.containsKey(region.getRegionName())) {
- String defaultRegionName =
- (String) allRegions.get(region.getRegionName());
- if (!defaultRegionName.equals(region.getDefaultRegionName())) {
- throw new SAXParseException("Region-name ("
- + region.getRegionName()
- + ") is being mapped to multiple "
- + "region-classes ("
- + defaultRegionName + " and "
- + region.getDefaultRegionName()
- + ")", locator);
- }
- }
- allRegions.put(region.getRegionName(),
- region.getDefaultRegionName());
- }
- }
- }
-
/**
* Checks whether or not a region name exists in this master set.
* @param regionName name of the region
import org.xml.sax.SAXParseException;
// FOP
-import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
*/
public class PageSequence extends FObj {
//
- // intial-page-number types
+ // initial-page-number types
//
public static final int EXPLICIT = 0;
public static final int AUTO = 1;
public static final int AUTO_EVEN = 2;
public static final int AUTO_ODD = 3;
- //
- // associations
- //
/**
* The parent root object
*/
*/
public HashMap flowMap;
- // according to communication from Paul Grosso (XSL-List,
- // 001228, Number 406), confusion in spec section 6.4.5 about
- // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
- // fo:flow per fo:page-sequence only.
-// private boolean isFlowSet = false;
+// private boolean isFlowSet = false;
// for structure handler
private boolean sequenceStarted = false;
public PageSequenceMaster pageSequenceMaster;
/**
- * The main content flow for this page-sequence.
+ * The fo:title object for this page-sequence.
*/
- private Flow mainFlow = null;
+ private Title titleFO;
/**
- * The fo:title object for this page-sequence.
+ * The fo:flow object for this page-sequence.
*/
- private Title titleFO;
+ private Flow mainFlow = null;
/**
* Create a page sequence FO node.
super(parent);
}
- /**
- * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
- XSL Content Model: (title?,static-content*,flow)
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws SAXParseException {
- if (nsURI == FO_URI) {
- if (localName.equals("title")) {
- if (titleFO != null) {
- tooManyNodesError(loc, "fo:title");
- } else if (flowMap.size() > 0) {
- nodesOutOfOrderError(loc, "fo:title", "fo:static-content");
- } else if (mainFlow != null) {
- nodesOutOfOrderError(loc, "fo:title", "fo:flow");
- }
- } else if (localName.equals("static-content")) {
- if (mainFlow != null) {
- nodesOutOfOrderError(loc, "fo:static-content", "fo:flow");
- }
- } else if (localName.equals("flow")) {
- if (mainFlow != null) {
- tooManyNodesError(loc, "fo:flow");
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- }
-
- /**
- * Signal end of this xml element.
- * This passes the end page sequence to the structure handler
- * so it can act upon that.
- */
- protected void endOfNode() throws SAXParseException {
- if (mainFlow == null) {
- missingChildElementError("(title?,static-content*,flow)");
- }
- try {
- getFOInputHandler().endPageSequence(this);
- } catch (FOPException fopex) {
- getLogger().error("Error in PageSequence.endOfNode(): "
- + fopex.getMessage(), fopex);
- }
- }
-
- /**
- * @see org.apache.fop.fo.FONode#addChildNode(FONode)
- */
- public void addChildNode(FONode child) {
- try {
- String childName = child.getName();
- if (childName.equals("fo:title")) {
- this.titleFO = (Title)child;
- } else if (childName.equals("fo:flow")) {
- this.mainFlow = (Flow)child;
- String flowName = this.mainFlow.getPropString(PR_FLOW_NAME);
- if (flowMap.containsKey(flowName)) {
- throw new FOPException("flow-name "
- + flowName
- + " is not unique within an fo:page-sequence");
- }
- if (!this.layoutMasterSet.regionNameExists(flowName)) {
- getLogger().error("region-name '"
- + flowName
- + "' doesn't exist in the layout-master-set.");
- }
- // Don't add main flow to the flow map
-// addFlow(mainFlow);
- startStructuredPageSequence();
- super.addChildNode(child); // For getChildren
- } else if (childName.equals("fo:static-content")) {
- String flowName = ((StaticContent)child).getPropString(PR_FLOW_NAME);
- if (flowMap.containsKey(flowName)) {
- throw new FOPException("flow-name " + flowName
- + " is not unique within an fo:page-sequence");
- }
- if (!this.layoutMasterSet.regionNameExists(flowName)) {
- throw new FOPException("region-name '" + flowName
- + "' doesn't exist in the layout-master-set.");
- }
- flowMap.put(flowName, child);
-// addFlow((Flow)child);
- startStructuredPageSequence();
- }
- } catch (FOPException fopex) {
- getLogger().error("Error in PageSequence.addChildNode(): "
- + fopex.getMessage(), fopex);
- }
- }
-
-
/**
* @see org.apache.fop.fo.FObj#addProperties
*/
protected void addProperties(Attributes attlist) throws SAXParseException {
super.addProperties(attlist);
-
this.root = (Root) parent;
-// this.root.addPageSequence(this);
layoutMasterSet = root.getLayoutMasterSet();
-
- // best time to run some checks on LayoutMasterSet
- layoutMasterSet.checkRegionNames();
-
flowMap = new HashMap();
// we are now on the first page of the page sequence
this.explicitFirstNumber = (pageStart > 0) ? pageStart : 1;
} catch (NumberFormatException nfe) {
throw new SAXParseException("\"" + ipnValue
- + "\" is not a valid value for initial-page-number", locator);
+ + "\" is not a valid value for initial-page-number", locator);
}
}
this.layoutMasterSet.getPageSequenceMaster(masterName);
if (this.pageSequenceMaster == null) {
throw new SAXParseException("master-reference '" + masterName
- + "' for fo:page-sequence matches no"
- + " simple-page-master or page-sequence-master", locator);
+ + "' for fo:page-sequence matches no"
+ + " simple-page-master or page-sequence-master", locator);
}
}
// get the 'format' properties
this.pageNumberGenerator =
new PageNumberGenerator(getPropString(PR_FORMAT),
- this.propertyList.get(PR_GROUPING_SEPARATOR).getCharacter(),
- this.propertyList.get(PR_GROUPING_SIZE).getNumber().intValue(),
- getPropEnum(PR_LETTER_VALUE));
+ this.propertyList.get(PR_GROUPING_SEPARATOR).getCharacter(),
+ this.propertyList.get(PR_GROUPING_SIZE).getNumber().intValue(),
+ getPropEnum(PR_LETTER_VALUE));
this.forcePageCount = getPropEnum(PR_FORCE_PAGE_COUNT);
startStructuredPageSequence();
}
+ /**
+ * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+ XSL Content Model: (title?,static-content*,flow)
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws SAXParseException {
+ if (nsURI == FO_URI) {
+ if (localName.equals("title")) {
+ if (titleFO != null) {
+ tooManyNodesError(loc, "fo:title");
+ } else if (flowMap.size() > 0) {
+ nodesOutOfOrderError(loc, "fo:title", "fo:static-content");
+ } else if (mainFlow != null) {
+ nodesOutOfOrderError(loc, "fo:title", "fo:flow");
+ }
+ } else if (localName.equals("static-content")) {
+ if (mainFlow != null) {
+ nodesOutOfOrderError(loc, "fo:static-content", "fo:flow");
+ }
+ } else if (localName.equals("flow")) {
+ if (mainFlow != null) {
+ tooManyNodesError(loc, "fo:flow");
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /**
+ * @see org.apache.fop.fo.FONode#addChildNode(FONode)
+ * @todo see if addChildNode() should also be called for fo's other than
+ * fo:flow.
+ */
+ public void addChildNode(FONode child) throws SAXParseException {
+ int childId = child.getNameId();
+
+ if (childId == FO_TITLE) {
+ this.titleFO = (Title) child;
+ } else if (childId == FO_FLOW) {
+ this.mainFlow = (Flow) child;
+ addFlow(mainFlow);
+ startStructuredPageSequence();
+ super.addChildNode(child); // For getChildren
+ } else if (childId == FO_STATIC_CONTENT) {
+ addFlow((StaticContent) child);
+ startStructuredPageSequence();
+ }
+ }
+
+ /**
+ * Signal end of this xml element.
+ * This passes the end page sequence to the structure handler
+ * so it can act upon that.
+ */
+ protected void endOfNode() throws SAXParseException {
+ if (mainFlow == null) {
+ missingChildElementError("(title?,static-content*,flow)");
+ }
+
+ getFOInputHandler().endPageSequence(this);
+ }
/**
* Add a flow or static content, mapped by its flow-name.
* The flow-name is used to associate the flow with a region on a page,
- * based on the names given to the regions in the page-master used to
- * generate that page.
+ * based on the region-names given to the regions in the page-master
+ * used to generate that page.
*/
-// private void addFlow(Flow flow) throws FOPException {
-// if (flowMap.containsKey(flow.getFlowName())) {
-// throw new FOPException("flow-names must be unique within an fo:page-sequence");
-// }
-// if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) {
-// getLogger().error("region-name '"
-// + flow.getFlowName()
-// + "' doesn't exist in the layout-master-set.");
-// }
-// flowMap.put(flow.getFlowName(), flow);
-// //setIsFlowSet(true);
-// }
+ private void addFlow(Flow flow) throws SAXParseException {
+ String flowName = flow.getPropString(PR_FLOW_NAME);
+
+ if (hasFlowName(flowName)) {
+ throw new SAXParseException ("duplicate flow-name \""
+ + flowName
+ + "\" found within fo:page-sequence", flow.locator);
+ }
+ if (!layoutMasterSet.regionNameExists(flowName)
+ && !flowName.equals("xsl-before-float-separator")
+ && !flowName.equals("xsl-footnote-separator")) {
+ throw new SAXParseException ("flow-name \""
+ + flowName
+ + "\" could not be mapped to a region-name in the"
+ + " layout-master-set", flow.locator);
+ }
+ }
/**
* Start the page-sequence logic in the Structured Handler
}
}
-
/**
* Initialize the current page number for the start of the page sequence.
*/
* @return the static content FO node
*/
public StaticContent getStaticContent(String name) {
- return (StaticContent)flowMap.get(name);
- }
-
- /**
- * Accessor method for layoutMasterSet
- * @return layoutMasterSet for this object
- */
- public LayoutMasterSet getLayoutMasterSet() {
- return layoutMasterSet;
+ return (StaticContent) flowMap.get(name);
}
/**
return mainFlow;
}
+ /**
+ * Determine if this PageSequence already has a flow with the given flow-name
+ * Used for validation of incoming fo:flow or fo:static-content objects
+ * @param flowName The flow-name to search for
+ * @return true if flow-name already defined within this page sequence,
+ * false otherwise
+ */
+ public boolean hasFlowName(String flowName) {
+ return flowMap.containsKey(flowName);
+ }
+
/**
* Public accessor for getting the PageSequenceMaster (if any) to which this
* PageSequence is attached.