git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[JGIT PATCH 8/9] Refactor SubcommandHandler to use CommandCatalog instead of reflection

From
Shawn O. Pearce <spearce@spearce.org>
Date
Jul 25, 2008, 19:46 UTC
Message-ID
<1217015167-4680-9-git-send-email-spearce@spearce.org>
In-Reply-To
<1217015167-4680-8-git-send-email-spearce@spearce.org>

Now that all commands are known to the CommandCatalog we do not need to perform direct reflection inside of the SubcommandHandler. Instead we can reuse the lookup table already known to the CommandCatalog.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/TextBuiltin.java      |    8 +--
 .../spearce/jgit/pgm/opt/SubcommandHandler.java    |   65 ++------------------
 2 files changed, 6 insertions(+), 67 deletions(-)
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
index e2eef84..5c066cb 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
@@ -83,13 +83,7 @@ public abstract class TextBuiltin {
 	/** RevWalk used during command line parsing, if it was required. */
 	protected RevWalk argWalk;
 
-	/**
-	 * Set the name this command can be invoked as on the command line.
-	 *
-	 * @param name
-	 *            the name of the command.
-	 */
-	public void setCommandName(final String name) {
+	final void setCommandName(final String name) {
 		commandName = name;
 	}
 
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/opt/SubcommandHandler.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/opt/SubcommandHandler.java
index c7e1bf6..86004bb 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/opt/SubcommandHandler.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/opt/SubcommandHandler.java
@@ -37,8 +37,6 @@
 
 package org.spearce.jgit.pgm.opt;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.text.MessageFormat;
 
 import org.kohsuke.args4j.CmdLineException;
@@ -47,7 +45,8 @@ import org.kohsuke.args4j.OptionDef;
 import org.kohsuke.args4j.spi.OptionHandler;
 import org.kohsuke.args4j.spi.Parameters;
 import org.kohsuke.args4j.spi.Setter;
-import org.spearce.jgit.pgm.Main;
+import org.spearce.jgit.pgm.CommandCatalog;
+import org.spearce.jgit.pgm.CommandRef;
 import org.spearce.jgit.pgm.TextBuiltin;
 
 /**
@@ -57,12 +56,6 @@ import org.spearce.jgit.pgm.TextBuiltin;
  * we can execute at runtime with the remaining arguments of the parser.
  */
 public class SubcommandHandler extends OptionHandler<TextBuiltin> {
-	private static String mypackage() {
-		final String p = Main.class.getName();
-		final int dot = p.lastIndexOf('.');
-		return p.substring(0, dot);
-	}
-
 	/**
 	 * Create a new handler for the command name.
 	 * <p>
@@ -80,65 +73,17 @@ public class SubcommandHandler extends OptionHandler<TextBuiltin> {
 	@Override
 	public int parseArguments(final Parameters params) throws CmdLineException {
 		final String name = params.getParameter(0);
-		final StringBuilder s = new StringBuilder();
-		s.append(mypackage());
-		s.append('.');
-		boolean upnext = true;
-		for (int i = 0; i < name.length(); i++) {
-			final char c = name.charAt(i);
-			if (c == '-') {
-				upnext = true;
-				continue;
-			}
-			if (upnext)
-				s.append(Character.toUpperCase(c));
-			else
-				s.append(c);
-			upnext = false;
-		}
-
-		final Class<?> clazz;
-		try {
-			clazz = Class.forName(s.toString());
-		} catch (ClassNotFoundException e) {
-			throw new CmdLineException(MessageFormat.format(
-					"{0} is not a jgit command", name));
-		}
-
-		if (!TextBuiltin.class.isAssignableFrom(clazz))
+		final CommandRef cr = CommandCatalog.get(name);
+		if (cr == null)
 			throw new CmdLineException(MessageFormat.format(
 					"{0} is not a jgit command", name));
 
-		final Constructor<?> cons;
-		try {
-			cons = clazz.getDeclaredConstructor();
-		} catch (SecurityException e) {
-			throw new CmdLineException("Cannot create " + name, e);
-		} catch (NoSuchMethodException e) {
-			throw new CmdLineException("Cannot create " + name, e);
-		}
-		cons.setAccessible(true);
-
-		final TextBuiltin cmd;
-		try {
-			cmd = (TextBuiltin) cons.newInstance();
-		} catch (InstantiationException e) {
-			throw new CmdLineException("Cannot create " + name, e);
-		} catch (IllegalAccessException e) {
-			throw new CmdLineException("Cannot create " + name, e);
-		} catch (InvocationTargetException e) {
-			throw new CmdLineException("Cannot create " + name, e);
-		}
-
-		cmd.setCommandName(name);
-		setter.addValue(cmd);
-
 		// Force option parsing to stop. Everything after us should
 		// be arguments known only to this command and must not be
 		// recognized by the current parser.
 		//
 		owner.stopOptionParsing();
-
+		setter.addValue(cr.create());
 		return 1;
 	}
 
-- 
1.6.0.rc0.182.gb96c7
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 9 of 12 in “List commonly used (or recognized) commands”
  1. 0/9 List commonly used (or recognized) commandsShawn O. Pearce, Jul 25, 2008
  2. 1/9 Switch jgit.pgm to J2SE-1.5 execution environmentShawn O. Pearce, Jul 25, 2008
  3. 2/9 Remove unnecessary duplicate if (help) test inside TextBuiltinShawn O. Pearce, Jul 25, 2008
  4. 3/9 Create an optional documentation annotation for TextBuiltinShawn O. Pearce, Jul 25, 2008
  5. 4/9 Create a lightweight registration wrapper for TextBuiltinShawn O. Pearce, Jul 25, 2008
  6. 5/9 Create a catalog of CommandRefs for lookup and enumerationShawn O. Pearce, Jul 25, 2008
  7. 6/9 Document some common commands with the new Command annotationShawn O. Pearce, Jul 25, 2008
  8. 7/9 Include commonly used commands in main help outputShawn O. Pearce, Jul 25, 2008
  9. 8/9 Refactor SubcommandHandler to use CommandCatalog instead of reflectionShawn O. Pearce, Jul 25, 2008
  10. 9/9 Add debug-show-commands to display the command tableShawn O. Pearce, Jul 25, 2008
  11. 5/9 Create a catalog of CommandRefs for lookup and enumerationShawn O. Pearce, Jul 25, 2008
  12. Shawn O. PearceJul 25, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.