From 304308b5d9037b96b774ec74ebb4cd9fe4e026ae Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 23 May 2005 13:07:35 +0000 Subject: [PATCH] Element list logging facility resurrected as an ElementListObserver (see LoggingElementListObserver). DebugHelper registers that logging facility. Add a call to your own test apps to log element lists. Added an additional check implementation for the layout engine checker which allows checking of Knuth element lists using the ElementListObserver. (Usage example: See keep-together2.xml) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198670 13f79535-47bb-0310-9956-ffa450edef68 --- test/java/org/apache/fop/DebugHelper.java | 38 +++ .../fop/layoutengine/ElementListCheck.java | 235 ++++++++++++++++++ .../layoutengine/ElementListCollector.java | 89 +++++++ .../apache/fop/layoutengine/EvalCheck.java | 10 +- .../fop/layoutengine/LayoutEngineCheck.java | 6 +- .../layoutengine/LayoutEngineTestSuite.java | 5 + .../fop/layoutengine/LayoutEngineTester.java | 55 ++-- .../apache/fop/layoutengine/LayoutResult.java | 51 ++++ .../apache/fop/layoutengine/TrueCheck.java | 9 +- .../logging/LoggingElementListObserver.java | 68 +++++ 10 files changed, 527 insertions(+), 39 deletions(-) create mode 100644 test/java/org/apache/fop/DebugHelper.java create mode 100644 test/java/org/apache/fop/layoutengine/ElementListCheck.java create mode 100644 test/java/org/apache/fop/layoutengine/ElementListCollector.java create mode 100644 test/java/org/apache/fop/layoutengine/LayoutResult.java create mode 100644 test/java/org/apache/fop/logging/LoggingElementListObserver.java diff --git a/test/java/org/apache/fop/DebugHelper.java b/test/java/org/apache/fop/DebugHelper.java new file mode 100644 index 000000000..79d0dd87e --- /dev/null +++ b/test/java/org/apache/fop/DebugHelper.java @@ -0,0 +1,38 @@ +/* + * Copyright 2005 Jeremias Maerki + * + * Licensed 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; + +import org.apache.fop.layoutmgr.ElementListObserver; +import org.apache.fop.logging.LoggingElementListObserver; + +/** + * Handles some standard tasks for debugging. + */ +public class DebugHelper { + + private static boolean elObserversRegistered = false; + + public static void registerStandardElementListObservers() { + if (!elObserversRegistered) { + ElementListObserver.addObserver(new LoggingElementListObserver()); + elObserversRegistered = true; + } + } + +} diff --git a/test/java/org/apache/fop/layoutengine/ElementListCheck.java b/test/java/org/apache/fop/layoutengine/ElementListCheck.java new file mode 100644 index 000000000..4c28a0dd9 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/ElementListCheck.java @@ -0,0 +1,235 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.layoutengine; + +import java.util.Iterator; +import java.util.List; + +import org.apache.fop.layoutmgr.KnuthBox; +import org.apache.fop.layoutmgr.KnuthElement; +import org.apache.fop.layoutmgr.KnuthGlue; +import org.apache.fop.layoutmgr.KnuthPenalty; +import org.w3c.dom.CDATASection; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +/** + * Check implementation that checks a Knuth element list. + */ +public class ElementListCheck implements LayoutEngineCheck { + + private String category; + private String id; + private int index = -1; + private Element checkElement; + + /** + * Creates a new instance from a DOM node. + * @param node DOM node that defines this check + */ + public ElementListCheck(Node node) { + this.category = node.getAttributes().getNamedItem("category").getNodeValue(); + if (node.getAttributes().getNamedItem("id") != null) { + this.id = node.getAttributes().getNamedItem("id").getNodeValue(); + } + if (!haveID()) { + if (node.getAttributes().getNamedItem("index") != null) { + String s = node.getAttributes().getNamedItem("index").getNodeValue(); + this.index = Integer.parseInt(s); + } + } + this.checkElement = (Element)node; + } + + /** + * @see org.apache.fop.layoutengine.LayoutEngineCheck + */ + public void check(LayoutResult result) { + ElementListCollector.ElementList elementList = findElementList(result); + NodeList children = checkElement.getChildNodes(); + int pos = -1; + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + if (node instanceof Element) { + pos++; + Element domEl = (Element)node; + KnuthElement knuthEl = (KnuthElement)elementList.getElementList().get(pos); + if ("skip".equals(domEl.getLocalName())) { + pos += Integer.parseInt(getElementText(domEl)) - 1; + } else if ("box".equals(domEl.getLocalName())) { + if (!(knuthEl instanceof KnuthBox)) { + fail("Expected KnuthBox" + + " at position " + pos + + " but got: " + knuthEl.getClass().getName()); + } + if (domEl.getAttribute("w").length() > 0) { + int w = Integer.parseInt(domEl.getAttribute("w")); + if (w != knuthEl.getW()) { + fail("Expected w=" + w + + " at position " + pos + + " but got: " + knuthEl.getW()); + } + } + } else if ("penalty".equals(domEl.getLocalName())) { + if (!(knuthEl instanceof KnuthPenalty)) { + fail("Expected KnuthPenalty " + + " at position " + pos + + " but got: " + knuthEl.getClass().getName()); + } + KnuthPenalty pen = (KnuthPenalty)knuthEl; + if (domEl.getAttribute("w").length() > 0) { + int w = Integer.parseInt(domEl.getAttribute("w")); + if (w != knuthEl.getW()) { + fail("Expected w=" + w + + " at position " + pos + + " but got: " + knuthEl.getW()); + } + } + if (domEl.getAttribute("p").length() > 0) { + int p; + if ("INF".equalsIgnoreCase(domEl.getAttribute("p"))) { + p = KnuthPenalty.INFINITE; + } else if ("INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) { + p = KnuthPenalty.INFINITE; + } else if ("-INF".equalsIgnoreCase(domEl.getAttribute("p"))) { + p = -KnuthPenalty.INFINITE; + } else if ("-INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) { + p = -KnuthPenalty.INFINITE; + } else { + p = Integer.parseInt(domEl.getAttribute("p")); + } + if (p != knuthEl.getP()) { + fail("Expected p=" + p + + " at position " + pos + + " but got: " + knuthEl.getP()); + } + } + if ("true".equals(domEl.getAttribute("flagged"))) { + if (!pen.isFlagged()) { + fail("Expected flagged penalty" + + " at position " + pos); + } + } else if ("false".equals(domEl.getAttribute("flagged"))) { + if (pen.isFlagged()) { + fail("Expected non-flagged penalty" + + " at position " + pos); + } + } + if ("true".equals(domEl.getAttribute("aux"))) { + if (!pen.isAuxiliary()) { + fail("Expected auxiliary penalty" + + " at position " + pos); + } + } else if ("false".equals(domEl.getAttribute("aux"))) { + if (pen.isAuxiliary()) { + fail("Expected non-auxiliary penalty" + + " at position " + pos); + } + } + } else if ("glue".equals(domEl.getLocalName())) { + if (!(knuthEl instanceof KnuthGlue)) { + fail("Expected KnuthGlue" + + " at position " + pos + + " but got: " + knuthEl.getClass().getName()); + } + KnuthGlue glue = (KnuthGlue)knuthEl; + if (domEl.getAttribute("w").length() > 0) { + int w = Integer.parseInt(domEl.getAttribute("w")); + if (w != knuthEl.getW()) { + fail("Expected w=" + w + + " at position " + pos + + " but got: " + knuthEl.getW()); + } + } + //TODO Check stretch and shrink + } else { + throw new IllegalArgumentException("Invalid child node for 'element-list': " + + domEl.getLocalName() + + " at position " + pos + " (" + this + ")"); + } + + } + } + pos++; + if (elementList.getElementList().size() > pos) { + fail("There are " + + (elementList.getElementList().size() - pos) + + " unchecked elements at the end of the list"); + } + } + + private void fail(String msg) { + throw new RuntimeException(msg + " (" + this + ")"); + } + + private boolean haveID() { + return (this.id != null && this.id.length() > 0); + } + + private ElementListCollector.ElementList findElementList(LayoutResult result) { + List candidates = new java.util.ArrayList(); + Iterator iter = result.getElementListCollector().getElementLists().iterator(); + while (iter.hasNext()) { + ElementListCollector.ElementList el = (ElementListCollector.ElementList)iter.next(); + if (el.getCategory().equals(category)) { + if (haveID() && this.id.equals(el.getID())) { + candidates.add(el); + break; + } else if (!haveID()) { + candidates.add(el); + } + } + } + if (candidates.size() == 0) { + throw new ArrayIndexOutOfBoundsException("Requested element list not found"); + } else if (index >= 0) { + return (ElementListCollector.ElementList)candidates.get(index); + } else { + return (ElementListCollector.ElementList)candidates.get(0); + } + } + + private static String getElementText(Element el) { + StringBuffer sb = new StringBuffer(); + NodeList children = el.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + if (node instanceof Text) { + sb.append(((Text)node).getData()); + } else if (node instanceof CDATASection) { + sb.append(((CDATASection)node).getData()); + } + } + return sb.toString(); + } + + /** @see java.lang.Object#toString() */ + public String toString() { + StringBuffer sb = new StringBuffer("element-list"); + sb.append(" category=").append(category); + if (haveID()) { + sb.append(" id=").append(id); + } else if (index >= 0) { + sb.append(" index=").append(index); + } + return sb.toString(); + } +} diff --git a/test/java/org/apache/fop/layoutengine/ElementListCollector.java b/test/java/org/apache/fop/layoutengine/ElementListCollector.java new file mode 100644 index 000000000..3956434f3 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/ElementListCollector.java @@ -0,0 +1,89 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.layoutengine; + +import java.util.List; + +import org.apache.fop.layoutmgr.ElementListObserver.Observer; + +/** + * This class collects element list generated during a FOP processing run. These lists are later + * used to perform automated checks. + */ +public class ElementListCollector implements Observer { + + private List elementLists = new java.util.ArrayList(); + + /** + * Resets the collector. + */ + public void reset() { + elementLists.clear(); + } + + /** + * @return the list of ElementList instances. + */ + public List getElementLists() { + return this.elementLists; + } + + /** @see org.apache.fop.layoutmgr.ElementListObserver.Observer */ + public void observe(List elementList, String category, String id) { + elementLists.add(new ElementList(elementList, category, id)); + } + + /** + * Data object representing an element list along with additional information. + */ + public static class ElementList { + + private List elementList; + private String category; + private String id; + + /** + * Creates a new ElementList instance + * @param elementList the element list + * @param category the category for the element list + * @param id an optional ID + */ + public ElementList(List elementList, String category, String id) { + this.elementList = elementList; + this.category = category; + this.id = id; + } + + /** @return the element list */ + public List getElementList() { + return elementList; + } + + /** @return the category */ + public String getCategory() { + return category; + } + + /** @return the ID, may be null */ + public String getID() { + return id; + } + } + +} \ No newline at end of file diff --git a/test/java/org/apache/fop/layoutengine/EvalCheck.java b/test/java/org/apache/fop/layoutengine/EvalCheck.java index ec15fd8f1..be71e50fb 100644 --- a/test/java/org/apache/fop/layoutengine/EvalCheck.java +++ b/test/java/org/apache/fop/layoutengine/EvalCheck.java @@ -21,9 +21,7 @@ package org.apache.fop.layoutengine; import javax.xml.transform.TransformerException; import org.apache.xpath.XPathAPI; -import org.apache.xpath.objects.XBoolean; import org.apache.xpath.objects.XObject; -import org.w3c.dom.Document; import org.w3c.dom.Node; /** @@ -53,13 +51,11 @@ public class EvalCheck implements LayoutEngineCheck { this.xpath = node.getAttributes().getNamedItem("xpath").getNodeValue(); } - /** - * @see org.apache.fop.layoutengine.LayoutEngineCheck#check(org.w3c.dom.Document) - */ - public void check(Document doc) { + /** @see org.apache.fop.layoutengine.LayoutEngineCheck */ + public void check(LayoutResult result) { XObject res; try { - res = XPathAPI.eval(doc, xpath); + res = XPathAPI.eval(result.getAreaTree(), xpath); } catch (TransformerException e) { throw new RuntimeException("XPath evaluation failed: " + e.getMessage()); } diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java index c04da6537..f912e2001 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java @@ -15,8 +15,6 @@ */ package org.apache.fop.layoutengine; -import org.w3c.dom.Document; - /** * Defines the interface for check operations. */ @@ -24,8 +22,8 @@ public interface LayoutEngineCheck { /** * Called to perform the check. - * @param doc Area Tree DOM to check + * @param result the results from the processing run */ - void check(Document doc); + void check(LayoutResult result); } diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java index f005aeb2c..507189dbf 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java @@ -35,6 +35,7 @@ import org.apache.commons.io.filefilter.NotFileFilter; import org.apache.commons.io.filefilter.PrefixFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; +import org.apache.fop.DebugHelper; import junit.framework.Test; import junit.framework.TestCase; @@ -45,6 +46,10 @@ import junit.framework.TestSuite; */ public class LayoutEngineTestSuite { + static { + DebugHelper.registerStandardElementListObservers(); + } + private static String[] readLinesFromFile(File f) throws IOException { List lines = new java.util.ArrayList(); Reader reader = new FileReader(f); diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java index f8ac4b9e4..c5247adc0 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java @@ -43,6 +43,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.fo.Constants; +import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.render.xml.XMLRenderer; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -68,6 +69,7 @@ public class LayoutEngineTester { static { CHECK_CLASSES.put("true", TrueCheck.class); CHECK_CLASSES.put("eval", EvalCheck.class); + CHECK_CLASSES.put("element-list", ElementListCheck.class); } /** @@ -106,32 +108,41 @@ public class LayoutEngineTester { */ public void runTest(File testFile) throws TransformerException, FOPException, MalformedURLException { - //Setup Transformer to convert the testcase XML to XSL-FO - Transformer transformer = getTestcase2FOStylesheet().newTransformer(); - Source src = new StreamSource(testFile); - //Setup Transformer to convert the area tree to a DOM - TransformerHandler athandler = tfactory.newTransformerHandler(); DOMResult domres = new DOMResult(); - athandler.setResult(domres); - - //Setup FOP for area tree rendering - FOUserAgent ua = new FOUserAgent(); - ua.setBaseURL(testFile.getParentFile().toURL().toString()); - XMLRenderer atrenderer = new XMLRenderer(); - atrenderer.setUserAgent(ua); - atrenderer.setTransformerHandler(athandler); - ua.setRendererOverride(atrenderer); - Fop fop = new Fop(Constants.RENDER_XML, ua); - - SAXResult fores = new SAXResult(fop.getDefaultHandler()); - transformer.transform(src, fores); + + ElementListCollector elCollector = new ElementListCollector(); + ElementListObserver.addObserver(elCollector); + try { + //Setup Transformer to convert the testcase XML to XSL-FO + Transformer transformer = getTestcase2FOStylesheet().newTransformer(); + Source src = new StreamSource(testFile); + + //Setup Transformer to convert the area tree to a DOM + TransformerHandler athandler = tfactory.newTransformerHandler(); + athandler.setResult(domres); + + //Setup FOP for area tree rendering + FOUserAgent ua = new FOUserAgent(); + ua.setBaseURL(testFile.getParentFile().toURL().toString()); + XMLRenderer atrenderer = new XMLRenderer(); + atrenderer.setUserAgent(ua); + atrenderer.setTransformerHandler(athandler); + ua.setRendererOverride(atrenderer); + Fop fop = new Fop(Constants.RENDER_XML, ua); + + SAXResult fores = new SAXResult(fop.getDefaultHandler()); + transformer.transform(src, fores); + } finally { + ElementListObserver.removeObserver(elCollector); + } Document doc = (Document)domres.getNode(); if (this.areaTreeBackupDir != null) { saveAreaTreeXML(doc, new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml")); } - checkAll(testFile, doc); + LayoutResult result = new LayoutResult(doc, elCollector); + checkAll(testFile, result); } /** @@ -159,10 +170,10 @@ public class LayoutEngineTester { /** * Perform all checks on the area tree. * @param testFile Test case XML file - * @param at The generated area tree + * @param result The layout results * @throws TransformerException if a problem occurs in XSLT/JAXP */ - protected void checkAll(File testFile, Document at) throws TransformerException { + protected void checkAll(File testFile, LayoutResult result) throws TransformerException { Transformer transformer = getTestcase2ChecksStylesheet().newTransformer(); Source src = new StreamSource(testFile); DOMResult res = new DOMResult(); @@ -181,7 +192,7 @@ public class LayoutEngineTester { Iterator i = checks.iterator(); while (i.hasNext()) { LayoutEngineCheck check = (LayoutEngineCheck)i.next(); - check.check(at); + check.check(result); } } diff --git a/test/java/org/apache/fop/layoutengine/LayoutResult.java b/test/java/org/apache/fop/layoutengine/LayoutResult.java new file mode 100644 index 000000000..b85ecda1b --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutResult.java @@ -0,0 +1,51 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.layoutengine; + +import org.w3c.dom.Document; + +/** + * This class holds references to all the results from the FOP processing run. + */ +public class LayoutResult { + + private Document areaTree; + private ElementListCollector elCollector; + + /** + * Creates a new LayoutResult instance. + * @param areaTree the area tree DOM + * @param elCollector the element list collector + */ + public LayoutResult(Document areaTree, ElementListCollector elCollector) { + this.areaTree = areaTree; + this.elCollector = elCollector; + } + + /** @return the generated area tree as DOM tree */ + public Document getAreaTree() { + return this.areaTree; + } + + /** @return the element list collector */ + public ElementListCollector getElementListCollector() { + return this.elCollector; + } + +} diff --git a/test/java/org/apache/fop/layoutengine/TrueCheck.java b/test/java/org/apache/fop/layoutengine/TrueCheck.java index 68a791503..8ecaf9b0b 100644 --- a/test/java/org/apache/fop/layoutengine/TrueCheck.java +++ b/test/java/org/apache/fop/layoutengine/TrueCheck.java @@ -23,7 +23,6 @@ import javax.xml.transform.TransformerException; import org.apache.xpath.XPathAPI; import org.apache.xpath.objects.XBoolean; import org.apache.xpath.objects.XObject; -import org.w3c.dom.Document; import org.w3c.dom.Node; /** @@ -49,13 +48,11 @@ public class TrueCheck implements LayoutEngineCheck { this.xpath = node.getAttributes().getNamedItem("xpath").getNodeValue(); } - /** - * @see org.apache.fop.layoutengine.LayoutEngineCheck#check(org.w3c.dom.Document) - */ - public void check(Document doc) { + /** @see org.apache.fop.layoutengine.LayoutEngineCheck */ + public void check(LayoutResult result) { XObject res; try { - res = XPathAPI.eval(doc, xpath); + res = XPathAPI.eval(result.getAreaTree(), xpath); } catch (TransformerException e) { throw new RuntimeException("XPath evaluation failed: " + e.getMessage()); } diff --git a/test/java/org/apache/fop/logging/LoggingElementListObserver.java b/test/java/org/apache/fop/logging/LoggingElementListObserver.java new file mode 100644 index 000000000..6bc9933a0 --- /dev/null +++ b/test/java/org/apache/fop/logging/LoggingElementListObserver.java @@ -0,0 +1,68 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed 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.logging; + +import java.util.List; +import java.util.ListIterator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.layoutmgr.KnuthElement; +import org.apache.fop.layoutmgr.ElementListObserver.Observer; + +/** + *

Logs all observed element lists. + *

+ *

You can enable/disabled individual categories separately, for example for JDK 1.4 logging: + *

+ *

org.apache.fop.logging.LoggingElementListObserver.level = INFO

+ *

org.apache.fop.logging.LoggingElementListObserver.table-cell.level = FINE

+ */ +public class LoggingElementListObserver implements Observer { + + /** @see org.apache.fop.layoutmgr.ElementListObserver.Observer */ + public void observe(List elementList, String category, String id) { + Log log = LogFactory.getLog(LoggingElementListObserver.class.getName() + "." + category); + if (!log.isDebugEnabled()) { + return; + } + log.debug(" "); + log.debug("ElementList: category=" + category + ", id=" + id); + ListIterator tempIter = elementList.listIterator(); + KnuthElement temp; + while (tempIter.hasNext()) { + temp = (KnuthElement) tempIter.next(); + if (temp.isBox()) { + log.debug(tempIter.previousIndex() + + ") " + temp); + } else if (temp.isGlue()) { + log.debug(tempIter.previousIndex() + + ") " + temp); + } else { + log.debug(tempIter.previousIndex() + + ") " + temp); + } + if (temp.getPosition() != null) { + log.debug(" " + temp.getPosition()); + } + } + log.debug(" "); + } + +} -- 2.39.5