Package org.springframework.osgi.compendium.internal

Source Code of org.springframework.osgi.compendium.internal.OsgiConfig

package org.springframework.osgi.compendium.internal;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.osgi.context.BundleContextAware;
import org.springframework.osgi.util.OsgiServiceUtils;
import org.springframework.osgi.util.internal.MapBasedDictionary;
import org.springframework.util.Assert;

/**
* Configuration admin trigger.
*
* @author Hal Hildebrand
*/
public class OsgiConfig implements InitializingBean, BeanFactoryAware, BundleContextAware, DisposableBean {

  public static class ConfigListener {
    private String reference;

    private String updateMethod;

    private String deletedMethod;

    private Object bean;

    public void setReference(String reference) {
      this.reference = reference;
    }

    public void setUpdateMethod(String updateMethod) {
      this.updateMethod = updateMethod;
    }

    public void setDeletedMethod(String deletedMethod) {
      this.deletedMethod = deletedMethod;
    }

    void resolve(BeanFactory beanFactory, boolean isFactory) {
      bean = beanFactory.getBean(reference);
      if (isFactory) {
        try {
          bean.getClass().getMethod(updateMethod, new Class[] { String.class, Map.class });
        }
        catch (NoSuchMethodException e) {
          try {
            bean.getClass().getMethod(updateMethod, new Class[] { String.class, Dictionary.class });
          }
          catch (NoSuchMethodException e1) {
            IllegalArgumentException illArgEx = new IllegalArgumentException(
                "Invalid or missing update method for bean " + reference + "; requires signature "
                    + updateMethod + "(java.util.Dictionary) or " + updateMethod
                    + "(java.util.Map)");
            illArgEx.initCause(e);
            throw illArgEx;
          }
        }
      }
      else {
        try {
          bean.getClass().getMethod(updateMethod, new Class[] { Map.class });
        }
        catch (NoSuchMethodException e) {
          try {
            bean.getClass().getMethod(updateMethod, new Class[] { Dictionary.class });
          }
          catch (NoSuchMethodException e1) {
            IllegalArgumentException illArgEx = new IllegalArgumentException(
                "Invalid or missing update method for bean " + reference + "; requires signature "
                    + updateMethod + "(java.util.Dictionary) or " + updateMethod
                    + "(java.util.Map)");
            illArgEx.initCause(e);
            throw illArgEx;
          }
        }
      }
      if (deletedMethod != null) {
        try {
          bean.getClass().getMethod(deletedMethod, new Class[] { String.class });
        }
        catch (NoSuchMethodException e) {
          IllegalArgumentException illArgEx = new IllegalArgumentException(
              "Invalid or missing deleted method for bean " + reference + "; requires signature "
                  + deletedMethod + "(java.lang.String)");
          illArgEx.initCause(e);
          throw illArgEx;
        }
      }
    }

    void updated(String instancePid, Dictionary properties) throws ConfigurationException {
      Method update;
      MapBasedDictionary props = new MapBasedDictionary(properties);
      try {
        update = bean.getClass().getMethod(updateMethod, new Class[] { String.class, Map.class });
      }
      catch (NoSuchMethodException e) {
        try {
          update = bean.getClass().getMethod(updateMethod, new Class[] { String.class, Dictionary.class });
        }
        catch (NoSuchMethodException e1) {
          throw new ConfigurationException(instancePid, "Invalid or missing update method for bean "
              + reference + "; requires signature " + updateMethod
              + "(java.util.String, java.util.Dictionary) or " + updateMethod + "(java.util.Map)", e);
        }
      }

      try {
        update.invoke(bean, new Object[] { instancePid, props });
      }
      catch (IllegalAccessException e) {
        throw new ConfigurationException(instancePid, "Insufficient permission to invoke update method", e);
      }
      catch (InvocationTargetException e) {
        throw new ConfigurationException(instancePid, "Error updating", e.getTargetException());
      }
    }

