All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xj4.lifecycle.LifecycleManager Maven / Gradle / Ivy

/**
 * Copyright 2008 Peach Jean Solutions
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xj4.lifecycle;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

import org.xj4.XJ4TestClass;
import org.xj4.util.ServiceLoader;
import org.xj4.spi.TestWrapper;
import org.xj4.spi.MethodWrapperSource;
import org.xj4.spi.ClassWrapperSource;
import org.xj4.spi.TestClassValidator;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.junit.runners.model.FrameworkMethod;

/**
 * Management class responsible for actually running the lifecycle methods of managed field.  This is the brains of the
 * lifecycle module.
 *
 * @author Jared Bunting
 */
class LifecycleManager implements ClassWrapperSource, MethodWrapperSource, TestClassValidator {

  private static final Log logger = LogFactory.getLog(LifecycleManager.class);

  private ServiceLoader providers = new ServiceLoader(LifecycleProvider.class);

  public List generateWrapper(XJ4TestClass testClass, FrameworkMethod method, Object target) {
    return generateWrappers(testClass, LifecycleType.INSTANCE, target);
  }

  public List generateWrapper(XJ4TestClass testClass) {
    return generateWrappers(testClass, LifecycleType.CLASS, null);
  }

  public void validate(XJ4TestClass testClass, List errors) {
    for(LifecycleDescriptor descriptor: generateDescriptors(testClass)) {
      descriptor.validate(errors);
    }
    for(FrameworkMethod method: testClass.getAnnotatedMethods(PreemptLifecycle.class)) {
      method.validatePublicVoidNoArg(Modifier.isStatic(method.getMethod().getModifiers()), errors);
    }
  }

  protected List generateDescriptors(XJ4TestClass testClass) {
    List descriptors = new ArrayList();
    for(Field field : retrieveManagedFields(testClass)) {
      descriptors.add(new LifecycleDescriptor(testClass, field, providers));
    }
    for(LifecycleDescriptor target: descriptors) {
      for(Class dependentType: target.getDependentClasses()) {
        for(LifecycleDescriptor candidate: descriptors) {
          if(candidate.satisfiesDependency(dependentType)) {
            target.satisfyDependency(dependentType, candidate);
            break;
          }
        }
      }
    }
    Collections.sort(descriptors);
    return descriptors;
  }

  protected List generateWrappers(XJ4TestClass testClass, LifecycleType lifecycleType, Object target) {
    List wrappers = new ArrayList();
    for(LifecycleDescriptor descriptor: generateDescriptors(testClass)) {
      if(lifecycleType.supports(descriptor)) {
        wrappers.addAll(descriptor.generateTestWrappers(target));
      }
    }
    return wrappers;
  }

  protected List retrieveManagedFields(XJ4TestClass testClass) {
    List fields = testClass.getAnnotatedFields(Manage.class);
    logger.debug("Found " + fields.size() + " managed fields.");
    return fields;
  }

  protected enum LifecycleType {
    CLASS() {
      public boolean supports(LifecycleDescriptor descriptor) {
        return !descriptor.isInstance();
      }
      public boolean supports(FrameworkMethod frameworkMethod) {
        return Modifier.isStatic(frameworkMethod.getMethod().getModifiers());
      }},
    INSTANCE() {
      public boolean supports(LifecycleDescriptor descriptor) {
        return descriptor.isInstance();
      }
      public boolean supports(FrameworkMethod frameworkMethod) {
        return !Modifier.isStatic(frameworkMethod.getMethod().getModifiers()); 
      }};

    public abstract boolean supports(LifecycleDescriptor descriptor);

    public abstract boolean supports(FrameworkMethod frameworkMethod);
  }

  protected List generateCustomTestWrapper(XJ4TestClass testClass, LifecycleType lifecycleType, Object target) {
    List methods = testClass.getAnnotatedMethods(PreemptLifecycle.class);
    List wrappers = new ArrayList();
    for(FrameworkMethod method: methods) {
      if(lifecycleType.supports(method)) {
        wrappers.add(new CustomTestWrapper(method, target));
      }
    }
    return wrappers;
  }

  private class CustomTestWrapper implements TestWrapper {
    private FrameworkMethod method;
    private Object target;

    private CustomTestWrapper(FrameworkMethod method, Object target) {
      this.method = method;
      this.target = target;
    }

    public void doBefore() throws Throwable {
      if(valid(PreemptLifecycle.ConditionType.BEFORE)) {
        method.invokeExplosively(target);
      }
    }

    public void doAfter() throws Throwable {
      if(valid(PreemptLifecycle.ConditionType.AFTER)) {
        method.invokeExplosively(target);
      }
    }

    private boolean valid(PreemptLifecycle.ConditionType type) {
      for(PreemptLifecycle.ConditionType configured: method.getAnnotation(PreemptLifecycle.class).value()) {
        if(configured == type) {
          return true;
        }
      }
      return false;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy