1 | package org.apache.continuum.web.action.admin; |
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.HashMap; |
27 | import java.util.List; |
28 | import java.util.Map; |
29 | |
30 | import org.apache.commons.lang.StringEscapeUtils; |
31 | import org.apache.continuum.model.repository.AbstractPurgeConfiguration; |
32 | import org.apache.continuum.model.repository.DirectoryPurgeConfiguration; |
33 | import org.apache.continuum.model.repository.LocalRepository; |
34 | import org.apache.continuum.model.repository.RepositoryPurgeConfiguration; |
35 | import org.apache.continuum.purge.ContinuumPurgeManager; |
36 | import org.apache.continuum.purge.PurgeConfigurationService; |
37 | import org.apache.continuum.repository.RepositoryService; |
38 | import org.apache.continuum.taskqueue.manager.TaskQueueManager; |
39 | import org.apache.maven.continuum.configuration.ConfigurationService; |
40 | import org.apache.maven.continuum.model.project.Schedule; |
41 | import org.apache.maven.continuum.security.ContinuumRoleConstants; |
42 | import org.apache.maven.continuum.web.action.ContinuumConfirmAction; |
43 | import org.apache.struts2.ServletActionContext; |
44 | import org.codehaus.plexus.redback.rbac.Resource; |
45 | import org.codehaus.redback.integration.interceptor.SecureAction; |
46 | import org.codehaus.redback.integration.interceptor.SecureActionBundle; |
47 | import org.codehaus.redback.integration.interceptor.SecureActionException; |
48 | import org.slf4j.Logger; |
49 | import org.slf4j.LoggerFactory; |
50 | |
51 | /** |
52 | * @author Maria Catherine Tan |
53 | * @version $Id: PurgeConfigurationAction.java 1101669 2011-05-10 22:46:21Z ctan $ |
54 | * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="purgeConfiguration" |
55 | * @since 25 jul 07 |
56 | */ |
57 | public class PurgeConfigurationAction |
58 | extends ContinuumConfirmAction |
59 | implements Preparable, SecureAction |
60 | { |
61 | private static final Logger logger = LoggerFactory.getLogger( PurgeConfigurationAction.class ); |
62 | |
63 | private static final String PURGE_TYPE_REPOSITORY = "repository"; |
64 | |
65 | private static final String PURGE_TYPE_DIRECTORY = "directory"; |
66 | |
67 | private static final String PURGE_DIRECTORY_RELEASES = "releases"; |
68 | |
69 | private static final String PURGE_DIRECTORY_BUILDOUTPUT = "buildOutput"; |
70 | |
71 | private static final int DEFAULT_RETENTION_COUNT = 2; |
72 | |
73 | private static final int DEFAULT_DAYS_OLDER = 100; |
74 | |
75 | private String purgeType; |
76 | |
77 | private String directoryType; |
78 | |
79 | private String description; |
80 | |
81 | private String message; |
82 | |
83 | private boolean deleteAll; |
84 | |
85 | private boolean deleteReleasedSnapshots; |
86 | |
87 | private boolean enabled; |
88 | |
89 | private boolean confirmed; |
90 | |
91 | private boolean defaultPurgeConfiguration; |
92 | |
93 | private int retentionCount; |
94 | |
95 | private int daysOlder; |
96 | |
97 | private int repositoryId; |
98 | |
99 | private int scheduleId; |
100 | |
101 | private int purgeConfigId; |
102 | |
103 | private AbstractPurgeConfiguration purgeConfig; |
104 | |
105 | private Map<Integer, String> repositories; |
106 | |
107 | private Map<Integer, String> schedules; |
108 | |
109 | private List<RepositoryPurgeConfiguration> repoPurgeConfigs; |
110 | |
111 | private List<DirectoryPurgeConfiguration> dirPurgeConfigs; |
112 | |
113 | private List<String> directoryTypes; |
114 | |
115 | /** |
116 | * @plexus.requirement |
117 | */ |
118 | private PurgeConfigurationService purgeConfigService; |
119 | |
120 | /** |
121 | * @plexus.requirement |
122 | */ |
123 | private RepositoryService repositoryService; |
124 | |
125 | @Override |
126 | public void prepare() |
127 | throws Exception |
128 | { |
129 | super.prepare(); |
130 | |
131 | // build schedules |
132 | if ( schedules == null ) |
133 | { |
134 | schedules = new HashMap<Integer, String>(); |
135 | |
136 | Collection<Schedule> allSchedules = getContinuum().getSchedules(); |
137 | |
138 | for ( Schedule schedule : allSchedules ) |
139 | { |
140 | schedules.put( schedule.getId(), schedule.getName() ); |
141 | } |
142 | } |
143 | |
144 | // build repositories |
145 | if ( repositories == null ) |
146 | { |
147 | repositories = new HashMap<Integer, String>(); |
148 | |
149 | List<LocalRepository> allRepositories = repositoryService.getAllLocalRepositories(); |
150 | |
151 | for ( LocalRepository repository : allRepositories ) |
152 | { |
153 | repositories.put( repository.getId(), repository.getName() ); |
154 | } |
155 | } |
156 | |
157 | directoryTypes = new ArrayList<String>(); |
158 | directoryTypes.add( PURGE_DIRECTORY_RELEASES ); |
159 | directoryTypes.add( PURGE_DIRECTORY_BUILDOUTPUT ); |
160 | } |
161 | |
162 | @Override |
163 | public String input() |
164 | throws Exception |
165 | { |
166 | if ( purgeConfigId != 0 ) |
167 | { |
168 | purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId ); |
169 | |
170 | if ( purgeConfig instanceof RepositoryPurgeConfiguration ) |
171 | { |
172 | RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig; |
173 | |
174 | this.purgeType = PURGE_TYPE_REPOSITORY; |
175 | this.daysOlder = repoPurge.getDaysOlder(); |
176 | this.retentionCount = repoPurge.getRetentionCount(); |
177 | this.deleteAll = repoPurge.isDeleteAll(); |
178 | this.deleteReleasedSnapshots = repoPurge.isDeleteReleasedSnapshots(); |
179 | this.enabled = repoPurge.isEnabled(); |
180 | this.defaultPurgeConfiguration = repoPurge.isDefaultPurge(); |
181 | this.description = repoPurge.getDescription(); |
182 | |
183 | if ( repoPurge.getRepository() != null ) |
184 | { |
185 | this.repositoryId = repoPurge.getRepository().getId(); |
186 | } |
187 | |
188 | if ( repoPurge.getSchedule() != null ) |
189 | { |
190 | this.scheduleId = repoPurge.getSchedule().getId(); |
191 | } |
192 | } |
193 | else if ( purgeConfig instanceof DirectoryPurgeConfiguration ) |
194 | { |
195 | DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig; |
196 | |
197 | this.purgeType = PURGE_TYPE_DIRECTORY; |
198 | this.daysOlder = dirPurge.getDaysOlder(); |
199 | this.retentionCount = dirPurge.getRetentionCount(); |
200 | this.directoryType = dirPurge.getDirectoryType(); |
201 | this.deleteAll = dirPurge.isDeleteAll(); |
202 | this.enabled = dirPurge.isEnabled(); |
203 | this.defaultPurgeConfiguration = dirPurge.isDefaultPurge(); |
204 | this.description = dirPurge.getDescription(); |
205 | |
206 | if ( dirPurge.getSchedule() != null ) |
207 | { |
208 | this.scheduleId = dirPurge.getSchedule().getId(); |
209 | } |
210 | } |
211 | } |
212 | else |
213 | { |
214 | this.retentionCount = DEFAULT_RETENTION_COUNT; |
215 | this.daysOlder = DEFAULT_DAYS_OLDER; |
216 | } |
217 | |
218 | return INPUT; |
219 | } |
220 | |
221 | public String list() |
222 | throws Exception |
223 | { |
224 | String errorMessage = ServletActionContext.getRequest().getParameter( "errorMessage" ); |
225 | |
226 | if ( errorMessage != null ) |
227 | { |
228 | addActionError( getText( errorMessage ) ); |
229 | } |
230 | |
231 | repoPurgeConfigs = purgeConfigService.getAllRepositoryPurgeConfigurations(); |
232 | dirPurgeConfigs = purgeConfigService.getAllDirectoryPurgeConfigurations(); |
233 | |
234 | return SUCCESS; |
235 | } |
236 | |
237 | public String save() |
238 | throws Exception |
239 | { |
240 | if ( purgeConfigId == 0 ) |
241 | { |
242 | if ( purgeType.equals( PURGE_TYPE_REPOSITORY ) ) |
243 | { |
244 | purgeConfig = new RepositoryPurgeConfiguration(); |
245 | } |
246 | else |
247 | { |
248 | purgeConfig = new DirectoryPurgeConfiguration(); |
249 | } |
250 | |
251 | purgeConfig = setupPurgeConfiguration( purgeConfig ); |
252 | |
253 | purgeConfig = purgeConfigService.addPurgeConfiguration( purgeConfig ); |
254 | } |
255 | else |
256 | { |
257 | purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId ); |
258 | purgeConfig = setupPurgeConfiguration( purgeConfig ); |
259 | |
260 | purgeConfigService.updatePurgeConfiguration( purgeConfig ); |
261 | } |
262 | |
263 | if ( purgeConfig.isDefaultPurge() ) |
264 | { |
265 | updateDefaultPurgeConfiguration(); |
266 | } |
267 | |
268 | if ( purgeConfig.isEnabled() && purgeConfig.getSchedule() != null ) |
269 | { |
270 | getContinuum().activePurgeSchedule( purgeConfig.getSchedule() ); |
271 | } |
272 | |
273 | return SUCCESS; |
274 | } |
275 | |
276 | public String remove() |
277 | throws Exception |
278 | { |
279 | if ( confirmed ) |
280 | { |
281 | purgeConfigService.removePurgeConfiguration( purgeConfigId ); |
282 | } |
283 | else |
284 | { |
285 | return CONFIRM; |
286 | } |
287 | |
288 | return SUCCESS; |
289 | } |
290 | |
291 | public String purge() |
292 | throws Exception |
293 | { |
294 | ContinuumPurgeManager purgeManager = getContinuum().getPurgeManager(); |
295 | TaskQueueManager taskQueueManager = getContinuum().getTaskQueueManager(); |
296 | |
297 | if ( purgeConfigId > 0 ) |
298 | { |
299 | purgeConfig = purgeConfigService.getPurgeConfiguration( purgeConfigId ); |
300 | |
301 | if ( purgeConfig instanceof RepositoryPurgeConfiguration ) |
302 | { |
303 | RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig; |
304 | |
305 | // check if repository is in use |
306 | if ( taskQueueManager.isRepositoryInUse( repoPurge.getRepository().getId() ) ) |
307 | { |
308 | message = "repository.error.purge.in.use"; |
309 | return ERROR; |
310 | } |
311 | |
312 | purgeManager.purgeRepository( repoPurge ); |
313 | } |
314 | else |
315 | { |
316 | DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig; |
317 | purgeManager.purgeDirectory( dirPurge ); |
318 | } |
319 | } |
320 | |
321 | return SUCCESS; |
322 | } |
323 | |
324 | public String getPurgeType() |
325 | { |
326 | return this.purgeType; |
327 | } |
328 | |
329 | public void setPurgeType( String purgeType ) |
330 | { |
331 | this.purgeType = purgeType; |
332 | } |
333 | |
334 | public String getDirectoryType() |
335 | { |
336 | return this.directoryType; |
337 | } |
338 | |
339 | public void setDirectoryType( String directoryType ) |
340 | { |
341 | this.directoryType = directoryType; |
342 | } |
343 | |
344 | public String getDescription() |
345 | { |
346 | return this.description; |
347 | } |
348 | |
349 | public void setDescription( String description ) |
350 | { |
351 | this.description = description; |
352 | } |
353 | |
354 | public String getMessage() |
355 | { |
356 | return this.message; |
357 | } |
358 | |
359 | public void setMessage( String message ) |
360 | { |
361 | this.message = message; |
362 | } |
363 | |
364 | public boolean isDeleteAll() |
365 | { |
366 | return this.deleteAll; |
367 | } |
368 | |
369 | public void setDeleteAll( boolean deleteAll ) |
370 | { |
371 | this.deleteAll = deleteAll; |
372 | } |
373 | |
374 | public boolean isDeleteReleasedSnapshots() |
375 | { |
376 | return this.deleteReleasedSnapshots; |
377 | } |
378 | |
379 | public void setDeleteReleasedSnapshots( boolean deleteReleasedSnapshots ) |
380 | { |
381 | this.deleteReleasedSnapshots = deleteReleasedSnapshots; |
382 | } |
383 | |
384 | public boolean isEnabled() |
385 | { |
386 | return this.enabled; |
387 | } |
388 | |
389 | public void setEnabled( boolean enabled ) |
390 | { |
391 | this.enabled = enabled; |
392 | } |
393 | |
394 | @Override |
395 | public boolean isConfirmed() |
396 | { |
397 | return this.confirmed; |
398 | } |
399 | |
400 | @Override |
401 | public void setConfirmed( boolean confirmed ) |
402 | { |
403 | this.confirmed = confirmed; |
404 | } |
405 | |
406 | public boolean isDefaultPurgeConfiguration() |
407 | { |
408 | return this.defaultPurgeConfiguration; |
409 | } |
410 | |
411 | public void setDefaultPurgeConfiguration( boolean defaultPurgeConfiguration ) |
412 | { |
413 | this.defaultPurgeConfiguration = defaultPurgeConfiguration; |
414 | } |
415 | |
416 | public int getRetentionCount() |
417 | { |
418 | return this.retentionCount; |
419 | } |
420 | |
421 | public void setRetentionCount( int retentionCount ) |
422 | { |
423 | this.retentionCount = retentionCount; |
424 | } |
425 | |
426 | public int getDaysOlder() |
427 | { |
428 | return this.daysOlder; |
429 | } |
430 | |
431 | public void setDaysOlder( int daysOlder ) |
432 | { |
433 | this.daysOlder = daysOlder; |
434 | } |
435 | |
436 | public int getRepositoryId() |
437 | { |
438 | return this.repositoryId; |
439 | } |
440 | |
441 | public void setRepositoryId( int repositoryId ) |
442 | { |
443 | this.repositoryId = repositoryId; |
444 | } |
445 | |
446 | public int getScheduleId() |
447 | { |
448 | return this.scheduleId; |
449 | } |
450 | |
451 | public void setScheduleId( int scheduleId ) |
452 | { |
453 | this.scheduleId = scheduleId; |
454 | } |
455 | |
456 | public int getPurgeConfigId() |
457 | { |
458 | return purgeConfigId; |
459 | } |
460 | |
461 | public void setPurgeConfigId( int purgeConfigId ) |
462 | { |
463 | this.purgeConfigId = purgeConfigId; |
464 | } |
465 | |
466 | public AbstractPurgeConfiguration getPurgeConfig() |
467 | { |
468 | return this.purgeConfig; |
469 | } |
470 | |
471 | public void setPurgeConfig( AbstractPurgeConfiguration purgeConfig ) |
472 | { |
473 | this.purgeConfig = purgeConfig; |
474 | } |
475 | |
476 | public Map<Integer, String> getRepositories() |
477 | { |
478 | return this.repositories; |
479 | } |
480 | |
481 | public void setRepositories( Map<Integer, String> repositories ) |
482 | { |
483 | this.repositories = repositories; |
484 | } |
485 | |
486 | public Map<Integer, String> getSchedules() |
487 | { |
488 | return this.schedules; |
489 | } |
490 | |
491 | public void setSchedules( Map<Integer, String> schedules ) |
492 | { |
493 | this.schedules = schedules; |
494 | } |
495 | |
496 | public List<RepositoryPurgeConfiguration> getRepoPurgeConfigs() |
497 | { |
498 | return this.repoPurgeConfigs; |
499 | } |
500 | |
501 | public void setRepoPurgeConfigs( List<RepositoryPurgeConfiguration> repoPurgeConfigs ) |
502 | { |
503 | this.repoPurgeConfigs = repoPurgeConfigs; |
504 | } |
505 | |
506 | public List<DirectoryPurgeConfiguration> getDirPurgeConfigs() |
507 | { |
508 | return this.dirPurgeConfigs; |
509 | } |
510 | |
511 | public void setDirPurgeConfigs( List<DirectoryPurgeConfiguration> dirPurgeConfigs ) |
512 | { |
513 | this.dirPurgeConfigs = dirPurgeConfigs; |
514 | } |
515 | |
516 | public List<String> getDirectoryTypes() |
517 | { |
518 | return this.directoryTypes; |
519 | } |
520 | |
521 | public void setDirectoryTypes( List<String> directoryTypes ) |
522 | { |
523 | this.directoryTypes = directoryTypes; |
524 | } |
525 | |
526 | private AbstractPurgeConfiguration setupPurgeConfiguration( AbstractPurgeConfiguration purgeConfiguration ) |
527 | throws Exception |
528 | { |
529 | if ( purgeConfiguration instanceof RepositoryPurgeConfiguration ) |
530 | { |
531 | return buildRepoPurgeConfiguration(); |
532 | } |
533 | else |
534 | { |
535 | return buildDirPurgeConfiguration(); |
536 | } |
537 | } |
538 | |
539 | private RepositoryPurgeConfiguration buildRepoPurgeConfiguration() |
540 | throws Exception |
541 | { |
542 | RepositoryPurgeConfiguration repoPurge = (RepositoryPurgeConfiguration) purgeConfig; |
543 | repoPurge.setDeleteAll( this.deleteAll ); |
544 | repoPurge.setDeleteReleasedSnapshots( this.deleteReleasedSnapshots ); |
545 | repoPurge.setDaysOlder( this.daysOlder ); |
546 | repoPurge.setRetentionCount( this.retentionCount ); |
547 | repoPurge.setEnabled( this.enabled ); |
548 | repoPurge.setDefaultPurge( this.defaultPurgeConfiguration ); |
549 | // escape xml to prevent xss attacks |
550 | repoPurge.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( this.description ) ) ); |
551 | repoPurge.setDefaultPurge( this.defaultPurgeConfiguration ); |
552 | |
553 | if ( repositoryId != 0 ) |
554 | { |
555 | LocalRepository repository = repositoryService.getLocalRepository( repositoryId ); |
556 | repoPurge.setRepository( repository ); |
557 | } |
558 | |
559 | if ( scheduleId > 0 ) |
560 | { |
561 | Schedule schedule = getContinuum().getSchedule( scheduleId ); |
562 | repoPurge.setSchedule( schedule ); |
563 | } |
564 | |
565 | return repoPurge; |
566 | } |
567 | |
568 | private DirectoryPurgeConfiguration buildDirPurgeConfiguration() |
569 | throws Exception |
570 | { |
571 | DirectoryPurgeConfiguration dirPurge = (DirectoryPurgeConfiguration) purgeConfig; |
572 | dirPurge.setDeleteAll( this.deleteAll ); |
573 | dirPurge.setEnabled( this.enabled ); |
574 | dirPurge.setDaysOlder( this.daysOlder ); |
575 | dirPurge.setRetentionCount( this.retentionCount ); |
576 | // escape xml to prevent xss attacks |
577 | dirPurge.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( this.description ) ) ); |
578 | dirPurge.setDirectoryType( this.directoryType ); |
579 | dirPurge.setDefaultPurge( this.defaultPurgeConfiguration ); |
580 | |
581 | if ( scheduleId > 0 ) |
582 | { |
583 | Schedule schedule = getContinuum().getSchedule( scheduleId ); |
584 | dirPurge.setSchedule( schedule ); |
585 | } |
586 | |
587 | ConfigurationService configService = getContinuum().getConfiguration(); |
588 | String path = null; |
589 | |
590 | if ( this.directoryType.equals( PURGE_DIRECTORY_RELEASES ) ) |
591 | { |
592 | path = configService.getWorkingDirectory().getAbsolutePath(); |
593 | } |
594 | else if ( this.directoryType.equals( PURGE_DIRECTORY_BUILDOUTPUT ) ) |
595 | { |
596 | path = configService.getBuildOutputDirectory().getAbsolutePath(); |
597 | } |
598 | |
599 | dirPurge.setLocation( path ); |
600 | |
601 | return dirPurge; |
602 | } |
603 | |
604 | private void updateDefaultPurgeConfiguration() |
605 | throws Exception |
606 | { |
607 | if ( purgeConfig instanceof RepositoryPurgeConfiguration ) |
608 | { |
609 | RepositoryPurgeConfiguration repoPurge = |
610 | purgeConfigService.getDefaultPurgeConfigurationForRepository( repositoryId ); |
611 | |
612 | if ( repoPurge != null && repoPurge.getId() != purgeConfig.getId() ) |
613 | { |
614 | repoPurge.setDefaultPurge( false ); |
615 | purgeConfigService.updateRepositoryPurgeConfiguration( repoPurge ); |
616 | } |
617 | } |
618 | else if ( purgeConfig instanceof DirectoryPurgeConfiguration ) |
619 | { |
620 | DirectoryPurgeConfiguration dirPurge = |
621 | purgeConfigService.getDefaultPurgeConfigurationForDirectoryType( directoryType ); |
622 | |
623 | if ( dirPurge != null && dirPurge.getId() != purgeConfig.getId() ) |
624 | { |
625 | dirPurge.setDefaultPurge( false ); |
626 | purgeConfigService.updateDirectoryPurgeConfiguration( dirPurge ); |
627 | } |
628 | } |
629 | } |
630 | |
631 | public SecureActionBundle getSecureActionBundle() |
632 | throws SecureActionException |
633 | { |
634 | SecureActionBundle bundle = new SecureActionBundle(); |
635 | bundle.setRequiresAuthentication( true ); |
636 | bundle.addRequiredAuthorization( ContinuumRoleConstants.CONTINUUM_MANAGE_PURGING, Resource.GLOBAL ); |
637 | |
638 | return bundle; |
639 | } |
640 | } |