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.

Markers.java 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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.HashMap;
  20. import java.util.Iterator;
  21. import java.util.Map;
  22. import org.apache.commons.logging.Log;
  23. import org.apache.commons.logging.LogFactory;
  24. import org.apache.fop.fo.Constants;
  25. /**
  26. * A class to register and resolve markers.
  27. */
  28. public final class Markers {
  29. // IsAny means either IsFirst or IsLast
  30. private Map<String, Marker> firstQualifyingIsFirst;
  31. private Map<String, Marker> firstQualifyingIsAny;
  32. private Map<String, Marker> lastQualifyingIsFirst;
  33. private Map<String, Marker> lastQualifyingIsLast;
  34. private Map<String, Marker> lastQualifyingIsAny;
  35. private static Log log = LogFactory.getLog(Markers.class);
  36. /**
  37. * Registers a marker with the position traits set.
  38. * Only the required markers are kept.
  39. * For "first-starting-within-page" it adds the markers
  40. * that are starting only if the marker class name is not
  41. * already added.
  42. * For "first-including-carryover" it adds any starting marker
  43. * if the marker class name is not already added.
  44. * For "last-starting-within-page" it adds all marks that
  45. * are starting, replacing earlier markers.
  46. * For "last-ending-within-page" it adds all markers that
  47. * are ending, replacing earlier markers.
  48. *
  49. * @param marks a map of markers to register
  50. * @param starting whether the registration happens at the start (true) or end (false) the the area
  51. * @param isfirst whether it is the first area of the parent LM
  52. * @param islast whether it is the last area of the parent LM
  53. */
  54. public void register(Map<String, Marker> marks, boolean starting, boolean isfirst, boolean islast) {
  55. // TODO: find way to put the page number in the log tracing
  56. if (marks == null) {
  57. return;
  58. }
  59. if (log.isDebugEnabled()) {
  60. log.debug("--" + marks.keySet() + ": " + (starting ? "starting" : "ending")
  61. + (isfirst ? ", first" : "") + (islast ? ", last" : ""));
  62. }
  63. if (starting) {
  64. // at the start of the area, register is-first and any areas
  65. if (firstQualifyingIsAny == null) {
  66. firstQualifyingIsAny = new HashMap<String, Marker>();
  67. }
  68. if (isfirst) {
  69. if (firstQualifyingIsFirst == null) {
  70. firstQualifyingIsFirst = new HashMap<String, Marker>();
  71. }
  72. // first on scope: only put in new values, leave current
  73. for (Iterator<String> iter = marks.keySet().iterator(); iter.hasNext();) {
  74. String key = iter.next();
  75. if (!firstQualifyingIsFirst.containsKey(key)) {
  76. firstQualifyingIsFirst.put(key, marks.get(key));
  77. if (log.isTraceEnabled()) {
  78. log.trace("Adding marker " + key + " to firstQualifyingIsFirst");
  79. }
  80. }
  81. if (!firstQualifyingIsAny.containsKey(key)) {
  82. firstQualifyingIsAny.put(key, marks.get(key));
  83. if (log.isTraceEnabled()) {
  84. log.trace("Adding marker " + key + " to firstQualifyingIsAny");
  85. }
  86. }
  87. }
  88. if (lastQualifyingIsFirst == null) {
  89. lastQualifyingIsFirst = new HashMap<String, Marker>();
  90. }
  91. // last on scope: replace all
  92. lastQualifyingIsFirst.putAll(marks);
  93. if (log.isTraceEnabled()) {
  94. log.trace("Adding all markers to LastStart");
  95. }
  96. } else {
  97. // first on scope: only put in new values, leave current
  98. for (Iterator<String> iter = marks.keySet().iterator(); iter.hasNext();) {
  99. String key = iter.next();
  100. if (!firstQualifyingIsAny.containsKey(key)) {
  101. firstQualifyingIsAny.put(key, marks.get(key));
  102. if (log.isTraceEnabled()) {
  103. log.trace("Adding marker " + key + " to firstQualifyingIsAny");
  104. }
  105. }
  106. }
  107. }
  108. } else {
  109. // at the end of the area, register is-last and any areas
  110. if (islast) {
  111. if (lastQualifyingIsLast == null) {
  112. lastQualifyingIsLast = new HashMap<String, Marker>();
  113. }
  114. // last on page: replace all
  115. lastQualifyingIsLast.putAll(marks);
  116. if (log.isTraceEnabled()) {
  117. log.trace("Adding all markers to lastQualifyingIsLast");
  118. }
  119. }
  120. if (lastQualifyingIsAny == null) {
  121. lastQualifyingIsAny = new HashMap<String, Marker>();
  122. }
  123. // last on page: replace all
  124. lastQualifyingIsAny.putAll(marks);
  125. if (log.isTraceEnabled()) {
  126. log.trace("Adding all markers to lastQualifyingIsAny");
  127. }
  128. }
  129. }
  130. /**
  131. * Retrieves the best candidate marker for the given position.
  132. * @param name the key used to register the marker
  133. * @param pos the retrieval scope position
  134. * @return a Marker instance
  135. */
  136. public Marker resolve(AbstractRetrieveMarker arm) {
  137. Marker mark = null;
  138. int pos = arm.getPosition();
  139. String name = arm.getRetrieveClassName();
  140. String posName = arm.getPositionLabel();
  141. String localName = arm.getLocalName();
  142. switch (pos) {
  143. case Constants.EN_FSWP: // retrieve-marker
  144. case Constants.EN_FIRST_STARTING: // retrieve-table-marker
  145. if (firstQualifyingIsFirst != null) {
  146. mark = firstQualifyingIsFirst.get(name);
  147. }
  148. if (mark == null && firstQualifyingIsAny != null) {
  149. mark = firstQualifyingIsAny.get(name);
  150. posName = "FirstAny after " + posName;
  151. }
  152. break;
  153. case Constants.EN_FIC: // retrieve-marker
  154. case Constants.EN_FIRST_INCLUDING_CARRYOVER: // retrieve-table-marker
  155. if (firstQualifyingIsAny != null) {
  156. mark = firstQualifyingIsAny.get(name);
  157. }
  158. break;
  159. case Constants.EN_LSWP: // retrieve-marker
  160. case Constants.EN_LAST_STARTING: // retrieve-table-marker
  161. if (lastQualifyingIsFirst != null) {
  162. mark = lastQualifyingIsFirst.get(name);
  163. }
  164. if (mark == null && lastQualifyingIsAny != null) {
  165. mark = lastQualifyingIsAny.get(name);
  166. posName = "LastAny after " + posName;
  167. }
  168. break;
  169. case Constants.EN_LEWP: // retrieve-marker
  170. case Constants.EN_LAST_ENDING: // retrieve-table-marker
  171. if (lastQualifyingIsLast != null) {
  172. mark = lastQualifyingIsLast.get(name);
  173. }
  174. if (mark == null && lastQualifyingIsAny != null) {
  175. mark = lastQualifyingIsAny.get(name);
  176. posName = "LastAny after " + posName;
  177. }
  178. break;
  179. default:
  180. throw new RuntimeException("Invalid position attribute in " + localName + ".");
  181. }
  182. if (log.isTraceEnabled()) {
  183. // TODO: find way to put the page number here
  184. log.trace(localName + ": name[" + name + "]; position [" + posName + "]");
  185. }
  186. return mark;
  187. }
  188. /** Dumps the current marker data to the logger. */
  189. public void dump() {
  190. if (log.isTraceEnabled()) {
  191. log.trace("FirstAny: " + this.firstQualifyingIsAny);
  192. log.trace("FirstStart: " + this.firstQualifyingIsFirst);
  193. log.trace("LastAny: " + this.lastQualifyingIsAny);
  194. log.trace("LastEnd: " + this.lastQualifyingIsLast);
  195. log.trace("LastStart: " + this.lastQualifyingIsFirst);
  196. }
  197. }
  198. }