Jelajahi Sumber

ZOOKEEPER-1408. CLI: sort output of ls command (Hartmut Lang via michim)

git-svn-id: https://svn.apache.org/repos/asf/zookeeper/trunk@1582943 13f79535-47bb-0310-9956-ffa450edef68
Michi Mutsuzaki 11 tahun lalu
induk
melakukan
0ad0169375

+ 2 - 0
CHANGES.txt

@@ -817,6 +817,8 @@ IMPROVEMENTS:
   ZOOKEEPER-297. centralize version numbering in the source/build (Diego de
   ZOOKEEPER-297. centralize version numbering in the source/build (Diego de
   Oliveira via michim)
   Oliveira via michim)
 
 
+  ZOOKEEPER-1408. CLI: sort output of ls command (Hartmut Lang via michim)
+
 headers
 headers
 
 
 Release 3.4.0 - 
 Release 3.4.0 - 

+ 2 - 0
src/java/main/org/apache/zookeeper/JLineZNodeCompleter.java

@@ -18,6 +18,7 @@
 
 
 package org.apache.zookeeper;
 package org.apache.zookeeper;
 
 
+import java.util.Collections;
 import java.util.List;
 import java.util.List;
 
 
 import jline.console.completer.Completer;
 import jline.console.completer.Completer;
@@ -79,6 +80,7 @@ class JLineZNodeCompleter implements Completer {
         catch( KeeperException e) {
         catch( KeeperException e) {
             return 0;
             return 0;
         }
         }
+        Collections.sort(candidates);
         return candidates.size() == 0 ? buffer.length() : buffer.lastIndexOf("/") + 1;
         return candidates.size() == 0 ? buffer.length() : buffer.lastIndexOf("/") + 1;
     }
     }
 }
 }

+ 14 - 9
src/java/main/org/apache/zookeeper/cli/CliCommand.java

