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.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
43
44
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
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
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
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 }