View Javadoc
1   package org.jastacry;
2   
3   import java.util.Locale;
4   import java.util.ResourceBundle;
5   
6   import org.apache.commons.cli.CommandLine;
7   import org.apache.commons.cli.CommandLineParser;
8   import org.apache.commons.cli.DefaultParser;
9   import org.apache.commons.cli.HelpFormatter;
10  import org.apache.commons.cli.MissingOptionException;
11  import org.apache.commons.cli.Option;
12  import org.apache.commons.cli.OptionGroup;
13  import org.apache.commons.cli.Options;
14  import org.apache.commons.cli.ParseException;
15  import org.apache.logging.log4j.LogManager;
16  import org.apache.logging.log4j.Logger;
17  import org.jastacry.GlobalData.Action;
18  import org.jastacry.GlobalData.Returncode;
19  
20  import net.sourceforge.cobertura.CoverageIgnore;
21  
22  /**
23   * Main JaStaCry class to start.
24   *
25   * <p>SPDX-License-Identifier: MIT
26   *
27   * @author Kai Kretschmann
28   */
29  public final class JaStaCry
30  {
31      /**
32       * Holder of i18n translations.
33       */
34      private static ResourceBundle bundle;
35  
36      /**
37       * Parameter, short version, for "help".
38       */
39      private static final String P_SHORT_HELP = "h";
40  
41      /**
42       * Parameter, long version, for "help".
43       */
44      private static final String P_LONG_HELP = "help";
45  
46      /**
47       * Parameter, short version, for "verbose".
48       */
49      private static final String P_SHORT_VERBOSE = "v";
50  
51      /**
52       * Parameter, short version, for "ASCII".
53       */
54      private static final String P_SHORT_ASCII = "t";
55  
56      /**
57       * Parameter, long version, for "ASCII".
58       */
59      private static final String P_LONG_ASCII = "text";
60  
61      /**
62       * Parameter, short version, for "encode".
63       */
64      private static final String P_SHORT_ENCODE = "e";
65  
66      /**
67       * Parameter, long version, for "encode".
68       */
69      private static final String P_LONG_ENCODE = "encode";
70  
71      /**
72       * Parameter, short version, for "decode".
73       */
74      private static final String P_SHORT_DECODE = "d";
75  
76      /**
77       * Parameter, long version, for "decode".
78       */
79      private static final String P_LONG_DECODE = "decode";
80  
81      /**
82       * Parameter, short version, for "config".
83       */
84      private static final String P_SHORT_CONFFILE = "c";
85  
86      /**
87       * Parameter, long version, for "config".
88       */
89      private static final String P_LONG_CONFFILE = "conffile";
90  
91      /**
92       * Parameter, short version, for "infile".
93       */
94      private static final String P_SHORT_INFILE = "i";
95  
96      /**
97       * Parameter, long version, for "infile".
98       */
99      private static final String P_LONG_INFILE = "infile";
100 
101     /**
102      * Parameter, short version, for "outfile".
103      */
104     private static final String P_SHORT_OUTFILE = "o";
105 
106     /**
107      * Parameter, long version, for "outfile".
108      */
109     private static final String P_LONG_OUTFILE = "outfile";
110 
111     /**
112      * log4j logger object.
113      */
114     private static final Logger LOGGER = LogManager.getLogger(JaStaCry.class.getName());
115 
116     /**
117      * boolean status: do we encode to plain text transport format.
118      */
119     private static boolean doASCIItransport;
120 
121     /**
122      * Filename of configuration file.
123      */
124     private static String confFilename;
125 
126     /**
127      * Some input filename.
128      */
129     private static String inputFilename;
130 
131     /**
132      * Some output filename.
133      */
134     private static String outputFilename;
135 
136     /**
137      * Be verbose about every step.
138      */
139     private static boolean isVerbose;
140 
141     /**
142      * action variable.
143      */
144     private static Action action;
145 
146     /**
147      * Hidden constructor.
148      */
149     @CoverageIgnore
150     private JaStaCry()
151     {
152         // not called
153     }
154 
155     /**
156      * Main class for running a command line interface.
157      *
158      * @param args parsed by Apache commons CLI package
159      */
160     @CoverageIgnore
161     @SuppressWarnings("squid:S4823") // Using command line arguments is security-sensitive
162     public static void main(final String[] args)
163     {
164         final int returncode = mainMethod(args);
165         System.exit(returncode); // NOPMD by kai on 21.11.17 17:04
166     }
167 
168     /**
169      * Main method.
170      *
171      * @param args for parsing
172      * @return int result code
173      */
174     public static int mainMethod(final String... args)
175     {
176         LOGGER.traceEntry();
177 
178         localizer();
179 
180         int returncode = setup(args);
181         if (0 != returncode)
182         {
183             LOGGER.error(getText("error.setupfound"), returncode);
184             return returncode; // NOPMD by kai on 21.11.17 16:59
185         } // if
186 
187         final Workerorker worker = new Worker();
188         worker.setAction(action);
189         worker.setConfFilename(confFilename);
190         worker.setDoAsciitransport(doASCIItransport);
191         worker.setInputFilename(inputFilename);
192         worker.setOutputFilename(outputFilename);
193         worker.setVerbose(isVerbose);
194 
195         returncode = worker.mainWork();
196         return LOGGER.traceExit(returncode);
197     }
198 
199     /**
200      * Create command line Options object.
201      *
202      * @return Options object
203      */
204     private static Options createOptions()
205     {
206         LOGGER.traceEntry();
207         final Options options = new Options();
208 
209         // optional parameters
210         options.addOption(P_SHORT_HELP, P_LONG_HELP, false, getText("help.help"));
211         options.addOption(P_SHORT_VERBOSE, false, getText("help.verbose"));
212         options.addOption(P_SHORT_ASCII, P_LONG_ASCII, false, getText("help.ascii"));
213 
214         // either/or arguments, but mandatory as a set
215         final OptionGroup ogAction = new OptionGroup();
216         Option option;
217         option = Option.builder(P_SHORT_ENCODE).required(false).longOpt(P_LONG_ENCODE).desc(getText("help.encode")).build();
218         ogAction.addOption(option);
219         option = Option.builder(P_SHORT_DECODE).required(false).longOpt(P_LONG_DECODE).desc(getText("help.decode")).build();
220         ogAction.addOption(option);
221         ogAction.setRequired(true);
222         options.addOptionGroup(ogAction);
223 
224         // mandatory parameters
225         option = Option.builder(P_SHORT_CONFFILE).required(true).hasArg().longOpt(P_LONG_CONFFILE).argName("FILE")
226                 .desc("use FILE as stack configuration").build();
227         options.addOption(option);
228 
229         option = Option.builder(P_SHORT_INFILE).required(true).hasArg().longOpt(P_LONG_INFILE).argName("FILE")
230                 .desc("use FILE as input stream").build();
231         options.addOption(option);
232 
233         option = Option.builder(P_SHORT_OUTFILE).required(true).hasArg().longOpt(P_LONG_OUTFILE).argName("FILE")
234                 .desc("use FILE as output stream").build();
235         options.addOption(option);
236 
237         return LOGGER.traceExit(options);
238     }
239 
240     /**
241      * Read current locale and load i18n bundle.
242      */
243     private static void localizer()
244     {
245         LOGGER.traceEntry();
246 
247         final Locale currentLocale = Locale.getDefault();
248         LOGGER.info("Locale: {}", currentLocale);
249 
250         // First read locale i18n stuff
251         bundle = ResourceBundle.getBundle("Bundle");
252 
253         LOGGER.traceExit();
254     }
255 
256     /**
257      * Helper function to get translated text from bundle.
258      * @param key String key for value
259      * @return String as translation
260      */
261     public static String getText(final String key)
262     {
263         return bundle.getString(key);
264     }
265 
266     /**
267      * Setup environment via command line arguments.
268      *
269      * @param args array of Strings from command line
270      * @return int error value
271      */
272     private static int setup(final String... args)
273     {
274         LOGGER.traceEntry();
275 
276         // Command line parameters
277         final Options options = createOptions();
278 
279         // Manual check for help, ignoring otherwise mandatory arguments
280         final HelpFormatter formatter = new HelpFormatter();
281         if (args.length > 0 && "-h".equalsIgnoreCase(args[0]))
282         {
283             formatter.printHelp(GlobalData.HELP, options);
284             return Returncode.RC_HELP.getNumVal();
285         } // if
286 
287         final CommandLineParser parser = new DefaultParser();
288         CommandLine cmdLine;
289         try
290         {
291             cmdLine = parser.parse(options, args);
292         }
293         catch (final MissingOptionException exOpt)
294         {
295             formatter.printHelp(GlobalData.HELP, options);
296             return Returncode.RC_ERROR.getNumVal();
297         }
298         catch (final ParseException e2)
299         {
300             LOGGER.catching(e2);
301             return LOGGER.traceExit(Returncode.RC_ERROR.getNumVal());
302         }
303 
304         if (null == cmdLine)
305         {
306             LOGGER.error("cmdLine null");
307             return LOGGER.traceExit(Returncode.RC_ERROR.getNumVal());
308         }
309 
310         // No need to check for P_SHORT_HELP here anymore.
311 
312         // Is verbose?
313         isVerbose = cmdLine.hasOption(P_SHORT_VERBOSE);
314         if (isVerbose)
315         {
316             LOGGER.info("JaStaCry starting");
317         }
318 
319         action = Action.UNKOWN;
320         // is it called with all needed parameters?
321         if (cmdLine.hasOption(P_SHORT_ENCODE) || cmdLine.hasOption(P_LONG_ENCODE))
322         {
323             action = Action.ENCODE;
324         } // if
325         if (cmdLine.hasOption(P_SHORT_DECODE) || cmdLine.hasOption(P_LONG_DECODE))
326         {
327             action = Action.DECODE;
328         } // if
329 
330         // Use text format?
331         doASCIItransport = cmdLine.hasOption(P_SHORT_ASCII) || cmdLine.hasOption(P_LONG_ASCII);
332 
333         // Get file names for config, input and output
334         confFilename = cmdLine.getOptionValue(P_LONG_CONFFILE);
335         inputFilename = cmdLine.getOptionValue(P_LONG_INFILE);
336         outputFilename = cmdLine.getOptionValue(P_LONG_OUTFILE);
337 
338         return LOGGER.traceExit(0);
339     }
340 
341 }