1 package org.codehaus.mojo.webstart.dependency;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.codehaus.mojo.webstart.dependency.task.JnlpDependencyTask;
23 import org.codehaus.mojo.webstart.util.IOUtil;
24 import org.codehaus.plexus.component.annotations.Component;
25 import org.codehaus.plexus.component.annotations.Requirement;
26 import org.codehaus.plexus.logging.AbstractLogEnabled;
27 import org.codehaus.plexus.logging.Logger;
28
29 import java.io.File;
30 import java.util.List;
31 import java.util.concurrent.LinkedBlockingQueue;
32 import java.util.concurrent.ThreadPoolExecutor;
33 import java.util.concurrent.TimeUnit;
34
35
36
37
38
39
40
41 @Component( role = JnlpDependencyRequestConsumer.class )
42 public class DefaultJnlpDependencyRequestConsumer
43 extends AbstractLogEnabled
44 implements JnlpDependencyRequestConsumer
45 {
46
47 @Requirement
48 private IOUtil ioUtil;
49
50
51
52
53 public JnlpDependencyResults execute( JnlpDependencyRequestConsumerConfig config, JnlpDependencyRequests requests )
54 {
55
56 getLogger().info( "Process " + requests.getNbRequests() + " dependencies." );
57
58 RequestExecutor executor = new RequestExecutor( getLogger(), ioUtil, config );
59
60 executor.registerRequests( requests.getRequests() );
61
62 JnlpDependencyResults results = executor.terminatesAndWaits();
63
64 return results;
65 }
66
67 private static class RequestExecutor
68 extends ThreadPoolExecutor
69 {
70
71 private final JnlpDependencyRequestConsumerConfig config;
72
73 private final Logger logger;
74
75 private final IOUtil ioUtil;
76
77 private final JnlpDependencyResults results;
78
79 public RequestExecutor( Logger logger, IOUtil ioUtil, JnlpDependencyRequestConsumerConfig config )
80 {
81 super( config.getMaxThreads(), config.getMaxThreads(), 1L, TimeUnit.SECONDS,
82 new LinkedBlockingQueue<Runnable>() );
83 this.logger = logger;
84 this.ioUtil = ioUtil;
85 this.config = config;
86 this.results = new JnlpDependencyResults();
87 }
88
89
90 @Override
91 protected void afterExecute( Runnable r, Throwable t )
92 {
93 super.afterExecute( r, t );
94 RequestTask task = (RequestTask) r;
95
96 JnlpDependencyResult result = task.result;
97
98 results.registerResult( task.request, result );
99
100 boolean withError = t != null;
101
102 if ( withError )
103 {
104 result.setError( t );
105
106 if ( config.isFailFast() )
107 {
108 logger.warn( "Fail fast after first dependency processing error." );
109
110
111 shutdownNow();
112 }
113 }
114
115
116 }
117
118
119
120
121
122
123
124
125
126 public JnlpDependencyResults terminatesAndWaits()
127 {
128
129 shutdown();
130
131 try
132 {
133
134
135 awaitTermination( 2 * 60 * 60 * 24, TimeUnit.SECONDS );
136 }
137 catch ( InterruptedException e )
138 {
139 logger.error( "Could not stop the executor after two days...", e );
140 }
141
142 return results;
143 }
144
145 public void registerRequests( List<JnlpDependencyRequest> dependencyRequests )
146 {
147
148 for ( JnlpDependencyRequest dependencyRequest : dependencyRequests )
149 {
150 RequestTask newtask = new RequestTask( logger, ioUtil, dependencyRequest );
151
152 JnlpDependencyResult result = newtask.result;
153 if ( result.isUptodate() )
154 {
155 if ( config.isVerbose() )
156 {
157 logger.info(
158 "Skip up-to-date dependency: " + dependencyRequest.getConfig().getArtifact().getId() );
159 }
160 results.registerResult( newtask.request, result );
161 }
162 else
163 {
164 if ( config.isVerbose() )
165 {
166 logger.info( "Process dependency: " + dependencyRequest.getConfig().getArtifact().getId() );
167 }
168 execute( newtask );
169 }
170 }
171 }
172 }
173
174
175 private static class RequestTask
176 implements Runnable
177 {
178
179 private final Logger logger;
180
181 private final IOUtil ioUtil;
182
183 private final JnlpDependencyRequest request;
184
185 private JnlpDependencyResult result;
186
187 private RequestTask( Logger logger, IOUtil ioUtil, JnlpDependencyRequest request )
188 {
189 this.logger = logger;
190 this.ioUtil = ioUtil;
191 this.request = request;
192 this.result = new JnlpDependencyResult( request );
193 }
194
195
196
197
198 public void run()
199 {
200 JnlpDependencyConfig config = request.getConfig();
201
202 File workingFile = request.getOriginalFile();
203
204 try
205 {
206
207 ioUtil.copyFile( config.getArtifact().getFile(), workingFile );
208
209 File workingDirectory = config.getWorkingDirectory();
210
211 JnlpDependencyTask[] tasks = request.getTasks();
212
213 for ( int i = 0, length = tasks.length; i < length; i++ )
214 {
215
216 JnlpDependencyTask task = tasks[i];
217
218
219 File newDirectory = new File( workingDirectory, i + "_" + task.getClass().getSimpleName() );
220 ioUtil.copyFileToDirectoryIfNecessary( workingFile, newDirectory );
221
222 workingFile = new File( newDirectory, workingFile.getName() );
223
224 logger.debug( String.format( "[task %s] (%s): workingFile: %s", i, task, workingFile ) );
225
226 workingFile = task.execute( config, workingFile );
227 }
228
229
230 ioUtil.copyFile( workingFile, request.getFinalFile() );
231 }
232 catch ( Exception e )
233 {
234 result.setError( e );
235 }
236
237 logger.info( "Dependency " + config.getArtifact().getId() + " treated." );
238 }
239 }
240 }