KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > krysalis > barcode > cli > Main


1 /*
2  * $Id: Main.java,v 1.10 2003/10/29 07:50:26 jmaerki Exp $
3  * ============================================================================
4  * The Krysalis Patchy Software License, Version 1.1_01
5  * Copyright (c) 2002-2003 Nicola Ken Barozzi. All rights reserved.
6  *
7  * This Licence is compatible with the BSD licence as described and
8  * approved by http://www.opensource.org/, and is based on the
9  * Apache Software Licence Version 1.1.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution,
24  * if any, must include the following acknowledgment:
25  * "This product includes software developed for project
26  * Krysalis (http://www.krysalis.org/)."
27  * Alternately, this acknowledgment may appear in the software itself,
28  * if and wherever such third-party acknowledgments normally appear.
29  *
30  * 4. The names "Krysalis" and "Nicola Ken Barozzi" and
31  * "Krysalis Barcode" must not be used to endorse or promote products
32  * derived from this software without prior written permission. For
33  * written permission, please contact nicolaken@krysalis.org.
34  *
35  * 5. Products derived from this software may not be called "Krysalis",
36  * "Krysalis Barcode", nor may "Krysalis" appear in their name,
37  * without prior written permission of Nicola Ken Barozzi.
38  *
39  * 6. This software may contain voluntary contributions made by many
40  * individuals, who decided to donate the code to this project in
41  * respect of this licence, and was originally created by
42  * Jeremias Maerki <jeremias@maerki.org>.
43  *
44  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
45  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47  * DISCLAIMED. IN NO EVENT SHALL THE KRYSALIS PROJECT OR
48  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
51  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  * SUCH DAMAGE.
56  * ====================================================================
57  */

58 package org.krysalis.barcode.cli;
59
60 import java.awt.image.BufferedImage JavaDoc;
61 import java.io.File JavaDoc;
62 import java.io.FileNotFoundException JavaDoc;
63 import java.io.IOException JavaDoc;
64 import java.io.OutputStream JavaDoc;
65 import java.io.PrintStream JavaDoc;
66 import java.io.PrintWriter JavaDoc;
67 import java.util.Set JavaDoc;
68
69 import javax.xml.transform.Result JavaDoc;
70 import javax.xml.transform.Source JavaDoc;
71 import javax.xml.transform.Transformer JavaDoc;
72 import javax.xml.transform.TransformerException JavaDoc;
73 import javax.xml.transform.TransformerFactory JavaDoc;
74
75 import org.krysalis.barcode.BarcodeException;
76 import org.krysalis.barcode.BarcodeGenerator;
77 import org.krysalis.barcode.BarcodeUtil;
78 import org.krysalis.barcode.output.bitmap.BitmapCanvasProvider;
79 import org.krysalis.barcode.output.bitmap.BitmapEncoderRegistry;
80 import org.krysalis.barcode.output.eps.EPSCanvasProvider;
81 import org.krysalis.barcode.output.svg.SVGCanvasProvider;
82 import org.krysalis.barcode.tools.MimeTypes;
83
84 import org.apache.avalon.framework.configuration.Configuration;
85 import org.apache.avalon.framework.configuration.DefaultConfiguration;
86 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
87 import org.apache.avalon.framework.logger.Logger;
88 import org.apache.commons.cli.CommandLine;
89 import org.apache.commons.cli.CommandLineParser;
90 import org.apache.commons.cli.HelpFormatter;
91 import org.apache.commons.cli.MissingOptionException;
92 import org.apache.commons.cli.Option;
93 import org.apache.commons.cli.OptionBuilder;
94 import org.apache.commons.cli.OptionGroup;
95 import org.apache.commons.cli.Options;
96 import org.apache.commons.cli.ParseException;
97 import org.apache.commons.cli.PosixParser;
98
99 /**
100  * Command-line interface.
101  *
102  * @author Jeremias Maerki
103  */

