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

com.avaje.ebean.WithStaticFinder Maven / Gradle / Ivy

package com.avaje.ebean;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * Used to replace a "Finder" that is located as a static field (typically on an Model entity bean).
 * 

* This uses reflection to get/set the finder implementation with the ability to replace the original implementation * with the test double and restoring the original. */ public class WithStaticFinder { Class beanType; String fieldName; Field field; Object original; Object testDouble; /** * Construct with a given bean type. */ public WithStaticFinder(Class beanType) { this.beanType = beanType; } /** * Construct with a given bean type. */ public WithStaticFinder(Class beanType, String fieldName) { this.beanType = beanType; this.fieldName = fieldName; } /** * Set the test double instance to use after useTestDouble() has been called. *

* Note that the test double instance is not set until useTestDouble() is called. */ public WithStaticFinder as(Object testDouble) throws FinderFieldNotFoundException { try { this.testDouble = testDouble; this.field = findField(); this.field.setAccessible(true); try { Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } this.original = field.get(null); return this; } catch (IllegalAccessException e) { throw new RuntimeException(e); } } /** * Set the test double to the field using reflection. *

* After this the test double will be used by calling code. */ public void useTestDouble() { try { this.field.set(null, testDouble); } catch (IllegalAccessException e) { throw new FinderIllegalAccessException(e); } } /** * Restore the original implementation using reflection. */ public void restoreOriginal() { try { this.field.set(null, original); } catch (IllegalAccessException e) { throw new FinderIllegalAccessException(e); } } /** * Find and return the "find" field. */ protected Field findField() throws FinderFieldNotFoundException { try { if (fieldName != null) { return beanType.getField(fieldName); } try { return beanType.getField("find"); } catch (NoSuchFieldException e) { return beanType.getField("FIND"); } } catch (NoSuchFieldException e) { throw new FinderFieldNotFoundException(e); } } /** * Set the given test double onto the given class returning the WithStaticFinder. *

* Use restore to put the original finder back onto the class. *

* *
{@code
   *
   *   // Replace the finder with TDCustFinder
   *   WithStaticFinder with = WithStaticFinder.use(Customer.class, new TDCustFinder());
   *   try {
   *     // perform some test
   *     Customer jim = Customer.find.byName("jim");
   *
   *   } finally {
   *     // restore the original finder
   *     with.restoreOriginal();
   *   }
   *
   * }
*/ public static WithStaticFinder use(Class cls, Object testFinder) { WithStaticFinder with = new WithStaticFinder<>(cls); with.as(testFinder); with.useTestDouble(); return with; } }