net.sf.jasperreports.engine.BookmarkHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
/*
* Contributors:
* John Bindel - [email protected]
*/
package net.sf.jasperreports.engine;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.base.BasePrintBookmark;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Teodor Danciu ([email protected])
*/
public class BookmarkHelper
{
private BookmarkStack bookmarkStack;
public BookmarkHelper(boolean isCollapseMissingBookmarkLevels)
{
bookmarkStack = new BookmarkStack(isCollapseMissingBookmarkLevels);
}
public void addBookmarks(JRPrintPage page, int pageIndex)
{
bookmarkStack.addBookmarks(page.getElements(), pageIndex, null);
}
public void updateBookmark(JRPrintElement element)
{
bookmarkStack.updateBookmark(element);
}
public List getRootBookmarks()
{
return bookmarkStack.getRootBookmarks();
}
public void appendBookmarks(BookmarkHelper bookmarkHelper, int pageOffset)
{
bookmarkStack.appendBookmarks(bookmarkHelper.bookmarkStack, pageOffset);
}
public void addBookmark(BasePrintBookmark bookmark, int pageOffset)
{
bookmarkStack.addBookmark(bookmark, pageOffset);
}
public BookmarkIterator bookmarkIterator()
{
return bookmarkStack.bookmarkIterator();
}
public boolean hasBookmarks()
{
return bookmarkStack.hasBookmarks();
}
}
/**
*
*/
class BookmarkStack
{
private static final Log log = LogFactory.getLog(BookmarkStack.class);
LinkedList stack;
boolean isCollapseMissingBookmarkLevels;
Map updateableBookmarks;
public BookmarkStack(boolean isCollapseMissingBookmarkLevels)
{
stack = new LinkedList();
this.isCollapseMissingBookmarkLevels = isCollapseMissingBookmarkLevels;
//root bookmark is only used as container for root node
BasePrintBookmark root = new BasePrintBookmark(null, 0, null, 0);
push(root);
updateableBookmarks = new HashMap();
}
public boolean hasBookmarks()
{
List bookmarks = stack.getFirst().getBookmarks();
return bookmarks != null && !bookmarks.isEmpty();
}
public void push(BasePrintBookmark bookmark)
{
stack.add(bookmark);
}
public BasePrintBookmark pop()
{
return stack.removeLast();
}
public BasePrintBookmark peek()
{
return stack.getLast();
}
protected BasePrintBookmark addBookmark(int level, String label, int pageIndex, String elementAddress)
{
BasePrintBookmark parent = this.peek();
// searching for parent
while(parent.getLevel() >= level)
{
this.pop();
parent = this.peek();
}
if (!isCollapseMissingBookmarkLevels)
{
PrintBookmark parentPrintBookmark = parent;
// creating empty bookmarks in order to preserve the bookmark level
for (int i = parent.getLevel() + 1; i < level; ++i)
{
BasePrintBookmark emptyBookmark = createBookmark(parent, "",
parentPrintBookmark.getPageIndex(), parentPrintBookmark.getElementAddress(),
parent.getLevel() + 1);
this.push(emptyBookmark);
parent = emptyBookmark;
}
}
BasePrintBookmark bookmark = createBookmark(parent, label, pageIndex, elementAddress,
isCollapseMissingBookmarkLevels ? level : parent.getLevel() + 1);
this.push(bookmark);
return bookmark;
}
protected BasePrintBookmark createBookmark(BasePrintBookmark parent, String label,
int pageIndex, String elementAddress, int level)
{
BasePrintBookmark printBookmark = new BasePrintBookmark(label, pageIndex, elementAddress, level);
if (parent != null)
{
parent.addBookmark(printBookmark);
}
return printBookmark;
}
protected void addBookmarks(List elements, int pageIndex, String elementAddress)
{
if (elements != null)
{
elementAddress = elementAddress == null ? "" : elementAddress;
int i = 0;
for (JRPrintElement element : elements)
{
if (element instanceof JRPrintFrame)
{
addBookmarks(((JRPrintFrame)element).getElements(), pageIndex, elementAddress + (elementAddress.length() == 0 ? "" : "_") + i + "_");
}
else if (element instanceof JRPrintAnchor)
{
JRPrintAnchor anchor = (JRPrintAnchor)element;
int level = anchor.getBookmarkLevel();
if (level != JRAnchor.NO_BOOKMARK)
{
String anchorName = anchor.getAnchorName();
BasePrintBookmark bookmark = addBookmark(level, anchorName, pageIndex, elementAddress + i);
// we're keeping a map with bookmarks for elements with late evaluation
// not placing bookmarks for other elements in the map to save some space
if (anchorName == null)// the element could have late evaluation; there's no exact test for it
{
PrintElementId elementId = PrintElementId.forElement(element);
updateableBookmarks.put(elementId, bookmark);
}
}
}
i++;
}
}
}
public void updateBookmark(JRPrintElement element)
{
if (element instanceof JRPrintAnchor)
{
JRPrintAnchor anchor = (JRPrintAnchor) element;
int level = anchor.getBookmarkLevel();
if (level != JRAnchor.NO_BOOKMARK)
{
PrintElementId elementId = PrintElementId.forElement(element);
BasePrintBookmark bookmark = updateableBookmarks.get(elementId);//FIXME remove from the map?
if (bookmark == null)
{
if (log.isDebugEnabled())
{
// this can happen when the element has a delayed evaluation on the same page
log.debug("Cound not find bookmark for " + elementId + " to update");
}
}
else
{
String anchorName = anchor.getAnchorName();
bookmark.setLabel(anchorName);
}
}
}
}
protected List getRootBookmarks()
{
return stack.getFirst().getBookmarks();
}
protected void addBookmark(BasePrintBookmark bookmark, int pageOffset)
{
addBookmark(bookmark.getLevel(), bookmark.getLabel(),
pageOffset + bookmark.getPageIndex(), bookmark.getElementAddress());
}
public void appendBookmarks(BookmarkStack bookmarkStack, int pageOffset)
{
// we're creating new objects though we could add the existing ones and update the page indices
// depth first to preserve parent/children relations in the new objects
for (BookmarkIterator iterator = bookmarkStack.bookmarkIterator(); iterator.hasBookmark(); iterator.next())
{
BasePrintBookmark bookmark = iterator.bookmark();
addBookmark(bookmark, pageOffset);
}
}
public BookmarkIterator bookmarkIterator()
{
return new BookmarkIterator(stack.getFirst());
}
}