104 public class Main {
105
106     private static final String JavaDoc[] APP_HEADER = {
107         "Krysalis Barcode command-line application, Version 1.0beta",
108         "Copyright (c) 2000-2003 "
109                 + "The Krysalis Community Project. All rights reserved.",
110         ""};
111
112     /** stdout for this application (default: System.out) */
113     public static PrintStream JavaDoc stdout = System.out;
114     /** stderr for this application (default: System.err) */
115     public static PrintStream JavaDoc stderr = System.err;
116     
117     private static ExitHandler exitHandler = new DefaultExitHandler();
118     private Options options;
119     private boolean headerPrinted = false;
120     private Logger log;
121
122     /**
123      * Main method.
124      * @param args commandline arguments
125      */

126     public static void main(String JavaDoc[] args) {
127         Main app = new Main();
128         app.handleCommandLine(args);
129         /*
130         try {
131             app.handleCommandLine(args);
132         } catch (Exception e) {
133             exitHandler.failureExit(app, "Unhandled exception", e, -1);
134         }*/

135     }
136     
137     /**
138      * Set an alternative exit handler here.
139      * @param handler the alternative exit handler
140      */

141     public static void setExitHandler(ExitHandler handler) {
142         exitHandler = handler;
143     }
144     
145     /**
146      * Handles the command line. The method calls the exit handler upon
147      * completion.
148      * @param args the command line arguments
149      */

150     public void handleCommandLine(String JavaDoc[] args) {
151         CommandLine cl;
152         String JavaDoc[] msg;
153         try {
154             CommandLineParser clp = new PosixParser();
155             cl = clp.parse(getOptions(), args);
156             
157             //Message
158
msg = cl.getArgs();
159             if (msg.length == 0) {
160                 throw new ParseException("No message");
161             }
162             if (msg.length > 1) {
163                 throw new ParseException("Too many parameters: " + msg.length);
164             }
165         } catch (MissingOptionException moe) {
166             printHelp(new PrintWriter JavaDoc(stdout));
167             exitHandler.failureExit(this,
168                 "Bad command line. Missing option: " + moe.getMessage(), null, -2);
169             return; //never reached
170
} catch (ParseException pe) {
171             printHelp(new PrintWriter JavaDoc(stdout));
172             //pe.printStackTrace();
173
exitHandler.failureExit(this,
174                 "Bad command line: " + pe.getMessage(), null, -2);
175             return; //never reached
176
}
177         try {
178             OutputStream JavaDoc out;
179             if (!cl.hasOption("o")) {
180                 log = new AdvancedConsoleLogger(AdvancedConsoleLogger.LEVEL_ERROR,
181                     false, stderr, stderr);
182                 printAppHeader();
183                 out = stdout;
184             } else {
185                 int logLevel = AdvancedConsoleLogger.LEVEL_INFO;
186                 if (cl.hasOption('v')) {
187                     logLevel = AdvancedConsoleLogger.LEVEL_DEBUG;
188                 }
189                 log = new AdvancedConsoleLogger(logLevel, false, stdout, stderr);
190                 printAppHeader();
191                 File JavaDoc outFile = new File JavaDoc(cl.getOptionValue("o"));
192                 if (log.isDebugEnabled()) {
193                     log.debug("Output to: " + outFile.getCanonicalPath());
194                 }
195                 out = new java.io.FileOutputStream JavaDoc(outFile);
196             }
197             
198             log.debug("Message: " + msg[0]);
199             
200             //Output format
201
String JavaDoc format = MimeTypes.expandFormat(
202                     cl.getOptionValue("f", MimeTypes.MIME_SVG));
203             log.info("Generating " + format + "...");
204             BarcodeUtil util = BarcodeUtil.getInstance();
205             BarcodeGenerator gen = util.createBarcodeGenerator(
206                     getConfiguration(cl), log);
207             
208             if (MimeTypes.MIME_SVG.equals(format)) {
209                 //Create Barcode and render it to SVG
210
SVGCanvasProvider svg = new SVGCanvasProvider(false);
211                 gen.generateBarcode(svg, msg[0]);
212     
213                 //Serialize SVG barcode
214
try {
215                     TransformerFactory JavaDoc factory = TransformerFactory.newInstance();
216                     Transformer JavaDoc trans = factory.newTransformer();
217                     Source JavaDoc src = new javax.xml.transform.dom.DOMSource JavaDoc(
218                         svg.getDOMFragment());
219                     Result JavaDoc res = new javax.xml.transform.stream.StreamResult JavaDoc(out);
220                     trans.transform(src, res);
221                 } catch (TransformerException JavaDoc te) {
222                     exitHandler.failureExit(this, "XML/XSLT library error", te, -6);
223                 }
224             } else if (MimeTypes.MIME_EPS.equals(format)) {
225                 EPSCanvasProvider eps = new EPSCanvasProvider(out);
226                 gen.generateBarcode(eps, msg[0]);
227                 eps.finish();
228             } else {
229                 int dpi = Integer.parseInt(cl.getOptionValue('d', "300"));
230                 log.debug("Resolution: " + dpi + "dpi");
231                 BitmapCanvasProvider bitmap;
232                 if (cl.hasOption("bw")) {
233                     log.debug("Black/white image (1-bit)");
234                     bitmap = new BitmapCanvasProvider(out,
235                         format, dpi, BufferedImage.TYPE_BYTE_BINARY, false);
236                 } else {
237                     log.debug("Grayscale image (8-bit) with anti-aliasing");
238                     bitmap = new BitmapCanvasProvider(out,
239                         format, dpi, BufferedImage.TYPE_BYTE_GRAY, true);
240                 }
241                 gen.generateBarcode(bitmap, msg[0]);
242                 bitmap.finish();
243             }
244             
245             out.close();
246             log.info("done.");
247             exitHandler.successfulExit(this);
248         } catch (IOException JavaDoc ioe) {
249             exitHandler.failureExit(this,
250                 "Error writing output file: " + ioe.getMessage(), null, -5);
251         } catch (BarcodeException be) {
252             exitHandler.failureExit(this,
253                 "Error generating the barcode", be, -3);
254         }
255     }
256     
257     private Options getOptions() {
258         if (options == null) {
259             this.options = new Options();
260             Option opt;
261             
262             this.options.addOption(OptionBuilder
263                 .withLongOpt("verbose")
264                 .withDescription("enable debug output")
265                 .create('v'));
266                 
267             //Group: file/stdout
268
this.options.addOption(OptionBuilder
269                 .withLongOpt("output")
270                 .withArgName("file")
271                 .hasArg()
272                 .withDescription("the output filename")
273                 .create('o'));
274             
275             //Group: config file/barcode type
276
OptionGroup group = new OptionGroup();
277             group.setRequired(true);
278             group.addOption(OptionBuilder
279                 .withArgName("file")
280                 .withLongOpt("config")
281                 .hasArg()
282                 .withDescription("the config file")
283                 .create('c'));
284             group.addOption(OptionBuilder
285                 .withArgName("name")
286                 .withLongOpt("symbol")
287                 .hasArg()
288                 .withDescription("the barcode symbology to select "
289                     + "(default settings, use -c if you want to customize)")
290                 .create('s'));
291             this.options.addOptionGroup(group);
292
293             //Output format type
294
this.options.addOption(OptionBuilder
295                 .withArgName("format")
296                 .withLongOpt("format")
297                 .hasArg()
298                 .withDescription("the output format: MIME type or file "
299                     + "extension\n"
300                     + "Default: " + MimeTypes.MIME_SVG + " (SVG)")
301                 .create('f'));
302
303             //Bitmap-specific options
304
this.options.addOption(OptionBuilder
305                 .withArgName("integer")
306                 .withLongOpt("dpi")
307                 .hasArg()
308                 .withDescription("(for bitmaps) the image resolution in dpi\n"
309                     + "Default: 300")
310                 .create('d'));
311             this.options.addOption(OptionBuilder
312                 .withLongOpt("bw")
313                 .withDescription("(for bitmaps) create monochrome (1-bit) "
314                     + "image instead of grayscale (8-bit)")
315                 .create());
316         }
317         return this.options;
318     }
319
320     private Configuration getConfiguration(CommandLine cl) {
321         if (cl.hasOption("s")) {
322             String JavaDoc sym = cl.getOptionValue("s");
323             DefaultConfiguration cfg = new DefaultConfiguration("cfg");
324             DefaultConfiguration child = new DefaultConfiguration(sym);
325             cfg.addChild(child);
326             return cfg;
327         }
328         if (cl.hasOption("c")) {
329             try {
330                 String JavaDoc filename = cl.getOptionValue("c");
331                 File JavaDoc cfgFile = new File JavaDoc(filename);
332                 if (!cfgFile.exists() || !cfgFile.isFile()) {
333                     throw new FileNotFoundException JavaDoc(
334                         "Config file not found: " + cfgFile);
335                 }
336                 log.info("Using configuration: " + cfgFile);
337                 
338                 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
339                 return builder.buildFromFile(cfgFile);
340             } catch (Exception JavaDoc e) {
341                 exitHandler.failureExit(this,
342                     "Error reading configuration file: " + e.getMessage(), null, -3);
343             }
344         }
345         return new DefaultConfiguration("cfg");
346     }
347
348     /**
349      * Prints the application header on the console. Ensures that this is only
350      * done once.
351      */

352     public void printAppHeader() {
353         if (!headerPrinted) {
354             if (log != null) {
355                 for (int i = 0; i < APP_HEADER.length; i++) {
356                     log.info(APP_HEADER[i]);
357                 }
358             } else {
359                 for (int i = 0; i < APP_HEADER.length; i++) {
360                     stdout.println(APP_HEADER[i]);
361                 }
362             }
363             headerPrinted = true;
364         }
365     }
366     
367     private void printHelp(PrintWriter JavaDoc writer) {
368         printAppHeader();
369
370         //Get a list of additional supported MIME types
371
Set JavaDoc knownMimes = new java.util.HashSet JavaDoc();
372         knownMimes.add(null);
373         knownMimes.add("");
374         knownMimes.add(MimeTypes.MIME_PNG);
375         knownMimes.add("image/png");
376         knownMimes.add(MimeTypes.MIME_JPEG);
377         knownMimes.add(MimeTypes.MIME_TIFF);
378         knownMimes.add(MimeTypes.MIME_GIF);
379         Set JavaDoc additionalMimes = BitmapEncoderRegistry.getSupportedMIMETypes();
380         additionalMimes.removeAll(knownMimes);
381
382         HelpFormatter help = new HelpFormatter();
383         final String JavaDoc unavailable = " (unavailable)";
384         help.printHelp(writer, HelpFormatter.DEFAULT_WIDTH,
385             "java -jar krysalis-barcode.jar "
386                 + "[-o <file>] [-t <type>] [-c <cfg-file>] <message>",
387             null,
388             getOptions(),
389             HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD,
390             "Valid output formats:"
391                 + "\nSVG: " + MimeTypes.MIME_SVG + ", svg"
392                 + "\nEPS: " + MimeTypes.MIME_EPS + ", eps"
393                 + "\nPNG: " + MimeTypes.MIME_PNG + ", png"
394                     + (BitmapEncoderRegistry.supports(MimeTypes.MIME_PNG)
395                         ? "" : unavailable)
396                 + "\nTIFF: " + MimeTypes.MIME_TIFF + ", tiff, tif"
397                     + (BitmapEncoderRegistry.supports(MimeTypes.MIME_TIFF)
398                         ? "" : unavailable)
399                 + "\nJPEG: " + MimeTypes.MIME_JPEG + ", jpeg, jpg"
400                     + (BitmapEncoderRegistry.supports(MimeTypes.MIME_JPEG)
401                         ? "" : unavailable)
402                 + "\nGIF: " + MimeTypes.MIME_GIF + ", gif"
403                     + (BitmapEncoderRegistry.supports(MimeTypes.MIME_GIF)
404                         ? "" : unavailable)
405                 + (additionalMimes.size() > 0
406                     ? "\nAdditional supported formats:\n" + additionalMimes
407                     : "")
408                 + "\n"
409                 + "\nIf -o is omitted the output is written to stdout.");
410         writer.flush();
411         
412     }
413
414 }
Popular Tags