001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: FOUserAgent.java 554091 2007-07-06 23:44:57Z adelmelle $ */
019:
020: package org.apache.fop.apps;
021:
022: // Java
023: import java.io.File;
024: import java.util.Date;
025: import java.util.Map;
026: import javax.xml.transform.Source;
027: import javax.xml.transform.TransformerException;
028: import javax.xml.transform.URIResolver;
029:
030: // commons logging
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033:
034: // FOP
035: import org.apache.fop.Version;
036: import org.apache.fop.fo.FOEventHandler;
037: import org.apache.fop.pdf.PDFEncryptionParams;
038: import org.apache.fop.render.Renderer;
039: import org.apache.fop.render.RendererFactory;
040: import org.apache.fop.render.XMLHandlerRegistry;
041: import org.apache.fop.render.pdf.PDFRenderer;
042:
043: /**
044: * This is the user agent for FOP.
045: * It is the entity through which you can interact with the XSL-FO processing and is
046: * used by the processing to obtain user configurable options.
047: * <p>
048: * Renderer specific extensions (that do not produce normal areas on
049: * the output) will be done like so:
050: * <br>
051: * The extension will create an area, custom if necessary
052: * <br>
053: * this area will be added to the user agent with a key
054: * <br>
055: * the renderer will know keys for particular extensions
056: * <br>
057: * eg. bookmarks will be held in a special hierarchical area representing
058: * the title and bookmark structure
059: * <br>
060: * These areas may contain resolvable areas that will be processed
061: * with other resolvable areas
062: */
063: public class FOUserAgent {
064:
065: /** Defines the default target resolution (72dpi) for FOP */
066: public static final float DEFAULT_TARGET_RESOLUTION = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
067:
068: private static Log log = LogFactory.getLog("FOP");
069:
070: private FopFactory factory;
071:
072: /**
073: * The base URL for all URL resolutions, especially for
074: * external-graphics.
075: */
076: private String base = null;
077:
078: /** The base URL for all font URL resolutions. */
079: private String fontBase = null;
080:
081: /** A user settable URI Resolver */
082: private URIResolver uriResolver = null;
083:
084: private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
085: private Map rendererOptions = new java.util.HashMap();
086: private File outputFile = null;
087: private Renderer rendererOverride = null;
088: private FOEventHandler foEventHandlerOverride = null;
089: private boolean locatorEnabled = true; // true by default (for error messages).
090:
091: /** Producer: Metadata element for the system/software that produces
092: * the document. (Some renderers can store this in the document.)
093: */
094: protected String producer = "Apache FOP Version "
095: + Version.getVersion();
096:
097: /** Creator: Metadata element for the user that created the
098: * document. (Some renderers can store this in the document.)
099: */
100: protected String creator = null;
101:
102: /** Creation Date: Override of the date the document was created.
103: * (Some renderers can store this in the document.)
104: */
105: protected Date creationDate = null;
106:
107: /** Author of the content of the document. */
108: protected String author = null;
109: /** Title of the document. */
110: protected String title = null;
111: /** Set of keywords applicable to this document. */
112: protected String keywords = null;
113:
114: /**
115: * Default constructor
116: * @see org.apache.fop.apps.FopFactory
117: * @deprecated Provided for compatibility only. Please use the methods from
118: * FopFactory to construct FOUserAgent instances!
119: */
120: public FOUserAgent() throws FOPException {
121: this (FopFactory.newInstance());
122: }
123:
124: /**
125: * Main constructor. <b>This constructor should not be called directly. Please use the
126: * methods from FopFactory to construct FOUserAgent instances!</b>
127: * @param factory the factory that provides environment-level information
128: * @see org.apache.fop.apps.FopFactory
129: */
130: public FOUserAgent(FopFactory factory) {
131: if (factory == null) {
132: throw new NullPointerException(
133: "The factory parameter must not be null");
134: }
135: this .factory = factory;
136: setBaseURL(factory.getBaseURL());
137: setFontBaseURL(factory.getFontBaseURL());
138: setTargetResolution(factory.getTargetResolution());
139: }
140:
141: /** @return the associated FopFactory instance */
142: public FopFactory getFactory() {
143: return this .factory;
144: }
145:
146: // ---------------------------------------------- rendering-run dependent stuff
147:
148: /**
149: * Sets an explicit renderer to use which overrides the one defined by the
150: * render type setting.
151: * @param renderer the Renderer instance to use
152: */
153: public void setRendererOverride(Renderer renderer) {
154: this .rendererOverride = renderer;
155: }
156:
157: /**
158: * Returns the overriding Renderer instance, if any.
159: * @return the overriding Renderer or null
160: */
161: public Renderer getRendererOverride() {
162: return rendererOverride;
163: }
164:
165: /**
166: * Sets an explicit FOEventHandler instance which overrides the one
167: * defined by the render type setting.
168: * @param handler the FOEventHandler instance
169: */
170: public void setFOEventHandlerOverride(FOEventHandler handler) {
171: this .foEventHandlerOverride = handler;
172: }
173:
174: /**
175: * Returns the overriding FOEventHandler instance, if any.
176: * @return the overriding FOEventHandler or null
177: */
178: public FOEventHandler getFOEventHandlerOverride() {
179: return this .foEventHandlerOverride;
180: }
181:
182: /**
183: * Sets the producer of the document.
184: * @param producer source of document
185: */
186: public void setProducer(String producer) {
187: this .producer = producer;
188: }
189:
190: /**
191: * Returns the producer of the document
192: * @return producer name
193: */
194: public String getProducer() {
195: return producer;
196: }
197:
198: /**
199: * Sets the creator of the document.
200: * @param creator of document
201: */
202: public void setCreator(String creator) {
203: this .creator = creator;
204: }
205:
206: /**
207: * Returns the creator of the document
208: * @return creator name
209: */
210: public String getCreator() {
211: return creator;
212: }
213:
214: /**
215: * Sets the creation date of the document.
216: * @param creationDate date of document
217: */
218: public void setCreationDate(Date creationDate) {
219: this .creationDate = creationDate;
220: }
221:
222: /**
223: * Returns the creation date of the document
224: * @return creation date of document
225: */
226: public Date getCreationDate() {
227: return creationDate;
228: }
229:
230: /**
231: * Sets the author of the document.
232: * @param author of document
233: */
234: public void setAuthor(String author) {
235: this .author = author;
236: }
237:
238: /**
239: * Returns the author of the document
240: * @return author name
241: */
242: public String getAuthor() {
243: return author;
244: }
245:
246: /**
247: * Sets the title of the document. This will override any title coming from
248: * an fo:title element.
249: * @param title of document
250: */
251: public void setTitle(String title) {
252: this .title = title;
253: }
254:
255: /**
256: * Returns the title of the document
257: * @return title name
258: */
259: public String getTitle() {
260: return title;
261: }
262:
263: /**
264: * Sets the keywords for the document.
265: * @param keywords for the document
266: */
267: public void setKeywords(String keywords) {
268: this .keywords = keywords;
269: }
270:
271: /**
272: * Returns the keywords for the document
273: * @return the keywords
274: */
275: public String getKeywords() {
276: return keywords;
277: }
278:
279: /**
280: * Returns the renderer options
281: * @return renderer options
282: */
283: public Map getRendererOptions() {
284: return rendererOptions;
285: }
286:
287: /**
288: * Sets the base URL.
289: * @param baseUrl base URL
290: */
291: public void setBaseURL(String baseUrl) {
292: this .base = baseUrl;
293: }
294:
295: /**
296: * sets font base URL
297: * @param fontBaseUrl font base URL
298: */
299: public void setFontBaseURL(String fontBaseUrl) {
300: this .fontBase = fontBaseUrl;
301: }
302:
303: /**
304: * Returns the base URL.
305: * @return the base URL
306: */
307: public String getBaseURL() {
308: return this .base;
309: }
310:
311: /**
312: * Sets the URI Resolver.
313: * @param resolver the new URI resolver
314: */
315: public void setURIResolver(URIResolver resolver) {
316: this .uriResolver = resolver;
317: }
318:
319: /**
320: * Returns the URI Resolver.
321: * @return the URI Resolver
322: */
323: public URIResolver getURIResolver() {
324: return this .uriResolver;
325: }
326:
327: /**
328: * Returns the parameters for PDF encryption.
329: * @return the PDF encryption parameters, null if not applicable
330: * @deprecated Use (PDFEncryptionParams)getRendererOptions().get("encryption-params")
331: * instead.
332: */
333: public PDFEncryptionParams getPDFEncryptionParams() {
334: return (PDFEncryptionParams) getRendererOptions().get(
335: PDFRenderer.ENCRYPTION_PARAMS);
336: }
337:
338: /**
339: * Sets the parameters for PDF encryption.
340: * @param pdfEncryptionParams the PDF encryption parameters, null to
341: * disable PDF encryption
342: * @deprecated Use getRendererOptions().put("encryption-params",
343: * new PDFEncryptionParams(..)) instead or set every parameter separately:
344: * getRendererOptions().put("noprint", Boolean.TRUE).
345: */
346: public void setPDFEncryptionParams(
347: PDFEncryptionParams pdfEncryptionParams) {
348: getRendererOptions().put(PDFRenderer.ENCRYPTION_PARAMS,
349: pdfEncryptionParams);
350: }
351:
352: /**
353: * Attempts to resolve the given URI.
354: * Will use the configured resolver and if not successful fall back
355: * to the default resolver.
356: * @param uri URI to access
357: * @return A {@link javax.xml.transform.Source} object, or null if the URI
358: * cannot be resolved.
359: * @see org.apache.fop.apps.FOURIResolver
360: */
361: public Source resolveURI(String uri) {
362: return resolveURI(uri, getBaseURL());
363: }
364:
365: /**
366: * Attempts to resolve the given URI.
367: * Will use the configured resolver and if not successful fall back
368: * to the default resolver.
369: * @param href URI to access
370: * @param base the base URI to resolve against
371: * @return A {@link javax.xml.transform.Source} object, or null if the URI
372: * cannot be resolved.
373: * @see org.apache.fop.apps.FOURIResolver
374: */
375: public Source resolveURI(String href, String base) {
376: Source source = null;
377: //RFC 2397 data URLs don't need to be resolved, just decode them through FOP's default
378: //URIResolver.
379: boolean bypassURIResolution = href.startsWith("data:");
380: if (!bypassURIResolution && uriResolver != null) {
381: try {
382: source = uriResolver.resolve(href, base);
383: } catch (TransformerException te) {
384: log.error("Attempt to resolve URI '" + href
385: + "' failed: ", te);
386: }
387: }
388: if (source == null) {
389: // URI Resolver not configured or returned null, use default resolver from the factory
390: source = getFactory().resolveURI(href, base);
391: }
392: return source;
393: }
394:
395: /**
396: * Sets the output File.
397: * @param f the output File
398: */
399: public void setOutputFile(File f) {
400: this .outputFile = f;
401: }
402:
403: /**
404: * Gets the output File.
405: * @return the output File
406: */
407: public File getOutputFile() {
408: return outputFile;
409: }
410:
411: /**
412: * Returns the conversion factor from pixel units to millimeters. This
413: * depends on the desired target resolution.
414: * @return float conversion factor
415: * @see #getTargetResolution()
416: */
417: public float getTargetPixelUnitToMillimeter() {
418: return 25.4f / this .targetResolution;
419: }
420:
421: /** @return the resolution for resolution-dependant output */
422: public float getTargetResolution() {
423: return this .targetResolution;
424: }
425:
426: /**
427: * Sets the target resolution in dpi. This value defines the target resolution of
428: * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
429: * bitmap images generated by filter effects in Apache Batik.
430: * @param dpi resolution in dpi
431: */
432: public void setTargetResolution(float dpi) {
433: this .targetResolution = dpi;
434: if (log.isDebugEnabled()) {
435: log.debug("target-resolution set to: " + targetResolution
436: + "dpi (px2mm=" + getTargetPixelUnitToMillimeter()
437: + ")");
438: }
439: }
440:
441: /**
442: * Sets the target resolution in dpi. This value defines the target resolution of
443: * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
444: * bitmap images generated by filter effects in Apache Batik.
445: * @param dpi resolution in dpi
446: */
447: public void setTargetResolution(int dpi) {
448: setTargetResolution((float) dpi);
449: }
450:
451: // ---------------------------------------------- environment-level stuff
452: // (convenience access to FopFactory methods)
453:
454: /** @return the font base URL */
455: public String getFontBaseURL() {
456: return fontBase != null ? fontBase : getBaseURL();
457: }
458:
459: /**
460: * Returns the conversion factor from pixel units to millimeters. This
461: * depends on the desired source resolution.
462: * @return float conversion factor
463: * @see #getSourceResolution()
464: */
465: public float getSourcePixelUnitToMillimeter() {
466: return getFactory().getSourcePixelUnitToMillimeter();
467: }
468:
469: /** @return the resolution for resolution-dependant input */
470: public float getSourceResolution() {
471: return getFactory().getSourceResolution();
472: }
473:
474: /**
475: * Gets the default page-height to use as fallback,
476: * in case page-height="auto"
477: *
478: * @return the page-height, as a String
479: * @see FopFactory#getPageHeight()
480: */
481: public String getPageHeight() {
482: return getFactory().getPageHeight();
483: }
484:
485: /**
486: * Gets the default page-width to use as fallback,
487: * in case page-width="auto"
488: *
489: * @return the page-width, as a String
490: * @see FopFactory#getPageWidth()
491: */
492: public String getPageWidth() {
493: return getFactory().getPageWidth();
494: }
495:
496: /**
497: * Returns whether FOP is strictly validating input XSL
498: * @return true of strict validation turned on, false otherwise
499: * @see FopFactory#validateStrictly()
500: */
501: public boolean validateStrictly() {
502: return getFactory().validateStrictly();
503: }
504:
505: /**
506: * @return true if the indent inheritance should be broken when crossing reference area
507: * boundaries (for more info, see the javadoc for the relative member variable)
508: * @see FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()
509: */
510: public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
511: return getFactory()
512: .isBreakIndentInheritanceOnReferenceAreaBoundary();
513: }
514:
515: /**
516: * @return the RendererFactory
517: */
518: public RendererFactory getRendererFactory() {
519: return getFactory().getRendererFactory();
520: }
521:
522: /**
523: * @return the XML handler registry
524: */
525: public XMLHandlerRegistry getXMLHandlerRegistry() {
526: return getFactory().getXMLHandlerRegistry();
527: }
528:
529: /**
530: * Controls the use of SAXLocators to provide location information in error
531: * messages.
532: *
533: * @param enableLocator <code>false</code> if SAX Locators should be disabled
534: * @return true if context information should be stored on each node in the FO tree.
535: */
536: public void setLocatorEnabled(boolean enableLocator) {
537: locatorEnabled = enableLocator;
538: }
539:
540: /**
541: * Checks if the use of Locators is enabled
542: * @return true if context information should be stored on each node in the FO tree.
543: */
544: public boolean isLocatorEnabled() {
545: return locatorEnabled;
546: }
547:
548: }
|