001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019 package org.crsh.cmdline.completers;
020
021 import java.util.HashSet;
022 import java.util.Set;
023
024 import javax.naming.InitialContext;
025 import javax.naming.NameClassPair;
026 import javax.naming.NamingEnumeration;
027 import javax.naming.NamingException;
028
029 import org.crsh.cmdline.ParameterDescriptor;
030 import org.crsh.cmdline.spi.Completer;
031 import org.crsh.cmdline.spi.ValueCompletion;
032
033 public class JNDICompleter implements Completer {
034
035 /**
036 * Create a list of context name to search in JNDI, e.g :contextName ["java:jboss/datasources", "",...]
037 * This list contains standard names to help search.
038 */
039 private static HashSet<String> initJndicontextNames() {
040 HashSet<String> contextNames = new HashSet<String>();
041 contextNames.add("java:jboss/");
042 contextNames.add("java:comp/env/jdbc");
043 contextNames.add("java:/");
044 contextNames.add("");
045 return contextNames;
046 }
047
048
049 public ValueCompletion complete(ParameterDescriptor<?> parameter,
050 String prefix) throws Exception {
051 if (null == prefix) {
052 prefix = "";
053 }
054 return getJndiList(prefix);
055 }
056
057 /**
058 * Search JNDI Path in Context and put the result in ValueCompletion.
059 *
060 * @return ValueCompletion
061 */
062 ValueCompletion getJndiList(String prefix) {
063 HashSet<String> contextNames = initJndicontextNames();
064 if (prefix != null) {
065 contextNames.add(prefix);
066 }
067 ValueCompletion completions = new ValueCompletion();
068 for (String contextName : contextNames) {
069
070 if (!contextName.endsWith("/")) {
071 contextName = contextName + "/";
072 }
073
074 try {
075 InitialContext ctx = new InitialContext();
076 NamingEnumeration<NameClassPair> list = ctx.list(contextName);
077 while (list.hasMore()) {
078 NameClassPair nc = list.next();
079 if (null == nc) {
080 continue;
081 }
082 String jndiPath = getJndiPath(contextName, nc.getName(), prefix);
083 if (jndiPath != null) {
084 completions.put(jndiPath, false);
085 }
086
087 }
088 } catch (NamingException e1) {
089 // We display nothing if there is no data source
090 }
091 }
092 return completions;
093 }
094
095 /**
096 * Make JndiPath String.
097 *
098 * @param contextName String (e.g:java:jboss/)
099 * @param ncName (e.g:datasources)
100 * @return String (e.g:java:jboss/datasources)
101 */
102 public String getJndiPath(String contextName, String ncName, String prefix) {
103 String result;
104 if ((null == contextName) || (null == ncName) || (null == prefix)) {
105 throw new IllegalArgumentException("Argument(s) must not be null");
106 }
107
108 if (ncName.isEmpty()) {
109 result = contextName;
110 } else {
111 result = contextName + ncName;
112 }
113
114 if (!prefix.isEmpty()) {
115 final int prefixSize = prefix.length();
116 final int resultSize = result.length();
117 String str = null;
118
119 if (result.startsWith(prefix)) {
120 if ((prefixSize > 0) && (resultSize > prefixSize)) {
121 str = result.substring(prefixSize);
122 }
123 } else if (prefix.startsWith(result)) {
124 if ((resultSize > 0) && (prefixSize < resultSize)) {
125 str = prefix.substring(resultSize);
126 }
127 } else {
128 str = null;
129 }
130 result = str;
131 }
132 return result;
133 }
134 }