KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > apps > FopFactory


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id$ */
19
20 package org.apache.fop.apps;
21
22 import java.awt.color.ColorSpace JavaDoc;
23 import java.awt.color.ICC_ColorSpace JavaDoc;
24 import java.awt.color.ICC_Profile JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.OutputStream JavaDoc;
28 import java.net.MalformedURLException JavaDoc;
29 import java.util.Collection JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33
34 import javax.xml.transform.Source JavaDoc;
35 import javax.xml.transform.TransformerException JavaDoc;
36 import javax.xml.transform.URIResolver JavaDoc;
37 import javax.xml.transform.stream.StreamSource JavaDoc;
38
39 import org.xml.sax.SAXException JavaDoc;
40
41 import org.apache.avalon.framework.configuration.Configuration;
42 import org.apache.avalon.framework.configuration.ConfigurationException;
43 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
44
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47
48 import org.apache.fop.fo.ElementMapping;
49 import org.apache.fop.fo.ElementMappingRegistry;
50 import org.apache.fop.hyphenation.HyphenationTreeResolver;
51 import org.apache.fop.image.ImageFactory;
52 import org.apache.fop.layoutmgr.LayoutManagerMaker;
53 import org.apache.fop.render.RendererFactory;
54 import org.apache.fop.render.XMLHandlerRegistry;
55 import org.apache.fop.util.ContentHandlerFactoryRegistry;
56
57 /**
58  * Factory class which instantiates new Fop and FOUserAgent instances. This class also holds
59  * environmental information and configuration used by FOP. Information that may potentially be
60  * different for each rendering run can be found and managed in the FOUserAgent.
61  */

