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 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
41
42
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
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
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
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 }