You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2012/05/11 10:39:19 UTC
svn commit: r1337063 [1/2] - in /karaf/trunk: shell/console/
shell/console/src/main/java/org/apache/felix/gogo/commands/
shell/console/src/main/java/org/apache/karaf/shell/commands/basic/
shell/console/src/main/java/org/apache/karaf/shell/commands/meta...
Author: cschneider
Date: Fri May 11 08:39:18 2012
New Revision: 1337063
URL: http://svn.apache.org/viewvc?rev=1337063&view=rev
Log:
KARAF-1447 Support old annotations for actions in addition to the new ones. Introduce metadata about commands
Added:
karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java
karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java
karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java
karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java
karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/
karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java
- copied, changed from r1336532, karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java
karaf/trunk/shell/help/src/main/resources/services/
- copied from r1336087, karaf/trunk/shell/console/src/main/resources/META-INF/services/
Removed:
karaf/trunk/shell/console/src/main/resources/META-INF/services/
karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java
Modified:
karaf/trunk/shell/console/pom.xml
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java
karaf/trunk/shell/help/pom.xml
karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java
karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java
karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java
karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java
karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
Modified: karaf/trunk/shell/console/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/pom.xml?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/pom.xml (original)
+++ karaf/trunk/shell/console/pom.xml Fri May 11 08:39:18 2012
@@ -141,7 +141,6 @@
org.apache.karaf.shell.console,
org.apache.karaf.shell.console.commands,
org.apache.karaf.shell.console.completer,
- org.apache.karaf.shell.console.table,
org.apache.karaf.shell.util,
org.apache.felix.gogo*;version=${felix.gogo.version},
org.apache.felix.service.command;version=${felix.gogo.version};status=provisional;mandatory:=status,
@@ -154,7 +153,6 @@
org.apache.karaf.shell.console.impl*,
org.fusesource.jansi.internal;-split-package:=first,
org.apache.felix.gogo.runtime*;-split-package:=first,
- org.apache.karaf.util*;-split-package:=first,
META-INF.native.*;-split-package:=first
</Private-Package>
<Bundle-NativeCode>
Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Action.java Fri May 11 08:39:18 2012
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.commands;
+
+
+/**
+ * An action allows to easily execute commands in karaf.
+ * It can be assumed that each action is only accessed by a single thread at a time.
+ *
+ * An Action is always part of an AbstractCommand. The AbstractCommand makes sure
+ * the single threaded assumption above is true. Before the call to the execute method
+ * the action is checked for annotated fields (@Argument, @Option). These fields
+ * are populated from the command arguments before the action is called.
+ *
+ * @deprecated use org.apache.karaf.shell.commands.Action instead
+ */
+@Deprecated
+public interface Action extends org.apache.karaf.shell.commands.Action {
+}
Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Argument.java Fri May 11 08:39:18 2012
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Represents a positional argument on a command line (as opposed to an optional named {@link Option}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Argument
+{
+ public static final String DEFAULT_STRING= "DEFAULT";
+
+ String DEFAULT = "##default";
+
+ String name() default DEFAULT;
+
+ String description() default "";
+
+ boolean required() default false;
+
+ int index() default 0;
+
+ boolean multiValued() default false;
+
+ String valueToShowInHelp() default DEFAULT_STRING;
+}
Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Command.java Fri May 11 08:39:18 2012
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Used to denote a class represents a command which is executable within a shell/scope or as a
+ * command line process.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Deprecated
+public @interface Command
+{
+ /**
+ * Returns the scope or sub shell of the command
+ */
+ String scope();
+
+ /**
+ * REturns the name of the command if used inside a shell
+ */
+ String name();
+
+ /**
+ * Returns the description of the command which is used to generate command line help
+ */
+ String description() default "";
+
+ /**
+ * Returns a detailed description of the command
+ */
+ String detailedDescription() default "";
+}
Added: karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/felix/gogo/commands/Option.java Fri May 11 08:39:18 2012
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.commands;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to mark an optional named command line option who's name typically starts with "--"
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Option
+{
+ public static final String DEFAULT_STRING= "DEFAULT";
+
+ String name();
+
+ String[] aliases() default {};
+
+ String description() default "";
+
+ boolean required() default false;
+
+ boolean multiValued() default false;
+
+ String valueToShowInHelp() default DEFAULT_STRING;
+}
Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/DefaultActionPreparator.java Fri May 11 08:39:18 2012
@@ -18,20 +18,18 @@
*/
package org.apache.karaf.shell.commands.basic;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
-import java.util.*;
-import java.io.PrintStream;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import jline.Terminal;
+
+import org.apache.felix.service.command.CommandSession;
import org.apache.karaf.shell.commands.Action;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
@@ -40,76 +38,41 @@ import org.apache.karaf.shell.commands.H
import org.apache.karaf.shell.commands.Option;
import org.apache.karaf.shell.commands.converter.DefaultConverter;
import org.apache.karaf.shell.commands.converter.GenericType;
-import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
import org.apache.karaf.shell.console.NameScoping;
import org.fusesource.jansi.Ansi;
public class DefaultActionPreparator implements ActionPreparator {
public boolean prepare(Action action, CommandSession session, List<Object> params) throws Exception {
- Map<Option, Field> options = new HashMap<Option, Field>();
- Map<Argument, Field> arguments = new HashMap<Argument, Field>();
- List<Argument> orderedArguments = new ArrayList<Argument>();
- // Introspect
- for (Class type = action.getClass(); type != null; type = type.getSuperclass()) {
- for (Field field : type.getDeclaredFields()) {
- Option option = field.getAnnotation(Option.class);
- if (option != null) {
- options.put(option, field);
- }
- Argument argument = field.getAnnotation(Argument.class);
- if (argument != null) {
- if (Argument.DEFAULT.equals(argument.name())) {
- final Argument delegate = argument;
- final String name = field.getName();
- argument = new Argument() {
- public String name() {
- return name;
- }
-
- public String description() {
- return delegate.description();
- }
-
- public boolean required() {
- return delegate.required();
- }
-
- public int index() {
- return delegate.index();
- }
-
- public boolean multiValued() {
- return delegate.multiValued();
- }
-
- public String valueToShowInHelp() {
- return delegate.valueToShowInHelp();
- }
-
- public Class<? extends Annotation> annotationType() {
- return delegate.annotationType();
- }
- };
- }
- arguments.put(argument, field);
- int index = argument.index();
- while (orderedArguments.size() <= index) {
- orderedArguments.add(null);
- }
- if (orderedArguments.get(index) != null) {
- throw new IllegalArgumentException("Duplicate argument index: " + index);
- }
- orderedArguments.set(index, argument);
- }
- }
- }
- // Check indexes are correct
- for (int i = 0; i < orderedArguments.size(); i++) {
- if (orderedArguments.get(i) == null) {
- throw new IllegalArgumentException("Missing argument for index: " + i);
+ ActionMetaData actionMetaData = new ActionMetaDataFactory().create(action.getClass());
+ Map<Option, Field> options = actionMetaData.getOptions();
+ Map<Argument, Field> arguments = actionMetaData.getArguments();
+ List<Argument> orderedArguments = actionMetaData.getOrderedArguments();
+ Command command2 = actionMetaData.getCommand();
+ String commandErrorSt = (command2 != null) ? Ansi.ansi()
+ .fg(Ansi.Color.RED)
+ .a("Error executing command ")
+ .a(command2.scope())
+ .a(":")
+ .a(Ansi.Attribute.INTENSITY_BOLD)
+ .a(command2.name())
+ .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
+ .fg(Ansi.Color.DEFAULT)
+ .a(": ")
+ .toString() : "";
+ for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
+ Object param = it.next();
+ if (HelpOption.HELP.name().equals(param)) {
+ Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
+ int termWidth = term != null ? term.getWidth() : 80;
+ boolean globalScope = NameScoping.isGlobalScope(session, actionMetaData.getCommand().scope());
+ actionMetaData.printUsage(action, System.out, globalScope, termWidth);
+ return false;
}
}
+
// Populate
Map<Option, Object> optionValues = new HashMap<Option, Object>();
Map<Argument, Object> argumentValues = new HashMap<Argument, Object>();
@@ -117,11 +80,7 @@ public class DefaultActionPreparator imp
int argIndex = 0;
for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
Object param = it.next();
- // Check for help
- if (HelpOption.HELP.name().equals(param) || Arrays.asList(HelpOption.HELP.aliases()).contains(param)) {
- printUsage(session, action, options, arguments, System.out);
- return false;
- }
+
if (processOptions && param instanceof String && ((String) param).startsWith("-")) {
boolean isKeyValuePair = ((String) param).indexOf('=') != -1;
String name;
@@ -140,30 +99,16 @@ public class DefaultActionPreparator imp
}
}
if (option == null) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
+ throw new CommandException(commandErrorSt +
Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" undefined option ")
+ .a("undefined option ")
.a(Ansi.Attribute.INTENSITY_BOLD)
.a(param)
.a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .fg(Ansi.Color.DEFAULT)
.newline()
- .a("Try '" + command.scope() + ":" + command.name() + " --help' for more information.")
+ .a("Try <command> --help' for more information.")
.toString(),
- "Undefined option: " + param
- );
- } else {
- throw new CommandException("Undefined option: " + param);
- }
+ "Undefined option: " + param);
}
Field field = options.get(option);
if (value == null && (field.getType() == boolean.class || field.getType() == Boolean.class)) {
@@ -173,30 +118,13 @@ public class DefaultActionPreparator imp
value = it.next();
}
if (value == null) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
- Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" missing value for option ")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(param)
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ throw new CommandException(commandErrorSt +
+ Ansi.ansi().a("missing value for option ").bold().a(param).boldOff().toString(),
"Missing value for option: " + param
);
- } else {
- throw new CommandException("Missing value for option: " + param);
- }
}
if (option.multiValued()) {
+ @SuppressWarnings("unchecked")
List<Object> l = (List<Object>) optionValues.get(option);
if (l == null) {
l = new ArrayList<Object>();
@@ -209,31 +137,17 @@ public class DefaultActionPreparator imp
} else {
processOptions = false;
if (argIndex >= orderedArguments.size()) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
- Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(": too many arguments specified")
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ throw new CommandException(commandErrorSt +
+ Ansi.ansi().a("too many arguments specified").toString(),
"Too many arguments specified"
);
- } else {
- throw new CommandException("Too many arguments specified");
- }
}
Argument argument = orderedArguments.get(argIndex);
if (!argument.multiValued()) {
argIndex++;
}
if (argument.multiValued()) {
+ @SuppressWarnings("unchecked")
List<Object> l = (List<Object>) argumentValues.get(argument);
if (l == null) {
l = new ArrayList<Object>();
@@ -248,58 +162,21 @@ public class DefaultActionPreparator imp
// Check required arguments / options
for (Option option : options.keySet()) {
if (option.required() && optionValues.get(option) == null) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
- Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(": option ")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(option.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" is required")
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ throw new CommandException(commandErrorSt +
+ Ansi.ansi().a("option ").bold().a(option.name()).boldOff().a(" is required").toString(),
"Option " + option.name() + " is required"
);
- } else {
- throw new CommandException("Option " + option.name() + " is required");
- }
}
}
for (Argument argument : arguments.keySet()) {
if (argument.required() && argumentValues.get(argument) == null) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
- Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(": argument ")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(argument.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" is required")
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ throw new CommandException(commandErrorSt +
+ Ansi.ansi().a("argument ").bold().a(argument.name()).boldOff().a(" is required").toString(),
"Argument " + argument.name() + " is required"
);
- } else {
- throw new CommandException("Argument " + argument.name() + " is required");
- }
}
}
+
// Convert and inject values
for (Map.Entry<Option, Object> entry : optionValues.entrySet()) {
Field field = options.get(entry.getKey());
@@ -307,36 +184,13 @@ public class DefaultActionPreparator imp
try {
value = convert(action, session, entry.getValue(), field.getGenericType());
} catch (Exception e) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
- Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(": unable to convert option ")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(entry.getKey().name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" with value '")
- .a(entry.getValue())
- .a("' to type ")
- .a(new GenericType(field.getGenericType()).toString())
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ throw new CommandException(commandErrorSt +
+ Ansi.ansi().a("unable to convert option ").bold().a(entry.getKey().name()).boldOff().a(" with value '").a(entry.getValue()).a("' to type ")
+ .a(new GenericType(field.getGenericType()).toString()).toString(),
"Unable to convert option " + entry.getKey().name() + " with value '"
+ entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
e
);
- } else {
- throw new CommandException("Unable to convert option " + entry.getKey().name() + " with value '"
- + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
- e);
- }
}
field.setAccessible(true);
field.set(action, value);
@@ -347,36 +201,14 @@ public class DefaultActionPreparator imp
try {
value = convert(action, session, entry.getValue(), field.getGenericType());
} catch (Exception e) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- throw new CommandException(
+ throw new CommandException(commandErrorSt +
Ansi.ansi()
- .fg(Ansi.Color.RED)
- .a("Error executing command ")
- .a(command.scope())
- .a(":")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(command.name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(": unable to convert argument ")
- .a(Ansi.Attribute.INTENSITY_BOLD)
- .a(entry.getKey().name())
- .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
- .a(" with value '")
- .a(entry.getValue())
- .a("' to type ")
- .a(new GenericType(field.getGenericType()).toString())
- .fg(Ansi.Color.DEFAULT)
- .toString(),
+ .a("unable to convert argument ").bold().a(entry.getKey().name()).boldOff().a(" with value '").a(entry.getValue())
+ .a("' to type ").a(new GenericType(field.getGenericType()).toString()).toString(),
"Unable to convert argument " + entry.getKey().name() + " with value '"
+ entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
e
);
- } else {
- throw new CommandException("Unable to convert argument " + entry.getKey().name() + " with value '"
- + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
- e);
- }
}
field.setAccessible(true);
field.set(action, value);
@@ -384,199 +216,6 @@ public class DefaultActionPreparator imp
return true;
}
- protected void printUsage(CommandSession session, Action action, Map<Option, Field> optionsMap, Map<Argument, Field> argsMap, PrintStream out) {
- Command command = action.getClass().getAnnotation(Command.class);
- if (command != null) {
- Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
- List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
- Collections.sort(arguments, new Comparator<Argument>() {
- public int compare(Argument o1, Argument o2) {
- return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
- }
- });
- Set<Option> options = new HashSet<Option>(optionsMap.keySet());
- options.add(HelpOption.HELP);
- boolean globalScope = NameScoping.isGlobalScope(session, command.scope());
- if (command != null && (command.description() != null || command.name() != null)) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DESCRIPTION").a(Ansi.Attribute.RESET));
- out.print(" ");
- if (command.name() != null) {
- if (globalScope) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
- } else {
- out.println(Ansi.ansi().a(command.scope()).a(":").a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
- }
- out.println();
- }
- out.print("\t");
- out.println(command.description());
- out.println();
- }
- StringBuffer syntax = new StringBuffer();
- if (command != null) {
- if (globalScope) {
- syntax.append(command.name());
- } else {
- syntax.append(String.format("%s:%s", command.scope(), command.name()));
- }
- }
- if (options.size() > 0) {
- syntax.append(" [options]");
- }
- if (arguments.size() > 0) {
- syntax.append(' ');
- for (Argument argument : arguments) {
- if (!argument.required()) {
- syntax.append(String.format("[%s] ", argument.name()));
- } else {
- syntax.append(String.format("%s ", argument.name()));
- }
- }
- }
-
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SYNTAX").a(Ansi.Attribute.RESET));
- out.print(" ");
- out.println(syntax.toString());
- out.println();
- if (arguments.size() > 0) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("ARGUMENTS").a(Ansi.Attribute.RESET));
- for (Argument argument : arguments) {
- out.print(" ");
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(argument.name()).a(Ansi.Attribute.RESET));
- printFormatted(" ", argument.description(), term != null ? term.getWidth() : 80, out);
- if (!argument.required()) {
- if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
- try {
- if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
- argsMap.get(argument).setAccessible(true);
- Object o = argsMap.get(argument).get(action);
- printObjectDefaultsTo(out, o);
- } else {
- printDefaultsTo(out, argument.valueToShowInHelp());
- }
- } catch (Throwable t) {
- // Ignore
- }
- }
- }
- }
- out.println();
- }
- if (options.size() > 0) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("OPTIONS").a(Ansi.Attribute.RESET));
- for (Option option : options) {
- String opt = option.name();
- for (String alias : option.aliases()) {
- opt += ", " + alias;
- }
- out.print(" ");
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(opt).a(Ansi.Attribute.RESET));
- printFormatted(" ", option.description(), term != null ? term.getWidth() : 80, out);
- if (option.valueToShowInHelp() != null && option.valueToShowInHelp().length() != 0) {
- try {
- if (Option.DEFAULT_STRING.equals(option.valueToShowInHelp())) {
- optionsMap.get(option).setAccessible(true);
- Object o = optionsMap.get(option).get(action);
- printObjectDefaultsTo(out, o);
- } else {
- printDefaultsTo(out, option.valueToShowInHelp());
- }
- } catch (Throwable t) {
- // Ignore
- }
- }
- }
- out.println();
- }
- if (command.detailedDescription().length() > 0) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
- String desc = loadDescription(action.getClass(), command.detailedDescription());
- printFormatted(" ", desc, term != null ? term.getWidth() : 80, out);
- }
- }
- }
-
- private void printObjectDefaultsTo(PrintStream out, Object o) {
- if (o != null
- && (!(o instanceof Boolean) || ((Boolean) o))
- && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
- printDefaultsTo(out, o.toString());
- }
- }
-
- private void printDefaultsTo(PrintStream out, String value) {
- out.print(" (defaults to ");
- out.print(value);
- out.println(")");
- }
-
- protected String loadDescription(Class clazz, String desc) {
- if (desc.startsWith("classpath:")) {
- InputStream is = clazz.getResourceAsStream(desc.substring("classpath:".length()));
- if (is == null) {
- is = clazz.getClassLoader().getResourceAsStream(desc.substring("classpath:".length()));
- }
- if (is == null) {
- desc = "Unable to load description from " + desc;
- } else {
- try {
- Reader r = new InputStreamReader(is);
- StringWriter sw = new StringWriter();
- int c;
- while ((c = r.read()) != -1) {
- sw.append((char) c);
- }
- desc = sw.toString();
- } catch (IOException e) {
- desc = "Unable to load description from " + desc;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
- }
- return desc;
- }
-
- // TODO move this to a helper class?
- public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
- printFormatted(prefix, str, termWidth, out, true);
- }
-
- public static void printFormatted(String prefix, String str, int termWidth, PrintStream out, boolean prefixFirstLine) {
- int pfxLen = length(prefix);
- int maxwidth = termWidth - pfxLen;
- Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
- int cur = 0;
- while (cur >= 0) {
- int lst = str.indexOf('\n', cur);
- String s = (lst >= 0) ? str.substring(cur, lst) : str.substring(cur);
- if (s.length() == 0) {
- out.println();
- } else {
- Matcher m = wrap.matcher(s);
- while (m.find()) {
- if (cur > 0 || prefixFirstLine) {
- out.print(prefix);
- }
- out.println(m.group());
- }
- }
- if (lst >= 0) {
- cur = lst + 1;
- } else {
- break;
- }
- }
- }
-
- public static int length(String str) {
- return str.length();
- }
-
protected Object convert(Action action, CommandSession session, Object value, Type toType) throws Exception {
if (toType == String.class) {
return value != null ? value.toString() : null;
Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/basic/SimpleCommand.java Fri May 11 08:39:18 2012
@@ -63,18 +63,18 @@ public class SimpleCommand extends Abstr
}
- public static ServiceRegistration export(BundleContext context, Class<? extends Action> actionClass)
+ public static ServiceRegistration<Function> export(BundleContext context, Class<? extends Action> actionClass)
{
Command cmd = actionClass.getAnnotation(Command.class);
if (cmd == null)
{
throw new IllegalArgumentException("Action class is not annotated with @Command");
}
- Hashtable props = new Hashtable();
+ Hashtable<String, String> props = new Hashtable<String, String>();
props.put("bundles.command.scope", cmd.scope());
props.put("bundles.command.function", cmd.name());
SimpleCommand command = new SimpleCommand(actionClass);
- return context.registerService(Function.class.getName(), command, props);
+ return context.registerService(Function.class, command, props);
}
}
Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaData.java Fri May 11 08:39:18 2012
@@ -0,0 +1,196 @@
+package org.apache.karaf.shell.commands.meta;
+
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.shell.commands.Action;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.HelpOption;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.util.IndentFormatter;
+import org.apache.karaf.shell.util.ShellUtil;
+import org.fusesource.jansi.Ansi;
+
+public class ActionMetaData {
+ private final Class<? extends Action> actionClass;
+ private final Command command;
+ private final Map<Option, Field> options;
+ private final Map<Argument, Field> arguments;
+ List<Argument> orderedArguments;
+ private final Completer[] completers;
+
+ public ActionMetaData(Class<? extends Action> actionClass, Command command, Map<Option, Field> options, Map<Argument, Field> args,
+ List<Argument> orderedArguments, Completer[] completers) {
+ super();
+ this.actionClass = actionClass;
+ this.command = command;
+ this.options = options;
+ this.arguments = args;
+ this.orderedArguments = orderedArguments;
+ this.completers = completers;
+ }
+
+ public Class<? extends Action> getActionClass() {
+ return actionClass;
+ }
+
+ public Command getCommand() {
+ return command;
+ }
+
+ public Map<Option, Field> getOptions() {
+ return options;
+ }
+
+ public Map<Argument, Field> getArguments() {
+ return arguments;
+ }
+
+ public Completer[] getCompleters() {
+ return completers;
+ }
+
+ public List<Argument> getOrderedArguments() {
+ return orderedArguments;
+ }
+
+ public void printUsage(Action action, PrintStream out, boolean globalScope, int termWidth) {
+ if (command != null) {
+ List<Argument> argumentsSet = new ArrayList<Argument>(arguments.keySet());
+ Collections.sort(argumentsSet, new Comparator<Argument>() {
+ public int compare(Argument o1, Argument o2) {
+ return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+ }
+ });
+ Set<Option> optionsSet = new HashSet<Option>(options.keySet());
+ optionsSet.add(HelpOption.HELP);
+ if (command != null && (command.description() != null || command.name() != null)) {
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DESCRIPTION").a(Ansi.Attribute.RESET));
+ out.print(" ");
+ if (command.name() != null) {
+ if (globalScope) {
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
+ } else {
+ out.println(Ansi.ansi().a(command.scope()).a(":").a(Ansi.Attribute.INTENSITY_BOLD).a(command.name()).a(Ansi.Attribute.RESET));
+ }
+ out.println();
+ }
+ out.print("\t");
+ out.println(command.description());
+ out.println();
+ }
+ StringBuffer syntax = new StringBuffer();
+ if (command != null) {
+ if (globalScope) {
+ syntax.append(command.name());
+ } else {
+ syntax.append(String.format("%s:%s", command.scope(), command.name()));
+ }
+ }
+ if (options.size() > 0) {
+ syntax.append(" [options]");
+ }
+ if (arguments.size() > 0) {
+ syntax.append(' ');
+ for (Argument argument : argumentsSet) {
+ if (!argument.required()) {
+ syntax.append(String.format("[%s] ", argument.name()));
+ } else {
+ syntax.append(String.format("%s ", argument.name()));
+ }
+ }
+ }
+
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SYNTAX").a(Ansi.Attribute.RESET));
+ out.print(" ");
+ out.println(syntax.toString());
+ out.println();
+ if (arguments.size() > 0) {
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("ARGUMENTS").a(Ansi.Attribute.RESET));
+ for (Argument argument : argumentsSet) {
+ out.print(" ");
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(argument.name()).a(Ansi.Attribute.RESET));
+ IndentFormatter.printFormatted(" ", argument.description(), termWidth, out);
+ if (!argument.required()) {
+ if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
+ try {
+ if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
+ arguments.get(argument).setAccessible(true);
+ Object o = arguments.get(argument).get(action);
+ printObjectDefaultsTo(out, o);
+ } else {
+ printDefaultsTo(out, argument.valueToShowInHelp());
+ }
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+ }
+ out.println();
+ }
+ if (options.size() > 0) {
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("OPTIONS").a(Ansi.Attribute.RESET));
+ for (Option option : optionsSet) {
+ String opt = option.name();
+ for (String alias : option.aliases()) {
+ opt += ", " + alias;
+ }
+ out.print(" ");
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(opt).a(Ansi.Attribute.RESET));
+ IndentFormatter.printFormatted(" ", option.description(), termWidth, out);
+ if (option.valueToShowInHelp() != null && option.valueToShowInHelp().length() != 0) {
+ try {
+ if (Option.DEFAULT_STRING.equals(option.valueToShowInHelp())) {
+ options.get(option).setAccessible(true);
+ Object o = options.get(option).get(action);
+ printObjectDefaultsTo(out, o);
+ } else {
+ printDefaultsTo(out, option.valueToShowInHelp());
+ }
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+ out.println();
+ }
+ if (command.detailedDescription().length() > 0) {
+ out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
+ String desc = loadDescription(actionClass, command.detailedDescription());
+ IndentFormatter.printFormatted(" ", desc, termWidth, out);
+ }
+ }
+ }
+
+ private String loadDescription(Class clazz, String desc) {
+ if (desc.startsWith("classpath:")) {
+ desc = ShellUtil.loadClassPathResource(clazz, desc.substring("classpath:".length()));
+ }
+ return desc;
+ }
+
+ private void printObjectDefaultsTo(PrintStream out, Object o) {
+ if (o != null
+ && (!(o instanceof Boolean) || ((Boolean) o))
+ && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
+ printDefaultsTo(out, o.toString());
+ }
+ }
+
+ private void printDefaultsTo(PrintStream out, String value) {
+ out.print(" (defaults to ");
+ out.print(value);
+ out.println(")");
+ }
+
+}
Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/commands/meta/ActionMetaDataFactory.java Fri May 11 08:39:18 2012
@@ -0,0 +1,232 @@
+package org.apache.karaf.shell.commands.meta;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.karaf.shell.commands.Action;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+public class ActionMetaDataFactory {
+ public ActionMetaData create(Class<? extends Action> actionClass) {
+ Command command = getCommand(actionClass);
+ Map<Option, Field> options = new HashMap<Option, Field>();
+ Map<Argument, Field> arguments = new HashMap<Argument, Field>();
+ List<Argument> orderedArguments = new ArrayList<Argument>();
+
+ for (Class<?> type = actionClass; type != null; type = type.getSuperclass()) {
+ for (Field field : type.getDeclaredFields()) {
+ Option option = field.getAnnotation(Option.class);
+ if (option == null) {
+ option = getAndConvertDeprecatedOption(field);
+ }
+ if (option != null) {
+ options.put(option, field);
+ }
+
+ Argument argument = field.getAnnotation(Argument.class);
+ if (argument == null) {
+ argument = getAndConvertDeprecatedArgument(field);
+ }
+ if (argument != null) {
+ argument = replaceDefaultArgument(field, argument);
+ arguments.put(argument, field);
+ int index = argument.index();
+ while (orderedArguments.size() <= index) {
+ orderedArguments.add(null);
+ }
+ if (orderedArguments.get(index) != null) {
+ throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + actionClass.getName());
+ }
+ orderedArguments.set(index, argument);
+ }
+ }
+ }
+ assertIndexesAreCorrect(actionClass, orderedArguments);
+
+ return new ActionMetaData(actionClass, command, options, arguments, orderedArguments, null);
+ }
+
+ public Command getCommand(Class<? extends Action> actionClass) {
+ Command command = actionClass.getAnnotation(Command.class);
+ if (command == null) {
+ command = getAndConvertDeprecatedCommand(actionClass);
+ }
+ return command;
+ }
+
+ @SuppressWarnings("deprecation")
+ public Command getAndConvertDeprecatedCommand(Class<? extends Action> actionClass) {
+ final org.apache.felix.gogo.commands.Command oldCommand = actionClass.getAnnotation(org.apache.felix.gogo.commands.Command.class);
+ if (oldCommand == null) {
+ return null;
+ }
+ return new Command() {
+
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return Command.class;
+ }
+
+ @Override
+ public String scope() {
+ return oldCommand.scope();
+ }
+
+ @Override
+ public String name() {
+ return oldCommand.name();
+ }
+
+ @Override
+ public String detailedDescription() {
+ return oldCommand.detailedDescription();
+ }
+
+ @Override
+ public String description() {
+ return oldCommand.description();
+ }
+ };
+ }
+
+ @SuppressWarnings("deprecation")
+ private Option getAndConvertDeprecatedOption(Field field) {
+ final org.apache.felix.gogo.commands.Option oldOption = field.getAnnotation(org.apache.felix.gogo.commands.Option.class);
+ if (oldOption == null) {
+ return null;
+ }
+ return new Option() {
+
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return Option.class;
+ }
+
+ @Override
+ public String valueToShowInHelp() {
+ return oldOption.valueToShowInHelp();
+ }
+
+ @Override
+ public boolean required() {
+ return oldOption.required();
+ }
+
+ @Override
+ public String name() {
+ return oldOption.name();
+ }
+
+ @Override
+ public boolean multiValued() {
+ return oldOption.multiValued();
+ }
+
+ @Override
+ public String description() {
+ return oldOption.description();
+ }
+
+ @Override
+ public String[] aliases() {
+ return oldOption.aliases();
+ }
+ };
+ }
+
+ @SuppressWarnings("deprecation")
+ private Argument getAndConvertDeprecatedArgument(Field field) {
+ final org.apache.felix.gogo.commands.Argument oldArgument = field.getAnnotation(org.apache.felix.gogo.commands.Argument.class);
+ if (oldArgument == null) {
+ return null;
+ }
+ return new Argument() {
+
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return Argument.class;
+ }
+
+ @Override
+ public String valueToShowInHelp() {
+ return oldArgument.valueToShowInHelp();
+ }
+
+ @Override
+ public boolean required() {
+ return oldArgument.required();
+ }
+
+ @Override
+ public String name() {
+ return oldArgument.name();
+ }
+
+ @Override
+ public boolean multiValued() {
+ return oldArgument.multiValued();
+ }
+
+ @Override
+ public int index() {
+ return oldArgument.index();
+ }
+
+ @Override
+ public String description() {
+ return oldArgument.description();
+ }
+ };
+ }
+
+ private Argument replaceDefaultArgument(Field field, Argument argument) {
+ if (Argument.DEFAULT.equals(argument.name())) {
+ final Argument delegate = argument;
+ final String name = field.getName();
+ argument = new Argument() {
+ public String name() {
+ return name;
+ }
+
+ public String description() {
+ return delegate.description();
+ }
+
+ public boolean required() {
+ return delegate.required();
+ }
+
+ public int index() {
+ return delegate.index();
+ }
+
+ public boolean multiValued() {
+ return delegate.multiValued();
+ }
+
+ public String valueToShowInHelp() {
+ return delegate.valueToShowInHelp();
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return delegate.annotationType();
+ }
+ };
+ }
+ return argument;
+ }
+
+ private void assertIndexesAreCorrect(Class<? extends Action> actionClass, List<Argument> orderedArguments) {
+ for (int i = 0; i < orderedArguments.size(); i++) {
+ if (orderedArguments.get(i) == null) {
+ throw new IllegalArgumentException("Missing argument for index: " + i + " on Action " + actionClass.getName());
+ }
+ }
+ }
+}
Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/commands/BlueprintCommand.java Fri May 11 08:39:18 2012
@@ -21,11 +21,11 @@ import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
+import org.apache.felix.service.command.CommandSession;
import org.apache.karaf.shell.commands.Action;
import org.apache.karaf.shell.commands.basic.AbstractCommand;
import org.apache.karaf.shell.commands.basic.ActionPreparator;
import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
-import org.apache.felix.service.command.CommandSession;
import org.apache.karaf.shell.console.BlueprintContainerAware;
import org.apache.karaf.shell.console.BundleContextAware;
import org.apache.karaf.shell.console.CompletableFunction;
Added: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java?rev=1337063&view=auto
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java (added)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/IndentFormatter.java Fri May 11 08:39:18 2012
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.karaf.shell.util;
+
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class IndentFormatter {
+
+ public static void printFormatted(String prefix, String str, int termWidth, PrintStream out, boolean prefixFirstLine) {
+ int pfxLen = prefix.length();
+ int maxwidth = termWidth - pfxLen;
+ Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
+ int cur = 0;
+ while (cur >= 0) {
+ int lst = str.indexOf('\n', cur);
+ String s = (lst >= 0) ? str.substring(cur, lst) : str.substring(cur);
+ if (s.length() == 0) {
+ out.println();
+ } else {
+ Matcher m = wrap.matcher(s);
+ while (m.find()) {
+ if (cur > 0 || prefixFirstLine) {
+ out.print(prefix);
+ }
+ out.println(m.group());
+ }
+ }
+ if (lst >= 0) {
+ cur = lst + 1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
+ printFormatted(prefix, str, termWidth, out, true);
+ }
+
+}
Modified: karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java (original)
+++ karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java Fri May 11 08:39:18 2012
@@ -19,6 +19,10 @@
package org.apache.karaf.shell.util;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -181,4 +185,32 @@ public class ShellUtil {
}
}
+ public static String loadClassPathResource(Class<?> clazz, String path) {
+ InputStream is = clazz.getResourceAsStream(path);
+ if (is == null) {
+ is = clazz.getClassLoader().getResourceAsStream(path);
+ }
+ if (is == null) {
+ return "Unable to load description from " + path;
+ }
+
+ try {
+ Reader r = new InputStreamReader(is);
+ StringWriter sw = new StringWriter();
+ int c;
+ while ((c = r.read()) != -1) {
+ sw.append((char) c);
+ }
+ return sw.toString();
+ } catch (IOException e) {
+ return "Unable to load description from " + path;
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
}
Copied: karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java (from r1336532, karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java)
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java?p2=karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java&p1=karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java&r1=1336532&r2=1337063&rev=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/console/help/TestFormatting.java (original)
+++ karaf/trunk/shell/console/src/test/java/org/apache/karaf/shell/util/TestFormatting.java Fri May 11 08:39:18 2012
@@ -16,19 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.karaf.shell.console.help;
+package org.apache.karaf.shell.util;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import junit.framework.TestCase;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
+
+import org.apache.karaf.shell.util.IndentFormatter;
public class TestFormatting extends TestCase {
public void testFormat() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DefaultActionPreparator.printFormatted(" ",
+ IndentFormatter.printFormatted(" ",
" This is a test with a long paragraph\n\n with an indented paragraph\nAnd another one\n", 20, new PrintStream(baos, true));
System.err.println(baos.toString());
}
Modified: karaf/trunk/shell/help/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/pom.xml?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/pom.xml (original)
+++ karaf/trunk/shell/help/pom.xml Fri May 11 08:39:18 2012
@@ -45,6 +45,10 @@
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.table</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
<dependency>
Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/CommandListHelpProvider.java Fri May 11 08:39:18 2012
@@ -20,22 +20,24 @@ package org.apache.karaf.shell.help.impl
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import jline.Terminal;
+
import org.apache.felix.gogo.runtime.CommandSessionImpl;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Function;
import org.apache.karaf.shell.commands.Action;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.basic.AbstractCommand;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
+import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
import org.apache.karaf.shell.console.HelpProvider;
import org.apache.karaf.shell.console.NameScoping;
+import org.apache.karaf.shell.table.Col;
+import org.apache.karaf.shell.table.ShellTable;
import org.fusesource.jansi.Ansi;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -68,11 +70,8 @@ public class CommandListHelpProvider imp
function = unProxy(function);
if (function instanceof AbstractCommand) {
try {
- Method mth = AbstractCommand.class.getDeclaredMethod("createNewAction");
- mth.setAccessible(true);
- Action action = (Action) mth.invoke(function);
- Class<? extends Action> clazz = action.getClass();
- Command ann = clazz.getAnnotation(Command.class);
+ Class<? extends Action> actionClass = ((AbstractCommand) function).getActionClass();
+ Command ann = new ActionMetaDataFactory().getCommand(actionClass);
description = ann.description();
} catch (Throwable e) {
}
@@ -87,43 +86,16 @@ public class CommandListHelpProvider imp
protected void printMethodList(CommandSession session, PrintStream out, SortedMap<String, String> commands) {
Terminal term = (Terminal) session.get(".jline.terminal");
+ int termWidth = term != null ? term.getWidth() : 80;
out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("COMMANDS").a(Ansi.Attribute.RESET));
- int max = 0;
+ ShellTable table = new ShellTable().noHeaders().separator(" ").size(termWidth);
+ table.column(new Col("Command").maxSize(35));
+ table.column(new Col("Description"));
for (Map.Entry<String,String> entry : commands.entrySet()) {
String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
- max = Math.max(max,key.length());
- }
- int margin = 4;
- String prefix1 = " ";
- if (term != null && term.getWidth() - max - prefix1.length() - margin > 50) {
- String prefix2 = prefix1;
- for (int i = 0; i < max + margin; i++) {
- prefix2 += " ";
- }
- for (Map.Entry<String,String> entry : commands.entrySet()) {
- out.print(prefix1);
- String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
- out.print(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
- for (int i = 0; i < max - key.length() + margin; i++) {
- out.print(' ');
- }
- if (entry.getValue() != null) {
- DefaultActionPreparator.printFormatted(prefix2, entry.getValue(), term.getWidth(), out, false);
- }
- }
- } else {
- String prefix2 = prefix1 + prefix1;
- for (Map.Entry<String,String> entry : commands.entrySet()) {
- out.print(prefix1);
- String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
- if (entry.getValue() != null) {
- DefaultActionPreparator.printFormatted(prefix2, entry.getValue(),
- term != null ? term.getWidth() : 80, out);
- }
- }
+ table.addRow().addContent(key, entry.getValue());
}
- out.println();
+ table.print(out);
}
protected Function unProxy(Function function) {
Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/HelpAction.java Fri May 11 08:39:18 2012
@@ -17,34 +17,9 @@
*/
package org.apache.karaf.shell.help.impl;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import jline.Terminal;
-import org.apache.felix.service.command.Function;
-import org.apache.karaf.shell.commands.Action;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.basic.AbstractCommand;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
import org.apache.karaf.shell.console.AbstractAction;
-import org.apache.karaf.shell.console.NameScoping;
-import org.apache.karaf.shell.console.SubShell;
-import org.fusesource.jansi.Ansi;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
/**
* Displays help on the available commands
@@ -69,122 +44,4 @@ public class HelpAction extends Abstract
return null;
}
- private SortedMap<String, String> getCommandDescriptions(Set<String> names) {
- SortedMap<String,String> commands = new TreeMap<String,String>();
- for (String name : names) {
- if (command != null && !name.startsWith(command)) {
- continue;
- }
- String description = null;
- Function function = (Function) session.get(name);
- function = unProxy(function);
- if (function instanceof AbstractCommand) {
- try {
- Method mth = AbstractCommand.class.getDeclaredMethod("createNewAction");
- mth.setAccessible(true);
- Action action = (Action) mth.invoke(function);
- Class<? extends Action> clazz = action.getClass();
- Command ann = clazz.getAnnotation(Command.class);
- description = ann.description();
- } catch (Throwable e) {
- }
- if (name.startsWith("*:")) {
- name = name.substring(2);
- }
- commands.put(name, description);
- }
- }
- return commands;
- }
-
- private void printMethodList(Terminal term, PrintStream out, SortedMap<String, String> commands) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("COMMANDS").a(Ansi.Attribute.RESET));
-// int max = 0;
-// for (Map.Entry<String,String> entry : commands.entrySet()) {
-// String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
-// max = Math.max(max,key.length());
-// }
- for (Map.Entry<String,String> entry : commands.entrySet()) {
- out.print(" ");
- String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(key).a(Ansi.Attribute.RESET));
- if (entry.getValue() != null) {
- DefaultActionPreparator.printFormatted(" ", entry.getValue(),
- term != null ? term.getWidth() : 80, out);
- }
- }
- out.println();
- }
-
- private void printSubShellHelp(Bundle bundle, SubShell subShell, PrintStream out) {
- Terminal term = session != null ? (Terminal) session.get(".jline.terminal") : null;
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("SUBSHELL").a(Ansi.Attribute.RESET));
- out.print(" ");
- if (subShell.getName() != null) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(subShell.getName()).a(Ansi.Attribute.RESET));
- out.println();
- }
- out.print("\t");
- out.println(subShell.getDescription());
- out.println();
- if (subShell.getDetailedDescription() != null) {
- out.println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("DETAILS").a(Ansi.Attribute.RESET));
- String desc = loadDescription(bundle, subShell.getDetailedDescription());
- DefaultActionPreparator.printFormatted(" ", desc, term != null ? term.getWidth() : 80, out);
- }
- }
-
- protected String loadDescription(Bundle bundle, String desc) {
- if (desc.startsWith("classpath:")) {
- URL url = bundle.getResource(desc.substring("classpath:".length()));
- if (url == null) {
- desc = "Unable to load description from " + desc;
- } else {
- InputStream is = null;
- try {
- is = url.openStream();
- Reader r = new InputStreamReader(is);
- StringWriter sw = new StringWriter();
- int c;
- while ((c = r.read()) != -1) {
- sw.append((char) c);
- }
- desc = sw.toString();
- } catch (IOException e) {
- desc = "Unable to load description from " + desc;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }
- }
- return desc;
- }
-
- protected Function unProxy(Function function) {
- try {
- if (function.getClass().getName().contains("CommandProxy")) {
- Field contextField = function.getClass().getDeclaredField("context");
- Field referenceField = function.getClass().getDeclaredField("reference");
- contextField.setAccessible(true);
- referenceField.setAccessible(true);
- BundleContext context = (BundleContext) contextField.get(function);
- ServiceReference reference = (ServiceReference) referenceField.get(function);
- Object target = context.getService(reference);
- try {
- if (target instanceof Function) {
- function = (Function) target;
- }
- } finally {
- context.ungetService(reference);
- }
- }
- } catch (Throwable t) {
- }
- return function;
- }
-
}
Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SimpleHelpProvider.java Fri May 11 08:39:18 2012
@@ -17,13 +17,9 @@
*/
package org.apache.karaf.shell.help.impl;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
import java.util.Map;
-import jline.Terminal;
import org.apache.felix.service.command.CommandSession;
-import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
import org.apache.karaf.shell.console.HelpProvider;
public class SimpleHelpProvider implements HelpProvider {
@@ -47,12 +43,6 @@ public class SimpleHelpProvider implemen
}
}
String str = help.get(path);
- if (str != null) {
- Terminal term = (Terminal) session.get(".jline.terminal");
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DefaultActionPreparator.printFormatted("", str, term != null ? term.getWidth() : 80, new PrintStream(baos, true));
- str = baos.toString();
- }
return str;
}
}
Modified: karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java?rev=1337063&r1=1337062&r2=1337063&view=diff
==============================================================================
--- karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java (original)
+++ karaf/trunk/shell/help/src/main/java/org/apache/karaf/shell/help/impl/SubShellHelpProvider.java Fri May 11 08:39:18 2012
@@ -27,10 +27,12 @@ import java.io.StringWriter;
import java.net.URL;
import jline.Terminal;
+
import org.apache.felix.service.command.CommandSession;
import org.apache.karaf.shell.commands.basic.DefaultActionPreparator;
import org.apache.karaf.shell.console.HelpProvider;
import org.apache.karaf.shell.console.SubShell;
+import org.apache.karaf.shell.util.IndentFormatter;
import org.fusesource.jansi.Ansi;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -90,7 +92,7 @@ public class SubShellHelpProvider implem
while (desc.endsWith("\n")) {
desc = desc.substring(0, desc.length() -1);
}
- DefaultActionPreparator.printFormatted(" ", desc, term != null ? term.getWidth() : 80, out);
+ IndentFormatter.printFormatted(" ", desc, term != null ? term.getWidth() : 80, out);
}
out.println();
out.println("${command-list|" + subShell.getName() + ":}");