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 2013/12/18 11:02:58 UTC

git commit: [KARAF-2044] Provide the ability to edit text resources from the Karaf shell

Updated Branches:
  refs/heads/karaf-2.x 6ae261ba8 -> ae25e731c


[KARAF-2044] Provide the ability to edit text resources from the Karaf shell


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/ae25e731
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/ae25e731
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/ae25e731

Branch: refs/heads/karaf-2.x
Commit: ae25e731cdab6a58c8ccd4224720d88a96528225
Parents: 6ae261b
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Mar 6 14:30:46 2013 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Dec 18 11:02:46 2013 +0100

----------------------------------------------------------------------
 pom.xml                                         |   6 +
 shell/commands/pom.xml                          |   4 +
 .../apache/karaf/shell/commands/EditAction.java | 189 +++++++++++++++++++
 .../OSGI-INF/blueprint/shell-commands.xml       |   8 +-
 shell/console/pom.xml                           |   6 +
 .../META-INF/services/org/jledit/simple         |   1 +
 .../OSGI-INF/blueprint/karaf-console.xml        |   3 +
 7 files changed, 216 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e1b30d3..0d3711c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -169,6 +169,7 @@
         <aries.util.version>1.1.0</aries.util.version>
         <jansi.version>1.11</jansi.version>
         <jline.version>2.11</jline.version>
+        <jledit.version>0.2.1</jledit.version>
         <jsw.version>3.2.3</jsw.version>
         <log4j.version>1.2.17</log4j.version>
         <maven.version>3.0-alpha-2</maven.version>
