/src/main/java/com/topmanage/jiraplugins/projecttemplates/ProjectCloner.java
Java | 574 lines | 403 code | 142 blank | 29 comment | 47 complexity | 38b3773504e16c7ae1c3778495ff42b9 MD5 | raw file
Possible License(s): Apache-2.0
- ///Some parts of this code were ported from the following open source groovy scripts:
- ///https://bitbucket.org/jamieechlin/scriptrunner-public/src/be2bcb817137/src/main/resources/com/onresolve/jira/groovy/canned/admin/CopyProject.groovy
- ///https://bitbucket.org/jamieechlin/scriptrunner-public/src/be2bcb8171373d2cc4348b6bd7204d51b301c5ec/src/main/resources/com/onresolve/jira/groovy/canned/workflow/postfunctions/CloneIssue.groovy
- package com.topmanage.jiraplugins.projecttemplates;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.atlassian.jira.avatar.Avatar;
- import com.atlassian.jira.avatar.AvatarManager;
- import com.atlassian.jira.bc.issue.IssueService;
- import com.atlassian.jira.bc.issue.search.SearchService;
- import com.atlassian.jira.bc.project.ProjectCreationData;
- import com.atlassian.jira.bc.project.ProjectService;
- import com.atlassian.jira.bc.project.component.ProjectComponent;
- import com.atlassian.jira.bc.project.component.ProjectComponentManager;
- import com.atlassian.jira.bc.projectroles.ProjectRoleService;
- import com.atlassian.jira.config.SubTaskManager;
- import com.atlassian.jira.exception.CreateException;
- import com.atlassian.jira.issue.CustomFieldManager;
- import com.atlassian.jira.issue.Issue;
- import com.atlassian.jira.issue.IssueFactory;
- import com.atlassian.jira.issue.IssueFieldConstants;
- import com.atlassian.jira.issue.IssueManager;
- import com.atlassian.jira.issue.MutableIssue;
- import com.atlassian.jira.issue.context.JiraContextNode;
- import com.atlassian.jira.issue.context.manager.JiraContextTreeManager;
- import com.atlassian.jira.issue.customfields.CustomFieldUtils;
- import com.atlassian.jira.issue.fields.CustomField;
- import com.atlassian.jira.issue.fields.FieldManager;
- import com.atlassian.jira.issue.fields.config.FieldConfig;
- import com.atlassian.jira.issue.fields.config.FieldConfigScheme;
- import com.atlassian.jira.issue.fields.config.manager.FieldConfigManager;
- import com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager;
- import com.atlassian.jira.issue.fields.config.manager.IssueTypeSchemeManager;
- import com.atlassian.jira.issue.fields.layout.field.FieldConfigurationScheme;
- import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager;
- import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager;
- import com.atlassian.jira.issue.index.IndexException;
- import com.atlassian.jira.issue.index.IssueIndexingService;
- import com.atlassian.jira.issue.label.Label;
- import com.atlassian.jira.issue.label.LabelManager;
- import com.atlassian.jira.issue.search.SearchException;
- import com.atlassian.jira.issue.search.SearchRequest;
- import com.atlassian.jira.issue.search.SearchResults;
- import com.atlassian.jira.issue.security.IssueSecuritySchemeManager;
- import com.atlassian.jira.jql.builder.JqlQueryBuilder;
- import com.atlassian.jira.notification.NotificationSchemeManager;
- import com.atlassian.jira.permission.PermissionSchemeManager;
- import com.atlassian.jira.project.Project;
- import com.atlassian.jira.project.ProjectCategory;
- import com.atlassian.jira.project.ProjectManager;
- import com.atlassian.jira.project.version.Version;
- import com.atlassian.jira.project.version.VersionManager;
- import com.atlassian.jira.security.roles.ProjectRole;
- import com.atlassian.jira.security.roles.ProjectRoleActors;
- import com.atlassian.jira.security.roles.RoleActor;
- import com.atlassian.jira.user.ApplicationUser;
- import com.atlassian.jira.user.util.UserManager;
- import com.atlassian.jira.util.ErrorCollection;
- //import com.atlassian.jira.security.roles.actor.GroupRoleActorFactory;
- //import com.atlassian.jira.security.roles.actor.UserRoleActorFactory;
- import com.atlassian.jira.util.ImportUtils;
- import com.atlassian.jira.util.SimpleErrorCollection;
- import com.atlassian.jira.web.bean.PagerFilter;
- import com.atlassian.jira.workflow.WorkflowSchemeManager;
- import com.atlassian.query.Query;
- import com.atlassian.query.order.SortOrder;
- import com.atlassian.templaterenderer.TemplateRenderer;
- import com.google.inject.internal.Lists;
- public class ProjectCloner {
- private static final Logger LOGGER = LoggerFactory.getLogger(ProjectCloner.class);
-
-
- private IssueService issueService;
- private ProjectService projectService;
- private SearchService searchService;
- private TemplateRenderer templateRenderer;
- private ProjectManager projectManager;
- private AvatarManager avatarManager;
- private PermissionSchemeManager permissionSchemeManager;
- private NotificationSchemeManager notificationSchemeManager;
- private IssueSecuritySchemeManager issueSecuritySchemeManager;
- private VersionManager versionManager;
- private ProjectComponentManager projectComponentManager;
- private JiraContextTreeManager jiraContextTreeManager;
- private FieldConfigSchemeManager fieldConfigSchemeManager;
- private IssueTypeSchemeManager issueTypeSchemeManager;
- private FieldManager fieldManager;
- private WorkflowSchemeManager workflowSchemeManager;
- private FieldLayoutManager fieldLayoutManager;
- private IssueTypeScreenSchemeManager issueTypeScreenSchemeManager;
- private CustomFieldManager customFieldManager;
- private FieldConfigManager fieldConfigManager;
- private ProjectRoleService projectRoleService;
- private IssueManager issueManager;
- private IssueFactory issueFactory;
-
- private ImportUtils importUtils;
- private LabelManager labelManager;
- private SubTaskManager subTaskManager;
- private UserManager jiraUserManager;
- private static final String LIST_BROWSER_TEMPLATE = "/templates/list.vm";
- private static final String NEW_BROWSER_TEMPLATE = "/templates/new.vm";
- private static final String EDIT_BROWSER_TEMPLATE = "/templates/edit.vm";
- private IssueIndexingService issueIndexingService;
-
- public ProjectCloner(IssueService issueService, ProjectService projectService,
- SearchService searchService,
- com.atlassian.jira.user.util.UserManager jiraUserManager,
- TemplateRenderer templateRenderer, ProjectManager projectManager,
- AvatarManager avatarManager, PermissionSchemeManager permissionSchemeManager,
- NotificationSchemeManager notificationSchemeManager, IssueSecuritySchemeManager issueSecuritySchemeManager,
- VersionManager versionManager, ProjectComponentManager projectComponentManager,
- IssueTypeSchemeManager issueTypeSchemeManager,
- FieldConfigSchemeManager fieldConfigSchemeManager, FieldManager fieldManager,
- WorkflowSchemeManager workflowSchemeManager, FieldLayoutManager fieldLayoutManager,
- IssueTypeScreenSchemeManager issueTypeScreenSchemeManager, CustomFieldManager customFieldManager,
- FieldConfigManager fieldConfigManager, ProjectRoleService projectRoleService,
- JiraContextTreeManager jiraContextTreeManager, IssueManager issueManager,
- IssueFactory issueFactory, IssueIndexingService issueIndexingService,
- ImportUtils importUtils, LabelManager labelManager, SubTaskManager subTaskManager) {
- this.issueService = issueService;
- this.projectService = projectService;
- this.searchService = searchService;
- this.templateRenderer = templateRenderer;
- this.jiraUserManager = jiraUserManager;
- this.projectManager = projectManager;
- this.avatarManager = avatarManager;
- this.permissionSchemeManager = permissionSchemeManager;
- this.notificationSchemeManager = notificationSchemeManager;
- this.issueSecuritySchemeManager = issueSecuritySchemeManager;
- this.versionManager = versionManager;
- this.projectComponentManager = projectComponentManager;
- this.jiraContextTreeManager = jiraContextTreeManager;
- this.issueTypeSchemeManager = issueTypeSchemeManager;
- this.fieldConfigSchemeManager = fieldConfigSchemeManager;
- this.fieldManager = fieldManager;
- this.workflowSchemeManager = workflowSchemeManager;
- this.fieldLayoutManager = fieldLayoutManager;
- this.issueTypeScreenSchemeManager = issueTypeScreenSchemeManager;
- this.customFieldManager = customFieldManager;
- this.fieldConfigManager = fieldConfigManager;
- this.projectRoleService = projectRoleService;
- this.issueManager = issueManager;
- this.issueFactory = issueFactory;
- this.issueIndexingService = issueIndexingService;
- this.importUtils = importUtils;
- this.labelManager = labelManager;
- this.subTaskManager = subTaskManager;
-
- }
-
-
- public Project PerformClone(String sourceProjectKey, String newProjectKey, String newProjectName, ProjectCategory newProjectCategory,
- boolean copyComponentes, boolean copyVersions, boolean copyIssues,
- ApplicationUser currentUser, String projectLead) throws ProjectCreationException{
-
- Project srcProject = projectManager.getProjectObjByKey(sourceProjectKey);
-
- //GenericValue srcProjectGV = srcProject.getGenericValue();
-
- Avatar srcProjectAvatar = srcProject.getAvatar();
-
- String lead = null;
- if (projectLead == null){
- lead = srcProject.getLeadUserName();
- }else{
- lead = projectLead;
- }
-
- ProjectCreationData data = new ProjectCreationData.Builder()
- .withType(srcProject.getProjectTypeKey())
- .withName(newProjectName)
- .withKey(newProjectKey)
- .withDescription(srcProject.getDescription())
- .withUrl(srcProject.getUrl())
- .withAssigneeType(srcProject.getAssigneeType())
- .withLead(jiraUserManager.getUserByName(lead))
- .withAvatarId(srcProjectAvatar.isSystemAvatar() ? srcProjectAvatar.getId() : avatarManager.getDefaultAvatarId(Avatar.Type.PROJECT))
- .build();
-
- final ProjectService.CreateProjectValidationResult result =
- projectService.validateCreateProject(currentUser, data);
-
- //Check if validation passed and send proper response if it did not
- if (!result.isValid()){
- ProjectCreationException e = new ProjectCreationException();
- ErrorCollection errorCollection = result.getErrorCollection();
- e.errors = errorCollection.getErrorMessages();
- throw e;
- }
-
-
- final Project newprojectObj = projectService.createProject(result);
-
- final ProjectService.UpdateProjectSchemesValidationResult schemesResult =
- projectService.validateUpdateProjectSchemes(
- currentUser,
- permissionSchemeManager.getSchemeFor(srcProject) == null ? null : permissionSchemeManager.getSchemeFor(srcProject).getId(),
- notificationSchemeManager.getSchemeFor(srcProject) == null ? null : notificationSchemeManager.getSchemeFor(srcProject).getId(),
- issueSecuritySchemeManager.getSchemeFor(srcProject) == null ? null : issueSecuritySchemeManager.getSchemeFor(srcProject).getId());
-
-
- projectService.updateProjectSchemes(schemesResult, newprojectObj);
-
- //Copy versions
- for (Version version : srcProject.getVersions()){
-
- if (!version.isArchived()){
- try {
- versionManager.createVersion(
- version.getName(),
- version.getReleaseDate(),
- version.getDescription(),
- newprojectObj.getId(),
- null);
- } catch (CreateException e) {
- LOGGER.error("Cannot copy versions", e);
- ProjectCreationException ex = new ProjectCreationException();
- ex.errors = Lists.newArrayList(e.getMessage());
- throw ex;
- }
- }
-
- }
-
-
- //Copy components
- for (ProjectComponent projectComponent : projectComponentManager.findAllForProject(srcProject.getId())){
- projectComponentManager.create(
- projectComponent.getName(),
- projectComponent.getDescription(),
- projectComponent.getLead(),
- projectComponent.getAssigneeType(),
- newprojectObj.getId());
- }
-
-
- //Issue type scheme
- FieldConfigScheme issueTypeScheme = issueTypeSchemeManager.getConfigScheme(srcProject);
- if (issueTypeScheme != issueTypeSchemeManager.getDefaultIssueTypeScheme()){
-
- List<Long> projectIds = issueTypeScheme.getAssociatedProjectIds();
- List<Long> newListWithIds = new ArrayList<Long>();
-
- for (Long id : projectIds){
- newListWithIds.add(id);
- }
-
- newListWithIds.add(newprojectObj.getId());
-
- Long[] projectIdsLong = ConvertLongListToArray(newListWithIds);
-
-
- List<JiraContextNode> contexts = CustomFieldUtils.buildJiraIssueContexts
- (false,null,projectIdsLong,jiraContextTreeManager);
-
- fieldConfigSchemeManager.updateFieldConfigScheme
- (issueTypeScheme,contexts,fieldManager.getConfigurableField(IssueFieldConstants.ISSUE_TYPE));
-
-
- }
-
- //Workflow Scheme
- if (workflowSchemeManager.getSchemeFor(srcProject) != workflowSchemeManager.getDefaultSchemeObject()){
- workflowSchemeManager.addSchemeToProject(newprojectObj,workflowSchemeManager.getSchemeFor(srcProject));
- }
-
- Project newprojectGV = newprojectObj;
-
- //Field Config/Layout Scheme
- FieldConfigurationScheme srcProjectFieldLayout = fieldLayoutManager.getFieldConfigurationScheme(srcProject);
- if (srcProjectFieldLayout != null){
-
- fieldLayoutManager.addSchemeAssociation(newprojectGV,srcProjectFieldLayout.getId());
-
- }
-
-
- //Issue Type Screen Scheme
- issueTypeScreenSchemeManager.addSchemeAssociation
- (newprojectObj, issueTypeScreenSchemeManager.getIssueTypeScreenScheme(srcProject));
-
- //Project Category
- projectManager.setProjectCategory(newprojectObj, newProjectCategory);
-
- //CustomFields
- for (CustomField customField : customFieldManager.getCustomFieldObjects()){
-
- for (FieldConfigScheme fieldConfigScheme : fieldConfigSchemeManager.getConfigSchemesForField(customField)){
-
- if (!fieldConfigScheme.isGlobal()){
-
- for (Project project : fieldConfigScheme.getAssociatedProjectObjects()){
-
- if (project.getId() == srcProject.getId()){
-
- Long fcsId = fieldConfigScheme.getId();
- FieldConfigScheme cfConfigScheme = fieldConfigSchemeManager.getFieldConfigScheme(fcsId);
- FieldConfigScheme.Builder cfSchemeBuilder = new FieldConfigScheme.Builder(cfConfigScheme);
- FieldConfig config = fieldConfigManager.getFieldConfig(fcsId);
-
- HashMap<String, FieldConfig> configs = new HashMap<String, FieldConfig>();
-
- for (String issueTypeId : fieldConfigScheme.getAssociatedIssueTypeIds()){
- configs.put(issueTypeId, config);
-
- }
-
- cfSchemeBuilder.setConfigs(configs);
- cfConfigScheme = cfSchemeBuilder.toFieldConfigScheme();
-
- List<Long> projectIdList = fieldConfigScheme.getAssociatedProjectIds();
- projectIdList.add(newprojectGV.getId());
-
- List<JiraContextNode> contexts = CustomFieldUtils.buildJiraIssueContexts(false,
- null,
- projectIdList.toArray(new Long[projectIdList.size()]),
- jiraContextTreeManager);
-
- fieldConfigSchemeManager.updateFieldConfigScheme
- (cfConfigScheme, contexts, customFieldManager.getCustomFieldObject(customField.getId()));
- }
-
- }
-
- }
-
- }
-
- }
- customFieldManager.refresh();
-
- //Project Roles
- SimpleErrorCollection errorCollection = new SimpleErrorCollection();
- for (ProjectRole projectRole : projectRoleService.getProjectRoles(currentUser, errorCollection)){
-
- ProjectRoleActors projectRoleActors = projectRoleService.getProjectRoleActors(currentUser, projectRole, srcProject, errorCollection);
-
- //String[] actorCategories = {UserRoleActorFactory.TYPE, GroupRoleActorFactory.TYPE};
- String[] actorCategories = {"atlassian-user-role-actor", "atlassian-group-role-actor"};
-
- for (String actorFactoryType : actorCategories){
-
- List<String> newProjectRoleActors = new ArrayList<String>();
-
- for (RoleActor actor : projectRoleActors.getRoleActorsByType(actorFactoryType)){
-
- newProjectRoleActors.add(actor.getParameter());
-
- }
- projectRoleService.addActorsToProjectRole(currentUser, newProjectRoleActors, projectRole, newprojectObj, actorFactoryType, errorCollection);
- }
- }
-
-
- //Copy Issues
-
- JqlQueryBuilder builder = JqlQueryBuilder.newBuilder();
- Query query = builder.where().project(srcProject.getId()).endWhere().orderBy().issueKey(SortOrder.ASC).endOrderBy().buildQuery();
-
- SearchRequest searchRequest = new SearchRequest(query);
-
- SearchResults results;
- try {
-
- results = searchService.search(currentUser, searchRequest.getQuery(), PagerFilter.getUnlimitedFilter());
-
-
- for (Issue documentIssue : results.getIssues()) {
-
- Issue issue = issueManager.getIssueObject(documentIssue.getId());
-
- //Clone issues
- if (issue != null){
-
- Issue theNewParent = null;
-
- //Clone non sub tasks
- if (issue.getParentObject() == null){
- theNewParent = CloneIssue(issue, newprojectObj, currentUser, null, lead);
- }
-
- //Clone Subtasks
- for (Issue subTask : issue.getSubTaskObjects()){
-
- Issue theNewIssue = CloneIssue(subTask, newprojectObj, currentUser, issue, lead);
- subTaskManager.createSubTaskIssueLink(theNewParent, theNewIssue, currentUser);
- }
- }
-
- }
-
- } catch (SearchException e) {
- LOGGER.error("Cannot search issues", e);
- ProjectCreationException ex = new ProjectCreationException();
- ex.errors = Lists.newArrayList(e.getMessage());
- throw ex;
- } catch (CreateException e) {
- LOGGER.error("Cannot create issue", e);
- ProjectCreationException ex = new ProjectCreationException();
- ex.errors = Lists.newArrayList(e.getMessage());
- throw ex;
- }
-
-
- return newprojectObj;
-
- }
-
-
- private Issue CloneIssue(Issue issue, Project destinationProject, ApplicationUser currentUser, Issue parentIssue, String assignee) throws ProjectCreationException{
-
- MutableIssue newIssue = issueFactory.getIssue();
-
-
- newIssue.setProjectObject(destinationProject);
-
- copySystemFieldValues(issue, newIssue, parentIssue, assignee);
- copyCustomFieldValues(issue, newIssue);
-
-
- try {
- Issue newIssueCreated = issueManager.createIssueObject(jiraUserManager.getUserByName(assignee), newIssue);
- reindexIssue(newIssueCreated);
-
- copyLabels(issue,newIssue,currentUser);
-
- return newIssueCreated;
-
- } catch (CreateException e) {
- LOGGER.error("Cannot create issue", e);
- ProjectCreationException ex = new ProjectCreationException();
- ex.errors = Lists.newArrayList(e.getMessage());
- throw ex;
- }
- }
-
- private void copyLabels(Issue issue, MutableIssue newIssue, ApplicationUser user){
-
- for (Label label : issue.getLabels() ){
-
- labelManager.addLabel(user, newIssue.getId(), label.getLabel(), false);
-
- }
-
- }
-
- private void reindexIssue(Issue issue) throws ProjectCreationException{
-
- try {
-
- Boolean wasIndexing = ImportUtils.isIndexIssues();
- ImportUtils.setIndexIssues(true);
- issueIndexingService.reIndex(issue);
- ImportUtils.setIndexIssues(wasIndexing);
-
- } catch (IndexException e) {
- LOGGER.error("Cannot reindex issue", e);
- ProjectCreationException ex = new ProjectCreationException();
- ex.errors = Lists.newArrayList(e.getMessage());
- throw ex;
- }
-
- }
-
- private void copyCustomFieldValues(Issue issue, MutableIssue newIssue){
-
- List<CustomField> newIssueCustomFields = customFieldManager.getCustomFieldObjects(newIssue);
- List<CustomField> issueCustomFields = customFieldManager.getCustomFieldObjects(issue);
-
- for (CustomField cf : issueCustomFields){
-
- if (newIssueCustomFields.contains(cf)){
-
- newIssue.setCustomFieldValue(cf, cf.getValue(issue));
- }
-
- }
-
-
-
- }
-
- private void copySystemFieldValues(Issue issue, MutableIssue newIssue, Issue parentIssue, String assignee){
-
- String[] systemFields = {"issueTypeId", "projectId", "summary", "assigneeId", "fixVersions", "affectedVersions",
- "reporterId", "environment", "description", "priorityId", "dueDate", "originalEstimate", "components",
- "securityLevel"
- };
-
- //Components
- List<ProjectComponent> newComponents = new ArrayList<ProjectComponent>();
- for (ProjectComponent component : issue.getComponentObjects()){
-
- ProjectComponent destComponent = projectComponentManager.findByComponentName(newIssue.getProjectObject().getId(), component.getName());
- newComponents.add(destComponent);
-
- }
- newIssue.setComponent(newComponents);
-
- //AffectedVersions
- List<Version> newVersions = new ArrayList<Version>();
- for (Version version : issue.getAffectedVersions()){
-
- Version newVersion = versionManager.getVersion(newIssue.getProjectObject().getId(), version.getName());
- newVersions.add(newVersion);
- }
- newIssue.setAffectedVersions(newVersions);
-
- //Fix Versions
- List<Version> newFixVersions = new ArrayList<Version>();
- for (Version fixVersion : issue.getFixVersions()){
-
- Version newFixVersion = versionManager.getVersion(newIssue.getProjectObject().getId(), fixVersion.getName());
- newFixVersions.add(newFixVersion);
- }
- newIssue.setFixVersions(newFixVersions);
-
- //Security Level
- Long securityLevelId = issue.getSecurityLevelId();
- if (securityLevelId != null){
- if (issueSecuritySchemeManager.getSchemeFor(issue.getProjectObject()) == issueSecuritySchemeManager.getSchemeFor(newIssue.getProjectObject())){
- newIssue.setSecurityLevelId(securityLevelId);
- }
- }
-
- //All the others
- newIssue.setIssueTypeId(issue.getIssueTypeObject().getId());
- newIssue.setIssueTypeObject(issue.getIssueTypeObject());
- newIssue.setSummary(issue.getSummary());
- newIssue.setReporterId(issue.getReporterId());
- newIssue.setEnvironment(issue.getEnvironment());
- newIssue.setDescription(issue.getDescription());
- newIssue.setPriorityId(issue.getPriorityObject().getId());
- newIssue.setDueDate(issue.getDueDate());
- newIssue.setOriginalEstimate(issue.getOriginalEstimate());
-
- //Define issue asignee
- if (assignee == null){
- newIssue.setAssigneeId(newIssue.getAssigneeId());
- }else{
- newIssue.setAssignee(jiraUserManager.getUser(assignee));
- }
-
- //Define as a subtask if parent object is defined
- //Set parent task if one was defined
- if (parentIssue != null) {
- newIssue.setParentObject(issue);
- }
- }
-
-
- private Long[] ConvertLongListToArray(List<Long> values) {
- Long[] result = new Long[values.size()];
- int i = 0;
- for (Long l : values)
- result[i++] = l;
- return result;
- }
-
-
- }