62 public class FopFactory {
63
64     /** Defines the default source resolution (72dpi) for FOP */
65     private static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi
66
/** Defines the default page-height */
67     private static final String JavaDoc DEFAULT_PAGE_HEIGHT = "11in";
68     /** Defines the default page-width */
69     private static final String JavaDoc DEFAULT_PAGE_WIDTH = "8.26in";
70
71     /** logger instance */
72     private static Log log = LogFactory.getLog(FopFactory.class);
73     
74     /** Factory for Renderers and FOEventHandlers */
75     private RendererFactory rendererFactory = new RendererFactory();
76     
77     /** Registry for XML handlers */
78     private XMLHandlerRegistry xmlHandlers = new XMLHandlerRegistry();
79     
80     /** The registry for ElementMapping instances */
81     private ElementMappingRegistry elementMappingRegistry;
82
83     /** The registry for ContentHandlerFactory instance */
84     private ContentHandlerFactoryRegistry contentHandlerFactoryRegistry
85                 = new ContentHandlerFactoryRegistry();
86     
87     /** Our default resolver if none is set */
88     private URIResolver JavaDoc foURIResolver = new FOURIResolver();
89     /** A user settable URI Resolver */
90     private URIResolver JavaDoc uriResolver = null;
91
92     /** The resolver for user-supplied hyphenation patterns */
93     private HyphenationTreeResolver hyphResolver;
94     
95     private ImageFactory imageFactory = new ImageFactory();
96
97     /** user configuration */
98     private Configuration userConfig = null;
99
100     /** The base URL for all font URL resolutions */
101     private String JavaDoc fontBaseURL;
102     
103     /**
104      * FOP has the ability, for some FO's, to continue processing even if the
105      * input XSL violates that FO's content model. This is the default
106      * behavior for FOP. However, this flag, if set, provides the user the
107      * ability for FOP to halt on all content model violations if desired.
108      */

109     private boolean strictValidation = true;
110
111     /** Allows enabling kerning on the base 14 fonts, default is false */
112     private boolean enableBase14Kerning = false;
113     
114     /** Source resolution in dpi */
115     private float sourceResolution = DEFAULT_SOURCE_RESOLUTION;
116     private String JavaDoc pageHeight = DEFAULT_PAGE_HEIGHT;
117     private String JavaDoc pageWidth = DEFAULT_PAGE_WIDTH;
118
119     /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
120     private boolean breakIndentInheritanceOnReferenceAreaBoundary = false;
121
122     /** Optional overriding LayoutManagerMaker */
123     private LayoutManagerMaker lmMakerOverride = null;
124
125     private Set JavaDoc ignoredNamespaces = new java.util.HashSet JavaDoc();
126     
127     /** Map with cached ICC based ColorSpace objects. */
128     private Map JavaDoc colorSpaceMap = null;
129     
130     /**
131      * Main constructor.
132      */

133     protected FopFactory() {
134         this.elementMappingRegistry = new ElementMappingRegistry(this);
135         // Use a synchronized Map - I am not really sure this is needed, but better safe than sorry.
136
this.colorSpaceMap = Collections.synchronizedMap(new java.util.HashMap JavaDoc());
137     }
138     
139     /**
140      * Returns a new FopFactory instance.
141      * @return the requested FopFactory instance.
142      */

143     public static FopFactory newInstance() {
144         return new FopFactory();
145     }
146     
147     /**
148      * Returns a new FOUserAgent instance. Use the FOUserAgent to configure special values that
149      * are particular to a rendering run. Don't reuse instances over multiple rendering runs but
150      * instead create a new one each time and reuse the FopFactory.
151      * @return the newly created FOUserAgent instance initialized with default values
152      */

153     public FOUserAgent newFOUserAgent() {
154         FOUserAgent userAgent = new FOUserAgent(this);
155         return userAgent;
156     }
157
158     /**
159      * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
160      * instance.
161      * <p>
162      * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
163      * use the constants defined in {@link MimeConstants}.
164      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
165      * @return the new Fop instance
166      * @throws FOPException when the constructor fails
167      */

168     public Fop newFop(String JavaDoc outputFormat) throws FOPException {
169         return new Fop(outputFormat, newFOUserAgent());
170     }
171
172     /**
173      * Returns a new {@link Fop} instance. Use this factory method if you want to configure this
174      * very rendering run, i.e. if you want to set some metadata like the title and author of the
175      * document you want to render. In that case, create a new {@link FOUserAgent}
176      * instance using {@link #newFOUserAgent()}.
177      * <p>
178      * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
179      * use the constants defined in {@link MimeConstants}.
180      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
181      * @param userAgent the user agent that will be used to control the rendering run
182      * @return the new Fop instance
183      * @throws FOPException when the constructor fails
184      */

185     public Fop newFop(String JavaDoc outputFormat, FOUserAgent userAgent) throws FOPException {
186         if (userAgent == null) {
187             throw new NullPointerException JavaDoc("The userAgent parameter must not be null!");
188         }
189         return new Fop(outputFormat, userAgent);
190     }
191     
192     /**
193      * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
194      * instance. Use this factory method if your output type requires an output stream.
195      * <p>
196      * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
197      * use the constants defined in {@link MimeConstants}.
198      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
199      * @param stream the output stream
200      * @return the new Fop instance
201      * @throws FOPException when the constructor fails
202      */

203     public Fop newFop(String JavaDoc outputFormat, OutputStream JavaDoc stream) throws FOPException {
204         return new Fop(outputFormat, newFOUserAgent(), stream);
205     }
206
207     /**
208      * Returns a new {@link Fop} instance. Use this factory method if your output type
209      * requires an output stream and you want to configure this very rendering run,
210      * i.e. if you want to set some metadata like the title and author of the document
211      * you want to render. In that case, create a new {@link FOUserAgent} instance
212      * using {@link #newFOUserAgent()}.
213      * <p>
214      * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
215      * use the constants defined in {@link MimeConstants}.
216      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
217      * @param userAgent the user agent that will be used to control the rendering run
218      * @param stream the output stream
219      * @return the new Fop instance
220      * @throws FOPException when the constructor fails
221      */

222     public Fop newFop(String JavaDoc outputFormat, FOUserAgent userAgent, OutputStream JavaDoc stream)
223                 throws FOPException {
224         if (userAgent == null) {
225             throw new NullPointerException JavaDoc("The userAgent parameter must not be null!");
226         }
227         return new Fop(outputFormat, userAgent, stream);
228     }
229     
230     /**
231      * Returns a new {@link Fop} instance. Use this factory method if you want to supply your
232      * own {@link org.apache.fop.render.Renderer Renderer} or
233      * {@link org.apache.fop.fo.FOEventHandler FOEventHandler}
234      * instance instead of the default ones created internally by FOP.
235      * @param userAgent the user agent that will be used to control the rendering run
236      * @return the new Fop instance
237      * @throws FOPException when the constructor fails
238      */

239     public Fop newFop(FOUserAgent userAgent) throws FOPException {
240         if (userAgent.getRendererOverride() == null
241                 && userAgent.getFOEventHandlerOverride() == null) {
242             throw new IllegalStateException JavaDoc("Either the overriding renderer or the overriding"
243                     + " FOEventHandler must be set when this factory method is used!");
244         }
245         return newFop(null, userAgent);
246     }
247
248     /** @return the RendererFactory */
249     public RendererFactory getRendererFactory() {
250         return this.rendererFactory;
251     }
252
253     /** @return the XML handler registry */
254     public XMLHandlerRegistry getXMLHandlerRegistry() {
255         return this.xmlHandlers;
256     }
257     
258     /** @return the element mapping registry */
259     public ElementMappingRegistry getElementMappingRegistry() {
260         return this.elementMappingRegistry;
261     }
262
263     /** @return the content handler factory registry */
264     public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
265         return this.contentHandlerFactoryRegistry;
266     }
267
268     /** @return the image factory */
269     public ImageFactory getImageFactory() {
270         return this.imageFactory;
271     }
272
273     /**
274      * Add the element mapping with the given class name.
275      * @param elementMapping the class name representing the element mapping.
276      */

