You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractRetrieveMarker.java 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fo.flow;
  19. import java.util.Iterator;
  20. import org.xml.sax.Locator;
  21. import org.apache.fop.apps.FOPException;
  22. import org.apache.fop.fo.FONode;
  23. import org.apache.fop.fo.FOText;
  24. import org.apache.fop.fo.FObj;
  25. import org.apache.fop.fo.FObjMixed;
  26. import org.apache.fop.fo.PropertyList;
  27. import org.apache.fop.fo.ValidationException;
  28. import org.apache.fop.fo.XMLObj;
  29. import org.apache.fop.fo.flow.table.Table;
  30. /**
  31. * Abstract base class for the <a href="http://www.w3.org/TR/xsl/#fo_retrieve-marker">
  32. * <code>fo:retrieve-marker</code></a> and
  33. * <a href="http://www.w3.org/TR/xsl/#fo_retrieve-table-marker">
  34. * <code>fo:retrieve-table-marker</code></a> formatting objects.
  35. */
  36. public abstract class AbstractRetrieveMarker extends FObjMixed {
  37. private PropertyList propertyList;
  38. private String retrieveClassName;
  39. /**
  40. * Create a new AbstractRetrieveMarker instance that
  41. * is a child of the given {@link FONode}
  42. *
  43. * @param parent the parent {@link FONode}
  44. */
  45. public AbstractRetrieveMarker(FONode parent) {
  46. super(parent);
  47. }
  48. /**
  49. * {@inheritDoc}
  50. * <p>XSL Content Model: empty
  51. */
  52. protected void validateChildNode(Locator loc, String nsURI, String localName)
  53. throws ValidationException {
  54. if (FO_URI.equals(nsURI)) {
  55. invalidChildError(loc, nsURI, localName);
  56. }
  57. }
  58. /**
  59. * {@inheritDoc}
  60. * Store a reference to the parent {@link PropertyList}
  61. * to be used when the retrieve-marker is resolved.
  62. */
  63. public void bind(PropertyList pList) throws FOPException {
  64. super.bind(pList);
  65. this.retrieveClassName = pList.get(PR_RETRIEVE_CLASS_NAME).getString();
  66. if (retrieveClassName == null || retrieveClassName.equals("")) {
  67. missingPropertyError("retrieve-class-name");
  68. }
  69. this.propertyList = pList.getParentPropertyList();
  70. }
  71. private PropertyList createPropertyListFor(FObj fo, PropertyList parent) {
  72. return getBuilderContext().getPropertyListMaker().make(fo, parent);
  73. }
  74. private void cloneSingleNode(FONode child, FONode newParent,
  75. Marker marker, PropertyList parentPropertyList)
  76. throws FOPException {
  77. if (child != null) {
  78. FONode newChild = child.clone(newParent, true);
  79. if (child instanceof FObj) {
  80. Marker.MarkerPropertyList pList;
  81. PropertyList newPropertyList = createPropertyListFor(
  82. (FObj) newChild, parentPropertyList);
  83. pList = marker.getPropertyListFor(child);
  84. newChild.processNode(
  85. child.getLocalName(),
  86. getLocator(),
  87. pList,
  88. newPropertyList);
  89. addChildTo(newChild, newParent);
  90. switch ( newChild.getNameId() ) {
  91. case FO_TABLE:
  92. Table t = (Table) child;
  93. cloneSubtree(t.getColumns().iterator(),
  94. newChild, marker, newPropertyList);
  95. cloneSingleNode(t.getTableHeader(),
  96. newChild, marker, newPropertyList);
  97. cloneSingleNode(t.getTableFooter(),
  98. newChild, marker, newPropertyList);
  99. cloneSubtree(child.getChildNodes(),
  100. newChild, marker, newPropertyList);
  101. break;
  102. case FO_LIST_ITEM:
  103. ListItem li = (ListItem) child;
  104. cloneSingleNode(li.getLabel(),
  105. newChild, marker, newPropertyList);
  106. cloneSingleNode(li.getBody(),
  107. newChild, marker, newPropertyList);
  108. break;
  109. default:
  110. cloneSubtree(child.getChildNodes(),
  111. newChild, marker, newPropertyList);
  112. break;
  113. }
  114. } else if (child instanceof FOText) {
  115. FOText ft = (FOText) newChild;
  116. ft.bind(parentPropertyList);
  117. addChildTo(newChild, newParent);
  118. } else if (child instanceof XMLObj) {
  119. addChildTo(newChild, newParent);
  120. }
  121. // trigger end-of-node white-space handling
  122. // and finalization for table-FOs
  123. newChild.finalizeNode();
  124. }
  125. }
  126. /**
  127. * Clone the FO nodes in the parent iterator,
  128. * attach the new nodes to the new parent,
  129. * and map the new nodes to the existing property lists.
  130. * FOText nodes are also in the new map, with a null value.
  131. * Clone the subtree by a recursive call to this method.
  132. * @param parentIter the iterator over the children of the old parent
  133. * @param newParent the new parent for the cloned nodes
  134. * @param marker the marker that contains the old property list mapping
  135. * @param parentPropertyList the parent PropertyList
  136. * @throws FOPException in case there was an error
  137. */
  138. private void cloneSubtree(Iterator parentIter, FONode newParent,
  139. Marker marker, PropertyList parentPropertyList)
  140. throws FOPException {
  141. if (parentIter != null) {
  142. FONode child;
  143. while (parentIter.hasNext()) {
  144. child = (FONode) parentIter.next();
  145. cloneSingleNode(child, newParent,
  146. marker, parentPropertyList);
  147. }
  148. }
  149. }
  150. private void cloneFromMarker(Marker marker)
  151. throws FOPException {
  152. cloneSubtree(marker.getChildNodes(), this,
  153. marker, propertyList);
  154. handleWhiteSpaceFor(this, null);
  155. }
  156. /**
  157. * Clone the subtree of the given marker
  158. *
  159. * @param marker the marker that is to be cloned
  160. */
  161. public void bindMarker(Marker marker) {
  162. // clean up remnants from a possible earlier layout
  163. if (firstChild != null) {
  164. currentTextNode = null;
  165. firstChild = null;
  166. }
  167. if (marker.getChildNodes() != null) {
  168. try {
  169. cloneFromMarker(marker);
  170. } catch (FOPException exc) {
  171. getFOValidationEventProducer().markerCloningFailed(this,
  172. marker.getMarkerClassName(), exc, getLocator());
  173. }
  174. } else if (log.isDebugEnabled()) {
  175. log.debug("Empty marker retrieved...");
  176. }
  177. }
  178. /**
  179. * Return the value for the <code>retrieve-class-name</code>
  180. * property
  181. *
  182. * @return the value for retrieve-class-name
  183. */
  184. public String getRetrieveClassName() {
  185. return this.retrieveClassName;
  186. }
  187. }