com.effectiveosgi.rt.config.impl.ConfigurationCommands Maven / Gradle / Ivy
The newest version!
package com.effectiveosgi.rt.config.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.felix.service.command.Converter;
import org.apache.felix.service.command.Descriptor;
import org.osgi.framework.Constants;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
public class ConfigurationCommands implements Converter {
private final ConfigurationAdmin configAdmin;
public ConfigurationCommands(ConfigurationAdmin configAdmin) {
this.configAdmin = configAdmin;
}
@Descriptor("List configurations")
public Configuration[] list() throws Exception {
return list(null);
}
@Descriptor("List confgurations")
public Configuration[] list(@Descriptor("PID prefix") String prefix) throws Exception {
Configuration[] configs = configAdmin.listConfigurations(prefix != null ? String.format("(%s=%s*)", Constants.SERVICE_PID, prefix) : null);
if (configs == null)
configs = new Configuration[0];
return configs;
}
// Returns a single Configuration for inspection, or an array of Configuration
// for listing
public Object info(String pid) throws Exception {
Configuration[] configs = configAdmin.listConfigurations(String.format("(%s=%s*)", Constants.SERVICE_PID, pid));
if (configs != null && configs.length == 1)
return configs[0];
return configs;
}
@Override
public Object convert(Class> desiredType, Object in) throws Exception {
return null;
}
@Override
public CharSequence format(Object target, int level, Converter escape) throws Exception {
if (target instanceof Configuration[])
return format((Configuration[]) target, level, escape);
if (target instanceof Configuration)
return format((Configuration) target, level, escape);
return null;
}
private CharSequence format(Configuration[] configs, int level, Converter escape) throws Exception {
final CharSequence result;
switch (level) {
case Converter.INSPECT:
StringBuilder builder = new StringBuilder();
Map> factoryConfigs = new LinkedHashMap<>();
Arrays.stream(configs).sorted(ConfigurationCommands::compareConfigurations).forEach(c -> {
List l = factoryConfigs.get(c.getFactoryPid());
if (l == null) {
l = new LinkedList<>();
factoryConfigs.put(c.getFactoryPid(), l);
}
l.add(c);
});
for (Entry> e : factoryConfigs.entrySet()) {
if (e.getKey() != null) {
builder.append(String.format("%s [%d record(s)]:%n", e.getKey(), e.getValue().size()));
for (Configuration c : e.getValue())
builder.append(" ").append(escape.format(c, Converter.LINE, escape)).append('\n');
} else {
for (Configuration c : e.getValue())
builder.append(escape.format(c, Converter.LINE, escape)).append('\n');
}
}
result = builder;
break;
case Converter.LINE:
result = escape.format(configs, LINE, escape);
break;
case Converter.PART:
default:
throw new UnsupportedOperationException("Requested format for Configuration unsupported");
}
return result;
}
private CharSequence format(Configuration config, int level, Converter escape) throws Exception {
final CharSequence result;
switch (level) {
case Converter.INSPECT:
StringBuilder builder = new StringBuilder();
builder.append(String.format("%s (%d changes) ", config.getPid(), config.getChangeCount()));
builder.append(config.getBundleLocation() != null ? " Bound to: " + config.getBundleLocation() : " Unbound")
.append('\n');
for (Enumeration keys = config.getProperties().keys(); keys.hasMoreElements();) {
String key = keys.nextElement();
Object value = config.getProperties().get(key);
builder.append(" ").append(key).append(':').append(formatType(value)).append("=").append(value)
.append('\n');
}
result = builder;
break;
case Converter.LINE:
result = String.format("%s [%d properties]", config.getPid(), config.getProperties().size());
break;
case Converter.PART:
default:
result = config.getPid();
}
return result;
}
private static final String UNKNOWN_TYPE_NAME = "?";
private String formatType(Object value) {
if (value == null)
return UNKNOWN_TYPE_NAME;
Class> clazz = value.getClass();
if (clazz.isPrimitive() || clazz == String.class)
return clazz.getSimpleName();
if (clazz.isArray())
return formatType(clazz.getComponentType()) + "[]";
if (value instanceof Collection) {
Collection> coll = (Collection>) value;
final String componentTypeName = coll.isEmpty() ? UNKNOWN_TYPE_NAME : formatType(coll.iterator().next());
return String.format("Collection<%s>", componentTypeName);
}
return UNKNOWN_TYPE_NAME;
}
static int compareConfigurations(Configuration a, Configuration b) {
String factoryA = a.getFactoryPid();
String factoryB = b.getFactoryPid();
int result = 0;
if (factoryA != null) {
if (factoryB == null)
result = -1;
else
result = factoryA.compareTo(factoryB);
} else {
if (factoryB == null)
result = 0;
else
result = 1;
}
if (result == 0)
result = a.getPid().compareTo(b.getPid());
return result;
}
}