@@ -794,6 +795,11 @@
                 <version>${jansi.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.jledit</groupId>
+                <artifactId>core</artifactId>
+                <version>${jledit.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.maven.artifact</groupId>
                 <artifactId>maven-artifact</artifactId>
                 <version>3.0-alpha-1</version>

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/commands/pom.xml
----------------------------------------------------------------------
diff --git a/shell/commands/pom.xml b/shell/commands/pom.xml
index b2b5be4..f4a0365 100644
--- a/shell/commands/pom.xml
+++ b/shell/commands/pom.xml
@@ -43,6 +43,10 @@
             <artifactId>org.apache.karaf.shell.console</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.jledit</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.gogo.runtime</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/commands/src/main/java/org/apache/karaf/shell/commands/EditAction.java
----------------------------------------------------------------------
diff --git a/shell/commands/src/main/java/org/apache/karaf/shell/commands/EditAction.java b/shell/commands/src/main/java/org/apache/karaf/shell/commands/EditAction.java
new file mode 100644
index 0000000..0208651
--- /dev/null
+++ b/shell/commands/src/main/java/org/apache/karaf/shell/commands/EditAction.java
@@ -0,0 +1,189 @@
+/*
+ * 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.commands;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.UUID;
+import java.util.regex.Pattern;
+
+import jline.Terminal;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.karaf.shell.console.AbstractAction;
+import org.jledit.ConsoleEditor;
+import org.jledit.EditorFactory;
+
+@Command(scope = "shell", name = "edit", description = "Calls a text editor.")
+public class EditAction extends AbstractAction {
+
+    private final Pattern URL_PATTERN = Pattern.compile("[^: ]+:[^ ]+");
+
+    @Argument(index = 0, name = "url", description = "The url of the resource to edit.", required = true, multiValued = false)
+    private String url;
+
+    private EditorFactory editorFactory;
+
+    @Override
+    protected Object doExecute() throws Exception {
+        URLConnection connection = null;
+        InputStream is = null;
+        OutputStream os = null;
+        String path = null;
+        boolean isLocal = true;
+        String sourceUrl = url;
+
+        // if no url format found, assume file url
+        if (!URL_PATTERN.matcher(sourceUrl).matches()) {
+            File f = new File(sourceUrl);
+            sourceUrl = "file://" + f.getAbsolutePath();
+        }
+
+        URL u = new URL(sourceUrl);
+        // if its not a file url
+        if (!u.getProtocol().equals("file")) {
+            isLocal = false;
+
+            try {
+                connection = u.openConnection();
+                is = connection.getInputStream();
+            } catch (IOException ex) {
+                System.out.println("Failed to open " + sourceUrl + " for reading.");
+                return null;
+            }
+            try {
+                os = connection.getOutputStream();
+            } catch (IOException ex) {
+                System.out.println("Failed to open " + sourceUrl + " for writing.");
+                return null;
+            }
+
+            // copy the resource to a tmp location
+            FileOutputStream fos = null;
+            try {
+                path = System.getProperty("karaf.data") + "/editor/" + UUID.randomUUID();
+                File f = new File(path);
+                if (!f.exists()) {
+                    if (!f.getParentFile().exists()) {
+                        f.getParentFile().mkdirs();
+                    }
+                }
+
+                fos = new FileOutputStream(f);
+                copy(is, fos);
+            } catch (Exception ex) {
+                System.out.println("Failed to copy resource from url:" + sourceUrl + " to tmp file: " + path + "  for editing.");
+            } finally {
+                close(fos);
+            }
+        } else {
+            path = u.getFile();
+        }
+
+
+        File file = new File(path);
+        if (!file.exists()) {
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+        }
+
+        // call the editor
+        ConsoleEditor editor = editorFactory.create(getTerminal());
+        editor.setTitle("Karaf");
+        editor.open(file.getAbsolutePath(), url);
+        editor.setOpenEnabled(false);
+        editor.start();
+
+        // if resource is not local, copy the resource back
+        if (!isLocal) {
+            FileInputStream fis = new FileInputStream(path);
+            try {
+                copy(fis, os);
+            } finally {
+                close(fis);
+            }
+        }
+
+        if (is != null) {
+            close(is);
+        }
+
+        if (os != null) {
+            close(os);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the {@link jline.Terminal} from the current session.
+     *
+     * @return
+     * @throws Exception
+     */
+    private Terminal getTerminal() throws Exception {
+        Object terminalObject = session.get(".jline.terminal");
+        if (terminalObject instanceof Terminal) {
+            return (Terminal) terminalObject;
+
+        }
+        throw new IllegalStateException("Could not get Terminal from CommandSession.");
+    }
+
+    /**
+     * Copies the content of {@link InputStream} to {@link OutputStream}.
+     *
+     * @param input
+     * @param output
+     * @throws IOException
+     */
+    private void copy(final InputStream input, final OutputStream output) throws IOException {
+        byte[] buffer = new byte[1024 * 16];
+        int n = 0;
+        while (-1 != (n = input.read(buffer))) {
+            output.write(buffer, 0, n);
+            output.flush();
+        }
+    }
+
+    public EditorFactory getEditorFactory() {
+        return editorFactory;
+    }
+
+    public void setEditorFactory(EditorFactory editorFactory) {
+        this.editorFactory = editorFactory;
+    }
+
+    private static void close(Closeable... closeables) {
+        for (Closeable c : closeables) {
+            try {
+                if (c != null) {
+                    c.close();
+                }
+            } catch (IOException e) {
+                // Ignore
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/commands/src/main/resources/OSGI-INF/blueprint/shell-commands.xml
----------------------------------------------------------------------
diff --git a/shell/commands/src/main/resources/OSGI-INF/blueprint/shell-commands.xml b/shell/commands/src/main/resources/OSGI-INF/blueprint/shell-commands.xml
index 5f0242e..6ac7731 100644
--- a/shell/commands/src/main/resources/OSGI-INF/blueprint/shell-commands.xml
+++ b/shell/commands/src/main/resources/OSGI-INF/blueprint/shell-commands.xml
@@ -100,6 +100,11 @@
         <command name="shell/wc">
             <action class="org.apache.karaf.shell.commands.WcAction"/>
         </command>
+        <command name="shell/edit">
+            <action class="org.apache.karaf.shell.commands.EditAction">
+                <property name="editorFactory" ref="editorFactory"/>
+            </action>
+        </command>
     </command-bundle>
 
    <bean id="commandCompleter" class="org.apache.karaf.shell.console.completer.CommandsCompleter"/>
@@ -120,5 +125,6 @@
     </reference-list>
 
     <reference id="commandProcessor" interface="org.apache.felix.service.command.CommandProcessor"/>
- 
+    <reference id="editorFactory" interface="org.jledit.EditorFactory"/>
+
 </blueprint>

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/console/pom.xml
----------------------------------------------------------------------
diff --git a/shell/console/pom.xml b/shell/console/pom.xml
index 2d8b246..59b6950 100644
--- a/shell/console/pom.xml
+++ b/shell/console/pom.xml
@@ -45,6 +45,10 @@
             <artifactId>jansi</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.jledit</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
         </dependency>
@@ -126,12 +130,14 @@
                             org.apache.karaf.shell.console*;version=${project.version},
                             org.fusesource.jansi;version=${jansi.version};-split-package:=merge-first,
                             jline*;version=${jline.version},
+                            org.jledit*;version=${jledit.version},
                             org.fusesource.hawtjni*;version=1.0;-split-package:=merge-first
                         </Export-Package>
                         <Private-Package>
                             org.fusesource.jansi.internal;-split-package:=merge-first,
                             !org.apache.karaf.util.properties,
                             org.apache.karaf.util*;-split-package:=merge-first,
+                            org.mozilla.universalchardet*;-split-package:=merge-first,
                             META-INF.native.*;-split-package:=merge-first
                         </Private-Package>
                         <Bundle-NativeCode>

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/console/src/main/resources/META-INF/services/org/jledit/simple
----------------------------------------------------------------------
diff --git a/shell/console/src/main/resources/META-INF/services/org/jledit/simple b/shell/console/src/main/resources/META-INF/services/org/jledit/simple
new file mode 100644
index 0000000..9e58ccc
--- /dev/null
+++ b/shell/console/src/main/resources/META-INF/services/org/jledit/simple
@@ -0,0 +1 @@
+org.jledit.simple.SimpleConsoleEditor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/ae25e731/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
----------------------------------------------------------------------
diff --git a/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml b/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
index 4364d6e..983d3ce 100644
--- a/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
+++ b/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
@@ -48,6 +48,8 @@
     <bean id="terminalFactory" class="org.apache.karaf.shell.console.jline.TerminalFactory"
           destroy-method="destroy"/>
 
+    <bean id="editorFactory" class="org.jledit.ConcreteEditorFactory"/>
+
     <service>
         <interfaces>
             <value>org.apache.felix.service.command.Function</value>
@@ -104,5 +106,6 @@
         <bean class="org.apache.karaf.shell.console.help.BrandingHelpProvider"/>
     </service>
 
+    <service ref="editorFactory" interface="org.jledit.EditorFactory"/>
 
 </blueprint>