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 }