View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.creadur.whisker.cli;
20  
21  import org.apache.commons.cli.CommandLine;
22  import org.apache.commons.cli.CommandLineParser;
23  import org.apache.commons.cli.GnuParser;
24  import org.apache.commons.cli.HelpFormatter;
25  import org.apache.commons.cli.MissingOptionException;
26  import org.apache.commons.cli.Options;
27  import org.apache.commons.cli.ParseException;
28  import org.apache.creadur.whisker.app.Act;
29  import org.apache.creadur.whisker.app.Whisker;
30  import org.apache.creadur.whisker.app.load.StreamableResourceFactory;
31  import org.apache.creadur.whisker.app.out.WriteResultsToSystemOutFactory;
32  import org.apache.creadur.whisker.out.velocity.VelocityEngine;
33  
34  /**
35   * Command line interface for whisker.
36   */
37  public final class Main {
38  
39      /**
40       * Prepended to help.
41       */
42      private static final String HELP_HEADER = "\nPass " +
43      		"the descriptor containing license meta-data " +
44      		"and the act to be done.\n";
45  
46      /**
47       * Appended to help.
48       */
49      private static final String HELP_FOOTER =
50          "\nApache Whisker assists assembled applications " +
51          "maintain correct legal documentation. " +
52          "Whisker is part of the " +
53          "Apache Creadur suite of tools for " +
54          "auditing and comprehending software distributions, " +
55          "and is open source community developed software. " +
56          "Get involved at http://www.apache.org.\n\n";
57  
58      /**
59       * Names the application.
60       */
61      private static final String APP_NAME = "apache-whisker-cli";
62  
63      /**
64       * Returns okay to system.
65       */
66      private static final int SYSTEM_EXIT_OK = 0;
67      /** Error code returned to system when parameters cannot be parsed. */
68      private static final int SYSTEM_EXIT_CLI_PARSE_FAILED = 1;
69  
70      /**
71       * Bootstraps application.
72       * @param args not null
73       * @throws Exception when application unexpectedly fails
74       */
75      public static void main(final String[] args) throws Exception {
76          System.exit(new Main(app()).run(args));
77      }
78  
79      /**
80       * Creates an instance of the application.
81       * @return not null
82       */
83      private static Whisker app() {
84          return new Whisker();
85      }
86  
87      /** The application run. */
88      private final Whisker whisker;
89  
90      /**
91       * Constructs a wrapper for the given application.
92       * @param whisker not null
93       */
94      public Main(final Whisker whisker) {
95          super();
96          this.whisker = whisker;
97      }
98  
99      /**
100      * Creates a parser for command line parameters.
101      * Use GNU-style.
102      * @return not null
103      */
104     private CommandLineParser parser() {
105         return new GnuParser();
106     }
107 
108     /**
109      * Parses a line of arguments.
110      * @param args not null
111      * @return not null
112      * @throws ParseException when parsing fails
113      */
114     public CommandLine parse(final String[] args) throws ParseException {
115         return parser().parse(options(), args);
116     }
117 
118     /**
119      * Parses arguments and configures the application.
120      * @param args not null
121      * @return not null
122      * @throws ParseException when arguments cannot be parsed
123      */
124     public Whisker configure(final String[] args) throws ParseException {
125         return configure(parse(args));
126     }
127 
128     /**
129      * Configures the application from the command line given.
130      * @param commandLine not null
131      * @return not null
132      * @throws MissingOptionException when a mandatory option
133      * has not been supplied
134      */
135     private Whisker configure(
136             final CommandLine commandLine) throws MissingOptionException {
137         whisker.setEngine(new VelocityEngine(new SystemLog()));
138         whisker.setSource(CommandLineOption.SOURCE.getOptionValue(commandLine));
139         whisker.setLicenseDescriptor(
140                 new StreamableResourceFactory().streamFromResource(
141                         licenseDescriptorName(commandLine)));
142         whisker.setWriterFactory(new WriteResultsToSystemOutFactory());
143         if (CommandLineOption.ACT_TO_AUDIT.isSetOn(commandLine)) {
144             whisker.setAct(Act.AUDIT);
145         } else if (CommandLineOption.ACT_TO_GENERATE.isSetOn(commandLine)) {
146             whisker.setAct(Act.GENERATE);
147         } else if (CommandLineOption.ACT_TO_SKELETON.isSetOn(commandLine)) {
148             whisker.setAct(Act.SKELETON);
149         }
150 
151         if (whisker.getSource() == null
152                 && whisker.getAct().isSourceRequired()) {
153             throw new MissingOptionException("-"
154                     + CommandLineOption.SOURCE.getShortName() + " "
155                     + CommandLineOption.SOURCE.getDescription());
156         }
157         return whisker;
158     }
159 
160     /**
161      * Extracts the license descriptor name value,
162      * @param commandLine not null
163      * @return the value for the license descriptor name
164      * passed from the command line
165      */
166     private String licenseDescriptorName(final CommandLine commandLine) {
167         return CommandLineOption.LICENSE_DESCRIPTION
168             .getOptionValue(commandLine);
169     }
170 
171     /**
172      * Runs Whisker.
173      * @param args not null
174      * @return system return code
175      * @throws Exception when application unexpectedly fails
176      */
177     public int run(final String[] args) throws Exception {
178         try {
179             if (printHelp(args)) {
180                 help();
181             } else {
182                 configure(args).act();
183             }
184             return SYSTEM_EXIT_OK;
185         } catch (ParseException e) {
186             System.out.println();
187             System.out.println(e.getMessage());
188             System.out.println();
189             help();
190             return SYSTEM_EXIT_CLI_PARSE_FAILED;
191         }
192     }
193 
194     /**
195      * Do these command line arguments ask for help?
196      * @param args not null
197      * @return true when command line contains option for help,
198      * false otherwise
199      * @throws ParseException
200      */
201     public boolean printHelp(String[] args) throws ParseException {
202         final CommandLineOption help = CommandLineOption.PRINT_HELP;
203         try {
204             return help.isSetOn(
205                 parser().parse(new Options().addOption(
206                         help.create()), args));
207         } catch (ParseException e) {
208             return false;
209         }
210     }
211 
212     /**
213      * Prints out help.
214      */
215     private void help() {
216         final HelpFormatter formatter = new HelpFormatter();
217         formatter.printHelp(APP_NAME, HELP_HEADER, options(), HELP_FOOTER, true);
218     }
219 
220     /**
221      * Builds options for the command line.
222      * @return not null
223      */
224     private Options options() {
225         return CommandLineOption.options();
226     }
227 }