git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195068 13f79535-47bb-0310-9956-ffa450edef68pull/30/head
public void run() throws FOPException { | public void run() throws FOPException { | ||||
Driver driver = new Driver(); | Driver driver = new Driver(); | ||||
driver.setLogger(log); | |||||
setupLogger(driver); | |||||
if (errorDump) { | if (errorDump) { | ||||
driver.setErrorDump(true); | driver.setErrorDump(true); | ||||
} | } | ||||
URL url = getClass().getResource(path); | URL url = getClass().getResource(path); | ||||
in = url.openStream(); | in = url.openStream(); | ||||
} catch (Exception ex) { | } catch (Exception ex) { | ||||
log.error("Can't find URL to: <" + path + "> " | |||||
getLogger().error("Can't find URL to: <" + path + "> " | |||||
+ ex.getMessage(), ex); | + ex.getMessage(), ex); | ||||
} | } | ||||
return new SecureResourceBundle(in); | return new SecureResourceBundle(in); |
default: | default: | ||||
starter = new CommandLineStarter(this); | starter = new CommandLineStarter(this); | ||||
} | } | ||||
starter.setLogger(log); | |||||
starter.enableLogging(log); | |||||
return starter; | return starter; | ||||
} | } | ||||
public void run() throws FOPException { | public void run() throws FOPException { | ||||
String version = Version.getVersion(); | String version = Version.getVersion(); | ||||
log.info(version); | |||||
getLogger().info(version); | |||||
XMLReader parser = inputHandler.getParser(); | XMLReader parser = inputHandler.getParser(); | ||||
setParserFeatures(parser); | setParserFeatures(parser); | ||||
Driver driver = new Driver(); | Driver driver = new Driver(); | ||||
driver.setLogger(log); | |||||
setupLogger(driver); | |||||
driver.initialize(); | driver.initialize(); | ||||
if (errorDump) { | if (errorDump) { |
// Avalon | // Avalon | ||||
import org.apache.avalon.framework.logger.ConsoleLogger; | import org.apache.avalon.framework.logger.ConsoleLogger; | ||||
import org.apache.avalon.framework.logger.Logger; | import org.apache.avalon.framework.logger.Logger; | ||||
import org.apache.avalon.framework.logger.LogEnabled; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
// DOM | // DOM | ||||
import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||
* <PRE> | * <PRE> | ||||
* Driver driver = new Driver(new InputSource (args[0]), | * Driver driver = new Driver(new InputSource (args[0]), | ||||
* new FileOutputStream(args[1])); | * new FileOutputStream(args[1])); | ||||
* driver.enableLogging(myLogger); //optional | |||||
* driver.setRenderer(RENDER_PDF); | * driver.setRenderer(RENDER_PDF); | ||||
* driver.run(); | * driver.run(); | ||||
* </PRE> | * </PRE> | ||||
* | * | ||||
* <PRE> | * <PRE> | ||||
* Driver driver = new Driver(); | * Driver driver = new Driver(); | ||||
* driver.enableLogging(myLogger); //optional | |||||
* driver.setRenderer(new org.apache.fop.render.awt.AWTRenderer(translator)); | * driver.setRenderer(new org.apache.fop.render.awt.AWTRenderer(translator)); | ||||
* driver.render(parser, fileInputSource(args[0])); | * driver.render(parser, fileInputSource(args[0])); | ||||
* </PRE> | * </PRE> | ||||
*/ | */ | ||||
public class Driver { | |||||
public class Driver implements LogEnabled { | |||||
/** | /** | ||||
* Render to PDF. OutputStream must be set | * Render to PDF. OutputStream must be set | ||||
/** | /** | ||||
* the structure handler | * the structure handler | ||||
*/ | |||||
*/ | |||||
private StructureHandler structHandler; | private StructureHandler structHandler; | ||||
/** | /** | ||||
/** | /** | ||||
* the system resources that FOP will use | * the system resources that FOP will use | ||||
*/ | */ | ||||
private Logger log; | |||||
private Logger log = null; | |||||
private FOUserAgent userAgent = null; | private FOUserAgent userAgent = null; | ||||
public static final String getParserClassName() { | public static final String getParserClassName() { | ||||
try { | |||||
try { | |||||
return javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader().getClass().getName(); | return javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader().getClass().getName(); | ||||
} catch (javax.xml.parsers.ParserConfigurationException e) { | } catch (javax.xml.parsers.ParserConfigurationException e) { | ||||
return null; | return null; | ||||
public void initialize() { | public void initialize() { | ||||
_stream = null; | _stream = null; | ||||
_treeBuilder = new FOTreeBuilder(); | |||||
_treeBuilder = new FOTreeBuilder(); | |||||
_treeBuilder.setUserAgent(getUserAgent()); | _treeBuilder.setUserAgent(getUserAgent()); | ||||
setupDefaultMappings(); | setupDefaultMappings(); | ||||
} | } | ||||
private FOUserAgent getUserAgent() { | private FOUserAgent getUserAgent() { | ||||
if(userAgent == null) { | if(userAgent == null) { | ||||
userAgent = new FOUserAgent(); | userAgent = new FOUserAgent(); | ||||
userAgent.setLogger(getLogger()); | |||||
userAgent.enableLogging(getLogger()); | |||||
String base = org.apache.fop.configuration.Configuration.getStringValue("baseDir"); | String base = org.apache.fop.configuration.Configuration.getStringValue("baseDir"); | ||||
userAgent.setBaseURL(base); | userAgent.setBaseURL(base); | ||||
} | } | ||||
return userAgent; | return userAgent; | ||||
} | } | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
public void enableLogging(Logger log) { | |||||
if (this.log == null) { | |||||
this.log = log; | |||||
} else { | |||||
getLogger().warn("Logger is already set! Won't use the new logger."); | |||||
} | |||||
} | } | ||||
private Logger getLogger() { | |||||
if(log == null) { | |||||
log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); | |||||
log.error("Logger not set"); | |||||
} | |||||
return log; | |||||
protected Logger getLogger() { | |||||
if(this.log == null) { | |||||
this.log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); | |||||
this.log.error("Logger not set. Using ConsoleLogger as default."); | |||||
} | |||||
return this.log; | |||||
} | } | ||||
/** | /** | ||||
public void setRenderer(int renderer) throws IllegalArgumentException { | public void setRenderer(int renderer) throws IllegalArgumentException { | ||||
switch (renderer) { | switch (renderer) { | ||||
case RENDER_PDF: | case RENDER_PDF: | ||||
setRenderer(new org.apache.fop.render.pdf.PDFRenderer()); | |||||
setRenderer("org.apache.fop.render.pdf.PDFRenderer"); | |||||
break; | break; | ||||
case RENDER_AWT: | case RENDER_AWT: | ||||
throw new IllegalArgumentException("Use renderer form of setRenderer() for AWT"); | throw new IllegalArgumentException("Use renderer form of setRenderer() for AWT"); | ||||
case RENDER_PRINT: | case RENDER_PRINT: | ||||
throw new IllegalArgumentException("Use renderer form of setRenderer() for PRINT"); | throw new IllegalArgumentException("Use renderer form of setRenderer() for PRINT"); | ||||
case RENDER_PCL: | case RENDER_PCL: | ||||
setRenderer(new org.apache.fop.render.pcl.PCLRenderer()); | |||||
setRenderer("org.apache.fop.render.pcl.PCLRenderer"); | |||||
break; | break; | ||||
case RENDER_PS: | case RENDER_PS: | ||||
setRenderer(new org.apache.fop.render.ps.PSRenderer()); | |||||
setRenderer("org.apache.fop.render.ps.PSRenderer"); | |||||
break; | break; | ||||
case RENDER_TXT: | case RENDER_TXT: | ||||
setRenderer(new org.apache.fop.render.txt.TXTRenderer()); | |||||
setRenderer("org.apache.fop.render.txt.TXTRenderer()"); | |||||
break; | break; | ||||
case RENDER_MIF: | case RENDER_MIF: | ||||
//structHandler = new org.apache.fop.mif.MIFHandler(_stream); | //structHandler = new org.apache.fop.mif.MIFHandler(_stream); | ||||
break; | break; | ||||
case RENDER_XML: | case RENDER_XML: | ||||
setRenderer(new org.apache.fop.render.xml.XMLRenderer()); | |||||
setRenderer("org.apache.fop.render.xml.XMLRenderer"); | |||||
break; | break; | ||||
case RENDER_SVG: | case RENDER_SVG: | ||||
setRenderer(new org.apache.fop.render.svg.SVGRenderer()); | |||||
setRenderer("org.apache.fop.render.svg.SVGRenderer"); | |||||
break; | break; | ||||
default: | default: | ||||
throw new IllegalArgumentException("Unknown renderer type"); | throw new IllegalArgumentException("Unknown renderer type"); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Set the Renderer to use | |||||
* @param renderer the renderer instance to use | |||||
* Set the Renderer to use. | |||||
* @param renderer the renderer instance to use (Note: Logger must be set at this point) | |||||
*/ | */ | ||||
public void setRenderer(Renderer renderer) { | public void setRenderer(Renderer renderer) { | ||||
renderer.setLogger(getLogger()); | |||||
renderer.setUserAgent(getUserAgent()); | renderer.setUserAgent(getUserAgent()); | ||||
_renderer = renderer; | _renderer = renderer; | ||||
} | } | ||||
try { | try { | ||||
_renderer = | _renderer = | ||||
(Renderer)Class.forName(rendererClassName).newInstance(); | (Renderer)Class.forName(rendererClassName).newInstance(); | ||||
if (_renderer instanceof LogEnabled) { | |||||
((LogEnabled)_renderer).enableLogging(getLogger()); | |||||
} | |||||
_renderer.setProducer(Version.getVersion()); | _renderer.setProducer(Version.getVersion()); | ||||
} catch (ClassNotFoundException e) { | } catch (ClassNotFoundException e) { | ||||
throw new IllegalArgumentException("Could not find " | throw new IllegalArgumentException("Could not find " | ||||
} else { | } else { | ||||
structHandler = new org.apache.fop.mif.MIFHandler(_stream); | structHandler = new org.apache.fop.mif.MIFHandler(_stream); | ||||
} | } | ||||
structHandler.setLogger(getLogger()); | |||||
_treeBuilder.setLogger(getLogger()); | |||||
structHandler.enableLogging(getLogger()); | |||||
_treeBuilder.setUserAgent(getUserAgent()); | _treeBuilder.setUserAgent(getUserAgent()); | ||||
_treeBuilder.setStructHandler(structHandler); | _treeBuilder.setStructHandler(structHandler); | ||||
*/ | */ | ||||
public void dumpError(Exception e) { | public void dumpError(Exception e) { | ||||
if (_errorDump) { | if (_errorDump) { | ||||
Logger log = getLogger(); | |||||
if (e instanceof SAXException) { | if (e instanceof SAXException) { | ||||
log.error("", e); | |||||
getLogger().error("", e); | |||||
if (((SAXException)e).getException() != null) { | if (((SAXException)e).getException() != null) { | ||||
log.error("", ((SAXException)e).getException()); | |||||
getLogger().error("", ((SAXException)e).getException()); | |||||
} | } | ||||
} else if (e instanceof FOPException) { | } else if (e instanceof FOPException) { | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
if (((FOPException)e).getException() != null) { | if (((FOPException)e).getException() != null) { | ||||
log.error("", ((FOPException)e).getException()); | |||||
getLogger().error("", ((FOPException)e).getException()); | |||||
} | } | ||||
} else { | } else { | ||||
log.error("", e); | |||||
getLogger().error("", e); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
String serviceFile = "META-INF/services/" + cls.getName(); | String serviceFile = "META-INF/services/" + cls.getName(); | ||||
// System.out.println("File: " + serviceFile); | |||||
// getLogger().debug("File: " + serviceFile); | |||||
Vector v = (Vector)providerMap.get(serviceFile); | Vector v = (Vector)providerMap.get(serviceFile); | ||||
if (v != null) | if (v != null) | ||||
while (e.hasMoreElements()) { | while (e.hasMoreElements()) { | ||||
try { | try { | ||||
java.net.URL u = (java.net.URL)e.nextElement(); | java.net.URL u = (java.net.URL)e.nextElement(); | ||||
// System.out.println("URL: " + u); | |||||
//getLogger().debug("URL: " + u); | |||||
InputStream is = u.openStream(); | InputStream is = u.openStream(); | ||||
Reader r = new InputStreamReader(is, "UTF-8"); | Reader r = new InputStreamReader(is, "UTF-8"); | ||||
line = br.readLine(); | line = br.readLine(); | ||||
continue; | continue; | ||||
} | } | ||||
// System.out.println("Line: " + line); | |||||
// getLogger().debug("Line: " + line); | |||||
// Try and load the class | // Try and load the class | ||||
// Object obj = cl.loadClass(line).newInstance(); | // Object obj = cl.loadClass(line).newInstance(); |
long memoryNow = runtime.totalMemory() - runtime.freeMemory(); | long memoryNow = runtime.totalMemory() - runtime.freeMemory(); | ||||
long memoryUsed = (memoryNow - initialMemory) / 1024L; | long memoryUsed = (memoryNow - initialMemory) / 1024L; | ||||
log.debug("Initial heap size: " + (initialMemory / 1024L) + "Kb"); | |||||
log.debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); | |||||
log.debug("Total memory used: " + memoryUsed + "Kb"); | |||||
if (!MEM_PROFILE_WITH_GC) { | |||||
log.debug(" Memory use is indicative; no GC was performed"); | |||||
log.debug(" These figures should not be used comparatively"); | |||||
if (getLogger().isDebugEnabled()) { | |||||
getLogger().debug("Initial heap size: " + (initialMemory / 1024L) + "Kb"); | |||||
getLogger().debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); | |||||
getLogger().debug("Total memory used: " + memoryUsed + "Kb"); | |||||
if (!MEM_PROFILE_WITH_GC) { | |||||
getLogger().debug(" Memory use is indicative; no GC was performed"); | |||||
getLogger().debug(" These figures should not be used comparatively"); | |||||
} | |||||
} | } | ||||
long timeUsed = System.currentTimeMillis() - startTime; | long timeUsed = System.currentTimeMillis() - startTime; | ||||
log.debug("Total time used: " + timeUsed + "ms"); | |||||
log.debug("Pages rendered: " + pageCount); | |||||
//log.debug("Avg render time: " + (timeUsed / pageCount) + "ms/page"); | |||||
if (getLogger().isDebugEnabled()) { | |||||
getLogger().debug("Total time used: " + timeUsed + "ms"); | |||||
getLogger().debug("Pages rendered: " + pageCount); | |||||
if (pageCount > 0) { | |||||
getLogger().debug("Avg render time: " + (timeUsed / pageCount) + "ms/page"); | |||||
} | |||||
} | |||||
} | } | ||||
public void startPageSequence(PageSequence pageSeq, org.apache.fop.fo.Title seqTitle, LayoutMasterSet lms) { | public void startPageSequence(PageSequence pageSeq, org.apache.fop.fo.Title seqTitle, LayoutMasterSet lms) { |
package org.apache.fop.apps; | package org.apache.fop.apps; | ||||
// Avalon | // Avalon | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
// SAX | // SAX | ||||
import org.xml.sax.XMLReader; | import org.xml.sax.XMLReader; | ||||
* Creates a SAX Parser (defaulting to Xerces). | * Creates a SAX Parser (defaulting to Xerces). | ||||
* | * | ||||
*/ | */ | ||||
public abstract class Starter { | |||||
public abstract class Starter extends AbstractLogEnabled { | |||||
Options options; | Options options; | ||||
InputHandler inputHandler; | InputHandler inputHandler; | ||||
protected Logger log; | |||||
public Starter() throws FOPException { | public Starter() throws FOPException { | ||||
options = new Options(); | options = new Options(); | ||||
} | } | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
} | |||||
public void setInputHandler(InputHandler inputHandler) { | public void setInputHandler(InputHandler inputHandler) { | ||||
this.inputHandler = inputHandler; | this.inputHandler = inputHandler; | ||||
} | } |
// Java | // Java | ||||
import java.util.HashSet; | import java.util.HashSet; | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
// Avalon | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
// FOP | |||||
import org.apache.fop.fo.pagination.*; | import org.apache.fop.fo.pagination.*; | ||||
import org.apache.fop.fo.flow.*; | import org.apache.fop.fo.flow.*; | ||||
import org.apache.fop.fo.*; | import org.apache.fop.fo.*; | ||||
* Sub-classes can then implement various methods to handle | * Sub-classes can then implement various methods to handle | ||||
* the FO Tree when the SAX events occur. | * the FO Tree when the SAX events occur. | ||||
*/ | */ | ||||
public class StructureHandler { | |||||
public class StructureHandler extends AbstractLogEnabled { | |||||
/** | /** | ||||
The current set of id's in the FO tree | The current set of id's in the FO tree | ||||
This is used so we know if the FO tree contains duplicates | This is used so we know if the FO tree contains duplicates | ||||
*/ | */ | ||||
private HashSet idReferences = new HashSet(); | private HashSet idReferences = new HashSet(); | ||||
protected Logger log; | |||||
public StructureHandler() { | public StructureHandler() { | ||||
} | } | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
} | |||||
public HashSet getIDReferences() { | public HashSet getIDReferences() { | ||||
return idReferences; | return idReferences; | ||||
} | } |
} | } | ||||
public void end() { | public void end() { | ||||
log.debug("adding bookmarks to area tree"); | |||||
getLogger().debug("adding bookmarks to area tree"); | |||||
data = new BookmarkData(); | data = new BookmarkData(); | ||||
for(int count = 0; count < outlines.size(); count++) { | for(int count = 0; count < outlines.size(); count++) { | ||||
Outline out = (Outline)outlines.get(count); | Outline out = (Outline)outlines.get(count); |
externalDestination = | externalDestination = | ||||
attlist.getValue("external-destination"); | attlist.getValue("external-destination"); | ||||
if (externalDestination != null &&!externalDestination.equals("")) { | if (externalDestination != null &&!externalDestination.equals("")) { | ||||
log.warn("fox:outline external-destination not supported currently."); | |||||
getLogger().warn("fox:outline external-destination not supported currently."); | |||||
} | } | ||||
if (internalDestination == null || internalDestination.equals("")) { | if (internalDestination == null || internalDestination.equals("")) { | ||||
log.warn("fox:outline requires an internal-destination."); | |||||
getLogger().warn("fox:outline requires an internal-destination."); | |||||
} | } | ||||
} | } |
ICC_Profile iccProfile = ICC_Profile.getInstance(is); | ICC_Profile iccProfile = ICC_Profile.getInstance(is); | ||||
colorSpace = new ICC_ColorSpace(iccProfile); | colorSpace = new ICC_ColorSpace(iccProfile); | ||||
} catch(IOException ioe) { | } catch(IOException ioe) { | ||||
log.error("Could not read Color Profile src", ioe); | |||||
getLogger().error("Could not read Color Profile src", ioe); | |||||
} catch(IllegalArgumentException iae) { | } catch(IllegalArgumentException iae) { | ||||
log.error("Color Profile src not an ICC Profile", iae); | |||||
getLogger().error("Color Profile src not an ICC Profile", iae); | |||||
} | } | ||||
} | } | ||||
} | } |
} | } | ||||
if(colorProfiles.get(cp.getProfileName()) != null) { | if(colorProfiles.get(cp.getProfileName()) != null) { | ||||
// duplicate names | // duplicate names | ||||
log.warn("Duplicate fo:color-profile profile name : " + cp.getProfileName()); | |||||
getLogger().warn("Duplicate fo:color-profile profile name : " + cp.getProfileName()); | |||||
} | } | ||||
colorProfiles.put(cp.getProfileName(), cp); | colorProfiles.put(cp.getProfileName(), cp); | ||||
} else { | } else { | ||||
log.warn("color-profile-name required for color profile"); | |||||
getLogger().warn("color-profile-name required for color profile"); | |||||
} | } | ||||
} else if(node instanceof XMLObj) { | } else if(node instanceof XMLObj) { | ||||
if(external == null) { | if(external == null) { | ||||
} | } | ||||
external.add(node); | external.add(node); | ||||
} else { | } else { | ||||
log.warn("invalid element " + node.getName() + "inside declarations"); | |||||
getLogger().warn("invalid element " + node.getName() + "inside declarations"); | |||||
} | } | ||||
} | } | ||||
children = null; | children = null; |
protected FONode parent; | protected FONode parent; | ||||
protected String name; | protected String name; | ||||
protected Logger log; | |||||
protected FONode(FONode parent) { | protected FONode(FONode parent) { | ||||
this.parent = parent; | this.parent = parent; | ||||
} | } | ||||
name = str; | name = str; | ||||
} | } | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
public Logger getLogger() { | |||||
return userAgent.getLogger(); | |||||
} | } | ||||
public void setUserAgent(FOUserAgent ua) { | public void setUserAgent(FOUserAgent ua) { | ||||
* @return A ListIterator. | * @return A ListIterator. | ||||
*/ | */ | ||||
public ListIterator getChildren() { | public ListIterator getChildren() { | ||||
return null; | |||||
return null; | |||||
} | } | ||||
/** | /** | ||||
* this FObj. | * this FObj. | ||||
*/ | */ | ||||
public ListIterator getChildren(FONode childNode) { | public ListIterator getChildren(FONode childNode) { | ||||
return null; | |||||
return null; | |||||
} | } | ||||
public CharIterator charIterator() { | public CharIterator charIterator() { | ||||
return new OneCharIterator(CharUtilities.CODE_EOT); | |||||
return new OneCharIterator(CharUtilities.CODE_EOT); | |||||
} | } | ||||
} | } |
/** | /** | ||||
* SAX Handler that builds the formatting object tree. | * SAX Handler that builds the formatting object tree. | ||||
* | |||||
* | |||||
* Modified by Mark Lillywhite mark-fop@inomial.com. Now uses | * Modified by Mark Lillywhite mark-fop@inomial.com. Now uses | ||||
* StreamRenderer to automagically render the document as | * StreamRenderer to automagically render the document as | ||||
* soon as it receives a page-sequence end-tag. Also, | * soon as it receives a page-sequence end-tag. Also, | ||||
* (mark-fop@inomial.com) | * (mark-fop@inomial.com) | ||||
*/ | */ | ||||
private StructureHandler structHandler; | private StructureHandler structHandler; | ||||
private Logger log; | |||||
private FOUserAgent userAgent; | private FOUserAgent userAgent; | ||||
public FOTreeBuilder() {} | public FOTreeBuilder() {} | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
public Logger getLogger() { | |||||
return userAgent.getLogger(); | |||||
} | } | ||||
public void setUserAgent(FOUserAgent ua) { | public void setUserAgent(FOUserAgent ua) { | ||||
public void startDocument() | public void startDocument() | ||||
throws SAXException { | throws SAXException { | ||||
rootFObj = null; // allows FOTreeBuilder to be reused | rootFObj = null; // allows FOTreeBuilder to be reused | ||||
log.info("building formatting object tree"); | |||||
getLogger().info("building formatting object tree"); | |||||
structHandler.startDocument(); | structHandler.startDocument(); | ||||
} | } | ||||
public void endDocument() | public void endDocument() | ||||
throws SAXException { | throws SAXException { | ||||
log.info("Parsing of document complete, stopping renderer"); | |||||
getLogger().info("Parsing of document complete, stopping renderer"); | |||||
structHandler.endDocument(); | structHandler.endDocument(); | ||||
} | } | ||||
String fullName = uri + "^" + localName; | String fullName = uri + "^" + localName; | ||||
if (!this.unknownFOs.containsKey(fullName)) { | if (!this.unknownFOs.containsKey(fullName)) { | ||||
this.unknownFOs.put(fullName, ""); | this.unknownFOs.put(fullName, ""); | ||||
log.warn("Unknown formatting object " | |||||
getLogger().warn("Unknown formatting object " | |||||
+ fullName); | + fullName); | ||||
} | } | ||||
if(namespaces.contains(uri.intern())) { | if(namespaces.contains(uri.intern())) { | ||||
try { | try { | ||||
fobj = fobjMaker.make(currentFObj); | fobj = fobjMaker.make(currentFObj); | ||||
fobj.setName(localName); | fobj.setName(localName); | ||||
fobj.setLogger(log); | |||||
// set the user agent for resolving user agent values | // set the user agent for resolving user agent values | ||||
fobj.setUserAgent(userAgent); | fobj.setUserAgent(userAgent); | ||||
// set the stream renderer so that appropriate | // set the stream renderer so that appropriate |
import org.apache.fop.render.XMLHandler; | import org.apache.fop.render.XMLHandler; | ||||
import org.apache.fop.render.RendererContext; | import org.apache.fop.render.RendererContext; | ||||
import org.apache.avalon.framework.logger.LogEnabled; | |||||
import org.apache.avalon.framework.logger.Logger; | import org.apache.avalon.framework.logger.Logger; | ||||
import org.w3c.dom.*; | import org.w3c.dom.*; | ||||
* These areas may contain resolveable areas that will be processed | * These areas may contain resolveable areas that will be processed | ||||
* with other resolveable areas | * with other resolveable areas | ||||
*/ | */ | ||||
public class FOUserAgent { | |||||
public class FOUserAgent implements LogEnabled { | |||||
HashMap defaults = new HashMap(); | HashMap defaults = new HashMap(); | ||||
HashMap handlers = new HashMap(); | HashMap handlers = new HashMap(); | ||||
Logger log; | Logger log; | ||||
String base; | String base; | ||||
public void setLogger(Logger logger) { | |||||
public void enableLogging(Logger logger) { | |||||
log = logger; | log = logger; | ||||
} | } | ||||
mh.put(ns, handler); | mh.put(ns, handler); | ||||
} | } | ||||
/** | |||||
/** | |||||
* Render the xml document with the given xml namespace. | * Render the xml document with the given xml namespace. | ||||
* The Render Context is by the handle to render into the current | * The Render Context is by the handle to render into the current | ||||
* rendering target. | * rendering target. | ||||
handler.handleXML(ctx, doc, namespace); | handler.handleXML(ctx, doc, namespace); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
// could not handle document | // could not handle document | ||||
log.error("Could not render XML", t); | |||||
getLogger().error("Could not render XML", t); | |||||
} | } | ||||
} else { | } else { | ||||
// no handler found for document | // no handler found for document | ||||
log.debug("No handler defined for XML: " + namespace); | |||||
getLogger().debug("No handler defined for XML: " + namespace); | |||||
} | } | ||||
} | } | ||||
} | } |
id = str; | id = str; | ||||
idrefs.add(id); | idrefs.add(id); | ||||
} else { | } else { | ||||
log.warn("duplicate id:" + str + " ignored"); | |||||
getLogger().warn("duplicate id:" + str + " ignored"); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!markers.containsKey(mcname) && children.isEmpty()) { | if (!markers.containsKey(mcname) && children.isEmpty()) { | ||||
markers.put(mcname, marker); | markers.put(mcname, marker); | ||||
} else { | } else { | ||||
log.error("fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent"); | |||||
getLogger().error("fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent"); | |||||
throw new FOPException( | throw new FOPException( | ||||
"fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent"); | "fo:marker must be an initial child," + "and 'marker-class-name' must be unique for same parent"); | ||||
} | } |
public void addLayoutManager(List lms) { | public void addLayoutManager(List lms) { | ||||
lms.add(new InlineStackingBPLayoutManager(this, | lms.add(new InlineStackingBPLayoutManager(this, | ||||
new LMiter(children.listIterator()))); | |||||
new LMiter(children.listIterator()))); | |||||
// set start and end properties for this element, id, etc. | // set start and end properties for this element, id, etc. | ||||
// int numChildren = this.children.size(); | // int numChildren = this.children.size(); | ||||
// for (int i = 0; i < numChildren; i++) { | // for (int i = 0; i < numChildren; i++) { | ||||
protected void addCharacters(char data[], int start, int length) { | protected void addCharacters(char data[], int start, int length) { | ||||
if(textInfo == null) { | if(textInfo == null) { | ||||
// Really only need one of these, but need to get fontInfo | |||||
// stored in propMgr for later use. | |||||
propMgr.setFontInfo(fontInfo); | |||||
textInfo = propMgr.getTextLayoutProps(fontInfo); | |||||
// Really only need one of these, but need to get fontInfo | |||||
// stored in propMgr for later use. | |||||
propMgr.setFontInfo(fontInfo); | |||||
textInfo = propMgr.getTextLayoutProps(fontInfo); | |||||
} | } | ||||
FOText ft = new FOText(data, start, length, textInfo); | FOText ft = new FOText(data, start, length, textInfo); | ||||
ft.setLogger(log); | |||||
ft.setUserAgent(userAgent); | |||||
ft.setStructHandler(structHandler); | ft.setStructHandler(structHandler); | ||||
addChild(ft); | addChild(ft); | ||||
} | } |
import org.apache.fop.apps.FOPException; | import org.apache.fop.apps.FOPException; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
public class Property { | public class Property { | ||||
public static class Maker { | public static class Maker { | ||||
return setSubprop(baseProp, partName, p); | return setSubprop(baseProp, partName, p); | ||||
} | } | ||||
} else { | } else { | ||||
//log.error("compound property component " | |||||
//getLogger().error("compound property component " | |||||
// + partName + " unknown."); | // + partName + " unknown."); | ||||
} | } | ||||
return baseProp; | return baseProp; | ||||
} | } | ||||
} catch (FOPException e) { | } catch (FOPException e) { | ||||
//log.error("convertShorthandProperty caught FOPException " | |||||
//getLogger().error("convertShorthandProperty caught FOPException " | |||||
// + e); | // + e); | ||||
} catch (org.apache.fop.fo.expr.PropertyException propEx) { | } catch (org.apache.fop.fo.expr.PropertyException propEx) { | ||||
//log.error("convertShorthandProperty caught PropertyException " | |||||
//getLogger().error("convertShorthandProperty caught PropertyException " | |||||
// + propEx); | // + propEx); | ||||
} | } | ||||
if (pret != null) { | if (pret != null) { | ||||
return make(propertyList, specVal, | return make(propertyList, specVal, | ||||
propertyList.getParentFObj()); | propertyList.getParentFObj()); | ||||
} catch (FOPException e) { | } catch (FOPException e) { | ||||
//log.error("Error computing property value for " | |||||
//getLogger()error("Error computing property value for " | |||||
// + propName + " from " | // + propName + " from " | ||||
// + specVal); | // + specVal); | ||||
return null; | return null; | ||||
*/ | */ | ||||
private String specVal; | private String specVal; | ||||
protected Logger log; | |||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
} | |||||
/** | /** | ||||
* Set the original value specified for the property attribute. | * Set the original value specified for the property attribute. | ||||
* @param specVal The specified value. | * @param specVal The specified value. |
} | } | ||||
public void setup() { | public void setup() { | ||||
log.debug("This element \"" + this.name | |||||
getLogger().debug("This element \"" + this.name | |||||
+ "\" is not yet implemented."); | + "\" is not yet implemented."); | ||||
} | } | ||||
} | } | ||||
public void setup() { | public void setup() { | ||||
log.debug("Layout Unknown element"); | |||||
getLogger().debug("Layout Unknown element"); | |||||
} | } | ||||
} | } |
// in theory someone might want to embed some defined | // in theory someone might want to embed some defined | ||||
// xml (eg. fo) inside the foreign xml | // xml (eg. fo) inside the foreign xml | ||||
// they could use a different namespace | // they could use a different namespace | ||||
log.debug("Invalid element: " + child.getName() + " inside foreign xml markup"); | |||||
getLogger().debug("Invalid element: " + child.getName() + " inside foreign xml markup"); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
private void handleWhiteSpace() { | private void handleWhiteSpace() { | ||||
log.debug("fo:block: handleWhiteSpace"); | |||||
getLogger().debug("fo:block: handleWhiteSpace"); | |||||
if (firstInlineChild != null) { | if (firstInlineChild != null) { | ||||
boolean bInWS = false; | boolean bInWS = false; | ||||
boolean bPrevWasLF = false; | boolean bPrevWasLF = false; |
cheight = (int)(fopimage.getHeight() * 1000); | cheight = (int)(fopimage.getHeight() * 1000); | ||||
} | } | ||||
if(scaling == Scaling.UNIFORM) { | if(scaling == Scaling.UNIFORM) { | ||||
// adjust the larger | |||||
// adjust the larger | |||||
double rat1 = cwidth / (fopimage.getWidth() * 1000f); | double rat1 = cwidth / (fopimage.getWidth() * 1000f); | ||||
double rat2 = cheight / (fopimage.getHeight() * 1000f); | double rat2 = cheight / (fopimage.getHeight() * 1000f); | ||||
if(rat1 < rat2) { | if(rat1 < rat2) { | ||||
if(overflow == Overflow.HIDDEN) { | if(overflow == Overflow.HIDDEN) { | ||||
clip = true; | clip = true; | ||||
} else if(overflow == Overflow.ERROR_IF_OVERFLOW) { | } else if(overflow == Overflow.ERROR_IF_OVERFLOW) { | ||||
log.error("Image: " + url + " overflows the viewport"); | |||||
getLogger().error("Image: " + url + " overflows the viewport"); | |||||
clip = true; | clip = true; | ||||
} | } | ||||
} | } | ||||
// Common Accessibility Properties | // Common Accessibility Properties | ||||
AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); | AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); | ||||
// Common Aural Properties | |||||
// Common Aural Properties | |||||
AuralProps mAurProps = propMgr.getAuralProps(); | AuralProps mAurProps = propMgr.getAuralProps(); | ||||
// Common Border, Padding, and Background Properties | // Common Border, Padding, and Background Properties |
} | } | ||||
} else {*/ | } else {*/ | ||||
cheight = len.mvalue(); | cheight = len.mvalue(); | ||||
} | |||||
} | |||||
Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f, cheight == -1 ? -1 : cheight / 1000f); | Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f, cheight == -1 ? -1 : cheight / 1000f); | ||||
Point2D size = child.getDimension(csize); | Point2D size = child.getDimension(csize); | ||||
if(overflow == Overflow.HIDDEN) { | if(overflow == Overflow.HIDDEN) { | ||||
clip = true; | clip = true; | ||||
} else if(overflow == Overflow.ERROR_IF_OVERFLOW) { | } else if(overflow == Overflow.ERROR_IF_OVERFLOW) { | ||||
log.error("Instream foreign object overflows the viewport"); | |||||
getLogger().error("Instream foreign object overflows the viewport"); | |||||
clip = true; | clip = true; | ||||
} | } | ||||
} | } | ||||
// Common Accessibility Properties | // Common Accessibility Properties | ||||
AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); | AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); | ||||
// Common Aural Properties | // Common Aural Properties | ||||
AuralProps mAurProps = propMgr.getAuralProps(); | AuralProps mAurProps = propMgr.getAuralProps(); | ||||
// this.properties.get("content-width"); | // this.properties.get("content-width"); | ||||
// this.properties.get("display-align"); | // this.properties.get("display-align"); | ||||
// this.properties.get("dominant-baseline"); | // this.properties.get("dominant-baseline"); | ||||
// this.properties.get("height"); | |||||
// this.properties.get("height"); | |||||
setupID(); | setupID(); | ||||
// this.properties.get("inline-progression-dimension"); | // this.properties.get("inline-progression-dimension"); | ||||
// this.properties.get("keep-with-next"); | // this.properties.get("keep-with-next"); |
try { | try { | ||||
((FObj)parent).addMarker(this); | ((FObj)parent).addMarker(this); | ||||
} catch (FOPException fopex) { | } catch (FOPException fopex) { | ||||
log.error("marker cannot be added to '" + parent | |||||
getLogger().error("marker cannot be added to '" + parent | |||||
+ "'"); | + "'"); | ||||
} | } | ||||
} | } |
break; | break; | ||||
case PagePosition.LAST: | case PagePosition.LAST: | ||||
// how the hell do you know at this point? | // how the hell do you know at this point? | ||||
log.debug("LAST PagePosition NYI"); | |||||
getLogger().warn("LAST PagePosition NYI"); | |||||
okOnPagePosition = true; | okOnPagePosition = true; | ||||
break; | break; | ||||
case PagePosition.REST: | case PagePosition.REST: | ||||
(RepeatablePageMasterAlternatives)parent; | (RepeatablePageMasterAlternatives)parent; | ||||
if (getMasterName() == null) { | if (getMasterName() == null) { | ||||
log.warn("single-page-master-reference" | |||||
getLogger().warn("single-page-master-reference" | |||||
+ "does not have a master-name and so is being ignored"); | + "does not have a master-name and so is being ignored"); | ||||
} else { | } else { | ||||
this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this); | this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this); |
_pageSequenceMaster = (PageSequenceMaster)parent; | _pageSequenceMaster = (PageSequenceMaster)parent; | ||||
if (getMasterName() == null) { | if (getMasterName() == null) { | ||||
log.warn("" + getName() | |||||
getLogger().warn("" + getName() | |||||
+ " does not have a master-reference and so is being ignored"); | + " does not have a master-reference and so is being ignored"); | ||||
} else { | } else { | ||||
_pageSequenceMaster.addSubsequenceSpecifier(this); | _pageSequenceMaster.addSubsequenceSpecifier(this); |
import org.apache.fop.fo.properties.*; | import org.apache.fop.fo.properties.*; | ||||
// Avalon | // Avalon | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
// Java | // Java | ||||
import java.util.*; | import java.util.*; | ||||
* and 'letterValue' properties on fo:page-sequence to return a String | * and 'letterValue' properties on fo:page-sequence to return a String | ||||
* corresponding to the supplied integer page number. | * corresponding to the supplied integer page number. | ||||
*/ | */ | ||||
public class PageNumberGenerator { | |||||
public class PageNumberGenerator extends AbstractLogEnabled { | |||||
private String format; | private String format; | ||||
private char groupingSeparator; | private char groupingSeparator; | ||||
"", "0", "00", "000", "0000", "00000" | "", "0", "00", "000", "0000", "00000" | ||||
}; | }; | ||||
private Logger log; | |||||
public PageNumberGenerator(String format, char groupingSeparator, | public PageNumberGenerator(String format, char groupingSeparator, | ||||
int groupingSize, int letterValue) { | int groupingSize, int letterValue) { | ||||
this.format = format; | this.format = format; | ||||
formatType = UPPERROMAN; | formatType = UPPERROMAN; | ||||
} else { | } else { | ||||
// token not handled | // token not handled | ||||
//log.debug("'format' token not recognized; using '1'"); | |||||
//getLogger().debug("'format' token not recognized; using '1'"); | |||||
formatType = DECIMAL; | formatType = DECIMAL; | ||||
minPadding = 0; | minPadding = 0; | ||||
} | } | ||||
// loop | // loop | ||||
for (int i = 0; i < fmtLen - 1; i++) { | for (int i = 0; i < fmtLen - 1; i++) { | ||||
if (format.charAt(i) != '0') { | if (format.charAt(i) != '0') { | ||||
//log.debug("'format' token not recognized; using '1'"); | |||||
//getLogger().debug("'format' token not recognized; using '1'"); | |||||
formatType = DECIMAL; | formatType = DECIMAL; | ||||
minPadding = 0; | minPadding = 0; | ||||
} else { | } else { | ||||
} | } | ||||
} | } | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
} | |||||
public String makeFormattedPageNumber(int number) { | public String makeFormattedPageNumber(int number) { | ||||
String pn = null; | String pn = null; | ||||
if (formatType == DECIMAL) { | if (formatType == DECIMAL) { |
masterName = this.properties.get("master-reference").getString(); | masterName = this.properties.get("master-reference").getString(); | ||||
// TODO: Add code here to set a reference to the PageSequenceMaster | |||||
// if the masterName names a page-sequence-master, else get a | |||||
// reference to the SimplePageMaster. Throw an exception if neither? | |||||
// TODO: Add code here to set a reference to the PageSequenceMaster | |||||
// if the masterName names a page-sequence-master, else get a | |||||
// reference to the SimplePageMaster. Throw an exception if neither? | |||||
// get the 'format' properties | // get the 'format' properties | ||||
this.pageNumberGenerator = | this.pageNumberGenerator = | ||||
this.properties.get("grouping-separator").getCharacter(), | this.properties.get("grouping-separator").getCharacter(), | ||||
this.properties.get("grouping-size").getNumber().intValue(), | this.properties.get("grouping-size").getNumber().intValue(), | ||||
this.properties.get("letter-value").getEnum()); | this.properties.get("letter-value").getEnum()); | ||||
this.pageNumberGenerator.enableLogging(getLogger()); | |||||
this.forcePageCount = | this.forcePageCount = | ||||
this.properties.get("force-page-count").getEnum(); | this.properties.get("force-page-count").getEnum(); | ||||
throw new FOPException("flow-names must be unique within an fo:page-sequence"); | throw new FOPException("flow-names must be unique within an fo:page-sequence"); | ||||
} | } | ||||
if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { | if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { | ||||
log.error("region-name '" | |||||
getLogger().error("region-name '" | |||||
+ flow.getFlowName() | + flow.getFlowName() | ||||
+ "' doesn't exist in the layout-master-set."); | + "' doesn't exist in the layout-master-set."); | ||||
} | } | ||||
* @param child The flow object child to be added to the PageSequence. | * @param child The flow object child to be added to the PageSequence. | ||||
*/ | */ | ||||
public void addChild(FONode child) { | public void addChild(FONode child) { | ||||
try { | |||||
String childName = child.getName(); | |||||
if (childName.equals("fo:title")) { | |||||
if (this._flowMap.size()>0) { | |||||
log.warn("fo:title should be first in page-sequence"); | |||||
} else { | |||||
this.titleFO = (Title)child; | |||||
structHandler.startPageSequence(this, titleFO, layoutMasterSet); | |||||
sequenceStarted = true; | |||||
} | |||||
} | |||||
else if (childName.equals("fo:flow")) { | |||||
if (this.mainFlow != null) { | |||||
throw new FOPException("Only a single fo:flow permitted" | |||||
+ " per fo:page-sequence"); | |||||
} | |||||
else { | |||||
if(!sequenceStarted) { | |||||
try { | |||||
String childName = child.getName(); | |||||
if (childName.equals("fo:title")) { | |||||
if (this._flowMap.size()>0) { | |||||
getLogger().warn("fo:title should be first in page-sequence"); | |||||
} else { | |||||
this.titleFO = (Title)child; | |||||
structHandler.startPageSequence(this, titleFO, layoutMasterSet); | |||||
sequenceStarted = true; | |||||
} | |||||
} else if (childName.equals("fo:flow")) { | |||||
if (this.mainFlow != null) { | |||||
throw new FOPException("Only a single fo:flow permitted" | |||||
+ " per fo:page-sequence"); | |||||
} else { | |||||
if(!sequenceStarted) { | |||||
structHandler.startPageSequence(this, titleFO, layoutMasterSet); | structHandler.startPageSequence(this, titleFO, layoutMasterSet); | ||||
sequenceStarted = true; | sequenceStarted = true; | ||||
} | } | ||||
this.mainFlow = (Flow)child; | |||||
addFlow(mainFlow); | |||||
super.addChild(child); // For getChildren | |||||
} | |||||
} | |||||
else if (childName.equals("fo:static-content")) { | |||||
if (this.mainFlow != null) { | |||||
throw new FOPException(childName + | |||||
" must precede fo:flow; ignoring"); | |||||
} | |||||
else { | |||||
this.mainFlow = (Flow)child; | |||||
addFlow(mainFlow); | |||||
super.addChild(child); // For getChildren | |||||
} | |||||
} else if (childName.equals("fo:static-content")) { | |||||
if (this.mainFlow != null) { | |||||
throw new FOPException(childName + | |||||
" must precede fo:flow; ignoring"); | |||||
} else { | |||||
if(!sequenceStarted) { | if(!sequenceStarted) { | ||||
structHandler.startPageSequence(this, titleFO, layoutMasterSet); | structHandler.startPageSequence(this, titleFO, layoutMasterSet); | ||||
sequenceStarted = true; | sequenceStarted = true; | ||||
} | } | ||||
addFlow((Flow)child); | |||||
} | |||||
} | |||||
else { | |||||
// Ignore it! | |||||
log.warn("FO '" + childName + | |||||
"' not a legal page-sequence child."); | |||||
return; | |||||
} | |||||
} catch (FOPException fopex) { | |||||
log.error("Error in PageSequence.addChild(): " + | |||||
fopex.getMessage()); | |||||
} | |||||
addFlow((Flow)child); | |||||
} | |||||
} else { | |||||
// Ignore it! | |||||
getLogger().warn("FO '" + childName + | |||||
"' not a legal page-sequence child."); | |||||
return; | |||||
} | |||||
} catch (FOPException fopex) { | |||||
getLogger().error("Error in PageSequence.addChild(): " + | |||||
fopex.getMessage(), fopex); | |||||
} | |||||
} | } | ||||
public void end() { | public void end() { | ||||
try { | |||||
this.structHandler.endPageSequence(this); | |||||
} catch (FOPException fopex) { | |||||
log.error("Error in PageSequence.end(): " + | |||||
fopex.getMessage()); | |||||
} | |||||
try { | |||||
this.structHandler.endPageSequence(this); | |||||
} catch (FOPException fopex) { | |||||
getLogger().error("Error in PageSequence.end(): " + | |||||
fopex.getMessage(), fopex); | |||||
} | |||||
} | } | ||||
* Runs the formatting of this page sequence into the given area tree | * Runs the formatting of this page sequence into the given area tree | ||||
*/ | */ | ||||
public void format(AreaTree areaTree) throws FOPException { | public void format(AreaTree areaTree) throws FOPException { | ||||
// Make a new PageLayoutManager and a FlowLayoutManager | |||||
// Run the PLM in a thread | |||||
// Wait for them to finish. | |||||
// If no main flow, nothing to layout! | |||||
if (this.mainFlow == null) return; | |||||
// Initialize if already used? | |||||
// Make a new PageLayoutManager and a FlowLayoutManager | |||||
// Run the PLM in a thread | |||||
// Wait for them to finish. | |||||
// If no main flow, nothing to layout! | |||||
if (this.mainFlow == null) return; | |||||
// Initialize if already used? | |||||
this.layoutMasterSet.resetPageMasters(); | this.layoutMasterSet.resetPageMasters(); | ||||
int firstAvailPageNumber = 0; | int firstAvailPageNumber = 0; | ||||
// This will layout pages and add them to the area tree | |||||
PageLayoutManager pageLM = new PageLayoutManager(areaTree, this); | |||||
// For now, skip the threading and just call run directly. | |||||
pageLM.run(); | |||||
// This will layout pages and add them to the area tree | |||||
PageLayoutManager pageLM = new PageLayoutManager(areaTree, this); | |||||
// For now, skip the threading and just call run directly. | |||||
pageLM.run(); | |||||
// Thread layoutThread = new Thread(pageLM); | // Thread layoutThread = new Thread(pageLM); | ||||
// layoutThread.start(); | // layoutThread.start(); | ||||
// } catch (InterruptedException ie) { | // } catch (InterruptedException ie) { | ||||
// log.error("PageSequence.format() interrupted waiting on layout"); | // log.error("PageSequence.format() interrupted waiting on layout"); | ||||
// } | // } | ||||
// Tell the root the last page number we created. | |||||
this.root.setRunningPageNumberCounter(this.currentPageNumber); | |||||
// Tell the root the last page number we created. | |||||
this.root.setRunningPageNumberCounter(this.currentPageNumber); | |||||
} | } | ||||
private void initPageNumber() { | private void initPageNumber() { | ||||
this.currentPageNumber = this.root.getRunningPageNumberCounter() + 1; | |||||
if (this.pageNumberType == AUTO_ODD) { | |||||
// Next page but force odd. May force empty page creation! | |||||
// Whose master is used for this??? Assume no. | |||||
// Use force-page-count=auto | |||||
// on preceding page-sequence to make sure that there is no gap! | |||||
if (currentPageNumber % 2 == 0) { | |||||
this.currentPageNumber++; | |||||
} | |||||
} else if (pageNumberType == AUTO_EVEN) { | |||||
if (currentPageNumber % 2 == 1) { | |||||
this.currentPageNumber++; | |||||
} | |||||
} | |||||
else if (pageNumberType == EXPLICIT) { | |||||
this.currentPageNumber = this.explicitFirstNumber; | |||||
} | |||||
this.firstPageNumber = this.currentPageNumber; | |||||
this.currentPageNumber = this.root.getRunningPageNumberCounter() + 1; | |||||
if (this.pageNumberType == AUTO_ODD) { | |||||
// Next page but force odd. May force empty page creation! | |||||
// Whose master is used for this??? Assume no. | |||||
// Use force-page-count=auto | |||||
// on preceding page-sequence to make sure that there is no gap! | |||||
if (currentPageNumber % 2 == 0) { | |||||
this.currentPageNumber++; | |||||
} | |||||
} else if (pageNumberType == AUTO_EVEN) { | |||||
if (currentPageNumber % 2 == 1) { | |||||
this.currentPageNumber++; | |||||
} | |||||
} | |||||
else if (pageNumberType == EXPLICIT) { | |||||
this.currentPageNumber = this.explicitFirstNumber; | |||||
} | |||||
this.firstPageNumber = this.currentPageNumber; | |||||
} | } | ||||
/** | /** | ||||
* @param bIsBlank If true, use a master for a blank page. | * @param bIsBlank If true, use a master for a blank page. | ||||
* @param bIsLast If true, use the master for the last page in the sequence. | * @param bIsLast If true, use the master for the last page in the sequence. | ||||
*/ | */ | ||||
public PageViewport createPage(boolean bIsBlank, boolean bIsLast) | |||||
throws FOPException | |||||
public PageViewport createPage(boolean bIsBlank, boolean bIsLast) | |||||
throws FOPException | |||||
{ | { | ||||
// Set even/odd flag and first flag based on current state | |||||
// Should do it this way, but fix it later.... | |||||
/*boolean bEvenPage = ((this.currentPageNumber %2)==0); | |||||
currentPage = makePage(bEvenPage, */ | |||||
currentPage = makePage(this.currentPageNumber, | |||||
this.currentPageNumber==this.firstPageNumber, | |||||
bIsLast, bIsBlank); | |||||
return currentPage; | |||||
// The page will have a viewport/reference area pair defined | |||||
// for each region in the master. | |||||
// Set up the page itself | |||||
// currentPage.setNumber(this.currentPageNumber); | |||||
// Set even/odd flag and first flag based on current state | |||||
// Should do it this way, but fix it later.... | |||||
/*boolean bEvenPage = ((this.currentPageNumber %2)==0); | |||||
currentPage = makePage(bEvenPage, */ | |||||
currentPage = makePage(this.currentPageNumber, | |||||
this.currentPageNumber==this.firstPageNumber, | |||||
bIsLast, bIsBlank); | |||||
return currentPage; | |||||
// The page will have a viewport/reference area pair defined | |||||
// for each region in the master. | |||||
// Set up the page itself | |||||
// currentPage.setNumber(this.currentPageNumber); | |||||
// SKIP ALL THIS FOR NOW!!! | // SKIP ALL THIS FOR NOW!!! | ||||
// String formattedPageNumber = | // String formattedPageNumber = | ||||
// pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); | // pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); | ||||
// this.pageCount++; // used for 'force-page-count' calculations | // this.pageCount++; // used for 'force-page-count' calculations | ||||
// handle the 'force-page-count' | // handle the 'force-page-count' | ||||
//forcePage(areaTree, firstAvailPageNumber); | |||||
//forcePage(areaTree, firstAvailPageNumber); | |||||
} | } | ||||
/** | /** | ||||
* @param isFirstPage true when this is the first page in the sequence | * @param isFirstPage true when this is the first page in the sequence | ||||
* @param isEmptyPage true if this page will be empty | * @param isEmptyPage true if this page will be empty | ||||
* (e.g. forced even or odd break) | * (e.g. forced even or odd break) | ||||
* @return a Page layout object based on the page master selected | |||||
* @return a Page layout object based on the page master selected | |||||
* from the params | * from the params | ||||
* TODO: modify the other methods to use even/odd flag and bIsLast | * TODO: modify the other methods to use even/odd flag and bIsLast | ||||
*/ | */ | ||||
private PageViewport makePage(int firstAvailPageNumber, | private PageViewport makePage(int firstAvailPageNumber, | ||||
boolean isFirstPage, boolean bIsLast, | |||||
boolean isEmptyPage) throws FOPException { | |||||
boolean isFirstPage, boolean bIsLast, | |||||
boolean isEmptyPage) throws FOPException { | |||||
// layout this page sequence | // layout this page sequence | ||||
// while there is still stuff in the flow, ask the | // while there is still stuff in the flow, ask the | ||||
// a legal alternative is to use the last sub-sequence | // a legal alternative is to use the last sub-sequence | ||||
// specification which should be handled in getNextSubsequence. | // specification which should be handled in getNextSubsequence. | ||||
// That's not done here. | |||||
// That's not done here. | |||||
if (pageMaster == null) { | if (pageMaster == null) { | ||||
throw new FOPException("page masters exhausted. Cannot recover."); | throw new FOPException("page masters exhausted. Cannot recover."); | ||||
} | } | ||||
SubSequenceSpecifier nextSubsequence = | SubSequenceSpecifier nextSubsequence = | ||||
getNextSubsequence(sequenceMaster); | getNextSubsequence(sequenceMaster); | ||||
if (nextSubsequence == null) { | if (nextSubsequence == null) { | ||||
log.error("Page subsequences exhausted. Using previous subsequence."); | |||||
getLogger().error("Page subsequences exhausted. Using previous subsequence."); | |||||
thisIsFirstPage = | thisIsFirstPage = | ||||
true; // this becomes the first page in the new (old really) page master | true; // this becomes the first page in the new (old really) page master | ||||
currentSubsequence.reset(); | currentSubsequence.reset(); | ||||
// } else { | // } else { | ||||
// System.out.println("flow is null. regionClass = '" + regionClass | |||||
// getLogger().error("flow is null. regionClass = '" + regionClass | |||||
// + "' currentSPM = " | // + "' currentSPM = " | ||||
// + getCurrentSimplePageMaster()); | // + getCurrentSimplePageMaster()); | ||||
this.layoutMasterSet = (LayoutMasterSet)parent; | this.layoutMasterSet = (LayoutMasterSet)parent; | ||||
String pm = this.properties.get("master-name").getString(); | String pm = this.properties.get("master-name").getString(); | ||||
if (pm == null) { | if (pm == null) { | ||||
log.warn("page-sequence-master does not have " | |||||
getLogger().warn("page-sequence-master does not have " | |||||
+ "a master-name and so is being ignored"); | + "a master-name and so is being ignored"); | ||||
} else { | } else { | ||||
this.layoutMasterSet.addPageSequenceMaster(pm, this); | this.layoutMasterSet.addPageSequenceMaster(pm, this); |
protected Rectangle getViewportRectangle (FODimension reldims) | protected Rectangle getViewportRectangle (FODimension reldims) | ||||
{ | { | ||||
/* | |||||
* Use space-before and space-after which will use corresponding | |||||
* absolute margin properties if specified. For indents: | |||||
* try to get corresponding absolute margin property using the | |||||
* writing-mode on the page (not on the region-body!). If that's not | |||||
* set but indent is explicitly set, it will return that. | |||||
*/ | |||||
/* | |||||
* Use space-before and space-after which will use corresponding | |||||
* absolute margin properties if specified. For indents: | |||||
* try to get corresponding absolute margin property using the | |||||
* writing-mode on the page (not on the region-body!). If that's not | |||||
* set but indent is explicitly set, it will return that. | |||||
*/ | |||||
MarginProps mProps = propMgr.getMarginProps(); | MarginProps mProps = propMgr.getMarginProps(); | ||||
int start = getRelMargin(PropertyList.START, "start-indent"); | |||||
return new Rectangle( start, mProps.spaceBefore, | |||||
reldims.ipd - start - | |||||
getRelMargin(PropertyList.END, "end-indent"), | |||||
reldims.bpd - mProps.spaceBefore - | |||||
mProps.spaceAfter); | |||||
int start = getRelMargin(PropertyList.START, "start-indent"); | |||||
return new Rectangle( start, mProps.spaceBefore, | |||||
reldims.ipd - start - | |||||
getRelMargin(PropertyList.END, "end-indent"), | |||||
reldims.bpd - mProps.spaceBefore - | |||||
mProps.spaceAfter); | |||||
} | } | ||||
/** | /** | ||||
* writing mode. | * writing mode. | ||||
*/ | */ | ||||
private int getRelMargin(int reldir, String sRelPropName) { | private int getRelMargin(int reldir, String sRelPropName) { | ||||
FObj parent = (FObj) getParent(); | |||||
String sPropName = "margin-" + | |||||
parent.properties.wmRelToAbs(reldir); | |||||
Property prop = properties.getExplicitBaseProp(sPropName); | |||||
if (prop == null) { | |||||
prop = properties.getExplicitBaseProp(sRelPropName); | |||||
} | |||||
return ((prop != null)? prop.getLength().mvalue() : 0); | |||||
FObj parent = (FObj) getParent(); | |||||
String sPropName = "margin-" + | |||||
parent.properties.wmRelToAbs(reldir); | |||||
Property prop = properties.getExplicitBaseProp(sPropName); | |||||
if (prop == null) { | |||||
prop = properties.getExplicitBaseProp(sRelPropName); | |||||
} | |||||
return ((prop != null)? prop.getLength().mvalue() : 0); | |||||
} | } | ||||
protected void setRegionTraits(RegionReference r, Rectangle2D absRegVPRect) { | protected void setRegionTraits(RegionReference r, Rectangle2D absRegVPRect) { | ||||
super.setRegionTraits(r, absRegVPRect); | |||||
super.setRegionTraits(r, absRegVPRect); | |||||
// r.setBackgroundColor(backgroundColor); | // r.setBackgroundColor(backgroundColor); | ||||
} | } | ||||
* Override the inherited method. | * Override the inherited method. | ||||
*/ | */ | ||||
public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) { | public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) { | ||||
// Should set some column stuff here I think, or put it elsewhere | |||||
BodyRegion body = new BodyRegion(); | |||||
setRegionTraits(body, absRegVPRect); | |||||
// Should set some column stuff here I think, or put it elsewhere | |||||
BodyRegion body = new BodyRegion(); | |||||
setRegionTraits(body, absRegVPRect); | |||||
int columnCount= | int columnCount= | ||||
this.properties.get("column-count").getNumber().intValue(); | this.properties.get("column-count").getNumber().intValue(); | ||||
if ((columnCount > 1) && (overflow == Overflow.SCROLL)) { | if ((columnCount > 1) && (overflow == Overflow.SCROLL)) { | ||||
// recover by setting 'column-count' to 1. This is allowed but | // recover by setting 'column-count' to 1. This is allowed but | ||||
// not required by the spec. | // not required by the spec. | ||||
log.error("Setting 'column-count' to 1 because " | |||||
getLogger().error("Setting 'column-count' to 1 because " | |||||
+ "'overflow' is set to 'scroll'"); | + "'overflow' is set to 'scroll'"); | ||||
columnCount = 1; | columnCount = 1; | ||||
} | } | ||||
body.setColumnCount(columnCount); | |||||
body.setColumnCount(columnCount); | |||||
int columnGap = | int columnGap = | ||||
this.properties.get("column-gap").getLength().mvalue(); | this.properties.get("column-gap").getLength().mvalue(); | ||||
body.setColumnGap(columnGap); | |||||
return body; | |||||
body.setColumnGap(columnGap); | |||||
return body; | |||||
} | } | ||||
} | } |
LayoutMasterSet layoutMasterSet = (LayoutMasterSet)parent; | LayoutMasterSet layoutMasterSet = (LayoutMasterSet)parent; | ||||
masterName = this.properties.get("master-name").getString(); | masterName = this.properties.get("master-name").getString(); | ||||
if (masterName == null) { | if (masterName == null) { | ||||
log.warn("simple-page-master does not have " | |||||
getLogger().warn("simple-page-master does not have " | |||||
+ "a master-name and so is being ignored"); | + "a master-name and so is being ignored"); | ||||
} else { | } else { | ||||
layoutMasterSet.addSimplePageMaster(this); | layoutMasterSet.addSimplePageMaster(this); | ||||
// Get absolute margin properties (top, left, bottom, right) | // Get absolute margin properties (top, left, bottom, right) | ||||
MarginProps mProps = propMgr.getMarginProps(); | MarginProps mProps = propMgr.getMarginProps(); | ||||
/* Create the page reference area rectangle in first quadrant coordinates | |||||
* (ie, 0,0 is at bottom,left of the "page media" and y increases | |||||
* when moving towards the top of the page. | |||||
* The media rectangle itself is (0,0,pageWidth,pageHeight). | |||||
*/ | |||||
Rectangle pageRefRect = | |||||
new Rectangle(mProps.marginLeft, mProps.marginTop, | |||||
pageWidth - mProps.marginLeft - mProps.marginRight, | |||||
pageHeight - mProps.marginTop - mProps.marginBottom); | |||||
/* Create the page reference area rectangle in first quadrant coordinates | |||||
* (ie, 0,0 is at bottom,left of the "page media" and y increases | |||||
* when moving towards the top of the page. | |||||
* The media rectangle itself is (0,0,pageWidth,pageHeight). | |||||
*/ | |||||
Rectangle pageRefRect = | |||||
new Rectangle(mProps.marginLeft, mProps.marginTop, | |||||
pageWidth - mProps.marginLeft - mProps.marginRight, | |||||
pageHeight - mProps.marginTop - mProps.marginBottom); | |||||
// ??? KL shouldn't this take the viewport too??? | |||||
Page page = new Page(); // page reference area | |||||
// ??? KL shouldn't this take the viewport too??? | |||||
Page page = new Page(); // page reference area | |||||
// Set up the CTM on the page reference area based on writing-mode | // Set up the CTM on the page reference area based on writing-mode | ||||
// and reference-orientation | // and reference-orientation | ||||
FODimension reldims=new FODimension(0,0); | |||||
CTM pageCTM = propMgr.getCTMandRelDims(pageRefRect, reldims); | |||||
FODimension reldims=new FODimension(0,0); | |||||
CTM pageCTM = propMgr.getCTMandRelDims(pageRefRect, reldims); | |||||
// Create a RegionViewport/ reference area pair for each page region | |||||
// Create a RegionViewport/ reference area pair for each page region | |||||
boolean bHasBody=false; | |||||
boolean bHasBody=false; | |||||
for (Iterator regenum = _regions.values().iterator(); | for (Iterator regenum = _regions.values().iterator(); | ||||
regenum.hasNext(); ) { | regenum.hasNext(); ) { | ||||
Region r = (Region)regenum.next(); | Region r = (Region)regenum.next(); | ||||
RegionViewport rvp = r.makeRegionViewport(reldims, pageCTM); | |||||
rvp.setRegion(r.makeRegionReferenceArea(rvp.getViewArea())); | |||||
page.setRegion(r.getRegionAreaClass(), rvp); | |||||
if (r.getRegionAreaClass() == RegionReference.BODY) { | |||||
bHasBody = true; | |||||
} | |||||
RegionViewport rvp = r.makeRegionViewport(reldims, pageCTM); | |||||
rvp.setRegion(r.makeRegionReferenceArea(rvp.getViewArea())); | |||||
page.setRegion(r.getRegionAreaClass(), rvp); | |||||
if (r.getRegionAreaClass() == RegionReference.BODY) { | |||||
bHasBody = true; | |||||
} | |||||
} | } | ||||
if (!bHasBody) { | |||||
log.error("simple-page-master has no region-body"); | |||||
if (!bHasBody) { | |||||
getLogger().error("simple-page-master has no region-body"); | |||||
} | } | ||||
this.pageMaster = new PageMaster(new PageViewport(page, | |||||
new Rectangle(0,0, | |||||
pageWidth,pageHeight))); | |||||
this.pageMaster = new PageMaster(new PageViewport(page, | |||||
new Rectangle(0,0, | |||||
pageWidth,pageHeight))); | |||||
// _regions = null; // PageSequence access SimplePageMaster.... | |||||
// _regions = null; // PageSequence access SimplePageMaster.... | |||||
children = null; | children = null; | ||||
properties = null; | properties = null; | ||||
} | } | ||||
} | } | ||||
protected void addChild(FONode child) { | protected void addChild(FONode child) { | ||||
if (child instanceof Region) { | |||||
addRegion((Region)child); | |||||
} | |||||
else { | |||||
log.error("SimplePageMaster cannot have child of type " + | |||||
child.getName()); | |||||
} | |||||
if (child instanceof Region) { | |||||
addRegion((Region)child); | |||||
} else { | |||||
getLogger().error("SimplePageMaster cannot have child of type " + | |||||
child.getName()); | |||||
} | |||||
} | } | ||||
protected void addRegion(Region region) { | protected void addRegion(Region region) { | ||||
String key = region.getRegionClass(); | |||||
String key = region.getRegionClass(); | |||||
if (_regions.containsKey(key)) { | if (_regions.containsKey(key)) { | ||||
log.error("Only one region of class " | |||||
getLogger().error("Only one region of class " | |||||
+ key | + key | ||||
+ " allowed within a simple-page-master."); | + " allowed within a simple-page-master."); | ||||
// throw new FOPException("Only one region of class " | // throw new FOPException("Only one region of class " |
import org.apache.fop.fo.FOUserAgent; | import org.apache.fop.fo.FOUserAgent; | ||||
// Avalon | // Avalon | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
// Java | // Java | ||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
* viewports. This keeps track of the current block and inline | * viewports. This keeps track of the current block and inline | ||||
* position. | * position. | ||||
*/ | */ | ||||
public abstract class AbstractRenderer implements Renderer { | |||||
protected Logger log; | |||||
public abstract class AbstractRenderer extends AbstractLogEnabled implements Renderer { | |||||
protected FOUserAgent userAgent; | protected FOUserAgent userAgent; | ||||
protected HashMap options; | protected HashMap options; | ||||
protected int currentBlockIPPosition = 0; | protected int currentBlockIPPosition = 0; | ||||
public void setLogger(Logger logger) { | |||||
log = logger; | |||||
} | |||||
public void setUserAgent(FOUserAgent agent) { | public void setUserAgent(FOUserAgent agent) { | ||||
userAgent = agent; | userAgent = agent; | ||||
} | } | ||||
protected void renderRegionViewport(RegionViewport port) { | protected void renderRegionViewport(RegionViewport port) { | ||||
if (port != null) { | if (port != null) { | ||||
Rectangle2D view = port.getViewArea(); | Rectangle2D view = port.getViewArea(); | ||||
// The CTM will transform coordinates relative to | |||||
// this region-reference area into page coords, so | |||||
// set origin for the region to 0,0. | |||||
// The CTM will transform coordinates relative to | |||||
// this region-reference area into page coords, so | |||||
// set origin for the region to 0,0. | |||||
currentBPPosition = 0; // (int) (view.getY() / 1000); | currentBPPosition = 0; // (int) (view.getY() / 1000); | ||||
currentIPPosition = 0; // (int) (view.getX() / 1000); | currentIPPosition = 0; // (int) (view.getX() / 1000); | ||||
currentBlockIPPosition = currentIPPosition; | currentBlockIPPosition = currentIPPosition; | ||||
RegionReference region = port.getRegion(); | RegionReference region = port.getRegion(); | ||||
startVParea(region.getCTM()); | |||||
startVParea(region.getCTM()); | |||||
if (region.getRegionClass() == RegionReference.BODY) { | if (region.getRegionClass() == RegionReference.BODY) { | ||||
renderBodyRegion((BodyRegion) region); | renderBodyRegion((BodyRegion) region); | ||||
} else { | } else { | ||||
renderRegion(region); | renderRegion(region); | ||||
} | } | ||||
endVParea(); | |||||
endVParea(); | |||||
} | } | ||||
} | } | ||||
public void renderInlineParent(InlineParent ip) { | public void renderInlineParent(InlineParent ip) { | ||||
// currentBlockIPPosition += ip.getWidth(); | // currentBlockIPPosition += ip.getWidth(); | ||||
Iterator iter = ip.getChildAreas().iterator(); | |||||
while (iter.hasNext()) { | |||||
Iterator iter = ip.getChildAreas().iterator(); | |||||
while (iter.hasNext()) { | |||||
((InlineArea)iter.next()).render(this); | ((InlineArea)iter.next()).render(this); | ||||
} | } | ||||
} | } |
import org.apache.fop.layout.FontInfo; | import org.apache.fop.layout.FontInfo; | ||||
import org.apache.fop.fo.FOUserAgent; | import org.apache.fop.fo.FOUserAgent; | ||||
// Avalon | |||||
import org.apache.avalon.framework.logger.Logger; | |||||
// Java | // Java | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
*/ | */ | ||||
public interface Renderer { | public interface Renderer { | ||||
public static final String ROLE = Renderer.class.getName(); | |||||
public void startRenderer(OutputStream outputStream) throws IOException; | public void startRenderer(OutputStream outputStream) throws IOException; | ||||
public void stopRenderer() throws IOException; | public void stopRenderer() throws IOException; | ||||
/** | |||||
* Set the logger | |||||
*/ | |||||
public void setLogger(Logger logger); | |||||
/** | /** | ||||
* Set the User Agent | * Set the User Agent | ||||
*/ | */ |
public void startRenderer(OutputStream outputStream) | public void startRenderer(OutputStream outputStream) | ||||
throws IOException { | throws IOException { | ||||
log.info("rendering areas to PCL"); | |||||
getLogger().info("rendering areas to PCL"); | |||||
currentStream = new PCLStream(outputStream); | currentStream = new PCLStream(outputStream); | ||||
// Set orientation. | // Set orientation. |
*/ | */ | ||||
public void startRenderer(OutputStream outputStream) | public void startRenderer(OutputStream outputStream) | ||||
throws IOException { | throws IOException { | ||||
log.debug("rendering areas to PostScript"); | |||||
getLogger().debug("rendering areas to PostScript"); | |||||
this.out = new PSStream(outputStream); | this.out = new PSStream(outputStream); | ||||
write("%!PS-Adobe-3.0"); | write("%!PS-Adobe-3.0"); | ||||
/* Write proc for including EPS */ | /* Write proc for including EPS */ | ||||
write("%%BeginResource: procset EPSprocs"); | write("%%BeginResource: procset EPSprocs"); | ||||
write("%%Title: EPS encapsulation procs"); | write("%%Title: EPS encapsulation procs"); | ||||
write("/BeginEPSF { %def"); | write("/BeginEPSF { %def"); | ||||
write("/b4_Inc_state save def % Save state for cleanup"); | write("/b4_Inc_state save def % Save state for cleanup"); | ||||
write("/dict_count countdictstack def % Count objects on dict stack"); | write("/dict_count countdictstack def % Count objects on dict stack"); | ||||
write("} if"); | write("} if"); | ||||
write("} if"); | write("} if"); | ||||
write("} bind def"); | write("} bind def"); | ||||
write("/EndEPSF { %def"); | write("/EndEPSF { %def"); | ||||
write("count op_count sub {pop} repeat % Clean up stacks"); | write("count op_count sub {pop} repeat % Clean up stacks"); | ||||
write("countdictstack dict_count sub {end} repeat"); | write("countdictstack dict_count sub {end} repeat"); | ||||
write("b4_Inc_state restore"); | write("b4_Inc_state restore"); | ||||
write("} bind def"); | write("} bind def"); | ||||
write("%%EndResource"); | write("%%EndResource"); | ||||
write("%%EndSetup"); | write("%%EndSetup"); | ||||
write("FOPFonts begin"); | write("FOPFonts begin"); | ||||
} | } |
try { | try { | ||||
svgT.transcode(input, output); | svgT.transcode(input, output); | ||||
} catch (TranscoderException e) { | } catch (TranscoderException e) { | ||||
log.error("could not write svg file :" + e.getMessage(), e); | |||||
getLogger().error("could not write svg file :" + e.getMessage(), e); | |||||
} | } | ||||
ostream.flush(); | ostream.flush(); | ||||
ostream = null; | ostream = null; |
void addStr(int row, int col, String str, boolean ischar) { | void addStr(int row, int col, String str, boolean ischar) { | ||||
if (debug) | if (debug) | ||||
System.out.println("TXTRenderer.addStr(" + row + ", " + col | |||||
getLogger().debug("TXTRenderer.addStr(" + row + ", " + col | |||||
+ ", \"" + str + "\", " + ischar + ")"); | + ", \"" + str + "\", " + ischar + ")"); | ||||
if (suppressGraphics &&!ischar) | if (suppressGraphics &&!ischar) | ||||
return; | return; | ||||
for (int countr = sb.length(); countr < col; countr++) | for (int countr = sb.length(); countr < col; countr++) | ||||
sb.append(' '); | sb.append(' '); | ||||
if (debug) | if (debug) | ||||
System.out.println("TXTRenderer.addStr() sb.length()=" | |||||
getLogger().debug("TXTRenderer.addStr() sb.length()=" | |||||
+ sb.length()); | + sb.length()); | ||||
for (int countr = col; countr < (col + str.length()); countr++) { | for (int countr = col; countr < (col + str.length()); countr++) { | ||||
if (countr >= sb.length()) | if (countr >= sb.length()) | ||||
sb.append(str.charAt(countr - col)); | sb.append(str.charAt(countr - col)); | ||||
else { | else { | ||||
if (debug) | if (debug) | ||||
System.out.println("TXTRenderer.addStr() sb.length()=" | |||||
getLogger().debug("TXTRenderer.addStr() sb.length()=" | |||||
+ sb.length() + " countr=" + countr); | + sb.length() + " countr=" + countr); | ||||
sb.setCharAt(countr, str.charAt(countr - col)); | sb.setCharAt(countr, str.charAt(countr - col)); | ||||
} | } |
*/ | */ | ||||
public void startRenderer(OutputStream outputStream) | public void startRenderer(OutputStream outputStream) | ||||
throws IOException { | throws IOException { | ||||
log.debug("rendering areas to XML"); | |||||
getLogger().debug("rendering areas to XML"); | |||||
this.writer = new PrintWriter(outputStream); | this.writer = new PrintWriter(outputStream); | ||||
this.writer.write( "<?xml version=\"1.0\"?>\n<!-- produced by " + | this.writer.write( "<?xml version=\"1.0\"?>\n<!-- produced by " + | ||||
this.producer + " -->\n"); | this.producer + " -->\n"); | ||||
writeEndTag("</pageSequence>"); | writeEndTag("</pageSequence>"); | ||||
writeEndTag("</areaTree>"); | writeEndTag("</areaTree>"); | ||||
this.writer.flush(); | this.writer.flush(); | ||||
log.debug("written out XML"); | |||||
getLogger().debug("written out XML"); | |||||
} | } | ||||
public void renderPage(PageViewport page) throws IOException, | public void renderPage(PageViewport page) throws IOException, | ||||
prop = " props=\"" + getPropString(map) + "\""; | prop = " props=\"" + getPropString(map) + "\""; | ||||
} | } | ||||
writeElement("<word wsadjust=\"" + word.getWSadjust() + "\"" + | writeElement("<word wsadjust=\"" + word.getWSadjust() + "\"" + | ||||
prop + ">" + word.getWord() + "</word>"); | |||||
prop + ">" + word.getWord() + "</word>"); | |||||
super.renderWord(word); | super.renderWord(word); | ||||
} | } | ||||
} | } | ||||
writeStartTag("<inlineparent" + prop + ">"); | writeStartTag("<inlineparent" + prop + ">"); | ||||
super.renderInlineParent(ip); | super.renderInlineParent(ip); | ||||
writeEndTag("</inlineparent>"); | |||||
writeEndTag("</inlineparent>"); | |||||
} | } | ||||
public void renderLeader(Leader area) { | public void renderLeader(Leader area) { | ||||
protected String getPropString(Map traitMap) { | protected String getPropString(Map traitMap) { | ||||
StringBuffer strbuf = new StringBuffer(); | StringBuffer strbuf = new StringBuffer(); | ||||
Iterator iter = traitMap.entrySet().iterator(); | |||||
while (iter.hasNext()) { | |||||
Iterator iter = traitMap.entrySet().iterator(); | |||||
while (iter.hasNext()) { | |||||
Map.Entry traitEntry = (Map.Entry) iter.next(); | Map.Entry traitEntry = (Map.Entry) iter.next(); | ||||
strbuf.append(Trait.getTraitName(traitEntry.getKey())); | |||||
strbuf.append(':'); | |||||
strbuf.append(traitEntry.getValue().toString()); | |||||
strbuf.append(';'); | |||||
} | |||||
return strbuf.toString(); | |||||
strbuf.append(Trait.getTraitName(traitEntry.getKey())); | |||||
strbuf.append(':'); | |||||
strbuf.append(traitEntry.getValue().toString()); | |||||
strbuf.append(';'); | |||||
} | |||||
return strbuf.toString(); | |||||
} | } | ||||
} | } |
((SVGOMDocument)doc).setURLObject(new URL(baseDir)); | ((SVGOMDocument)doc).setURLObject(new URL(baseDir)); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("Could not set base URL for svg", e); | |||||
getLogger().error("Could not set base URL for svg", e); | |||||
} | } | ||||
Element e = ((SVGDocument)doc).getRootElement(); | Element e = ((SVGDocument)doc).getRootElement(); | ||||
str = svgRoot.getAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE); | str = svgRoot.getAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE); | ||||
if (str.length() == 0) str = "100%"; | if (str.length() == 0) str = "100%"; | ||||
float width = UnitProcessor.svgHorizontalLengthToUserSpace | float width = UnitProcessor.svgHorizontalLengthToUserSpace | ||||
(str, SVGConstants.SVG_WIDTH_ATTRIBUTE, ctx); | |||||
(str, SVGConstants.SVG_WIDTH_ATTRIBUTE, ctx); | |||||
str = svgRoot.getAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE); | str = svgRoot.getAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE); | ||||
if (str.length() == 0) str = "100%"; | if (str.length() == 0) str = "100%"; | ||||
protected int fontSize; | protected int fontSize; | ||||
float pixeltoMM; | float pixeltoMM; | ||||
public PDFUnitContext(int size, Element e, float ptmm) { | |||||
public PDFUnitContext(int size, Element e, float ptmm) { | |||||
this.e = e; | this.e = e; | ||||
this.fontSize = size; | this.fontSize = size; | ||||
} | } |
import org.apache.fop.fo.FOUserAgent; | import org.apache.fop.fo.FOUserAgent; | ||||
import org.apache.avalon.framework.logger.ConsoleLogger; | import org.apache.avalon.framework.logger.ConsoleLogger; | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
import java.io.*; | import java.io.*; | ||||
import java.util.*; | import java.util.*; | ||||
* Tests: different renderers, saving and loading pages with serialization | * Tests: different renderers, saving and loading pages with serialization | ||||
* out of order rendering | * out of order rendering | ||||
*/ | */ | ||||
public class AreaTreeBuilder { | |||||
private Logger log = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG); | |||||
public class AreaTreeBuilder extends AbstractLogEnabled { | |||||
/** | /** | ||||
*/ | */ | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
AreaTreeBuilder atb = new AreaTreeBuilder(); | AreaTreeBuilder atb = new AreaTreeBuilder(); | ||||
atb.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG)); | |||||
atb.runTests(args[0], args[1], args[2]); | atb.runTests(args[0], args[1], args[2]); | ||||
System.exit(0); | System.exit(0); | ||||
* | * | ||||
*/ | */ | ||||
protected void runTests(String in, String type, String out) { | protected void runTests(String in, String type, String out) { | ||||
log.debug("Starting tests"); | |||||
getLogger().debug("Starting tests"); | |||||
runTest(in, type, out); | runTest(in, type, out); | ||||
log.debug("Finished"); | |||||
getLogger().debug("Finished"); | |||||
} | } | ||||
/** | /** | ||||
} else if ("svg".equals(type)) { | } else if ("svg".equals(type)) { | ||||
rend = new SVGRenderer(); | rend = new SVGRenderer(); | ||||
} | } | ||||
setupLogger(rend); | |||||
FontInfo fi = new FontInfo(); | FontInfo fi = new FontInfo(); | ||||
rend.setupFontInfo(fi); | rend.setupFontInfo(fi); | ||||
rend.setUserAgent(new FOUserAgent()); | |||||
FOUserAgent ua = new FOUserAgent(); | |||||
setupLogger(ua); | |||||
rend.setUserAgent(ua); | |||||
AreaTree.StorePagesModel sm = AreaTree.createStorePagesModel(); | AreaTree.StorePagesModel sm = AreaTree.createStorePagesModel(); | ||||
TreeLoader tl = new TreeLoader(fi); | TreeLoader tl = new TreeLoader(fi); | ||||
tl.buildAreaTree(is); | tl.buildAreaTree(is); | ||||
renderAreaTree(sm, rend, out); | renderAreaTree(sm, rend, out); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("error reading file" + e.getMessage(), e); | |||||
getLogger().error("error reading file" + e.getMessage(), e); | |||||
} | } | ||||
} | } | ||||
OutputStream os = | OutputStream os = | ||||
new BufferedOutputStream(new FileOutputStream(out)); | new BufferedOutputStream(new FileOutputStream(out)); | ||||
rend.setLogger(log); | |||||
rend.startRenderer(os); | rend.startRenderer(os); | ||||
int count = 0; | int count = 0; | ||||
page.savePage(tempstream); | page.savePage(tempstream); | ||||
tempstream.close(); | tempstream.close(); | ||||
File temp = new File("temp.ser"); | File temp = new File("temp.ser"); | ||||
log.debug("page serialized to: " + temp.length()); | |||||
getLogger().debug("page serialized to: " + temp.length()); | |||||
temp = null; | temp = null; | ||||
ObjectInputStream in = new ObjectInputStream( | ObjectInputStream in = new ObjectInputStream( | ||||
new BufferedInputStream( | new BufferedInputStream( | ||||
rend.stopRenderer(); | rend.stopRenderer(); | ||||
os.close(); | os.close(); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("error rendering output", e); | |||||
getLogger().error("error rendering output", e); | |||||
} | } | ||||
} | } | ||||
Node obj = childs.item(i); | Node obj = childs.item(i); | ||||
if (obj.getNodeName().equals("block")) { | if (obj.getNodeName().equals("block")) { | ||||
Block block = new Block(); | Block block = new Block(); | ||||
addTraits((Element)obj, block); | |||||
addTraits((Element)obj, block); | |||||
addBlockChildren(block, (Element) obj); | addBlockChildren(block, (Element) obj); | ||||
list.add(block); | list.add(block); | ||||
} | } | ||||
// error | // error | ||||
} | } | ||||
LineArea line = new LineArea(); | LineArea line = new LineArea(); | ||||
addTraits((Element) obj, line); | |||||
addTraits((Element) obj, line); | |||||
String height = ((Element) obj).getAttribute("height"); | String height = ((Element) obj).getAttribute("height"); | ||||
int h = Integer.parseInt(height); | int h = Integer.parseInt(height); | ||||
line.setHeight(h); | line.setHeight(h); | ||||
for (int i = 0; i < childs.getLength(); i++) { | for (int i = 0; i < childs.getLength(); i++) { | ||||
Node obj = childs.item(i); | Node obj = childs.item(i); | ||||
if (obj instanceof Element) { | if (obj instanceof Element) { | ||||
//System.out.println(obj.getNodeName()); | |||||
//getLogger().debug(obj.getNodeName()); | |||||
Element rootEle = (Element) obj; | Element rootEle = (Element) obj; | ||||
String space = rootEle.getAttribute("xmlns"); | String space = rootEle.getAttribute("xmlns"); | ||||
if (svgNS.equals(space)) { | if (svgNS.equals(space)) { | ||||
String tok = st.nextToken(); | String tok = st.nextToken(); | ||||
int index = tok.indexOf(":"); | int index = tok.indexOf(":"); | ||||
String id = tok.substring(0, index); | String id = tok.substring(0, index); | ||||
Object traitCode = Trait.getTraitCode(id); | |||||
if (traitCode != null) { | |||||
area.addTrait(traitCode, | |||||
Trait.makeTraitValue(traitCode, | |||||
tok.substring(index + 1))); | |||||
} | |||||
else { | |||||
System.err.println("Unknown trait: " + id ); | |||||
} | |||||
Object traitCode = Trait.getTraitCode(id); | |||||
if (traitCode != null) { | |||||
area.addTrait(traitCode, | |||||
Trait.makeTraitValue(traitCode, | |||||
tok.substring(index + 1))); | |||||
} | |||||
else { | |||||
System.err.println("Unknown trait: " + id ); | |||||
} | |||||
} | } | ||||
} | } | ||||
import org.apache.fop.configuration.*; | import org.apache.fop.configuration.*; | ||||
import org.apache.avalon.framework.logger.ConsoleLogger; | import org.apache.avalon.framework.logger.ConsoleLogger; | ||||
import org.apache.avalon.framework.logger.Logger; | |||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||||
import java.io.*; | import java.io.*; | ||||
import java.util.*; | import java.util.*; | ||||
* Modified by Mark Lillywhite mark-fop@inomial.com to use the new Driver | * Modified by Mark Lillywhite mark-fop@inomial.com to use the new Driver | ||||
* interface. | * interface. | ||||
*/ | */ | ||||
public class TestConverter { | |||||
public class TestConverter extends AbstractLogEnabled { | |||||
boolean failOnly = false; | boolean failOnly = false; | ||||
boolean outputPDF = false; | boolean outputPDF = false; | ||||
File destdir; | File destdir; | ||||
File compare = null; | File compare = null; | ||||
String baseDir = "./"; | String baseDir = "./"; | ||||
HashMap differ = new HashMap(); | HashMap differ = new HashMap(); | ||||
private Logger log; | |||||
/** | /** | ||||
* This main method can be used to run the test converter from | * This main method can be used to run the test converter from | ||||
System.out.println("test suite file name required"); | System.out.println("test suite file name required"); | ||||
} | } | ||||
TestConverter tc = new TestConverter(); | TestConverter tc = new TestConverter(); | ||||
tc.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_ERROR)); | |||||
String testFile = null; | String testFile = null; | ||||
for (int count = 0; count < args.length; count++) { | for (int count = 0; count < args.length; count++) { | ||||
tc.runTests(testFile, "results", null); | tc.runTests(testFile, "results", null); | ||||
} | } | ||||
public TestConverter() { | |||||
setupLogging(); | |||||
} | |||||
private void setupLogging() { | |||||
log = new ConsoleLogger(ConsoleLogger.LEVEL_ERROR); | |||||
} | |||||
public void setOutputPDF(boolean pdf) { | public void setOutputPDF(boolean pdf) { | ||||
outputPDF = pdf; | outputPDF = pdf; | ||||
} | } | ||||
* The document is read as a dom and each testcase is covered. | * The document is read as a dom and each testcase is covered. | ||||
*/ | */ | ||||
public HashMap runTests(String fname, String dest, String compDir) { | public HashMap runTests(String fname, String dest, String compDir) { | ||||
log.debug("running tests in file:" + fname); | |||||
getLogger().debug("running tests in file:" + fname); | |||||
try { | try { | ||||
if (compDir != null) { | if (compDir != null) { | ||||
compare = new File(baseDir + "/" + compDir); | compare = new File(baseDir + "/" + compDir); | ||||
if (testsuite.hasAttributes()) { | if (testsuite.hasAttributes()) { | ||||
String profile = | String profile = | ||||
testsuite.getAttributes().getNamedItem("profile").getNodeValue(); | testsuite.getAttributes().getNamedItem("profile").getNodeValue(); | ||||
log.debug("testing test suite:" + profile); | |||||
getLogger().debug("testing test suite:" + profile); | |||||
} | } | ||||
NodeList testcases = testsuite.getChildNodes(); | NodeList testcases = testsuite.getChildNodes(); | ||||
} | } | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
e.printStackTrace(); | |||||
getLogger().error("Error while running tests", e); | |||||
} | } | ||||
return differ; | return differ; | ||||
} | } | ||||
if (tcase.hasAttributes()) { | if (tcase.hasAttributes()) { | ||||
String profile = | String profile = | ||||
tcase.getAttributes().getNamedItem("profile").getNodeValue(); | tcase.getAttributes().getNamedItem("profile").getNodeValue(); | ||||
log.debug("testing profile:" + profile); | |||||
getLogger().debug("testing profile:" + profile); | |||||
} | } | ||||
NodeList cases = tcase.getChildNodes(); | NodeList cases = tcase.getChildNodes(); | ||||
if (xslNode != null) { | if (xslNode != null) { | ||||
xsl = xslNode.getNodeValue(); | xsl = xslNode.getNodeValue(); | ||||
} | } | ||||
log.debug("converting xml:" + xml + " and xsl:" + | |||||
getLogger().debug("converting xml:" + xml + " and xsl:" + | |||||
xsl + " to area tree"); | xsl + " to area tree"); | ||||
try { | try { | ||||
Configuration.put("baseDir", | Configuration.put("baseDir", | ||||
xmlFile.getParentFile().toURL().toExternalForm()); | xmlFile.getParentFile().toURL().toExternalForm()); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("Error setting base directory"); | |||||
getLogger().error("Error setting base directory"); | |||||
} | } | ||||
InputHandler inputHandler = null; | InputHandler inputHandler = null; | ||||
XMLReader parser = inputHandler.getParser(); | XMLReader parser = inputHandler.getParser(); | ||||
setParserFeatures(parser); | setParserFeatures(parser); | ||||
Logger logger = log.getChildLogger("fop"); | |||||
Driver driver = new Driver(); | Driver driver = new Driver(); | ||||
driver.setLogger(logger); | |||||
setupLogger(driver, "fop"); | |||||
driver.initialize(); | driver.initialize(); | ||||
if (outputPDF) { | if (outputPDF) { | ||||
driver.setRenderer(Driver.RENDER_PDF); | driver.setRenderer(Driver.RENDER_PDF); | ||||
driver.setOutputStream(new BufferedOutputStream( | driver.setOutputStream(new BufferedOutputStream( | ||||
new FileOutputStream(new File(destdir, | new FileOutputStream(new File(destdir, | ||||
outname + (outputPDF ? ".pdf" : ".at.xml"))))); | outname + (outputPDF ? ".pdf" : ".at.xml"))))); | ||||
log.debug("ddir:" + destdir + " on:" + outname + ".pdf"); | |||||
getLogger().debug("ddir:" + destdir + " on:" + outname + ".pdf"); | |||||
driver.render(parser, inputHandler.getInputSource()); | driver.render(parser, inputHandler.getInputSource()); | ||||
// check difference | // check difference | ||||
} | } | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
e.printStackTrace(); | |||||
getLogger().error("Error while running tests", e); | |||||
} | } | ||||
} | } | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
try { | try { | ||||
Starter starter = new FOPTaskStarter(this); | Starter starter = new FOPTaskStarter(this); | ||||
starter.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_INFO)); | |||||
starter.run(); | starter.run(); | ||||
} catch (FOPException ex) { | } catch (FOPException ex) { | ||||
throw new BuildException(ex); | throw new BuildException(ex); | ||||
class FOPTaskStarter extends Starter { | class FOPTaskStarter extends Starter { | ||||
Fop task; | Fop task; | ||||
Logger log; | |||||
FOPTaskStarter(Fop task) throws FOPException { | FOPTaskStarter(Fop task) throws FOPException { | ||||
this.task = task; | this.task = task; | ||||
log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); | |||||
} | } | ||||
private int determineRenderer(String format) { | private int determineRenderer(String format) { | ||||
return Driver.RENDER_XML; | return Driver.RENDER_XML; | ||||
} else { | } else { | ||||
String err = "Couldn't determine renderer to use: "+format; | String err = "Couldn't determine renderer to use: "+format; | ||||
log.error(err); | |||||
getLogger().error(err); | |||||
throw new BuildException(err); | throw new BuildException(err); | ||||
} | } | ||||
} | } | ||||
return ".xml"; | return ".xml"; | ||||
default: | default: | ||||
String err = "Unknown renderer: "+renderer; | String err = "Unknown renderer: "+renderer; | ||||
log.error(err); | |||||
getLogger().error(err); | |||||
throw new BuildException(err); | throw new BuildException(err); | ||||
} | } | ||||
} | } | ||||
toExternalForm()); | toExternalForm()); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("Error setting base directory",e); | |||||
getLogger().error("Error setting base directory", e); | |||||
} | } | ||||
task.log("Using base directory: " + | task.log("Using base directory: " + | ||||
try { | try { | ||||
out = new FileOutputStream(outFile); | out = new FileOutputStream(outFile); | ||||
} catch (Exception ex) { | } catch (Exception ex) { | ||||
log.error("Failed to open " + outFile); | |||||
getLogger().error("Failed to open " + outFile); | |||||
throw new BuildException(ex); | throw new BuildException(ex); | ||||
} | } | ||||
try { | try { | ||||
Driver driver = new Driver(inputHandler.getInputSource(), out); | Driver driver = new Driver(inputHandler.getInputSource(), out); | ||||
driver.setLogger(log); | |||||
setupLogger(driver); | |||||
driver.setRenderer(renderer); | driver.setRenderer(renderer); | ||||
if (renderer == Driver.RENDER_XML) { | |||||
HashMap rendererOptions = new HashMap(); | |||||
rendererOptions.put("fineDetail", new Boolean(true)); | |||||
driver.getRenderer().setOptions(rendererOptions); | |||||
} | |||||
if (renderer == Driver.RENDER_XML) { | |||||
HashMap rendererOptions = new HashMap(); | |||||
rendererOptions.put("fineDetail", new Boolean(true)); | |||||
driver.getRenderer().setOptions(rendererOptions); | |||||
} | |||||
driver.setXMLReader(parser); | driver.setXMLReader(parser); | ||||
driver.run(); | driver.run(); | ||||
out.close(); | out.close(); | ||||
} catch (Exception ex) { | } catch (Exception ex) { | ||||
log.error("Couldn't render file: " + ex.getMessage()); | |||||
getLogger().error("Couldn't render file: " + ex.getMessage()); | |||||
throw new BuildException(ex); | throw new BuildException(ex); | ||||
} | } | ||||
} | } |