Create a lightweight registration wrapper for TextBuiltin
[egit/zawir.git] / org.spearce.jgit.pgm / src / org / spearce / jgit / pgm / CommandRef.java
blob40400a72fa6a6134d499848604814868d060e4dd
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;
40 import java.lang.reflect.Constructor;
41 import java.lang.reflect.InvocationTargetException;
43 /**
44 * Description of a command (a {@link TextBuiltin} subclass.
45 * <p>
46 * These descriptions are lightweight compared to creating a command instance
47 * and are therefore suitable for catalogs of "known" commands without linking
48 * the command's implementation and creating a dummy instance of the command.
50 public class CommandRef {
51 private final Class<? extends TextBuiltin> impl;
53 private final String name;
55 private String usage;
57 boolean common;
59 CommandRef(final Class<? extends TextBuiltin> clazz) {
60 this(clazz, guessName(clazz));
63 CommandRef(final Class<? extends TextBuiltin> clazz, final Command cmd) {
64 this(clazz, cmd.name().length() > 0 ? cmd.name() : guessName(clazz));
65 usage = cmd.usage();
66 common = cmd.common();
69 private CommandRef(final Class<? extends TextBuiltin> clazz, final String cn) {
70 impl = clazz;
71 name = cn;
72 usage = "";
75 private static String guessName(final Class<? extends TextBuiltin> clazz) {
76 final StringBuilder s = new StringBuilder();
77 if (clazz.getName().startsWith("org.spearce.jgit.pgm.debug."))
78 s.append("debug-");
80 boolean lastWasDash = true;
81 for (final char c : clazz.getSimpleName().toCharArray()) {
82 if (Character.isUpperCase(c)) {
83 if (!lastWasDash)
84 s.append('-');
85 lastWasDash = !lastWasDash;
86 s.append(Character.toLowerCase(c));
87 } else {
88 s.append(c);
91 return s.toString();
94 /**
95 * @return name the command is invoked as from the command line.
97 public String getName() {
98 return name;
102 * @return one line description of the command's feature set.
104 public String getUsage() {
105 return usage;
109 * @return true if this command is considered to be commonly used.
111 public boolean isCommon() {
112 return common;
116 * @return name of the Java class which implements this command.
118 public String getImplementationClassName() {
119 return impl.getName();
123 * @return a new instance of the command implementation.
125 public TextBuiltin create() {
126 final Constructor<? extends TextBuiltin> c;
127 try {
128 c = impl.getDeclaredConstructor();
129 } catch (SecurityException e) {
130 throw new RuntimeException("Cannot create command " + getName(), e);
131 } catch (NoSuchMethodException e) {
132 throw new RuntimeException("Cannot create command " + getName(), e);
134 c.setAccessible(true);
136 final TextBuiltin r;
137 try {
138 r = c.newInstance();
139 } catch (InstantiationException e) {
140 throw new RuntimeException("Cannot create command " + getName(), e);
141 } catch (IllegalAccessException e) {
142 throw new RuntimeException("Cannot create command " + getName(), e);
143 } catch (IllegalArgumentException e) {
144 throw new RuntimeException("Cannot create command " + getName(), e);
145 } catch (InvocationTargetException e) {
146 throw new RuntimeException("Cannot create command " + getName(), e);
148 r.setCommandName(getName());
149 return r;