1 package org.apache.maven.execution.scope.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.IdentityHashMap;
25 import java.util.LinkedList;
26 import java.util.Map;
27
28 import org.apache.maven.execution.MojoExecutionEvent;
29 import org.apache.maven.execution.MojoExecutionListener;
30 import org.apache.maven.execution.scope.WeakMojoExecutionListener;
31 import org.apache.maven.plugin.MojoExecutionException;
32
33 import com.google.inject.Key;
34 import com.google.inject.OutOfScopeException;
35 import com.google.inject.Provider;
36 import com.google.inject.Scope;
37 import com.google.inject.util.Providers;
38
39
40
41
42 public class MojoExecutionScope
43 implements Scope, MojoExecutionListener
44 {
45 private static final Provider<Object> SEEDED_KEY_PROVIDER = new Provider<Object>()
46 {
47 public Object get()
48 {
49 throw new IllegalStateException();
50 }
51 };
52
53 private static final class ScopeState
54 {
55 private final Map<Key<?>, Provider<?>> seeded = new HashMap<>();
56
57 private final Map<Key<?>, Object> provided = new HashMap<>();
58 }
59
60 private final ThreadLocal<LinkedList<ScopeState>> values = new ThreadLocal<>();
61
62 public MojoExecutionScope()
63 {
64 }
65
66 public void enter()
67 {
68 LinkedList<ScopeState> stack = values.get();
69 if ( stack == null )
70 {
71 stack = new LinkedList<>();
72 values.set( stack );
73 }
74 stack.addFirst( new ScopeState() );
75 }
76
77 private ScopeState getScopeState()
78 {
79 LinkedList<ScopeState> stack = values.get();
80 if ( stack == null || stack.isEmpty() )
81 {
82 throw new IllegalStateException();
83 }
84 return stack.getFirst();
85 }
86
87 public void exit()
88 throws MojoExecutionException
89 {
90 final LinkedList<ScopeState> stack = values.get();
91 if ( stack == null || stack.isEmpty() )
92 {
93 throw new IllegalStateException();
94 }
95 stack.removeFirst();
96 if ( stack.isEmpty() )
97 {
98 values.remove();
99 }
100 }
101
102 public <T> void seed( Class<T> clazz, Provider<T> value )
103 {
104 getScopeState().seeded.put( Key.get( clazz ), value );
105 }
106
107 public <T> void seed( Class<T> clazz, final T value )
108 {
109 getScopeState().seeded.put( Key.get( clazz ), Providers.of( value ) );
110 }
111
112 public <T> Provider<T> scope( final Key<T> key, final Provider<T> unscoped )
113 {
114 return new Provider<T>()
115 {
116 @SuppressWarnings( "unchecked" )
117 public T get()
118 {
119 LinkedList<ScopeState> stack = values.get();
120 if ( stack == null || stack.isEmpty() )
121 {
122 throw new OutOfScopeException( "Cannot access " + key + " outside of a scoping block" );
123 }
124
125 ScopeState state = stack.getFirst();
126
127 Provider<?> seeded = state.seeded.get( key );
128
129 if ( seeded != null )
130 {
131 return (T) seeded.get();
132 }
133
134 T provided = (T) state.provided.get( key );
135 if ( provided == null && unscoped != null )
136 {
137 provided = unscoped.get();
138 state.provided.put( key, provided );
139 }
140
141 return provided;
142 }
143 };
144 }
145
146 @SuppressWarnings( { "unchecked" } )
147 public static <T> Provider<T> seededKeyProvider()
148 {
149 return (Provider<T>) SEEDED_KEY_PROVIDER;
150 }
151
152 public void beforeMojoExecution( MojoExecutionEvent event )
153 throws MojoExecutionException
154 {
155 for ( WeakMojoExecutionListener provided : getProvidedListeners() )
156 {
157 provided.beforeMojoExecution( event );
158 }
159 }
160
161 public void afterMojoExecutionSuccess( MojoExecutionEvent event )
162 throws MojoExecutionException
163 {
164 for ( WeakMojoExecutionListener provided : getProvidedListeners() )
165 {
166 provided.afterMojoExecutionSuccess( event );
167 }
168 }
169
170 public void afterExecutionFailure( MojoExecutionEvent event )
171 {
172 for ( WeakMojoExecutionListener provided : getProvidedListeners() )
173 {
174 provided.afterExecutionFailure( event );
175 }
176 }
177
178 private Collection<WeakMojoExecutionListener> getProvidedListeners()
179 {
180
181
182 IdentityHashMap<WeakMojoExecutionListener, Object> listeners =
183 new IdentityHashMap<>();
184 for ( Object provided : getScopeState().provided.values() )
185 {
186 if ( provided instanceof WeakMojoExecutionListener )
187 {
188 listeners.put( (WeakMojoExecutionListener) provided, null );
189 }
190 }
191 return listeners.keySet();
192 }
193 }