- Add PropertyListMaker to support fo:maker and fo:retrieve-marker. PR: 31699 git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198095 13f79535-47bb-0310-9956-ffa450edef68tags/Root_Temp_KnuthStylePageBreaking
@@ -82,6 +82,11 @@ public abstract class FOEventHandler { | |||
*/ | |||
private Set idReferences = new HashSet(); | |||
/* | |||
* The property list maker. | |||
*/ | |||
protected PropertyListMaker propertyListMaker; | |||
/** | |||
* Main constructor | |||
* @param FOUserAgent the apps.FOUserAgent instance for this process | |||
@@ -123,6 +128,20 @@ public abstract class FOEventHandler { | |||
return this.fontInfo; | |||
} | |||
/** | |||
* Return the propertyListMaker. | |||
*/ | |||
public PropertyListMaker getPropertyListMaker() { | |||
return propertyListMaker; | |||
} | |||
/** | |||
* Set a new propertyListMaker. | |||
*/ | |||
public void setPropertyListMaker(PropertyListMaker propertyListMaker) { | |||
this.propertyListMaker = propertyListMaker; | |||
} | |||
/** | |||
* This method is called to indicate the start of a new document run. | |||
* @throws SAXException In case of a problem |
@@ -106,7 +106,12 @@ public class FOTreeBuilder extends DefaultHandler { | |||
//This creates either an AreaTreeHandler and ultimately a Renderer, or | |||
//one of the RTF-, MIF- etc. Handlers. | |||
foEventHandler = RendererFactory.createFOEventHandler(foUserAgent, renderType, stream); | |||
foEventHandler.setPropertyListMaker(new PropertyListMaker() { | |||
public PropertyList make(FObj fobj, PropertyList parentPropertyList) { | |||
return new StaticPropertyList(fobj, parentPropertyList); | |||
} | |||
}); | |||
// Add standard element mappings | |||
setupDefaultMappings(); | |||
@@ -101,8 +101,7 @@ public class FObj extends FONode implements Constants { | |||
* Create a default property list for this element. | |||
*/ | |||
protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws SAXParseException { | |||
//return foEventHandler.getPropertyListMaker().make(this, parent); | |||
return new StaticPropertyList(this, parent); | |||
return foEventHandler.getPropertyListMaker().make(this, parent); | |||
} | |||
/** |
@@ -0,0 +1,27 @@ | |||
/* | |||
* Copyright 2004 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; | |||
/** | |||
* A PropertyListMaker is a factory that creates PropertyLists. | |||
*/ | |||
public interface PropertyListMaker { | |||
PropertyList make(FObj fobj, PropertyList parentPropertyList); | |||
} |
@@ -18,14 +18,21 @@ | |||
package org.apache.fop.fo.flow; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
// XML | |||
import org.xml.sax.Locator; | |||
import org.xml.sax.SAXParseException; | |||
// FOP | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.FObj; | |||
import org.apache.fop.fo.FObjMixed; | |||
import org.apache.fop.fo.FOEventHandler; | |||
import org.apache.fop.fo.properties.Property; | |||
import org.apache.fop.fo.PropertyList; | |||
import org.apache.fop.fo.PropertyListMaker; | |||
/** | |||
* Marker formatting object. | |||
@@ -35,6 +42,10 @@ public class Marker extends FObjMixed { | |||
private String markerClassName; | |||
// End of property values | |||
private MarkerPropertyList propertyList; | |||
private PropertyListMaker savePropertyListMaker; | |||
private HashMap children = new HashMap(); | |||
/** | |||
* Create a marker fo. | |||
* @param parent the parent fo node | |||
@@ -49,6 +60,52 @@ public class Marker extends FObjMixed { | |||
public void bind(PropertyList pList) throws SAXParseException { | |||
markerClassName = pList.get(PR_MARKER_CLASS_NAME).getString(); | |||
} | |||
/** | |||
* Rebind the marker and all the children using the specified | |||
* parentPropertyList which comes from the fo:retrieve-marker element. | |||
* @param parentPropertyList The property list from fo:retrieve-marker. | |||
*/ | |||
public void rebind(PropertyList parentPropertyList) throws SAXParseException { | |||
// Set a new parent property list and bind all the children again. | |||
propertyList.setParentPropertyList(parentPropertyList); | |||
for (Iterator i = children.keySet().iterator(); i.hasNext(); ) { | |||
FObj child = (FObj) i.next(); | |||
PropertyList childList = (PropertyList) children.get(child); | |||
child.bind(childList); | |||
} | |||
} | |||
protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws SAXParseException { | |||
propertyList = new MarkerPropertyList(this, parent); | |||
return propertyList; | |||
} | |||
protected void startOfNode() { | |||
FOEventHandler foEventHandler = getFOEventHandler(); | |||
// Push a new property list maker which will make MarkerPropertyLists. | |||
savePropertyListMaker = foEventHandler.getPropertyListMaker(); | |||
foEventHandler.setPropertyListMaker(new PropertyListMaker() { | |||
public PropertyList make(FObj fobj, PropertyList parentPropertyList) { | |||
PropertyList pList = new MarkerPropertyList(fobj, parentPropertyList); | |||
children.put(fobj, pList); | |||
return pList; | |||
} | |||
}); | |||
} | |||
protected void addChildNode(FONode child) throws SAXParseException { | |||
if (!children.containsKey(child)) { | |||
children.put(child, propertyList); | |||
} | |||
super.addChildNode(child); | |||
} | |||
protected void endOfNode() { | |||
// Pop the MarkerPropertyList maker. | |||
getFOEventHandler().setPropertyListMaker(savePropertyListMaker); | |||
savePropertyListMaker = null; | |||
} | |||
/** | |||
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) | |||
@@ -85,4 +142,32 @@ public class Marker extends FObjMixed { | |||
public int getNameId() { | |||
return FO_MARKER; | |||
} | |||
/** | |||
* An implementation of PropertyList which only stores the explicit | |||
* assigned properties. It is memory efficient but slow. | |||
*/ | |||
public class MarkerPropertyList extends PropertyList { | |||
HashMap explicit = new HashMap(); | |||
public MarkerPropertyList(FObj fobj, PropertyList parentPropertyList) { | |||
super(fobj, parentPropertyList); | |||
} | |||
/** | |||
* Set the parent property list. Used to assign a new parent | |||
* before re-binding all the child elements. | |||
*/ | |||
public void setParentPropertyList(PropertyList parentPropertyList) { | |||
this.parentPropertyList = parentPropertyList; | |||
} | |||
public void putExplicit(int propId, Property value) { | |||
explicit.put(new Integer(propId), value); | |||
} | |||
public Property getExplicit(int propId) { | |||
return (Property) explicit.get(new Integer(propId)); | |||
} | |||
} | |||
} |
@@ -28,7 +28,9 @@ import org.xml.sax.SAXParseException; | |||
// FOP | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.FObjMixed; | |||
import org.apache.fop.fo.FOEventHandler; | |||
import org.apache.fop.fo.PropertyList; | |||
import org.apache.fop.fo.StaticPropertyList; | |||
import org.apache.fop.layoutmgr.RetrieveMarkerLayoutManager; | |||
@@ -44,6 +46,8 @@ public class RetrieveMarker extends FObjMixed { | |||
private int retrieveBoundary; | |||
// End of property values | |||
private PropertyList propertyList; | |||
/** | |||
* Create a retrieve marker object. | |||
* | |||
@@ -71,6 +75,19 @@ public class RetrieveMarker extends FObjMixed { | |||
invalidChildError(loc, nsURI, localName); | |||
} | |||
protected PropertyList createPropertyList(PropertyList parent, | |||
FOEventHandler foEventHandler) throws SAXParseException { | |||
// TODO: A special RetrieveMarkerPropertyList would be more memory | |||
// efficient. Storing a StaticPropertyList like this will keep all | |||
// the parent PropertyLists alive. | |||
propertyList = new StaticPropertyList(this, parent); | |||
return propertyList; | |||
} | |||
public PropertyList getPropertyList() { | |||
return propertyList; | |||
} | |||
/** | |||
* Return the "retrieve-class-name" property. | |||
*/ |
@@ -22,6 +22,8 @@ import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.LinkedList; | |||
import org.xml.sax.SAXParseException; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.fo.flow.Marker; | |||
import org.apache.fop.fo.flow.RetrieveMarker; | |||
@@ -108,15 +110,20 @@ public class RetrieveMarkerLayoutManager extends AbstractLayoutManager { | |||
List list = new ArrayList(); | |||
Marker marker = retrieveMarker(name, position, boundary); | |||
if (marker != null) { | |||
try { | |||
marker.rebind(fobj.getPropertyList()); | |||
} catch (SAXParseException exc) { | |||
log.error("fo:retrieve-marker unable to rebind property values", exc); | |||
} | |||
marker.addLayoutManager(list); | |||
if (list.size() > 0) { | |||
replaceLM = (LayoutManager)list.get(0); | |||
replaceLM.setParent(this); | |||
replaceLM.initialize(); | |||
log.debug("retrieved: " + replaceLM + ":" + list.size()); | |||
} else { | |||
log.debug("found no marker with name: " + name); | |||
} | |||
} else { | |||
log.debug("found no marker with name: " + name); | |||
} | |||
} | |||
} |