277     public void addElementMapping(ElementMapping elementMapping) {
278         this.elementMappingRegistry.addElementMapping(elementMapping);
279     }
280
281     /**
282      * Sets an explicit LayoutManagerMaker instance which overrides the one
283      * defined by the AreaTreeHandler.
284      * @param lmMaker the LayoutManagerMaker instance
285      */

286     public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
287         this.lmMakerOverride = lmMaker;
288     }
289
290     /**
291      * Returns the overriding LayoutManagerMaker instance, if any.
292      * @return the overriding LayoutManagerMaker or null
293      */

294     public LayoutManagerMaker getLayoutManagerMakerOverride() {
295         return this.lmMakerOverride;
296     }
297
298     /**
299      * Sets the font base URL.
300      * @param fontBaseURL font base URL
301      */

302     public void setFontBaseURL(String JavaDoc fontBaseURL) {
303         this.fontBaseURL = fontBaseURL;
304     }
305
306     /** @return the font base URL */
307     public String JavaDoc getFontBaseURL() {
308         return this.fontBaseURL;
309     }
310
311     /**
312      * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
313      * patterns and as backup for URI resolution performed during a rendering run.
314      * @param resolver the new URI resolver
315      */

316     public void setURIResolver(URIResolver JavaDoc resolver) {
317         this.uriResolver = resolver;
318     }
319
320     /**
321      * Returns the URI Resolver.
322      * @return the URI Resolver
323      */

324     public URIResolver JavaDoc getURIResolver() {
325         return this.uriResolver;
326     }
327
328     /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
329     public HyphenationTreeResolver getHyphenationTreeResolver() {
330         return this.hyphResolver;
331     }
332     
333     /**
334      * Activates strict XSL content model validation for FOP
335      * Default is false (FOP will continue processing where it can)
336      * @param validateStrictly true to turn on strict validation
337      */

338     public void setStrictValidation(boolean validateStrictly) {
339         this.strictValidation = validateStrictly;
340     }
341
342     /**
343      * Returns whether FOP is strictly validating input XSL
344      * @return true of strict validation turned on, false otherwise
345      */

346     public boolean validateStrictly() {
347         return strictValidation;
348     }
349
350     /**
351      * @return true if the indent inheritance should be broken when crossing reference area
352      * boundaries (for more info, see the javadoc for the relative member variable)
353      */

