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