KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > pdf > PDFFilterList


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: PDFFilterList.java 426576 2006-07-28 15:44:37Z jeremias $ */
19  
20 package org.apache.fop.pdf;
21
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 // commons logging
28
import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 // Avalon
32
import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34
35 /**
36  * This class represents a list of PDF filters to be applied when serializing
37  * the output of a PDF object.
38  */

39 public class PDFFilterList {
40
41     /** Key for the default filter */
42     public static final String JavaDoc DEFAULT_FILTER = "default";
43     /** Key for the filter used for normal content*/
44     public static final String JavaDoc CONTENT_FILTER = "content";
45     /** Key for the filter used for images */
46     public static final String JavaDoc IMAGE_FILTER = "image";
47     /** Key for the filter used for JPEG images */
48     public static final String JavaDoc JPEG_FILTER = "jpeg";
49     /** Key for the filter used for TIFF images */
50     public static final String JavaDoc TIFF_FILTER = "tiff";
51     /** Key for the filter used for fonts */
52     public static final String JavaDoc FONT_FILTER = "font";
53     /** Key for the filter used for metadata */
54     public static final String JavaDoc METADATA_FILTER = "metadata";
55
56     private List JavaDoc filters = new java.util.ArrayList JavaDoc();
57
58     private boolean ignoreASCIIFilters = false;
59     
60     /**
61      * logging instance
62      */

63     protected static Log logger = LogFactory.getLog("org.apache.fop.render");
64     
65     /**
66      * Default constructor.
67      * <p>
68      * The flag for ignoring ASCII filters defaults to false.
69      */

70     public PDFFilterList() {
71         //nop
72
}
73     
74     /**
75      * Use this descriptor if you want to have ASCII filters (such as ASCIIHex
76      * and ASCII85) ignored, for example, when encryption is active.
77      * @param ignoreASCIIFilters true if ASCII filters should be ignored
78      */

79     public PDFFilterList(boolean ignoreASCIIFilters) {
80         this.ignoreASCIIFilters = ignoreASCIIFilters;
81     }
82
83     /**
84      * Indicates whether the filter list is already initialized.
85      * @return true if more there are filters present
86      */

87     public boolean isInitialized() {
88         return this.filters.size() > 0;
89     }
90
91     /**
92      * Add a filter for compression of the stream. Filters are
93      * applied in the order they are added. This should always be a
94      * new instance of the particular filter of choice. The applied
95      * flag in the filter is marked true after it has been applied to the
96      * data.
97      * @param filter filter to add
98      */

99     public void addFilter(PDFFilter filter) {
100         if (filter != null) {
101             if (this.ignoreASCIIFilters && filter.isASCIIFilter()) {
102                 return; //ignore ASCII filter
103
}
104             filters.add(filter);
105         }
106     }
107     
108     /**
109      * Add a filter for compression of the stream by name.
110      * @param filterType name of the filter to add
111      */

112     public void addFilter(String JavaDoc filterType) {
113         if (filterType == null) {
114             return;
115         }
116         if (filterType.equals("flate")) {
117             addFilter(new FlateFilter());
118         } else if (filterType.equals("null")) {
119             addFilter(new NullFilter());
120         } else if (filterType.equals("ascii-85")) {
121             if (this.ignoreASCIIFilters) {
122                 return; //ignore ASCII filter
123
}
124             addFilter(new ASCII85Filter());
125         } else if (filterType.equals("ascii-hex")) {
126             if (this.ignoreASCIIFilters) {
127                 return; //ignore ASCII filter
128
}
129             addFilter(new ASCIIHexFilter());
130         } else if (filterType.equals("")) {
131             return;
132         } else {
133             throw new IllegalArgumentException JavaDoc(
134                 "Unsupported filter type in stream-filter-list: " + filterType);
135         }
136     }
137
138     /**
139      * Checks the filter list for the filter and adds it in the correct
140      * place if necessary.
141      * @param pdfFilter the filter to check / add
142      */

143     public void ensureFilterInPlace(PDFFilter pdfFilter) {
144         if (this.filters.size() == 0) {
145             addFilter(pdfFilter);
146         } else {
147             if (!(this.filters.get(0).equals(pdfFilter))) {
148                 this.filters.add(0, pdfFilter);
149             }
150         }
151     }
152
153     /**
154      * Adds the default filters to this stream.
155      * @param filters Map of filters
156      * @param type which filter list to modify
157      */

158     public void addDefaultFilters(Map JavaDoc filters, String JavaDoc type) {
159         List JavaDoc filterset = null;
160         if (filters != null) {
161             filterset = (List JavaDoc)filters.get(type);
162             if (filterset == null) {
163                 filterset = (List JavaDoc)filters.get(DEFAULT_FILTER);
164             }
165         }
166         if (filterset == null || filterset.size() == 0) {
167             if (METADATA_FILTER.equals(type)) {
168                 //XMP metadata should not be embedded in clear-text
169
addFilter(new NullFilter());
170             } else if (JPEG_FILTER.equals(type)) {
171                 //JPEG is already well compressed
172
addFilter(new NullFilter());
173             } else if (TIFF_FILTER.equals(type)) {
174                 //CCITT-encoded images are already well compressed
175
addFilter(new NullFilter());
176             } else {
177                 // built-in default to flate
178
addFilter(new FlateFilter());
179             }
180         } else {
181             for (int i = 0; i < filterset.size(); i++) {
182                 String JavaDoc v = (String JavaDoc)filterset.get(i);
183                 addFilter(v);
184             }
185         }
186     }
187
188     /**
189      * Apply the filters to the data
190      * in the order given and return the /Filter and /DecodeParms
191      * entries for the stream dictionary. If the filters have already
192      * been applied to the data (either externally, or internally)
193      * then the dictionary entries are built and returned.
194      * @return a String representing the filter list
195      */

196     protected String JavaDoc buildFilterDictEntries() {
197         if (filters != null && filters.size() > 0) {
198             List JavaDoc names = new java.util.ArrayList JavaDoc();
199             List JavaDoc parms = new java.util.ArrayList JavaDoc();
200
201             // run the filters
202
int nonNullParams = 0;
203             for (int count = 0; count < filters.size(); count++) {
204                 PDFFilter filter = (PDFFilter)filters.get(count);
205                 // place the names in our local vector in reverse order
206
if (filter.getName().length() > 0) {
207                     names.add(0, filter.getName());
208                     if (filter.getDecodeParms() != null) {
209                         parms.add(0, filter.getDecodeParms());
210                         nonNullParams++;
211                     } else {
212                         parms.add(0, null);
213                     }
214                 }
215             }
216
217             // now build up the filter entries for the dictionary
218
return buildFilterEntries(names)
219                     + (nonNullParams > 0 ? buildDecodeParms(parms) : "");
220         }
221         return "";
222
223     }
224
225     private String JavaDoc buildFilterEntries(List JavaDoc names) {
226         int filterCount = 0;
227         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(64);
228         for (int i = 0; i < names.size(); i++) {
229             final String JavaDoc name = (String JavaDoc)names.get(i);
230             if (name.length() > 0) {
231                 filterCount++;
232                 sb.append(name);
233                 sb.append(" ");
234             }
235         }
236         if (filterCount > 0) {
237             if (filterCount > 1) {
238                 return "/Filter [ " + sb.toString() + "]";
239             } else {
240                 return "/Filter " + sb.toString();
241             }
242         } else {
243             return "";
244         }
245     }
246
247     private String JavaDoc buildDecodeParms(List JavaDoc parms) {
248         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
249         boolean needParmsEntry = false;
250         sb.append("\n/DecodeParms ");
251
252         if (parms.size() > 1) {
253             sb.append("[ ");
254         }
255         for (int count = 0; count < parms.size(); count++) {
256             String JavaDoc s = (String JavaDoc)parms.get(count);
257             if (s != null) {
258                 sb.append(s);
259                 needParmsEntry = true;
260             } else {
261                 sb.append("null");
262             }
263             sb.append(" ");
264         }
265         if (parms.size() > 1) {
266             sb.append("]");
267         }
268         if (needParmsEntry) {
269             return sb.toString();
270         } else {
271             return "";
272         }
273     }
274
275     
276     /**
277      * Applies all registered filters as necessary. The method returns an
278      * OutputStream which will receive the filtered contents.
279      * @param stream raw data output stream
280      * @return OutputStream filtered output stream
281      * @throws IOException In case of an I/O problem
282      */

283     public OutputStream JavaDoc applyFilters(OutputStream JavaDoc stream) throws IOException JavaDoc {
284         OutputStream JavaDoc out = stream;
285         if (filters != null) {
286             for (int count = filters.size() - 1; count >= 0; count--) {
287                 PDFFilter filter = (PDFFilter)filters.get(count);
288                 out = filter.applyFilter(out);
289             }
290         }
291         return out;
292     }
293
294     /**
295      * Builds a filter map from an Avalon Configuration object.
296      * @param cfg the Configuration object
297      * @return Map the newly built filter map
298      * @throws ConfigurationException if a filter list is defined twice
299      */

300     public static Map JavaDoc buildFilterMapFromConfiguration(Configuration cfg)
301                 throws ConfigurationException {
302         Map JavaDoc filterMap = new java.util.HashMap JavaDoc();
303         Configuration[] filterLists = cfg.getChildren("filterList");
304         for (int i = 0; i < filterLists.length; i++) {
305             Configuration filters = filterLists[i];
306             String JavaDoc type = filters.getAttribute("type", null);
307             Configuration[] filt = filters.getChildren("value");
308             List JavaDoc filterList = new java.util.ArrayList JavaDoc();
309             for (int j = 0; j < filt.length; j++) {
310                 String JavaDoc name = filt[j].getValue();
311                 filterList.add(name);
312             }
313             
314             if (type == null) {
315                 type = PDFFilterList.DEFAULT_FILTER;
316             }
317
318             if (!filterList.isEmpty() && logger.isDebugEnabled()) {
319                 StringBuffer JavaDoc debug = new StringBuffer JavaDoc("Adding PDF filter");
320                 if (filterList.size() != 1) {
321                     debug.append("s");
322                 }
323                 debug.append(" for type ").append(type).append(": ");
324                 for (int j = 0; j < filterList.size(); j++) {
325                     if (j != 0) {
326                         debug.append(", ");
327                     }
328                     debug.append(filterList.get(j));
329                 }
330                 logger.debug(debug.toString());
331             }
332             
333             if (filterMap.get(type) != null) {
334                 throw new ConfigurationException("A filterList of type '"
335                     + type + "' has already been defined");
336             }
337             filterMap.put(type, filterList);
338         }
339         return filterMap;
340     }
341
342 }
343
Popular Tags