private ServiceRegistration registerConfigurationListener()

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;
    }