diff --git a/dev-plugins/src/main/java/org/jboss/forge/dev/AS7DeployerPlugin.java b/dev-plugins/src/main/java/org/jboss/forge/dev/AS7DeployerPlugin.java
index f8a7ad661a..47a5b88f60 100644
--- a/dev-plugins/src/main/java/org/jboss/forge/dev/AS7DeployerPlugin.java
+++ b/dev-plugins/src/main/java/org/jboss/forge/dev/AS7DeployerPlugin.java
@@ -21,8 +21,7 @@
*/
package org.jboss.forge.dev;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
import java.util.Map;
import javax.enterprise.context.ApplicationScoped;
@@ -33,18 +32,15 @@
import org.jboss.forge.project.services.ResourceFactory;
import org.jboss.forge.resources.DirectoryResource;
import org.jboss.forge.resources.FileResource;
+import org.jboss.forge.resources.Resource;
import org.jboss.forge.shell.Shell;
import org.jboss.forge.shell.ShellMessages;
import org.jboss.forge.shell.ShellPrompt;
-import org.jboss.forge.shell.plugins.Alias;
-import org.jboss.forge.shell.plugins.Command;
-import org.jboss.forge.shell.plugins.PipeOut;
-import org.jboss.forge.shell.plugins.Plugin;
+import org.jboss.forge.shell.plugins.*;
import org.jboss.forge.shell.util.OSUtils;
/**
* @author Lincoln Baxter, III
- *
*/
@Alias("as7")
@ApplicationScoped
@@ -80,16 +76,81 @@ public void deploy(final PipeOut out)
FileResource> deployedArtifact = getDeployedArtifact();
if (!deployedArtifact.exists()
- || prompt.promptBoolean("Overwrite existing deployment? [" + deployedArtifact.getFullyQualifiedName()
- + "]"))
+ || prompt.promptBoolean("Overwrite existing deployment? [" + deployedArtifact.getFullyQualifiedName()
+ + "]"))
{
deployedArtifact.setContents(finalArtifact.getResourceInputStream());
shell.execute("rm -rf " + deployedArtifact.getFullyQualifiedName() + ".*");
ShellMessages.success(out, "Deployed [" + finalArtifact + "] to ["
- + getDeploymentDirectory().getFullyQualifiedName() + "]");
+ + getDeploymentDirectory().getFullyQualifiedName() + "]");
}
}
+ @Command
+ public void deployExploded(@Option(name = "triggerDeploy", flagOnly = true) boolean triggerDeploy,
+ @Option(name = "build", flagOnly = true) boolean build,
+ final PipeOut out) throws Exception
+ {
+ if(build) {
+ shell.execute("mvn compile war:exploded");
+ }
+
+ FileResource> finalArtifact = getExploded();
+
+ String artifactName = finalArtifact.getName() + ".war";
+ DirectoryResource deployDir = getDeploymentDirectory().getOrCreateChildDirectory(artifactName);
+ copyDirectory(finalArtifact.getUnderlyingResourceObject(), deployDir.getUnderlyingResourceObject());
+
+ if(triggerDeploy) {
+
+ FileResource> deployFile = (FileResource>)getDeploymentDirectory().getChild(artifactName + ".dodeploy");
+
+ deployFile.createNewFile();
+ }
+
+ if(triggerDeploy) {
+ String deployMessage = "[" + finalArtifact + "] to ["
+ + getDeploymentDirectory().getFullyQualifiedName() + "]";
+ ShellMessages.success(out, "Deployed " + deployMessage);
+ } else {
+ ShellMessages.success(out, "Copied [" + finalArtifact + "] to ["
+ + getDeploymentDirectory().getFullyQualifiedName() + ".war]. Use --triggerDeploy to redeploy the application");
+ }
+ }
+
+ private void copyDirectory(File sourceLocation, File targetLocation) throws IOException
+ {
+ if (sourceLocation.isDirectory())
+ {
+ if (!targetLocation.exists())
+ {
+ targetLocation.mkdir();
+ }
+
+ String[] children = sourceLocation.list();
+ for (int i = 0; i < children.length; i++)
+ {
+ copyDirectory(new File(sourceLocation, children[i]),
+ new File(targetLocation, children[i]));
+ }
+ } else
+ {
+
+ InputStream in = new FileInputStream(sourceLocation);
+ OutputStream out = new FileOutputStream(targetLocation);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0)
+ {
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ }
+ }
+
+
@Command
public void undeploy(final PipeOut out)
{
@@ -97,13 +158,13 @@ public void undeploy(final PipeOut out)
FileResource> deployedArtifact = getDeployedArtifact();
if (deployedArtifact.exists()
- && prompt.promptBoolean("Really undeploy [" + deployedArtifact.getFullyQualifiedName()
- + "]?"))
+ && prompt.promptBoolean("Really undeploy [" + deployedArtifact.getFullyQualifiedName()
+ + "]?"))
{
deployedArtifact.setContents(finalArtifact.getResourceInputStream());
shell.execute("rm -rf " + deployedArtifact.getFullyQualifiedName() + "*");
ShellMessages.success(out, "Removed deployment [" + finalArtifact + "] from ["
- + getDeploymentDirectory().getFullyQualifiedName() + "]");
+ + getDeploymentDirectory().getFullyQualifiedName() + "]");
}
}
@@ -142,6 +203,12 @@ public FileResource> getFinalArtifact()
return finalArtifact;
}
+ public DirectoryResource getExploded()
+ {
+ PackagingFacet packaging = project.getFacet(PackagingFacet.class);
+ return project.getProjectRoot().getChildDirectory("target").getChildDirectory(packaging.getFinalName());
+ }
+
public FileResource> getDeployedArtifact()
{
DirectoryResource deployDir = getDeploymentDirectory();
diff --git a/pom.xml b/pom.xml
index ff7e357bbf..d2b8700b73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
1.7.5
1.0.0.Final
3.0.0.Beta4
- 1.0.0.GA
+ 1.0.1.GA
4.8.1
1.2.16
1.0.0-alpha-11
@@ -99,6 +99,11 @@
pom
+
+ org.jboss.forge
+ forge-distribution
+ ${project.version}
+
org.jboss.forge
forge-event-bus
@@ -185,6 +190,11 @@
${project.version}
+
+ org.jboss.modules
+ jboss-modules
+ ${jboss.modules.version}
+
org.jboss.weld.se
weld-se-core
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/Shell.java b/shell-api/src/main/java/org/jboss/forge/shell/Shell.java
index 768c1777a1..ce50e866ea 100644
--- a/shell-api/src/main/java/org/jboss/forge/shell/Shell.java
+++ b/shell-api/src/main/java/org/jboss/forge/shell/Shell.java
@@ -192,6 +192,15 @@ public interface Shell extends ShellPrintWriter, ShellPrompt, ShellHistory
*/
String readLine() throws IOException;
+ /**
+ * Ask the current {@link InputStream} for input, masking keystrokes in the console with the given mask.
+ *
+ * @param mask The character to use for masking input
+ * @return any read data as a string, or null if none available.
+ * @throws IOException on error
+ */
+ String readLine(Character mask) throws IOException;
+
/**
* Controls the shell's usage of ANSI escape code support. This method does not guarantee ANSI will function
* properly, as the underlying Terminal must also support it.
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/ShellPrompt.java b/shell-api/src/main/java/org/jboss/forge/shell/ShellPrompt.java
index 34f276ef90..718513eed4 100644
--- a/shell-api/src/main/java/org/jboss/forge/shell/ShellPrompt.java
+++ b/shell-api/src/main/java/org/jboss/forge/shell/ShellPrompt.java
@@ -214,4 +214,10 @@ public interface ShellPrompt
* @param type The command completer type to instantiate and use during completion
*/
String promptCompleter(String string, Class extends CommandCompleter> type);
+
+ /**
+ * First print the given message, prompt the user for input (masking keystrokes for secrecy,) then return user input.
+ */
+ String promptSecret(String message);
+
}
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java b/shell-api/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java
new file mode 100644
index 0000000000..8d0f3de40d
--- /dev/null
+++ b/shell-api/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.command;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.forge.resources.Resource;
+
+/**
+ * Defines a command.
+ *
+ * @author Lincoln Baxter, III
+ *
+ */
+public interface CommandMetadata
+{
+ /**
+ * Get the help text for this comand.
+ */
+ String getHelp();
+
+ /**
+ * Get the {@link Method} that implements this command.
+ */
+ Method getMethod();
+
+ /**
+ * Get the name of this command.
+ */
+ String getName();
+
+ /**
+ * Get the option defined by the given name.
+ *
+ * @throws IllegalArgumentException if no such option exists.
+ */
+ OptionMetadata getNamedOption(String name) throws IllegalArgumentException;
+
+ /**
+ * Return the number of ordered (unnamed) options defined by this command.
+ */
+ int getNumOrderedOptions();
+
+ /**
+ * Return the option at the given index in the plugin method signature, not the index of the option on the command
+ * line.
+ */
+ OptionMetadata getOptionByAbsoluteIndex(int index);
+
+ /**
+ * Return a list of all options defined by this command.
+ */
+ List getOptions();
+
+ /**
+ * Return the option at the given index as required on the command line, not the index of the option in the
+ * implementing method signature.
+ */
+ OptionMetadata getOrderedOptionByIndex(int index) throws IllegalArgumentException;
+
+ /**
+ * Return the {@link PluginMetadata} containing this command.
+ */
+ PluginMetadata getParent();
+
+ /**
+ * Return the set of {@link Resource} types for which this command is in scope, or available.
+ */
+ @SuppressWarnings("rawtypes")
+ Set> getResourceScopes();
+
+ /**
+ * Return true if this command has an {@link OptionMetadata} with the given name.
+ */
+ boolean hasOption(String name);
+
+ /**
+ * Return true if this command has any options.
+ */
+ boolean hasOptions();
+
+ /**
+ * Return true if this command accepts ordered options.
+ */
+ boolean hasOrderedOptions();
+
+ /**
+ * Return true if this command accepts options that declare a short name.
+ */
+ boolean hasShortOption(String name);
+
+ /**
+ * Return true if this command is the default command for its declaring {@link PluginMetadata}
+ */
+ boolean isDefault();
+
+ /**
+ * Return true if this command is usable with the given resource scope.
+ */
+ @SuppressWarnings("rawtypes")
+ boolean usableWithResource(Class extends Resource> class1);
+
+}
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java b/shell-api/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java
new file mode 100644
index 0000000000..07dd9d33c7
--- /dev/null
+++ b/shell-api/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java
@@ -0,0 +1,156 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.command;
+
+import org.jboss.forge.shell.PromptType;
+import org.jboss.forge.shell.completer.CommandCompleter;
+import org.jboss.forge.shell.plugins.PipeIn;
+import org.jboss.forge.shell.plugins.PipeOut;
+
+/**
+ * Defines an option.
+ *
+ * @author Lincoln Baxter, III
+ */
+public interface OptionMetadata
+{
+ /**
+ * Return the boxed type for this option. E.g: If the literal type is 'int', the boxed type is {@link Integer}
+ */
+ Class> getBoxedType();
+
+ /**
+ * Return the type of the {@link CommandCompleter} for this option.
+ */
+ Class extends CommandCompleter> getCompleterType();
+
+ /**
+ * Get the default value for this option. Default values are used when no value is passed from the command line.
+ */
+ String getDefaultValue();
+
+ /**
+ * Get the description text for this option.
+ */
+ String getDescription();
+
+ /**
+ * Get the help text for this option.
+ */
+ String getHelp();
+
+ /**
+ * Get the index of this option in the receiving method signature parameter list.
+ */
+ int getIndex();
+
+ /**
+ * Get the name of this option.
+ */
+ String getName();
+
+ /**
+ * Get the verbose description of this option.
+ */
+ String getOptionDescriptor();
+
+ /**
+ * Get the {@link CommandMetadata} defining this option.
+ */
+ CommandMetadata getParent();
+
+ /**
+ * Get the requested {@link PromptType} for this option.
+ */
+ PromptType getPromptType();
+
+ /**
+ * Get the short name for this option, if it exists; otherwise, return empty string.
+ */
+ String getShortName();
+
+ /**
+ * Get the literal type of this option.
+ */
+ Class> getType();
+
+ /**
+ * Return true if this option specifies a custom {@link CommandCompleter}.
+ */
+ boolean hasCustomCompleter();
+
+ /**
+ * Return true if this option has a default value.
+ */
+ boolean hasDefaultValue();
+
+ /**
+ * Return true if this option is a boolean type.
+ */
+ boolean isBoolean();
+
+ /**
+ * Return true if this option is an enum type.
+ */
+ boolean isEnum();
+
+ /**
+ * Return true if this option is only a flag, and only has a short name, taking no value on the command line.
+ */
+ boolean isFlagOnly();
+
+ /**
+ * Return true if this option is named.
+ */
+ boolean isNamed();
+
+ /**
+ * Return true if this option is not named, and must be specified by order.
+ */
+ boolean isOrdered();
+
+ /**
+ * Return true if this option is the {@link PipeIn}
+ */
+ boolean isPipeIn();
+
+ /**
+ * Return true if this option is the {@link PipeOut}
+ */
+ boolean isPipeOut();
+
+ /**
+ * Return true if this option is required, and cannot be omitted on the command line.
+ */
+ boolean isRequired();
+
+ /**
+ * Return true if this option accepts multiple values on the command line.
+ */
+ boolean isVarargs();
+
+ /**
+ * Return true if this option is not ordered: E.g. It may be named, or may be a {@link PipeIn} or {@link PipeOut}
+ */
+ boolean notOrdered();
+
+}
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java b/shell-api/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java
new file mode 100644
index 0000000000..77b4dbfbe8
--- /dev/null
+++ b/shell-api/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java
@@ -0,0 +1,144 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.command;
+
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.forge.resources.Resource;
+import org.jboss.forge.shell.Shell;
+import org.jboss.forge.shell.plugins.Plugin;
+import org.jboss.forge.shell.plugins.RequiresFacet;
+import org.jboss.forge.shell.plugins.RequiresProject;
+
+/**
+ * Defines a plugin.
+ *
+ * @author Lincoln Baxter, III
+ *
+ */
+public interface PluginMetadata
+{
+ /**
+ * Return true if all constraints defined on this plugin (such as {@link RequiresProject} or {@link RequiresFacet})
+ * are satisfied by the current project (if available) and {@link Shell#getCurrentResource()} scope.
+ */
+ boolean constrantsSatisfied(Shell shell);
+
+ /**
+ * Get a list of all commands defined by this plugin, regardless of the current {@link Shell#getCurrentResource()}
+ * scope or constraints.
+ */
+ List getAllCommands();
+
+ /**
+ * Get the command with the given name, if it exists in this plugin and is not overloaded in multiple
+ * {@link Resource} scopes. If it does not exist, return null.
+ */
+ CommandMetadata getCommand(String name);
+
+ /**
+ * Get the command with the given name and {@link Resource} scope, if it exists in this plugin. If it does not exist,
+ * return null.
+ */
+ CommandMetadata getCommand(String name, Class extends Resource>> scope);
+
+ /**
+ * Get the command with the given name if it exists in this plugin, and is available in the current
+ * {@link Shell#getCurrentResource()} scope. If it does not exist, or is not in scope, return null.
+ */
+ CommandMetadata getCommand(String name, Shell shell);
+
+ /**
+ * Get a list of all commands defined by this plugin, if they are in scope.
+ */
+ List getCommands();
+
+ /**
+ * For the {@link Shell#getCurrentResource()} scope, return a list of all available commands defined by this plugin.
+ */
+ List getCommands(Shell shell);
+
+ /**
+ * Get the default command specified by this plugin. If none exists, return null.
+ */
+ CommandMetadata getDefaultCommand();
+
+ /**
+ * Get the help text for this plugin.
+ */
+ String getHelp();
+
+ /**
+ * Get the name by which this plugin is referenced on the command line.
+ */
+ String getName();
+
+ /**
+ * Get the {@link Resource} scopes for which this plugin is available.
+ */
+ Set>> getResourceScopes();
+
+ /**
+ * Get the topic text for this plugin.
+ */
+ String getTopic();
+
+ /**
+ * Get the implementing {@link Plugin} class type for this {@link PluginMetadata}
+ */
+ Class extends Plugin> getType();
+
+ /**
+ * Return true if this plugin defines a command with the given name and {@link Resource} scope.
+ */
+ boolean hasCommand(String name, Class extends Resource>> scope);
+
+ /**
+ * Return true if this plugin defines a command with the given name in the current
+ * {@link Shell#getCurrentResourceScope()}
+ */
+ boolean hasCommand(String name, Shell shell);
+
+ /**
+ * Return true if this plugin has any commands.
+ */
+ boolean hasCommands();
+
+ /**
+ * Return true if this plugin has a default command. Default commands are executed with the name of the plugin,
+ * instead of the name of the command.
+ */
+ boolean hasDefaultCommand();
+
+ /**
+ * Return true if this plugin is overloaded in multiple {@link Resource} scopes.
+ */
+ boolean isCommandOverloaded(String name);
+
+ /**
+ * Return true if this plugin is usable in the given {@link Resource} scope
+ */
+ @SuppressWarnings("rawtypes")
+ boolean usableWithScope(Class extends Resource> scope);
+
+}
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java b/shell-api/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java
new file mode 100644
index 0000000000..db6aa6411e
--- /dev/null
+++ b/shell-api/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.command;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.forge.shell.Shell;
+import org.jboss.forge.shell.plugins.Plugin;
+import org.jboss.forge.shell.plugins.RequiresFacet;
+import org.jboss.forge.shell.plugins.RequiresProject;
+
+/**
+ * Contains the collection of all installed and available plugins.
+ *
+ * @author Lincoln Baxter, III
+ */
+public interface PluginRegistry
+{
+ /**
+ * Add a plugin to the registry. Typically this will only be used by Forge itself.
+ */
+ void addPlugin(PluginMetadata plugin);
+
+ /**
+ * Get the {@link PluginMetadata} for the given plugin name. Returns an empty list if no plugins exist for the given
+ * name.
+ */
+ List getPluginMetadata(String plugin);
+
+ /**
+ * Resolves a single {@link PluginMetadata} instance representing the singular type that is in scope, and satisfied
+ * by the current project constraints such as {@link RequiresProject} or {@link RequiresFacet}
+ */
+ PluginMetadata getPluginMetadataForScopeAndConstraints(String name, Shell shell);
+
+ /**
+ * Get a map of all known plugin names and metadata.
+ */
+ Map> getPlugins();
+
+ /**
+ * Get the {@link Plugin} instance defined by the given {@link PluginMetadata}
+ */
+ Plugin instanceOf(PluginMetadata meta);
+}
diff --git a/shell-api/src/main/java/org/jboss/forge/shell/spi/CommandInterceptor.java b/shell-api/src/main/java/org/jboss/forge/shell/spi/CommandInterceptor.java
new file mode 100644
index 0000000000..09fab16624
--- /dev/null
+++ b/shell-api/src/main/java/org/jboss/forge/shell/spi/CommandInterceptor.java
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.spi;
+
+/**
+ * Allows the shell input stream to be intercepted, modified, or observed by extensions.
+ *
+ * @author Lincoln Baxter, III
+ *
+ */
+public interface CommandInterceptor
+{
+ /**
+ * Intercepts a command and returns it along with any modifications. The returned value will be passed to the Shell
+ * for invocation. If the returned value is null, the shell simply ignores this line and waits for the next input.
+ */
+ public String intercept(String line);
+}
diff --git a/shell/src/main/java/org/jboss/forge/shell/ShellImpl.java b/shell/src/main/java/org/jboss/forge/shell/ShellImpl.java
index c9563703a4..a35c7bf67a 100644
--- a/shell/src/main/java/org/jboss/forge/shell/ShellImpl.java
+++ b/shell/src/main/java/org/jboss/forge/shell/ShellImpl.java
@@ -40,6 +40,7 @@
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
@@ -83,6 +84,7 @@
import org.jboss.forge.shell.exceptions.ShellExecutionException;
import org.jboss.forge.shell.plugins.builtin.Echo;
import org.jboss.forge.shell.project.CurrentProject;
+import org.jboss.forge.shell.spi.CommandInterceptor;
import org.jboss.forge.shell.util.Files;
import org.jboss.forge.shell.util.GeneralUtils;
import org.jboss.forge.shell.util.JavaPathspecParser;
@@ -106,7 +108,7 @@ public class ShellImpl extends AbstractShellPrompt implements Shell
static final String DEFAULT_PROMPT_NO_PROJ = "[\\c{red}no project\\c] \\c{blue}\\W\\c \\c{red}\\$\\c ";
static final String PROP_DEFAULT_PLUGIN_REPO = "DEFFAULT_PLUGIN_REPO";
- static final String DEFAULT_PLUGIN_REPO = "http://seamframework.org/service/File/148617";
+ static final String DEFAULT_PLUGIN_REPO = "https://raw.github.com/forge/plugin-repository/master/repository.yaml";
static final String PROP_VERBOSE = "VERBOSE";
@@ -225,6 +227,9 @@ public boolean canConvertFrom(final Class aClass)
@Inject
private ShellConfig shellConfig;
+ @Inject
+ private Instance commandInterceptors;
+
void init(@Observes final Startup event, final PluginCommandCompleter pluginCompleter) throws Exception
{
BooleanConverter booleanConverter = new BooleanConverter();
@@ -573,7 +578,7 @@ private String formatSourcedError(final CommandMetadata cmd)
String out = null;
if (cmd != null)
{
- out = cmd.getPluginMetadata().getName();
+ out = cmd.getParent().getName();
if (!cmd.isDefault())
out += " " + cmd.getName();
@@ -588,7 +593,21 @@ private String formatSourcedError(final CommandMetadata cmd)
@Override
public String readLine() throws IOException
{
- String line = reader.readLine();
+ return readLine(null);
+ }
+
+ @Override
+ public String readLine(final Character mask) throws IOException
+ {
+ String line = null;
+ if (mask != null)
+ {
+ line = reader.readLine(mask);
+ }
+ else
+ {
+ line = reader.readLine();
+ }
if (isExecuting() && (line == null))
{
@@ -659,12 +678,17 @@ public void cursorLeft(final int x)
}
@Override
- public void execute(final String line)
+ public void execute(String line)
{
try
{
executing = true;
- fshRuntime.run(line);
+ for (CommandInterceptor interceptor : commandInterceptors) {
+ line = interceptor.intercept(line);
+ }
+
+ if (line != null)
+ fshRuntime.run(line);
}
catch (Exception e)
{
@@ -1100,6 +1124,35 @@ public String promptWithCompleter(String message, final Completer tempCompleter)
}
}
+ @Override
+ public String promptSecret(String message)
+ {
+ if (!message.isEmpty() && message.matches("^.*\\S$"))
+ {
+ message = message + " ";
+ }
+ message = renderColor(ShellColor.CYAN, " ? ") + message;
+
+ try
+ {
+ reader.removeCompleter(this.completer);
+ reader.setHistoryEnabled(false);
+ reader.setPrompt(message);
+ String line = readLine('*');
+ return line;
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("Shell input stream failure", e);
+ }
+ finally
+ {
+ reader.addCompleter(this.completer);
+ reader.setHistoryEnabled(true);
+ reader.setPrompt("");
+ }
+ }
+
@Override
protected PromptTypeConverter getPromptTypeConverter()
{
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/CommandLibraryExtension.java b/shell/src/main/java/org/jboss/forge/shell/command/CommandLibraryExtension.java
index eafa06c5be..a9084f0c6e 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/CommandLibraryExtension.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/CommandLibraryExtension.java
@@ -84,7 +84,7 @@ public PluginMetadata getMetadataFor(final Class extends Plugin> plugin)
{
String name = getPluginName(plugin);
- PluginMetadata pluginMeta = new PluginMetadata();
+ PluginMetadataImpl pluginMeta = new PluginMetadataImpl();
pluginMeta.setName(name);
pluginMeta.setType(plugin);
@@ -116,7 +116,7 @@ public PluginMetadata getMetadataFor(final Class extends Plugin> plugin)
}
@SuppressWarnings("rawtypes")
- private List processPluginCommands(final PluginMetadata pluginMeta, final Class> plugin)
+ private List processPluginCommands(final PluginMetadataImpl pluginMeta, final Class> plugin)
{
List results = new ArrayList();
@@ -125,7 +125,7 @@ private List processPluginCommands(final PluginMetadata pluginM
if (Annotations.isAnnotationPresent(method, Command.class))
{
Command command = Annotations.getAnnotation(method, Command.class);
- CommandMetadata commandMeta = new CommandMetadata();
+ CommandMetadataImpl commandMeta = new CommandMetadataImpl();
commandMeta.setMethod(method);
commandMeta.setHelp(command.help());
commandMeta.setParent(pluginMeta);
@@ -184,7 +184,7 @@ private List processPluginCommands(final PluginMetadata pluginM
int i = 0;
for (Class> clazz : parameterTypes)
{
- OptionMetadata optionMeta = new OptionMetadata();
+ OptionMetadataImpl optionMeta = new OptionMetadataImpl();
optionMeta.setType(clazz);
optionMeta.setIndex(i);
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java b/shell/src/main/java/org/jboss/forge/shell/command/CommandMetadataImpl.java
similarity index 90%
rename from shell/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java
rename to shell/src/main/java/org/jboss/forge/shell/command/CommandMetadataImpl.java
index 8fc0039113..25d64c8467 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/CommandMetadata.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/CommandMetadataImpl.java
@@ -35,11 +35,10 @@
/**
* @author Lincoln Baxter, III
*/
-public class CommandMetadata
+public class CommandMetadataImpl implements CommandMetadata
{
private PluginMetadata parent;
private Method method;
- private Method pipeInMethod;
private boolean isDefault = false;
@@ -47,11 +46,10 @@ public class CommandMetadata
private String help = "";
private List options = new ArrayList();
- private int parmLength = 0;
-
@SuppressWarnings("rawtypes")
private Set> resourceScopes = Collections.emptySet();
+ @Override
public OptionMetadata getNamedOption(final String name) throws IllegalArgumentException
{
for (OptionMetadata option : options)
@@ -64,10 +62,7 @@ public OptionMetadata getNamedOption(final String name) throws IllegalArgumentEx
throw new IllegalArgumentException("No such option [" + name + "] for command: " + this);
}
- /**
- * Return the option at the given index. This index represents where the option was defined in the plugin method
- * signature, not the index of the option on the command line.
- */
+ @Override
public OptionMetadata getOptionByAbsoluteIndex(final int index)
{
for (OptionMetadata option : options)
@@ -81,6 +76,7 @@ public OptionMetadata getOptionByAbsoluteIndex(final int index)
}
+ @Override
public OptionMetadata getOrderedOptionByIndex(final int index) throws IllegalArgumentException
{
int currentIndex = 0;
@@ -98,6 +94,7 @@ else if (option.isOrdered())
throw new IllegalArgumentException("No option with index [" + index + "] exists for command: " + this);
}
+ @Override
public int getNumOrderedOptions()
{
int count = 0;
@@ -111,6 +108,7 @@ public int getNumOrderedOptions()
return count;
}
+ @Override
public Method getMethod()
{
return method;
@@ -121,16 +119,7 @@ public void setMethod(final Method method)
this.method = method;
}
- public Method getPipeInMethod()
- {
- return pipeInMethod;
- }
-
- public void setPipeInMethod(final Method pipeInMethod)
- {
- this.pipeInMethod = pipeInMethod;
- }
-
+ @Override
public boolean isDefault()
{
return isDefault;
@@ -141,6 +130,7 @@ public void setDefault(final boolean isDefault)
this.isDefault = isDefault;
}
+ @Override
public String getName()
{
return name;
@@ -151,6 +141,7 @@ public void setName(final String name)
this.name = name;
}
+ @Override
public List getOptions()
{
if (options == null)
@@ -199,6 +190,7 @@ public void addOption(final OptionMetadata option)
this.options.add(option);
}
+ @Override
public String getHelp()
{
return help;
@@ -215,7 +207,8 @@ public String toString()
return name;
}
- public PluginMetadata getPluginMetadata()
+ @Override
+ public PluginMetadata getParent()
{
return parent;
}
@@ -225,11 +218,13 @@ public void setParent(final PluginMetadata parent)
this.parent = parent;
}
+ @Override
public boolean hasOptions()
{
return !getOptions().isEmpty();
}
+ @Override
public boolean hasShortOption(final String name)
{
for (OptionMetadata option : options)
@@ -242,6 +237,7 @@ public boolean hasShortOption(final String name)
return false;
}
+ @Override
public boolean hasOption(final String name)
{
for (OptionMetadata option : options)
@@ -257,6 +253,7 @@ public boolean hasOption(final String name)
return false;
}
+ @Override
@SuppressWarnings("rawtypes")
public Set> getResourceScopes()
{
@@ -275,16 +272,7 @@ public boolean usableWithResource(final Class extends Resource> resource)
return (this.resourceScopes.size() == 0) || this.resourceScopes.contains(resource);
}
- public int getParmLength()
- {
- return parmLength;
- }
-
- public void setParmLength(final int parmLength)
- {
- this.parmLength = parmLength;
- }
-
+ @Override
public boolean hasOrderedOptions()
{
try {
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/Execution.java b/shell/src/main/java/org/jboss/forge/shell/command/Execution.java
index 76a0a69f5b..9139eb995b 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/Execution.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/Execution.java
@@ -70,7 +70,7 @@ public void verifyConstraints(final Shell shell)
{
try
{
- enforcer.verifyAvailable(shell.getCurrentProject(), command.getPluginMetadata());
+ enforcer.verifyAvailable(shell.getCurrentProject(), command.getParent());
}
catch (ConstraintException e)
{
@@ -84,7 +84,7 @@ public void perform(final PipeOut pipeOut)
{
if (command != null)
{
- Class extends Plugin> pluginType = command.getPluginMetadata().getType();
+ Class extends Plugin> pluginType = command.getParent().getType();
Set> beans = manager.getBeans(pluginType);
Bean> bean = manager.resolve(beans);
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java b/shell/src/main/java/org/jboss/forge/shell/command/OptionMetadataImpl.java
similarity index 94%
rename from shell/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java
rename to shell/src/main/java/org/jboss/forge/shell/command/OptionMetadataImpl.java
index a3580497a7..af017db608 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/OptionMetadata.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/OptionMetadataImpl.java
@@ -35,7 +35,7 @@
* @author Lincoln Baxter, III
*
*/
-public class OptionMetadata
+public class OptionMetadataImpl implements OptionMetadata
{
private CommandMetadata parent;
private Class> type;
@@ -55,13 +55,13 @@ public class OptionMetadata
private boolean pipeIn;
private Class extends CommandCompleter> completerType;
- public OptionMetadata()
- {
- }
+ public OptionMetadataImpl()
+ {}
/**
* Get an informational string describing this Option
*/
+ @Override
public String getOptionDescriptor()
{
StringAppender appender = new StringAppender("[");
@@ -87,6 +87,7 @@ public String getOptionDescriptor()
/**
* Return whether this option is to be mapped via name or via parameter order.
*/
+ @Override
public boolean isNamed()
{
return (name != null) && !"".equals(name);
@@ -96,6 +97,7 @@ public boolean isNamed()
* Return the Boxed type of this Option, e.g: If the option is actual an int.class
, return
* Integer.class
instead.
*/
+ @Override
public Class> getBoxedType()
{
return ParseTools.boxPrimitive(getType());
@@ -104,6 +106,7 @@ public Class> getBoxedType()
/**
* Return the literal type represented by this Option, e.g: the actual method parameter type.
*/
+ @Override
public Class> getType()
{
return type;
@@ -117,6 +120,7 @@ public void setType(final Class> type)
/**
* Return the name of this Option, if it has one
*/
+ @Override
public String getName()
{
return name;
@@ -130,6 +134,7 @@ public void setName(final String name)
/**
* Get the short name of this option, if it has one.
*/
+ @Override
public String getShortName()
{
return shortName;
@@ -143,6 +148,7 @@ public void setShortName(final String shortName)
/**
* Return whether or not this option is purely a boolean flag.
*/
+ @Override
public boolean isFlagOnly()
{
return flagOnly;
@@ -156,6 +162,7 @@ public void setFlagOnly(final boolean flagOnly)
/**
* Return the description of this Option
*/
+ @Override
public String getDescription()
{
return description;
@@ -166,9 +173,7 @@ public void setDescription(final String description)
this.description = description;
}
- /**
- * Get the index of this Option in the receiving method parameter list.
- */
+ @Override
public int getIndex()
{
return index;
@@ -182,6 +187,7 @@ public void setIndex(final int index)
/**
* Get the help text for this Option
*/
+ @Override
public String getHelp()
{
return help;
@@ -195,6 +201,7 @@ public void setHelp(final String help)
/**
* Return whether or not this option requires a value at execution time.
*/
+ @Override
public boolean isRequired()
{
return required;
@@ -214,6 +221,7 @@ public String toString()
/**
* Get the parent Command of this Option
*/
+ @Override
public CommandMetadata getParent()
{
return parent;
@@ -227,6 +235,7 @@ public void setParent(final CommandMetadata parent)
/**
* Return whether or not this option represents a {@link Boolean} type
*/
+ @Override
public boolean isBoolean()
{
return (Boolean.TYPE.equals(getType()) || Boolean.class.equals(getType()));
@@ -235,14 +244,16 @@ public boolean isBoolean()
/**
* Return whether or not this option represents an {@link Enum} type.
*/
+ @Override
public boolean isEnum()
{
- return getType() != null && getType().isEnum();
+ return (getType() != null) && getType().isEnum();
}
/**
* Return whether or not this option represents a Varargs parameter type
*/
+ @Override
public boolean isVarargs()
{
return getType().isArray();
@@ -251,6 +262,7 @@ public boolean isVarargs()
/**
* Return the default value for this Option, if specified
*/
+ @Override
public String getDefaultValue()
{
return defaultValue;
@@ -264,6 +276,7 @@ public void setDefaultValue(final String defaultValue)
/**
* Return whether or not this Option provides a default value
*/
+ @Override
public boolean hasDefaultValue()
{
return (defaultValue != null) && !"".equals(defaultValue);
@@ -272,6 +285,7 @@ public boolean hasDefaultValue()
/**
* Return the selected {@link PromptType} for this Option.
*/
+ @Override
public PromptType getPromptType()
{
return promptType;
@@ -285,6 +299,7 @@ public void setPromptType(final PromptType type)
/**
* Return whether or not this Option is a {@link PipeOut}
*/
+ @Override
public boolean isPipeOut()
{
return pipeOut;
@@ -298,6 +313,7 @@ public void setPipeOut(final boolean pipeOut)
/**
* Return whether or not this Option is a {@link PipeIn}
*/
+ @Override
public boolean isPipeIn()
{
return pipeIn;
@@ -311,11 +327,13 @@ public void setPipeIn(final boolean pipeIn)
/**
* Return whether or not this Option is not ordered, e.g: It might have a name, or be an input/output pipe.
*/
+ @Override
public boolean notOrdered()
{
return pipeIn || pipeOut || isNamed();
}
+ @Override
public boolean isOrdered()
{
return !notOrdered();
@@ -324,6 +342,7 @@ public boolean isOrdered()
/**
* Return whether or not this option has specified a custom {@link CommandCompleter}
*/
+ @Override
public boolean hasCustomCompleter()
{
return (completerType != null) && !completerType.equals(NullCommandCompleter.class);
@@ -337,6 +356,7 @@ public void setCompleterType(final Class extends CommandCompleter> type)
/**
* Get the custom {@link CommandCompleter} for this Option, if specified.
*/
+ @Override
public Class extends CommandCompleter> getCompleterType()
{
return completerType;
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java b/shell/src/main/java/org/jboss/forge/shell/command/PluginMetadataImpl.java
similarity index 94%
rename from shell/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java
rename to shell/src/main/java/org/jboss/forge/shell/command/PluginMetadataImpl.java
index 90bcfc2d5f..eb30f8da00 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/PluginMetadata.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/PluginMetadataImpl.java
@@ -40,7 +40,7 @@
* @author Lincoln Baxter, III
* @author Mike Brock
*/
-public class PluginMetadata
+public class PluginMetadataImpl implements PluginMetadata
{
private String help = "";
private String name = "";
@@ -56,11 +56,13 @@ public class PluginMetadata
private boolean scopeOverloaded = false;
+ @Override
public CommandMetadata getCommand(final String name)
{
return getCommand(name, (Class extends Resource>>) null);
}
+ @Override
public CommandMetadata getCommand(final String name, final Shell shell)
{
return getCommand(name, shell.getCurrentResourceScope());
@@ -69,6 +71,7 @@ public CommandMetadata getCommand(final String name, final Shell shell)
/**
* Get the command matching the given name, or return null.
*/
+ @Override
public CommandMetadata getCommand(final String name, final Class extends Resource>> scope)
{
if (scope == null)
@@ -105,21 +108,25 @@ public CommandMetadata getCommand(final String name, final Class extends Resou
return null;
}
+ @Override
public boolean hasCommand(final String name, final Shell shell)
{
return getCommand(name, shell.getCurrentResourceScope()) != null;
}
+ @Override
public boolean hasCommand(final String name, final Class extends Resource>> scope)
{
return getCommand(name, scope) != null;
}
+ @Override
public boolean hasDefaultCommand()
{
return getDefaultCommand() != null;
}
+ @Override
public CommandMetadata getDefaultCommand()
{
return defaultCommand;
@@ -140,7 +147,7 @@ public void addCommand(final CommandMetadata command)
if (defaultCommand != null)
{
throw new RuntimeException("default command already defined: " + command.getName() + "; for plugin: "
- + name);
+ + name);
}
defaultCommand = command;
}
@@ -157,17 +164,19 @@ public void addCommand(final CommandMetadata command)
commandMap.get(command.getName()).add(command);
}
+ @Override
public List getCommands()
{
return getCommands((Class extends Resource>>) null);
}
+ @Override
public List getCommands(final Shell shell)
{
return getCommands(shell.getCurrentResourceScope());
}
- public List getCommands(final Class extends Resource>> scope)
+ private List getCommands(final Class extends Resource>> scope)
{
if ((scope == null) && scopeOverloaded)
{
@@ -188,6 +197,7 @@ public List getCommands(final Class extends Resource>> scop
return Collections.unmodifiableList(result);
}
+ @Override
public List getAllCommands()
{
List result = new ArrayList();
@@ -201,6 +211,7 @@ public List getAllCommands()
return Collections.unmodifiableList(result);
}
+ @Override
public boolean isCommandOverloaded(final String name)
{
return commandMap.containsKey(name) && (commandMap.get(name).size() > 1);
@@ -212,6 +223,7 @@ public String toString()
return name;
}
+ @Override
public String getName()
{
return name;
@@ -222,6 +234,7 @@ public void setName(final String name)
this.name = name;
}
+ @Override
public Class extends Plugin> getType()
{
return type;
@@ -232,6 +245,7 @@ public void setType(final Class extends Plugin> type)
this.type = type;
}
+ @Override
public String getHelp()
{
return help;
@@ -242,6 +256,7 @@ public void setHelp(final String help)
this.help = help;
}
+ @Override
public String getTopic()
{
return topic;
@@ -252,11 +267,13 @@ public void setTopic(final String topic)
this.topic = topic.toUpperCase();
}
+ @Override
public boolean hasCommands()
{
return !commandMap.isEmpty();
}
+ @Override
public boolean constrantsSatisfied(final Shell shell)
{
try
@@ -271,12 +288,14 @@ public boolean constrantsSatisfied(final Shell shell)
}
}
+ @Override
@SuppressWarnings("rawtypes")
public boolean usableWithScope(final Class extends Resource> scope)
{
return resourceScopes.isEmpty() || resourceScopes.contains(scope);
}
+ @Override
public Set>> getResourceScopes()
{
return resourceScopes;
diff --git a/shell/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java b/shell/src/main/java/org/jboss/forge/shell/command/PluginRegistryImpl.java
similarity index 94%
rename from shell/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java
rename to shell/src/main/java/org/jboss/forge/shell/command/PluginRegistryImpl.java
index 74c6ac5eba..7459047ab2 100644
--- a/shell/src/main/java/org/jboss/forge/shell/command/PluginRegistry.java
+++ b/shell/src/main/java/org/jboss/forge/shell/command/PluginRegistryImpl.java
@@ -49,7 +49,7 @@
* @author Lincoln Baxter, III
*/
@Singleton
-public class PluginRegistry
+public class PluginRegistryImpl implements PluginRegistry
{
private Map> plugins;
private Map, PluginMetadata>> accessCache;
@@ -58,7 +58,7 @@ public class PluginRegistry
private final BeanManager manager;
@Inject
- public PluginRegistry(final CommandLibraryExtension library, final BeanManager manager)
+ public PluginRegistryImpl(final CommandLibraryExtension library, final BeanManager manager)
{
this.library = library;
this.manager = manager;
@@ -72,11 +72,13 @@ public void init()
sanityCheck();
}
+ @Override
public Map> getPlugins()
{
return plugins;
}
+ @Override
public void addPlugin(final PluginMetadata plugin)
{
if (!plugins.containsKey(plugin.getName()))
@@ -93,13 +95,14 @@ public String toString()
return "PluginRegistry [plugins=" + plugins + "]";
}
+ @Override
public Plugin instanceOf(final PluginMetadata meta)
{
return getContextualInstance(manager, meta.getType());
}
@SuppressWarnings("unchecked")
- public static T getContextualInstance(final BeanManager manager, final Class type)
+ private static T getContextualInstance(final BeanManager manager, final Class type)
{
T result = null;
Bean bean = (Bean) manager.resolve(manager.getBeans(type));
@@ -119,6 +122,7 @@ public static T getContextualInstance(final BeanManager manager, final Class
*
* @return the metadata, or null if no plugin with given name exists.
*/
+ @Override
public List getPluginMetadata(final String plugin)
{
List list = plugins.get(plugin);
@@ -133,6 +137,7 @@ public List getPluginMetadata(final String plugin)
* {@link org.jboss.forge.maven.Project}, {@link PackagingType}, and {@link Facet} constraints. Return null if no
* match for the given constraints can be found.
*/
+ @Override
public PluginMetadata getPluginMetadataForScopeAndConstraints(final String name, final Shell shell)
{
Class extends Resource>> scope = shell.getCurrentResourceScope();
diff --git a/shell/src/main/java/org/jboss/forge/shell/completer/OptionValueResolverCompleter.java b/shell/src/main/java/org/jboss/forge/shell/completer/OptionValueResolverCompleter.java
index 31f0d6e4bb..0f4ec106f1 100644
--- a/shell/src/main/java/org/jboss/forge/shell/completer/OptionValueResolverCompleter.java
+++ b/shell/src/main/java/org/jboss/forge/shell/completer/OptionValueResolverCompleter.java
@@ -1,5 +1,12 @@
package org.jboss.forge.shell.completer;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Map;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
import org.jboss.forge.project.Project;
import org.jboss.forge.project.facets.JavaSourceFacet;
import org.jboss.forge.project.services.ResourceFactory;
@@ -12,18 +19,10 @@
import org.jboss.forge.shell.Shell;
import org.jboss.forge.shell.command.OptionMetadata;
import org.jboss.forge.shell.command.parser.CommandParserContext;
-import org.jboss.forge.shell.completer.CommandCompleter;
-import org.jboss.forge.shell.completer.CommandCompleterState;
import org.jboss.forge.shell.util.BeanManagerUtils;
import org.jboss.forge.shell.util.JavaPathspecParser;
import org.jboss.forge.shell.util.PathspecParser;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.inject.Inject;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Map;
-
public class OptionValueResolverCompleter implements CommandCompleter
{
@@ -51,6 +50,12 @@ public void complete(final CommandCompleterState st)
if (option.hasCustomCompleter())
{
CommandCompleter completer = BeanManagerUtils.getContextualInstance(manager, option.getCompleterType());
+ if (completer == null)
+ {
+ throw new RuntimeException("Could not instantiate completer of type: "
+ + option.getCompleterType().getName()
+ + ", completers must be valid CDI beans (public top-level classes.)");
+ }
completer.complete(state);
}
else if (option.isEnum())
@@ -64,9 +69,9 @@ else if (isJavaResourceAssignable(option))
completeJavaPaths(state, option, valueMap, new ResourceFilter()
{
@Override
- public boolean accept(Resource> resource)
+ public boolean accept(final Resource> resource)
{
- return (resource instanceof DirectoryResource || resource instanceof JavaResource);
+ return ((resource instanceof DirectoryResource) || (resource instanceof JavaResource));
}
});
}
@@ -75,7 +80,7 @@ else if (isJavaPackageAssignable(option))
completeJavaPaths(state, option, valueMap, new ResourceFilter()
{
@Override
- public boolean accept(Resource> resource)
+ public boolean accept(final Resource> resource)
{
return (resource instanceof DirectoryResource);
}
@@ -89,11 +94,11 @@ else if (isFileResourceAssignable(option))
}
}
- private void completeJavaPaths(PluginCommandCompleterState state, OptionMetadata option,
- Map valueMap, ResourceFilter filter)
+ private void completeJavaPaths(final PluginCommandCompleterState state, final OptionMetadata option,
+ final Map valueMap, final ResourceFilter filter)
{
Project project = shell.getCurrentProject();
- if (project != null && project.hasFacet(JavaSourceFacet.class))
+ if ((project != null) && project.hasFacet(JavaSourceFacet.class))
{
ArrayList results = new ArrayList();
String[] values;
@@ -130,26 +135,26 @@ else if (valueMap.get(option) == null)
// the separator char
// set the value ahead by 1.
int lastNest = val.lastIndexOf(".");
- state.setIndex(state.getOriginalIndex() - val.length() + (lastNest != -1 ? lastNest + 1 : 0));
+ state.setIndex((state.getOriginalIndex() - val.length()) + (lastNest != -1 ? lastNest + 1 : 0));
state.getCandidates().addAll(results);
}
}
- private boolean isJavaPackageAssignable(OptionMetadata option)
+ private boolean isJavaPackageAssignable(final OptionMetadata option)
{
return PromptType.JAVA_PACKAGE.equals(option.getPromptType());
}
- private boolean isJavaResourceAssignable(OptionMetadata option)
+ private boolean isJavaResourceAssignable(final OptionMetadata option)
{
return JavaResource[].class.isAssignableFrom(option.getBoxedType())
|| JavaResource.class.isAssignableFrom(option.getBoxedType())
|| PromptType.JAVA_CLASS.equals(option.getPromptType());
}
- private void completeFilenames(PluginCommandCompleterState state, OptionMetadata option,
- Map valueMap)
+ private void completeFilenames(final PluginCommandCompleterState state, final OptionMetadata option,
+ final Map valueMap)
{
ArrayList results = new ArrayList();
String[] values;
@@ -188,7 +193,7 @@ else if (valueMap.get(option) == null)
// Record the current index point in the buffer. If we're at
// the separator char
// set the value ahead by 1.
- state.setIndex(state.getOriginalIndex() - val.length() + (lastNest != -1 ? lastNest + 1 : 0));
+ state.setIndex((state.getOriginalIndex() - val.length()) + (lastNest != -1 ? lastNest + 1 : 0));
state.getCandidates().addAll(results);
}
diff --git a/shell/src/main/java/org/jboss/forge/shell/constraint/ConstraintEnforcer.java b/shell/src/main/java/org/jboss/forge/shell/constraint/ConstraintEnforcer.java
index f29acbcbfe..3c78318797 100644
--- a/shell/src/main/java/org/jboss/forge/shell/constraint/ConstraintEnforcer.java
+++ b/shell/src/main/java/org/jboss/forge/shell/constraint/ConstraintEnforcer.java
@@ -41,7 +41,7 @@ public void verifyAvailable(final Project currentProject, final CommandMetadata
UnsatisfiedPackagingTypeException, UnsatisfiedFacetDependencyException
{
- Class extends Plugin> type = command.getPluginMetadata().getType();
+ Class extends Plugin> type = command.getParent().getType();
if (ConstraintInspector.requiresProject(type) && (currentProject == null))
{
throw new NoProjectException(
diff --git a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/AliasInterceptor.java b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/AliasInterceptor.java
new file mode 100644
index 0000000000..ae122e7f02
--- /dev/null
+++ b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/AliasInterceptor.java
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.forge.shell.plugins.builtin;
+
+import org.jboss.forge.shell.spi.CommandInterceptor;
+
+/**
+ * Responsible for converting aliases into full commands.
+ *
+ * @author Lincoln Baxter, III
+ *
+ */
+public class AliasInterceptor implements CommandInterceptor
+{
+ @Override
+ public String intercept(final String line)
+ {
+ if ("alias".equals(line.trim()))
+ return null;
+
+ return line;
+ }
+}
diff --git a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ForgePlugin.java b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ForgePlugin.java
index 1185ca5bf2..47d027044b 100644
--- a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ForgePlugin.java
+++ b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ForgePlugin.java
@@ -86,8 +86,9 @@ public class ForgePlugin implements Plugin
private final Shell shell;
@Inject
- public ForgePlugin(ForgeEnvironment environment, Event reinitializeEvent,
- ShellPrintWriter writer, ShellPrompt prompt, DependencyResolver resolver, Shell shell)
+ public ForgePlugin(final ForgeEnvironment environment, final Event reinitializeEvent,
+ final ShellPrintWriter writer, final ShellPrompt prompt, final DependencyResolver resolver,
+ final Shell shell)
{
this.environment = environment;
this.reinitializeEvent = reinitializeEvent;
@@ -102,7 +103,7 @@ public ForgePlugin(ForgeEnvironment environment, Event
*/
@DefaultCommand
- public void about(PipeOut out)
+ public void about(final PipeOut out)
{
out.println(" ____ _____ ");
out.println(" / ___| ___ __ _ _ __ ___ | ___|__ _ __ __ _ ___ ");
@@ -128,7 +129,7 @@ public void listInstalled(
@Option(name = "all",
shortName = "a",
description = "Show extra information about each installed plugin",
- defaultValue = "false") boolean showAll)
+ defaultValue = "false") final boolean showAll)
{
DirectoryResource pluginDir = environment.getPluginDirectory();
List> list = pluginDir.listResources();
@@ -210,21 +211,30 @@ public void listInstalled(
@Command(value = "find-plugin",
help = "Searches the configured Forge plugin index for a plugin matching the given search text")
- public void find(@Option(description = "search string") String searchString, final PipeOut out) throws Exception
+ public void find(@Option(description = "search string") final String searchString, final PipeOut out)
+ throws Exception
{
- // TODO remove this message once stabilized.
- ShellMessages.info(out, "This is a prototype feature and has limited functionality.");
List pluginList = PluginUtil.findPlugin(environment, searchString, out);
+ if (!pluginList.isEmpty())
+ {
+ out.println();
+ }
for (PluginRef ref : pluginList)
{
out.println(" - " + out.renderColor(ShellColor.BOLD, ref.getName()) + " (" + ref.getArtifact() + ")");
+ out.println("\tAuthor: " + ref.getAuthor());
+ out.println("\tWebsite: " + ref.getWebsite());
+ out.println("\tLocation: " + ref.getLocation());
+ out.println("\tTags: " + ref.getTags());
+ out.println("\tDescription: " + ref.getDescription());
+ out.println();
}
}
@Command(value = "install-plugin",
help = "Installs a plugin from the configured Forge plugin index")
- public void installFromIndex(@Option(description = "plugin-name") String pluginName,
+ public void installFromIndex(@Option(description = "plugin-name") final String pluginName,
final PipeOut out) throws Exception
{
// TODO remove this message once stabilized.
@@ -255,13 +265,13 @@ else if (ref.isGit())
}
}
- private void installFromMvnRepos(Dependency dep, PipeOut out, final DependencyRepository... repoList)
+ private void installFromMvnRepos(final Dependency dep, final PipeOut out, final DependencyRepository... repoList)
throws Exception
{
installFromMvnRepos(dep, out, Arrays.asList(repoList));
}
- private void installFromMvnRepos(Dependency dep, PipeOut out, final List repoList)
+ private void installFromMvnRepos(final Dependency dep, final PipeOut out, final List repoList)
throws Exception
{
List temp = resolver.resolveArtifacts(dep, repoList);
@@ -297,9 +307,9 @@ else if (artifacts.size() > 1)
@Command(value = "mvn-plugin",
help = "Download and install a plugin from a maven repository")
- public void installFromMvnRepos(@Option(description = "plugin-identifier", required = true) Dependency dep,
- @Option(name = "knownRepo", description = "target repository") KnownRepository repo,
- @Option(name = "repoUrl", description = "target repository URL") String repoURL,
+ public void installFromMvnRepos(@Option(description = "plugin-identifier", required = true) final Dependency dep,
+ @Option(name = "knownRepo", description = "target repository") final KnownRepository repo,
+ @Option(name = "repoUrl", description = "target repository URL") final String repoURL,
final PipeOut out) throws Exception
{
if (repoURL != null)
@@ -323,12 +333,12 @@ else if (repo == null)
@Command(value = "jar-plugin",
help = "Install a plugin from a local project folder")
public void installFromLocalJar(
- @Option(name = "jar", description = "jar file to install", required = true) Resource> resource,
- @Option(name = "id", description = "plugin identifier, [e.g. \"com.example.group : example-plugin\"]", required = true) Dependency dep,
+ @Option(name = "jar", description = "jar file to install", required = true) final Resource> resource,
+ @Option(name = "id", description = "plugin identifier, [e.g. \"com.example.group : example-plugin\"]", required = true) final Dependency dep,
final PipeOut out) throws Exception
{
FileResource> source = resource.reify(FileResource.class);
- if (source == null || !source.exists())
+ if ((source == null) || !source.exists())
{
throw new IllegalArgumentException("JAR file must be specified.");
}
@@ -355,8 +365,8 @@ public void installFromLocalJar(
@Command(value = "url-plugin",
help = "Download and install a plugin from the given URL")
public void installFromRemoteURL(
- @Option(description = "URL of jar file", required = true) URL url,
- @Option(name = "id", description = "plugin identifier, [e.g. \"com.example.group : example-plugin\"]", required = true) Dependency dep,
+ @Option(description = "URL of jar file", required = true) final URL url,
+ @Option(name = "id", description = "plugin identifier, [e.g. \"com.example.group : example-plugin\"]", required = true) final Dependency dep,
final PipeOut out) throws Exception
{
ShellMessages.info(out, "WARNING!");
@@ -375,11 +385,11 @@ public void installFromRemoteURL(
@Command(value = "source-plugin",
help = "Install a plugin from a local project folder")
public void installFromLocalProject(
- @Option(description = "project directory", required = true) Resource> projectFolder,
+ @Option(description = "project directory", required = true) final Resource> projectFolder,
final PipeOut out) throws Exception
{
DirectoryResource workspace = projectFolder.reify(DirectoryResource.class);
- if (workspace == null || !workspace.exists())
+ if ((workspace == null) || !workspace.exists())
{
throw new IllegalArgumentException("Project folder must be specified.");
}
@@ -393,9 +403,9 @@ public void installFromLocalProject(
@Command(value = "git-plugin",
help = "Install a plugin from a public git repository")
public void installFromGit(
- @Option(description = "git repo", required = true) String gitRepo,
- @Option(name = "ref", description = "branch or tag to build") String ref,
- @Option(name = "checkoutDir", description = "directory in which to clone the repository") Resource> checkoutDir,
+ @Option(description = "git repo", required = true) final String gitRepo,
+ @Option(name = "ref", description = "branch or tag to build") final String ref,
+ @Option(name = "checkoutDir", description = "directory in which to clone the repository") final Resource> checkoutDir,
final PipeOut out) throws Exception
{
@@ -407,7 +417,7 @@ public void installFromGit(
DirectoryResource buildDir = workspace.getChildDirectory("repo");
if (checkoutDir != null)
{
- if (!checkoutDir.exists() && checkoutDir instanceof FileResource>)
+ if (!checkoutDir.exists() && (checkoutDir instanceof FileResource>))
{
((FileResource>) checkoutDir).mkdirs();
}
@@ -451,7 +461,7 @@ public void installFromGit(
/*
* Helpers
*/
- private void buildFromCurrentProject(final PipeOut out, DirectoryResource buildDir) throws Abort
+ private void buildFromCurrentProject(final PipeOut out, final DirectoryResource buildDir) throws Abort
{
DirectoryResource savedLocation = shell.getCurrentDirectory();
try
@@ -465,7 +475,7 @@ private void buildFromCurrentProject(final PipeOut out, DirectoryResource buildD
}
DependencyFacet deps = project.getFacet(DependencyFacet.class);
- if (!deps.hasDependency(DependencyBuilder.create("org.jboss.forge:forge-shell-api"))
+ if (!deps.hasDependency(DependencyBuilder.create("org.jboss.forge:forge-shell-api"))
&& !prompt.promptBoolean("The project does not appear to be a Forge Plugin Project, install anyway?",
false))
{
@@ -474,7 +484,7 @@ private void buildFromCurrentProject(final PipeOut out, DirectoryResource buildD
ShellMessages.info(out, "Invoking build with underlying build system.");
Resource> artifact = project.getFacet(PackagingFacet.class).executeBuild();
- if (artifact != null && artifact.exists())
+ if ((artifact != null) && artifact.exists())
{
MetadataFacet meta = project.getFacet(MetadataFacet.class);
Dependency dep = meta.getOutputDependency();
@@ -487,7 +497,7 @@ private void buildFromCurrentProject(final PipeOut out, DirectoryResource buildD
else
{
throw new IllegalStateException("Build artifact [" + artifact.getFullyQualifiedName()
- + "] is missing and cannot be installed. Please resolve build errors and try again.");
+ + "] is missing and cannot be installed. Please resolve build errors and try again.");
}
}
finally
@@ -496,15 +506,15 @@ private void buildFromCurrentProject(final PipeOut out, DirectoryResource buildD
}
}
- private FileResource> createIncrementedPluginJarFile(Dependency dep)
+ private FileResource> createIncrementedPluginJarFile(final Dependency dep)
{
int version = 0;
PluginJar pluginJar = new PluginJar(dep);
DirectoryResource pluginDir = environment.getPluginDirectory();
List> list = pluginDir.listResources(new StartsWith(pluginJar.getName()));
- if (list.size() > 0 && !prompt.promptBoolean(
- "An existing version of this plugin was found. Replace it?", true))
+ if ((list.size() > 0) && !prompt.promptBoolean(
+ "An existing version of this plugin was found. Replace it?", true))
{
throw new RuntimeException("Aborted.");
}
@@ -530,15 +540,15 @@ private class StartsWith implements ResourceFilter
{
private final String prefix;
- public StartsWith(String prefix)
+ public StartsWith(final String prefix)
{
this.prefix = prefix;
}
@Override
- public boolean accept(Resource> resource)
+ public boolean accept(final Resource> resource)
{
- return resource != null && resource.getName() != null && resource.getName().startsWith(prefix);
+ return (resource != null) && (resource.getName() != null) && resource.getName().startsWith(prefix);
}
}
diff --git a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ListCommandsPlugin.java b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ListCommandsPlugin.java
index 91860502aa..9022a407ec 100644
--- a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ListCommandsPlugin.java
+++ b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/ListCommandsPlugin.java
@@ -184,7 +184,7 @@ private static String render(final boolean showAll, final Class extends Resour
}
else
{
- return (cmdMeta.getPluginMetadata().getName() + ":" + cmdMeta.getName() + (contextual ? "*" : ""));
+ return (cmdMeta.getParent().getName() + ":" + cmdMeta.getName() + (contextual ? "*" : ""));
}
}
else if (contextual)
@@ -195,7 +195,7 @@ else if (contextual)
}
else
{
- return (cmdMeta.getPluginMetadata().getName() + ":" + cmdMeta.getName() + "*");
+ return (cmdMeta.getParent().getName() + ":" + cmdMeta.getName() + "*");
}
}
diff --git a/shell/src/main/java/org/jboss/forge/shell/util/PluginRef.java b/shell/src/main/java/org/jboss/forge/shell/util/PluginRef.java
index 109c9e7e88..57ab7245a2 100644
--- a/shell/src/main/java/org/jboss/forge/shell/util/PluginRef.java
+++ b/shell/src/main/java/org/jboss/forge/shell/util/PluginRef.java
@@ -32,25 +32,15 @@
*/
public class PluginRef
{
- private final String name;
- private final String author;
- private final String description;
- private final String artifact;
- private final String gitRepo;
- private final String homeRepo;
- private final String gitRef;
-
- public PluginRef(String name, String author, String description, String artifact, String homeRepo, String gitRepo,
- String gitRef)
- {
- this.name = name;
- this.author = author;
- this.description = description;
- this.artifact = artifact;
- this.homeRepo = homeRepo;
- this.gitRepo = gitRepo;
- this.gitRef = gitRef;
- }
+ private String name = "";
+ private String website = "";
+ private String author = "";
+ private String description = "";
+ private String tags = "";
+ private String artifact = "";
+ private String gitRepo = "";
+ private String homeRepo = "";
+ private String gitRef = "";
public String getGitRef()
{
@@ -59,17 +49,22 @@ public String getGitRef()
public String getName()
{
- return name;
+ return name == null ? "" : name;
}
public String getAuthor()
{
- return author;
+ return author == null ? "" : author;
}
public String getDescription()
{
- return description;
+ return description == null ? "" : description;
+ }
+
+ public String getTags()
+ {
+ return tags == null ? "" : tags;
}
public Dependency getArtifact()
@@ -79,16 +74,80 @@ public Dependency getArtifact()
public String getHomeRepo()
{
- return homeRepo;
+ return homeRepo == null ? "" : homeRepo;
}
public String getGitRepo()
{
- return gitRepo;
+ return gitRepo == null ? "" : gitRepo;
}
public boolean isGit()
{
return !Strings.isNullOrEmpty(gitRepo);
}
+
+ public String getWebsite()
+ {
+ return website == null ? "" : website;
+ }
+
+ public String getLocation()
+ {
+ String location = getHomeRepo();
+ if (Strings.isNullOrEmpty(location))
+ {
+ location = getGitRepo();
+ }
+ if (Strings.isNullOrEmpty(location))
+ {
+ location = "Unknown";
+ }
+ return location;
+ }
+
+ public void setName(final String name)
+ {
+ this.name = name;
+ }
+
+ public void setWebsite(final String website)
+ {
+ this.website = website;
+ }
+
+ public void setAuthor(final String author)
+ {
+ this.author = author;
+ }
+
+ public void setDescription(final String description)
+ {
+ this.description = description;
+ }
+
+ public void setTags(final String tags)
+ {
+ this.tags = tags;
+ }
+
+ public void setArtifact(final String artifact)
+ {
+ this.artifact = artifact;
+ }
+
+ public void setGitRepo(final String gitRepo)
+ {
+ this.gitRepo = gitRepo;
+ }
+
+ public void setHomeRepo(final String homeRepo)
+ {
+ this.homeRepo = homeRepo;
+ }
+
+ public void setGitRef(final String gitRef)
+ {
+ this.gitRef = gitRef;
+ }
}
diff --git a/shell/src/main/java/org/jboss/forge/shell/util/PluginUtil.java b/shell/src/main/java/org/jboss/forge/shell/util/PluginUtil.java
index 477675607a..4ad897482e 100644
--- a/shell/src/main/java/org/jboss/forge/shell/util/PluginUtil.java
+++ b/shell/src/main/java/org/jboss/forge/shell/util/PluginUtil.java
@@ -49,9 +49,11 @@ public class PluginUtil
private static final String PROP_DESCRIPTION = "description";
private static final String PROP_AUTHOR = "author";
private static final String PROP_NAME = "name";
- private static final Object PROP_GIT_REF = "gitref";
+ private static final String PROP_WEBSITE = "website";
+ private static final String PROP_GIT_REF = "gitref";
+ private static final String PROP_TAGS = "tags";
- private static String getDefaultRepo(ForgeEnvironment environment)
+ private static String getDefaultRepo(final ForgeEnvironment environment)
{
String defaultRepo = (String) environment.getProperty("DEFFAULT_PLUGIN_REPO");
if (defaultRepo == null)
@@ -62,7 +64,8 @@ private static String getDefaultRepo(ForgeEnvironment environment)
}
@SuppressWarnings("unchecked")
- public static List findPlugin(ForgeEnvironment environment, String searchString, PipeOut out)
+ public static List findPlugin(final ForgeEnvironment environment, final String searchString,
+ final PipeOut out)
throws Exception
{
String defaultRepo = getDefaultRepo(environment);
@@ -91,6 +94,7 @@ public static List findPlugin(ForgeEnvironment environment, String se
List pluginList = new ArrayList();
Yaml yaml = new Yaml();
+ // TODO this needs to be cached instead of downloaded each time
for (Object o : yaml.loadAll(httpResponse.getEntity().getContent()))
{
if (o == null)
@@ -99,11 +103,12 @@ public static List findPlugin(ForgeEnvironment environment, String se
}
Map map = (Map) o;
- String name = map.get(PROP_NAME);
- if (pattern.matcher(name).matches())
+ PluginRef ref = bindToPuginRef(map);
+ if (pattern.matcher(ref.getName()).matches() || pattern.matcher(ref.getDescription()).matches()
+ || pattern.matcher(ref.getTags()).matches())
{
- pluginList.add(bindToPuginRef(map));
+ pluginList.add(ref);
}
}
@@ -137,14 +142,18 @@ public static void downloadFromURL(final PipeOut out, final URL url, final FileR
}
}
- private static PluginRef bindToPuginRef(Map map)
+ private static PluginRef bindToPuginRef(final Map map)
{
- return new PluginRef(map.get(PROP_NAME),
- map.get(PROP_AUTHOR),
- map.get(PROP_DESCRIPTION),
- map.get(PROP_ARTIFACT),
- map.get(PROP_HOME_MAVEN_REPO),
- map.get(PROP_GIT_REPOSITORY),
- map.get(PROP_GIT_REF));
+ PluginRef ref = new PluginRef();
+ ref.setName(map.get(PROP_NAME));
+ ref.setWebsite(map.get(PROP_WEBSITE));
+ ref.setArtifact(map.get(PROP_ARTIFACT));
+ ref.setAuthor(map.get(PROP_AUTHOR));
+ ref.setDescription(map.get(PROP_DESCRIPTION));
+ ref.setTags(map.get(PROP_TAGS));
+ ref.setHomeRepo(map.get(PROP_HOME_MAVEN_REPO));
+ ref.setGitRepo(map.get(PROP_GIT_REPOSITORY));
+ ref.setGitRef(map.get(PROP_GIT_REF));
+ return ref;
}
}
diff --git a/shell/src/test/java/org/jboss/forge/shell/test/ShellPromptTest.java b/shell/src/test/java/org/jboss/forge/shell/test/ShellPromptTest.java
index d6d26021a9..e6845a4a92 100644
--- a/shell/src/test/java/org/jboss/forge/shell/test/ShellPromptTest.java
+++ b/shell/src/test/java/org/jboss/forge/shell/test/ShellPromptTest.java
@@ -33,7 +33,6 @@
import java.util.Map;
import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.forge.shell.InvalidInput;
import org.jboss.forge.shell.test.completer.MockEnum;
import org.jboss.forge.test.AbstractShellTest;
import org.junit.Test;
@@ -43,195 +42,224 @@
* @author Lincoln Baxter, III
*/
@RunWith(Arquillian.class)
-public class ShellPromptTest extends AbstractShellTest {
- @Test
- public void testPromptBoolean() throws Exception {
- queueInputLines("y");
- assertTrue(getShell().promptBoolean("Would you like cake?"));
-
- queueInputLines("yes");
- assertTrue(getShell().promptBoolean("Would you like cake?"));
-
- queueInputLines("n");
- assertFalse(getShell().promptBoolean("Would you like cake?"));
-
- queueInputLines("no");
- assertFalse(getShell().promptBoolean("Would you like cake?"));
- }
-
- @Test
- public void testPromptBooleanDefaultsToYes() throws Exception {
- queueInputLines("");
- assertTrue(getShell().promptBoolean("Would you like cake?"));
- }
-
- @Test
- public void testPromptBooleanLoopsIfBadInput() throws Exception {
- queueInputLines("asdfdsf\n \n");
- assertFalse(getShell().promptBoolean("Would you like cake?", false));
-
- queueInputLines("asdfdsf\n n\n");
- assertFalse(getShell().promptBoolean("Would you like cake?", false));
-
- queueInputLines("asdfdsf\n y\n");
- }
-
- @Test
- public void testPromptChoiceList() throws Exception {
- List choices = Arrays.asList("blue", "green", "red", "yellow");
-
- queueInputLines("foo", "2");
- int choice = getShell().promptChoice("What is your favorite color?", choices);
- assertEquals(1, choice);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPromptChoiceListEmpty() throws Exception {
- List choices = Arrays.asList();
- getShell().promptChoice("What is your favorite color?", choices);
- fail();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPromptChoiceListNull() throws Exception {
- List choices = null;
- getShell().promptChoice("What is your favorite color?", choices);
- fail();
- }
-
- @Test
- public void testPromptChoiceListTyped() throws Exception {
- List choices = Arrays.asList("blue", "green", "red", "yellow");
-
- queueInputLines("foo", "2");
- String choice = getShell().promptChoiceTyped("What is your favorite color?", choices);
- assertEquals(choices.get(1), choice);
- }
-
- @Test
- public void testPromptChoiceListTypedDefault() throws Exception {
- List choices = Arrays.asList("blue", "green", "red", "yellow");
-
- queueInputLines("foo", "");
- String choice = getShell().promptChoiceTyped("What is your favorite color?", choices, "yellow");
- assertEquals(choices.get(3), choice);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPromptChoiceTypedListEmpty() throws Exception {
- List choices = Arrays.asList();
- getShell().promptChoiceTyped("What is your favorite color?", choices);
- fail();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPromptChoiceTypedListNull() throws Exception {
- List choices = null;
- getShell().promptChoiceTyped("What is your favorite color?", choices);
- fail();
- }
-
- @Test
- public void testPromptChoiceMapByIndex() throws Exception {
- Map options = new HashMap();
- options.put("blue", "option1");
- options.put("green", "option2");
- options.put("red", "option3");
-
- queueInputLines("2");
- String choice = getShell().promptChoice("What is your favorite color?", options);
- assertEquals("option1", choice);
- }
-
- @Test
- public void testPromptChoiceMapByIndexSingleItem() throws Exception {
- Map options = new HashMap();
- options.put("blue", "option1");
-
- queueInputLines("1");
- String choice = getShell().promptChoice("What is your favorite color?", options);
- assertEquals("option1", choice);
- }
-
- @Test
- public void testPromptChoiceMapByName() throws Exception {
- Map options = new HashMap();
- options.put("blue", "option1");
- options.put("green", "option2");
- options.put("red", "option3");
-
- queueInputLines("green");
- String choice = getShell().promptChoice("What is your favorite color?", options);
- assertEquals("option2", choice);
- }
-
- @Test
- public void testPromptChoiceMapLoopsIfNonExistingIndex() throws Exception {
- Map options = new HashMap();
- options.put("blue", "option1");
- options.put("green", "option2");
- options.put("red", "option3");
-
- queueInputLines("5", "2");
- String choice = getShell().promptChoice("What is your favorite color?", options);
- assertEquals("option1", choice);
- }
-
- @Test
- public void testPromptChoiceMapLoopsInvalidInput() throws Exception {
- Map options = new HashMap();
- options.put("blue", "option1");
- options.put("green", "option2");
- options.put("red", "option3");
-
- queueInputLines("bla", "2");
- String choice = getShell().promptChoice("What is your favorite color?", options);
- assertEquals("option1", choice);
- }
-
- @Test
- public void testPromptEnum() throws Exception {
- queueInputLines("BAR");
- assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testPromptEnumFallbackToListAsksForChoice() throws Exception {
- queueInputLines("");
- getShell().promptEnum("Enummy?", MockEnum.class);
- fail();
- }
-
- @Test
- public void testPromptEnumFallbackToList() throws Exception {
- queueInputLines("not-a-value", "2");
- assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class));
-
- queueInputLines("not-a-value", "", "", "", "3");
- assertEquals(MockEnum.BAZ, getShell().promptEnum("Enummy?", MockEnum.class));
-
- queueInputLines("not-a-value", "4");
- assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class));
- }
-
- @Test
- public void testPromptEnumDefault() throws Exception {
- queueInputLines("");
- assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.CAT));
-
- queueInputLines("");
- assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.CAT));
- }
-
- @Test
- public void testPromptEnumDefaultFallbackToList() throws Exception {
- queueInputLines("not-a-value", "");
- assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.BAR));
- }
-
- @Test
- public void testPromptEnumDefaultFallbackToListWithDefault() throws Exception {
- queueInputLines("not-a-value", "eeee", "aaa", "");
- assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.BAR));
- }
+public class ShellPromptTest extends AbstractShellTest
+{
+ @Test
+ public void testPromptBoolean() throws Exception
+ {
+ queueInputLines("y");
+ assertTrue(getShell().promptBoolean("Would you like cake?"));
+
+ queueInputLines("yes");
+ assertTrue(getShell().promptBoolean("Would you like cake?"));
+
+ queueInputLines("n");
+ assertFalse(getShell().promptBoolean("Would you like cake?"));
+
+ queueInputLines("no");
+ assertFalse(getShell().promptBoolean("Would you like cake?"));
+ }
+
+ @Test
+ public void testPromptBooleanDefaultsToYes() throws Exception
+ {
+ queueInputLines("");
+ assertTrue(getShell().promptBoolean("Would you like cake?"));
+ }
+
+ @Test
+ public void testPromptBooleanLoopsIfBadInput() throws Exception
+ {
+ queueInputLines("asdfdsf\n \n");
+ assertFalse(getShell().promptBoolean("Would you like cake?", false));
+
+ queueInputLines("asdfdsf\n n\n");
+ assertFalse(getShell().promptBoolean("Would you like cake?", false));
+
+ queueInputLines("asdfdsf\n y\n");
+ }
+
+ @Test
+ public void testPromptChoiceList() throws Exception
+ {
+ List choices = Arrays.asList("blue", "green", "red", "yellow");
+
+ queueInputLines("foo", "2");
+ int choice = getShell().promptChoice("What is your favorite color?", choices);
+ assertEquals(1, choice);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPromptChoiceListEmpty() throws Exception
+ {
+ List choices = Arrays.asList();
+ getShell().promptChoice("What is your favorite color?", choices);
+ fail();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPromptChoiceListNull() throws Exception
+ {
+ List choices = null;
+ getShell().promptChoice("What is your favorite color?", choices);
+ fail();
+ }
+
+ @Test
+ public void testPromptChoiceListTyped() throws Exception
+ {
+ List choices = Arrays.asList("blue", "green", "red", "yellow");
+
+ queueInputLines("foo", "2");
+ String choice = getShell().promptChoiceTyped("What is your favorite color?", choices);
+ assertEquals(choices.get(1), choice);
+ }
+
+ @Test
+ public void testPromptChoiceListTypedDefault() throws Exception
+ {
+ List choices = Arrays.asList("blue", "green", "red", "yellow");
+
+ queueInputLines("foo", "");
+ String choice = getShell().promptChoiceTyped("What is your favorite color?", choices, "yellow");
+ assertEquals(choices.get(3), choice);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPromptChoiceTypedListEmpty() throws Exception
+ {
+ List choices = Arrays.asList();
+ getShell().promptChoiceTyped("What is your favorite color?", choices);
+ fail();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPromptChoiceTypedListNull() throws Exception
+ {
+ List choices = null;
+ getShell().promptChoiceTyped("What is your favorite color?", choices);
+ fail();
+ }
+
+ @Test
+ public void testPromptChoiceMapByIndex() throws Exception
+ {
+ Map options = new HashMap();
+ options.put("blue", "option1");
+ options.put("green", "option2");
+ options.put("red", "option3");
+
+ queueInputLines("2");
+ String choice = getShell().promptChoice("What is your favorite color?", options);
+ assertEquals("option1", choice);
+ }
+
+ @Test
+ public void testPromptChoiceMapByIndexSingleItem() throws Exception
+ {
+ Map options = new HashMap();
+ options.put("blue", "option1");
+
+ queueInputLines("1");
+ String choice = getShell().promptChoice("What is your favorite color?", options);
+ assertEquals("option1", choice);
+ }
+
+ @Test
+ public void testPromptChoiceMapByName() throws Exception
+ {
+ Map options = new HashMap();
+ options.put("blue", "option1");
+ options.put("green", "option2");
+ options.put("red", "option3");
+
+ queueInputLines("green");
+ String choice = getShell().promptChoice("What is your favorite color?", options);
+ assertEquals("option2", choice);
+ }
+
+ @Test
+ public void testPromptChoiceMapLoopsIfNonExistingIndex() throws Exception
+ {
+ Map options = new HashMap();
+ options.put("blue", "option1");
+ options.put("green", "option2");
+ options.put("red", "option3");
+
+ queueInputLines("5", "2");
+ String choice = getShell().promptChoice("What is your favorite color?", options);
+ assertEquals("option1", choice);
+ }
+
+ @Test
+ public void testPromptChoiceMapLoopsInvalidInput() throws Exception
+ {
+ Map options = new HashMap();
+ options.put("blue", "option1");
+ options.put("green", "option2");
+ options.put("red", "option3");
+
+ queueInputLines("bla", "2");
+ String choice = getShell().promptChoice("What is your favorite color?", options);
+ assertEquals("option1", choice);
+ }
+
+ @Test
+ public void testPromptEnum() throws Exception
+ {
+ queueInputLines("BAR");
+ assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testPromptEnumFallbackToListAsksForChoice() throws Exception
+ {
+ queueInputLines("");
+ getShell().promptEnum("Enummy?", MockEnum.class);
+ fail();
+ }
+
+ @Test
+ public void testPromptEnumFallbackToList() throws Exception
+ {
+ queueInputLines("not-a-value", "2");
+ assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class));
+
+ queueInputLines("not-a-value", "", "", "", "3");
+ assertEquals(MockEnum.BAZ, getShell().promptEnum("Enummy?", MockEnum.class));
+
+ queueInputLines("not-a-value", "4");
+ assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class));
+ }
+
+ @Test
+ public void testPromptEnumDefault() throws Exception
+ {
+ queueInputLines("");
+ assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.CAT));
+
+ queueInputLines("");
+ assertEquals(MockEnum.CAT, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.CAT));
+ }
+
+ @Test
+ public void testPromptEnumDefaultFallbackToList() throws Exception
+ {
+ queueInputLines("not-a-value", "");
+ assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.BAR));
+ }
+
+ @Test
+ public void testPromptEnumDefaultFallbackToListWithDefault() throws Exception
+ {
+ queueInputLines("not-a-value", "eeee", "aaa", "");
+ assertEquals(MockEnum.BAR, getShell().promptEnum("Enummy?", MockEnum.class, MockEnum.BAR));
+ }
+
+ @Test
+ public void testPromptSecret() throws Exception
+ {
+ queueInputLines("secret");
+ assertEquals("secret", getShell().promptSecret("What's your secret?"));
+ }
}