]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
New pagination spec
authorarved <arved@unknown>
Tue, 11 Jul 2000 02:59:00 +0000 (02:59 +0000)
committerarved <arved@unknown>
Tue, 11 Jul 2000 02:59:00 +0000 (02:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193477 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/apps/XTDriver.java [new file with mode: 0644]
src/org/apache/fop/fo/XTFOTreeBuilder.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/PageMasterReference.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/PageSequenceMaster.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/SinglePageMasterReference.java [new file with mode: 0644]
src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/apps/XTDriver.java b/src/org/apache/fop/apps/XTDriver.java
new file mode 100644 (file)
index 0000000..679188d
--- /dev/null
@@ -0,0 +1,359 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "FOP" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.fop.apps;
+
+// FOP
+import org.apache.fop.fo.XTFOTreeBuilder;
+import org.apache.fop.fo.XTElementMapping; 
+import org.apache.fop.layout.AreaTree;
+import org.apache.fop.layout.FontInfo;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.messaging.MessageHandler;
+
+// DOM
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Attr;
+
+// SAX
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+// Java
+import java.io.PrintWriter;
+import java.io.IOException;
+
+/**
+ * <P>Primary class that drives overall FOP process.
+ *
+ * <P>Once this class is instantiated, methods are called to set the
+ * Renderer to use, the (possibly multiple) ElementMapping(s) to
+ * use and the PrintWriter to use to output the results of the
+ * rendering (where applicable). In the case of the Renderer and
+ * ElementMapping(s), the Driver may be supplied either with the
+ * object itself, or the name of the class, in which case Driver will
+ * instantiate the class itself. The advantage of the latter is it
+ * enables runtime determination of Renderer and ElementMapping(s).
+ *
+ * <P>Once the Driver is set up, the buildFOTree method
+ * is called. Depending on whether DOM or SAX is being used, the
+ * invocation of the method is either buildFOTree(Document) or
+ * buildFOTree(Parser, InputSource) respectively.
+ *
+ * <P>A third possibility may be used to build the FO Tree, namely
+ * calling getDocumentHandler() and firing the SAX events yourself.
+ *
+ * <P>Once the FO Tree is built, the format() and render() methods may be
+ * called in that order.
+ *
+ * <P>Here is an example use of Driver from CommandLine.java:
+ *
+ * <PRE>
+ *   Driver driver = new Driver();
+ *   driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer", version);
+ *   driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
+ *   driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
+ *   driver.setWriter(new PrintWriter(new FileWriter(args[1])));
+ *   driver.buildFOTree(parser, fileInputSource(args[0]));
+ *   driver.format();
+ *   driver.render();
+ * </PRE>
+ */
+public class XTDriver {
+
+    /** the FO tree builder */
+    protected XTFOTreeBuilder treeBuilder;
+
+    /** the area tree that is the result of formatting the FO tree */
+    protected AreaTree areaTree;
+
+    /** the renderer to use to output the area tree */
+    protected Renderer renderer;
+
+    /** the PrintWriter to use to output the results of the renderer */
+    protected PrintWriter writer;
+
+    /** create a new Driver */
+    public XTDriver() {
+       this.treeBuilder = new XTFOTreeBuilder();
+    }
+   
+    /** set the Renderer to use */
+    public void setRenderer(Renderer renderer) {
+       this.renderer = renderer;
+    }
+
+    /**
+     * set the class name of the Renderer to use as well as the
+     * producer string for those renderers that can make use of it
+     */
+    public void setRenderer(String rendererClassName, String producer) {
+       this.renderer = createRenderer(rendererClassName);
+       this.renderer.setProducer(producer);
+    }
+
+    /**
+     * protected method used by setRenderer(String, String) to
+     * instantiate the Renderer class
+     */
+    protected Renderer createRenderer(String rendererClassName) {
+    MessageHandler.logln("using renderer " + rendererClassName);
+
+       try {
+           return (Renderer)
+               Class.forName(rendererClassName).newInstance();
+       } catch (ClassNotFoundException e) {
+           MessageHandler.errorln("Could not find " + rendererClassName);
+       } catch (InstantiationException e) {
+           MessageHandler.errorln("Could not instantiate "
+                              + rendererClassName);
+       } catch (IllegalAccessException e) {
+           MessageHandler.errorln("Could not access " + rendererClassName);
+       } catch (ClassCastException e) {
+           MessageHandler.errorln(rendererClassName + " is not a renderer"); 
+       }
+       return null;
+    }
+    
+    /**
+     * add the given element mapping.
+     *
+     * an element mapping maps element names to Java classes
+     */
+    public void addElementMapping(XTElementMapping mapping) {
+       mapping.addToBuilder(this.treeBuilder);
+    }
+    
+    /**
+     * add the element mapping with the given class name
+     */
+    public void addElementMapping(String mappingClassName) {
+       createElementMapping(mappingClassName).addToBuilder(this.treeBuilder);
+    }
+
+    /**
+     * protected method used by addElementMapping(String) to
+     * instantiate element mapping class
+     */
+    protected XTElementMapping createElementMapping(String mappingClassName) {
+    MessageHandler.logln("using element mapping " + mappingClassName);
+
+       try {
+           return (XTElementMapping)
+               Class.forName(mappingClassName).newInstance();
+       } catch (ClassNotFoundException e) {
+           MessageHandler.errorln("Could not find " + mappingClassName);
+       } catch (InstantiationException e) {
+           MessageHandler.errorln("Could not instantiate "
+                              + mappingClassName);
+       } catch (IllegalAccessException e) {
+           MessageHandler.errorln("Could not access " + mappingClassName);
+       } catch (ClassCastException e) {
+           MessageHandler.errorln(mappingClassName + " is not an element mapping"); 
+       }
+       return null;
+    }
+
+    /**
+     * return the tree builder (a SAX DocumentHandler).
+     *
+     * used in situations where SAX is used but not via a FOP-invoked
+     * SAX parser. A good example is an XSLT engine that fires SAX
+     * events but isn't a SAX Parser itself.
+     */
+    public DocumentHandler getDocumentHandler() {
+       return this.treeBuilder;
+    }
+
+    /**
+     * build the formatting object tree using the given SAX Parser and
+     * SAX InputSource
+     */
+    public void buildFOTree(Parser parser, InputSource source)
+               throws FOPException {
+
+       parser.setDocumentHandler(this.treeBuilder);
+       try {
+           parser.parse(source);
+       } catch (SAXException e) {
+           if (e.getException() instanceof FOPException)
+               throw (FOPException) e.getException();
+           else
+               throw new FOPException(e.getMessage());
+       } catch (IOException e) {
+           throw new FOPException(e.getMessage());
+       }
+    }
+
+    /**
+     * build the formatting object tree using the given DOM Document
+     */
+    public void buildFOTree(Document document) 
+       throws FOPException {
+
+       /* most of this code is modified from John Cowan's */
+
+       Node currentNode;
+       AttributesImpl currentAtts;
+       
+       /* temporary array for making Strings into character arrays */
+       char[] array = null;
+
+       currentAtts = new AttributesImpl();
+       
+       /* start at the document element */
+       currentNode = document;
+
+       try {
+           while (currentNode != null) {
+               switch (currentNode.getNodeType()) {
+               case Node.DOCUMENT_NODE:
+                   this.treeBuilder.startDocument();
+                   break;
+               case Node.CDATA_SECTION_NODE:
+               case Node.TEXT_NODE:
+                   String data = currentNode.getNodeValue();
+                   int datalen = data.length();
+                   if (array == null || array.length < datalen) {
+                       /* if the array isn't big enough, make a new
+                          one */
+                       array = new char[datalen];
+                   }
+                   data.getChars(0, datalen, array, 0);
+                   this.treeBuilder.characters(array, 0, datalen);
+                   break;
+               case Node.PROCESSING_INSTRUCTION_NODE:
+                   this.treeBuilder.processingInstruction(
+                       currentNode.getNodeName(),
+                       currentNode.getNodeValue());
+                   break;
+               case Node.ELEMENT_NODE:
+                   NamedNodeMap map = currentNode.getAttributes();
+                   currentAtts.clear();
+                   for (int i = map.getLength() - 1; i >= 0; i--) {
+                       Attr att = (Attr)map.item(i);
+                       currentAtts.addAttribute("",
+                         att.getName(),
+                         "",
+                         "CDATA",
+                         att.getValue());
+                   }
+                   this.treeBuilder.startElement(
+                       "", currentNode.getNodeName(), "", currentAtts);
+                   break;
+               }
+               
+               Node nextNode = currentNode.getFirstChild();
+               if (nextNode != null) {
+                   currentNode = nextNode;
+                   continue;
+               }
+               
+               while (currentNode != null) {
+                   switch (currentNode.getNodeType()) {
+                   case Node.DOCUMENT_NODE:
+                       this.treeBuilder.endDocument();
+                       break;
+                   case Node.ELEMENT_NODE:
+                       this.treeBuilder.endElement(
+                           "", currentNode.getNodeName(), "" );
+                       break;
+                   }
+                   
+                   nextNode = currentNode.getNextSibling();
+                   if (nextNode != null) {
+                       currentNode = nextNode;
+                       break;
+                   }
+                   
+                   currentNode = currentNode.getParentNode();
+               }
+           }
+       } catch (SAXException e) {
+           throw new FOPException(e.getMessage());
+       }
+    }
+
+    /**
+     * set the PrintWriter to use to output the result of the Renderer
+     * (if applicable)
+     */
+    public void setWriter(PrintWriter writer) {
+       this.writer = writer;
+    }
+
+    /**
+     * format the formatting object tree into an area tree
+     */
+    public void format()
+       throws FOPException {
+       FontInfo fontInfo = new FontInfo();
+       this.renderer.setupFontInfo(fontInfo);
+
+       this.areaTree = new AreaTree();
+       this.areaTree.setFontInfo(fontInfo);
+
+       this.treeBuilder.format(areaTree);
+    }
+
+    /**
+     * render the area tree to the output form
+     */
+    public void render()
+       throws IOException, FOPException {
+       this.renderer.render(areaTree, this.writer);
+    }
+}
diff --git a/src/org/apache/fop/fo/XTFOTreeBuilder.java b/src/org/apache/fop/fo/XTFOTreeBuilder.java
new file mode 100644 (file)
index 0000000..81fd0a4
--- /dev/null
@@ -0,0 +1,257 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo;
+
+// FOP
+import org.apache.fop.layout.AreaTree;
+import org.apache.fop.messaging.MessageHandler;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.pagination.Root;
+
+// SAX
+import org.xml.sax.HandlerBase;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+import org.xml.sax.Attributes;
+
+// Java
+import java.util.Hashtable;
+import java.util.Stack;
+import java.io.IOException;
+
+/**
+ * SAX Handler that builds the formatting object tree.
+ */
+public class XTFOTreeBuilder extends HandlerBase {
+
+    /**
+     * table mapping element names to the makers of objects
+     * representing formatting objects
+     */
+    protected Hashtable fobjTable = new Hashtable();
+
+    /**
+     * class that builds a property list for each formatting object
+     */
+    protected PropertyListBuilder propertyListBuilder = new
+       PropertyListBuilder(); 
+       
+    /**
+     * current formatting object being handled
+     */
+    protected FObj currentFObj = null;
+
+    /**
+     * the root of the formatting object tree
+     */
+    protected FObj rootFObj = null;
+
+    /**
+     * set of names of formatting objects encountered but unknown
+     */
+    protected Hashtable unknownFOs = new Hashtable();
+
+    // namespace implementation ideas pinched from John Cowan
+    protected static class NSMap {
+       String prefix;
+       String uri;
+       int level;
+
+       NSMap(String prefix, String uri, int level) {
+           this.prefix = prefix;
+           this.uri = uri;
+           this.level = level;
+       }
+    }
+
+    protected int level = 0;
+    protected Stack namespaceStack = new Stack();
+
+    {
+       namespaceStack.push(new NSMap("xml",
+                                     "http://www.w3.org/XML/1998/namespace",
+                                     -1));
+       namespaceStack.push(new NSMap("", "", -1));
+    }
+
+    protected String findURI(String prefix) {
+       for (int i = namespaceStack.size() - 1; i >= 0; i--) {
+           NSMap nsMap = (NSMap) (namespaceStack.elementAt(i));
+           if (prefix.equals(nsMap.prefix)) return nsMap.uri;
+       }
+       return null;
+    }
+
+    protected String mapName(String name)
+       throws SAXException {
+       int colon = name.indexOf(':');
+       String prefix = "";
+       String localPart = name;
+       if (colon != -1) {
+           prefix = name.substring(0, colon);
+           localPart = name.substring(colon + 1);
+       }
+       String uri = findURI(prefix);
+       if (uri == null) {
+           if (prefix.equals("")) {
+               return name;
+           } else {
+               throw new SAXException(new FOPException("Unknown namespace prefix " + prefix));
+           }
+       }
+       return uri + "^" + localPart;
+    }
+
+    /**
+     * add a mapping from element name to maker.
+     *
+     * @param namespaceURI namespace URI of formatting object element
+     * @param localName local name of formatting object element
+     * @param maker Maker for class representing formatting object
+    */
+    public void addMapping(String namespaceURI, String localName,
+                          FObj.Maker maker) {
+       this.fobjTable.put(namespaceURI + "^" + localName, maker);
+    }
+
+    /** SAX Handler for characters */
+    public void characters(char data[], int start, int length) {
+       currentFObj.addCharacters(data, start, start + length);
+    }
+
+    /** SAX Handler for the end of an element */
+    public void endElement(
+               String uri, String localName, String rawName) {
+       currentFObj.end();
+       currentFObj = (FObj) currentFObj.getParent();
+       level--;
+       while (((NSMap) namespaceStack.peek()).level > level) {
+           namespaceStack.pop();
+       }
+    }
+
+    /** SAX Handler for the start of the document */
+    public void startDocument() {
+       MessageHandler.logln("building formatting object tree");
+    }
+
+    /** SAX Handler for the start of an element */
+    public void startElement(String uri,
+       String localName, String rawName, Attributes attlist)
+       throws SAXException { 
+
+       /* the formatting object started */
+       FObj fobj;
+
+       /* the maker for the formatting object started */
+       FObj.Maker fobjMaker;
+
+       level++;
+       int length = attlist.getLength();
+       for (int i = 0; i < length; i++) {
+           String att = attlist.getRawName(i);
+           if (att.equals("xmlns")) {
+               namespaceStack.push( new NSMap("",
+                                              attlist.getValue(i),
+                                              level));
+           } else if (att.startsWith("xmlns:")) {
+               String value = attlist.getValue(i);
+               namespaceStack.push(new NSMap(att.substring(6), value,
+                                             level));
+           }
+       }
+
+       String fullName = mapName(rawName);
+
+       fobjMaker = (FObj.Maker) fobjTable.get(fullName);
+
+       if (fobjMaker == null) {
+           if (!this.unknownFOs.containsKey(fullName)) {
+               this.unknownFOs.put(fullName, "");
+               MessageHandler.errorln("WARNING: Unknown formatting object "
+                                  + fullName);  
+           }
+           fobjMaker = new FObjMixed.Maker(); // fall back
+       }
+       
+       try {
+               PropertyList list = this.propertyListBuilder.makeList(attlist,  
+                    (currentFObj == null) ? null : currentFObj.properties);
+           fobj = fobjMaker.make(currentFObj, list);
+       } catch (FOPException e) {
+               throw new SAXException(e);
+       }
+
+       if (rootFObj == null) {
+           rootFObj = fobj;
+           if (!fobj.getName().equals("fo:root")) {
+               throw new SAXException(new FOPException("Root element must"
+                                                       + " be root, not "
+                                                       + fobj.getName())); 
+           }
+       } else {
+           currentFObj.addChild(fobj);
+       }
+       
+       currentFObj = fobj;
+    }
+
+    /**
+     * format this formatting object tree
+     *
+     * @param areaTree the area tree to format into
+     */
+    public void format(AreaTree areaTree)
+       throws FOPException {
+       MessageHandler.logln("formatting FOs into areas");
+       ((Root) this.rootFObj).format(areaTree);
+    }
+}
diff --git a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
new file mode 100644 (file)
index 0000000..5db191d
--- /dev/null
@@ -0,0 +1,174 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.apps.FOPException;                   
+import org.apache.fop.messaging.MessageHandler;
+
+public class ConditionalPageMasterReference
+       extends PageMasterReference implements SubSequenceSpecifier {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new ConditionalPageMasterReference(parent,propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new ConditionalPageMasterReference.Maker();
+    }
+
+       private String masterName;
+       private RepeatablePageMasterAlternatives repeatablePageMasterAlternatives;
+       
+       private int pagePosition;
+       private int oddOrEven;
+       private int blankOrNotBlank;
+       
+    public ConditionalPageMasterReference(FObj parent, PropertyList propertyList)
+               throws FOPException {
+       super(parent, propertyList);
+       this.name = "fo:conditional-page-master-reference";
+
+       if (parent.getName().equals("fo:repeatable-page-master-alternatives")) {
+           this.repeatablePageMasterAlternatives =
+                       (RepeatablePageMasterAlternatives) parent;
+           setMasterName( this.properties.get("master-name").getString() );
+           if (getMasterName() == null) {
+               System.err.println("WARNING: single-page-master-reference" +
+                   "does not have a master-name and so is being ignored");
+           } else {
+               this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this);
+           }
+               
+           setPagePosition( this.properties.get("page-position").getEnum() );
+           setOddOrEven( this.properties.get("odd-or-even").getEnum() );
+           setBlankOrNotBlank( this.properties.get("blank-or-not-blank").getEnum() );
+               
+       } else {
+           throw new FOPException("fo:conditional-page-master-reference must be child "
+                                  + "of fo:repeatable-page-master-alternatives, not " 
+                                  + parent.getName());
+       }
+    }
+       
+       protected boolean isValid( int currentPageNumber, boolean thisIsFirstPage )
+       {
+               // page-position
+               boolean okOnPagePosition = true;        // default is 'any'
+               switch (getPagePosition()) {
+                       case PagePosition.FIRST:
+                               if (!thisIsFirstPage)
+                                       okOnPagePosition = false;
+                               break;
+                       case PagePosition.LAST:
+                               // how the hell do you know at this point?
+                               MessageHandler.log( "LAST PagePosition NYI" );
+                               okOnPagePosition = true;
+                               break;
+                       case PagePosition.REST:
+                               if (thisIsFirstPage)
+                                       okOnPagePosition = false;
+                               break;
+                       case PagePosition.ANY:
+                               okOnPagePosition = true;
+               }
+               
+               // odd or even
+               boolean okOnOddOrEven = true;   // default is 'any'
+               int ooe = getOddOrEven();
+               boolean isOddPage = ((currentPageNumber % 2) == 1) ? true : false;
+               if ((OddOrEven.ODD == ooe) && !isOddPage)
+               {
+                       okOnOddOrEven = false;
+               }
+               if ((OddOrEven.EVEN == ooe) && isOddPage) {
+                       okOnOddOrEven = false;
+               } 
+               
+               // no check for blankness at the moment
+               
+               return (okOnOddOrEven && okOnPagePosition);
+       }
+       
+    protected void setPagePosition( int pagePosition )
+       {
+               this.pagePosition = pagePosition;
+       }
+
+    protected int getPagePosition()
+       {
+               return this.pagePosition;
+       }
+
+    protected void setOddOrEven( int oddOrEven )
+       {
+               this.oddOrEven = oddOrEven;
+       }
+
+    protected int getOddOrEven()
+       {
+               return this.oddOrEven;
+       }
+
+    protected void setBlankOrNotBlank( int blankOrNotBlank )
+       {
+               this.blankOrNotBlank = blankOrNotBlank;
+       }
+
+    protected int getBlankOrNotBlank()
+       {
+               return this.blankOrNotBlank;
+       }
+}
diff --git a/src/org/apache/fop/fo/pagination/PageMasterReference.java b/src/org/apache/fop/fo/pagination/PageMasterReference.java
new file mode 100644 (file)
index 0000000..b177f72
--- /dev/null
@@ -0,0 +1,92 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.apps.FOPException;                   
+import org.apache.fop.messaging.MessageHandler;
+
+public class PageMasterReference extends FObj implements SubSequenceSpecifier {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new PageMasterReference(parent,propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new PageMasterReference.Maker();
+    }
+
+       private String masterName;
+       
+    public PageMasterReference(FObj parent, PropertyList propertyList)
+               throws FOPException {
+               super(parent, propertyList);
+       }
+               
+    public void setMasterName( String masterName )
+       {
+               this.masterName = masterName;
+       }
+
+    public String getMasterName()
+       {
+               return this.masterName;
+       }
+
+    public String getNextPageMaster( int currentPageNumber,
+       boolean thisIsFirstPage ) {
+               return getMasterName();
+       }
+}
diff --git a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java
new file mode 100644 (file)
index 0000000..1090d9f
--- /dev/null
@@ -0,0 +1,140 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+// FOP
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.layout.PageMaster;
+import org.apache.fop.layout.Region;
+import org.apache.fop.apps.FOPException;                                  
+import org.apache.fop.messaging.MessageHandler;
+
+// Java
+import java.util.Vector;
+
+public class PageSequenceMaster extends FObj {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new PageSequenceMaster(parent, propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new PageSequenceMaster.Maker();
+    }
+
+    LayoutMasterSet layoutMasterSet;
+    Vector subSequenceSpecifiers;
+    SubSequenceSpecifier currentPmr;
+
+    // The terminology may be confusing. A 'page-sequence-master' consists
+    // of a sequence of what the XSL spec refers to as
+    // 'sub-sequence-specifiers'. These are, in fact, simple or complex
+    // references to page-masters. So the methods use the former
+       // terminology ('sub-sequence-specifiers', or SSS),
+    // but the actual FO's are MasterReferences.
+    protected PageSequenceMaster(FObj parent, PropertyList propertyList)
+       throws FOPException {
+       super(parent, propertyList);
+       this.name = "fo:page-sequence-master";
+
+       subSequenceSpecifiers = new Vector();
+       
+       if (parent.getName().equals("fo:layout-master-set")) {
+           this.layoutMasterSet = (LayoutMasterSet) parent;
+           String pm = this.properties.get("master-name").getString();
+           if (pm == null) {
+               System.err.println("WARNING: page-sequence-master does not have "
+                                  + "a page-master-name and so is being ignored");
+           } else {
+               this.layoutMasterSet.addPageSequenceMaster(pm, this);
+           }
+       } else {
+           throw new FOPException("fo:page-sequence-master must be child "
+                                  + "of fo:layout-master-set, not " 
+                                  + parent.getName());
+       }
+    }
+    
+    protected void addSubsequenceSpecifier( SubSequenceSpecifier pageMasterReference )
+    {
+               subSequenceSpecifiers.add( pageMasterReference );
+    }
+
+    protected SubSequenceSpecifier getNextSubsequenceSpecifier()
+    {
+               currentPmr = (SubSequenceSpecifier)subSequenceSpecifiers.remove( 0 );
+               return currentPmr;
+    }
+
+    public PageMaster getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage )
+    {
+               if (null == currentPmr)
+               {
+                       currentPmr = getNextSubsequenceSpecifier();
+               }
+               
+           String nextPageMaster =
+                       currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage );
+               
+               if (null == nextPageMaster)
+               {
+                       currentPmr = getNextSubsequenceSpecifier();
+                       nextPageMaster =
+                               currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage );
+               }
+               
+               return this.layoutMasterSet.getSimplePageMaster( nextPageMaster ).getPageMaster();
+    }
+}
diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
new file mode 100644 (file)
index 0000000..85a71e2
--- /dev/null
@@ -0,0 +1,162 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.apps.FOPException;                   
+import org.apache.fop.messaging.MessageHandler;
+
+// Java
+import java.util.Vector;
+
+public class RepeatablePageMasterAlternatives extends FObj
+       implements SubSequenceSpecifier {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new RepeatablePageMasterAlternatives(parent,propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new RepeatablePageMasterAlternatives.Maker();
+    }
+
+       private PageSequenceMaster pageSequenceMaster;
+       
+    private int maximumRepeats;
+    private int numberConsumed = 0;
+
+    private int BOUNDED = 1;
+    private int UNBOUNDED = 0;
+
+    private int state;
+    private Vector conditionalPageMasterRefs;
+
+    public RepeatablePageMasterAlternatives(FObj parent, PropertyList propertyList)
+               throws FOPException {
+       super(parent, propertyList);
+       this.name = "fo:repeatable-page-master-alternatives";
+
+       conditionalPageMasterRefs = new Vector();
+       
+       if (parent.getName().equals("fo:page-sequence-master")) {
+           this.pageSequenceMaster = (PageSequenceMaster) parent;
+               this.pageSequenceMaster.addSubsequenceSpecifier(this);
+       } else {
+           throw new FOPException("fo:repeatable-page-master-alternatives" +
+               "must be child of fo:page-sequence-master, not " +
+               parent.getName());
+       }
+
+       String mr = this.properties.get("maximum-repeats").getString();
+       if (!mr.equals("no-limit"))
+       {
+           try {
+                       setMaximumRepeats( Integer.parseInt( mr ) );
+                       this.state = BOUNDED;
+           } catch (NumberFormatException nfe) {
+                       throw new FOPException( "Invalid number for " +
+                               "'maximum-repeats' property" );
+           }
+
+       } else {
+           this.state = UNBOUNDED;   // unbounded
+       }
+
+    }
+       
+    public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage ) {
+               String pm = null;
+               
+               if (this.state == BOUNDED ) {
+                       if (numberConsumed < getMaximumRepeats()) {
+                               numberConsumed++;
+                       } else {
+                               return null;
+                       }
+               }
+
+               for (int i = 0; i < conditionalPageMasterRefs.size(); i++)
+               {
+                       ConditionalPageMasterReference cpmr =
+                       (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i);
+
+                       // 0-indexed page number
+                       if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage))
+                       {
+                               pm = cpmr.getMasterName();
+                               break;
+                       }
+               }
+
+               return pm;
+    }
+
+       private void setMaximumRepeats( int maximumRepeats)
+       {
+               this.maximumRepeats =
+                       (maximumRepeats < 0) ? 0 : maximumRepeats;
+       }
+       
+       private int getMaximumRepeats()
+       {
+               return this.maximumRepeats;
+       }
+
+       public void addConditionalPageMasterReference(
+               ConditionalPageMasterReference cpmr)
+       {
+               this.conditionalPageMasterRefs.add( cpmr );
+       }
+       
+}
diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
new file mode 100644 (file)
index 0000000..ac9c327
--- /dev/null
@@ -0,0 +1,144 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.apps.FOPException;                   
+
+public class RepeatablePageMasterReference extends PageMasterReference
+       implements SubSequenceSpecifier {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new RepeatablePageMasterReference(parent,propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new RepeatablePageMasterReference.Maker();
+    }
+
+       private String masterName;
+       private PageSequenceMaster pageSequenceMaster;
+       
+    private int maximumRepeats;
+    private int numberConsumed = 0;
+
+    private int BOUNDED = 1;
+    private int UNBOUNDED = 0;
+
+    private int state;
+       
+    public RepeatablePageMasterReference(FObj parent, PropertyList propertyList)
+               throws FOPException {
+       super(parent, propertyList);
+       this.name = "fo:repeatable-page-master-reference";
+
+       if (parent.getName().equals("fo:page-sequence-master")) {
+           this.pageSequenceMaster = (PageSequenceMaster) parent;
+           setMasterName( this.properties.get("master-name").getString() );
+           if (getMasterName() == null) {
+               System.err.println("WARNING: repeatable-page-master-reference" +
+                   "does not have a master-name and so is being ignored");
+           } else {
+               this.pageSequenceMaster.addSubsequenceSpecifier(this);
+           }
+       } else {
+           throw new FOPException("fo:repeatable-page-master-reference must be" +
+                "child of fo:page-sequence, not " 
+               + parent.getName());
+       }
+
+       String mr = this.properties.get("maximum-repeats").getString();
+       if (!mr.equals("no-limit"))
+       {
+           try {
+                       setMaximumRepeats( Integer.parseInt( mr ) );
+                       this.state = BOUNDED;
+           } catch (NumberFormatException nfe) {
+                       throw new FOPException( "Invalid number for " +
+                               "'maximum-repeats' property" );
+           }
+
+       } else {
+           this.state = UNBOUNDED;   // unbounded
+       }
+
+    }
+       
+    public String getNextPageMaster( int currentPageNumber,
+               boolean thisIsFirstPage ) {
+               String pm = getMasterName();
+               
+               if (this.state == BOUNDED)
+               {
+                       if (numberConsumed < getMaximumRepeats()) {
+                               numberConsumed++;
+                       } else {
+                               pm = null;
+                       }
+               }
+               return pm;
+       }
+       
+       private void setMaximumRepeats( int maximumRepeats)
+       {
+               this.maximumRepeats =
+                       (maximumRepeats < 0) ? 0 : maximumRepeats;
+       }
+       
+       private int getMaximumRepeats()
+       {
+               return this.maximumRepeats;
+       }
+
+}
diff --git a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java
new file mode 100644 (file)
index 0000000..cf6071c
--- /dev/null
@@ -0,0 +1,117 @@
+/*-- $Id$ -- 
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+import org.apache.fop.fo.*;
+import org.apache.fop.apps.FOPException;                   
+import org.apache.fop.messaging.MessageHandler;
+
+public class SinglePageMasterReference extends PageMasterReference
+       implements SubSequenceSpecifier {
+       
+    public static class Maker extends FObj.Maker {
+       public FObj make(FObj parent, PropertyList propertyList)
+           throws FOPException {
+           return new SinglePageMasterReference(parent,propertyList);
+       }
+    }
+
+    public static FObj.Maker maker() {
+       return new SinglePageMasterReference.Maker();
+    }
+
+       private String masterName;
+       private PageSequenceMaster pageSequenceMaster;
+       
+    private static final int FIRST = 0;
+    private static final int DONE = 1;
+       
+    private int state;
+       
+    public SinglePageMasterReference(FObj parent, PropertyList propertyList)
+               throws FOPException {
+
+       super(parent, propertyList);
+       this.name = "fo:single-page-master-reference";
+
+       if (parent.getName().equals("fo:page-sequence-master")) {
+           this.pageSequenceMaster = (PageSequenceMaster) parent;
+           setMasterName( this.properties.get("master-name").getString() );
+
+           if (getMasterName() == null) {
+               MessageHandler.error("WARNING: single-page-master-reference" +
+                   "does not have a master-name and so is being ignored");
+           } else {
+               this.pageSequenceMaster.addSubsequenceSpecifier(this);
+           }
+       } else {
+           throw new FOPException("fo:page-sequence-master must be child "
+                                  + "of fo:layout-master-set, not " 
+                                  + parent.getName());
+       }
+
+       this.state = FIRST;
+    }
+       
+    public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage ) {
+       return getMasterName();
+    }
+
+    public void setMasterName( String masterName )
+       {
+               this.masterName = masterName;
+       }
+
+    public String getMasterName()
+       {
+               return this.masterName;
+       }
+}
diff --git a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
new file mode 100644 (file)
index 0000000..fe18f15
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "Fop" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.fo.pagination;
+
+/** Classes that implement this interface can be added to a PageSequenceMaster,
+ * and are capable of looking up an appropriate PageMaster.
+ */
+public interface SubSequenceSpecifier
+{
+    public String getNextPageMaster( int currentPageNumber,
+               boolean thisIsFirstPage );
+}
+