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 com.opensymphony.xwork2.Preparable;
23  import org.apache.commons.lang.StringEscapeUtils;
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.continuum.web.util.AuditLog;
26  import org.apache.continuum.web.util.AuditLogConstants;
27  import org.apache.maven.continuum.ContinuumException;
28  import org.apache.maven.continuum.model.project.BuildQueue;
29  import org.apache.maven.continuum.model.project.Schedule;
30  import org.apache.maven.continuum.web.exception.AuthenticationRequiredException;
31  import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import java.util.ArrayList;
36  import java.util.Collection;
37  import java.util.List;
38  
39  /**
40   * @author Nik Gonzalez
41   * @version $Id: ScheduleAction.java 1372260 2012-08-13 04:29:09Z brett $
42   * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="schedule"
43   */
44  public class ScheduleAction
45      extends ContinuumConfirmAction
46      implements Preparable
47  {
48      private static final Logger logger = LoggerFactory.getLogger( ScheduleAction.class );
49  
50      private int id;
51  
52      private boolean active = false;
53  
54      private int delay;
55  
56      private String description;
57  
58      private String name;
59  
60      private Collection schedules;
61  
62      private Schedule schedule;
63  
64      private boolean confirmed;
65  
66      private int maxJobExecutionTime;
67  
68      private String second = "0";
69  
70      private String minute = "0";
71  
72      private String hour = "*";
73  
74      private String dayOfMonth = "*";
75  
76      private String month = "*";
77  
78      private String dayOfWeek = "?";
79  
80      private String year;
81  
82      private List<BuildQueue> availableBuildQueues;
83  
84      private List<BuildQueue> selectedBuildQueues = new ArrayList<BuildQueue>();
85  
86      private List<String> selectedBuildQueuesIds = new ArrayList<String>();
87  
88      public void prepare()
89          throws Exception
90      {
91          super.prepare();
92  
93          populateBuildQueues();
94      }
95  
96      private void populateBuildQueues()
97          throws ContinuumException
98      {
99          if ( schedule != null )
100         {
101             selectedBuildQueues = schedule.getBuildQueues();
102             for ( BuildQueue bq : selectedBuildQueues )
103             {
104                 this.selectedBuildQueuesIds.add( Integer.toString( bq.getId() ) );
105             }
106         }
107 
108         availableBuildQueues = getContinuum().getAllBuildQueues();
109 
110         // remove selected build queues from available build queues
111         for ( BuildQueue buildQueue : selectedBuildQueues )
112         {
113             if ( availableBuildQueues.contains( buildQueue ) )
114             {
115                 availableBuildQueues.remove( buildQueue );
116             }
117         }
118     }
119 
120     public String summary()
121         throws ContinuumException
122     {
123         try
124         {
125             checkManageSchedulesAuthorization();
126         }
127         catch ( AuthorizationRequiredException authzE )
128         {
129             addActionError( authzE.getMessage() );
130             return REQUIRES_AUTHORIZATION;
131         }
132         catch ( AuthenticationRequiredException e )
133         {
134             addActionError( e.getMessage() );
135             return REQUIRES_AUTHENTICATION;
136 
137         }
138 
139         schedules = getContinuum().getSchedules();
140 
141         return SUCCESS;
142     }
143 
144     public String input()
145         throws ContinuumException
146     {
147 
148         try
149         {
150             checkManageSchedulesAuthorization();
151         }
152         catch ( AuthorizationRequiredException authzE )
153         {
154             addActionError( authzE.getMessage() );
155             return REQUIRES_AUTHORIZATION;
156         }
157         catch ( AuthenticationRequiredException e )
158         {
159             addActionError( e.getMessage() );
160             return REQUIRES_AUTHENTICATION;
161         }
162 
163         if ( id != 0 )
164         {
165             schedule = getContinuum().getSchedule( id );
166             active = schedule.isActive();
167 
168             String[] cronEx = schedule.getCronExpression().split( " " );
169             second = cronEx[0];
170             minute = cronEx[1];
171             hour = cronEx[2];
172             dayOfMonth = cronEx[3];
173             month = cronEx[4];
174             dayOfWeek = cronEx[5];
175             if ( cronEx.length > 6 )
176             {
177                 year = cronEx[6];
178             }
179 
180             description = schedule.getDescription();
181             name = schedule.getName();
182             delay = schedule.getDelay();
183             maxJobExecutionTime = schedule.getMaxJobExecutionTime();
184 
185             populateBuildQueues();
186         }
187         else
188         {
189             // all new schedules should be active
190             active = true;
191         }
192 
193         return SUCCESS;
194     }
195 
196     public String save()
197         throws ContinuumException
198     {
199 
200         try
201         {
202             checkManageSchedulesAuthorization();
203         }
204         catch ( AuthorizationRequiredException authzE )
205         {
206             addActionError( authzE.getMessage() );
207             return REQUIRES_AUTHORIZATION;
208         }
209         catch ( AuthenticationRequiredException e )
210         {
211             addActionError( e.getMessage() );
212             return REQUIRES_AUTHENTICATION;
213         }
214 
215         if ( StringUtils.isBlank( name ) )
216         {
217             logger.error( "Can't create schedule. No schedule name was supplied." );
218             addActionError( getText( "buildDefinition.noname.save.error.message" ) );
219         }
220         if ( !getContinuum().getConfiguration().isDistributedBuildEnabled() &&
221             ( selectedBuildQueuesIds == null || selectedBuildQueuesIds.isEmpty() ) )
222         {
223             addActionError( getText( "schedule.buildqueues.empty.error" ) );
224         }
225         if ( hasErrors() )
226         {
227             return ERROR;
228         }
229 
230         try
231         {
232             Schedule s = getContinuum().getScheduleByName( name );
233             if ( s != null && id != s.getId() )
234             {
235                 addActionError( getText( "schedule.name.already.exists" ) );
236                 return ERROR;
237             }
238         }
239         catch ( ContinuumException e )
240         {
241             logger.debug( "Unexpected error getting schedule" );
242         }
243 
244         AuditLog event = new AuditLog( getName(), AuditLogConstants.ADD_SCHEDULE );
245         event.setCategory( AuditLogConstants.SCHEDULE );
246         event.setCurrentUser( getPrincipal() );
247 
248         if ( id == 0 )
249         {
250             try
251             {
252                 getContinuum().addSchedule( setFields( new Schedule() ) );
253                 event.log();
254             }
255             catch ( ContinuumException e )
256             {
257                 addActionError( getText( "schedule.buildqueues.add.error" ) );
258                 return ERROR;
259             }
260             return SUCCESS;
261         }
262         else
263         {
264             try
265             {
266                 getContinuum().updateSchedule( setFields( getContinuum().getSchedule( id ) ) );
267                 event.setAction( AuditLogConstants.MODIFY_SCHEDULE );
268                 event.log();
269             }
270             catch ( ContinuumException e )
271             {
272                 addActionError( getText( "schedule.buildqueues.add.error" ) );
273                 return ERROR;
274             }
275             return SUCCESS;
276         }
277     }
278 
279     private Schedule setFields( Schedule schedule )
280         throws ContinuumException
281     {
282         schedule.setActive( active );
283         schedule.setCronExpression( getCronExpression() );
284         schedule.setDelay( delay );
285         schedule.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( description ) ) );
286         schedule.setName( name );
287         schedule.setMaxJobExecutionTime( maxJobExecutionTime );
288         if ( !getContinuum().getConfiguration().isDistributedBuildEnabled() )
289         {
290             // if distributed build don't update schedules
291             schedule.setBuildQueues( null );
292             for ( String id : selectedBuildQueuesIds )
293             {
294                 BuildQueue buildQueue = getContinuum().getBuildQueue( Integer.parseInt( id ) );
295                 schedule.addBuildQueue( buildQueue );
296             }
297         }
298 
299         return schedule;
300     }
301 
302     public String confirm()
303         throws ContinuumException
304     {
305         try
306         {
307             checkManageSchedulesAuthorization();
308         }
309         catch ( AuthorizationRequiredException authzE )
310         {
311             addActionError( authzE.getMessage() );
312             return REQUIRES_AUTHORIZATION;
313         }
314         catch ( AuthenticationRequiredException e )
315         {
316             addActionError( e.getMessage() );
317             return REQUIRES_AUTHENTICATION;
318         }
319 
320         schedule = getContinuum().getSchedule( id );
321 
322         return SUCCESS;
323     }
324 
325     public String remove()
326         throws ContinuumException
327     {
328         try
329         {
330             checkManageSchedulesAuthorization();
331         }
332         catch ( AuthorizationRequiredException authzE )
333         {
334             addActionError( authzE.getMessage() );
335             return REQUIRES_AUTHORIZATION;
336         }
337         catch ( AuthenticationRequiredException e )
338         {
339             addActionError( e.getMessage() );
340             return REQUIRES_AUTHENTICATION;
341         }
342 
343         if ( confirmed )
344         {
345             try
346             {
347                 getContinuum().removeSchedule( id );
348             }
349             catch ( ContinuumException e )
350             {
351                 addActionError( getText( "schedule.remove.error" ) );
352                 return ERROR;
353             }
354         }
355         else
356         {
357             setConfirmationInfo( "Schedule Removal", "removeSchedule", name, "id", "" + id );
358 
359             name = getContinuum().getSchedule( id ).getName();
360 
361             return CONFIRM;
362         }
363 
364         AuditLog event = new AuditLog( name, AuditLogConstants.REMOVE_SCHEDULE );
365         event.setCategory( AuditLogConstants.SCHEDULE );
366         event.setCurrentUser( getPrincipal() );
367         event.log();
368 
369         return SUCCESS;
370     }
371 
372     public Collection getSchedules()
373     {
374         return schedules;
375     }
376 
377     public int getId()
378     {
379         return id;
380     }
381 
382     public void setId( int id )
383     {
384         this.id = id;
385     }
386 
387     public boolean isActive()
388     {
389         return active;
390     }
391 
392     public void setActive( boolean active )
393     {
394         this.active = active;
395     }
396 
397     public int getDelay()
398     {
399         return delay;
400     }
401 
402     public void setDelay( int delay )
403     {
404         this.delay = delay;
405     }
406 
407     public String getDescription()
408     {
409         return description;
410     }
411 
412     public void setDescription( String description )
413     {
414         this.description = description;
415     }
416 
417     public String getName()
418     {
419         return name;
420     }
421 
422     public void setName( String name )
423     {
424         this.name = name;
425     }
426 
427     public Schedule getSchedule()
428     {
429         return schedule;
430     }
431 
432     public void setSchedule( Schedule schedule )
433     {
434         this.schedule = schedule;
435     }
436 
437     public boolean isConfirmed()
438     {
439         return confirmed;
440     }
441 
442     public void setConfirmed( boolean confirmed )
443     {
444         this.confirmed = confirmed;
445     }
446 
447     public int getMaxJobExecutionTime()
448     {
449         return maxJobExecutionTime;
450     }
451 
452     public void setMaxJobExecutionTime( int maxJobExecutionTime )
453     {
454         this.maxJobExecutionTime = maxJobExecutionTime;
455     }
456 
457     public String getSecond()
458     {
459         return second;
460     }
461 
462     public void setSecond( String second )
463     {
464         this.second = second;
465     }
466 
467     public String getMinute()
468     {
469         return minute;
470     }
471 
472     public void setMinute( String minute )
473     {
474         this.minute = minute;
475     }
476 
477     public String getHour()
478     {
479         return hour;
480     }
481 
482     public void setHour( String hour )
483     {
484         this.hour = hour;
485     }
486 
487     public String getDayOfMonth()
488     {
489         return dayOfMonth;
490     }
491 
492     public void setDayOfMonth( String dayOfMonth )
493     {
494         this.dayOfMonth = dayOfMonth;
495     }
496 
497     public String getYear()
498     {
499         return year;
500     }
501 
502     public void setYear( String year )
503     {
504         this.year = year;
505     }
506 
507     public String getMonth()
508     {
509         return month;
510     }
511 
512     public void setMonth( String month )
513     {
514         this.month = month;
515     }
516 
517     public String getDayOfWeek()
518     {
519         return dayOfWeek;
520     }
521 
522     public void setDayOfWeek( String dayOfWeek )
523     {
524         this.dayOfWeek = dayOfWeek;
525     }
526 
527     private String getCronExpression()
528     {
529         return ( second + " " + minute + " " + hour + " " + dayOfMonth + " " + month + " " + dayOfWeek + " " +
530             year ).trim();
531     }
532 
533     public List<BuildQueue> getAvailableBuildQueues()
534     {
535         return availableBuildQueues;
536     }
537 
538     public void setAvailableBuildQueues( List<BuildQueue> availableBuildQueues )
539     {
540         this.availableBuildQueues = availableBuildQueues;
541     }
542 
543     public List<BuildQueue> getSelectedBuildQueues()
544     {
545         return selectedBuildQueues;
546     }
547 
548     public void setSelectedBuildQueues( List<BuildQueue> selectedBuildQueues )
549     {
550         this.selectedBuildQueues = selectedBuildQueues;
551     }
552 
553     public List<String> getSelectedBuildQueuesIds()
554     {
555         return selectedBuildQueuesIds;
556     }
557 
558     public void setSelectedBuildQueuesIds( List<String> selectedBuildQueuesIds )
559     {
560         this.selectedBuildQueuesIds = selectedBuildQueuesIds;
561     }
562 }