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  
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.List;
28  
29  import org.apache.commons.lang.StringEscapeUtils;
30  import org.apache.commons.lang.StringUtils;
31  import org.apache.maven.continuum.ContinuumException;
32  import org.apache.maven.continuum.model.project.BuildQueue;
33  import org.apache.maven.continuum.model.project.Schedule;
34  import org.apache.maven.continuum.web.exception.AuthenticationRequiredException;
35  import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
36  import org.apache.continuum.web.util.AuditLog;
37  import org.apache.continuum.web.util.AuditLogConstants;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /**
42   * @author Nik Gonzalez
43   * @version $Id: ScheduleAction.java 1101669 2011-05-10 22:46:21Z ctan $
44   * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="schedule"
45   */
46  public class ScheduleAction
47      extends ContinuumConfirmAction
48      implements Preparable
49  {
50      private static final Logger logger = LoggerFactory.getLogger( ScheduleAction.class );
51  
52      private int id;
53  
54      private boolean active = false;
55  
56      private int delay;
57  
58      private String description;
59  
60      private String name;
61  
62      private Collection schedules;
63  
64      private Schedule schedule;
65  
66      private boolean confirmed;
67  
68      private int maxJobExecutionTime;
69  
70      private String second = "0";
71  
72      private String minute = "0";
73  
74      private String hour = "*";
75  
76      private String dayOfMonth = "*";
77  
78      private String month = "*";
79  
80      private String dayOfWeek = "?";
81  
82      private String year;
83  
84      private List<BuildQueue> availableBuildQueues;
85  
86      private List<BuildQueue> selectedBuildQueues = new ArrayList<BuildQueue>();
87      
88      private List<String> selectedBuildQueuesIds = new ArrayList<String>();
89  
90      public void prepare()
91          throws Exception
92      {
93          super.prepare();
94  
95          populateBuildQueues();
96      }
97  
98      private void populateBuildQueues()
99          throws ContinuumException
100     {
101         if ( schedule != null )
102         {
103             selectedBuildQueues = schedule.getBuildQueues();
104             for ( BuildQueue bq : selectedBuildQueues )
105             {
106                 this.selectedBuildQueuesIds.add( Integer.toString( bq.getId() ) );
107             }
108         }
109 
110         availableBuildQueues = getContinuum().getAllBuildQueues();
111 
112         // remove selected build queues from available build queues
113         for ( BuildQueue buildQueue : selectedBuildQueues )
114         {
115             if ( availableBuildQueues.contains( buildQueue ) )
116             {
117                 availableBuildQueues.remove( buildQueue );
118             }
119         }
120     }
121 
122     public String summary()
123         throws ContinuumException
124     {
125         try
126         {
127             checkManageSchedulesAuthorization();
128         }
129         catch ( AuthorizationRequiredException authzE )
130         {
131             addActionError( authzE.getMessage() );
132             return REQUIRES_AUTHORIZATION;
133         }
134         catch ( AuthenticationRequiredException e )
135         {
136             addActionError( e.getMessage() );
137             return REQUIRES_AUTHENTICATION;
138 
139         }
140 
141         schedules = getContinuum().getSchedules();
142 
143         return SUCCESS;
144     }
145 
146     public String input()
147         throws ContinuumException
148     {
149 
150         try
151         {
152             checkManageSchedulesAuthorization();
153         }
154         catch ( AuthorizationRequiredException authzE )
155         {
156             addActionError( authzE.getMessage() );
157             return REQUIRES_AUTHORIZATION;
158         }
159         catch ( AuthenticationRequiredException e )
160         {
161             addActionError( e.getMessage() );
162             return REQUIRES_AUTHENTICATION;
163         }
164 
165         if ( id != 0 )
166         {
167             schedule = getContinuum().getSchedule( id );
168             active = schedule.isActive();
169 
170             String[] cronEx = schedule.getCronExpression().split( " " );
171             second = cronEx[0];
172             minute = cronEx[1];
173             hour = cronEx[2];
174             dayOfMonth = cronEx[3];
175             month = cronEx[4];
176             dayOfWeek = cronEx[5];
177             if ( cronEx.length > 6 )
178             {
179                 year = cronEx[6];
180             }
181 
182             description = schedule.getDescription();
183             name = schedule.getName();
184             delay = schedule.getDelay();
185             maxJobExecutionTime = schedule.getMaxJobExecutionTime();
186 
187             populateBuildQueues();
188         }
189         else
190         {
191             // all new schedules should be active
192             active = true;
193         }
194 
195         return SUCCESS;
196     }
197 
198     public String save()
199         throws ContinuumException
200     {
201 
202         try
203         {
204             checkManageSchedulesAuthorization();
205         }
206         catch ( AuthorizationRequiredException authzE )
207         {
208             addActionError( authzE.getMessage() );
209             return REQUIRES_AUTHORIZATION;
210         }
211         catch ( AuthenticationRequiredException e )
212         {
213             addActionError( e.getMessage() );
214             return REQUIRES_AUTHENTICATION;
215         }
216 
217         if ( StringUtils.isBlank( name ) )
218         {
219             logger.error( "Can't create schedule. No schedule name was supplied." );
220             addActionError( getText( "buildDefinition.noname.save.error.message" ) );
221         }
222         if ( !getContinuum().getConfiguration().isDistributedBuildEnabled()
223             && ( selectedBuildQueuesIds == null || selectedBuildQueuesIds.isEmpty() ) )
224         {
225             addActionError( getText( "schedule.buildqueues.empty.error" ) );
226         }
227         if ( hasErrors() )
228         {
229             return ERROR;
230         }
231 
232         try
233         {
234             Schedule s = getContinuum().getScheduleByName( name );
235             if ( s != null && id != s.getId() )
236             {
237                 addActionError( getText( "schedule.name.already.exists" ) );
238                 return ERROR;
239             }
240         }
241         catch ( ContinuumException e )
242         {
243             logger.debug( "Unexpected error getting schedule" );
244         }
245         
246         AuditLog event = new AuditLog( getName(), AuditLogConstants.ADD_SCHEDULE );
247         event.setCategory( AuditLogConstants.SCHEDULE );
248         event.setCurrentUser( getPrincipal() );
249 
250         if ( id == 0 )
251         {
252             try
253             {
254                 getContinuum().addSchedule( setFields( new Schedule() ) );
255                 event.log();
256             }
257             catch ( ContinuumException e )
258             {
259                 addActionError( getText( "schedule.buildqueues.add.error" ) );
260                 return ERROR;
261             }
262             return SUCCESS;
263         }
264         else
265         {
266             try
267             {
268                 getContinuum().updateSchedule( setFields( getContinuum().getSchedule( id ) ) );
269                 event.setAction( AuditLogConstants.MODIFY_SCHEDULE );
270                 event.log();
271             }
272             catch ( ContinuumException e )
273             {
274                 addActionError( getText( "schedule.buildqueues.add.error" ) );
275                 return ERROR;
276             }
277             return SUCCESS;
278         }
279     }
280 
281     private Schedule setFields( Schedule schedule )
282         throws ContinuumException
283     {
284         schedule.setActive( active );
285         schedule.setCronExpression( getCronExpression() );
286         schedule.setDelay( delay );
287         schedule.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( description ) ) );
288         schedule.setName( name );
289         schedule.setMaxJobExecutionTime(maxJobExecutionTime);
290         if (!getContinuum().getConfiguration().isDistributedBuildEnabled()) {
291             // if distributed build don't update schedules
292             schedule.setBuildQueues(null);
293             for (String id : selectedBuildQueuesIds) {
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 }