KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > apps > rasterizer > SVGConverter


1 /*
2
3    Copyright 2001-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    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 package org.apache.batik.apps.rasterizer;
19
20 import java.awt.Color JavaDoc;
21 import java.awt.geom.Rectangle2D JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileFilter JavaDoc;
24 import java.io.FileNotFoundException JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import org.apache.batik.transcoder.Transcoder;
34 import org.apache.batik.transcoder.TranscoderInput;
35 import org.apache.batik.transcoder.TranscoderOutput;
36 import org.apache.batik.transcoder.image.ImageTranscoder;
37 import org.apache.batik.transcoder.image.JPEGTranscoder;
38 import org.apache.batik.transcoder.image.PNGTranscoder;
39
40 /**
41  * This application can be used to convert SVG images to raster images.
42  * <br />
43  * Possible result raster image formats are PNG, JPEG, TIFF, and PDF.
44  * The Batik Transcoder API is used to execute the conversion. FOP is
45  * needed to be able to transcode to the PDF format<br />
46  *
47  * The source has to be list of files or URL (set by the <tt>setSources</tt>
48  * method). <br />
49  *
50  * The destination can be:<br /><ul>
51  * <li><b>unspecified</b>. In that case, only file sources can be converted and
52  * a file in the same directory as the source will be created.</li>
53  * <li><b>a directory</b>, set by the <tt>setDst</tt> method. In that case,
54  * the output files are created in that destination directory</li>
55  * <li><b>a file</b>. In case there is a <i>single
56  * source</i>, the destination can be a single named file
57  * (set with the <tt>setDst</tt> method.</li>)<br />
58  * </ul>
59  *
60  * <hr />
61  *
62  * There are a number of options which control the way the image is
63  * converted to the destination format:<br /><ul>
64  * <li>destinationType: controls the type of conversion which should be done.
65  * see the {@link DestinationType} documentation.</li>
66  * <li>width/height: they control the desired width and height, in user space,
67  * for the output image.</li>
68  * <li>maxWidth/maxHeight: control the maximum width and height,
69  * in user space, of the output image.</li>
70  * <li>area: controls the specific sub-area of the image which should be
71  * rendered.</li>
72  * <li>backgroundColor: controls the color which is used to fill the
73  * background before rendering the image</li>
74  * <li>quality: relevant only for JPEG destinations, this controls the
75  * encoding quality.</li>
76  * <li>indexed: relevant only for PNG, controls the number of bits
77  * used in writting of a palletized files.</li>
78  * <li>mediaType: controls the CSS media, or list of media, for which the
79  * image should be rendered.</li>
80  * <li>alternate: controls the alternate CSS stylesheet to activate,
81  * if any.</li>
82  * <li>language: controls the user language with which the SVG document
83  * should be converted.</li>
84  * <li>userStylesheet: defines the user stylesheet to apply to SVG documents
85  * in addition to other stylesheets referenced by or embedded in the
86  * SVG documents.</li>
87  * <li>pixelUnitToMillimeter: defines the size of a pixel in millimeters
88  * to use when processing the SVG documents.</li>
89  * </ul>
90  *
91  * @version $Id: SVGConverter.java,v 1.22 2005/03/27 08:58:29 cam Exp $
92  * @author <a HREF="mailto:Henri.Ruini@nokia.com">Henri Ruini</a>
93  * @author <a HREF="mailto:vhardy@apache.org">Vincent Hardy</a>
94  */

