001    /*
002     * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003     * Copyright (C) 2011 NightLabs Consulting GmbH
004     *
005     * This program is free software: you can redistribute it and/or modify
006     * it under the terms of the GNU Affero General Public License as
007     * published by the Free Software Foundation, either version 3 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU Affero General Public License for more details.
014     *
015     * You should have received a copy of the GNU Affero General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    package org.cumulus4j.keymanager.cli;
019    
020    import java.io.IOException;
021    import java.util.ArrayList;
022    import java.util.Collections;
023    import java.util.HashMap;
024    import java.util.List;
025    import java.util.Map;
026    
027    import org.cumulus4j.keystore.KeyStore;
028    import org.kohsuke.args4j.CmdLineException;
029    import org.kohsuke.args4j.CmdLineParser;
030    
031    /**
032     * <p>
033     * Command line tool for the key store.
034     * </p>
035     * <p>
036     * Though this is the main class of the CLI, the actual logic for all command line
037     * operations is implemented in subclasses of {@link SubCommand}.
038     * </p>
039     *
040     * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
041     */
042    public class KeyManagerCLI
043    {
044            public static final List<Class<? extends SubCommand>> subCommandClasses;
045            static {
046                    ArrayList<Class<? extends SubCommand>> l = new ArrayList<Class<? extends SubCommand>>();
047    
048                    l.add(PutUserSubCommand.class);
049                    l.add(DeleteUserSubCommand.class);
050                    l.add(HelpSubCommand.class);
051                    l.add(InfoSubCommand.class);
052                    l.add(InitDateDependentKeyStrategySubCommand.class);
053                    l.add(LicenceSubCommand.class);
054                    l.add(LicenseSubCommand.class);
055                    l.add(VersionSubCommand.class);
056    
057                    l.trimToSize();
058                    subCommandClasses = Collections.unmodifiableList(l);
059            };
060    
061            public static final List<SubCommand> subCommands;
062            public static final Map<String, SubCommand> subCommandName2subCommand;
063            static {
064                    try {
065                            ArrayList<SubCommand> l = new ArrayList<SubCommand>();
066                            Map<String, SubCommand> m = new HashMap<String, SubCommand>();
067                            for (Class<? extends SubCommand> c : subCommandClasses) {
068                                    SubCommand subCommand = c.newInstance();
069                                    l.add(subCommand);
070                                    m.put(subCommand.getSubCommandName(), subCommand);
071                            }
072    
073                            l.trimToSize();
074                            subCommands = Collections.unmodifiableList(l);
075                            subCommandName2subCommand = Collections.unmodifiableMap(m);
076                    } catch (Exception e) {
077                            throw new RuntimeException(e);
078                    }
079            }
080    
081            private static final String CMD_PREFIX;
082            static {
083                    try {
084                            CMD_PREFIX = "java -jar org.cumulus4j.keymanager.cli-" + VersionSubCommand.getVersion() + ".jar";
085                    } catch (IOException e) {
086                            throw new RuntimeException(e);
087                    }
088            }
089    
090            private static final String[] stripSubCommand(String[] args)
091            {
092                    String[] result = new String[args.length - 1];
093                    for (int i = 0; i < result.length; i++)
094                            result[i] = args[i + 1];
095    
096                    return result;
097            }
098    
099            /**
100             * Main method providing a command line interface (CLI) to the {@link KeyStore}.
101             *
102             * @param args the program arguments.
103             */
104            public static void main(String[] args)
105            {
106                    int programExitStatus = 1;
107                    boolean displayHelp = true;
108                    String subCommandName = null;
109                    SubCommand subCommand = null;
110    
111                    if (args.length > 0) {
112                            subCommandName = args[0];
113    
114                            if ("help".equals(subCommandName)) {
115                                    if (args.length > 1) {
116                                            subCommandName = args[1];
117                                            subCommand = subCommandName2subCommand.get(subCommandName);
118                                            if (subCommand == null) {
119                                                    System.err.println("Unknown sub-command: " + subCommandName);
120                                                    subCommandName = null;
121                                            }
122                                    }
123                            }
124                            else {
125                                    subCommand = subCommandName2subCommand.get(subCommandName);
126                                    if (subCommand == null) {
127                                            System.err.println("Unknown sub-command: " + subCommandName);
128                                            subCommandName = null;
129                                    }
130                                    else {
131                                            displayHelp = false;
132    
133                                            CmdLineParser parser = new CmdLineParser(subCommand);
134                                            try {
135                                                    String[] argsWithoutSubCommand = stripSubCommand(args);
136                                                    parser.parseArgument(argsWithoutSubCommand);
137                                                    subCommand.prepare();
138                                                    subCommand.run();
139                                                    programExitStatus = 0;
140                                            } catch (CmdLineException e) {
141                                                    // handling of wrong arguments
142                                                    programExitStatus = 2;
143                                                    displayHelp = true;
144                                                    System.err.println("Error: " + e.getMessage());
145                                                    System.err.println();
146                                            } catch (Exception x) {
147                                                    programExitStatus = 3;
148                                                    x.printStackTrace();
149                                            }
150                                    }
151                            }
152                    }
153    
154                    if (displayHelp) {
155                            if (subCommand == null) {
156                                    System.err.println("Syntax: " + CMD_PREFIX + " <sub-command> <options>");
157                                    System.err.println();
158                                    System.err.println("Get help for a specific sub-command: " + CMD_PREFIX + " help <sub-command>");
159                                    System.err.println();
160                                    System.err.println("Available sub-commands:");
161                                    for (SubCommand sc : subCommands) {
162                                            System.err.println("  " + sc.getSubCommandName());
163                                    }
164                            }
165                            else {
166                                    CmdLineParser parser = new CmdLineParser(subCommand);
167                                    System.err.println(subCommand.getSubCommandName() + ": " + subCommand.getSubCommandDescription());
168                                    System.err.println();
169                                    System.err.print("Syntax: " + CMD_PREFIX + " " + subCommand.getSubCommandName());
170                                    parser.printSingleLineUsage(System.err);
171                                    System.err.println();
172                                    System.err.println();
173                                    System.err.println("Options:");
174                                    parser.printUsage(System.err);
175                            }
176                    }
177    
178                    System.exit(programExitStatus);
179            }
180    
181    }