123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /*
- * 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$ */
-
- package org.apache.fop.fo.flow;
-
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
-
- import org.apache.fop.fo.Constants;
-
- /**
- * A class to register and resolve markers.
- */
- public final class Markers {
-
- // IsAny means either IsFirst or IsLast
- private Map<String, Marker> firstQualifyingIsFirst;
- private Map<String, Marker> firstQualifyingIsAny;
- private Map<String, Marker> lastQualifyingIsFirst;
- private Map<String, Marker> lastQualifyingIsLast;
- private Map<String, Marker> lastQualifyingIsAny;
-
- private static Log log = LogFactory.getLog(Markers.class);
-
- /**
- * Registers a marker with the position traits set.
- * Only the required markers are kept.
- * For "first-starting-within-page" it adds the markers
- * that are starting only if the marker class name is not
- * already added.
- * For "first-including-carryover" it adds any starting marker
- * if the marker class name is not already added.
- * For "last-starting-within-page" it adds all marks that
- * are starting, replacing earlier markers.
- * For "last-ending-within-page" it adds all markers that
- * are ending, replacing earlier markers.
- *
- * @param marks a map of markers to register
- * @param starting whether the registration happens at the start (true) or end (false) the the area
- * @param isfirst whether it is the first area of the parent LM
- * @param islast whether it is the last area of the parent LM
- */
- public void register(Map<String, Marker> marks, boolean starting, boolean isfirst, boolean islast) {
- // TODO: find way to put the page number in the log tracing
-
- if (marks == null) {
- return;
- }
- if (log.isDebugEnabled()) {
- log.debug("--" + marks.keySet() + ": " + (starting ? "starting" : "ending")
- + (isfirst ? ", first" : "") + (islast ? ", last" : ""));
- }
-
- if (starting) {
- // at the start of the area, register is-first and any areas
- if (firstQualifyingIsAny == null) {
- firstQualifyingIsAny = new HashMap<String, Marker>();
- }
- if (isfirst) {
- if (firstQualifyingIsFirst == null) {
- firstQualifyingIsFirst = new HashMap<String, Marker>();
- }
- // first on scope: only put in new values, leave current
- for (Iterator<String> iter = marks.keySet().iterator(); iter.hasNext();) {
- String key = iter.next();
- if (!firstQualifyingIsFirst.containsKey(key)) {
- firstQualifyingIsFirst.put(key, marks.get(key));
- if (log.isTraceEnabled()) {
- log.trace("Adding marker " + key + " to firstQualifyingIsFirst");
- }
- }
- if (!firstQualifyingIsAny.containsKey(key)) {
- firstQualifyingIsAny.put(key, marks.get(key));
- if (log.isTraceEnabled()) {
- log.trace("Adding marker " + key + " to firstQualifyingIsAny");
- }
- }
- }
- if (lastQualifyingIsFirst == null) {
- lastQualifyingIsFirst = new HashMap<String, Marker>();
- }
- // last on scope: replace all
- lastQualifyingIsFirst.putAll(marks);
- if (log.isTraceEnabled()) {
- log.trace("Adding all markers to LastStart");
- }
- } else {
- // first on scope: only put in new values, leave current
- for (Iterator<String> iter = marks.keySet().iterator(); iter.hasNext();) {
- String key = iter.next();
- if (!firstQualifyingIsAny.containsKey(key)) {
- firstQualifyingIsAny.put(key, marks.get(key));
- if (log.isTraceEnabled()) {
- log.trace("Adding marker " + key + " to firstQualifyingIsAny");
- }
- }
- }
- }
- } else {
- // at the end of the area, register is-last and any areas
- if (islast) {
- if (lastQualifyingIsLast == null) {
- lastQualifyingIsLast = new HashMap<String, Marker>();
- }
- // last on page: replace all
- lastQualifyingIsLast.putAll(marks);
- if (log.isTraceEnabled()) {
- log.trace("Adding all markers to lastQualifyingIsLast");
- }
- }
- if (lastQualifyingIsAny == null) {
- lastQualifyingIsAny = new HashMap<String, Marker>();
- }
- // last on page: replace all
- lastQualifyingIsAny.putAll(marks);
- if (log.isTraceEnabled()) {
- log.trace("Adding all markers to lastQualifyingIsAny");
- }
- }
- }
-
- /**
- * Retrieves the best candidate marker for the given position.
- * @param name the key used to register the marker
- * @param pos the retrieval scope position
- * @return a Marker instance
- */
- public Marker resolve(AbstractRetrieveMarker arm) {
- Marker mark = null;
- int pos = arm.getPosition();
- String name = arm.getRetrieveClassName();
- String posName = arm.getPositionLabel();
- String localName = arm.getLocalName();
- switch (pos) {
- case Constants.EN_FSWP: // retrieve-marker
- case Constants.EN_FIRST_STARTING: // retrieve-table-marker
- if (firstQualifyingIsFirst != null) {
- mark = firstQualifyingIsFirst.get(name);
- }
- if (mark == null && firstQualifyingIsAny != null) {
- mark = firstQualifyingIsAny.get(name);
- posName = "FirstAny after " + posName;
- }
- break;
- case Constants.EN_FIC: // retrieve-marker
- case Constants.EN_FIRST_INCLUDING_CARRYOVER: // retrieve-table-marker
- if (firstQualifyingIsAny != null) {
- mark = firstQualifyingIsAny.get(name);
- }
- break;
- case Constants.EN_LSWP: // retrieve-marker
- case Constants.EN_LAST_STARTING: // retrieve-table-marker
- if (lastQualifyingIsFirst != null) {
- mark = lastQualifyingIsFirst.get(name);
- }
- if (mark == null && lastQualifyingIsAny != null) {
- mark = lastQualifyingIsAny.get(name);
- posName = "LastAny after " + posName;
- }
- break;
- case Constants.EN_LEWP: // retrieve-marker
- case Constants.EN_LAST_ENDING: // retrieve-table-marker
- if (lastQualifyingIsLast != null) {
- mark = lastQualifyingIsLast.get(name);
- }
- if (mark == null && lastQualifyingIsAny != null) {
- mark = lastQualifyingIsAny.get(name);
- posName = "LastAny after " + posName;
- }
- break;
- default:
- throw new RuntimeException("Invalid position attribute in " + localName + ".");
- }
- if (log.isTraceEnabled()) {
- // TODO: find way to put the page number here
- log.trace(localName + ": name[" + name + "]; position [" + posName + "]");
- }
- return mark;
- }
-
- /** Dumps the current marker data to the logger. */
- public void dump() {
- if (log.isTraceEnabled()) {
- log.trace("FirstAny: " + this.firstQualifyingIsAny);
- log.trace("FirstStart: " + this.firstQualifyingIsFirst);
- log.trace("LastAny: " + this.lastQualifyingIsAny);
- log.trace("LastEnd: " + this.lastQualifyingIsLast);
- log.trace("LastStart: " + this.lastQualifyingIsFirst);
- }
- }
-
- }
|