95 public class SVGConverter {
96     //
97
// Error codes reported by the SVGConverter
98
//
99

100     //
101
// Reported when no source file has been specified.
102
//
103
public static final String JavaDoc ERROR_NO_SOURCES_SPECIFIED
104         = "SVGConverter.error.no.sources.specified";
105
106     //
107
// Reported when there is more than one valid input source
108
// and no output directory has been set and the source is
109
// not a file.
110
//
111
public static final String JavaDoc ERROR_CANNOT_COMPUTE_DESTINATION
112         = "SVGConverter.error.cannot.compute.destination";
113
114     //
115
// Reported when the dst is a file and there are multiple
116
// sources.
117
//
118
public static final String JavaDoc ERROR_CANNOT_USE_DST_FILE
119         = "SVGConverter.error.cannot.use.dst.file";
120
121     //
122
// Reported when the <tt>Transcoder</tt> for the requested
123
// <tt>destinationType</tt> cannot be found.
124
//
125
public static final String JavaDoc ERROR_CANNOT_ACCESS_TRANSCODER
126         = "SVGConverter.error.cannot.access.transcoder";
127
128     //
129
// Reported when the source is found to be the same as
130
// the destination. Note that it is not guaranteed that
131
// this error condition will always be detected.
132
//
133
public static final String JavaDoc ERROR_SOURCE_SAME_AS_DESTINATION
134         = "SVGConverter.error.source.same.as.destination";
135
136     //
137
// Reported when one of the sources cannot be read.
138
//
139
public static final String JavaDoc ERROR_CANNOT_READ_SOURCE
140         = "SVGConverter.error.cannot.read.source";
141
142     //
143
// Reported when an error happens while opening a source
144
// file.
145
//
146
public static final String JavaDoc ERROR_CANNOT_OPEN_SOURCE
147         = "SVGConverter.error.cannot.open.source";
148
149     //
150
// Reported if the output is not writeable. This may
151
// happen if the output file already exists and does not
152
// have write permission.
153
//
154
public static final String JavaDoc ERROR_OUTPUT_NOT_WRITEABLE
155         = "SVGConverter.error.output.not.writeable";
156
157     //
158
// Reported when an error happens while trying to open
159
// the output file for writing.
160
//
161
public static final String JavaDoc ERROR_CANNOT_OPEN_OUTPUT_FILE
162         = "SVGConverter.error.cannot.open.output.file";
163
164     //
165
// Reported when the converter was not able to create
166
// the destination directory for the files.
167
//
168
public static final String JavaDoc ERROR_UNABLE_TO_CREATE_OUTPUT_DIR
169         = "SVGConverter.error.unable.to.create.output.dir";
170
171     //
172
// Reported when an error occurs while convertion the
173
// source file.
174
//
175
public static final String JavaDoc ERROR_WHILE_RASTERIZING_FILE
176         = "SVGConverter.error.while.rasterizing.file";
177
178     //
179
// Class variables and constants
180
//
181

182     /** SVG file extension */
183     protected static final String JavaDoc SVG_EXTENSION = ".svg";
184
185     /** Default quality value. A value of -1 means disabled. */
186     protected static final float DEFAULT_QUALITY
187         = -1f;
188
189     /** Maximum quality value */
190     protected static final float MAXIMUM_QUALITY
191         = .99F;
192
193     /** Default result type */
194     protected static final DestinationType DEFAULT_RESULT_TYPE
195         = DestinationType.PNG;
196
197     /** Default width */
198     protected static final float DEFAULT_WIDTH = -1;
199
200     /** Default height */
201     protected static final float DEFAULT_HEIGHT = -1;
202
203     /** Result type */
204     protected DestinationType destinationType = DEFAULT_RESULT_TYPE;
205
206     /** Output image height. */
207     protected float height = DEFAULT_HEIGHT;
208
209     /** Output image width. */
210     protected float width = DEFAULT_WIDTH;
211
212     /** Maximum output image height. */
213     protected float maxHeight = DEFAULT_HEIGHT;
214
215     /** Maximum output image width. */
216     protected float maxWidth = DEFAULT_WIDTH;
217
218     /** Output image quality. */
219     protected float quality = DEFAULT_QUALITY;
220
221     /** Should output Image be indexed . */
222     protected int indexed = -1;
223
224     /** Output AOI area. */
225     protected Rectangle2D JavaDoc area = null;
226
227     /** Language */
228     protected String JavaDoc language = null;
229
230     /** User stylesheet */
231     protected String JavaDoc userStylesheet = null;
232
233     /** Millimeters Per Pixel */
234     protected float pixelUnitToMillimeter = -1f;
235
236     /** Validation flag */
237     protected boolean validate = false;
238
239     /** Execute the 'onload' scripts flag */
240     protected boolean executeOnload = false;
241
242     /** Set of allowed script types. */
243     protected String JavaDoc allowedScriptTypes = null;
244
245     /** Controls whether scripts can only have the same origin as
246         the document which references them. */

247     protected boolean constrainScriptOrigin = true;
248
249     /** Controls whether scripts should be run securely or not */
250     protected boolean securityOff = false;
251
252     /** Sources files or URLs */
253     protected Vector JavaDoc sources = null;
254
255     /**
256      * Destination image path. Can be a file (for single source) or
257      * a directory
258      */

259     protected File JavaDoc dst;
260
261     /** Background color for the output images. */
262     protected Color JavaDoc backgroundColor = null;
263
264     /** Media type for which the SVG image should be rendered */
265     protected String JavaDoc mediaType = null;
266
267     /** Default value for the font-family when it is unspecified */
268     protected String JavaDoc defaultFontFamily = null;
269
270     /** Alternate stylesheet for which should be applied to the SVG */
271     protected String JavaDoc alternateStylesheet = null;
272
273     /** Contents of <tt>fileset</tt> elements. */
274     protected Vector JavaDoc files = new Vector JavaDoc();
275
276     /**
277      * Controls some aspects of the converter's operation,
278      * such as whether or not it should proceed in some
279      * error situations. See {@link SVGConverterController}
280      */

281     protected SVGConverterController controller;
282
283     //
284
// Default constructor
285
//
286
public SVGConverter(){
287         this(new DefaultSVGConverterController());
288     }
289
290     //
291
// Constructor
292
//
293
public SVGConverter(SVGConverterController controller){
294         if (controller == null){
295             throw new IllegalArgumentException JavaDoc();
296         }
297
298         this.controller = controller;
299     }
300
301     //
302
// Property get/set methods
303
//
304

305     /**
306      * Sets the <tt>destinationType</tt> attribute value.
307      * Should not be null.
308      */

309     public void setDestinationType(DestinationType destinationType) {
310         if(destinationType == null){
311             throw new IllegalArgumentException JavaDoc();
312         }
313         this.destinationType = destinationType;
314     }
315
316     public DestinationType getDestinationType(){
317         return destinationType;
318     }
319
320     /**
321      * In less than or equal to zero, the height is not
322      * constrained on the output image. The height is in
323      * user space.
324      */

325     public void setHeight(float height) {
326         this.height = height;
327     }
328
329     public float getHeight(){
330         return height;
331     }
332
333     /**
334      * In less than or equal to zero, the width is not
335      * constrained on the output image. The width is in
336      * user space.
337      */

338     public void setWidth(float width) {
339         this.width = width;
340     }
341
342     public float getWidth(){
343         return width;
344     }
345
346     /**
347      * If less than or equal to zero, the maximum height
348      * does not have any effect on the output image.
349      * The maximum height is in user space.
350      */

351     public void setMaxHeight(float height) {
352         this.maxHeight = height;
353     }
354
355     public float getMaxHeight(){
356         return maxHeight;
357     }
358
359     /**
360      * If less than or equal to zero, the maximum width
361      * does not have any effect on the output image.
362      * The maximum width is in user space.
363      */

364     public void setMaxWidth(float width) {
365         this.maxWidth = width;
366     }
367
368     public float getMaxWidth(){
369         return maxWidth;
370     }
371
372     /**
373      * Sets the JPEG encoding quality. The value should be strictly
374      * less than 1. If the value is less than zero, then the maximum
375      * encoding quality is used.
376      */

377     public void setQuality(float quality) throws IllegalArgumentException JavaDoc {
378         if(quality >= 1){
379             throw new IllegalArgumentException JavaDoc();
380         }
381
382         this.quality = quality;
383     }
384
385     public float getQuality(){
386         return quality;
387     }
388
389     /**
390      * Tells the PNG encoder to reduce the image to 256 colors, so the
391      * PNG file is indexed.
392      */

393     public void setIndexed(int bits) throws IllegalArgumentException JavaDoc {
394         this.indexed = bits;
395     }
396
397     public int getIndexed(){
398         return indexed;
399     }
400
401     /**
402      * Sets the user language. If the value is null, then the default (see
403      * {@link org.apache.batik.bridge.UserAgent#getLanguages})
404      * is used.
405      */

406     public void setLanguage(String JavaDoc language){
407         this.language = language;
408     }
409
410     public String JavaDoc getLanguage(){
411         return language;
412     }
413
414     /**
415      * Sets the user stylesheet. May be null.
416      */

417     public void setUserStylesheet(String JavaDoc userStylesheet){
418         this.userStylesheet = userStylesheet;
419     }
420
421     public String JavaDoc getUserStylesheet(){
422         return userStylesheet;
423     }
424
425     /**
426      * Sets the millimeters per pixel constant. A negative
427      * value will cause the default value
428      * (see {@link org.apache.batik.bridge.UserAgent#getPixelUnitToMillimeter})
429      * to be used.
430      */

431     public void setPixelUnitToMillimeter(float pixelUnitToMillimeter){
432         this.pixelUnitToMillimeter = pixelUnitToMillimeter;
433     }
434
435     public float getPixelUnitToMillimeter(){
436         return pixelUnitToMillimeter;
437     }
438
439     /**
440      * Sets the <tt>area</tt> as a Rectangle. This value can
441      * be null in which case the whole image will be rendered. If the
442      * area is not null, then only the portion of the image it
443      * defines will be rendered.
444      */

445     public void setArea(Rectangle2D JavaDoc area){
446         this.area = area;
447     }
448
449     public Rectangle2D JavaDoc getArea(){
450         return area;
451     }
452
453     /**
454      * Sets the list of individual SVG sources. The strings
455      * can be either URLs or file names. Note that invalid
456      * sources (e.g., read-protected files or invalid URLs)
457      * will cause <tt>SVGConverterExceptions</tt> to be
458      * thrown during the transcoding process (see {@link #execute});
459      */

460     public void setSources(String JavaDoc[] sources) {
461         if(sources == null){
462             this.sources = null;
463         }
464         else{
465             this.sources = new Vector JavaDoc();
466             for (int i=0; i<sources.length; i++){
467                 if (sources[i] != null){
468                     this.sources.addElement(sources[i]);
469                 }
470             }
471
472             if (this.sources.size() == 0){
473                 this.sources = null;
474             }
475         }
476     }
477
478     public Vector JavaDoc getSources(){
479         return sources;
480     }
481
482     /**
483      * When converting a single source, dst can be a file.
484      * Othewise, it should be a directory.
485      */

486     public void setDst(File JavaDoc dst) {
487         this.dst = dst;
488     }
489
490     public File JavaDoc getDst(){
491         return dst;
492     }
493
494     /**
495      * Sets the <tt>backgroundColor</tt> value. This can be
496      * null in which case no color will be used to fill the
497      * background before rendering this SVG image.
498      */

499     public void setBackgroundColor(Color JavaDoc backgroundColor){
500         this.backgroundColor = backgroundColor;
501     }
502
503     public Color JavaDoc getBackgroundColor(){
504         return backgroundColor;
505     }
506
507     /**
508      * Sets the <tt>mediaType</tt> value. This value controls
509      * the CSS media for which the image should be rendered. It
510      * can be null, in which case no specific media selectors will
511      * apply. If it is not null, it can contain space separated values
512      * of the medias for which the image should be rendered. For example,
513      * "screen", "print" or "scree projection" are valid values.
514      */

515     public void setMediaType(String JavaDoc mediaType){
516         this.mediaType = mediaType;
517     }
518
519     public String JavaDoc getMediaType(){
520         return mediaType;
521     }
522
523     /**
524      * Sets the <tt>defaultFontFamily</tt> value. This value controls
525      * the default value for the font-family CSS property when that
526      * property is unspecified.
527      */

528     public void setDefaultFontFamily(String JavaDoc defaultFontFamily) {
529         this.defaultFontFamily = defaultFontFamily;
530     }
531
532     public String JavaDoc getDefaultFontFamily() {
533         return defaultFontFamily;
534     }
535
536     /**
537      * Sets the <tt>alternateStyleSheet</tt> value. This value
538      * controls the CSS alternate stylesheet to select in the
539      * rendered SVG file(s). It may be null, in which case no alternate
540      * stylesheet will be selected.
541      */

542     public void setAlternateStylesheet(String JavaDoc alternateStylesheet){
543         this.alternateStylesheet = alternateStylesheet;
544     }
545
546     public String JavaDoc getAlternateStylesheet(){
547         return alternateStylesheet;
548     }
549
550     /**
551      * Defines whether or not input sources should be validated in
552      * the conversion process
553      */

554     public void setValidate(boolean validate){
555         this.validate = validate;
556     }
557
558     public boolean getValidate(){
559         return validate;
560     }
561
562     /**
563      * Sets whether or not scripts attached to the DOM using 'onload'
564      * event attribute must be executed before rasterizing.
565      *
566      * @param b true means scripts will be executed
567      */

568     public void setExecuteOnload(boolean b){
569         this.executeOnload = b;
570     }
571
572     /**
573      * Returns true if the scripts attached to the DOM using 'onload'
574      * event attribute is going to be executed before rasterizing,
575      * false otherwise.
576      */

577     public boolean getExecuteOnload(){
578         return executeOnload;
579     }
580     
581     /**
582      * Sets the set of allowed script types (i.e., the set of possible
583      * values for the type attribute in the &lt;script&gt; element),
584      * as a comma separated list of allowed values.
585      */

586     public void setAllowedScriptTypes(String JavaDoc allowedScriptTypes){
587         this.allowedScriptTypes = allowedScriptTypes;
588     }
589
590     /**
591      * Returns the list of allowed script types.
592      *
593      * @see #setAllowedScriptTypes
594      */

595     public String JavaDoc getAllowedScriptTypes(){
596         return allowedScriptTypes;
597     }
598
599     /**
600      * Sets whether scripts should only be loaded from the same
601      * location as the documents referencing them.
602      */

603     public void setConstrainScriptOrigin(boolean constrainScriptOrigin){
604         this.constrainScriptOrigin = constrainScriptOrigin;
605     }
606
607     /**
608      * Returns whether scripts can only be loaded from the same
609      * origin as the documents referencing them.
610      */

611     public boolean getConstrainScriptOrigin(){
612         return constrainScriptOrigin;
613     }
614
615     /**
616      * Sets whether or not scripts should be run securely
617      */

618     public void setSecurityOff(boolean securityOff){
619         this.securityOff = securityOff;
620     }
621
622     /**
623      * Returns whether or not scripts will be run securely
624      */

625     public boolean getSecurityOff(){
626         return securityOff;
627     }
628
629     /**
630      * Returns true if f is a File. <code>f</code> is found to be a file if
631      * it exists and is a file. If it does not exist, it is declared
632      * to be a file if it has the same extension as the DestinationType.
633      */

634     protected boolean isFile(File JavaDoc f){
635         if (f.exists()){
636             return f.isFile();
637         } else {
638             if (f.toString().toLowerCase().endsWith(destinationType.getExtension())){
639                 return true;
640             }
641         }
642
643         return false;
644     }
645
646     /**
647      * Starts the conversion process.
648      * @throws SVGConverterException thrown if parameters are not set correctly.
649      */

650     public void execute() throws SVGConverterException {
651         // Compute the set of SVGConverterSource from the source properties
652
// (srcDir and srcFile);
653
// This throws an exception if there is not at least one src file.
654
Vector JavaDoc sources = computeSources();
655
656         // Compute the destination files from dest
657
Vector JavaDoc dstFiles = null;
658         if(sources.size() == 1 && dst != null && isFile(dst)){
659             dstFiles = new Vector JavaDoc();
660             dstFiles.addElement(dst);
661         }
662         else{
663             dstFiles = computeDstFiles(sources);
664         }
665
666         // Now, get the transcoder to use for the operation
667
Transcoder transcoder = destinationType.getTranscoder();
668         if(transcoder == null) {
669             throw new SVGConverterException(ERROR_CANNOT_ACCESS_TRANSCODER,
670                                              new Object JavaDoc[]{destinationType.toString()},
671                                              true /* fatal error */);
672         }
673
674         // Now, compute the set of transcoding hints to use
675
Map JavaDoc hints = computeTranscodingHints();
676         transcoder.setTranscodingHints(hints);
677
678         // Notify listener that task has been computed
679
if(!controller.proceedWithComputedTask(transcoder,
680                                                hints,
681                                                sources,
682                                                dstFiles)){
683             return;
684         }
685
686         // Convert files one by one
687
for(int i = 0 ; i < sources.size() ; i++) {
688             // Get the file from the vector.
689
SVGConverterSource currentFile
690                 = (SVGConverterSource)sources.elementAt(i);
691             File JavaDoc outputFile = (File JavaDoc)dstFiles.elementAt(i);
692
693             createOutputDir(outputFile);
694             transcode(currentFile, outputFile, transcoder);
695         }
696     }
697     
698     /**
699      * Populates a vector with destination files names
700      * computed from the names of the files in the sources vector
701      * and the value of the dst property
702      */

703     protected Vector JavaDoc computeDstFiles(Vector JavaDoc sources)
704     throws SVGConverterException {
705         Vector JavaDoc dstFiles = new Vector JavaDoc();
706         if (dst != null) {
707             if (dst.exists() && dst.isFile()) {
708                 throw new SVGConverterException(ERROR_CANNOT_USE_DST_FILE);
709             }
710
711             //
712
// Either dst exist and is a directory or dst does not
713
// exist and we may fail later on in createOutputDir
714
//
715
int n = sources.size();
716             for(int i=0; i<n; i++){
717                 SVGConverterSource src = (SVGConverterSource)sources.elementAt(i);
718                 // Generate output filename from input filename.
719
File JavaDoc outputName = new File JavaDoc(dst.getPath(),
720                                            getDestinationFile(src.getName()));
721                 dstFiles.addElement(outputName);
722                 
723             }
724         } else {
725             //
726
// No destination directory has been specified.
727
// Try and create files in the same directory as the
728
// sources. This only work if sources are files.
729
//
730
int n = sources.size();
731             for(int i=0; i<n; i++){
732                 SVGConverterSource src = (SVGConverterSource)sources.elementAt(i);
733                 if (!(src instanceof SVGConverterFileSource)) {
734                     throw new SVGConverterException(ERROR_CANNOT_COMPUTE_DESTINATION,
735                                                      new Object JavaDoc[]{src});
736                 }
737
738                 // Generate output filename from input filename.
739
SVGConverterFileSource fs = (SVGConverterFileSource)src;
740                 File JavaDoc outputName = new File JavaDoc(fs.getFile().getParent(),
741                                            getDestinationFile(src.getName()));
742                 dstFiles.addElement(outputName);
743             }
744             
745         }
746
747         return dstFiles;
748     }
749
750     /**
751      * Populates a vector with the set of SVG files from the
752      * srcDir if it is not null and with the sources (files or URLs)
753      * if any.
754      */

755     protected Vector JavaDoc computeSources() throws SVGConverterException{
756         Vector JavaDoc sources = new Vector JavaDoc();
757
758         // Check that at least one source has been specified.
759
if (this.sources == null){
760             throw new SVGConverterException(ERROR_NO_SOURCES_SPECIFIED);
761         }
762
763         int n = this.sources.size();
764         for (int i=0; i<n; i++){
765             String JavaDoc sourceString = (String JavaDoc)(this.sources.elementAt(i));
766             File JavaDoc file = new File JavaDoc(sourceString);
767             if (file.exists()) {
768                 sources.addElement(new SVGConverterFileSource(file));
769             } else {
770                 String JavaDoc[] fileNRef = getFileNRef(sourceString);
771                 file = new File JavaDoc(fileNRef[0]);
772                 if (file.exists()){
773                     sources.addElement(new SVGConverterFileSource(file, fileNRef[1]));
774                 } else{
775                     sources.addElement(new SVGConverterURLSource(sourceString));
776                 }
777             }
778         }
779         
780         return sources;
781     }
782
783     public String JavaDoc[] getFileNRef(String JavaDoc fileName){
784         int n = fileName.lastIndexOf("#");
785         String JavaDoc[] result = {fileName, ""};
786         if (n > -1){
787             result[0] = fileName.substring(0, n);
788             if (n+1 < fileName.length()){
789                 result[1] = fileName.substring(n+1);
790             }
791         }
792
793         return result;
794     }
795
796     // -----------------------------------------------------------------------
797
// Internal methods
798
// -----------------------------------------------------------------------
799

800     /**
801      * Computes the set of transcoding hints to use for the operation
802      */

803     protected Map JavaDoc computeTranscodingHints(){
804         HashMap JavaDoc map = new HashMap JavaDoc();
805
806         // Set AOI. ----------------------------------------------------------
807
if (area != null) {
808             map.put(ImageTranscoder.KEY_AOI, area);
809         }
810
811         // Set image quality. ------------------------------------------------
812
if (quality > 0) {
813             map.put(JPEGTranscoder.KEY_QUALITY, new Float JavaDoc(this.quality));
814         }
815
816         // Set image indexed. ------------------------------------------------
817
if (indexed != -1) {
818             map.put(PNGTranscoder.KEY_INDEXED, new Integer JavaDoc(indexed));
819         }
820
821         // Set image background color -----------------------------------------
822
if (backgroundColor != null){
823             map.put(ImageTranscoder.KEY_BACKGROUND_COLOR, backgroundColor);
824         }
825
826         // Set image height and width. ----------------------------------------
827
if (height > 0) {
828             map.put(ImageTranscoder.KEY_HEIGHT, new Float JavaDoc(this.height));
829         }
830         if (width > 0){
831             map.put(ImageTranscoder.KEY_WIDTH, new Float JavaDoc(this.width));
832         }
833
834         // Set maximum height and width ---------------------------------------
835
if (maxHeight > 0) {
836             map.put(ImageTranscoder.KEY_MAX_HEIGHT, new Float JavaDoc(this.maxHeight));
837         }
838         if (maxWidth > 0){
839             map.put(ImageTranscoder.KEY_MAX_WIDTH, new Float JavaDoc(this.maxWidth));
840         }
841
842         // Set CSS Media
843
if (mediaType != null){
844             map.put(ImageTranscoder.KEY_MEDIA, mediaType);
845         }
846
847         // Set default font-family
848
if (defaultFontFamily != null) {
849             map.put(ImageTranscoder.KEY_DEFAULT_FONT_FAMILY, defaultFontFamily);
850         }
851
852         // Set alternateStylesheet
853
if (alternateStylesheet != null){
854             map.put(ImageTranscoder.KEY_ALTERNATE_STYLESHEET, alternateStylesheet);
855         }
856
857         // Set user stylesheet
858
if (userStylesheet != null){
859             map.put(ImageTranscoder.KEY_USER_STYLESHEET_URI, userStylesheet);
860         }
861
862         // Set the user language
863
if (language != null){
864             map.put(ImageTranscoder.KEY_LANGUAGE, language);
865         }
866
867         // Sets the millimeters per pixel
868
if (pixelUnitToMillimeter > 0){
869             map.put(ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER,
870                     new Float JavaDoc(pixelUnitToMillimeter));
871         }
872
873         // Set validation
874
if (validate){
875             map.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING,
876                     new Boolean JavaDoc(validate));
877         }
878
879         // Set onload
880
if (executeOnload) {
881             map.put(ImageTranscoder.KEY_EXECUTE_ONLOAD, new Boolean JavaDoc(executeOnload));
882         }
883         
884         // Set allowed scripts
885
if (allowedScriptTypes != null) {
886             map.put(ImageTranscoder.KEY_ALLOWED_SCRIPT_TYPES, allowedScriptTypes);
887         }
888
889         // Set constrain script origin
890
if (!constrainScriptOrigin) {
891             map.put(ImageTranscoder.KEY_CONSTRAIN_SCRIPT_ORIGIN,
892                     new Boolean JavaDoc(constrainScriptOrigin));
893         }
894
895         return map;
896     }
897
898     /**
899      * Converts the input image to the result image.
900      * with the given transcoder. If a failure happens, the
901      * controller is notified and decides whether to proceed
902      * or not. If it decides to proceed, the converter will
903      * continue processing other files. Otherwise, it will
904      * throw an exception.
905      */

