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 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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.flow.table.Table;
  29. import org.apache.fop.fo.flow.table.TableFObj;
  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, (FObj) newParent);
  90. if (newChild.getNameId() == FO_TABLE) {
  91. Table t = (Table) child;
  92. cloneSubtree(t.getColumns().iterator(),
  93. newChild, marker, newPropertyList);
  94. cloneSingleNode(t.getTableHeader(),
  95. newChild, marker, newPropertyList);
  96. cloneSingleNode(t.getTableFooter(),
  97. newChild, marker, newPropertyList);
  98. }
  99. cloneSubtree(child.getChildNodes(), newChild,
  100. marker, newPropertyList);
  101. } else if (child instanceof FOText) {
  102. FOText ft = (FOText) newChild;
  103. ft.bind(parentPropertyList);
  104. addChildTo(newChild, (FObj) newParent);
  105. }
  106. // trigger end-of-node white-space handling
  107. // and finalization for table-FOs
  108. newChild.finalizeNode();
  109. }
  110. }
  111. /**
  112. * Clone the FO nodes in the parent iterator,
  113. * attach the new nodes to the new parent,
  114. * and map the new nodes to the existing property lists.
  115. * FOText nodes are also in the new map, with a null value.
  116. * Clone the subtree by a recursive call to this method.
  117. * @param parentIter the iterator over the children of the old parent
  118. * @param newParent the new parent for the cloned nodes
  119. * @param marker the marker that contains the old property list mapping
  120. * @param parentPropertyList the parent PropertyList
  121. * @throws FOPException in case there was an error
  122. */
  123. private void cloneSubtree(Iterator parentIter, FONode newParent,
  124. Marker marker, PropertyList parentPropertyList)
  125. throws FOPException {
  126. if (parentIter != null) {
  127. FONode child;
  128. while (parentIter.hasNext()) {
  129. child = (FONode) parentIter.next();
  130. cloneSingleNode(child, newParent,
  131. marker, parentPropertyList);
  132. }
  133. }
  134. }
  135. private void cloneFromMarker(Marker marker)
  136. throws FOPException {
  137. // clean up remnants from a possible earlier layout
  138. if (firstChild != null) {
  139. currentTextNode = null;
  140. firstChild = null;
  141. }
  142. cloneSubtree(marker.getChildNodes(), this,
  143. marker, propertyList);
  144. handleWhiteSpaceFor(this, null);
  145. }
  146. /**
  147. * Clone the subtree of the given marker
  148. *
  149. * @param marker the marker that is to be cloned
  150. */
  151. public void bindMarker(Marker marker) {
  152. if (marker.getChildNodes() != null) {
  153. try {
  154. cloneFromMarker(marker);
  155. } catch (FOPException exc) {
  156. getFOValidationEventProducer().markerCloningFailed(this,
  157. marker.getMarkerClassName(), exc, getLocator());
  158. }
  159. } else if (log.isDebugEnabled()) {
  160. log.debug("Empty marker retrieved...");
  161. }
  162. }
  163. /**
  164. * Return the value for the <code>retrieve-class-name</code>
  165. * property
  166. *
  167. * @return the value for retrieve-class-name
  168. */
  169. public String getRetrieveClassName() {
  170. return this.retrieveClassName;
  171. }
  172. }