001 package org.crsh.cmdline.completers;
002
003 import org.crsh.cmdline.ParameterDescriptor;
004 import org.crsh.cmdline.spi.Completer;
005 import org.crsh.cmdline.spi.ValueCompletion;
006
007 import java.util.Collection;
008
009 /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
010 public abstract class AbstractPathCompleter<P> implements Completer {
011
012 protected abstract String getCurrentPath() throws Exception;
013
014 protected abstract P getPath(String path) throws Exception;
015
016 protected abstract boolean exists(P path) throws Exception;
017
018 protected abstract boolean isDirectory(P path) throws Exception;
019
020 protected abstract boolean isFile(P path) throws Exception;
021
022 protected abstract Collection<P> getChilren(P path) throws Exception;
023
024 protected abstract String getName(P path) throws Exception;
025
026 public final ValueCompletion complete(ParameterDescriptor<?> parameter, String prefix) throws Exception {
027
028 // Handle empty dir
029 if (!prefix.startsWith("/")) {
030 String currentPath = getCurrentPath();
031 if (!currentPath.endsWith("/")) {
032 currentPath += "/";
033 }
034 if (prefix.length() > 0) {
035 prefix = currentPath + prefix;
036 } else {
037 prefix = currentPath;
038 }
039 }
040
041 //
042 P f = getPath(prefix);
043
044 //
045 if (exists(f)) {
046 if (isDirectory(f)) {
047 if (prefix.endsWith("/")) {
048 Collection<P> children = getChilren(f);
049 if (children != null) {
050 if (children.size() > 0) {
051 return listDir(f, "");
052 } else {
053 return ValueCompletion.create();
054 }
055 } else {
056 return ValueCompletion.create();
057 }
058 } else {
059 Collection<P> children = getChilren(f);
060 if (children == null) {
061 return ValueCompletion.create();
062 } else {
063 return ValueCompletion.create("/", false);
064 }
065 }
066 } else if (isFile(f)) {
067 return ValueCompletion.create("", true);
068 }
069 return ValueCompletion.create();
070 } else {
071 int pos = prefix.lastIndexOf('/');
072 if (pos != -1) {
073 String filter;
074 if (pos == 0) {
075 f = getPath("/");
076 filter = prefix.substring(1);
077 } else {
078 f = getPath(prefix.substring(0, pos));
079 filter = prefix.substring(pos + 1);
080 }
081 if (exists(f)) {
082 if (isDirectory(f)) {
083 return listDir(f, filter);
084 } else {
085 return ValueCompletion.create();
086 }
087 } else {
088 return ValueCompletion.create();
089 }
090 } else {
091 return ValueCompletion.create();
092 }
093 }
094 }
095
096 private ValueCompletion listDir(P dir, final String filter) throws Exception {
097 Collection<P> children = getChilren(dir);
098 if (children != null) {
099 ValueCompletion map = new ValueCompletion(filter);
100 for (P child : children) {
101 String name = getName(child);
102 if (name.startsWith(filter)) {
103 String suffix = name.substring(filter.length());
104 if (isDirectory(child)) {
105 Collection<P> grandChildren = getChilren(child);
106 if (grandChildren != null) {
107 map.put(suffix + "/", false);
108 } else {
109 // Skip it
110 }
111 } else {
112 map.put(suffix, true);
113 }
114 }
115 }
116 return map;
117 } else {
118 return ValueCompletion.create();
119 }
120 }
121 }