906     protected void transcode(SVGConverterSource inputFile,
907                              File JavaDoc outputFile,
908                              Transcoder transcoder)
909         throws SVGConverterException {
910         TranscoderInput input = null;
911         TranscoderOutput output = null;
912         OutputStream JavaDoc outputStream = null;
913
914         if (!controller.proceedWithSourceTranscoding(inputFile,
915                                                      outputFile)){
916             return;
917         }
918
919         try {
920             if (inputFile.isSameAs(outputFile.getPath())) {
921                 throw new SVGConverterException(ERROR_SOURCE_SAME_AS_DESTINATION,
922                                                  true /* fatal error */);
923             }
924             
925             // Compute transcoder input.
926
if (!inputFile.isReadable()) {
927                 throw new SVGConverterException(ERROR_CANNOT_READ_SOURCE,
928                                                  new Object JavaDoc[]{inputFile.getName()});
929             }
930
931             try {
932                 InputStream JavaDoc in = inputFile.openStream();
933                 in.close();
934             } catch(IOException JavaDoc ioe) {
935                 throw new SVGConverterException(ERROR_CANNOT_OPEN_SOURCE,
936                                                  new Object JavaDoc[] {inputFile.getName(),
937                                                                ioe.toString()});
938                                                                }
939             
940             input = new TranscoderInput(inputFile.getURI());
941
942             // Compute transcoder output.
943
if (!isWriteable(outputFile)) {
944                 throw new SVGConverterException(ERROR_OUTPUT_NOT_WRITEABLE,
945                                                  new Object JavaDoc[] {outputFile.getName()});
946             }
947             try {
948                 outputStream = new FileOutputStream JavaDoc(outputFile);
949             } catch(FileNotFoundException JavaDoc fnfe) {
950                 throw new SVGConverterException(ERROR_CANNOT_OPEN_OUTPUT_FILE,
951                                                  new Object JavaDoc[] {outputFile.getName()});
952             }
953             
954             output = new TranscoderOutput(outputStream);
955         } catch(SVGConverterException e){
956             boolean proceed = controller.proceedOnSourceTranscodingFailure
957                 (inputFile, outputFile, e.getErrorCode());
958             if (proceed){
959                 return;
960             } else {
961                 throw e;
962             }
963         }
964
965         // Transcode now
966
boolean success = false;
967         try {
968             transcoder.transcode(input, output);
969             success = true;
970         } catch(Exception JavaDoc te) {
971             te.printStackTrace();
972             try {
973                 outputStream.flush();
974                 outputStream.close();
975             } catch(IOException JavaDoc ioe) {}
976             
977             // Report error to the controller. If controller decides
978
// to stop, throw an exception
979
boolean proceed = controller.proceedOnSourceTranscodingFailure
980                 (inputFile, outputFile, ERROR_WHILE_RASTERIZING_FILE);
981
982             if (!proceed){
983                 throw new SVGConverterException(ERROR_WHILE_RASTERIZING_FILE,
984                                                  new Object JavaDoc[] {outputFile.getName(),
985                                                                te.getMessage()});
986             }
987         }
988
989         // Close streams and clean up.
990
try {
991             outputStream.flush();
992             outputStream.close();
993         } catch(IOException JavaDoc ioe) {
994             return;
995         }
996
997         if (success){
998             controller.onSourceTranscodingSuccess(inputFile, outputFile);
999         }
1000    }
1001
1002    /**
1003     * Get the name of the result image file.
1004     *
1005     * <P>This method modifies the result filename, it changes the existing
1006     * suffix to correspong the result file type. It also adds the suffix
1007     * if the file doesn't have one.</P>
1008     *
1009     * @param file Result file name as a String object.
1010     *
1011     * @return Name of the file. The directory of the file is not returned.
1012     * The returned string is empty if the parameter is not a file.
1013     */

