/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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: AbstractRetrieveMarker.java 1466146 2013-04-09 17:31:41Z vhennebert $ */

package org.apache.fop.fo.flow;

import java.util.Iterator;

import org.xml.sax.Locator;

import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.XMLObj;
import org.apache.fop.fo.flow.table.Table;

Abstract base class for the fo:retrieve-marker and fo:retrieve-table-marker formatting objects.
/** * Abstract base class for the <a href="http://www.w3.org/TR/xsl/#fo_retrieve-marker"> * <code>fo:retrieve-marker</code></a> and * <a href="http://www.w3.org/TR/xsl/#fo_retrieve-table-marker"> * <code>fo:retrieve-table-marker</code></a> formatting objects. */
public abstract class AbstractRetrieveMarker extends FObjMixed { private PropertyList propertyList; private String retrieveClassName; private int position; private String positionLabel; private int boundary; private String boundaryLabel; private StructureTreeElement structureTreeElement;
Create a new AbstractRetrieveMarker instance that is a child of the given FONode
Params:
/** * Create a new AbstractRetrieveMarker instance that * is a child of the given {@link FONode} * * @param parent the parent {@link FONode} */
public AbstractRetrieveMarker(FONode parent) { super(parent); }
{@inheritDoc}

XSL Content Model: empty

/** * {@inheritDoc} * <p>XSL Content Model: empty */
protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { invalidChildError(loc, nsURI, localName); } }
{@inheritDoc} Store a reference to the parent PropertyList to be used when the retrieve-marker is resolved.
/** * {@inheritDoc} * Store a reference to the parent {@link PropertyList} * to be used when the retrieve-marker is resolved. */
public void bind(PropertyList pList) throws FOPException { super.bind(pList); this.retrieveClassName = pList.get(PR_RETRIEVE_CLASS_NAME).getString(); if (retrieveClassName == null || retrieveClassName.equals("")) { missingPropertyError("retrieve-class-name"); } this.propertyList = pList.getParentPropertyList(); } @Override public void setStructureTreeElement(StructureTreeElement structureTreeElement) { this.structureTreeElement = structureTreeElement; } @Override public StructureTreeElement getStructureTreeElement() { return structureTreeElement; } private PropertyList createPropertyListFor(FObj fo, PropertyList parent) { return getBuilderContext().getPropertyListMaker().make(fo, parent); } private void cloneSingleNode(FONode child, FONode newParent, Marker marker, PropertyList parentPropertyList) throws FOPException { if (child != null) { FONode newChild = child.clone(newParent, true); if (child instanceof FObj) { Marker.MarkerPropertyList pList; PropertyList newPropertyList = createPropertyListFor( (FObj) newChild, parentPropertyList); pList = marker.getPropertyListFor(child); newChild.processNode( child.getLocalName(), getLocator(), pList, newPropertyList); addChildTo(newChild, newParent); newChild.startOfNode(); switch (newChild.getNameId()) { case FO_TABLE: Table t = (Table) child; cloneSubtree(t.getColumns().iterator(), newChild, marker, newPropertyList); cloneSingleNode(t.getTableHeader(), newChild, marker, newPropertyList); cloneSingleNode(t.getTableFooter(), newChild, marker, newPropertyList); cloneSubtree(child.getChildNodes(), newChild, marker, newPropertyList); break; case FO_LIST_ITEM: ListItem li = (ListItem) child; cloneSingleNode(li.getLabel(), newChild, marker, newPropertyList); cloneSingleNode(li.getBody(), newChild, marker, newPropertyList); break; default: cloneSubtree(child.getChildNodes(), newChild, marker, newPropertyList); break; } newChild.endOfNode(); } else if (child instanceof FOText) { FOText ft = (FOText) newChild; ft.bind(parentPropertyList); addChildTo(newChild, newParent); if (newParent instanceof AbstractRetrieveMarker) { /* * Otherwise the parent of newChild is a cloned FObjMixed that will * call this FOText's endOfNode when its own endOfNode method is * called. */ newChild.endOfNode(); } } else if (child instanceof XMLObj) { addChildTo(newChild, newParent); } } }
Clone the FO nodes in the parent iterator, attach the new nodes to the new parent, and map the new nodes to the existing property lists. FOText nodes are also in the new map, with a null value. Clone the subtree by a recursive call to this method.
Params:
  • parentIter – the iterator over the children of the old parent
  • newParent – the new parent for the cloned nodes
  • marker – the marker that contains the old property list mapping
  • parentPropertyList – the parent PropertyList
Throws:
/** * Clone the FO nodes in the parent iterator, * attach the new nodes to the new parent, * and map the new nodes to the existing property lists. * FOText nodes are also in the new map, with a null value. * Clone the subtree by a recursive call to this method. * @param parentIter the iterator over the children of the old parent * @param newParent the new parent for the cloned nodes * @param marker the marker that contains the old property list mapping * @param parentPropertyList the parent PropertyList * @throws FOPException in case there was an error */
private void cloneSubtree(Iterator parentIter, FONode newParent, Marker marker, PropertyList parentPropertyList) throws FOPException { if (parentIter != null) { FONode child; while (parentIter.hasNext()) { child = (FONode) parentIter.next(); cloneSingleNode(child, newParent, marker, parentPropertyList); } } } private void cloneFromMarker(Marker marker) throws FOPException { cloneSubtree(marker.getChildNodes(), this, marker, propertyList); handleWhiteSpaceFor(this, null); }
Clone the subtree of the given marker
Params:
  • marker – the marker that is to be cloned
/** * Clone the subtree of the given marker * * @param marker the marker that is to be cloned */
public void bindMarker(Marker marker) { // clean up remnants from a possible earlier layout if (firstChild != null) { currentTextNode = null; firstChild = null; } if (marker.getChildNodes() != null) { try { restoreFOEventHandlerState(); cloneFromMarker(marker); } catch (FOPException exc) { getFOValidationEventProducer().markerCloningFailed(this, marker.getMarkerClassName(), exc, getLocator()); } } else if (log.isDebugEnabled()) { log.debug("Empty marker retrieved..."); } } protected abstract void restoreFOEventHandlerState();
Return the value for the retrieve-class-name property
Returns:the value for retrieve-class-name
/** * Return the value for the <code>retrieve-class-name</code> * property * * @return the value for retrieve-class-name */
public String getRetrieveClassName() { return this.retrieveClassName; } protected void setBoundaryLabel(String label) { this.boundaryLabel = label; } protected void setPositionLabel(String label) { this.positionLabel = label; } public String getBoundaryLabel() { return this.boundaryLabel; } public String getPositionLabel() { return this.positionLabel; } protected void setPosition(int position) { this.position = position; } protected void setBoundary(int boundary) { this.boundary = boundary; } public int getPosition() { return this.position; } public int getBoundary() { return this.boundary; } public abstract String getLocalName(); public abstract int getNameId(); public void changePositionTo(int position) { this.position = position; } }