KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > render > RendererFactory


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: RendererFactory.java 426576 2006-07-28 15:44:37Z jeremias $ */
19  
20 package org.apache.fop.render;
21
22 import java.io.OutputStream JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.container.ContainerUtil;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import org.apache.xmlgraphics.util.Service;
35
36 import org.apache.fop.apps.FOPException;
37 import org.apache.fop.apps.FOUserAgent;
38 import org.apache.fop.area.AreaTreeHandler;
39 import org.apache.fop.fo.FOEventHandler;
40
41 /**
42  * Factory for FOEventHandlers and Renderers.
43  */

44 public class RendererFactory {
45     
46     /** the logger */
47     private static Log log = LogFactory.getLog(RendererFactory.class);
48
49     private Map JavaDoc rendererMakerMapping = new java.util.HashMap JavaDoc();
50     private Map JavaDoc eventHandlerMakerMapping = new java.util.HashMap JavaDoc();
51     
52     
53     /**
54      * Main constructor.
55      */

56     public RendererFactory() {
57         discoverRenderers();
58         discoverFOEventHandlers();
59     }
60     
61     /**
62      * Add a new RendererMaker. If another maker has already been registered for a
63      * particular MIME type, this call overwrites the existing one.
64      * @param maker the RendererMaker
65      */

66     public void addRendererMaker(AbstractRendererMaker maker) {
67         String JavaDoc[] mimes = maker.getSupportedMimeTypes();
68         for (int i = 0; i < mimes.length; i++) {
69             //This overrides any renderer previously set for a MIME type
70
if (rendererMakerMapping.get(mimes[i]) != null) {
71                 log.trace("Overriding renderer for " + mimes[i]
72                         + " with " + maker.getClass().getName());
73             }
74             rendererMakerMapping.put(mimes[i], maker);
75         }
76     }
77     
78     /**
79      * Add a new FOEventHandlerMaker. If another maker has already been registered for a
80      * particular MIME type, this call overwrites the existing one.
81      * @param maker the FOEventHandlerMaker
82      */

83     public void addFOEventHandlerMaker(AbstractFOEventHandlerMaker maker) {
84         String JavaDoc[] mimes = maker.getSupportedMimeTypes();
85         for (int i = 0; i < mimes.length; i++) {
86             //This overrides any event handler previously set for a MIME type
87
if (eventHandlerMakerMapping.get(mimes[i]) != null) {
88                 log.trace("Overriding FOEventHandler for " + mimes[i]
89                         + " with " + maker.getClass().getName());
90             }
91             eventHandlerMakerMapping.put(mimes[i], maker);
92         }
93     }
94     
95     /**
96      * Add a new RendererMaker. If another maker has already been registered for a
97      * particular MIME type, this call overwrites the existing one.
98      * @param className the fully qualified class name of the RendererMaker
99      */

100     public void addRendererMaker(String JavaDoc className) {
101         try {
102             AbstractRendererMaker makerInstance
103                 = (AbstractRendererMaker)Class.forName(className).newInstance();
104             addRendererMaker(makerInstance);
105         } catch (ClassNotFoundException JavaDoc e) {
106             throw new IllegalArgumentException JavaDoc("Could not find "
107                                                + className);
108         } catch (InstantiationException JavaDoc e) {
109             throw new IllegalArgumentException JavaDoc("Could not instantiate "
110                                                + className);
111         } catch (IllegalAccessException JavaDoc e) {
112             throw new IllegalArgumentException JavaDoc("Could not access "
113                                                + className);
114         } catch (ClassCastException JavaDoc e) {
115             throw new IllegalArgumentException JavaDoc(className
116                                                + " is not an "
117                                                + AbstractRendererMaker.class.getName());
118         }
119     }
120     
121     /**
122      * Add a new FOEventHandlerMaker. If another maker has already been registered for a
123      * particular MIME type, this call overwrites the existing one.
124      * @param className the fully qualified class name of the FOEventHandlerMaker
125      */

126     public void addFOEventHandlerMaker(String JavaDoc className) {
127         try {
128             AbstractFOEventHandlerMaker makerInstance
129                 = (AbstractFOEventHandlerMaker)Class.forName(className).newInstance();
130             addFOEventHandlerMaker(makerInstance);
131         } catch (ClassNotFoundException JavaDoc e) {
132             throw new IllegalArgumentException JavaDoc("Could not find "
133                                                + className);
134         } catch (InstantiationException JavaDoc e) {
135             throw new IllegalArgumentException JavaDoc("Could not instantiate "
136                                                + className);
137         } catch (IllegalAccessException JavaDoc e) {
138             throw new IllegalArgumentException JavaDoc("Could not access "
139                                                + className);
140         } catch (ClassCastException JavaDoc e) {
141             throw new IllegalArgumentException JavaDoc(className
142                                                + " is not an "
143                                                + AbstractFOEventHandlerMaker.class.getName());
144         }
145     }
146     
147     /**
148      * Returns a RendererMaker which handles the given MIME type.
149      * @param mime the requested output format
150      * @return the requested RendererMaker or null if none is available
151      */

152     public AbstractRendererMaker getRendererMaker(String JavaDoc mime) {
153         AbstractRendererMaker maker
154             = (AbstractRendererMaker)rendererMakerMapping.get(mime);
155         return maker;
156     }
157     
158     /**
159      * Returns a FOEventHandlerMaker which handles the given MIME type.
160      * @param mime the requested output format
161      * @return the requested FOEventHandlerMaker or null if none is available
162      */

163     public AbstractFOEventHandlerMaker getFOEventHandlerMaker(String JavaDoc mime) {
164         AbstractFOEventHandlerMaker maker
165             = (AbstractFOEventHandlerMaker)eventHandlerMakerMapping.get(mime);
166         return maker;
167     }
168     
169     /**
170      * Creates a Renderer object based on render-type desired
171      * @param userAgent the user agent for access to configuration
172      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
173      * @return the new Renderer instance
174      * @throws FOPException if the renderer cannot be properly constructed
175      */

176     public Renderer createRenderer(FOUserAgent userAgent, String JavaDoc outputFormat)
177                     throws FOPException {
178         if (userAgent.getRendererOverride() != null) {
179             return userAgent.getRendererOverride();
180         } else {
181             AbstractRendererMaker maker = getRendererMaker(outputFormat);
182             if (maker == null) {
183                 throw new UnsupportedOperationException JavaDoc(
184                         "No renderer for the requested format available: " + outputFormat);
185             }
186             Renderer rend = maker.makeRenderer(userAgent);
187             rend.setUserAgent(userAgent);
188             String JavaDoc mimeType = rend.getMimeType(); //Always use main MIME type for this
189
Configuration userRendererConfig = null;
190             if (mimeType != null) {
191                 userRendererConfig
192                     = userAgent.getUserRendererConfig(mimeType);
193             }
194             if (userRendererConfig != null) {
195                 try {
196                     ContainerUtil.configure(rend, userRendererConfig);
197                 } catch (ConfigurationException e) {
198                     throw new FOPException(e);
199                 }
200             }
201             return rend;
202         }
203     }
204     
205     
206     /**
207      * Creates FOEventHandler instances based on the desired output.
208      * @param userAgent the user agent for access to configuration
209      * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
210      * @param out the OutputStream where the output is written to (if applicable)
211      * @return the newly constructed FOEventHandler
212      * @throws FOPException if the FOEventHandler cannot be properly constructed
213      */

214     public FOEventHandler createFOEventHandler(FOUserAgent userAgent,
215                 String JavaDoc outputFormat, OutputStream JavaDoc out) throws FOPException {
216
217         if (userAgent.getFOEventHandlerOverride() != null) {
218             return userAgent.getFOEventHandlerOverride();
219         } else {
220             AbstractFOEventHandlerMaker maker = getFOEventHandlerMaker(outputFormat);
221             if (maker == null) {
222                 AbstractRendererMaker rendMaker = getRendererMaker(outputFormat);
223                 if (rendMaker == null && userAgent.getRendererOverride() == null) {
224                     throw new UnsupportedOperationException JavaDoc(
225                             "Don't know how to handle \"" + outputFormat + "\" as an output format."
226                             + " Neither an FOEventHandler, nor a Renderer could be found"
227                             + " for this output format.");
228                 } else {
229                     if (out == null
230                             && userAgent.getRendererOverride() == null
231                             && rendMaker.needsOutputStream()) {
232                         throw new FOPException(
233                             "OutputStream has not been set");
234                     }
235                     //Found a Renderer so we need to construct an AreaTreeHandler.
236
return new AreaTreeHandler(userAgent, outputFormat, out);
237                 }
238             } else {
239                 return maker.makeFOEventHandler(userAgent, out);
240             }
241         }
242     }
243     
244     /**
245      * @return an array of all supported MIME types
246      */

247     public String JavaDoc[] listSupportedMimeTypes() {
248         List JavaDoc lst = new java.util.ArrayList JavaDoc();
249         Iterator JavaDoc iter = this.rendererMakerMapping.keySet().iterator();
250         while (iter.hasNext()) {
251             lst.add(((String JavaDoc)iter.next()));
252         }
253         iter = this.eventHandlerMakerMapping.keySet().iterator();
254         while (iter.hasNext()) {
255             lst.add(((String JavaDoc)iter.next()));
256         }
257         Collections.sort(lst);
258         return (String JavaDoc[])lst.toArray(new String JavaDoc[lst.size()]);
259     }
260     
261     /**
262      * Discovers Renderer implementations through the classpath and dynamically
263      * registers them.
264      */

265     private void discoverRenderers() {
266         // add mappings from available services
267
Iterator JavaDoc providers
268             = Service.providers(Renderer.class);
269         if (providers != null) {
270             while (providers.hasNext()) {
271                 AbstractRendererMaker maker = (AbstractRendererMaker)providers.next();
272                 try {
273                     if (log.isDebugEnabled()) {
274                         log.debug("Dynamically adding maker for Renderer: "
275                                 + maker.getClass().getName());
276                     }
277                     addRendererMaker(maker);
278                 } catch (IllegalArgumentException JavaDoc e) {
279                     log.error("Error while adding maker for Renderer", e);
280                 }
281
282             }
283         }
284     }
285     
286     /**
287      * Discovers FOEventHandler implementations through the classpath and dynamically
288      * registers them.
289      */

290     private void discoverFOEventHandlers() {
291         // add mappings from available services
292
Iterator JavaDoc providers
293             = Service.providers(FOEventHandler.class);
294         if (providers != null) {
295             while (providers.hasNext()) {
296                 AbstractFOEventHandlerMaker maker = (AbstractFOEventHandlerMaker)providers.next();
297                 try {
298                     if (log.isDebugEnabled()) {
299                         log.debug("Dynamically adding maker for FOEventHandler: "
300                                 + maker.getClass().getName());
301                     }
302                     addFOEventHandlerMaker(maker);
303                 } catch (IllegalArgumentException JavaDoc e) {
304                     log.error("Error while adding maker for FOEventHandler", e);
305                 }
306
307             }
308         }
309     }
310     
311 }
312
Popular Tags