001package org.crsh.util;
002
003import org.crsh.cli.completers.AbstractPathCompleter;
004import org.crsh.text.renderers.BindingRenderer;
005
006import javax.naming.Binding;
007import javax.naming.Context;
008import javax.naming.InitialContext;
009import javax.naming.NamingEnumeration;
010import java.util.*;
011import java.util.regex.Pattern;
012
013/** @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a> */
014public class JNDIHandler {
015
016  public static List<BindingRenderer.BindingData> lookup(List<String> filters, String name, Boolean verbose) {
017
018    Pattern pattern = null;
019    if (name != null) {
020      pattern = Pattern.compile("^" + Utils.globexToRegex(name) + "$");
021    }
022
023    List<BindingRenderer.BindingData> data = new ArrayList<BindingRenderer.BindingData>();
024
025    data.addAll(get(filters, pattern, verbose, ""));
026    data.addAll(get(filters, pattern, verbose, "java:/"));
027    data.addAll(get(filters, pattern, verbose, "java:comp/env/jdbc"));
028    data.addAll(get(filters, pattern, verbose, "java:jboss"));
029    data.addAll(get(filters, pattern, verbose, "java:global"));
030    data.addAll(get(filters, pattern, verbose, "java:app"));
031    data.addAll(get(filters, pattern, verbose, "java:module"));
032
033    return data;
034
035  }
036
037  static List<BindingRenderer.BindingData> get(
038      List<String> filters,
039      Pattern pattern,
040      Boolean verbose,
041      String path) {
042
043    return get(filters, pattern, verbose, path, path, null);
044  }
045
046  static List<BindingRenderer.BindingData> get(
047      List<String> filters,
048      Pattern pattern,
049      Boolean verbose,
050      String path,
051      String search,
052      Context ctx) {
053
054    List<BindingRenderer.BindingData> data = new ArrayList<BindingRenderer.BindingData>();
055
056    try {
057      if (ctx == null) {
058        ctx = new InitialContext();
059      }
060      if (path.length() > 0) {
061        path += "/";
062      }
063
064      NamingEnumeration<Binding> e = ctx.listBindings(search);
065      while (e.hasMoreElements()) {
066        Binding instance = e.next();
067
068        String fullName = path + instance.getName();
069
070        if (
071            filters == null ||
072                filters.size() == 0 ||
073                Utils.instanceOf(instance.getObject().getClass(), filters)) {
074          if (pattern == null || pattern.matcher(fullName).find()) {
075            data.add(new BindingRenderer.BindingData(fullName, instance.getClassName(), instance, verbose));
076          }
077        }
078        if (instance.getObject() instanceof Context) {
079          data.addAll(get(filters, pattern, verbose, fullName, "", (Context) instance.getObject()));
080        }
081
082      }
083
084    }
085    catch (Exception e) {
086    }
087
088    return data;
089  }
090
091  public static class JNDICompleter extends AbstractPathCompleter<String> {
092
093    private final String[] filters;
094    private List<BindingRenderer.BindingData> bindings;
095
096    public JNDICompleter(String... filters) {
097      this.filters = filters;
098      bindings = JNDIHandler.lookup(Arrays.asList(filters), null, true);
099    }
100
101    @Override
102    protected String getCurrentPath() {
103      return "";
104    }
105
106    @Override
107    protected String getPath(String path) {
108      return path;
109    }
110
111    @Override
112    protected boolean exists(String path) {
113      if (path.equals("/") || path.endsWith("/")) {
114        return true;
115      } else {
116        for (BindingRenderer.BindingData binding : bindings) {
117          if (binding.name.startsWith(path.substring(1) + "/")) {
118            return true;
119          }
120        }
121      }
122      return false;
123    }
124
125    @Override
126    protected boolean isDirectory(String path) {
127      if (path.equals("/")) {
128        return true;
129      }
130      if (path.startsWith("/")) {
131        path = path.substring(1);
132      }
133      for (BindingRenderer.BindingData binding : bindings) {
134        if (binding.name.startsWith(path + "/")) {
135          return true;
136        }
137      }
138      return false;
139    }
140
141    @Override
142    protected boolean isFile(String path) {
143      if (path.equals("/")) {
144        return false;
145      }
146      if (path.startsWith("/")) {
147        path = path.substring(1);
148      }
149      if (path.endsWith("/")) {
150        for (BindingRenderer.BindingData binding : bindings) {
151          if (binding.name.equals(path.substring(0, path.length() - 1))) {
152            return true;
153          }
154        }
155      }
156      return false;
157    }
158
159    @Override
160    protected Collection<String> getChilren(String path) {
161      List<String> l = new ArrayList<String>();
162      for (BindingRenderer.BindingData binding : bindings) {
163        if (path.equals("/") || binding.name.startsWith(path.substring(1))) {
164          String completion = binding.name.substring(path.substring(1).length());
165          if (completion.startsWith("/")) {
166            completion = completion.substring(1);
167          }
168          l.add(completion);
169        }
170      }
171      return l;
172    }
173
174    @Override
175    protected String getName(String path) {
176      return path;
177    }
178  }
179
180}