1 package org.apache.continuum.installation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Properties;
30
31 import javax.annotation.Resource;
32
33 import org.apache.continuum.dao.InstallationDao;
34 import org.apache.maven.continuum.execution.ExecutorConfigurator;
35 import org.apache.maven.continuum.installation.AlreadyExistsInstallationException;
36 import org.apache.maven.continuum.installation.InstallationException;
37 import org.apache.maven.continuum.installation.InstallationService;
38 import org.apache.maven.continuum.model.system.Installation;
39 import org.apache.maven.continuum.model.system.Profile;
40 import org.apache.maven.continuum.profile.AlreadyExistsProfileException;
41 import org.apache.maven.continuum.profile.ProfileException;
42 import org.apache.maven.continuum.profile.ProfileService;
43 import org.apache.maven.continuum.store.ContinuumStoreException;
44 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
45 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
46 import org.codehaus.plexus.util.StringUtils;
47 import org.codehaus.plexus.util.cli.CommandLineException;
48 import org.codehaus.plexus.util.cli.CommandLineUtils;
49 import org.codehaus.plexus.util.cli.Commandline;
50 import org.codehaus.plexus.util.cli.StreamConsumer;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.springframework.stereotype.Service;
54
55
56
57
58
59
60
61 @Service("installationService")
62 public class DefaultInstallationService
63 implements InstallationService, Initializable
64 {
65 private static final Logger log = LoggerFactory.getLogger( DefaultInstallationService.class );
66
67 @Resource
68 private InstallationDao installationDao;
69
70 @Resource
71 private ProfileService profileService;
72
73 private Map<String, ExecutorConfigurator> typesValues;
74
75
76
77
78
79 public void initialize()
80 throws InitializationException
81 {
82 this.typesValues = new HashMap<String, ExecutorConfigurator>();
83 this.typesValues.put( InstallationService.ANT_TYPE,
84 new ExecutorConfigurator( "ant", "bin", "ANT_HOME", "-version" ) );
85
86 this.typesValues.put( InstallationService.ENVVAR_TYPE, null );
87 this.typesValues.put( InstallationService.JDK_TYPE,
88 new ExecutorConfigurator( "java", "bin", "JAVA_HOME", "-version" ) );
89 this.typesValues.put( InstallationService.MAVEN1_TYPE,
90 new ExecutorConfigurator( "maven", "bin", "MAVEN_HOME", "-v" ) );
91 this.typesValues.put( InstallationService.MAVEN2_TYPE,
92 new ExecutorConfigurator( "mvn", "bin", "M2_HOME", "-v" ) );
93 }
94
95
96
97
98 public Installation add( Installation installation )
99 throws InstallationException, AlreadyExistsInstallationException
100 {
101 try
102 {
103 return this.add( installation, false );
104 }
105 catch ( AlreadyExistsProfileException e )
106 {
107
108 throw new InstallationException( e.getMessage(), e );
109 }
110 }
111
112 public Installation add( Installation installation, boolean automaticProfile )
113 throws InstallationException, AlreadyExistsProfileException, AlreadyExistsInstallationException
114 {
115 if ( alreadyExistInstallationName( installation ) )
116 {
117 throw new AlreadyExistsInstallationException(
118 "Installation with name " + installation.getName() + " already exists" );
119 }
120
121 Installation storedOne;
122 try
123 {
124 String envVarName = this.getEnvVar( installation.getType() );
125
126 if ( StringUtils.isNotEmpty( envVarName ) )
127 {
128 installation.setVarName( envVarName );
129 }
130 storedOne = installationDao.addInstallation( installation );
131 }
132 catch ( ContinuumStoreException e )
133 {
134 throw new InstallationException( e.getMessage(), e );
135 }
136 try
137 {
138 if ( automaticProfile )
139 {
140 Profile profile = new Profile();
141 profile.setName( storedOne.getName() );
142 profile = profileService.addProfile( profile );
143 profileService.addInstallationInProfile( profile, storedOne );
144 }
145 }
146 catch ( ProfileException e )
147 {
148 throw new InstallationException( "failed to create automatic Profile " + e.getMessage(), e );
149 }
150 return storedOne;
151 }
152
153
154
155
156 public void delete( Installation installation )
157 throws InstallationException
158 {
159 try
160 {
161 installationDao.removeInstallation( installation );
162 }
163 catch ( ContinuumStoreException e )
164 {
165 throw new InstallationException( e.getMessage(), e );
166 }
167
168 }
169
170
171
172
173 @SuppressWarnings("unchecked")
174 public List<Installation> getAllInstallations()
175 throws InstallationException
176 {
177 try
178 {
179 List<Installation> installations = installationDao.getAllInstallations();
180 return installations == null ? Collections.EMPTY_LIST : installations;
181 }
182 catch ( ContinuumStoreException e )
183 {
184 throw new InstallationException( e.getMessage(), e );
185 }
186 }
187
188
189
190
191 public Installation getInstallation( int installationId )
192 throws InstallationException
193 {
194 try
195 {
196 return installationDao.getInstallation( installationId );
197 }
198 catch ( ContinuumStoreException e )
199 {
200 throw new InstallationException( e.getMessage(), e );
201 }
202 }
203
204
205
206
207 public void update( Installation installation )
208 throws InstallationException, AlreadyExistsInstallationException
209 {
210 try
211 {
212 Installation stored = getInstallation( installation.getInstallationId() );
213 if ( stored == null )
214 {
215 throw new InstallationException( "installation with name " + installation.getName() + " not exists" );
216 }
217
218 stored.setName( installation.getName() );
219 if ( alreadyExistInstallationName( installation ) )
220 {
221 throw new AlreadyExistsInstallationException(
222 "Installation with name " + installation.getName() + " already exists" );
223 }
224 stored.setType( installation.getType() );
225 String envVarName = this.getEnvVar( installation.getType() );
226
227 if ( StringUtils.isNotEmpty( envVarName ) )
228 {
229 installation.setVarName( envVarName );
230 }
231 else
232 {
233 stored.setVarName( installation.getVarName() );
234 }
235 stored.setVarValue( installation.getVarValue() );
236 installationDao.updateInstallation( stored );
237 }
238 catch ( ContinuumStoreException e )
239 {
240 throw new InstallationException( e.getMessage(), e );
241 }
242
243 }
244
245
246
247
248 public ExecutorConfigurator getExecutorConfigurator( String type )
249 {
250 return this.typesValues.get( type );
251 }
252
253
254
255
256 public String getEnvVar( String type )
257 {
258 ExecutorConfigurator executorConfigurator = this.typesValues.get( type );
259 return executorConfigurator == null ? null : executorConfigurator.getEnvVar();
260 }
261
262
263
264
265
266
267
268
269
270
271 public List<String> getDefaultJdkInformations()
272 throws InstallationException
273 {
274 try
275 {
276 Properties systemEnvVars = CommandLineUtils.getSystemEnvVars( false );
277
278 String javaHome = (String) systemEnvVars.get( "JAVA_HOME" );
279
280 if ( StringUtils.isEmpty( javaHome ) )
281 {
282 return getJavaHomeInformations( System.getProperty( "java.home" ) );
283 }
284 return getJavaHomeInformations( javaHome );
285
286 }
287 catch ( IOException e )
288 {
289 throw new InstallationException( e.getMessage(), e );
290 }
291 catch ( CommandLineException e )
292 {
293 throw new InstallationException( e.getMessage(), e );
294 }
295 }
296
297
298
299
300
301
302 public List<String> getJdkInformations( Installation installation )
303 throws InstallationException
304 {
305 if ( installation == null )
306 {
307 return getDefaultJdkInformations();
308 }
309 if ( StringUtils.isEmpty( installation.getVarValue() ) )
310 {
311 return getDefaultJdkInformations();
312 }
313 try
314 {
315 return getJavaHomeInformations( installation.getVarValue() );
316 }
317 catch ( CommandLineException e )
318 {
319 throw new InstallationException( e.getMessage(), e );
320 }
321 }
322
323
324
325
326
327
328 private List<String> getJavaHomeInformations( String javaHome )
329 throws CommandLineException
330 {
331 Commandline commandline = new Commandline();
332
333 String executable = javaHome + File.separator + "bin" + File.separator + "java";
334
335 commandline.setExecutable( executable );
336 commandline.addArguments( new String[]{"-version"} );
337 final List<String> cliOutput = new ArrayList<String>();
338
339 int result = CommandLineUtils.executeCommandLine( commandline, new StreamConsumer()
340 {
341 public void consumeLine( String line )
342 {
343 cliOutput.add( line );
344 }
345 }, new StreamConsumer()
346 {
347 public void consumeLine( String line )
348 {
349 cliOutput.add( line );
350 }
351 } );
352 if ( result != 0 )
353 {
354 throw new CommandLineException( "cli to get JAVA_HOME informations return code " + result );
355 }
356 return cliOutput;
357 }
358
359 private Map<String, String> getEnvVars( Profile profile )
360 {
361 Map<String, String> environnments = new HashMap<String, String>();
362 if ( profile == null )
363 {
364 return environnments;
365 }
366 if ( profile.getBuilder() != null )
367 {
368 environnments.put( profile.getBuilder().getVarName(), profile.getBuilder().getVarValue() );
369 }
370 if ( profile.getJdk() != null )
371 {
372 environnments.put( profile.getJdk().getVarName(), profile.getJdk().getVarValue() );
373 }
374 if ( profile.getEnvironmentVariables() != null )
375 {
376 for ( Installation installation : (List<Installation>) profile.getEnvironmentVariables() )
377 {
378 environnments.put( installation.getVarName(), installation.getVarValue() );
379 }
380 }
381 return environnments;
382 }
383
384
385
386
387 @SuppressWarnings("unchecked")
388 public List<String> getExecutorConfiguratorVersion( String path, ExecutorConfigurator executorConfigurator,
389 Profile profile )
390 throws InstallationException
391 {
392
393 if ( executorConfigurator == null )
394 {
395 return Collections.EMPTY_LIST;
396 }
397 if ( executorConfigurator.getExecutable() == null )
398 {
399 return Collections.EMPTY_LIST;
400 }
401 StringBuilder executable = new StringBuilder();
402 try
403 {
404 Commandline commandline = new Commandline();
405 if ( StringUtils.isNotEmpty( path ) )
406 {
407 executable.append( path ).append( File.separator );
408 executable.append( executorConfigurator.getRelativePath() ).append( File.separator );
409 commandline.addEnvironment( executorConfigurator.getEnvVar(), path );
410 }
411
412 Map<String, String> environments = getEnvVars( profile );
413
414 for ( String key : environments.keySet() )
415 {
416 String value = environments.get( key );
417 commandline.addEnvironment( key, value );
418 }
419
420 executable = executable.append( executorConfigurator.getExecutable() );
421 commandline.setExecutable( executable.toString() );
422 commandline.addArguments( new String[]{executorConfigurator.getVersionArgument()} );
423 final List<String> cliOutput = new ArrayList<String>();
424
425 int result = CommandLineUtils.executeCommandLine( commandline, new StreamConsumer()
426 {
427 public void consumeLine( String line )
428 {
429 cliOutput.add( line );
430 }
431 }, new StreamConsumer()
432 {
433 public void consumeLine( String line )
434 {
435 cliOutput.add( line );
436 }
437 } );
438 if ( result != 0 )
439 {
440 throw new InstallationException( "cli to get " + executable + " version return code " + result );
441 }
442 return cliOutput;
443 }
444 catch ( CommandLineException e )
445 {
446 log.error( "fail to execute " + executable + " with arg " + executorConfigurator.getVersionArgument() );
447 throw new InstallationException( e.getMessage(), e );
448 }
449 }
450
451 private boolean alreadyExistInstallationName( Installation installation )
452 throws InstallationException
453 {
454 List<Installation> all = getAllInstallations();
455 for ( Installation install : all )
456 {
457 if ( org.apache.commons.lang.StringUtils.equals( installation.getName(), install.getName() ) &&
458 ( installation.getInstallationId() == 0 ||
459 installation.getInstallationId() != install.getInstallationId() ) )
460 {
461 return true;
462 }
463 }
464 return false;
465 }
466
467 }