1014    protected String JavaDoc getDestinationFile(String JavaDoc file) {
1015        int suffixStart; // Location of the first char of
1016
// the suffix in a String.
1017
String JavaDoc oldName; // Existing filename.
1018
String JavaDoc newSuffix = destinationType.getExtension();
1019                                    // New suffix.
1020

1021        oldName = file;
1022        // Find the first char of the suffix.
1023
suffixStart = oldName.lastIndexOf(".");
1024        String JavaDoc dest = null;
1025        if (suffixStart != -1) {
1026            // Replace existing suffix.
1027
dest = new String JavaDoc(oldName.substring(0, suffixStart) + newSuffix);
1028        } else {
1029            // Add new suffix.
1030
dest = new String JavaDoc(oldName + newSuffix);
1031        }
1032
1033        return dest;
1034    }
1035
1036    /**
1037     * Creates directories for output files if needed.
1038     *
1039     * @param output Output file with path.
1040     *
1041     * @throws SVGConverterException Output directory doesn't exist and it can't be created.
1042     */

1043    protected void createOutputDir(File JavaDoc output)
1044        throws SVGConverterException {
1045
1046        File JavaDoc outputDir; // Output directory object.
1047
boolean success = true; // false if the output directory
1048
// doesn't exist and it can't be created
1049
// true otherwise
1050

1051
1052        // Create object from output directory.
1053
String JavaDoc parentDir = output.getParent();
1054        if (parentDir != null){
1055            outputDir = new File JavaDoc(output.getParent());
1056            if (outputDir.exists() == false) {
1057                // Output directory doesn't exist, so create it.
1058
success = outputDir.mkdirs();
1059            } else {
1060                if (outputDir.isDirectory() == false) {
1061                    // File, which have a same name as the output directory, exists.
1062
// Create output directory.
1063
success = outputDir.mkdirs();
1064                }
1065            }
1066        }
1067
1068        if (!success) {
1069            throw new SVGConverterException(ERROR_UNABLE_TO_CREATE_OUTPUT_DIR);
1070        }
1071    }
1072
1073    /**
1074     * Checks if the application is allowed to write to the file.
1075     *
1076     * @param file File to be checked.
1077     *
1078     * @return <tt>true</tt> if the file is writeable and <tt>false</tt> otherwise.
1079     */

1080    protected boolean isWriteable(File JavaDoc file) {
1081        if (file.exists()) {
1082            // Check the existing file.
1083
if (!file.canWrite()) {
1084                return false;
1085            }
1086        } else {
1087            // Check the file that doesn't exist yet.
1088
// Create a new file. The file is writeable if
1089
// the creation succeeds.
1090
try {
1091                file.createNewFile();
1092            } catch(IOException JavaDoc ioe) {
1093                return false;
1094            }
1095        }
1096        return true;
1097    }
1098
1099    // -----------------------------------------------------------------------
1100
// Inner classes
1101
// -----------------------------------------------------------------------
1102

1103    /**
1104     * Convenience class to filter svg files
1105     */

1106    public static class SVGFileFilter implements FileFilter JavaDoc {
1107        public static final String JavaDoc SVG_EXTENSION = ".svg";
1108        
1109        public boolean accept(File JavaDoc file){
1110            if (file != null && file.getName().toLowerCase().endsWith(SVG_EXTENSION)){
1111                return true;
1112            }
1113            
1114            return false;
1115        }
1116    }
1117
1118}
1119
1120
Popular Tags