/*
* Copyright (C) 2012 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.crsh.cli.completers;
import org.crsh.cli.descriptor.ParameterDescriptor;
import org.crsh.cli.spi.Completer;
import org.crsh.cli.spi.Completion;
import org.crsh.cli.type.ValueType;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @author Julien Viet
*/
public class ObjectNameCompleter implements Completer {
private static String[] parseKeyValue(String s) {
int eq = s.indexOf('=');
if (eq == -1) {
return new String[]{s, null};
} else {
return new String[]{s.substring(0, eq), s.substring(eq + 1, s.length())};
}
}
@Override
public Completion complete(ParameterDescriptor parameter, String prefix) throws Exception {
if (parameter.getType() == ValueType.OBJECT_NAME) {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
int colon = prefix.indexOf(':');
if (colon == -1) {
Completion.Builder b = new Completion.Builder(prefix);
LinkedHashSet<String> domains = new LinkedHashSet<String>();
for (ObjectName name : server.queryNames(null, null)) {
domains.add(name.getDomain());
}
for (String domain : domains) {
if (domain.startsWith(prefix)) {
b.add(domain.substring(prefix.length()) + ":", false);
}
}
return b.build();
} else {
String domain = prefix.substring(0, colon);
String rest = prefix.substring(colon + 1);
int prev = 0;
Hashtable<String, String> keyValues = new Hashtable<String, String>();
while (true) {
int next = rest.indexOf(',', prev);
if (next == -1) {
String[] keyValue = parseKeyValue(rest.substring(prev));
Set<ObjectName> completions = new HashSet<ObjectName>();
for (ObjectName name : server.queryNames(null, null)) {
if (name.getDomain().equals(domain) && name.getKeyPropertyList().entrySet().containsAll(keyValues.entrySet())) {
completions.add(name);
}
}
if (keyValue[1] == null) {
Completion.Builder b = new Completion.Builder(keyValue[0]);
for (ObjectName name : completions) {
for (String key : name.getKeyPropertyList().keySet()) {
if (!keyValues.containsKey(key) && key.startsWith(keyValue[0])) {
b.add(key.substring(keyValue[0].length()) + "=", false);
}
}
}
return b.build();
} else {
Completion.Builder b = new Completion.Builder(keyValue[1]);
for (ObjectName completion : completions) {
String value = completion.getKeyProperty(keyValue[0]);
if (value != null && value.startsWith(keyValue[1])) {
Hashtable<String, String> a = completion.getKeyPropertyList();
a.remove(keyValue[0]);
a.keySet().removeAll(keyValues.keySet());
if (a.isEmpty()) {
b.add(value.substring(keyValue[1].length()), true);
} else {
b.add(value.substring(keyValue[1].length()) + ",", false);
}
}
}
return b.build();
}
} else {
String[] keyValue = parseKeyValue(rest.substring(prev, next));
keyValues.put(keyValue[0], keyValue[1]);
prev = next + 1;
}
}
}
} else {
return Completion.create();
}
}
}