1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockito.internal.configuration.injection; 7 8 import java.lang.reflect.Field; 9 import java.util.Set; 10 11 /** 12 * Injector strategy contract 13 */ 14 public abstract class MockInjectionStrategy { 15 16 /** 17 * NOP Strategy that will always try the next strategy. 18 */ nop()19 public static MockInjectionStrategy nop() { 20 return new MockInjectionStrategy() { 21 protected boolean processInjection(Field field, Object fieldOwner, Set<Object> mockCandidates) { 22 return false; 23 } 24 }; 25 } 26 27 28 private MockInjectionStrategy nextStrategy; 29 30 /** 31 * Enqueue next injection strategy. 32 * 33 * <p> 34 * The implementation should take care of the actual calling if required. 35 * </p> 36 * 37 * @param strategy Queued strategy. 38 * @return The passed strategy instance to allow chaining. 39 */ 40 public MockInjectionStrategy thenTry(MockInjectionStrategy strategy) { 41 if(nextStrategy != null) { 42 nextStrategy.thenTry(strategy); 43 } else { 44 nextStrategy = strategy; 45 } 46 return strategy; 47 } 48 49 /** 50 * Actually inject mockCandidates on field. 51 * 52 * <p> 53 * Actual algorithm is defined in the implementations of {@link #processInjection(Field, Object, Set)}. 54 * However if injection occurred successfully, the process should return <code>true</code>, 55 * and <code>false</code> otherwise. 56 * </p> 57 * 58 * <p> 59 * The code takes care of calling the next strategy if available and if of course if required 60 * </p> 61 * 62 * @param onField Field needing injection. 63 * @param fieldOwnedBy The owning instance of the field. 64 * @param mockCandidates A set of mock candidate, that might be injected. 65 * @return <code>true</code> if successful, <code>false</code> otherwise. 66 */ 67 public boolean process(Field onField, Object fieldOwnedBy, Set<Object> mockCandidates) { 68 if(processInjection(onField, fieldOwnedBy, mockCandidates)) { 69 return true; 70 } 71 return relayProcessToNextStrategy(onField, fieldOwnedBy, mockCandidates); 72 } 73 74 /** 75 * Process actual injection. 76 * 77 * <p> 78 * Don't call this method directly, instead call {@link #process(Field, Object, Set)} 79 * </p> 80 * 81 * @param field Field needing injection 82 * @param fieldOwner Field owner instance. 83 * @param mockCandidates Pool of mocks to inject. 84 * @return <code>true</code> if injection occurred, <code>false</code> otherwise 85 */ 86 protected abstract boolean processInjection(Field field, Object fieldOwner, Set<Object> mockCandidates); 87 88 private boolean relayProcessToNextStrategy(Field field, Object fieldOwner, Set<Object> mockCandidates) { 89 return nextStrategy != null && nextStrategy.process(field, fieldOwner, mockCandidates); 90 } 91 } 92