View Javadoc

1   package org.apache.maven.continuum.web.action;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.lang.StringEscapeUtils;
23  import org.apache.continuum.web.util.AuditLog;
24  import org.apache.continuum.web.util.AuditLogConstants;
25  import org.apache.maven.continuum.ContinuumException;
26  import org.apache.maven.continuum.builddefinition.BuildDefinitionService;
27  import org.apache.maven.continuum.builddefinition.BuildDefinitionServiceException;
28  import org.apache.maven.continuum.builddefinition.BuildDefinitionUpdatePolicyConstants;
29  import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
30  import org.apache.maven.continuum.model.project.BuildDefinition;
31  import org.apache.maven.continuum.model.project.Project;
32  import org.apache.maven.continuum.model.project.Schedule;
33  import org.apache.maven.continuum.model.system.Profile;
34  import org.apache.maven.continuum.profile.ProfileException;
35  import org.apache.maven.continuum.store.ContinuumStoreException;
36  import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
37  import org.apache.maven.continuum.web.exception.ContinuumActionException;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.HashMap;
43  import java.util.List;
44  import java.util.Map;
45  
46  /**
47   * BuildDefinitionAction:
48   *
49   * @author Jesse McConnell <jmcconnell@apache.org>
50   * @version $Id: BuildDefinitionAction.java 1372260 2012-08-13 04:29:09Z brett $
51   * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="buildDefinition"
52   */
53  public class BuildDefinitionAction
54      extends ContinuumConfirmAction
55  {
56      private int buildDefinitionId;
57  
58      private int projectId;
59  
60      private int projectGroupId;
61  
62      private int scheduleId;
63  
64      private boolean defaultBuildDefinition;
65  
66      private boolean confirmed = false;
67  
68      private String executor;
69  
70      private String goals;
71  
72      private String arguments;
73  
74      private String buildFile;
75  
76      private boolean buildFresh;
77  
78      private Map<Integer, String> schedules;
79  
80      private List<Profile> profiles;
81  
82      private boolean groupBuildDefinition = false;
83  
84      private boolean groupBuildView = false;
85  
86      private String projectGroupName = "";
87  
88      private int profileId;
89  
90      private String description;
91  
92      private List<String> buildDefinitionTypes;
93  
94      private String buildDefinitionType;
95  
96      private boolean alwaysBuild;
97  
98      private int updatePolicy = BuildDefinitionUpdatePolicyConstants.UPDATE_DESCRIPTION_ALWAYS;
99  
100     private Map<Integer, String> buildDefinitionUpdatePolicies;
101 
102     /**
103      * @plexus.requirement
104      */
105     private BuildDefinitionService buildDefinitionService;
106 
107     @Override
108     public void prepare()
109         throws Exception
110     {
111         super.prepare();
112 
113         if ( schedules == null )
114         {
115             schedules = new HashMap<Integer, String>();
116 
117             Collection<Schedule> allSchedules = getContinuum().getSchedules();
118 
119             for ( Schedule schedule : allSchedules )
120             {
121                 schedules.put( schedule.getId(), schedule.getName() );
122             }
123         }
124 
125         // todo: missing from continuum, investigate
126         if ( profiles == null )
127         {
128             profiles = this.getContinuum().getProfileService().getAllProfiles();
129         }
130 
131         buildDefinitionTypes = new ArrayList<String>();
132         buildDefinitionTypes.add( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR );
133         buildDefinitionTypes.add( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR );
134         buildDefinitionTypes.add( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR );
135         buildDefinitionTypes.add( ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR );
136 
137         buildDefinitionUpdatePolicies = new HashMap<Integer, String>();
138         String text = getText( "buildDefinition.updatePolicy.always" );
139         buildDefinitionUpdatePolicies.put( BuildDefinitionUpdatePolicyConstants.UPDATE_DESCRIPTION_ALWAYS, text );
140         text = getText( "buildDefinition.updatePolicy.never" );
141         buildDefinitionUpdatePolicies.put( BuildDefinitionUpdatePolicyConstants.UPDATE_DESCRIPTION_NEVER, text );
142         text = getText( "buildDefinition.updatePolicy.newPom" );
143         buildDefinitionUpdatePolicies.put( BuildDefinitionUpdatePolicyConstants.UPDATE_DESCRIPTION_ONLY_FOR_NEW_POM,
144                                            text );
145     }
146 
147     /**
148      * if there is a build definition id set, then retrieve it..either way set us to up to work with build definition
149      *
150      * @return action result
151      */
152     @Override
153     public String input()
154         throws ContinuumException, ContinuumStoreException, BuildDefinitionServiceException
155     {
156         try
157         {
158             if ( executor == null )
159             {
160                 if ( projectId != 0 )
161                 {
162                     executor = getContinuum().getProject( projectId ).getExecutorId();
163                 }
164                 else
165                 {
166                     List<Project> projects = getContinuum().getProjectGroupWithProjects( projectGroupId ).getProjects();
167 
168                     if ( projects.size() > 0 )
169                     {
170                         Project project = projects.get( 0 );
171                         executor = project.getExecutorId();
172                     }
173                 }
174             }
175 
176             if ( buildDefinitionId != 0 )
177             {
178                 if ( projectId != 0 )
179                 {
180                     checkModifyProjectBuildDefinitionAuthorization( getProjectGroupName() );
181                 }
182                 else
183                 {
184                     checkModifyGroupBuildDefinitionAuthorization( getProjectGroupName() );
185                 }
186 
187                 BuildDefinition buildDefinition = getContinuum().getBuildDefinition( buildDefinitionId );
188                 goals = buildDefinition.getGoals();
189                 arguments = buildDefinition.getArguments();
190                 buildFile = buildDefinition.getBuildFile();
191                 buildFresh = buildDefinition.isBuildFresh();
192                 scheduleId = buildDefinition.getSchedule().getId();
193                 defaultBuildDefinition = buildDefinition.isDefaultForProject();
194                 Profile profile = buildDefinition.getProfile();
195                 if ( profile != null )
196                 {
197                     profileId = profile.getId();
198                 }
199                 description = buildDefinition.getDescription();
200                 buildDefinitionType = buildDefinition.getType();
201                 alwaysBuild = buildDefinition.isAlwaysBuild();
202                 updatePolicy = buildDefinition.getUpdatePolicy();
203             }
204             else
205             {
206                 String preDefinedBuildFile = "";
207 
208                 if ( projectId != 0 )
209                 {
210                     checkAddProjectBuildDefinitionAuthorization( getProjectGroupName() );
211                     BuildDefinition bd = getContinuum().getDefaultBuildDefinition( projectId );
212                     if ( bd != null )
213                     {
214                         preDefinedBuildFile = bd.getBuildFile();
215                     }
216                 }
217                 else
218                 {
219                     checkAddGroupBuildDefinitionAuthorization( getProjectGroupName() );
220                     List<BuildDefinition> bds = getContinuum().getBuildDefinitionsForProjectGroup( projectGroupId );
221                     if ( bds != null && !bds.isEmpty() )
222                     {
223                         preDefinedBuildFile = bds.get( 0 ).getBuildFile();
224                     }
225                 }
226 
227                 if ( StringUtils.isEmpty( preDefinedBuildFile ) )
228                 {
229                     if ( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR.equals( executor ) )
230                     {
231                         buildFile =
232                             ( (BuildDefinition) buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate().getBuildDefinitions().get(
233                                 0 ) ).getBuildFile();
234                         buildDefinitionType = ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR;
235                     }
236                     else if ( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR.equals( executor ) )
237                     {
238                         buildFile =
239                             ( (BuildDefinition) buildDefinitionService.getDefaultMavenOneBuildDefinitionTemplate().getBuildDefinitions().get(
240                                 0 ) ).getBuildFile();
241                         buildDefinitionType = ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR;
242                     }
243                     else if ( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR.equals( executor ) )
244                     {
245                         buildFile =
246                             ( (BuildDefinition) buildDefinitionService.getDefaultAntBuildDefinitionTemplate().getBuildDefinitions().get(
247                                 0 ) ).getBuildFile();
248                         buildDefinitionType = ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR;
249                     }
250                     else
251                     {
252                         buildDefinitionType = ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR;
253                     }
254                 }
255                 else
256                 {
257                     buildFile = preDefinedBuildFile;
258                 }
259             }
260 
261             // if buildDefinitionType is null it will find with the executor
262             if ( StringUtils.isEmpty( buildDefinitionType ) )
263             {
264                 if ( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR.equals( executor ) )
265                 {
266                     buildDefinitionType = ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR;
267                 }
268                 else if ( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR.equals( executor ) )
269                 {
270                     buildDefinitionType = ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR;
271                 }
272                 else if ( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR.equals( executor ) )
273                 {
274                     buildDefinitionType = ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR;
275                 }
276                 else
277                 {
278                     buildDefinitionType = ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR;
279                 }
280             }
281 
282         }
283         catch ( AuthorizationRequiredException authzE )
284         {
285             return REQUIRES_AUTHORIZATION;
286         }
287 
288         return SUCCESS;
289     }
290 
291     public String saveBuildDefinition()
292         throws ContinuumException, ProfileException
293     {
294         if ( projectId != 0 && !groupBuildDefinition )
295         {
296             return saveToProject();
297         }
298         else
299         {
300             return saveToGroup();
301         }
302     }
303 
304     public String saveToProject()
305         throws ContinuumException, ProfileException
306     {
307 
308         AuditLog event = null;
309         String resource = "Project id=" + projectId + ":" + goals + " " + arguments;
310 
311         try
312         {
313             if ( buildDefinitionId == 0 )
314             {
315                 checkAddProjectBuildDefinitionAuthorization( getProjectGroupName() );
316 
317                 getContinuum().addBuildDefinitionToProject( projectId, getBuildDefinitionFromInput() );
318 
319                 event = new AuditLog( resource, AuditLogConstants.ADD_GOAL );
320             }
321             else
322             {
323                 checkModifyProjectBuildDefinitionAuthorization( getProjectGroupName() );
324 
325                 getContinuum().updateBuildDefinitionForProject( projectId, getBuildDefinitionFromInput() );
326 
327                 event = new AuditLog( resource, AuditLogConstants.MODIFY_GOAL );
328             }
329         }
330         catch ( ContinuumActionException cae )
331         {
332             addActionError( cae.getMessage() );
333             return INPUT;
334         }
335         catch ( AuthorizationRequiredException authzE )
336         {
337             addActionError( authzE.getMessage() );
338             return REQUIRES_AUTHORIZATION;
339         }
340 
341         event.setCategory( AuditLogConstants.BUILD_DEFINITION );
342         event.setCurrentUser( getPrincipal() );
343         event.log();
344 
345         if ( groupBuildView )
346         {
347             return "success_group";
348         }
349 
350         return SUCCESS;
351     }
352 
353     public String saveToGroup()
354         throws ContinuumException, ProfileException
355     {
356         try
357         {
358             BuildDefinition newBuildDef = getBuildDefinitionFromInput();
359 
360             if ( getContinuum().getBuildDefinitionsForProjectGroup( projectGroupId ).size() == 0 )
361             {
362                 newBuildDef.setDefaultForProject( true );
363             }
364 
365             if ( buildDefinitionId == 0 )
366             {
367                 checkAddGroupBuildDefinitionAuthorization( getProjectGroupName() );
368 
369                 getContinuum().addBuildDefinitionToProjectGroup( projectGroupId, newBuildDef );
370             }
371             else
372             {
373                 checkModifyGroupBuildDefinitionAuthorization( getProjectGroupName() );
374 
375                 getContinuum().updateBuildDefinitionForProjectGroup( projectGroupId, newBuildDef );
376             }
377         }
378         catch ( ContinuumActionException cae )
379         {
380             addActionError( cae.getMessage() );
381             return INPUT;
382         }
383         catch ( AuthorizationRequiredException authzE )
384         {
385             addActionError( authzE.getMessage() );
386             return REQUIRES_AUTHORIZATION;
387         }
388 
389         if ( projectId != 0 )
390         {
391             String resource = "Project id=" + projectId + ":" + goals + " " + arguments;
392             AuditLog event = null;
393             if ( buildDefinitionId == 0 )
394             {
395                 event = new AuditLog( resource, AuditLogConstants.ADD_GOAL );
396             }
397             else
398             {
399                 event = new AuditLog( resource, AuditLogConstants.MODIFY_GOAL );
400             }
401             event.setCategory( AuditLogConstants.BUILD_DEFINITION );
402             event.setCurrentUser( getPrincipal() );
403             event.log();
404             return SUCCESS;
405         }
406         else
407         {
408             String resource = "Project Group id=" + projectGroupId + ":" + goals + " " + arguments;
409             AuditLog event = null;
410             if ( buildDefinitionId == 0 )
411             {
412                 event = new AuditLog( resource, AuditLogConstants.ADD_GOAL );
413             }
414             else
415             {
416                 event = new AuditLog( resource, AuditLogConstants.MODIFY_GOAL );
417             }
418             event.setCategory( AuditLogConstants.BUILD_DEFINITION );
419             event.setCurrentUser( getPrincipal() );
420             event.log();
421             return "success_group";
422         }
423     }
424 
425     public String removeFromProject()
426         throws ContinuumException
427     {
428         try
429         {
430             checkRemoveProjectBuildDefinitionAuthorization( getProjectGroupName() );
431 
432             if ( confirmed )
433             {
434                 getContinuum().removeBuildDefinitionFromProject( projectId, buildDefinitionId );
435 
436                 String resource = "Project id=" + projectId + ":" + goals + " " + arguments;
437                 AuditLog event = new AuditLog( resource, AuditLogConstants.REMOVE_GOAL );
438                 event.setCategory( AuditLogConstants.BUILD_DEFINITION );
439                 event.setCurrentUser( getPrincipal() );
440                 event.log();
441 
442                 return SUCCESS;
443             }
444             else
445             {
446                 BuildDefinition buildDefinition = getContinuum().getBuildDefinition( buildDefinitionId );
447                 this.description = buildDefinition.getDescription();
448                 this.goals = buildDefinition.getGoals();
449                 return CONFIRM;
450             }
451         }
452         catch ( AuthorizationRequiredException authzE )
453         {
454             addActionError( authzE.getMessage() );
455             return REQUIRES_AUTHORIZATION;
456         }
457     }
458 
459     public String removeFromProjectGroup()
460         throws ContinuumException
461     {
462         try
463         {
464             checkRemoveGroupBuildDefinitionAuthorization( getProjectGroupName() );
465 
466             if ( confirmed )
467             {
468                 getContinuum().removeBuildDefinitionFromProjectGroup( projectGroupId, buildDefinitionId );
469 
470                 String resource = "Project Group id=" + projectGroupId + ":" + goals + " " + arguments;
471                 AuditLog event = new AuditLog( resource, AuditLogConstants.REMOVE_GOAL );
472                 event.setCategory( AuditLogConstants.BUILD_DEFINITION );
473                 event.setCurrentUser( getPrincipal() );
474                 event.log();
475 
476                 return SUCCESS;
477             }
478             else
479             {
480                 BuildDefinition buildDefinition = getContinuum().getBuildDefinition( buildDefinitionId );
481                 this.description = buildDefinition.getDescription();
482                 this.goals = buildDefinition.getGoals();
483                 return CONFIRM;
484             }
485         }
486         catch ( AuthorizationRequiredException authzE )
487         {
488             addActionError( authzE.getMessage() );
489             return REQUIRES_AUTHORIZATION;
490         }
491     }
492 
493     private BuildDefinition getBuildDefinitionFromInput()
494         throws ContinuumActionException, ProfileException
495     {
496 
497         Schedule schedule;
498 
499         try
500         {
501             schedule = getContinuum().getSchedule( scheduleId );
502         }
503         catch ( ContinuumException e )
504         {
505             addActionError( getText( "unable to get schedule" ) );
506             throw new ContinuumActionException( "unable to get schedule" );
507         }
508 
509         BuildDefinition buildDefinition = new BuildDefinition();
510 
511         if ( buildDefinitionId != 0 )
512         {
513             buildDefinition.setId( buildDefinitionId );
514         }
515         buildDefinition.setGoals( goals );
516         buildDefinition.setArguments( arguments );
517         buildDefinition.setBuildFile( buildFile );
518         buildDefinition.setBuildFresh( buildFresh );
519         buildDefinition.setDefaultForProject( defaultBuildDefinition );
520         buildDefinition.setSchedule( schedule );
521         if ( profileId != -1 )
522         {
523             Profile profile = getContinuum().getProfileService().getProfile( profileId );
524             if ( profile != null )
525             {
526                 buildDefinition.setProfile( profile );
527             }
528         }
529         buildDefinition.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( description ) ) );
530         buildDefinition.setType( buildDefinitionType );
531         buildDefinition.setAlwaysBuild( alwaysBuild );
532         buildDefinition.setUpdatePolicy( updatePolicy );
533         return buildDefinition;
534     }
535 
536     public int getBuildDefinitionId()
537     {
538         return buildDefinitionId;
539     }
540 
541     public void setBuildDefinitionId( final int buildDefinitionId )
542     {
543         this.buildDefinitionId = buildDefinitionId;
544     }
545 
546     public int getProjectId()
547     {
548         return projectId;
549     }
550 
551     public void setProjectId( final int projectId )
552     {
553         this.projectId = projectId;
554     }
555 
556     public int getProjectGroupId()
557     {
558         return projectGroupId;
559     }
560 
561     public void setProjectGroupId( final int projectGroupId )
562     {
563         this.projectGroupId = projectGroupId;
564     }
565 
566     public int getScheduleId()
567     {
568         return scheduleId;
569     }
570 
571     public void setScheduleId( final int scheduleId )
572     {
573         this.scheduleId = scheduleId;
574     }
575 
576     public boolean isDefaultBuildDefinition()
577     {
578         return defaultBuildDefinition;
579     }
580 
581     public void setDefaultBuildDefinition( final boolean defaultBuildDefinition )
582     {
583         this.defaultBuildDefinition = defaultBuildDefinition;
584     }
585 
586     @Override
587     public boolean isConfirmed()
588     {
589         return confirmed;
590     }
591 
592     @Override
593     public void setConfirmed( final boolean confirmed )
594     {
595         this.confirmed = confirmed;
596     }
597 
598     public String getExecutor()
599     {
600         return executor;
601     }
602 
603     public void setExecutor( final String executor )
604     {
605         this.executor = executor;
606     }
607 
608     public String getGoals()
609     {
610         return goals;
611     }
612 
613     public void setGoals( final String goals )
614     {
615         this.goals = goals;
616     }
617 
618     public String getArguments()
619     {
620         return arguments;
621     }
622 
623     public void setArguments( final String arguments )
624     {
625         this.arguments = arguments;
626     }
627 
628     public String getBuildFile()
629     {
630         return buildFile;
631     }
632 
633     public void setBuildFile( final String buildFile )
634     {
635         this.buildFile = buildFile;
636     }
637 
638     public boolean isBuildFresh()
639     {
640         return buildFresh;
641     }
642 
643     public void setBuildFresh( final boolean buildFresh )
644     {
645         this.buildFresh = buildFresh;
646     }
647 
648     public Map<Integer, String> getSchedules()
649     {
650         return schedules;
651     }
652 
653     public void setSchedules( final Map<Integer, String> schedules )
654     {
655         this.schedules = schedules;
656     }
657 
658     public List<Profile> getProfiles()
659     {
660         return profiles;
661     }
662 
663     public void setProfiles( final List<Profile> profiles )
664     {
665         this.profiles = profiles;
666     }
667 
668     public boolean isGroupBuildDefinition()
669     {
670         return groupBuildDefinition;
671     }
672 
673     public void setGroupBuildDefinition( final boolean groupBuildDefinition )
674     {
675         this.groupBuildDefinition = groupBuildDefinition;
676     }
677 
678     public String getProjectGroupName()
679         throws ContinuumException
680     {
681         if ( projectGroupName == null || "".equals( projectGroupName ) )
682         {
683             if ( projectGroupId != 0 )
684             {
685                 projectGroupName = getContinuum().getProjectGroup( projectGroupId ).getName();
686             }
687             else
688             {
689                 projectGroupName = getContinuum().getProjectGroupByProjectId( projectId ).getName();
690             }
691         }
692 
693         return projectGroupName;
694     }
695 
696     public int getProfileId()
697     {
698         return profileId;
699     }
700 
701     public void setProfileId( final int profileId )
702     {
703         this.profileId = profileId;
704     }
705 
706     public String getDescription()
707     {
708         return description;
709     }
710 
711     public void setDescription( final String description )
712     {
713         this.description = description;
714     }
715 
716     public String getBuildDefinitionType()
717     {
718         return buildDefinitionType;
719     }
720 
721     public void setBuildDefinitionType( final String buildDefinitionType )
722     {
723         this.buildDefinitionType = buildDefinitionType;
724     }
725 
726     public List<String> getBuildDefinitionTypes()
727     {
728         return buildDefinitionTypes;
729     }
730 
731     public boolean isAlwaysBuild()
732     {
733         return alwaysBuild;
734     }
735 
736     public void setAlwaysBuild( final boolean alwaysBuild )
737     {
738         this.alwaysBuild = alwaysBuild;
739     }
740 
741     public boolean isGroupBuildView()
742     {
743         return groupBuildView;
744     }
745 
746     public void setGroupBuildView( final boolean groupBuildView )
747     {
748         this.groupBuildView = groupBuildView;
749     }
750 
751     public int getUpdatePolicy()
752     {
753         return updatePolicy;
754     }
755 
756     public void setUpdatePolicy( int updatePolicy )
757     {
758         this.updatePolicy = updatePolicy;
759     }
760 
761     public Map<Integer, String> getBuildDefinitionUpdatePolicies()
762     {
763         return buildDefinitionUpdatePolicies;
764     }
765 }