/*
 * 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.Map;
import java.util.Set;

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.
/** * 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.
Params:
  • marks – a map of markers to register
  • starting – whether the registration happens at the start (true) or end (false) the the area
  • isfirst – whether it is the first area of the parent LM
  • islast – whether it is the last area of the parent LM
/** * 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 Set<Map.Entry<String, Marker>> entries = marks.entrySet(); for (Map.Entry<String, Marker> entry : entries) { String key = entry.getKey(); Marker marker = entry.getValue(); if (!firstQualifyingIsFirst.containsKey(key)) { firstQualifyingIsFirst.put(key, marker); if (log.isTraceEnabled()) { log.trace("Adding marker " + key + " to firstQualifyingIsFirst"); } } if (!firstQualifyingIsAny.containsKey(key)) { firstQualifyingIsAny.put(key, marker); 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 Set<Map.Entry<String, Marker>> entries = marks.entrySet(); for (Map.Entry<String, Marker> entry : entries) { String key = entry.getKey(); Marker marker = entry.getValue(); if (!firstQualifyingIsAny.containsKey(key)) { firstQualifyingIsAny.put(key, marker); 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.
Returns:a Marker instance
/** * Retrieves the best candidate marker for the given 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.
/** 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); } } }