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 java.util.ArrayList; |
23 | import java.util.Collection; |
24 | import java.util.Collections; |
25 | import java.util.Comparator; |
26 | import java.util.HashMap; |
27 | import java.util.Iterator; |
28 | import java.util.LinkedHashMap; |
29 | import java.util.List; |
30 | import java.util.Map; |
31 | import java.util.regex.Pattern; |
32 | |
33 | import org.apache.commons.collections.ComparatorUtils; |
34 | import org.apache.commons.lang.StringEscapeUtils; |
35 | import org.apache.commons.lang.StringUtils; |
36 | import org.apache.continuum.buildmanager.BuildManagerException; |
37 | import org.apache.continuum.buildmanager.BuildsManager; |
38 | import org.apache.continuum.model.project.ProjectScmRoot; |
39 | import org.apache.continuum.model.repository.LocalRepository; |
40 | import org.apache.continuum.web.util.AuditLog; |
41 | import org.apache.continuum.web.util.AuditLogConstants; |
42 | import org.apache.maven.continuum.ContinuumException; |
43 | import org.apache.maven.continuum.model.project.BuildDefinition; |
44 | import org.apache.maven.continuum.model.project.BuildResult; |
45 | import org.apache.maven.continuum.model.project.Project; |
46 | import org.apache.maven.continuum.model.project.ProjectDependency; |
47 | import org.apache.maven.continuum.model.project.ProjectGroup; |
48 | import org.apache.maven.continuum.project.ContinuumProjectState; |
49 | import org.apache.maven.continuum.web.bean.ProjectGroupUserBean; |
50 | import org.apache.maven.continuum.web.exception.AuthorizationRequiredException; |
51 | import org.codehaus.plexus.redback.rbac.RBACManager; |
52 | import org.codehaus.plexus.redback.rbac.RbacManagerException; |
53 | import org.codehaus.plexus.redback.rbac.RbacObjectNotFoundException; |
54 | import org.codehaus.plexus.redback.rbac.Role; |
55 | import org.codehaus.plexus.redback.rbac.UserAssignment; |
56 | import org.codehaus.plexus.redback.role.RoleManager; |
57 | import org.codehaus.plexus.redback.role.RoleManagerException; |
58 | import org.codehaus.plexus.redback.users.User; |
59 | import org.slf4j.Logger; |
60 | import org.slf4j.LoggerFactory; |
61 | |
62 | /** |
63 | * ProjectGroupAction: |
64 | * |
65 | * @author Jesse McConnell <jmcconnell@apache.org> |
66 | * @version $Id: ProjectGroupAction.java 1101669 2011-05-10 22:46:21Z ctan $ |
67 | * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="projectGroup" |
68 | */ |
69 | public class ProjectGroupAction |
70 | extends ContinuumConfirmAction |
71 | { |
72 | private static final Logger logger = LoggerFactory.getLogger( ProjectGroupAction.class ); |
73 | |
74 | private static final Map<String, String> FILTER_CRITERIA = new HashMap<String, String>(); |
75 | |
76 | static |
77 | { |
78 | FILTER_CRITERIA.put( "username", "Username contains" ); |
79 | FILTER_CRITERIA.put( "fullName", "Name contains" ); |
80 | FILTER_CRITERIA.put( "email", "Email contains" ); |
81 | } |
82 | |
83 | /** |
84 | * @plexus.requirement role-hint="cached" |
85 | */ |
86 | private RBACManager rbac; |
87 | |
88 | /** |
89 | * @plexus.requirement role-hint="default" |
90 | */ |
91 | private RoleManager roleManager; |
92 | |
93 | /** |
94 | * @plexus.requirement role-hint="parallel" |
95 | */ |
96 | private BuildsManager parallelBuildsManager; |
97 | |
98 | private int projectGroupId; |
99 | |
100 | private ProjectGroup projectGroup; |
101 | |
102 | private String name; |
103 | |
104 | private String description; |
105 | |
106 | private Map projects = new HashMap(); |
107 | |
108 | private Map<Integer, String> projectGroups = new HashMap<Integer, String>(); |
109 | |
110 | private boolean projectInCOQueue = false; |
111 | |
112 | private Collection<Project> projectList; |
113 | |
114 | private List<ProjectGroupUserBean> projectGroupUsers; |
115 | |
116 | private String filterProperty; |
117 | |
118 | private String filterKey; |
119 | |
120 | //Default order is by username |
121 | private String sorterProperty = "username"; |
122 | |
123 | private boolean ascending = true; |
124 | |
125 | private Collection groupProjects; |
126 | |
127 | private int releaseProjectId; |
128 | |
129 | private Map<String, Integer> buildDefinitions; |
130 | |
131 | private int buildDefinitionId; |
132 | |
133 | private boolean fromSummaryPage = false; |
134 | |
135 | private String preferredExecutor = "maven2"; |
136 | |
137 | private String url; |
138 | |
139 | private int repositoryId; |
140 | |
141 | private List<LocalRepository> repositories; |
142 | |
143 | private boolean disabledRepositories = true; |
144 | |
145 | private List<ProjectScmRoot> projectScmRoots; |
146 | |
147 | public void prepare() |
148 | throws Exception |
149 | { |
150 | super.prepare(); |
151 | |
152 | repositories = getContinuum().getRepositoryService().getAllLocalRepositories(); |
153 | } |
154 | |
155 | public String summary() |
156 | throws ContinuumException |
157 | { |
158 | try |
159 | { |
160 | checkViewProjectGroupAuthorization( getProjectGroupName() ); |
161 | } |
162 | catch ( AuthorizationRequiredException authzE ) |
163 | { |
164 | addActionError( authzE.getMessage() ); |
165 | return REQUIRES_AUTHORIZATION; |
166 | } |
167 | catch ( ContinuumException e ) |
168 | { |
169 | addActionError( getText( "projectGroup.invalid.id", "Invalid Project Group Id: " + projectGroupId, |
170 | Integer.toString( projectGroupId ) ) ); |
171 | return "to_summary_page"; |
172 | } |
173 | |
174 | projectGroup = getContinuum().getProjectGroupWithProjects( projectGroupId ); |
175 | |
176 | List<BuildDefinition> projectGroupBuildDefs = |
177 | getContinuum().getBuildDefinitionsForProjectGroup( projectGroupId ); |
178 | |
179 | if ( projectGroupBuildDefs != null ) |
180 | { |
181 | this.buildDefinitions = new LinkedHashMap<String, Integer>( projectGroupBuildDefs.size() ); |
182 | for ( BuildDefinition buildDefinition : projectGroupBuildDefs ) |
183 | { |
184 | |
185 | if ( !buildDefinition.isDefaultForProject() ) |
186 | { |
187 | String key = StringUtils.isEmpty( buildDefinition.getDescription() ) ? buildDefinition.getGoals() |
188 | : buildDefinition.getDescription(); |
189 | buildDefinitions.put( key, buildDefinition.getId() ); |
190 | } |
191 | } |
192 | } |
193 | else |
194 | { |
195 | this.buildDefinitions = Collections.EMPTY_MAP; |
196 | } |
197 | |
198 | if ( projectGroup != null ) |
199 | { |
200 | if ( projectGroup.getProjects() != null && projectGroup.getProjects().size() > 0 ) |
201 | { |
202 | int nbMaven2Projects = 0; |
203 | int nbMaven1Projects = 0; |
204 | int nbAntProjects = 0; |
205 | int nbShellProjects = 0; |
206 | |
207 | Project rootProject = ( getContinuum().getProjectsInBuildOrder( |
208 | getContinuum().getProjectsInGroupWithDependencies( projectGroupId ) ) ).get( 0 ); |
209 | if ( "maven2".equals( rootProject.getExecutorId() ) || "maven-1".equals( rootProject.getExecutorId() ) ) |
210 | { |
211 | url = rootProject.getUrl(); |
212 | } |
213 | |
214 | for ( Object o : projectGroup.getProjects() ) |
215 | { |
216 | Project p = (Project) o; |
217 | if ( "maven2".equals( p.getExecutorId() ) ) |
218 | { |
219 | nbMaven2Projects += 1; |
220 | } |
221 | else if ( "maven-1".equals( p.getExecutorId() ) ) |
222 | { |
223 | nbMaven1Projects += 1; |
224 | } |
225 | else if ( "ant".equals( p.getExecutorId() ) ) |
226 | { |
227 | nbAntProjects += 1; |
228 | } |
229 | else if ( "shell".equals( p.getExecutorId() ) ) |
230 | { |
231 | nbShellProjects += 1; |
232 | } |
233 | } |
234 | |
235 | int nbActualPreferredProject = nbMaven2Projects; |
236 | if ( nbMaven1Projects > nbActualPreferredProject ) |
237 | { |
238 | preferredExecutor = "maven-1"; |
239 | nbActualPreferredProject = nbMaven1Projects; |
240 | } |
241 | if ( nbAntProjects > nbActualPreferredProject ) |
242 | { |
243 | preferredExecutor = "ant"; |
244 | nbActualPreferredProject = nbAntProjects; |
245 | } |
246 | if ( nbShellProjects > nbActualPreferredProject ) |
247 | { |
248 | preferredExecutor = "shell"; |
249 | } |
250 | } |
251 | |
252 | projectScmRoots = getContinuum().getProjectScmRootByProjectGroup( projectGroup.getId() ); |
253 | } |
254 | |
255 | return SUCCESS; |
256 | } |
257 | |
258 | public String members() |
259 | throws ContinuumException |
260 | { |
261 | try |
262 | { |
263 | checkViewProjectGroupAuthorization( getProjectGroupName() ); |
264 | } |
265 | catch ( AuthorizationRequiredException authzE ) |
266 | { |
267 | addActionError( authzE.getMessage() ); |
268 | return REQUIRES_AUTHORIZATION; |
269 | } |
270 | |
271 | projectGroup = getContinuum().getProjectGroupWithProjects( projectGroupId ); |
272 | |
273 | groupProjects = projectGroup.getProjects(); |
274 | |
275 | populateProjectGroupUsers( projectGroup ); |
276 | |
277 | return SUCCESS; |
278 | } |
279 | |
280 | public Collection getGroupProjects() |
281 | throws ContinuumException |
282 | { |
283 | return groupProjects; |
284 | } |
285 | |
286 | public String buildDefinitions() |
287 | throws ContinuumException |
288 | { |
289 | return summary(); |
290 | } |
291 | |
292 | public String notifiers() |
293 | throws ContinuumException |
294 | { |
295 | return summary(); |
296 | } |
297 | |
298 | public String remove() |
299 | throws ContinuumException |
300 | { |
301 | try |
302 | { |
303 | checkRemoveProjectGroupAuthorization( getProjectGroupName() ); |
304 | } |
305 | catch ( AuthorizationRequiredException authzE ) |
306 | { |
307 | addActionError( authzE.getMessage() ); |
308 | return REQUIRES_AUTHORIZATION; |
309 | } |
310 | |
311 | try |
312 | { |
313 | getContinuum().removeProjectGroup( projectGroupId ); |
314 | } |
315 | catch ( ContinuumException e ) |
316 | { |
317 | logger.error( "Error while removing project group with id " + projectGroupId, e ); |
318 | addActionError( getText( "projectGroup.delete.error", "Unable to remove project group", |
319 | Integer.toString( projectGroupId ) ) ); |
320 | } |
321 | |
322 | AuditLog event = new AuditLog( "Project Group id=" + projectGroupId, AuditLogConstants.REMOVE_PROJECT_GROUP ); |
323 | event.setCategory( AuditLogConstants.PROJECT ); |
324 | event.setCurrentUser( getPrincipal() ); |
325 | event.log(); |
326 | |
327 | return SUCCESS; |
328 | } |
329 | |
330 | public String confirmRemove() |
331 | throws ContinuumException |
332 | { |
333 | try |
334 | { |
335 | checkRemoveProjectGroupAuthorization( getProjectGroupName() ); |
336 | } |
337 | catch ( AuthorizationRequiredException authzE ) |
338 | { |
339 | addActionError( authzE.getMessage() ); |
340 | return REQUIRES_AUTHORIZATION; |
341 | } |
342 | |
343 | name = getProjectGroupName(); |
344 | return CONFIRM; |
345 | } |
346 | |
347 | private void initialize() |
348 | throws ContinuumException |
349 | { |
350 | try |
351 | { |
352 | checkManageLocalRepositoriesAuthorization(); |
353 | disabledRepositories = false; |
354 | } |
355 | catch ( AuthorizationRequiredException authzE ) |
356 | { |
357 | // do nothing |
358 | } |
359 | |
360 | projectGroup = getContinuum().getProjectGroupWithProjects( projectGroupId ); |
361 | |
362 | projectList = projectGroup.getProjects(); |
363 | |
364 | if ( projectList != null ) |
365 | { |
366 | for ( Project p : projectList ) |
367 | { |
368 | try |
369 | { |
370 | if ( parallelBuildsManager.isInAnyCheckoutQueue( p.getId() ) ) |
371 | { |
372 | projectInCOQueue = true; |
373 | } |
374 | } |
375 | catch ( BuildManagerException e ) |
376 | { |
377 | throw new ContinuumException( e.getMessage(), e ); |
378 | } |
379 | projects.put( p, p.getProjectGroup().getId() ); |
380 | } |
381 | } |
382 | |
383 | for ( ProjectGroup pg : getContinuum().getAllProjectGroups() ) |
384 | { |
385 | if ( isAuthorized( projectGroup.getName() ) ) |
386 | { |
387 | projectGroups.put( pg.getId(), pg.getName() ); |
388 | } |
389 | } |
390 | repositories = getContinuum().getRepositoryService().getAllLocalRepositories(); |
391 | } |
392 | |
393 | public String edit() |
394 | throws ContinuumException |
395 | { |
396 | try |
397 | { |
398 | checkModifyProjectGroupAuthorization( getProjectGroupName() ); |
399 | } |
400 | catch ( AuthorizationRequiredException authzE ) |
401 | { |
402 | addActionError( authzE.getMessage() ); |
403 | return REQUIRES_AUTHORIZATION; |
404 | } |
405 | |
406 | initialize(); |
407 | |
408 | name = projectGroup.getName(); |
409 | |
410 | description = projectGroup.getDescription(); |
411 | |
412 | projectList = projectGroup.getProjects(); |
413 | |
414 | if ( projectGroup.getLocalRepository() != null ) |
415 | { |
416 | repositoryId = projectGroup.getLocalRepository().getId(); |
417 | } |
418 | else |
419 | { |
420 | repositoryId = -1; |
421 | } |
422 | |
423 | Collection<Project> projList = getContinuum().getProjectsInGroupWithDependencies( projectGroup.getId() ); |
424 | if ( projList != null && projList.size() > 0 ) |
425 | { |
426 | Project rootProject = ( getContinuum().getProjectsInBuildOrder( projList ) ).get( 0 ); |
427 | |
428 | if ( rootProject != null ) |
429 | { |
430 | setUrl( rootProject.getUrl() ); |
431 | } |
432 | } |
433 | return SUCCESS; |
434 | } |
435 | |
436 | public String save() |
437 | throws Exception |
438 | { |
439 | try |
440 | { |
441 | checkModifyProjectGroupAuthorization( getProjectGroupName() ); |
442 | } |
443 | catch ( AuthorizationRequiredException authzE ) |
444 | { |
445 | addActionError( authzE.getMessage() ); |
446 | return REQUIRES_AUTHORIZATION; |
447 | } |
448 | |
449 | for ( ProjectGroup projectGroup : getContinuum().getAllProjectGroups() ) |
450 | { |
451 | if ( name.equals( projectGroup.getName() ) && projectGroup.getId() != projectGroupId ) |
452 | { |
453 | addActionError( getText( "projectGroup.error.name.already.exists" ) ); |
454 | } |
455 | } |
456 | |
457 | if ( hasActionErrors() ) |
458 | { |
459 | initialize(); |
460 | return INPUT; |
461 | } |
462 | |
463 | projectGroup = getContinuum().getProjectGroupWithProjects( projectGroupId ); |
464 | |
465 | // need to administer roles since they are based off of this |
466 | // todo convert everything like to work off of string keys |
467 | if ( !name.equals( projectGroup.getName() ) ) |
468 | { |
469 | // CONTINUUM-1502 |
470 | name = name.trim(); |
471 | try |
472 | { |
473 | roleManager.updateRole( "project-administrator", projectGroup.getName(), name ); |
474 | roleManager.updateRole( "project-developer", projectGroup.getName(), name ); |
475 | roleManager.updateRole( "project-user", projectGroup.getName(), name ); |
476 | |
477 | projectGroup.setName( name ); |
478 | } |
479 | catch ( RoleManagerException e ) |
480 | { |
481 | throw new ContinuumException( "unable to rename the project group", e ); |
482 | } |
483 | |
484 | } |
485 | |
486 | projectGroup.setDescription( StringEscapeUtils.escapeXml( StringEscapeUtils.unescapeXml( description ) ) ); |
487 | |
488 | // [CONTINUUM-2228]. In select field can't select empty values. |
489 | if ( repositoryId > 0 ) |
490 | { |
491 | LocalRepository repository = getContinuum().getRepositoryService().getLocalRepository( repositoryId ); |
492 | projectGroup.setLocalRepository( repository ); |
493 | } |
494 | |
495 | getContinuum().updateProjectGroup( projectGroup ); |
496 | |
497 | Collection<Project> projectList = getContinuum().getProjectsInGroupWithDependencies( projectGroupId ); |
498 | if ( projectList != null && projectList.size() > 0 ) |
499 | { |
500 | Project rootProject = ( getContinuum().getProjectsInBuildOrder( projectList ) ).get( 0 ); |
501 | |
502 | rootProject.setUrl( url ); |
503 | |
504 | getContinuum().updateProject( rootProject ); |
505 | } |
506 | |
507 | Iterator keys = projects.keySet().iterator(); |
508 | while ( keys.hasNext() ) |
509 | { |
510 | String key = (String) keys.next(); |
511 | |
512 | String[] id = (String[]) projects.get( key ); |
513 | |
514 | int projectId = Integer.parseInt( key ); |
515 | |
516 | Project project = null; |
517 | Iterator i = projectGroup.getProjects().iterator(); |
518 | while ( i.hasNext() ) |
519 | { |
520 | project = (Project) i.next(); |
521 | if ( projectId == project.getId() ) |
522 | { |
523 | break; |
524 | } |
525 | } |
526 | |
527 | ProjectGroup newProjectGroup = getContinuum().getProjectGroupWithProjects( new Integer( id[0] ) ); |
528 | |
529 | if ( newProjectGroup.getId() != projectGroup.getId() && isAuthorized( newProjectGroup.getName() ) ) |
530 | { |
531 | logger.info( "Moving project " + project.getName() + " to project group " + newProjectGroup.getName() ); |
532 | project.setProjectGroup( newProjectGroup ); |
533 | |
534 | // CONTINUUM-1512 |
535 | Collection<BuildResult> results = getContinuum().getBuildResultsForProject( project.getId() ); |
536 | for ( BuildResult br : results ) |
537 | { |
538 | getContinuum().removeBuildResult( br.getId() ); |
539 | } |
540 | |
541 | getContinuum().updateProject( project ); |
542 | } |
543 | } |
544 | |
545 | AuditLog event = new AuditLog( "Project Group id=" + projectGroupId, AuditLogConstants.MODIFY_PROJECT_GROUP ); |
546 | event.setCategory( AuditLogConstants.PROJECT ); |
547 | event.setCurrentUser( getPrincipal() ); |
548 | event.log(); |
549 | |
550 | return SUCCESS; |
551 | } |
552 | |
553 | public String build() |
554 | throws ContinuumException |
555 | { |
556 | try |
557 | { |
558 | checkBuildProjectGroupAuthorization( getProjectGroupName() ); |
559 | } |
560 | catch ( AuthorizationRequiredException authzE ) |
561 | { |
562 | addActionError( authzE.getMessage() ); |
563 | return REQUIRES_AUTHORIZATION; |
564 | } |
565 | |
566 | if ( this.getBuildDefinitionId() == -1 ) |
567 | { |
568 | getContinuum().buildProjectGroup( projectGroupId ); |
569 | } |
570 | else |
571 | { |
572 | getContinuum().buildProjectGroupWithBuildDefinition( projectGroupId, buildDefinitionId ); |
573 | } |
574 | |
575 | AuditLog event = new AuditLog( "Project Group id=" + projectGroupId, AuditLogConstants.FORCE_BUILD ); |
576 | event.setCategory( AuditLogConstants.PROJECT ); |
577 | event.setCurrentUser( getPrincipal() ); |
578 | event.log(); |
579 | |
580 | if ( this.isFromSummaryPage() ) |
581 | { |
582 | return "to_summary_page"; |
583 | } |
584 | else |
585 | { |
586 | return SUCCESS; |
587 | } |
588 | } |
589 | |
590 | public String release() |
591 | throws ContinuumException |
592 | { |
593 | try |
594 | { |
595 | checkBuildProjectGroupAuthorization( getProjectGroupName() ); |
596 | } |
597 | catch ( AuthorizationRequiredException authzE ) |
598 | { |
599 | addActionError( authzE.getMessage() ); |
600 | return REQUIRES_AUTHORIZATION; |
601 | } |
602 | |
603 | // get the parent of the group by finding the parent project |
604 | // i.e., the project that doesn't have a parent, or it's parent is not in the group. |
605 | |
606 | Project parent = null; |
607 | |
608 | boolean allBuildsOk = true; |
609 | |
610 | boolean allMavenTwo = true; |
611 | |
612 | projectList = getContinuum().getProjectsInGroupWithDependencies( projectGroupId ); |
613 | |
614 | if ( projectList != null ) |
615 | { |
616 | for ( Project p : projectList ) |
617 | { |
618 | if ( p.getState() != ContinuumProjectState.OK ) |
619 | { |
620 | allBuildsOk = false; |
621 | } |
622 | |
623 | if ( ( p.getParent() == null ) || ( !isParentInProjectGroup( p.getParent(), projectList ) ) ) |
624 | { |
625 | if ( parent == null ) |
626 | { |
627 | parent = p; |
628 | } |
629 | else |
630 | { |
631 | // currently, we have no provisions for releasing 2 or more parents |
632 | // at the same time, this will be implemented in the future |
633 | addActionError( getText( "projectGroup.release.error.severalParentProjects" ) ); |
634 | return INPUT; |
635 | } |
636 | } |
637 | |
638 | if ( !"maven2".equals( p.getExecutorId() ) ) |
639 | { |
640 | allMavenTwo = false; |
641 | } |
642 | } |
643 | } |
644 | |
645 | if ( parent == null ) |
646 | { |
647 | addActionError( getText( "projectGroup.release.error.emptyGroup" ) ); |
648 | return INPUT; |
649 | } |
650 | |
651 | releaseProjectId = parent.getId(); |
652 | |
653 | if ( allBuildsOk && allMavenTwo ) |
654 | { |
655 | return SUCCESS; |
656 | } |
657 | else |
658 | { |
659 | addActionError( getText( "projectGroup.release.error.projectNotInSuccess" ) ); |
660 | return INPUT; |
661 | } |
662 | } |
663 | |
664 | private boolean isParentInProjectGroup( ProjectDependency parent, Collection<Project> projectsInGroup ) |
665 | throws ContinuumException |
666 | { |
667 | boolean result = false; |
668 | |
669 | for ( Project project : projectsInGroup ) |
670 | { |
671 | if ( parent != null ) |
672 | { |
673 | if ( ( project.getArtifactId().equals( parent.getArtifactId() ) ) && |
674 | ( project.getGroupId().equals( parent.getGroupId() ) ) && |
675 | ( project.getVersion().equals( parent.getVersion() ) ) ) |
676 | { |
677 | result = true; |
678 | } |
679 | } |
680 | } |
681 | |
682 | return result; |
683 | } |
684 | |
685 | private void populateProjectGroupUsers( ProjectGroup group ) |
686 | { |
687 | List<User> users = new ArrayList<User>(); |
688 | |
689 | try |
690 | { |
691 | List<Role> roles = rbac.getAllRoles(); |
692 | List<String> roleNames = new ArrayList<String>(); |
693 | for ( Role r : roles ) |
694 | { |
695 | String projectGroupName = StringUtils.substringAfter( r.getName(), "-" ).trim(); |
696 | |
697 | if ( projectGroupName.equals( group.getName() ) ) |
698 | { |
699 | roleNames.add( r.getName() ); |
700 | } |
701 | } |
702 | List<UserAssignment> userAssignments = rbac.getUserAssignmentsForRoles( roleNames ); |
703 | for ( UserAssignment ua : userAssignments ) |
704 | { |
705 | User u = getSecuritySystem().getUserManager().findUser( ua.getPrincipal() ); |
706 | if ( u != null ) |
707 | { |
708 | users.add( u ); |
709 | } |
710 | } |
711 | } |
712 | catch ( Exception e ) |
713 | { |
714 | logger.error( "Can't get the users list", e ); |
715 | } |
716 | |
717 | if ( StringUtils.isNotBlank( filterKey ) ) |
718 | { |
719 | users = findUsers( users, filterProperty, filterKey ); |
720 | } |
721 | if ( StringUtils.isNotBlank( sorterProperty ) ) |
722 | { |
723 | sortUsers( users, sorterProperty, ascending ); |
724 | } |
725 | |
726 | projectGroupUsers = new ArrayList<ProjectGroupUserBean>(); |
727 | |
728 | if ( users == null ) |
729 | { |
730 | return; |
731 | } |
732 | |
733 | for ( User user : users ) |
734 | { |
735 | ProjectGroupUserBean pgUser = new ProjectGroupUserBean(); |
736 | |
737 | pgUser.setUser( user ); |
738 | |
739 | pgUser.setProjectGroup( group ); |
740 | |
741 | try |
742 | { |
743 | Collection<Role> effectiveRoles = rbac.getEffectivelyAssignedRoles( user.getUsername() ); |
744 | |
745 | for ( Role role : effectiveRoles ) |
746 | { |
747 | if ( role.getName().indexOf( projectGroup.getName() ) > -1 ) |
748 | { |
749 | pgUser.setRoles( effectiveRoles ); |
750 | projectGroupUsers.add( pgUser ); |
751 | break; |
752 | } |
753 | } |
754 | } |
755 | catch ( RbacObjectNotFoundException e ) |
756 | { |
757 | pgUser.setRoles( Collections.EMPTY_LIST ); |
758 | } |
759 | catch ( RbacManagerException e ) |
760 | { |
761 | pgUser.setRoles( Collections.EMPTY_LIST ); |
762 | } |
763 | } |
764 | } |
765 | |
766 | private List<User> findUsers( List<User> users, String searchProperty, String searchKey ) |
767 | { |
768 | List<User> userList = new ArrayList<User>(); |
769 | for ( User user : users ) |
770 | { |
771 | if ( "username".equals( searchProperty ) ) |
772 | { |
773 | String username = user.getUsername(); |
774 | if ( username != null ) |
775 | { |
776 | if ( username.toLowerCase().indexOf( searchKey.toLowerCase() ) >= 0 ) |
777 | { |
778 | userList.add( user ); |
779 | } |
780 | } |
781 | } |
782 | else if ( "fullName".equals( searchProperty ) ) |
783 | { |
784 | String fullname = user.getFullName(); |
785 | if ( fullname != null ) |
786 | { |
787 | if ( fullname.toLowerCase().indexOf( searchKey.toLowerCase() ) >= 0 ) |
788 | { |
789 | userList.add( user ); |
790 | } |
791 | } |
792 | } |
793 | else if ( "email".equals( searchProperty ) ) |
794 | { |
795 | String email = user.getEmail(); |
796 | if ( email != null ) |
797 | { |
798 | if ( email.toLowerCase().indexOf( searchKey.toLowerCase() ) >= 0 ) |
799 | { |
800 | userList.add( user ); |
801 | } |
802 | } |
803 | } |
804 | } |
805 | |
806 | return userList; |
807 | } |
808 | |
809 | private void sortUsers( List<User> userList, final String sorterProperty, final boolean orderAscending ) |
810 | { |
811 | Collections.sort( userList, new Comparator<User>() |
812 | { |
813 | public int compare( User o1, User o2 ) |
814 | { |
815 | String value1, value2; |
816 | if ( "fullName".equals( sorterProperty ) ) |
817 | { |
818 | value1 = o1.getFullName(); |
819 | value2 = o2.getFullName(); |
820 | } |
821 | else if ( "email".equals( sorterProperty ) ) |
822 | { |
823 | value1 = o1.getEmail(); |
824 | value2 = o2.getEmail(); |
825 | } |
826 | else |
827 | { |
828 | value1 = o1.getUsername(); |
829 | value2 = o2.getUsername(); |
830 | } |
831 | if ( orderAscending ) |
832 | { |
833 | return ComparatorUtils.nullLowComparator( null ).compare( value1, value2 ); |
834 | } |
835 | return ComparatorUtils.nullLowComparator( null ).compare( value2, value1 ); |
836 | } |
837 | } ); |
838 | } |
839 | |
840 | public int getProjectGroupId() |
841 | { |
842 | return projectGroupId; |
843 | } |
844 | |
845 | public void setProjectGroupId( int projectGroupId ) |
846 | { |
847 | this.projectGroupId = projectGroupId; |
848 | } |
849 | |
850 | public ProjectGroup getProjectGroup() |
851 | { |
852 | return projectGroup; |
853 | } |
854 | |
855 | public void setProjectGroup( ProjectGroup projectGroup ) |
856 | { |
857 | this.projectGroup = projectGroup; |
858 | } |
859 | |
860 | public String getDescription() |
861 | { |
862 | return description; |
863 | } |
864 | |
865 | public void setDescription( String description ) |
866 | { |
867 | this.description = description; |
868 | } |
869 | |
870 | public String getName() |
871 | { |
872 | return name; |
873 | } |
874 | |
875 | public void setName( String name ) |
876 | { |
877 | this.name = name; |
878 | } |
879 | |
880 | public Map getProjects() |
881 | { |
882 | return projects; |
883 | } |
884 | |
885 | public void setProjects( Map projects ) |
886 | { |
887 | this.projects = projects; |
888 | } |
889 | |
890 | public Map<Integer, String> getProjectGroups() |
891 | { |
892 | return projectGroups; |
893 | } |
894 | |
895 | public void setProjectGroups( Map<Integer, String> projectGroups ) |
896 | { |
897 | this.projectGroups = projectGroups; |
898 | } |
899 | |
900 | public boolean isProjectInCOQueue() |
901 | { |
902 | return projectInCOQueue; |
903 | } |
904 | |
905 | public void setProjectInCOQueue( boolean projectInQueue ) |
906 | { |
907 | this.projectInCOQueue = projectInQueue; |
908 | } |
909 | |
910 | public Collection<Project> getProjectList() |
911 | { |
912 | return projectList; |
913 | } |
914 | |
915 | public List<ProjectGroupUserBean> getProjectGroupUsers() |
916 | { |
917 | return projectGroupUsers; |
918 | } |
919 | |
920 | public boolean isAscending() |
921 | { |
922 | return ascending; |
923 | } |
924 | |
925 | public void setAscending( boolean ascending ) |
926 | { |
927 | this.ascending = ascending; |
928 | } |
929 | |
930 | public String getFilterKey() |
931 | { |
932 | return filterKey; |
933 | } |
934 | |
935 | public void setFilterKey( String filterKey ) |
936 | { |
937 | this.filterKey = filterKey; |
938 | } |
939 | |
940 | public String getFilterProperty() |
941 | { |
942 | return filterProperty; |
943 | } |
944 | |
945 | public void setFilterProperty( String filterProperty ) |
946 | { |
947 | this.filterProperty = filterProperty; |
948 | } |
949 | |
950 | public Map<String, String> getCriteria() |
951 | { |
952 | return FILTER_CRITERIA; |
953 | } |
954 | |
955 | public void setReleaseProjectId( int releaseProjectId ) |
956 | { |
957 | this.releaseProjectId = releaseProjectId; |
958 | } |
959 | |
960 | public int getReleaseProjectId() |
961 | { |
962 | return this.releaseProjectId; |
963 | } |
964 | |
965 | public ProjectGroup getProjectGroup( int projectGroupId ) |
966 | throws ContinuumException |
967 | { |
968 | if ( projectGroup == null ) |
969 | { |
970 | projectGroup = getContinuum().getProjectGroup( projectGroupId ); |
971 | } |
972 | else |
973 | { |
974 | if ( projectGroup.getId() != projectGroupId ) |
975 | { |
976 | projectGroup = getContinuum().getProjectGroup( projectGroupId ); |
977 | } |
978 | } |
979 | |
980 | return projectGroup; |
981 | } |
982 | |
983 | public String getProjectGroupName() |
984 | throws ContinuumException |
985 | { |
986 | |
987 | return getProjectGroup( projectGroupId ).getName(); |
988 | } |
989 | |
990 | public Map<String, Integer> getBuildDefinitions() |
991 | { |
992 | return buildDefinitions; |
993 | } |
994 | |
995 | public void setBuildDefinitions( Map<String, Integer> buildDefinitions ) |
996 | { |
997 | this.buildDefinitions = buildDefinitions; |
998 | } |
999 | |
1000 | public int getBuildDefinitionId() |
1001 | { |
1002 | return buildDefinitionId; |
1003 | } |
1004 | |
1005 | public void setBuildDefinitionId( int buildDefinitionId ) |
1006 | { |
1007 | this.buildDefinitionId = buildDefinitionId; |
1008 | } |
1009 | |
1010 | public boolean isFromSummaryPage() |
1011 | { |
1012 | return fromSummaryPage; |
1013 | } |
1014 | |
1015 | public void setFromSummaryPage( boolean fromSummaryPage ) |
1016 | { |
1017 | this.fromSummaryPage = fromSummaryPage; |
1018 | } |
1019 | |
1020 | public String getPreferredExecutor() |
1021 | { |
1022 | return preferredExecutor; |
1023 | } |
1024 | |
1025 | public String getUrl() |
1026 | { |
1027 | return url; |
1028 | } |
1029 | |
1030 | public void setUrl( String url ) |
1031 | { |
1032 | this.url = url; |
1033 | } |
1034 | |
1035 | public int getRepositoryId() |
1036 | { |
1037 | return repositoryId; |
1038 | } |
1039 | |
1040 | public void setRepositoryId( int repositoryId ) |
1041 | { |
1042 | this.repositoryId = repositoryId; |
1043 | } |
1044 | |
1045 | public List<LocalRepository> getRepositories() |
1046 | { |
1047 | return repositories; |
1048 | } |
1049 | |
1050 | public void setRepositories( List<LocalRepository> repositories ) |
1051 | { |
1052 | this.repositories = repositories; |
1053 | } |
1054 | |
1055 | public boolean isDisabledRepositories() |
1056 | { |
1057 | return disabledRepositories; |
1058 | } |
1059 | |
1060 | public void setDisabledRepositories( boolean disabledRepositories ) |
1061 | { |
1062 | this.disabledRepositories = disabledRepositories; |
1063 | } |
1064 | |
1065 | public List<ProjectScmRoot> getProjectScmRoots() |
1066 | { |
1067 | return projectScmRoots; |
1068 | } |
1069 | |
1070 | public void setProjectScmRoots( List<ProjectScmRoot> projectScmRoots ) |
1071 | { |
1072 | this.projectScmRoots = projectScmRoots; |
1073 | } |
1074 | |
1075 | private boolean isAuthorized( String projectGroupName ) |
1076 | { |
1077 | try |
1078 | { |
1079 | checkAddProjectToGroupAuthorization( projectGroupName ); |
1080 | return true; |
1081 | } |
1082 | catch ( AuthorizationRequiredException authzE ) |
1083 | { |
1084 | return false; |
1085 | } |
1086 | } |
1087 | |
1088 | public String getSorterProperty() |
1089 | { |
1090 | return sorterProperty; |
1091 | } |
1092 | |
1093 | public void setSorterProperty( String sorterProperty ) |
1094 | { |
1095 | this.sorterProperty = sorterProperty; |
1096 | } |
1097 | } |