    void updated(Dictionary properties, String servicePid) throws ConfigurationException {
      Method update;
      MapBasedDictionary props = new MapBasedDictionary(properties);
      try {
        update = bean.getClass().getMethod(updateMethod, new Class[] { Map.class });
      }
      catch (NoSuchMethodException e) {
        try {
          update = bean.getClass().getMethod(updateMethod, new Class[] { Dictionary.class });
        }
        catch (NoSuchMethodException e1) {
          throw new ConfigurationException(servicePid, "Invalid or missing update method for bean "
              + reference + "; requires signature " + updateMethod + "(java.util.Dictionary) or "
              + updateMethod + "(java.util.Map)", e);
        }
      }

      try {
        update.invoke(bean, new Object[] { props });
      }
      catch (IllegalAccessException e) {
        throw new ConfigurationException(servicePid, "Insufficient permission to invoke update method", e);
      }
      catch (InvocationTargetException e) {
        throw new ConfigurationException(servicePid, "Error updating", e.getTargetException());
      }
    }

    void deleted(String instancePid) {
      if (deletedMethod == null) {
        return;
      }
      Method deleted;
      try {
        deleted = bean.getClass().getMethod(deletedMethod, new Class[] { String.class });
      }
      catch (NoSuchMethodException e) {
        throw (IllegalStateException) new IllegalStateException("Invalid or missing deleted method for bean "
            + reference + "; requires signature " + deletedMethod + "(java.lang.String)").initCause(e);
      }

      try {
        deleted.invoke(bean, new Object[] { instancePid });
      }
      catch (IllegalAccessException e) {
        throw (IllegalStateException) new IllegalStateException(
            "Insufficient permission to invoke deleted method").initCause(e);
      }
      catch (InvocationTargetException e) {
        throw (IllegalStateException) new IllegalStateException("Error deleting").initCause(e.getTargetException());
      }
    }
  }

  private class OsgiManagedServiceUpdater implements ManagedService {
    public void updated(Dictionary properties) throws ConfigurationException {
      for (Iterator l = listeners.iterator(); l.hasNext();) {
        ConfigListener listener = (ConfigListener) l.next();
        listener.updated(properties, pid);
      }

    }
  }

  private class OsgiManagedServiceFactoryUpdater implements ManagedServiceFactory {
    public void deleted(String instancePid) {
      for (Iterator l = listeners.iterator(); l.hasNext();) {
        ConfigListener listener = (ConfigListener) l.next();
        listener.deleted(instancePid);
      }
    }

    public String getName() {
      return "Managed service factory updater for: [" + pid + "]";
    }

    public void updated(String instancePid, Dictionary properties) throws ConfigurationException {
      for (Iterator l = listeners.iterator(); l.hasNext();) {
        ConfigListener listener = (ConfigListener) l.next();
        listener.updated(instancePid, properties);
      }
    }
  }

  private String pid;

  private List listeners;

  private BeanFactory beanFactory;

  private boolean factory = false;

  private BundleContext bundleContext;

  private ServiceRegistration registration;

  private static final Log log = LogFactory.getLog(OsgiConfig.class);

  public void afterPropertiesSet() throws Exception {
    Assert.notNull(pid, "persistence id property is required");
    for (Iterator l = listeners.iterator(); l.hasNext();) {
      ConfigListener listener = (ConfigListener) l.next();
      listener.resolve(beanFactory, factory);
    }
    Dictionary props = new MapBasedDictionary();
    props.put(Constants.SERVICE_PID, pid);

    if (factory) {
      registration = bundleContext.registerService(ManagedServiceFactory.class.getName(), new OsgiManagedServiceFactoryUpdater(),
        props);
    }
    else {
      registration = bundleContext.registerService(ManagedService.class.getName(), new OsgiManagedServiceUpdater(), props);
    }
  }

  public void destroy() throws Exception {
    OsgiServiceUtils.unregisterService(registration);
  }

  public void setBundleContext(BundleContext context) {
    bundleContext = context;
  }

  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory;
  }

  public void setListeners(List listeners) {
    this.listeners = listeners;
  }

  public void setPid(String pid) {
    this.pid = pid;
  }

  public void setFactory(boolean factory) {
    this.factory = factory;
  }

}
TOP

Related Classes of org.springframework.osgi.compendium.internal.OsgiConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.