@@ -42,21 +42,26 @@ abstract public class CliCommand {
      * @param optionStr the string used to call this command 
      * @param optionStr the string used to call this command 
      */
      */
     public CliCommand(String cmdStr, String optionStr) {
     public CliCommand(String cmdStr, String optionStr) {
-        this(cmdStr, optionStr, System.out, System.err);
+        this.out = System.out;
+        this.err = System.err;
+        this.cmdStr = cmdStr;
+        this.optionStr = optionStr;
     }
     }
 
 
     /**
     /**
-     * a CLI command with command string and options.
-     * @param cmdStr the string used to call this command
-     * @param optionStr the string used to call this command
-     * @param out stream used for all normal printing
-     * @param err stream used for all error printing
+     * Set out printStream (useable for testing)
+     * @param out 
      */
      */
-    public CliCommand(String cmdStr, String optionStr, PrintStream out, PrintStream err) {
+    public void setOut(PrintStream out) {
         this.out = out;
         this.out = out;
+    }
+
+    /**
+     * Set err printStream (useable for testing)
+     * @param err 
+     */
+    public void setErr(PrintStream err) {
         this.err = err;
         this.err = err;
-        this.cmdStr = cmdStr;
-        this.optionStr = optionStr;
     }
     }
 
 
     /**
     /**

+ 3 - 0
src/java/main/org/apache/zookeeper/cli/CreateCommand.java

@@ -80,6 +80,9 @@ public class CreateCommand extends CliCommand {
         } catch(KeeperException.EphemeralOnLocalSessionException e) {
         } catch(KeeperException.EphemeralOnLocalSessionException e) {
             err.println("Unable to create ephemeral node on a local session");
             err.println("Unable to create ephemeral node on a local session");
             return false;
             return false;
+        } catch (KeeperException.InvalidACLException ex) {
+            err.println(ex.getMessage());
+            return false;
         }
         }
         return true;
         return true;
     }
     }

+ 1 - 1
src/java/main/org/apache/zookeeper/cli/DeleteCommand.java

@@ -56,7 +56,7 @@ public class DeleteCommand extends CliCommand {
         if (args.length > 2) {
         if (args.length > 2) {
             // rewrite to option
             // rewrite to option
             String [] newCmd = new String[4];
             String [] newCmd = new String[4];
-            newCmd[0] = cmdArgs [0];
+            newCmd[0] = cmdArgs[0];
             newCmd[1] = "-v";
             newCmd[1] = "-v";
             newCmd[2] = cmdArgs[2]; // version
             newCmd[2] = cmdArgs[2]; // version
             newCmd[3] = cmdArgs[1]; // path            
             newCmd[3] = cmdArgs[1]; // path            

+ 14 - 16
src/java/main/org/apache/zookeeper/cli/Ls2Command.java

@@ -1,19 +1,18 @@
 /**
 /**
- * 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
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
  *
  * Unless required by applicable law or agreed to in writing, software
  * 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.
+ * 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.zookeeper.cli;
 package org.apache.zookeeper.cli;
 
 
@@ -28,7 +27,6 @@ import org.apache.zookeeper.data.Stat;
 public class Ls2Command extends CliCommand {
 public class Ls2Command extends CliCommand {
 
 
     private static Options options = new Options();
     private static Options options = new Options();
-   
     private String args[];
     private String args[];
     
     
     public Ls2Command() {
     public Ls2Command() {
@@ -40,17 +38,17 @@ public class Ls2Command extends CliCommand {
         Parser parser = new PosixParser();
         Parser parser = new PosixParser();
         CommandLine cl = parser.parse(options, cmdArgs);
         CommandLine cl = parser.parse(options, cmdArgs);
         args = cl.getArgs();
         args = cl.getArgs();
-        if(args.length < 2) {
+        if (args.length < 2) {
             throw new ParseException(getUsageStr());
             throw new ParseException(getUsageStr());
         }    
         }    
         
         
         return this;
         return this;
     }
     }
 
 
-    
-    
     @Override
     @Override
     public boolean exec() throws KeeperException, InterruptedException {
     public boolean exec() throws KeeperException, InterruptedException {
+        err.println("'ls2' has been deprecated. "
+                  + "Please use 'ls [-s] path' instead.");
         String path = args[1];
         String path = args[1];
         boolean watch = args.length > 2;
         boolean watch = args.length > 2;
         Stat stat = new Stat();
         Stat stat = new Stat();

+ 40 - 3
src/java/main/org/apache/zookeeper/cli/LsCommand.java

@@ -16,9 +16,11 @@
  */
  */
 package org.apache.zookeeper.cli;
 package org.apache.zookeeper.cli;
 
 
+import java.util.Collections;
 import java.util.List;
 import java.util.List;
 import org.apache.commons.cli.*;
 import org.apache.commons.cli.*;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
 
 
 /**
 /**
  * ls command for cli
  * ls command for cli
@@ -31,11 +33,12 @@ public class LsCommand extends CliCommand {
 
 
     {
     {
         options.addOption("?", false, "help");
         options.addOption("?", false, "help");
+        options.addOption("s", false, "stat");
         options.addOption("w", false, "watch");
         options.addOption("w", false, "watch");
     }
     }
 
 
     public LsCommand() {
     public LsCommand() {
-        super("ls", "[-w] path");
+        super("ls", "[-s] [-w] path");
     }
     }
 
 
     private void printHelp() {
     private void printHelp() {
@@ -78,8 +81,42 @@ public class LsCommand extends CliCommand {
     public boolean exec() throws KeeperException, InterruptedException {
     public boolean exec() throws KeeperException, InterruptedException {
         String path = args[1];
         String path = args[1];
         boolean watch = cl.hasOption("w");
         boolean watch = cl.hasOption("w");
-        List<String> children = zk.getChildren(path, watch);
-        out.println(children);
+        boolean withStat = cl.hasOption("s");
+        try {
+            Stat stat = new Stat();
+            List<String> children;
+            if (withStat) {
+                // with stat
+                children = zk.getChildren(path, watch, stat);
+            } else {
+                // without stat
+                children = zk.getChildren(path, watch);
+            }
+            out.println(printChildren(children));
+            if (withStat) {
+                new StatPrinter(out).print(stat);
+            }
+        } catch (KeeperException.NoAuthException ex) {
+            err.println(ex.getMessage());
+            watch = false;
+        }
         return watch;
         return watch;
     }
     }
+
+    private String printChildren(List<String> children) {
+        Collections.sort(children);
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        boolean first = true;
+        for (String child : children) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+            sb.append(child);
+        }
+        sb.append("]");
+        return sb.toString();
+    }
 }
 }

+ 1 - 1
src/java/main/org/apache/zookeeper/cli/SetAclCommand.java

@@ -71,7 +71,7 @@ public class SetAclCommand extends CliCommand {
                 new StatPrinter(out).print(stat);
                 new StatPrinter(out).print(stat);
             }
             }
         } catch (KeeperException.InvalidACLException ex) {
         } catch (KeeperException.InvalidACLException ex) {
-            err.println("Invalid ACL: " + aclStr);
+            err.println(ex.getMessage());
         } catch (KeeperException.NoAuthException ex) {
         } catch (KeeperException.NoAuthException ex) {
             err.println(ex.getMessage());
             err.println(ex.getMessage());
         }
         }

+ 25 - 0
src/java/test/org/apache/zookeeper/ZooKeeperTest.java

@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 
 import org.apache.zookeeper.AsyncCallback.VoidCallback;
 import org.apache.zookeeper.AsyncCallback.VoidCallback;
 import org.apache.zookeeper.ZooDefs.Ids;
 import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.cli.LsCommand;
 import org.apache.zookeeper.data.Stat;
 import org.apache.zookeeper.data.Stat;
 import org.apache.zookeeper.test.ClientBase;
 import org.apache.zookeeper.test.ClientBase;
 import org.junit.Assert;
 import org.junit.Assert;
@@ -367,4 +368,28 @@ public class ZooKeeperTest extends ClientBase {
         }
         }
     }
     }
 
 
+    @Test
+    public void testSortedLs() throws Exception {
+        final ZooKeeper zk = createClient();
+        ZooKeeperMain zkMain = new ZooKeeperMain(zk);
+
+        zkMain.executeLine("create /aa1");
+        zkMain.executeLine("create /aa2");
+        zkMain.executeLine("create /aa3");
+        zkMain.executeLine("create /test1");
+        zkMain.executeLine("create /zk1");
+
+        // call ls and put result in byteStream
+        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(byteStream);
+        String lsCmd = "ls /";
+        LsCommand entity = new LsCommand();
+        entity.setZk(zk);
+        entity.setOut(out);
+        entity.parse(lsCmd.split(" ")).exec();
+
+        String result = byteStream.toString();
+        assertTrue(result, result.contains("[aa1, aa2, aa3, test1, zk1, zookeeper]"));
+    }
+
 }
 }