You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/03/25 09:31:14 UTC
[2/3] karaf git commit: [KARAF-3633] Help mechanism improvements
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/scr/examples/managed-service/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/scr/examples/managed-service/src/main/resources/OSGI-INF/bundle.info b/scr/examples/managed-service/src/main/resources/OSGI-INF/bundle.info
index 6d72846..eae4f9f 100644
--- a/scr/examples/managed-service/src/main/resources/OSGI-INF/bundle.info
+++ b/scr/examples/managed-service/src/main/resources/OSGI-INF/bundle.info
@@ -1,4 +1,22 @@
-\u001B[1mSYNOPSIS\u001B[0m
+#
+#
+# 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.
+#
+#
+h1. SYNOPSIS
${project.name}
${project.description}
@@ -6,5 +24,5 @@
Maven URL:
\u001B[33mmvn:${project.groupId}/${project.artifactId}/${project.version}\u001B[0m
-\u001B[1mDESCRIPTION\u001B[0m
+h1. DESCRIPTION
An SCR example project for Managed Services.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/scr/examples/service/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/scr/examples/service/src/main/resources/OSGI-INF/bundle.info b/scr/examples/service/src/main/resources/OSGI-INF/bundle.info
index 2d76175..8b9e24c 100644
--- a/scr/examples/service/src/main/resources/OSGI-INF/bundle.info
+++ b/scr/examples/service/src/main/resources/OSGI-INF/bundle.info
@@ -1,4 +1,22 @@
-\u001B[1mSYNOPSIS\u001B[0m
+#
+#
+# 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.
+#
+#
+h1. SYNOPSIS
${project.name}
${project.description}
@@ -6,5 +24,5 @@
Maven URL:
\u001B[33mmvn:${project.groupId}/${project.artifactId}/${project.version}\u001B[0m
-\u001B[1mDESCRIPTION\u001B[0m
+h1. DESCRIPTION
An SCR example project for basic Services and Components.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/scr/management/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/scr/management/src/main/resources/OSGI-INF/bundle.info b/scr/management/src/main/resources/OSGI-INF/bundle.info
index e8eba83..bc3c130 100644
--- a/scr/management/src/main/resources/OSGI-INF/bundle.info
+++ b/scr/management/src/main/resources/OSGI-INF/bundle.info
@@ -1,4 +1,22 @@
-\u001B[1mSYNOPSIS\u001B[0m
+#
+#
+# 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.
+#
+#
+h1. SYNOPSIS
${project.name}
${project.description}
@@ -6,7 +24,7 @@
Maven URL:
\u001B[33mmvn:${project.groupId}/${project.artifactId}/${project.version}\u001B[0m
-\u001B[1mDESCRIPTION\u001B[0m
+h1. DESCRIPTION
This bundle provide MBean to manage Declarative Service Components in Karaf features via JMX.
Especially, it provides the ScrServiceMBean supporting the following operations:
@@ -16,5 +34,5 @@
\u001B[36misComponentActive(String)\u001B[0m Check to see if a given component is in an ACTIVE state.
-\u001B[1mSEE ALSO\u001B[0m
+h1. SEE ALSO
\u001B[36mDeclarative Services\u001B[0m and \u001B[Remote Management via JMX\u001B[0m sections of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/service/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/service/core/src/main/resources/OSGI-INF/bundle.info b/service/core/src/main/resources/OSGI-INF/bundle.info
index 3fde000..27fc917 100644
--- a/service/core/src/main/resources/OSGI-INF/bundle.info
+++ b/service/core/src/main/resources/OSGI-INF/bundle.info
@@ -1,19 +1,42 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-The services mbean management bundle exposes a Services MBean that can be used with any JMX client (for instance JConsole).
+ The services mbean management bundle exposes a Services MBean that can be used with any JMX client (for instance JConsole).
-The Services MBean allows quite the same action that can be performed using services:* commands:
- * list()
+ The Services MBean allows quite the same action that can be performed using services:* commands:
+ * list()
+
+h1. Commands
+
+ The bundle contains the following commands:
+\${command-list|service|indent=8,list,cyan}
h1. See also
- * Monitoring and Administration using JMX - section of the Karaf User Guide
+ * Monitoring and Administration using JMX - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/service/guard/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/service/guard/src/main/resources/OSGI-INF/bundle.info b/service/guard/src/main/resources/OSGI-INF/bundle.info
index be2ec64..6f69b56 100644
--- a/service/guard/src/main/resources/OSGI-INF/bundle.info
+++ b/service/guard/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/commands/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/shell/commands/src/main/resources/OSGI-INF/bundle.info b/shell/commands/src/main/resources/OSGI-INF/bundle.info
index 873370f..8b16f30 100644
--- a/shell/commands/src/main/resources/OSGI-INF/bundle.info
+++ b/shell/commands/src/main/resources/OSGI-INF/bundle.info
@@ -1,39 +1,39 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-This bundle provides various shell commands.
-
-The following commands are available:
-* shell:cat - Displays the content of a file or url.
-* shell:clear - Clears the console buffer.
-* shell:date - Display the current time in the given FORMAT
-* shell:each - Execute a closure on a list of arguments.
-* shell:echo - Echoes or prints arguments to STDOUT.
-* shell:exec - Executes system processes.
-* shell:grep - Prints lines matching the given pattern.
-* shell:head - Displays the first lines of a file.
-* shell:history - Prints command history.
-* shell:if - If/Then/Else block.
-* shell:info - Prints system information.
-* shell:java - Executes a Java standard application.
-* shell:logout - Disconnects shell from current session.
-* shell:more - File pager.
-* shell:new - Creates a new java object.
-* shell:printf - Formats and prints arguments.
-* shell:sleep - Sleeps for a bit then wakes up.
-* shell:sort - Writes sorted concatenation of all files to standard output.
-* shell:tac - Captures the STDIN and returns it as a string. Optionally writes the content to a file.
-* shell:tail - Displays the last lines of a file.
-* shell:wc - Print newline, word, and byte counts for each file.
+ This bundle provides various shell commands.
+
+h1. Commands
+
+ The following commands are available:
+\${command-list|dev|indent=8,list,cyan}
h1. See also
-Commands - and Using the console - sections of the Karaf User Guide.
\ No newline at end of file
+ Commands - and Using the console - sections of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/console/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/shell/console/src/main/resources/OSGI-INF/bundle.info b/shell/console/src/main/resources/OSGI-INF/bundle.info
index 23fcee4..93a9994 100644
--- a/shell/console/src/main/resources/OSGI-INF/bundle.info
+++ b/shell/console/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/pom.xml
----------------------------------------------------------------------
diff --git a/shell/core/pom.xml b/shell/core/pom.xml
index 75a88c0..89f95f8 100644
--- a/shell/core/pom.xml
+++ b/shell/core/pom.xml
@@ -140,6 +140,7 @@
<Private-Package>
org.apache.karaf.service.guard.tools,
org.apache.karaf.shell.impl.*,
+ org.apache.karaf.util,
org.apache.karaf.util.jaas,
org.apache.karaf.util.tracker,
org.apache.felix.utils.properties,
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/SubShellCommand.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/SubShellCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/SubShellCommand.java
index d2826f3..1dc46a9 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/SubShellCommand.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/SubShellCommand.java
@@ -18,9 +18,12 @@
*/
package org.apache.karaf.shell.impl.console.commands;
+import java.io.PrintStream;
+import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.impl.console.commands.help.HelpCommand;
public class SubShellCommand extends TopLevelCommand {
@@ -55,4 +58,12 @@ public class SubShellCommand extends TopLevelCommand {
session.put(Session.SCOPE, name + ":" + session.get(Session.SCOPE));
}
+ @Override
+ protected void printHelp(Session session, PrintStream out) {
+ try {
+ new HelpCommand(session.getFactory()).execute(session, Arrays.<Object>asList("shell|" + name));
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to print subshell help", e);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/TopLevelCommand.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/TopLevelCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/TopLevelCommand.java
index 1f52fbe..2a5620a 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/TopLevelCommand.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/TopLevelCommand.java
@@ -53,7 +53,7 @@ public abstract class TopLevelCommand implements Command {
@Override
public Object execute(Session session, List<Object> arguments) throws Exception {
if (arguments.contains("--help")) {
- printHelp(System.out);
+ printHelp(session, System.out);
return null;
}
if (!arguments.isEmpty()) {
@@ -67,7 +67,7 @@ public abstract class TopLevelCommand implements Command {
return null;
}
- protected void printHelp(PrintStream out) {
+ protected void printHelp(Session session, PrintStream out) {
out.println(INTENSITY_BOLD + "DESCRIPTION" + INTENSITY_NORMAL);
out.print(" ");
out.println(INTENSITY_BOLD + getName() + INTENSITY_NORMAL);
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/BundleHelpProvider.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/BundleHelpProvider.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/BundleHelpProvider.java
new file mode 100644
index 0000000..79a8f12
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/BundleHelpProvider.java
@@ -0,0 +1,80 @@
+/**
+ *
+ * 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.impl.console.commands.help;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.URL;
+
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.console.Terminal;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.AnsiPrintingWikiVisitor;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.WikiParser;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.WikiVisitor;
+import org.apache.karaf.shell.support.ShellUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class BundleHelpProvider implements HelpProvider {
+
+ @Override
+ public String getHelp(Session session, String path) {
+ if (path.indexOf('|') > 0) {
+ if (path.startsWith("bundle|")) {
+ path = path.substring("bundle|".length());
+ } else {
+ return null;
+ }
+ }
+
+ if (path.matches("[0-9]*")) {
+ long id = Long.parseLong(path);
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ Bundle bundle = bundleContext.getBundle(id);
+ if (bundle != null) {
+ String title = ShellUtil.getBundleName(bundle);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ ps.println("\n" + title);
+ ps.println(ShellUtil.getUnderlineString(title));
+ URL bundleInfo = bundle.getEntry("OSGI-INF/bundle.info");
+ if (bundleInfo != null) {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(bundleInfo.openStream()))) {
+ int maxSize = 80;
+ Terminal terminal = session.getTerminal();
+ if (terminal != null) {
+ maxSize = terminal.getWidth();
+ }
+ WikiVisitor visitor = new AnsiPrintingWikiVisitor(ps, maxSize);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(reader);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ ps.close();
+ return baos.toString();
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandListHelpProvider.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandListHelpProvider.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandListHelpProvider.java
index 2c2a1b3..6612402 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandListHelpProvider.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandListHelpProvider.java
@@ -19,8 +19,12 @@ package org.apache.karaf.shell.impl.console.commands.help;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -28,33 +32,55 @@ import org.apache.karaf.shell.api.console.Command;
import org.apache.karaf.shell.api.console.Session;
import org.apache.karaf.shell.api.console.Terminal;
import org.apache.karaf.shell.support.NameScoping;
-import org.apache.karaf.shell.support.ansi.SimpleAnsi;
import org.apache.karaf.shell.support.table.Col;
import org.apache.karaf.shell.support.table.ShellTable;
public class CommandListHelpProvider implements HelpProvider {
public String getHelp(Session session, String path) {
+ String mode = "raw";
if (path.indexOf('|') > 0) {
if (path.startsWith("command-list|")) {
path = path.substring("command-list|".length());
+ if (path.indexOf('|') > 0) {
+ mode = path.substring(path.indexOf('|') + 1);
+ path = path.substring(0, path.indexOf('|'));
+ }
} else {
return null;
}
+ } else {
+ return null;
+ }
+
+ // Retrieve matching commands
+ Set<Command> commands = getCommands(session, path);
+ SortedMap<String,String> descriptions = new TreeMap<>();
+ for (Command command : commands) {
+ String subshell = (String) session.get(Session.SUBSHELL);
+ String name = command.getScope() + ":" + command.getName();
+ String description = command.getDescription();
+ if (name.startsWith("*:")) {
+ name = name.substring(2);
+ }
+ if (subshell != null && !subshell.trim().isEmpty() && name.startsWith(subshell + ":")) {
+ name = name.substring(subshell.length() + 1);
+ }
+ descriptions.put(name, description);
}
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- SortedMap<String, String> commands = getCommandDescriptions(session, path);
- if (commands.isEmpty()) {
+ if (descriptions.isEmpty()) {
return null;
- } else if (commands.size() == 1 && commands.containsKey(path)) {
+ } else if (descriptions.size() == 1 && descriptions.containsKey(path)) {
return null;
} else {
- printMethodList(session, new PrintStream(baos), commands);
+ printMethodList(session, new PrintStream(baos), descriptions, Arrays.asList(mode.split(",")));
return baos.toString();
}
}
- private SortedMap<String, String> getCommandDescriptions(Session session, String path) {
+ private Set<Command> getCommands(Session session, String path) {
// TODO: this is not really clean
List<Command> commands = session.getRegistry().getCommands();
@@ -62,12 +88,12 @@ public class CommandListHelpProvider implements HelpProvider {
String subshell = (String) session.get(Session.SUBSHELL);
String completionMode = (String) session.get(Session.COMPLETION_MODE);
- SortedMap<String,String> descriptions = new TreeMap<String,String>();
+ Set<Command> matchingCommands = new HashSet<>();
for (Command command : commands) {
String name = command.getScope() + ":" + command.getName();
- if (command != null && !name.startsWith(path)) {
+ if (!name.startsWith(path)) {
continue;
}
@@ -88,28 +114,51 @@ public class CommandListHelpProvider implements HelpProvider {
}
}
- String description = command.getDescription();
- if (name.startsWith("*:")) {
- name = name.substring(2);
- }
- if (subshell != null && !subshell.trim().isEmpty() && name.startsWith(subshell + ":")) {
- name = name.substring(subshell.length() + 1);
- }
- descriptions.put(name, description);
+ matchingCommands.add(command);
}
- return descriptions;
+ return matchingCommands;
}
- protected void printMethodList(Session session, PrintStream out, SortedMap<String, String> commands) {
+ protected void printMethodList(Session session, PrintStream out, SortedMap<String, String> commands, Collection<String> modes) {
+ boolean list = false;
+ boolean cyan = false;
+ int indent = 0;
+ for (String mode : modes) {
+ if (mode.equals("list")) {
+ list = true;
+ } else if (mode.equals("cyan")) {
+ cyan = true;
+ } else if (mode.equals("indent")) {
+ indent = 4;
+ } else if (mode.startsWith("indent=")) {
+ indent = Integer.parseInt(mode.substring("indent=".length()));
+ }
+ }
+
Terminal term = session.getTerminal();
int termWidth = term != null ? term.getWidth() : 80;
- out.println(SimpleAnsi.INTENSITY_BOLD + "COMMANDS" + SimpleAnsi.INTENSITY_NORMAL);
- ShellTable table = new ShellTable().noHeaders().separator(" ").size(termWidth);
- table.column(new Col("Command").maxSize(64));
- table.column(new Col("Description"));
+ ShellTable table = new ShellTable().noHeaders().separator(" ").size(termWidth - 1);
+ Col col = new Col("Command").maxSize(64);
+ if (indent > 0 || list) {
+ table.column(new Col(""));
+ }
+ if (cyan) {
+ col.cyan();
+ } else {
+ col.bold();
+ }
+ table.column(col);
+ table.column(new Col("Description").wrap());
for (Map.Entry<String,String> entry : commands.entrySet()) {
String key = NameScoping.getCommandNameWithoutGlobalPrefix(session, entry.getKey());
- table.addRow().addContent(SimpleAnsi.INTENSITY_BOLD + key + SimpleAnsi.INTENSITY_NORMAL, entry.getValue());
+ String prefix = "";
+ for (int i = 0; i < indent; i++) {
+ prefix += " ";
+ }
+ if (list) {
+ prefix += " *";
+ }
+ table.addRow().addContent(prefix, key, entry.getValue());
}
table.print(out, true);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandsHelpProvider.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandsHelpProvider.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandsHelpProvider.java
new file mode 100644
index 0000000..44ada77
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/CommandsHelpProvider.java
@@ -0,0 +1,87 @@
+/**
+ *
+ * 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.impl.console.commands.help;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.karaf.shell.api.console.Command;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.ansi.SimpleAnsi;
+
+public class CommandsHelpProvider implements HelpProvider {
+
+ public String getHelp(Session session, String path) {
+ if (path.indexOf('|') > 0) {
+ if (path.startsWith("commands|")) {
+ path = path.substring("commands|".length());
+ } else {
+ return null;
+ }
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ ps.println(SimpleAnsi.INTENSITY_BOLD + "COMMANDS" + SimpleAnsi.INTENSITY_NORMAL);
+ ps.println("${command-list|" + path + "}");
+ return baos.toString();
+ }
+
+ private Set<Command> getCommands(Session session, String path) {
+ // TODO: this is not really clean
+
+ List<Command> commands = session.getRegistry().getCommands();
+
+ String subshell = (String) session.get(Session.SUBSHELL);
+ String completionMode = (String) session.get(Session.COMPLETION_MODE);
+
+ Set<Command> matchingCommands = new HashSet<>();
+ for (Command command : commands) {
+
+ String name = command.getScope() + ":" + command.getName();
+
+ if (command != null && !name.startsWith(path)) {
+ continue;
+ }
+
+ if (completionMode != null && completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_SUBSHELL)) {
+ // filter the help only for "global" commands
+ if (subshell == null || subshell.trim().isEmpty()) {
+ if (!name.startsWith(Session.SCOPE_GLOBAL)) {
+ continue;
+ }
+ }
+ }
+
+ if (completionMode != null && (completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_SUBSHELL)
+ || completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_FIRST))) {
+ // filter the help only for commands local to the subshell
+ if (!name.startsWith(subshell)) {
+ continue;
+ }
+ }
+
+ matchingCommands.add(command);
+ }
+ return matchingCommands;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java
index 945a429..3402f8a 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java
@@ -18,7 +18,9 @@
*/
package org.apache.karaf.shell.impl.console.commands.help;
+import java.io.BufferedReader;
import java.io.PrintStream;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -48,8 +50,11 @@ public class HelpCommand implements Command {
Registry registry = factory.getRegistry();
registry.register(this);
registry.register(new SimpleHelpProvider());
- registry.register(new CommandListHelpProvider());
+ registry.register(new ShellHelpProvider());
registry.register(new SingleCommandHelpProvider());
+ registry.register(new CommandsHelpProvider());
+ registry.register(new CommandListHelpProvider());
+ registry.register(new BundleHelpProvider());
}
@Override
@@ -83,7 +88,12 @@ public class HelpCommand implements Command {
String path = arguments.isEmpty() ? null : arguments.get(0) == null ? null : arguments.get(0).toString();
String help = getHelp(session, path);
if (help != null) {
- System.out.println(help);
+ try (BufferedReader reader = new BufferedReader(new StringReader(help))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ System.out.println(line);
+ }
+ }
}
return null;
}
@@ -184,7 +194,7 @@ public class HelpCommand implements Command {
private String removeNewLine(String help) {
if (help != null && help.endsWith("\n")) {
- help = help.substring(0, help.length() -1);
+ help = help.substring(0, help.length() - 1);
}
return help;
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/ShellHelpProvider.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/ShellHelpProvider.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/ShellHelpProvider.java
new file mode 100644
index 0000000..8285c3e
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/ShellHelpProvider.java
@@ -0,0 +1,144 @@
+/**
+ *
+ * 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.impl.console.commands.help;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.console.Command;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.console.Terminal;
+import org.apache.karaf.shell.impl.action.command.ActionCommand;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.AnsiPrintingWikiVisitor;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.WikiParser;
+import org.apache.karaf.shell.impl.console.commands.help.wikidoc.WikiVisitor;
+import org.apache.karaf.shell.support.ansi.SimpleAnsi;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class ShellHelpProvider implements HelpProvider {
+
+ public String getHelp(Session session, String path) {
+ if (path.indexOf('|') > 0) {
+ if (path.startsWith("shell|")) {
+ path = path.substring("shell|".length());
+ } else {
+ return null;
+ }
+ }
+
+ // Retrieve matching commands
+ Set<Command> commands = getCommands(session, path);
+
+ // Compute the scopes and matching bundles
+ Set<Bundle> bundles = new HashSet<>();
+ Set<String> scopes = new HashSet<>();
+ for (Command command : commands) {
+ if (command instanceof ActionCommand) {
+ Class<? extends Action> action = ((ActionCommand) command).getActionClass();
+ bundles.add(FrameworkUtil.getBundle(action));
+ }
+ scopes.add(command.getScope());
+ }
+ // When there is a single scope / bundle and a matching information file
+ // use that one instead
+ if (scopes.size() == 1 && bundles.size() == 1 && path.equals(scopes.iterator().next())) {
+ Bundle bundle = bundles.iterator().next();
+ URL resource = bundle.getResource("OSGI-INF/shell-" + path + ".info");
+ if (resource != null) {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream()))) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ int maxSize = 80;
+ Terminal terminal = session.getTerminal();
+ if (terminal != null) {
+ maxSize = terminal.getWidth();
+ }
+ WikiVisitor visitor = new AnsiPrintingWikiVisitor(ps, maxSize);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(reader);
+ return baos.toString();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ printShellHelp(session, new PrintStream(baos), path);
+ return baos.toString();
+ }
+
+ return null;
+ }
+
+ private Set<Command> getCommands(Session session, String path) {
+ // TODO: this is not really clean
+
+ List<Command> commands = session.getRegistry().getCommands();
+
+ String subshell = (String) session.get(Session.SUBSHELL);
+ String completionMode = (String) session.get(Session.COMPLETION_MODE);
+
+ Set<Command> matchingCommands = new HashSet<>();
+ for (Command command : commands) {
+
+ String name = command.getScope() + ":" + command.getName();
+
+ if (command != null && !name.startsWith(path)) {
+ continue;
+ }
+
+ if (completionMode != null && completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_SUBSHELL)) {
+ // filter the help only for "global" commands
+ if (subshell == null || subshell.trim().isEmpty()) {
+ if (!name.startsWith(Session.SCOPE_GLOBAL)) {
+ continue;
+ }
+ }
+ }
+
+ if (completionMode != null && (completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_SUBSHELL)
+ || completionMode.equalsIgnoreCase(Session.COMPLETION_MODE_FIRST))) {
+ // filter the help only for commands local to the subshell
+ if (!name.startsWith(subshell)) {
+ continue;
+ }
+ }
+
+ matchingCommands.add(command);
+ }
+ return matchingCommands;
+ }
+
+ protected void printShellHelp(Session session, PrintStream out, String path) {
+ out.println(SimpleAnsi.INTENSITY_BOLD + "SUBSHELL" + SimpleAnsi.INTENSITY_NORMAL);
+ out.println("\t" + SimpleAnsi.INTENSITY_BOLD + path + SimpleAnsi.INTENSITY_NORMAL);
+ out.println();
+ out.println(SimpleAnsi.INTENSITY_BOLD + "COMMANDS" + SimpleAnsi.INTENSITY_NORMAL);
+ out.println("${command-list|" + path + "|embedded}");
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
new file mode 100644
index 0000000..bd5acd9
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
@@ -0,0 +1,94 @@
+/*
+ * 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.impl.console.commands.help.wikidoc;
+
+import java.io.PrintStream;
+
+import org.apache.karaf.shell.support.table.ShellTable;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.Ansi.Attribute;
+import org.fusesource.jansi.Ansi.Color;
+
+/**
+ * Translates the Wiki tags to Ansi escape sequences to display them on the console
+ */
+public class AnsiPrintingWikiVisitor implements WikiVisitor {
+
+ private PrintStream out;
+ private int maxSize;
+ private StringBuilder sb = new StringBuilder();
+ private String indent;
+
+ public AnsiPrintingWikiVisitor(PrintStream out, int maxSize) {
+ this.out = out;
+ this.maxSize = maxSize;
+ }
+
+ @Override
+ public void startPara(int size) {
+ indent = "";
+ while (size-- > 0) {
+ indent += " ";
+ }
+ }
+
+ @Override
+ public void endPara() {
+ if (sb.length() > 0) {
+ ShellTable table = new ShellTable().noHeaders().separator("").size(maxSize - 1);
+ table.column("").maxSize(indent.length());
+ table.column("").wrap();
+ table.addRow().addContent(indent, sb.toString());
+ table.print(out);
+ sb.setLength(0);
+ } else {
+ out.println();
+ }
+ }
+
+ @Override
+ public void heading(int level, String header) {
+ sb.append(Ansi.ansi().a(Attribute.INTENSITY_BOLD).a(header)
+ .a(Attribute.INTENSITY_BOLD_OFF).toString());
+ }
+
+ @Override
+ public void link(String target, String title) {
+ sb.append(Ansi.ansi().fg(Color.YELLOW)
+ .a(target).fg(Color.DEFAULT));
+ }
+
+ @Override
+ public void enumeration(String text) {
+ sb.append(Ansi.ansi().a(" * ").fg(Color.CYAN).a(text).fg(Color.DEFAULT).a(" "));
+ }
+
+ @Override
+ public void text(String text) {
+ sb.append(text);
+ }
+
+ @Override
+ public void bold(boolean on) {
+ if (on) {
+ sb.append(Ansi.ansi().bold().toString());
+ } else {
+ sb.append(Ansi.ansi().boldOff().toString());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParser.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParser.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParser.java
new file mode 100644
index 0000000..783331e
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParser.java
@@ -0,0 +1,171 @@
+/*
+ * 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.impl.console.commands.help.wikidoc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.karaf.util.StringEscapeUtils;
+
+/**
+ * Parses wiki syntax from a reader and calls a Wikivisitor with the
+ * tokens it finds
+ */
+public class WikiParser {
+
+ WikiVisitor visitor;
+
+ public WikiParser(WikiVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ public void parse(Reader reader) throws IOException {
+ BufferedReader br = new BufferedReader(reader);
+ String line;
+ while ((line = br.readLine()) != null) {
+ if (!line.startsWith("#")) {
+ parse(line);
+ }
+ }
+ }
+
+ public void parse(String line) {
+ String unescaped = StringEscapeUtils.unescapeJava(line);
+ Tokenizer tokenizer = new Tokenizer(unescaped);
+ String token;
+ boolean bold = false;
+ boolean first = true;
+ while ((token = tokenizer.nextToken("\u001B[h*")) != null) {
+ if (first) {
+ first = false;
+ int tabs = 0;
+ for (int i = 0; i < token.length() && token.charAt(i) == '\t'; i++) {
+ tabs++;
+ }
+ token = token.substring(tabs);
+ for (int i = 0; i < tabs; i++) {
+ token = " " + token;
+ }
+ int i = 0;
+ while (i < token.length() && token.charAt(i) == ' ') {
+ i++;
+ }
+ visitor.startPara(i);
+ token = token.substring(i);
+ }
+ if ("\u001B".equals(token)) {
+ parseEsc(tokenizer, token);
+ } else if ("[".equals(token)) {
+ parseLink(tokenizer);
+ } else if ("h".equals(token)) {
+ parseHeading(tokenizer);
+ } else if ("*".equals(token)) {
+ parseEnumeration(tokenizer);
+ } else if ("**".equals(token)) {
+ bold = !bold;
+ visitor.bold(bold);
+ } else {
+ visitor.text(token);
+ }
+ }
+ if (first) {
+ visitor.startPara(0);
+ }
+ visitor.endPara();
+ }
+
+ private void parseEsc(Tokenizer tokenizer, String token) {
+ visitor.text(token + tokenizer.nextToken("\u001B[h*") + tokenizer.nextToken("\u001B[]"));
+ }
+
+ private void parseEnumeration(Tokenizer tokenizer) {
+ String text = tokenizer.nextToken("-\n");
+ visitor.enumeration(text.trim());
+ }
+
+ private void parseHeading(Tokenizer tokenizer) {
+ String level = tokenizer.nextToken("123456789");
+ if (!level.matches("[123456789]")) {
+ visitor.text("h" + level);
+ return;
+ }
+ String dot = tokenizer.nextToken(".\n");
+ if (!".".equals(dot)) {
+ visitor.text("h" + level + dot);
+ return;
+ }
+ String heading = tokenizer.nextToken("\n");
+ if (heading == null) {
+ heading = "";
+ }
+ visitor.heading(Integer.parseInt(level), heading.trim());
+ }
+
+ private void parseLink(Tokenizer tokenizer) {
+ String token = tokenizer.nextToken("]");
+ visitor.link(token, "");
+ tokenizer.nextToken("]");
+ }
+
+ public static class Tokenizer {
+
+ final String str;
+ int pos;
+
+ public Tokenizer(String str) {
+ this.str = str;
+ }
+
+ public String nextToken(String delim) {
+ StringBuilder sb = new StringBuilder();
+ boolean escape = false;
+ boolean del = false;
+ while (pos < str.length()) {
+ char c = str.charAt(pos++);
+ if (escape) {
+ escape = false;
+ sb.append(c);
+ } else if (c == '\\') {
+ if (del) {
+ pos--;
+ break;
+ } else {
+ escape = true;
+ }
+ } else if (delim.indexOf(c) >= 0) {
+ if (sb.length() == 0 || del) {
+ sb.append(c);
+ del = true;
+ } else {
+ pos--;
+ break;
+ }
+ } else {
+ if (del) {
+ pos--;
+ break;
+ }
+ sb.append(c);
+ }
+ }
+ return sb.length() > 0 ? sb.toString() : null;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiVisitor.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiVisitor.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiVisitor.java
new file mode 100644
index 0000000..b6c1caa
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiVisitor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.impl.console.commands.help.wikidoc;
+
+/**
+ * Will be used by WikiParser to call the respective handler when it recognizes the tag
+ */
+public interface WikiVisitor {
+
+ void link(String target, String title);
+ void heading(int level, String title);
+ void enumeration(String text);
+ void text(String text);
+ void bold(boolean on);
+ void startPara(int size);
+ void endPara();
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/support/ansi/SimpleAnsi.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/ansi/SimpleAnsi.java b/shell/core/src/main/java/org/apache/karaf/shell/support/ansi/SimpleAnsi.java
index d7d75d7..92ce8b6 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/support/ansi/SimpleAnsi.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/support/ansi/SimpleAnsi.java
@@ -23,6 +23,7 @@ import org.fusesource.jansi.Ansi.Color;
public class SimpleAnsi {
public static String COLOR_RED = Ansi.ansi().fg(Color.RED).toString();
+ public static String COLOR_CYAN = Ansi.ansi().fg(Color.CYAN).toString();
public static String COLOR_DEFAULT = Ansi.ansi().fg(Color.DEFAULT).toString();
public static String INTENSITY_BOLD = Ansi.ansi().bold().toString();
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/java/org/apache/karaf/shell/support/table/Col.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/table/Col.java b/shell/core/src/main/java/org/apache/karaf/shell/support/table/Col.java
index 95dba51..29bbbb3 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/support/table/Col.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/support/table/Col.java
@@ -43,6 +43,8 @@ public class Col {
boolean wrap;
boolean bold;
+ boolean cyan;
+
/**
* Alignment
@@ -96,6 +98,15 @@ public class Col {
return this;
}
+ public Col cyan() {
+ return cyan(true);
+ }
+
+ public Col cyan(boolean cyan) {
+ this.cyan = cyan;
+ return this;
+ }
+
public int getSize() {
return size;
}
@@ -146,6 +157,9 @@ public class Col {
if (bold) {
line = SimpleAnsi.INTENSITY_BOLD + line + SimpleAnsi.INTENSITY_NORMAL;
}
+ if (cyan) {
+ line = SimpleAnsi.COLOR_CYAN + line + SimpleAnsi.COLOR_DEFAULT;
+ }
sb.append(line);
}
return sb.toString();
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/shell/core/src/main/resources/OSGI-INF/bundle.info b/shell/core/src/main/resources/OSGI-INF/bundle.info
index 4d4296e..2dbd380 100644
--- a/shell/core/src/main/resources/OSGI-INF/bundle.info
+++ b/shell/core/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/core/src/test/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParserTest.java
----------------------------------------------------------------------
diff --git a/shell/core/src/test/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParserTest.java b/shell/core/src/test/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParserTest.java
new file mode 100644
index 0000000..62cc6ca
--- /dev/null
+++ b/shell/core/src/test/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/WikiParserTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.impl.console.commands.help.wikidoc;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class WikiParserTest {
+
+ private static final String TESTDOC =
+ "h1. myTestdoc\n" +
+ "\n" +
+ "Some text\n" +
+ "* enumeration\n" +
+ " some text [a link] some more text\n" +
+ "h1 is no heading";
+
+ private static final String HEADINGCASES =
+ "h1.\n" +
+ "hf.";
+
+ @Test
+ public void parseTestDoc() throws IOException {
+ WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.heading(1, "myTestdoc");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.text("Some text");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.enumeration("enumeration");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+ visitor.startPara(1);
+ EasyMock.expectLastCall();
+ visitor.text("some text ");
+ EasyMock.expectLastCall();
+ visitor.link("a link", "");
+ EasyMock.expectLastCall();
+ visitor.text(" some more text");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.text("h1 is no heading");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(visitor);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(new StringReader(TESTDOC));
+ EasyMock.verify(visitor);
+ }
+
+ @Test
+ public void parseHeadingSpecialCases() throws IOException {
+ WikiVisitor visitor = EasyMock.createStrictMock(WikiVisitor.class);
+
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.heading(1, "");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+
+ visitor.startPara(0);
+ EasyMock.expectLastCall();
+ visitor.text("hf.");
+ EasyMock.expectLastCall();
+ visitor.endPara();
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(visitor);
+ WikiParser parser = new WikiParser(visitor);
+ parser.parse(new StringReader(HEADINGCASES));
+ EasyMock.verify(visitor);
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/shell/ssh/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/resources/OSGI-INF/bundle.info b/shell/ssh/src/main/resources/OSGI-INF/bundle.info
index bf0b068..feeda99 100644
--- a/shell/ssh/src/main/resources/OSGI-INF/bundle.info
+++ b/shell/ssh/src/main/resources/OSGI-INF/bundle.info
@@ -1,19 +1,41 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-This bundle provides SSH support for the Karaf shell console.
+ This bundle provides SSH support for the Karaf shell console.
-It acts as SSH client and server allowing you to receive SSH connection and be able to
-connect to a remote SSH server.
+ It acts as SSH client and server allowing you to receive SSH connection and be able to connect to a remote SSH server.
+
+h1. Commands
+
+ The following commands are available:
+\${command-list|ssh|indent=8,list,cyan}
h1. See also
-Using remote instances - section of the Karaf User Guide
+ Using remote instances - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/system/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/system/src/main/resources/OSGI-INF/bundle.info b/system/src/main/resources/OSGI-INF/bundle.info
index acca1c8..966181e 100644
--- a/system/src/main/resources/OSGI-INF/bundle.info
+++ b/system/src/main/resources/OSGI-INF/bundle.info
@@ -1,16 +1,39 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-This bundle provides support of the system service, which control the Karaf container.
+ This bundle provides support of the system service, which control the Karaf container.
+
+h1. Commands
+
+ The following commands are available:
+\${command-list|system|indent=8,list,cyan}
h1. See also
-Shutdown - section of the Karaf User Guide
+ Shutdown - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/web/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/web/src/main/resources/OSGI-INF/bundle.info b/web/src/main/resources/OSGI-INF/bundle.info
index 650fee9..2500de5 100644
--- a/web/src/main/resources/OSGI-INF/bundle.info
+++ b/web/src/main/resources/OSGI-INF/bundle.info
@@ -1,16 +1,39 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-This bundle provides support of the WebContainer service, which allows to manipulate the Karaf embedded web container.
+ This bundle provides support of the WebContainer service, which allows to manipulate the Karaf embedded web container.
+
+h1. Commands
+
+ The following commands are available:
+\${command-list|web|indent=8,list,cyan}
h1. See also
-Web Container - section of the Karaf User Guide
+ Web Container - section of the Karaf User Guide
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/webconsole/console/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/webconsole/console/src/main/resources/OSGI-INF/bundle.info b/webconsole/console/src/main/resources/OSGI-INF/bundle.info
index 7fa1614..961cb45 100644
--- a/webconsole/console/src/main/resources/OSGI-INF/bundle.info
+++ b/webconsole/console/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/webconsole/features/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/webconsole/features/src/main/resources/OSGI-INF/bundle.info b/webconsole/features/src/main/resources/OSGI-INF/bundle.info
index e7ff46c..2547e95 100644
--- a/webconsole/features/src/main/resources/OSGI-INF/bundle.info
+++ b/webconsole/features/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/webconsole/gogo/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/webconsole/gogo/src/main/resources/OSGI-INF/bundle.info b/webconsole/gogo/src/main/resources/OSGI-INF/bundle.info
index 8c0e7a5..b4fc2a8 100644
--- a/webconsole/gogo/src/main/resources/OSGI-INF/bundle.info
+++ b/webconsole/gogo/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/webconsole/http/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/webconsole/http/src/main/resources/OSGI-INF/bundle.info b/webconsole/http/src/main/resources/OSGI-INF/bundle.info
index e65c23f..3caaafb 100644
--- a/webconsole/http/src/main/resources/OSGI-INF/bundle.info
+++ b/webconsole/http/src/main/resources/OSGI-INF/bundle.info
@@ -1,4 +1,22 @@
-\u001B[1mSYNOPSIS\u001B[0m
+#
+#
+# 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.
+#
+#
+h1. SYNOPSIS
${project.name}
${project.description}
@@ -6,8 +24,8 @@
Maven URL:
\u001B[33mmvn:${project.groupId}/${project.artifactId}/${project.version}\u001B[0m
-\u001B[1mDESCRIPTION\u001B[0m
+h1. DESCRIPTION
This bundle provides the Karaf http plugin for the Felix Web Console.
-\u001B[1mSEE ALSO\u001B[0m
+h1. SEE ALSO
\u001B[36mWeb console\u001B[0m section of the Karaf User Guide.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/webconsole/instance/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/webconsole/instance/src/main/resources/OSGI-INF/bundle.info b/webconsole/instance/src/main/resources/OSGI-INF/bundle.info
index 1000da0..4fd2549 100644
--- a/webconsole/instance/src/main/resources/OSGI-INF/bundle.info
+++ b/webconsole/instance/src/main/resources/OSGI-INF/bundle.info
@@ -1,3 +1,21 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
${project.name}
http://git-wip-us.apache.org/repos/asf/karaf/blob/f38a1e20/wrapper/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/wrapper/src/main/resources/OSGI-INF/bundle.info b/wrapper/src/main/resources/OSGI-INF/bundle.info
index 8462cc5..3a9277c 100644
--- a/wrapper/src/main/resources/OSGI-INF/bundle.info
+++ b/wrapper/src/main/resources/OSGI-INF/bundle.info
@@ -1,16 +1,39 @@
+#
+#
+# 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.
+#
+#
h1. Synopsis
-${project.name}
+ ${project.name}
-${project.description}
+ ${project.description}
-Maven URL:
-[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+ Maven URL:
+ [mvn:${project.groupId}/${project.artifactId}/${project.version}]
h1. Description
-This bundle provides support of the service wrapper, which allows for starting/stopping Karaf as a system service.
+ This bundle provides support of the service wrapper, which allows for starting/stopping Karaf as a system service.
+
+h1. Commands
+
+ The following commands are provided:
+\${command-list|wrapper|indent=8,list,cyan}
h1. See also
-Service Wrapper - section of the Karaf User Guide
+ Service Wrapper - section of the Karaf User Guide