Package net.sourceforge.javautil.lifecycle.impl

Source Code of net.sourceforge.javautil.lifecycle.impl.LifecyclePojo$PojoPhase

package net.sourceforge.javautil.lifecycle.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassMethod;
import net.sourceforge.javautil.lifecycle.ILifecycle;
import net.sourceforge.javautil.lifecycle.ILifecyclePhase;
import net.sourceforge.javautil.lifecycle.ILifecycle.PhaseType;
import net.sourceforge.javautil.lifecycle.annotation.LifecycleRollback;
import net.sourceforge.javautil.lifecycle.annotation.Phase;

/**
* This will allow POJO's (Plain Old Java Object) to annotate methods with {@link Phase}
* that will be executed as part of it's {@link ILifecycle} management. This supports the
* {@link PostConstruct} annotation and maps the corresponding method to the {@link PhaseType#INITIALIZE}
* phase. This also supports the {@link PreDestroy} as an {@link PhaseType#POSTSTOP} equivalent.<br/><br/>
*
* In addition this supports the {@link LifecycleRollback} annotation mapping corresponding roll-back
* methods to the {@link PhaseType}'s specified. If no {@link PhaseType} is specified the method will
* be considered the default roll-back method for all {@link PhaseType} for which other roll-back methods
* are not specified.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class LifecyclePojo<T> extends LifecycleAbstract<T> {
 
  /**
   * The phases that make up the life-cycle of the target POJO
   */
  protected final List<ILifecyclePhase<T>> phases = new ArrayList<ILifecyclePhase<T>>();
  protected final Map<PhaseType, ClassMethod> rollbacks = new LinkedHashMap<PhaseType, ClassMethod>();

  public LifecyclePojo(T managed) {
    super(managed);
   
    boolean initialize = false;
    boolean create = false;
    boolean start = false;
    boolean stop = false;
    boolean destroy = false;

    ClassDescriptor desc = ClassCache.getFor(managed.getClass());
   
    ClassMethod postConstruct = desc.getMethod(PostConstruct.class);
    if (postConstruct != null) {
      this.phases.add(new PojoPhase(PhaseType.INITIALIZE, "Post Construct", 0, postConstruct));
      initialize = true;
    }
   
    ClassMethod preDestroy = desc.getMethod(PreDestroy.class);
    if (preDestroy != null)
      this.phases.add(new PojoPhase(PhaseType.POSTSTOP, "Pre Destroy", 1000, preDestroy));
   
   
    ClassMethod[] methods = desc.getMethods(Phase.class);
    for (ClassMethod method : methods) {
      PojoPhase phase = new PojoPhase(method.getAnnotation(Phase.class), method);
     
      switch (phase.getType()) {
        case INSTANTIATED:
          throw new UnsupportedOperationException("Cannot specify instantiated phase");
         
        case INITIALIZE:
          if (initialize) throw new UnsupportedOperationException("Can only specify one initialize phase"); else initialize = true;
          break;
         
        case CREATE:
          if (create) throw new UnsupportedOperationException("Can only specify one create phase"); else create = true;
          break;

        case START:
          if (start) throw new UnsupportedOperationException("Can only specify one start phase"); else start = true;
          break;

        case STOP:
          if (stop) throw new UnsupportedOperationException("Can only specify one stop phase"); else stop = true;
          break;

        case DESTROY:
          if (destroy) throw new UnsupportedOperationException("Can only specify one destroy phase"); else destroy = true;
          break;
         
        default:
      }
     
      this.phases.add(phase);
    }
   
    ClassMethod[] rollbacks = desc.getMethods(LifecycleRollback.class);
    for (ClassMethod method : rollbacks) {
      LifecycleRollback lr = method.getAnnotation(LifecycleRollback.class);
      if (lr.value().length == 0) this.rollbacks.put(null, method);
      else for (PhaseType type : lr.value()) {
        this.rollbacks.put(type, method);
      }
    }
   
    Collections.sort(phases);
  }
 
  @Override protected ILifecyclePhase<T> getPhase(ILifecycle.PhaseType type) {
    for (int p=0; p<phases.size(); p++) {
      if (phases.get(p).getType() == type) return phases.get(p);
    }
    return null;
  }

  @Override protected List<ILifecyclePhase<T>> getPhases(ILifecycle.PhaseType type) {
    List<ILifecyclePhase<T>> phases = new ArrayList<ILifecyclePhase<T>>();
    for (int p=0; p<this.phases.size(); p++) {
      if (this.phases.get(p).getType() == type) phases.add(this.phases.get(p));
    }
    return phases;
  }
 
  /**
   * A wrapper for the actual Pojo method that will be executed.
   *
   * @author elponderador
   * @author $Author$
   * @version $Id$
   */
  public class PojoPhase<T> extends LifecyclePhaseAbstract<T> {
   
    protected final ClassMethod method;

    public PojoPhase(Phase phase, ClassMethod method) {
      super(phase.value(), phase.description(), phase.priority());
      this.method = method;
    }
   
    public PojoPhase(PhaseType phase, String description, int priority, ClassMethod method) {
      super(phase, description, priority);
      this.method = method;
    }

    public void execute(T target) {
      boolean accessible = method.getJavaMember().isAccessible();
      try {
        if (!accessible) method.getJavaMember().setAccessible(true);
        this.method.invoke(target);
      } finally {
        if (!accessible) method.getJavaMember().setAccessible(false);
      }
    }

    public void rollback(T target) {
      ClassMethod rollback = rollbacks.get(this.type);
      if (rollback == null) rollback = rollbacks.get(null);
     
      if (rollback != null) rollback.invoke(target, this);
    }
   
  }

}
TOP

Related Classes of net.sourceforge.javautil.lifecycle.impl.LifecyclePojo$PojoPhase

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.