1 package org.apache.maven.continuum.web.action;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.opensymphony.xwork2.ActionContext;
23 import com.opensymphony.xwork2.config.ConfigurationManager;
24 import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider;
25 import com.opensymphony.xwork2.inject.Container;
26 import com.opensymphony.xwork2.util.ValueStack;
27 import com.opensymphony.xwork2.util.ValueStackFactory;
28 import org.apache.commons.io.FileUtils;
29 import org.apache.maven.continuum.ContinuumException;
30 import org.apache.maven.continuum.builddefinition.BuildDefinitionServiceException;
31 import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
32 import org.apache.maven.continuum.model.project.ProjectGroup;
33 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
34 import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
35 import org.apache.struts2.interceptor.ServletRequestAware;
36 import org.codehaus.plexus.util.StringUtils;
37
38 import java.io.File;
39 import java.io.IOException;
40 import java.io.UnsupportedEncodingException;
41 import java.net.MalformedURLException;
42 import java.net.URL;
43 import java.net.URLEncoder;
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.List;
47 import javax.servlet.http.HttpServletRequest;
48
49
50
51
52
53
54
55 public abstract class AddMavenProjectAction
56 extends ContinuumActionSupport
57 implements ServletRequestAware
58 {
59 private static final long serialVersionUID = -3965565189557706469L;
60
61 private static final int DEFINED_BY_POM_GROUP_ID = -1;
62
63 private String pomUrl;
64
65 private File pomFile;
66
67 private String pom = null;
68
69 private String scmUsername;
70
71 private String scmPassword;
72
73 private Collection<ProjectGroup> projectGroups;
74
75 private String projectGroupName;
76
77 private int selectedProjectGroup = DEFINED_BY_POM_GROUP_ID;
78
79 private boolean disableGroupSelection;
80
81 private boolean scmUseCache;
82
83 private int projectGroupId;
84
85 private List<BuildDefinitionTemplate> buildDefinitionTemplates;
86
87 private int buildDefinitionTemplateId;
88
89 private List<String> errorMessages = new ArrayList<String>();
90
91 private HttpServletRequest httpServletRequest;
92
93 public String execute()
94 throws ContinuumException, BuildDefinitionServiceException
95 {
96 try
97 {
98 initializeProjectGroupName();
99
100 if ( StringUtils.isEmpty( getProjectGroupName() ) )
101 {
102 checkAddProjectGroupAuthorization();
103 }
104 else
105 {
106 checkAddProjectToGroupAuthorization( getProjectGroupName() );
107 }
108 }
109 catch ( AuthorizationRequiredException authzE )
110 {
111 addActionError( authzE.getMessage() );
112 return REQUIRES_AUTHORIZATION;
113 }
114
115
116 if ( ActionContext.getContext() == null )
117 {
118
119
120 ConfigurationManager configurationManager = new ConfigurationManager();
121 configurationManager.addContainerProvider( new XWorkConfigurationProvider() );
122 com.opensymphony.xwork2.config.Configuration config = configurationManager.getConfiguration();
123 Container container = config.getContainer();
124
125 ValueStack stack = container.getInstance( ValueStackFactory.class ).createValueStack();
126 stack.getContext().put( ActionContext.CONTAINER, container );
127 ActionContext.setContext( new ActionContext( stack.getContext() ) );
128 }
129
130 boolean checkProtocol = true;
131
132 if ( !StringUtils.isEmpty( pomUrl ) )
133 {
134 try
135 {
136 URL url = new URL( pomUrl );
137 if ( pomUrl.startsWith( "http" ) && !StringUtils.isEmpty( scmUsername ) )
138 {
139 String encoding = this.httpServletRequest.getCharacterEncoding();
140 if ( StringUtils.isEmpty( encoding ) )
141 {
142 encoding = System.getProperty( "file.encoding" );
143 }
144
145 String encodedUsername = URLEncoder.encode( scmUsername, encoding );
146 String encodedPassword = URLEncoder.encode( scmPassword, encoding );
147
148 StringBuffer urlBuffer = new StringBuffer();
149 urlBuffer.append( url.getProtocol() ).append( "://" );
150 urlBuffer.append( encodedUsername ).append( ':' ).append( encodedPassword ).append( '@' ).append(
151 url.getHost() );
152 if ( url.getPort() != -1 )
153 {
154 urlBuffer.append( ":" ).append( url.getPort() );
155 }
156 urlBuffer.append( url.getPath() );
157
158 pom = urlBuffer.toString();
159 }
160 else
161 {
162 pom = pomUrl;
163 }
164 }
165 catch ( MalformedURLException e )
166 {
167 addActionError( getText( "add.project.unknown.error" ) );
168 return doDefault();
169 }
170 catch ( UnsupportedEncodingException e )
171 {
172 addActionError( getText( "add.project.unknown.error" ) );
173 return doDefault();
174 }
175
176 }
177 else
178 {
179 if ( pomFile != null )
180 {
181 try
182 {
183
184 checkProtocol = false;
185
186
187 File tmpPom = File.createTempFile( "continuum_tmp", "tmp" );
188 FileUtils.copyFile( pomFile, tmpPom );
189 pom = tmpPom.toURL().toString();
190 }
191 catch ( MalformedURLException e )
192 {
193
194 throw new RuntimeException( e );
195 }
196 catch ( IOException e )
197 {
198 throw new RuntimeException( e );
199 }
200 }
201 else
202 {
203
204 addActionError( getText( "add.project.field.required.error" ) );
205 return doDefault();
206 }
207 }
208
209 ContinuumProjectBuildingResult result = doExecute( pom, selectedProjectGroup, checkProtocol, scmUseCache );
210
211 if ( result.hasErrors() )
212 {
213 for ( String key : result.getErrors() )
214 {
215 String cause = result.getErrorsWithCause().get( key );
216 String msg = getText( key, new String[]{cause} );
217
218
219
220 if ( key.equals( ContinuumProjectBuildingResult.ERROR_MISSING_SCM ) )
221 {
222 msg = getResourceBundle().getString( key ) + " " + cause;
223 }
224 if ( !StringUtils.equals( msg, key ) )
225 {
226 errorMessages.add( msg );
227 }
228 else
229 {
230 addActionError( msg );
231 }
232
233 }
234
235 return doDefault();
236 }
237
238 if ( this.getSelectedProjectGroup() > 0 )
239 {
240 this.setProjectGroupId( this.getSelectedProjectGroup() );
241 return "projectGroupSummary";
242 }
243
244 if ( result.getProjectGroups() != null && !result.getProjectGroups().isEmpty() )
245 {
246 this.setProjectGroupId( ( result.getProjectGroups().get( 0 ) ).getId() );
247 return "projectGroupSummary";
248 }
249
250 return SUCCESS;
251 }
252
253
254
255
256
257
258
259
260
261 protected abstract ContinuumProjectBuildingResult doExecute( String pomUrl, int selectedProjectGroup,
262 boolean checkProtocol, boolean scmUseCache )
263 throws ContinuumException;
264
265
266 public String doDefault()
267 throws BuildDefinitionServiceException
268 {
269 return input();
270 }
271
272 public String input()
273 throws BuildDefinitionServiceException
274 {
275 try
276 {
277 initializeProjectGroupName();
278
279 if ( StringUtils.isEmpty( getProjectGroupName() ) )
280 {
281 checkAddProjectGroupAuthorization();
282 }
283 else
284 {
285 checkAddProjectToGroupAuthorization( getProjectGroupName() );
286 }
287 }
288 catch ( AuthorizationRequiredException authzE )
289 {
290 addActionError( authzE.getMessage() );
291 return REQUIRES_AUTHORIZATION;
292 }
293 Collection<ProjectGroup> allProjectGroups = getContinuum().getAllProjectGroups();
294 projectGroups = new ArrayList<ProjectGroup>();
295
296 ProjectGroup defaultGroup = new ProjectGroup();
297 defaultGroup.setId( DEFINED_BY_POM_GROUP_ID );
298 defaultGroup.setName( "Defined by POM" );
299 projectGroups.add( defaultGroup );
300
301 for ( ProjectGroup pg : allProjectGroups )
302 {
303 if ( isAuthorizedToAddProjectToGroup( pg.getName() ) )
304 {
305 projectGroups.add( pg );
306 }
307 }
308
309 initializeProjectGroupName();
310 this.setBuildDefinitionTemplates( getContinuum().getBuildDefinitionService().getAllBuildDefinitionTemplate() );
311 return INPUT;
312 }
313
314 protected String hidePasswordInUrl( String url )
315 {
316 int indexAt = url.indexOf( "@" );
317
318 if ( indexAt < 0 )
319 {
320 return url;
321 }
322
323 String s = url.substring( 0, indexAt );
324
325 int pos = s.lastIndexOf( ":" );
326
327 return s.substring( 0, pos + 1 ) + "*****" + url.substring( indexAt );
328 }
329
330 private void initializeProjectGroupName()
331 {
332 if ( disableGroupSelection && selectedProjectGroup != DEFINED_BY_POM_GROUP_ID )
333 {
334 try
335 {
336 projectGroupName = getContinuum().getProjectGroup( selectedProjectGroup ).getName();
337 }
338 catch ( ContinuumException e )
339 {
340 e.printStackTrace();
341 }
342 }
343 }
344
345 public String getPom()
346 {
347 return pom;
348 }
349
350 public void setPom( String pom )
351 {
352 this.pom = pom;
353 }
354
355 public File getPomFile()
356 {
357 return pomFile;
358 }
359
360 public void setPomFile( File pomFile )
361 {
362 this.pomFile = pomFile;
363 }
364
365 public String getPomUrl()
366 {
367 return pomUrl;
368 }
369
370 public void setPomUrl( String pomUrl )
371 {
372 this.pomUrl = pomUrl;
373 }
374
375 public void setScmPassword( String scmPassword )
376 {
377 this.scmPassword = scmPassword;
378 }
379
380 public String getScmUsername()
381 {
382 return scmUsername;
383 }
384
385 public void setScmUsername( String scmUsername )
386 {
387 this.scmUsername = scmUsername;
388 }
389
390 public Collection getProjectGroups()
391 {
392 return projectGroups;
393 }
394
395 public String getProjectGroupName()
396 {
397 return projectGroupName;
398 }
399
400 public void setProjectGroupName( String projectGroupName )
401 {
402 this.projectGroupName = projectGroupName;
403 }
404
405 public int getSelectedProjectGroup()
406 {
407 return selectedProjectGroup;
408 }
409
410 public void setSelectedProjectGroup( int selectedProjectGroup )
411 {
412 this.selectedProjectGroup = selectedProjectGroup;
413 }
414
415 public boolean isDisableGroupSelection()
416 {
417 return this.disableGroupSelection;
418 }
419
420 public void setDisableGroupSelection( boolean disableGroupSelection )
421 {
422 this.disableGroupSelection = disableGroupSelection;
423 }
424
425 public boolean isScmUseCache()
426 {
427 return scmUseCache;
428 }
429
430 public void setScmUseCache( boolean scmUseCache )
431 {
432 this.scmUseCache = scmUseCache;
433 }
434
435 public int getProjectGroupId()
436 {
437 return projectGroupId;
438 }
439
440 public void setProjectGroupId( int projectGroupId )
441 {
442 this.projectGroupId = projectGroupId;
443 }
444
445 public List<BuildDefinitionTemplate> getBuildDefinitionTemplates()
446 {
447 return buildDefinitionTemplates;
448 }
449
450 public void setBuildDefinitionTemplates( List<BuildDefinitionTemplate> buildDefinitionTemplates )
451 {
452 this.buildDefinitionTemplates = buildDefinitionTemplates;
453 }
454
455 public int getBuildDefinitionTemplateId()
456 {
457 return buildDefinitionTemplateId;
458 }
459
460 public void setBuildDefinitionTemplateId( int buildDefinitionTemplateId )
461 {
462 this.buildDefinitionTemplateId = buildDefinitionTemplateId;
463 }
464
465 private boolean isAuthorizedToAddProjectToGroup( String projectGroupName )
466 {
467 try
468 {
469 checkAddProjectToGroupAuthorization( projectGroupName );
470 return true;
471 }
472 catch ( AuthorizationRequiredException authzE )
473 {
474 return false;
475 }
476 }
477
478 public List<String> getErrorMessages()
479 {
480 return errorMessages;
481 }
482
483 public void setErrorMessages( List<String> errorMessages )
484 {
485 this.errorMessages = errorMessages;
486 }
487
488 public void setServletRequest( HttpServletRequest httpServletRequest )
489 {
490 this.httpServletRequest = httpServletRequest;
491 }
492 }