354     public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
355         return breakIndentInheritanceOnReferenceAreaBoundary;
356     }
357
358     /**
359      * Controls whether to enable a feature that breaks indent inheritance when crossing
360      * reference area boundaries.
361      * <p>
362      * This flag controls whether FOP will enable special code that breaks property
363      * inheritance for start-indent and end-indent when the evaluation of the inherited
364      * value would cross a reference area. This is described under
365      * http://wiki.apache.org/xmlgraphics-fop/IndentInheritance as is intended to
366      * improve interoperability with commercial FO implementations and to produce
367      * results that are more in line with the expectation of unexperienced FO users.
368      * Note: Enabling this features violates the XSL specification!
369      * @param value true to enable the feature
370      */

371     public void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value) {
372         this.breakIndentInheritanceOnReferenceAreaBoundary = value;
373     }
374     
375     /** @return true if kerning on base 14 fonts is enabled */
376     public boolean isBase14KerningEnabled() {
377         return this.enableBase14Kerning;
378     }
379     
380     /**
381      * Controls whether kerning is activated on base 14 fonts.
382      * @param value true if kerning should be activated
383      */

384     public void setBase14KerningEnabled(boolean value) {
385         this.enableBase14Kerning = value;
386     }
387     
388     /** @return the resolution for resolution-dependant input */
389     public float getSourceResolution() {
390         return this.sourceResolution;
391     }
392
393     /**
394      * Returns the conversion factor from pixel units to millimeters. This
395      * depends on the desired source resolution.
396      * @return float conversion factor
397      * @see #getSourceResolution()
398      */

399     public float getSourcePixelUnitToMillimeter() {
400         return 25.4f / getSourceResolution();
401     }
402     
403     /**
404      * Sets the source resolution in dpi. This value is used to interpret the pixel size
405      * of source documents like SVG images and bitmap images without resolution information.
406      * @param dpi resolution in dpi
407      */

408     public void setSourceResolution(int dpi) {
409         this.sourceResolution = dpi;
410     }
411     
412     /**
413      * Gets the default page-height to use as fallback,
414      * in case page-height="auto"
415      *
416      * @return the page-height, as a String
417      */

418     public String JavaDoc getPageHeight() {
419         return this.pageHeight;
420     }
421     
422     /**
423      * Sets the page-height to use as fallback, in case
424      * page-height="auto"
425      *
426      * @param pageHeight page-height as a String
427      */

428     public void setPageHeight(String JavaDoc pageHeight) {
429         this.pageHeight = pageHeight;
430     }
431     
432     /**
433      * Gets the default page-width to use as fallback,
434      * in case page-width="auto"
435      *
436      * @return the page-width, as a String
437      */

438     public String JavaDoc getPageWidth() {
439         return this.pageWidth;
440     }
441     
442     /**
443      * Sets the page-width to use as fallback, in case
444      * page-width="auto"
445      *
446      * @param pageWidth page-width as a String
447      */

448     public void setPageWidth(String JavaDoc pageWidth) {
449         this.pageWidth = pageWidth;
450     }
451     
452     /**
453      * Adds a namespace to the set of ignored namespaces.
454      * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
455      * namespace is in the ignored set.
456      * @param namespaceURI the namespace URI
457      */

458     public void ignoreNamespace(String JavaDoc namespaceURI) {
459         this.ignoredNamespaces.add(namespaceURI);
460     }
461     
462     /**
463      * Adds a collection of namespaces to the set of ignored namespaces.
464      * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
465      * namespace is in the ignored set.
466      * @param namespaceURIs the namespace URIs
467      */

468     public void ignoreNamespaces(Collection JavaDoc namespaceURIs) {
469         this.ignoredNamespaces.addAll(namespaceURIs);
470     }
471     
472     /**
473      * Indicates whether a namespace URI is on the ignored list.
474      * @param namespaceURI the namespace URI
475      * @return true if the namespace is ignored by FOP
476      */

477     public boolean isNamespaceIgnored(String JavaDoc namespaceURI) {
478         return this.ignoredNamespaces.contains(namespaceURI);
479     }
480     
481     /** @return the set of namespaces that are ignored by FOP */
482     public Set JavaDoc getIgnoredNamespace() {
483         return Collections.unmodifiableSet(this.ignoredNamespaces);
484     }
485     
486     //------------------------------------------- Configuration stuff
487

