Skip to content
This repository has been archived by the owner on Aug 23, 2018. It is now read-only.

Commit

Permalink
Documented and cleaned up.
Browse files Browse the repository at this point in the history
  • Loading branch information
darccio committed Jul 20, 2010
1 parent f5e5abf commit 5231025
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 42 deletions.
24 changes: 0 additions & 24 deletions pom.xml
Expand Up @@ -28,34 +28,13 @@
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>codehaus-plugin-repository</id>
<name>Codehaus Plugin Repository</name>
<url>http://repository.codehaus.org</url>
</pluginRepository>
<pluginRepository>
<id>codehaus-plugin-snapshot-repository</id>
<name>Codehaus Plugin Snapshot Repository</name>
<url>http://snapshots.repository.codehaus.org</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.3</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
Expand Down Expand Up @@ -90,9 +69,6 @@
It is good for Paranamer and its BytecodeReader ;) -->
</configuration>
</plugin>
<!--plugin> <groupId>com.thoughtworks.paranamer</groupId> <artifactId>paranamer-maven-plugin</artifactId>
<version>2.2.1</version> <executions> <execution> <goals> <goal>generate</goal>
</goals> <phase>compile</phase> </execution> </executions> </plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down
40 changes: 35 additions & 5 deletions src/main/java/hm/murdock/Murdock.java
Expand Up @@ -17,21 +17,45 @@
* Murdock is an easy and ligtweight framework for command line apps.
*
* CLI apps have been with us a long time and they deserve a new brand framework
* in these GUI times. BTW, GUI are evil, stop.
* in these GUI times. BTW, GUI are evil, period.
*
* It features:
* This is the main class where all the magic starts. At this point, Murdock
* comprises two parts:
*
* <ul>
* <li>The Context: single point to access Murdock's configuration and
* environment (although there is nothing that keeps you from working your own
* way).</li>
* <li>The Router: main dispatcher which matches the given command (first
* paramater) with the corresponding module/action.</li>
* <ul>
* <li>REST-like command line interface (Play! framework inspired)</li>
* <li>Modules support for enhanced functionality</li>
* <li>If only a word is provided, it tries to match an action but shows all the
* matching actions if there is more than one.</li>
* <li>If a command with module:action syntax is provided, it looks for its
* corresponding module and action.</li>
* </ul>
* </ul>
*
* We must keep in mind that module name used here is the name of the action's
* containing class in lower case. Murdock does not handle CamelCase names so
* (e.g.) it will be camelcase, not camel_case.
*
* @author Dario (i@dario.im)
*
*/
public final class Murdock {

/**
* Current version.
*
* TODO Probably it should be overridable.
*/
public static final String VERSION = "0.0.1";

/**
* Name of the framework. It started as Baracus so why keep hard-coded
* references to its name?
*/
public static final String NAME = Murdock.class.getSimpleName()
.toLowerCase(Locale.US);

Expand All @@ -53,7 +77,7 @@ public Murdock(Context context) {
* module.
*
* If multiple modules handle the same action name, it shows all
* possibilities.
* possibilities, without executing them.
*
* @param arguments
*/
Expand All @@ -72,6 +96,12 @@ public void delegate(String... arguments) {
}
}

/**
*
* @param args
* @throws ConfigurationException
* If there is any problem while loading configuration.
*/
public static void main(String... args) throws ConfigurationException {
Murdock murdock = new Murdock();
murdock.delegate(args);
Expand Down
37 changes: 26 additions & 11 deletions src/main/java/hm/murdock/cli/Router.java
Expand Up @@ -34,14 +34,38 @@
*/
public final class Router {

/**
* Little hack which matches a context object with a router. This is used to
* don't recreate the router again in the help module.
*
* If I find a better way to do this, I will change this.
*/
private static final Map<Context, Router> routers = new HashMap<Context, Router>();

/**
* App's context.
*/
private final Context context;

private final Map<String /* action */, Map<String /* module:action */, Action>> actions;
/**
* Available actions.
*
* Each map belongs to an action word (second part of "module:action"
* syntax) and contains actions mapped with they full invoke name as
* module:action.
*/
private final Map<String /* "action" */, Map<String /* "module:action" */, Action>> actions;

/**
* Available modules and its actions.
*/
private final Map<Class<? extends Module>, List<Action>> modules;

/**
* Set of methods not overridable in Murdock.
*
* Right now they are methods from {@link Object} and {@link Addon} classes.
*/
private final Set<Method> notOverridableMethods;

/**
Expand Down Expand Up @@ -72,6 +96,7 @@ public Router(Context context) {

Map<String, Map<Hook, Method>> trackedHooks = new HashMap<String, Map<Hook, Method>>();

// Let's register everything.
registerModules(reflections, trackedHooks);
registerHelpers(reflections, trackedHooks);
registerHooks(trackedHooks);
Expand Down Expand Up @@ -103,16 +128,6 @@ private void registerModules(Reflections reflections,
Set<Class<? extends Module>> modules = reflections
.getSubTypesOf(Module.class);

/*
* Set<Method> notOverridableMethods = new HashSet<Method>();
* notOverridableMethods
* .addAll(Arrays.asList(Object.class.getMethods()));
*
* Map<String, Map<Hook, Method>> hooks = new HashMap<String, Map<Hook,
* Method>>(); this.actions = new HashMap<String, Map<String,
* Action>>();
*/

for (Class<? extends Module> module : modules) {
List<Action> moduleActions = new ArrayList<Action>();

Expand Down
27 changes: 25 additions & 2 deletions src/main/java/hm/murdock/utils/Context.java
Expand Up @@ -24,12 +24,25 @@
*/
public final class Context {

/**
* Reference to our home directory (e.g. ~/.murdock/).
*/
private final File appHome;

/**
* Loaded configuration from disk, located at {@link Context#appHome}.
*/
private final Properties configuration;

/**
* Are we in our first run? This is true while {@link Context#appHome}
* doesn't exist.
*/
private final Boolean firstRun;

/**
* Reference to configuration file.
*/
private final File configurationFile;

private final Logger logger;
Expand Down Expand Up @@ -70,6 +83,10 @@ public Context() throws ConfigurationException {
throw new ConfigurationException(
ConfigurationExceptionType.INVALID_FORMAT_CONFIG, e);
} catch (FileNotFoundException e) {
/*
* If we don't find the configuration file, we continue. This
* can change in future versions.
*/
logger.warn(ConfigurationExceptionType.UNABLE_ACCESS_CONFIG
.getMessage(configurationFile.getAbsoluteFile()), e);
} catch (IOException e) {
Expand All @@ -79,8 +96,12 @@ public Context() throws ConfigurationException {
}
} else {
if (!firstRun) {
logger.warn("Configuration file is missing at "
+ configurationFile.getAbsolutePath());
/*
* If we don't find the configuration file, we continue. This
* can change in future versions.
*/
logger.warn(ConfigurationExceptionType.UNABLE_ACCESS_CONFIG
.getMessage(configurationFile.getAbsoluteFile()));
}
}
}
Expand Down Expand Up @@ -110,6 +131,7 @@ public File getAppHome() {
*/
@SuppressWarnings("unchecked")
public <T> T getProperty(ContextProperty<T> property) {
// TODO Add automatic prefix for inherited classes from ContextProperty.
return (T) this.configuration.get(property.toString());
}

Expand All @@ -126,6 +148,7 @@ public <T> T getProperty(ContextProperty<T> property) {
@SuppressWarnings("unchecked")
public <T, E> E setProperty(ContextProperty<T> property, E value)
throws ConfigurationException {
// TODO Add automatic prefix for inherited classes from ContextProperty.
E oldValue = (E) this.configuration.put(property.toString(), value);
if (!property.isFlash()) {
try {
Expand Down

0 comments on commit 5231025

Please sign in to comment.