in src/main/java/org/apache/sling/feature/apiregions/impl/Activator.java [253:331]
private ServiceRegistration<?> registerConfigurationListener(final Object cfgAdmin) {
try {
final Class<?> listenerClass = cfgAdmin.getClass().getClassLoader().loadClass(CFG_LISTENER_CLASS_NAME);
// ConfigurationEvent
final Class<?> eventClass = cfgAdmin.getClass().getClassLoader().loadClass(CFG_EVENT_CLASS_NAME);
final Method eventGetTypeMethod = eventClass.getMethod("getType");
final Method eventGetFactoryPidMethod = eventClass.getDeclaredMethod("getFactoryPid");
final Method eventGetPidMethod = eventClass.getDeclaredMethod("getPid");
// ConfigurationAdmin
final Method caGetConfigMethod = cfgAdmin.getClass().getDeclaredMethod("getConfiguration", String.class, String.class);
final Method caListConfigcMethod = cfgAdmin.getClass().getDeclaredMethod("listConfigurations", String.class);
// Configuration
final Class<?> cfgClass = cfgAdmin.getClass().getClassLoader().loadClass(CFG_CLASS_NAME);
final Method cfgGetPropertiesMethod = cfgClass.getDeclaredMethod("getProperties");
final Method cfgGetPidMethod = cfgClass.getDeclaredMethod("getPid");
Object msf = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[] {listenerClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?> mdDecl = method.getDeclaringClass();
if (mdDecl.equals(Object.class)) {
switch (method.getName()) {
case "equals" :
return proxy == args[0];
case "hashCode" :
return System.identityHashCode(proxy);
case "toString" :
return "Proxy for " + listenerClass;
default :
throw new UnsupportedOperationException("Method " + method
+ " not supported on proxy for " + listenerClass);
}
}
if ("configurationEvent".equals(method.getName()) && args.length == 1) {
// configuration event
final Object event = args[0];
// check factory pid first
final String factoryPid = (String)eventGetFactoryPidMethod.invoke(event, (Object[])null);
if ( FACTORY_PID.equals(factoryPid) ) {
final String pid = (String)eventGetPidMethod.invoke(event, (Object[])null);
final Object eventType = eventGetTypeMethod.invoke(event, (Object[])null);
if (eventType.equals(1)) {
// update
final Object cfg = caGetConfigMethod.invoke(cfgAdmin, new Object[] {pid, null});
@SuppressWarnings("unchecked")
final Dictionary<String, Object> props = (Dictionary<String, Object>)cfgGetPropertiesMethod.invoke(cfg, (Object[])null);
configuration.setConfig(pid, props);
} else if ( eventType.equals(2)) {
// delete
configuration.removeConfig(pid);
}
}
}
return null;
}
});
final ServiceRegistration<?> reg = bundleContext.registerService(CFG_LISTENER_CLASS_NAME, msf, null);
// get existing configurations
final Object result = caListConfigcMethod.invoke(cfgAdmin, "(service.factoryPid=" + FACTORY_PID + ")");
if ( result != null ) {
for(int i=0; i<Array.getLength(result); i++) {
final Object cfg = Array.get(result, i);
final String pid = (String)cfgGetPidMethod.invoke(cfg, (Object[])null);
@SuppressWarnings("unchecked")
final Dictionary<String, Object> props = (Dictionary<String, Object>)cfgGetPropertiesMethod.invoke(cfg, (Object[])null);
configuration.setConfig(pid, props);
}
}
return reg;
} catch (Exception e) {
LOG.log(Level.SEVERE, "Problem attempting to register configuration lister for " + cfgAdmin, e);
}
return null;
}