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