blob: 15fe81aed06a9e4a4bbf4c602971a497da0dfb7d [file] [log] [blame]
/*
* 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.
* 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.flow;
import java.util.HashMap;
import java.util.Iterator;
import org.xml.sax.Locator;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.PropertyListMaker;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.properties.Property;
/**
* Marker formatting object.
*/
public class Marker extends FObjMixed {
// The value of properties relevant for fo:marker.
private String markerClassName;
// End of property values
private PropertyListMaker savePropertyListMaker;
private HashMap descPLists = new HashMap();
/**
* Create a marker fo.
* @param parent the parent fo node
*/
public Marker(FONode parent) {
super(parent);
}
/**
* @see org.apache.fop.fo.FObj#bind(PropertyList)
*/
public void bind(PropertyList pList) throws FOPException {
if (findAncestor(FO_FLOW) < 0) {
invalidChildError(locator, FO_URI, "marker",
"An fo:marker is permitted only as the descendant " +
"of an fo:flow");
}
markerClassName = pList.get(PR_MARKER_CLASS_NAME).getString();
if (markerClassName == null || markerClassName.equals("")) {
missingPropertyError("marker-class-name");
}
}
/**
* retrieve the property list of foNode
* @param foNode the FO node whose property list is requested
* @return the MarkerPropertyList of foNode
*/
protected MarkerPropertyList getPList(FONode foNode) {
return (MarkerPropertyList) descPLists.get(foNode);
}
protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws FOPException {
return new MarkerPropertyList(this, parent);
}
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);
descPLists.put(fobj, pList);
return pList;
}
});
}
protected void endOfNode() {
// Pop the MarkerPropertyList maker.
getFOEventHandler().setPropertyListMaker(savePropertyListMaker);
savePropertyListMaker = null;
// unparent the child property lists
Iterator iter = getChildNodes();
if (iter != null) {
while (iter.hasNext()) {
FONode child = (FONode) iter.next();
MarkerPropertyList pList
= (MarkerPropertyList) descPLists.get(child);
if (pList != null) {
pList.setParentPropertyList(null);
}
}
}
}
/**
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
* XSL Content Model: (#PCDATA|%inline;|%block;)*
* Additionally: "An fo:marker may contain any formatting objects that
* are permitted as a replacement of any fo:retrieve-marker that retrieves
* the fo:marker's children."
* @todo implement "additional" constraint, possibly within fo:retrieve-marker
*/
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (!isBlockOrInlineItem(nsURI, localName)) {
invalidChildError(loc, nsURI, localName);
}
}
/**
* Return the "marker-class-name" property.
*/
public String getMarkerClassName() {
return markerClassName;
}
/**
* @see org.apache.fop.fo.FObj#getName()
*/
public String getName() {
return "fo:marker";
}
/**
* @see org.apache.fop.fo.FObj#getNameId()
*/
public int getNameId() {
return FO_MARKER;
}
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer(super.toString());
sb.append(" {").append(getMarkerClassName()).append("}");
return sb.toString();
}
/**
* 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));
}
}
}