Convert jgit's Main to use args4j for basic parsing services
[egit/zawir.git] / org.spearce.jgit.pgm / src / org / spearce / jgit / pgm / opt / SubcommandHandler.java
blobc7e1bf614d27fd1bfe98d4476b92f1f8654870cf
1 /*
2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org.spearce.jgit.pgm.opt;
40 import java.lang.reflect.Constructor;
41 import java.lang.reflect.InvocationTargetException;
42 import java.text.MessageFormat;
44 import org.kohsuke.args4j.CmdLineException;
45 import org.kohsuke.args4j.CmdLineParser;
46 import org.kohsuke.args4j.OptionDef;
47 import org.kohsuke.args4j.spi.OptionHandler;
48 import org.kohsuke.args4j.spi.Parameters;
49 import org.kohsuke.args4j.spi.Setter;
50 import org.spearce.jgit.pgm.Main;
51 import org.spearce.jgit.pgm.TextBuiltin;
53 /**
54 * Custom Argument handler for jgit command selection.
55 * <p>
56 * Translates a single argument string to a {@link TextBuiltin} instance which
57 * we can execute at runtime with the remaining arguments of the parser.
59 public class SubcommandHandler extends OptionHandler<TextBuiltin> {
60 private static String mypackage() {
61 final String p = Main.class.getName();
62 final int dot = p.lastIndexOf('.');
63 return p.substring(0, dot);
66 /**
67 * Create a new handler for the command name.
68 * <p>
69 * This constructor is used only by args4j.
71 * @param parser
72 * @param option
73 * @param setter
75 public SubcommandHandler(final CmdLineParser parser,
76 final OptionDef option, final Setter<? super TextBuiltin> setter) {
77 super(parser, option, setter);
80 @Override
81 public int parseArguments(final Parameters params) throws CmdLineException {
82 final String name = params.getParameter(0);
83 final StringBuilder s = new StringBuilder();
84 s.append(mypackage());
85 s.append('.');
86 boolean upnext = true;
87 for (int i = 0; i < name.length(); i++) {
88 final char c = name.charAt(i);
89 if (c == '-') {
90 upnext = true;
91 continue;
93 if (upnext)
94 s.append(Character.toUpperCase(c));
95 else
96 s.append(c);
97 upnext = false;
100 final Class<?> clazz;
101 try {
102 clazz = Class.forName(s.toString());
103 } catch (ClassNotFoundException e) {
104 throw new CmdLineException(MessageFormat.format(
105 "{0} is not a jgit command", name));
108 if (!TextBuiltin.class.isAssignableFrom(clazz))
109 throw new CmdLineException(MessageFormat.format(
110 "{0} is not a jgit command", name));
112 final Constructor<?> cons;
113 try {
114 cons = clazz.getDeclaredConstructor();
115 } catch (SecurityException e) {
116 throw new CmdLineException("Cannot create " + name, e);
117 } catch (NoSuchMethodException e) {
118 throw new CmdLineException("Cannot create " + name, e);
120 cons.setAccessible(true);
122 final TextBuiltin cmd;
123 try {
124 cmd = (TextBuiltin) cons.newInstance();
125 } catch (InstantiationException e) {
126 throw new CmdLineException("Cannot create " + name, e);
127 } catch (IllegalAccessException e) {
128 throw new CmdLineException("Cannot create " + name, e);
129 } catch (InvocationTargetException e) {
130 throw new CmdLineException("Cannot create " + name, e);
133 cmd.setCommandName(name);
134 setter.addValue(cmd);
136 // Force option parsing to stop. Everything after us should
137 // be arguments known only to this command and must not be
138 // recognized by the current parser.
140 owner.stopOptionParsing();
142 return 1;
145 @Override
146 public String getDefaultMetaVariable() {
147 return "command";