488     /**
489      * Set the user configuration.
490      * @param userConfigFile the configuration file
491      * @throws IOException if an I/O error occurs
492      * @throws SAXException if a parsing error occurs
493      */

494     public void setUserConfig(File JavaDoc userConfigFile)
495                 throws SAXException JavaDoc, IOException JavaDoc {
496         try {
497             DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
498             setUserConfig(cfgBuilder.buildFromFile(userConfigFile));
499         } catch (ConfigurationException cfge) {
500             log.error("Error loading configuration: "
501                     + cfge.getMessage());
502         }
503     }
504     
505     /**
506      * Set the user configuration from an URI.
507      * @param uri the URI to the configuration file
508      * @throws IOException if an I/O error occurs
509      * @throws SAXException if a parsing error occurs
510      */

511     public void setUserConfig(String JavaDoc uri)
512                 throws SAXException JavaDoc, IOException JavaDoc {
513         try {
514             DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
515             setUserConfig(cfgBuilder.build(uri));
516         } catch (ConfigurationException cfge) {
517             log.error("Error loading configuration: "
518                     + cfge.getMessage());
519         }
520     }
521     
522     /**
523      * Set the user configuration.
524      * @param userConfig configuration
525      */

526     public void setUserConfig(Configuration userConfig) {
527         this.userConfig = userConfig;
528         try {
529             initUserConfig();
530         } catch (ConfigurationException cfge) {
531             log.error("Error initializing factory configuration: "
532                     + cfge.getMessage());
533         }
534     }
535
536     /**
537      * Get the user configuration.
538      * @return the user configuration
539      */

540     public Configuration getUserConfig() {
541         return userConfig;
542     }
543     
544     /**
545      * Initializes user agent settings from the user configuration
546      * file, if present: baseURL, resolution, default page size,...
547      *
548      * @throws ConfigurationException when there is an entry that
549      * misses the required attribute
550      */

