View Javadoc
1   /*
2    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.pgm;
12  
13  import java.lang.reflect.Constructor;
14  import java.lang.reflect.InvocationTargetException;
15  import java.text.MessageFormat;
16  
17  import org.eclipse.jgit.pgm.internal.CLIText;
18  
19  /**
20   * Description of a command (a {@link org.eclipse.jgit.pgm.TextBuiltin}
21   * subclass).
22   * <p>
23   * These descriptions are lightweight compared to creating a command instance
24   * and are therefore suitable for catalogs of "known" commands without linking
25   * the command's implementation and creating a dummy instance of the command.
26   */
27  public class CommandRef {
28  	private final Class<? extends TextBuiltin> impl;
29  
30  	private final String name;
31  
32  	private String usage;
33  
34  	boolean common;
35  
36  	CommandRef(Class<? extends TextBuiltin> clazz) {
37  		this(clazz, guessName(clazz));
38  	}
39  
40  	CommandRef(Class<? extends TextBuiltin> clazz, Command cmd) {
41  		this(clazz, cmd.name().length() > 0 ? cmd.name() : guessName(clazz));
42  		usage = cmd.usage();
43  		common = cmd.common();
44  	}
45  
46  	private CommandRef(Class<? extends TextBuiltin> clazz, String cn) {
47  		impl = clazz;
48  		name = cn;
49  		usage = ""; //$NON-NLS-1$
50  	}
51  
52  	private static String guessName(Class<? extends TextBuiltin> clazz) {
53  		final StringBuilder s = new StringBuilder();
54  		if (clazz.getName().startsWith("org.eclipse.jgit.pgm.debug.")) //$NON-NLS-1$
55  			s.append("debug-"); //$NON-NLS-1$
56  
57  		boolean lastWasDash = true;
58  		for (char c : clazz.getSimpleName().toCharArray()) {
59  			if (Character.isUpperCase(c)) {
60  				if (!lastWasDash)
61  					s.append('-');
62  				lastWasDash = !lastWasDash;
63  				s.append(Character.toLowerCase(c));
64  			} else {
65  				s.append(c);
66  				lastWasDash = false;
67  			}
68  		}
69  		return s.toString();
70  	}
71  
72  	/**
73  	 * Get the <code>name</code>.
74  	 *
75  	 * @return name the command is invoked as from the command line.
76  	 */
77  	public String getName() {
78  		return name;
79  	}
80  
81  	/**
82  	 * Get <code>usage</code>.
83  	 *
84  	 * @return one line description of the command's feature set.
85  	 */
86  	public String getUsage() {
87  		return usage;
88  	}
89  
90  	/**
91  	 * Is this command commonly used
92  	 *
93  	 * @return true if this command is considered to be commonly used.
94  	 */
95  	public boolean isCommon() {
96  		return common;
97  	}
98  
99  	/**
100 	 * Get implementation class name
101 	 *
102 	 * @return name of the Java class which implements this command.
103 	 */
104 	public String getImplementationClassName() {
105 		return impl.getName();
106 	}
107 
108 	/**
109 	 * Get implementation class loader
110 	 *
111 	 * @return loader for {@link #getImplementationClassName()}.
112 	 */
113 	public ClassLoader getImplementationClassLoader() {
114 		return impl.getClassLoader();
115 	}
116 
117 	/**
118 	 * Create an instance of the command implementation
119 	 *
120 	 * @return a new instance of the command implementation.
121 	 */
122 	public TextBuiltin create() {
123 		final Constructor<? extends TextBuiltin> c;
124 		try {
125 			c = impl.getDeclaredConstructor();
126 		} catch (SecurityException | NoSuchMethodException e) {
127 			throw new RuntimeException(MessageFormat
128 					.format(CLIText.get().cannotCreateCommand, getName(), e));
129 		}
130 		c.setAccessible(true);
131 
132 		final TextBuiltin r;
133 		try {
134 			r = c.newInstance();
135 		} catch (InstantiationException | IllegalAccessException
136 				| IllegalArgumentException | InvocationTargetException e) {
137 			throw new RuntimeException(MessageFormat
138 					.format(CLIText.get().cannotCreateCommand, getName(), e));
139 		}
140 		r.setCommandName(getName());
141 		return r;
142 	}
143 
144 	/** {@inheritDoc} */
145 	@SuppressWarnings("nls")
146 	@Override
147 	public String toString() {
148 		return "CommandRef [impl=" + impl + ", name=" + name + ", usage="
149 				+ CLIText.get().resourceBundle().getString(usage) + ", common="
150 				+ common + "]";
151 	}
152 }