551     public void initUserConfig() throws ConfigurationException {
552         log.debug("Initializing User Agent Configuration");
553         setFontBaseURL(getBaseURLfromConfig(userConfig, "font-base"));
554         final String JavaDoc hyphBase = getBaseURLfromConfig(userConfig, "hyphenation-base");
555         if (hyphBase != null) {
556             this.hyphResolver = new HyphenationTreeResolver() {
557                 public Source JavaDoc resolve(String JavaDoc href) {
558                     return resolveURI(href, hyphBase);
559                 }
560             };
561         }
562         if (userConfig.getChild("source-resolution", false) != null) {
563             this.sourceResolution
564                 = userConfig.getChild("source-resolution").getValueAsFloat(
565                         DEFAULT_SOURCE_RESOLUTION);
566             log.info("Source resolution set to: " + sourceResolution
567                     + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
568         }
569         if (userConfig.getChild("strict-validation", false) != null) {
570             this.strictValidation = userConfig.getChild("strict-validation").getValueAsBoolean();
571         }
572         if (userConfig.getChild("break-indent-inheritance", false) != null) {
573             this.breakIndentInheritanceOnReferenceAreaBoundary
574                 = userConfig.getChild("break-indent-inheritance").getValueAsBoolean();
575         }
576         Configuration pageConfig = userConfig.getChild("default-page-settings");
577         if (pageConfig.getAttribute("height", null) != null) {
578             setPageHeight(pageConfig.getAttribute("height"));
579             log.info("Default page-height set to: " + pageHeight);
580         }
581         if (pageConfig.getAttribute("width", null) != null) {
582             setPageWidth(pageConfig.getAttribute("width"));
583             log.info("Default page-width set to: " + pageWidth);
584         }
585     }
586
587     /**
588      * Retrieves and verifies a base URL.
589      * @param cfg The Configuration object to retrieve the base URL from
590      * @param name the element name for the base URL
591      * @return the requested base URL or null if not available
592      */

593     public static String JavaDoc getBaseURLfromConfig(Configuration cfg, String JavaDoc name) {
594         if (cfg.getChild(name, false) != null) {
595             try {
596                 String JavaDoc cfgBaseDir = cfg.getChild(name).getValue(null);
597                 if (cfgBaseDir != null) {
598                     File JavaDoc dir = new File JavaDoc(cfgBaseDir);
599                     if (dir.isDirectory()) {
600                         cfgBaseDir = dir.toURL().toExternalForm();
601                     }
602                 }
603                 log.info(name + " set to: " + cfgBaseDir);
604                 return cfgBaseDir;
605             } catch (MalformedURLException JavaDoc mue) {
606                 log.error("Base URL in user config is malformed!");
607             }
608         }
609         return null;
610     }
611
612     //------------------------------------------- URI resolution
613

614     /**
615      * Attempts to resolve the given URI.
616      * Will use the configured resolver and if not successful fall back
617      * to the default resolver.
618      * @param uri URI to access
619      * @param base the base URI to resolve against
620      * @return A {@link javax.xml.transform.Source} object, or null if the URI
621      * cannot be resolved.
622      * @see org.apache.fop.apps.FOURIResolver
623      */

624     public Source JavaDoc resolveURI(String JavaDoc uri, String JavaDoc base) {
625         Source JavaDoc source = null;
626         //RFC 2397 data URLs don't need to be resolved, just decode them.
627
boolean bypassURIResolution = uri.startsWith("data:");
628         if (!bypassURIResolution && uriResolver != null) {
629             try {
630                 source = uriResolver.resolve(uri, base);
631             } catch (TransformerException JavaDoc te) {
632                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
633             }
634         }
635         if (source == null) {
636             // URI Resolver not configured or returned null, use default resolver
637
try {
638                 source = foURIResolver.resolve(uri, base);
639             } catch (TransformerException JavaDoc te) {
640                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
641             }
642         }
643         return source;
644     }
645         
646     /**
647      * Create (if needed) and return an ICC ColorSpace instance.
648      *
649      * The ICC profile source is taken from the src attribute of the color-profile FO element.
650      * If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache.
651      *
652      * The FOP URI resolver is used to try and locate the ICC file.
653      * If that fails null is returned.
654      *
655      * @param base a base URI to resolve relative URIs
656      * @param iccProfileSrc ICC Profile source to return a ColorSpace for
657      * @return ICC ColorSpace object or null if ColorSpace could not be created
658      */

659     public ColorSpace JavaDoc getColorSpace(String JavaDoc base, String JavaDoc iccProfileSrc) {
660         ColorSpace JavaDoc colorSpace = null;
661         if (!this.colorSpaceMap.containsKey(base + iccProfileSrc)) {
662             try {
663                 ICC_Profile JavaDoc iccProfile = null;
664                 // First attempt to use the FOP URI resolver to locate the ICC
665
// profile
666
Source JavaDoc src = this.resolveURI(iccProfileSrc, base);
667                 if (src != null && src instanceof StreamSource JavaDoc) {
668                     // FOP URI resolver found ICC profile - create ICC profile
669
// from the Source
670
iccProfile = ICC_Profile.getInstance(((StreamSource JavaDoc) src)
671                             .getInputStream());
672                 } else {
673                     // TODO - Would it make sense to fall back on VM ICC
674
// resolution
675
// Problem is the cache might be more difficult to maintain
676
//
677
// FOP URI resolver did not find ICC profile - perhaps the
678
// Java VM can find it?
679
// iccProfile = ICC_Profile.getInstance(iccProfileSrc);
680
}
681                 if (iccProfile != null) {
682                     colorSpace = new ICC_ColorSpace JavaDoc(iccProfile);
683                 }
684             } catch (IOException JavaDoc e) {
685                 // Ignore exception - will be logged a bit further down
686
// (colorSpace == null case)
687
}
688
689             if (colorSpace != null) {
690                 // Put in cache (not when VM resolved it as we can't control
691
this.colorSpaceMap.put(base + iccProfileSrc, colorSpace);
692             } else {
693                 // TODO To avoid an excessive amount of warnings perhaps
694
// register a null ColorMap in the colorSpaceMap
695
log.warn("Color profile '" + iccProfileSrc + "' not found.");
696             }
697         } else {
698             colorSpace = (ColorSpace JavaDoc) this.colorSpaceMap.get(base
699                     + iccProfileSrc);
700         }
701         return colorSpace;
702     }
703     
704 }
705
Popular Tags