Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorddunne2011-05-11 18:08:50 +0000
committerRyan D. Brooks2011-05-11 18:08:50 +0000
commit54c315ffd1e76a961a168b14804a6d1e5b8b7ffb (patch)
tree41398d44c6acc8224b4764ebb52dbd7f409b18d0 /plugins/org.eclipse.osee.ats.core/src/org
parent9441dccf757f7d6bcceb41a698804b042cc531f6 (diff)
downloadorg.eclipse.osee-54c315ffd1e76a961a168b14804a6d1e5b8b7ffb.tar.gz
org.eclipse.osee-54c315ffd1e76a961a168b14804a6d1e5b8b7ffb.tar.xz
org.eclipse.osee-54c315ffd1e76a961a168b14804a6d1e5b8b7ffb.zip
feature: Create ats.core
Diffstat (limited to 'plugins/org.eclipse.osee.ats.core/src/org')
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/access/AtsBranchAccessContextId.java29
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/artifact/AbstractAtsArtifact.java30
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/AtsBranchManagerCore.java415
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/CommitStatus.java37
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/commit/ICommitConfigArtifact.java30
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/ActionableItemArtifact.java46
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsArtifactToken.java43
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsBulkLoad.java64
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsLoadConfigArtifactsOperation.java65
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionArtifact.java400
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManager.java111
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManagerCore.java40
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionOptions.java6
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/Activator.java33
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/AbstractReviewArtifact.java240
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionOption.java183
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewArtifact.java39
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewManager.java108
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewState.java25
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/IReviewArtifact.java31
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewArtifact.java43
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewManager.java120
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewState.java25
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewFormalType.java6
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewManager.java350
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/XDecisionOptions.java106
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectItem.java269
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectManager.java209
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/Role.java18
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRole.java184
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleError.java33
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleManager.java285
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleValidator.java62
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/AbstractTaskableArtifact.java251
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskArtifact.java252
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResOptionDefinition.java173
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResolutionOptionRule.java145
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskStates.java24
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/SimpleTeamState.java29
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamState.java37
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowArtifact.java238
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowManager.java218
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkflowProviders.java89
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/ATSAttributes.java76
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsArtifactTypes.java37
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsAttributeTypes.java137
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsRelationTypes.java102
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsCacheManager.java176
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsUtilCore.java111
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/WorkflowManagerCore.java103
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/TargetedVersionUtil.java78
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionArtifact.java163
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionLockedType.java7
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionReleaseType.java7
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AbstractWorkDefItem.java59
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/CompositeStateItem.java41
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ConvertAtsDslToWorkDefinition.java407
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewDefinition.java96
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewOption.java69
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/IWorkDefintionFactoryLegacyMgr.java27
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ModelUtil.java141
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/PeerReviewDefinition.java91
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ReviewBlockType.java7
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinition.java23
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinitionOption.java31
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleManager.java32
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateColor.java29
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateDefinition.java249
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateEventType.java21
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateItem.java14
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetDefinition.java89
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOption.java62
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOptionHandler.java108
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinition.java205
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactory.java256
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactoryLegacyMgr.java91
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionMatch.java54
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionSheet.java39
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/AtsWorkDefinitionProviderCore.java65
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/BooleanDefUtil.java22
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/UserRefUtil.java56
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AbstractWorkflowArtifact.java822
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifact.java45
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifactRollup.java148
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionManagerCore.java36
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionableItemManagerCore.java168
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeType.java45
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeTypeUtil.java37
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/EstimatedHoursUtil.java31
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/HoursSpentUtil.java185
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ITeamWorkflowProvider.java74
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteSMAStateUtil.java59
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteTotalUtil.java204
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PriorityUtil.java24
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/SMAState.java217
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/StateManager.java448
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XCurrentStateDam.java72
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateAssigneesDam.java118
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateDam.java24
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ArtifactLog.java79
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/AtsLog.java390
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ILogStorageProvider.java24
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogItem.java135
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogType.java36
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/ArtifactNote.java89
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/AtsNote.java140
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/INoteStorageProvider.java26
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteItem.java153
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteType.java43
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/ITransitionListener.java28
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionListeners.java81
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java495
-rw-r--r--plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionOption.java20
113 files changed, 13018 insertions, 0 deletions
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/access/AtsBranchAccessContextId.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/access/AtsBranchAccessContextId.java
new file mode 100644
index 00000000000..20e91108cd3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/access/AtsBranchAccessContextId.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.access;
+
+import org.eclipse.osee.framework.core.data.IAccessContextId;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class AtsBranchAccessContextId {
+
+ public static final IAccessContextId DEFAULT_BRANCH_CONTEXT = TokenFactory.createAccessContextId(
+ "AFRkIhi2m2cdanu3i2AA", "ats.branchobject.default.context");
+ public static final IAccessContextId DENY_CONTEXT = TokenFactory.createAccessContextId("ABcgU0QxFG_cQU4Ph1wA",
+ "ats.branchobject.deny");
+
+ private AtsBranchAccessContextId() {
+ // Branch Object Contexts;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/artifact/AbstractAtsArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/artifact/AbstractAtsArtifact.java
new file mode 100644
index 00000000000..270b23c4a1c
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/artifact/AbstractAtsArtifact.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.artifact;
+
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+
+public abstract class AbstractAtsArtifact extends Artifact {
+
+ public AbstractAtsArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ @SuppressWarnings("unused")
+ public Artifact getParentAtsArtifact() throws OseeCoreException {
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/AtsBranchManagerCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/AtsBranchManagerCore.java
new file mode 100644
index 00000000000..ea4090517f8
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/AtsBranchManagerCore.java
@@ -0,0 +1,415 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.branch;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.osee.ats.core.commit.ICommitConfigArtifact;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.version.VersionArtifact;
+import org.eclipse.osee.framework.core.enums.BranchState;
+import org.eclipse.osee.framework.core.enums.BranchType;
+import org.eclipse.osee.framework.core.exception.MultipleBranchesExist;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.model.TransactionRecord;
+import org.eclipse.osee.framework.core.model.cache.BranchFilter;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+import org.eclipse.osee.framework.skynet.core.conflict.ConflictManagerExternal;
+import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsBranchManagerCore {
+
+ private static Map<String, Branch> hridToWorkingBranchCache = new HashMap<String, Branch>();
+ private static Map<String, Long> hridToWorkingBranchCacheUpdated = new HashMap<String, Long>(50);
+ public static Set<Branch> branchesInCommit = new HashSet<Branch>();
+
+ /**
+ * Return working branch associated with SMA whether it is committed or not; This data is cached across all workflows
+ * with the cache being updated by local and remote events.
+ */
+ public static Branch getWorkingBranch(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ long now = new Date().getTime();
+ boolean notSet = hridToWorkingBranchCacheUpdated.get(teamArt.getHumanReadableId()) == null;
+ if (notSet || (now - hridToWorkingBranchCacheUpdated.get(teamArt.getHumanReadableId()) > 1000)) {
+ hridToWorkingBranchCache.put(teamArt.getHumanReadableId(),
+ getWorkingBranchExcludeStates(teamArt, BranchState.REBASELINED, BranchState.DELETED));
+ hridToWorkingBranchCacheUpdated.put(teamArt.getHumanReadableId(), now);
+ }
+ return hridToWorkingBranchCache.get(teamArt.getHumanReadableId());
+ }
+
+ /**
+ * Return working branch associated with SMA, even if it's been archived; This data is cached across all workflows
+ * with the cache being updated by local and remote events. Filters out rebaseline branches (which are working
+ * branches also).
+ */
+ public static Branch getWorkingBranchExcludeStates(TeamWorkFlowArtifact teamArt, BranchState... negatedBranchStates) throws OseeCoreException {
+ BranchFilter branchFilter = new BranchFilter(BranchType.WORKING, BranchType.BASELINE);
+ branchFilter.setNegatedBranchStates(negatedBranchStates);
+ branchFilter.setAssociatedArtifact(teamArt);
+
+ List<Branch> branches = BranchManager.getBranches(branchFilter);
+
+ if (branches.isEmpty()) {
+ return null;
+ } else if (branches.size() > 1) {
+ throw new MultipleBranchesExist(
+ "Unexpected multiple associated un-deleted working branches found for workflow [%s]",
+ teamArt.getHumanReadableId());
+ } else {
+ return branches.get(0);
+ }
+ }
+
+ /**
+ * @return whether there is a working branch that is not committed
+ */
+ public static boolean isWorkingBranchInWork(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Branch branch = getWorkingBranch(teamArt);
+ return branch != null && !branch.getBranchState().isCommitted();
+ }
+
+ /**
+ * Return true if merge branch exists in DB (whether archived or not)
+ */
+ public static boolean isMergeBranchExists(TeamWorkFlowArtifact teamArt, Branch destinationBranch) throws OseeCoreException {
+ return isMergeBranchExists(teamArt, getWorkingBranch(teamArt), destinationBranch);
+ }
+
+ /**
+ * Method available for optimized checking of merge branches so don't have to re-acquire working branch if already
+ * have
+ */
+ public static boolean isMergeBranchExists(TeamWorkFlowArtifact teamArt, Branch workingBranch, Branch destinationBranch) throws OseeCoreException {
+ if (workingBranch == null) {
+ return false;
+ }
+ return BranchManager.doesMergeBranchExist(workingBranch, destinationBranch);
+ }
+
+ public static boolean isMergeCompleted(TeamWorkFlowArtifact teamArt, Branch destinationBranch) throws OseeCoreException {
+ ConflictManagerExternal conflictManager =
+ new ConflictManagerExternal(destinationBranch, getWorkingBranch(teamArt));
+ return !conflictManager.remainingConflictsExist();
+ }
+
+ public static TransactionRecord getCommitTransactionRecord(TeamWorkFlowArtifact teamArt, ICommitConfigArtifact configArt) throws OseeCoreException {
+ Branch branch = configArt.getParentBranch();
+ if (branch == null) {
+ return null;
+ }
+
+ Collection<TransactionRecord> transactions = TransactionManager.getCommittedArtifactTransactionIds(teamArt);
+ for (TransactionRecord transId : transactions) {
+ if (transId.getBranchId() == branch.getId()) {
+ return transId;
+ }
+ }
+ return null;
+ }
+
+ public static CommitStatus getCommitStatus(TeamWorkFlowArtifact teamArt, ICommitConfigArtifact configArt) throws OseeCoreException {
+ Branch desinationBranch = configArt.getParentBranch();
+ if (desinationBranch == null) {
+ return CommitStatus.Branch_Not_Configured;
+ }
+
+ Collection<TransactionRecord> transactions = TransactionManager.getCommittedArtifactTransactionIds(teamArt);
+ boolean mergeBranchExists = AtsBranchManagerCore.isMergeBranchExists(teamArt, desinationBranch);
+
+ for (TransactionRecord transId : transactions) {
+ if (desinationBranch.equals(transId.getBranch())) {
+ if (mergeBranchExists) {
+ return CommitStatus.Committed_With_Merge;
+ } else {
+ return CommitStatus.Committed;
+ }
+ }
+ }
+
+ Result result = AtsBranchManagerCore.isCommitBranchAllowed(teamArt, configArt);
+ if (result.isFalse()) {
+ return CommitStatus.Branch_Commit_Disabled;
+ }
+ if (AtsBranchManagerCore.getWorkingBranch(teamArt) == null) {
+ return CommitStatus.Working_Branch_Not_Created;
+ }
+ if (mergeBranchExists) {
+ return CommitStatus.Merge_In_Progress;
+ }
+ return CommitStatus.Commit_Needed;
+ }
+
+ public static Result isCommitBranchAllowed(TeamWorkFlowArtifact teamArt, ICommitConfigArtifact configArt) throws OseeCoreException {
+ if (!teamArt.isTeamWorkflow()) {
+ return Result.FalseResult;
+ }
+ if (teamArt.getTeamDefinition().isTeamUsesVersions()) {
+ if (teamArt.getTargetedVersion() == null) {
+ return new Result(false, "Workflow not targeted for Version");
+ }
+ Result result = teamArt.getTargetedVersion().isCommitBranchAllowed();
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (teamArt.getTargetedVersion().getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Version [" + teamArt.getTargetedVersion() + "]");
+ }
+ return Result.TrueResult;
+
+ } else {
+ Result result = teamArt.getTeamDefinition().isCommitBranchAllowed();
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (teamArt.getTeamDefinition().getParentBranch() == null) {
+ return new Result(false,
+ "Parent Branch not configured for Team Definition [" + teamArt.getTeamDefinition() + "]");
+ }
+ return Result.TrueResult;
+ }
+ }
+
+ public static Result isCreateBranchAllowed(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ if (!teamArt.isTeamWorkflow()) {
+ return Result.FalseResult;
+ }
+
+ if (teamArt.getTeamDefinition().isTeamUsesVersions()) {
+ if (teamArt.getTargetedVersion() == null) {
+ return new Result(false, "Workflow not targeted for Version");
+ }
+ Result result = teamArt.getTargetedVersion().isCreateBranchAllowed();
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (teamArt.getTargetedVersion().getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Version [" + teamArt.getTargetedVersion() + "]");
+ }
+ if (!teamArt.getTargetedVersion().getParentBranch().getBranchType().isBaselineBranch()) {
+ return new Result(false, "Parent Branch must be of Baseline branch type. See Admin for configuration.");
+ }
+ return Result.TrueResult;
+
+ } else {
+ Result result = teamArt.getTeamDefinition().isCreateBranchAllowed();
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (teamArt.getTeamDefinition().getParentBranch() == null) {
+ return new Result(false,
+ "Parent Branch not configured for Team Definition [" + teamArt.getTeamDefinition() + "]");
+ }
+ if (!teamArt.getTeamDefinition().getParentBranch().getBranchType().isBaselineBranch()) {
+ return new Result(false, "Parent Branch must be of Baseline branch type. See Admin for configuration.");
+ }
+ return Result.TrueResult;
+ }
+ }
+
+ /**
+ * Returns true if there was ever a commit of a working branch regardless of whether the working branch is archived
+ * or not.
+ */
+ public static boolean isWorkingBranchEverCommitted(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ return getBranchesCommittedTo(teamArt).size() > 0;
+ }
+
+ public static Collection<ICommitConfigArtifact> getConfigArtifactsConfiguredToCommitTo(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Set<ICommitConfigArtifact> configObjects = new HashSet<ICommitConfigArtifact>();
+ if (teamArt.isTeamUsesVersions()) {
+ if (teamArt.getTargetedVersion() != null) {
+ teamArt.getTargetedVersion().getParallelVersions(configObjects);
+ }
+ } else {
+ if (teamArt.isTeamWorkflow() && teamArt.getTeamDefinition().getParentBranch() != null) {
+ configObjects.add(teamArt.getTeamDefinition());
+ }
+ }
+ return configObjects;
+ }
+
+ public static ICommitConfigArtifact getParentBranchConfigArtifactConfiguredToCommitTo(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ if (teamArt.isTeamUsesVersions()) {
+ if (teamArt.getTargetedVersion() != null) {
+ return teamArt.getTargetedVersion();
+ }
+ } else {
+ if (teamArt.isTeamWorkflow() && teamArt.getTeamDefinition().getParentBranch() != null) {
+ return teamArt.getTeamDefinition();
+ }
+ }
+ return null;
+ }
+
+ public static boolean isAllObjectsToCommitToConfigured(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ return getConfigArtifactsConfiguredToCommitTo(teamArt).size() == getBranchesToCommitTo(teamArt).size();
+ }
+
+ public static Collection<Branch> getBranchesLeftToCommit(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Set<Branch> branchesLeft = new HashSet<Branch>();
+ Collection<Branch> committedTo = getBranchesCommittedTo(teamArt);
+ for (Branch branchToCommit : getBranchesToCommitTo(teamArt)) {
+ if (!committedTo.contains(branchToCommit)) {
+ branchesLeft.add(branchToCommit);
+ }
+ }
+ return branchesLeft;
+ }
+
+ public static Collection<Branch> getBranchesToCommitTo(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Set<Branch> branches = new HashSet<Branch>();
+ for (Object obj : getConfigArtifactsConfiguredToCommitTo(teamArt)) {
+ if (obj instanceof VersionArtifact && ((VersionArtifact) obj).getParentBranch() != null) {
+ branches.add(((VersionArtifact) obj).getParentBranch());
+ } else if (obj instanceof TeamDefinitionArtifact && ((TeamDefinitionArtifact) obj).getParentBranch() != null) {
+ branches.add(((TeamDefinitionArtifact) obj).getParentBranch());
+ }
+ }
+ return branches;
+ }
+
+ public static Collection<Branch> getBranchesCommittedTo(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Set<Branch> branches = new HashSet<Branch>();
+ for (TransactionRecord transId : getTransactionIds(teamArt, false)) {
+ branches.add(transId.getBranch());
+ }
+ return branches;
+ }
+
+ /**
+ * @return true if there is at least one destination branch committed to
+ */
+ public static boolean isCommittedBranchExists(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ return isAllObjectsToCommitToConfigured(teamArt) && !getBranchesCommittedTo(teamArt).isEmpty();
+ }
+
+ /**
+ * Return true if all commit destination branches are configured and have been committed to
+ */
+ public static boolean isBranchesAllCommitted(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Collection<Branch> committedTo = getBranchesCommittedTo(teamArt);
+ for (Branch destBranch : getBranchesToCommitTo(teamArt)) {
+ if (!committedTo.contains(destBranch)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isBranchesAllCommittedExcept(TeamWorkFlowArtifact teamArt, Branch branchToExclude) throws OseeCoreException {
+ Collection<Branch> committedTo = getBranchesCommittedTo(teamArt);
+ for (Branch destBranch : getBranchesToCommitTo(teamArt)) {
+ if (!destBranch.equals(branchToExclude) && !committedTo.contains(destBranch)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return Branch that is the configured branch to create working branch from.
+ */
+ public static Branch getConfiguredBranchForWorkflow(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Branch parentBranch = null;
+
+ // Check for parent branch id in Version artifact
+ if (teamArt.isTeamUsesVersions()) {
+ VersionArtifact verArt = teamArt.getTargetedVersion();
+ if (verArt != null) {
+ parentBranch = verArt.getParentBranch();
+ }
+ }
+
+ // If not defined in version, check for parent branch from team definition
+ if (parentBranch == null && teamArt.isTeamWorkflow()) {
+ parentBranch = teamArt.getTeamDefinition().getParentBranch();
+ }
+
+ // If not defined, return null
+ return parentBranch;
+ }
+
+ public static boolean isBranchInCommit(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ if (!isWorkingBranchInWork(teamArt)) {
+ return false;
+ }
+ return branchesInCommit.contains(getWorkingBranch(teamArt));
+ }
+
+ public static Integer getId(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Branch branch = getWorkingBranch(teamArt);
+ if (branch == null) {
+ return null;
+ }
+ return branch.getId();
+ }
+
+ private static Collection<TransactionRecord> getCommitTransactionsToUnarchivedBaslineBranchs(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Collection<TransactionRecord> committedTransactions =
+ TransactionManager.getCommittedArtifactTransactionIds(teamArt);
+
+ Collection<TransactionRecord> transactionIds = new ArrayList<TransactionRecord>();
+ for (TransactionRecord transactionId : committedTransactions) {
+ // exclude working branches including branch states that are re-baselined
+ Branch branch = transactionId.getBranch();
+ if (branch.getBranchType().isBaselineBranch() && branch.getArchiveState().isUnArchived()) {
+ transactionIds.add(transactionId);
+ }
+ }
+ return transactionIds;
+ }
+
+ /**
+ * @return TransactionId associated with this state machine artifact
+ */
+ public static Collection<TransactionRecord> getTransactionIds(TeamWorkFlowArtifact teamArt, boolean forMergeBranches) throws OseeCoreException {
+ if (forMergeBranches) {
+ Branch workingBranch = getWorkingBranch(teamArt);
+ // grab only the transaction that had merge conflicts
+ Collection<TransactionRecord> transactionIds = new ArrayList<TransactionRecord>();
+ for (TransactionRecord transactionId : getCommitTransactionsToUnarchivedBaslineBranchs(teamArt)) {
+ if (isMergeBranchExists(teamArt, workingBranch, transactionId.getBranch())) {
+ transactionIds.add(transactionId);
+ }
+ }
+ return transactionIds;
+ } else {
+ return getCommitTransactionsToUnarchivedBaslineBranchs(teamArt);
+ }
+ }
+
+ public static TransactionRecord getEarliestTransactionId(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Collection<TransactionRecord> transactionIds = getTransactionIds(teamArt, false);
+ if (transactionIds.size() == 1) {
+ return transactionIds.iterator().next();
+ }
+ TransactionRecord earliestTransactionId = transactionIds.iterator().next();
+ for (TransactionRecord transactionId : transactionIds) {
+ if (transactionId.getId() < earliestTransactionId.getId()) {
+ earliestTransactionId = transactionId;
+ }
+ }
+ return earliestTransactionId;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/CommitStatus.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/CommitStatus.java
new file mode 100644
index 00000000000..119140b0e2b
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/branch/CommitStatus.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.branch;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum CommitStatus {
+ Working_Branch_Not_Created("Working Branch Not Created"),
+ Branch_Not_Configured("Branch Not Configured"),
+ Branch_Commit_Disabled("Branch Commit Disabled"),
+ Commit_Needed("Start Commit"),
+ Merge_In_Progress("Merge in Progress"),
+ Committed("Committed"),
+ Committed_With_Merge("Committed With Merge");
+
+ private final String displayName;
+
+ private CommitStatus(String displayName) {
+ this.displayName = displayName;
+ }
+
+ /**
+ * @return the displayName
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/commit/ICommitConfigArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/commit/ICommitConfigArtifact.java
new file mode 100644
index 00000000000..cee30940a46
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/commit/ICommitConfigArtifact.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.commit;
+
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.util.Result;
+
+/**
+ * @author Donald G. Dunne
+ */
+public interface ICommitConfigArtifact {
+
+ public Branch getParentBranch() throws OseeCoreException;
+
+ public Result isCommitBranchAllowed() throws OseeCoreException;
+
+ public Result isCreateBranchAllowed() throws OseeCoreException;
+
+ public String getFullDisplayName() throws OseeCoreException;
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/ActionableItemArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/ActionableItemArtifact.java
new file mode 100644
index 00000000000..9da88170f9a
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/ActionableItemArtifact.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.config;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ActionableItemArtifact extends Artifact {
+
+ public ActionableItemArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ public Collection<User> getLeads() throws OseeCoreException {
+ return getRelatedArtifacts(AtsRelationTypes.TeamLead_Lead, User.class);
+ }
+
+ public boolean isActionable() throws OseeCoreException {
+ return getSoleAttributeValue(AtsAttributeTypes.Actionable, false);
+ }
+
+ public Collection<TeamDefinitionArtifact> getImpactedTeamDefs() throws OseeCoreException {
+ return TeamDefinitionManagerCore.getImpactedTeamDefs(Arrays.asList(this));
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsArtifactToken.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsArtifactToken.java
new file mode 100644
index 00000000000..6e392d8cc19
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsArtifactToken.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.config;
+
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.framework.core.data.IArtifactToken;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+import org.eclipse.osee.framework.core.enums.CoreArtifactTypes;
+
+public final class AtsArtifactToken {
+
+ public static IArtifactToken HeadingFolder = TokenFactory.createArtifactToken("AAABER+3yR4A8O7WYQ+Xbw",
+ "Action Tracking System", CoreArtifactTypes.Folder);
+ public static IArtifactToken TopTeamDefinition = TokenFactory.createArtifactToken("AAABER+35b4A8O7WHrXTiA", "Teams",
+ AtsArtifactTypes.TeamDefinition);
+ public static IArtifactToken TopActionableItem = TokenFactory.createArtifactToken("AAABER+37QEA8O7WSQaqJQ",
+ "Actionable Items", AtsArtifactTypes.ActionableItem);
+ public static IArtifactToken ConfigFolder = TokenFactory.createArtifactToken("AAABF4n18eYAc1ruQSSWdg", "Config",
+ CoreArtifactTypes.Folder);
+ public static IArtifactToken WorkDefinitionsFolder = TokenFactory.createArtifactToken("ADTfjCLEj2DH2WYyeOgA",
+ "Work Definitions", CoreArtifactTypes.Folder);
+ public static IArtifactToken WorkPagesFolder = TokenFactory.createArtifactToken("AAABGnncY_gAAo+3N69ASA",
+ "Work Pages", CoreArtifactTypes.Folder);
+ public static IArtifactToken WorkRulesFolder = TokenFactory.createArtifactToken("AAABGnmhCyYAoJoIciyaag",
+ "Work Rules", CoreArtifactTypes.Folder);
+ public static IArtifactToken WorkWidgetsFolder = TokenFactory.createArtifactToken("AAABGnmjk4IAoJoIa945Kg",
+ "Work Widgets", CoreArtifactTypes.Folder);
+ public static IArtifactToken WorkFlowsFolder = TokenFactory.createArtifactToken("AAABGnncZ_4AAo+3D0sGfw",
+ "Work Flows", CoreArtifactTypes.Folder);
+
+ private AtsArtifactToken() {
+ // Constants
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsBulkLoad.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsBulkLoad.java
new file mode 100644
index 00000000000..9e392fbe78c
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsBulkLoad.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.config;
+
+import java.util.Collection;
+import java.util.Set;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.operation.EmptyOperation;
+import org.eclipse.osee.framework.core.operation.IOperation;
+import org.eclipse.osee.framework.core.operation.Operations;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.relation.RelationManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsBulkLoad {
+
+ private static boolean atsTypeDataLoadedStarted = false;
+
+ public synchronized static IOperation getConfigLoadingOperation() {
+ if (atsTypeDataLoadedStarted == false) {
+ atsTypeDataLoadedStarted = true;
+ return new AtsLoadConfigArtifactsOperation();
+ }
+ return new EmptyOperation("ATS Bulk Loading", Activator.PLUGIN_ID);
+ }
+
+ public static void reloadConfig(boolean pend) {
+ if (pend) {
+ Operations.executeWork(new AtsLoadConfigArtifactsOperation());
+ } else {
+ Operations.executeAsJob(new AtsLoadConfigArtifactsOperation(), false);
+ }
+ }
+
+ public static void loadConfig(boolean pend) {
+ if (AtsLoadConfigArtifactsOperation.isLoaded()) {
+ return;
+ }
+ reloadConfig(pend);
+ }
+
+ public static Set<Artifact> loadFromActions(Collection<? extends Artifact> actions) throws OseeCoreException {
+ return RelationManager.getRelatedArtifacts(actions, 4, AtsRelationTypes.SmaToTask_Task,
+ AtsRelationTypes.ActionToWorkflow_WorkFlow, AtsRelationTypes.TeamWorkflowToReview_Review);
+ }
+
+ public static Set<Artifact> loadFromTeamWorkflows(Collection<? extends Artifact> teams) throws OseeCoreException {
+ return RelationManager.getRelatedArtifacts(teams, 3, AtsRelationTypes.SmaToTask_Task,
+ AtsRelationTypes.TeamWorkflowToReview_Team, AtsRelationTypes.ActionToWorkflow_Action);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsLoadConfigArtifactsOperation.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsLoadConfigArtifactsOperation.java
new file mode 100644
index 00000000000..6d78deff33b
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/AtsLoadConfigArtifactsOperation.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.config;
+
+import java.util.Collections;
+import java.util.logging.Level;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.operation.AbstractOperation;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.relation.RelationManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsLoadConfigArtifactsOperation extends AbstractOperation {
+ private static boolean loaded = false;
+
+ public AtsLoadConfigArtifactsOperation() {
+ super("ATS Loading Configuration", Activator.PLUGIN_ID);
+ }
+
+ public void forceReload() throws OseeCoreException {
+ loaded = false;
+ ensureLoaded();
+ }
+
+ public synchronized void ensureLoaded() throws OseeCoreException {
+ if (!loaded) {
+ loaded = true;
+ OseeLog.log(Activator.class, Level.INFO, "Loading ATS Configuration");
+ Artifact headingArt = AtsUtilCore.getFromToken(AtsArtifactToken.HeadingFolder);
+ // Loading artifacts will cache them in ArtifactCache
+ RelationManager.getRelatedArtifacts(Collections.singleton(headingArt), 8,
+ CoreRelationTypes.Default_Hierarchical__Child, AtsRelationTypes.TeamDefinitionToVersion_Version);
+ // Load Work Definitions
+ // TODO not doing anymore
+ // WorkItemDefinitionFactory.loadDefinitions();
+ loaded = true;
+ }
+ }
+
+ @Override
+ protected void doWork(IProgressMonitor monitor) throws Exception {
+ ensureLoaded();
+ }
+
+ public static boolean isLoaded() {
+ return loaded;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionArtifact.java
new file mode 100644
index 00000000000..fae43912a82
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionArtifact.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.commit.ICommitConfigArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.version.VersionArtifact;
+import org.eclipse.osee.ats.core.version.VersionLockedType;
+import org.eclipse.osee.ats.core.version.VersionReleaseType;
+import org.eclipse.osee.ats.core.workdef.RuleDefinition;
+import org.eclipse.osee.ats.core.workdef.RuleDefinitionOption;
+import org.eclipse.osee.ats.core.workdef.RuleManager;
+import org.eclipse.osee.ats.core.workdef.WorkDefinitionFactory;
+import org.eclipse.osee.ats.core.workdef.WorkDefinitionMatch;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.enums.CoreArtifactTypes;
+import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
+import org.eclipse.osee.framework.core.exception.BranchDoesNotExist;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactTypeManager;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TeamDefinitionArtifact extends Artifact implements ICommitConfigArtifact {
+
+ public TeamDefinitionArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ @Override
+ public Result isCreateBranchAllowed() throws OseeCoreException {
+ if (!getSoleAttributeValue(AtsAttributeTypes.AllowCreateBranch, false)) {
+ return new Result(false, "Branch creation disabled for Team Definition [" + this + "]");
+ }
+ if (getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Team Definition [" + this + "]");
+ }
+ return Result.TrueResult;
+ }
+
+ @Override
+ public Result isCommitBranchAllowed() throws OseeCoreException {
+ if (!getSoleAttributeValue(AtsAttributeTypes.AllowCommitBranch, false)) {
+ return new Result(false, "Team Definition [" + this + "] not configured to allow branch commit.");
+ }
+ if (getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Team Definition [" + this + "]");
+ }
+ return Result.TrueResult;
+ }
+
+ public void initialize(String fullname, String description, Collection<User> leads, Collection<User> members, Collection<ActionableItemArtifact> actionableItems, TeamDefinitionOptions... teamDefinitionOptions) throws OseeCoreException {
+ List<Object> teamDefOptions = Collections.getAggregate((Object[]) teamDefinitionOptions);
+
+ setSoleAttributeValue(AtsAttributeTypes.Description, description);
+ setSoleAttributeValue(AtsAttributeTypes.FullName, fullname);
+ for (User user : leads) {
+ addRelation(AtsRelationTypes.TeamLead_Lead, user);
+ // All leads are members
+ addRelation(AtsRelationTypes.TeamMember_Member, user);
+ }
+ for (User user : members) {
+ addRelation(AtsRelationTypes.TeamMember_Member, user);
+ }
+
+ if (teamDefOptions.contains(TeamDefinitionOptions.TeamUsesVersions)) {
+ setSoleAttributeValue(AtsAttributeTypes.TeamUsesVersions, true);
+ }
+ if (teamDefOptions.contains(TeamDefinitionOptions.RequireTargetedVersion)) {
+ addRule(RuleDefinitionOption.RequireTargetedVersion);
+ }
+
+ // Relate to actionable items
+ for (ActionableItemArtifact aia : actionableItems) {
+ addRelation(AtsRelationTypes.TeamActionableItem_ActionableItem, aia);
+ }
+ }
+
+ @Override
+ public Branch getParentBranch() throws OseeCoreException {
+ try {
+ String guid = getSoleAttributeValue(AtsAttributeTypes.BaselineBranchGuid, "");
+ if (GUID.isValid(guid)) {
+ return BranchManager.getBranchByGuid(guid);
+ }
+ } catch (BranchDoesNotExist ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return null;
+ }
+
+ /**
+ * This method will walk up the TeamDefinition tree until a def is found that configured with versions. This allows
+ * multiple TeamDefinitions to be versioned/released together by having the parent hold the versions. It is not
+ * required that a product configured in ATS uses the versions option. If no parent with versions is found, null is
+ * returned. If boolean "Team Uses Versions" is false, just return cause this team doesn't use versions
+ *
+ * @return parent TeamDefinition that holds the version definitions
+ */
+ public TeamDefinitionArtifact getTeamDefinitionHoldingVersions() throws OseeCoreException {
+ if (!isTeamUsesVersions()) {
+ return null;
+ }
+ if (getVersionsArtifacts().size() > 0) {
+ return this;
+ }
+ if (getParent() instanceof TeamDefinitionArtifact) {
+ TeamDefinitionArtifact parentTda = (TeamDefinitionArtifact) getParent();
+ if (parentTda != null) {
+ return parentTda.getTeamDefinitionHoldingVersions();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This method will walk up the TeamDefinition tree until a def is found that configured with work flow.
+ *
+ * @return parent TeamDefinition that holds the work flow id attribute
+ */
+ public TeamDefinitionArtifact getTeamDefinitionHoldingWorkFlow() throws OseeCoreException {
+ for (Artifact artifact : getRelatedArtifacts(CoreRelationTypes.WorkItem__Child, Artifact.class)) {
+ if (artifact.isOfType(CoreArtifactTypes.WorkFlowDefinition)) {
+ return this;
+ }
+ }
+ if (getParent() instanceof TeamDefinitionArtifact) {
+ TeamDefinitionArtifact parentTda = (TeamDefinitionArtifact) getParent();
+ if (parentTda != null) {
+ return parentTda.getTeamDefinitionHoldingWorkFlow();
+ }
+ }
+ return null;
+ }
+
+ public Artifact getNextReleaseVersion() throws OseeCoreException {
+ for (Artifact verArt : getRelatedArtifacts(AtsRelationTypes.TeamDefinitionToVersion_Version)) {
+ if (verArt.getSoleAttributeValue(AtsAttributeTypes.NextVersion, false)) {
+ return verArt;
+ }
+ }
+ return null;
+ }
+
+ public Collection<VersionArtifact> getVersionsFromTeamDefHoldingVersions(VersionReleaseType releaseType, VersionLockedType lockedType) throws OseeCoreException {
+ TeamDefinitionArtifact teamDef = getTeamDefinitionHoldingVersions();
+ if (teamDef == null) {
+ return new ArrayList<VersionArtifact>();
+ }
+ return teamDef.getVersionsArtifacts(releaseType, lockedType);
+ }
+
+ public double getManDayHrsFromItemAndChildren() {
+ return getHoursPerWorkDayFromItemAndChildren(this);
+ }
+
+ public Artifact getWorkflowArtifact(Artifact teamDef) throws OseeCoreException {
+ Artifact workFlowArt = null;
+ for (Artifact artifact : teamDef.getRelatedArtifacts(CoreRelationTypes.WorkItem__Child, Artifact.class)) {
+ if (artifact.isOfType(CoreArtifactTypes.WorkFlowDefinition)) {
+ if (workFlowArt != null) {
+ OseeLog.log(
+ Activator.class,
+ Level.SEVERE,
+ "Multiple workflows found where only one expected for Team Definition " + getHumanReadableId() + " - " + getName());
+ }
+ workFlowArt = artifact;
+ }
+ }
+ return workFlowArt;
+ }
+
+ public WorkDefinitionMatch getWorkDefinition() throws OseeCoreException {
+ Artifact teamDef = getTeamDefinitionHoldingWorkFlow();
+ if (teamDef == null) {
+ return null;
+ }
+ Artifact workFlowArt = getWorkflowArtifact(teamDef);
+ if (workFlowArt == null) {
+ return null;
+ }
+ WorkDefinitionMatch match = WorkDefinitionFactory.getWorkDefinition(workFlowArt.getName());
+ if (match.isMatched()) {
+ match.addTrace(String.format("from teamDef [%s] related work child [%s]", teamDef, workFlowArt.getName()));
+ }
+ return match;
+ }
+
+ /**
+ * If hours per work day attribute is set, use it, otherwise, walk up the Team Definition tree. Value used in
+ * calculations.
+ */
+ public double getHoursPerWorkDayFromItemAndChildren(TeamDefinitionArtifact teamDef) {
+ try {
+ Double manDaysHrs = teamDef.getSoleAttributeValue(AtsAttributeTypes.HoursPerWorkDay, 0.0);
+ if (manDaysHrs != null && manDaysHrs != 0) {
+ return manDaysHrs;
+ }
+ if (teamDef.getParent() instanceof TeamDefinitionArtifact) {
+ return teamDef.getHoursPerWorkDayFromItemAndChildren((TeamDefinitionArtifact) teamDef.getParent());
+ }
+ return AtsUtilCore.DEFAULT_HOURS_PER_WORK_DAY;
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return 0.0;
+ }
+
+ /**
+ * Return ONLY leads configured for this TeamDefinitionArtifact. Depending on the use, like creating new actions, the
+ * assignees (or Leads) are determined first from users configured as leads of individual actionable items and only
+ * if that returns no leads, THEN default to using the leads configured for the TeamDefinition. In these cases, use
+ * getLeads(Collection<ActionableItemArtifact>) instead.
+ *
+ * @return users configured as leads for this TeamDefinitionArtifact
+ */
+ public Collection<User> getLeads() throws OseeCoreException {
+ return getRelatedArtifacts(AtsRelationTypes.TeamLead_Lead, User.class);
+ }
+
+ public Collection<User> getPrivilegedMembers() throws OseeCoreException {
+ return getRelatedArtifacts(AtsRelationTypes.PrivilegedMember_Member, User.class);
+ }
+
+ /**
+ * Returns leads configured first by ActionableItems and only if this is an empty set, THEN defaults to those
+ * configured by TeamDefinitions. Use getLeads() to only get the leads configured for this TeamDefinitionArtifact.
+ *
+ * @return users configured as leads by ActionableItems, then by TeamDefinition
+ */
+ public Collection<User> getLeads(Collection<ActionableItemArtifact> actionableItems) throws OseeCoreException {
+ Set<User> leads = new HashSet<User>();
+ for (ActionableItemArtifact aia : actionableItems) {
+ if (aia.getImpactedTeamDefs().contains(this)) {
+ // If leads are specified for this aia, add them
+ if (aia.getLeads().size() > 0) {
+ leads.addAll(aia.getLeads());
+ } else {
+ for (TeamDefinitionArtifact teamDef : aia.getImpactedTeamDefs()) {
+ leads.addAll(teamDef.getLeads());
+ }
+ }
+ }
+ }
+ if (leads.isEmpty()) {
+ leads.addAll(getLeads());
+ }
+ return leads;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<User> getMembersAndLeads() throws OseeCoreException {
+ return Collections.setUnion(getMembers(), getLeads());
+ }
+
+ public Collection<User> getMembers() throws OseeCoreException {
+ return getRelatedArtifacts(AtsRelationTypes.TeamMember_Member, User.class);
+ }
+
+ public Artifact getVersionArtifact(String name, boolean create) throws OseeCoreException {
+ for (Artifact verArt : getVersionsArtifacts()) {
+ if (verArt.getName().equals(name)) {
+ return verArt;
+ }
+ }
+ if (create) {
+ return createVersion(name);
+ }
+ return null;
+ }
+
+ public VersionArtifact createVersion(String name) throws OseeCoreException {
+ VersionArtifact versionArt =
+ (VersionArtifact) ArtifactTypeManager.addArtifact(AtsArtifactTypes.Version, AtsUtilCore.getAtsBranch(), name);
+ addRelation(AtsRelationTypes.TeamDefinitionToVersion_Version, versionArt);
+ return versionArt;
+ }
+
+ public Collection<VersionArtifact> getVersionsArtifacts() throws OseeCoreException {
+ return getRelatedArtifacts(AtsRelationTypes.TeamDefinitionToVersion_Version, VersionArtifact.class);
+ }
+
+ public Collection<VersionArtifact> getVersionsArtifacts(VersionReleaseType releaseType, VersionLockedType lockType) throws OseeCoreException {
+ return Collections.setIntersection(getVersionsArtifacts(releaseType), getVersionsArtifacts(lockType));
+ }
+
+ private Collection<VersionArtifact> getVersionsArtifacts(VersionReleaseType releaseType) throws OseeCoreException {
+ ArrayList<VersionArtifact> versions = new ArrayList<VersionArtifact>();
+ for (VersionArtifact version : getVersionsArtifacts()) {
+ if (version.isReleased() && (releaseType == VersionReleaseType.Released || releaseType == VersionReleaseType.Both)) {
+ versions.add(version);
+ } else if ((!version.isReleased() && releaseType == VersionReleaseType.UnReleased) || releaseType == VersionReleaseType.Both) {
+ versions.add(version);
+ }
+ }
+ return versions;
+ }
+
+ private Collection<VersionArtifact> getVersionsArtifacts(VersionLockedType lockType) throws OseeCoreException {
+ ArrayList<VersionArtifact> versions = new ArrayList<VersionArtifact>();
+ for (VersionArtifact version : getVersionsArtifacts()) {
+ if (version.isVersionLocked() && (lockType == VersionLockedType.Locked || lockType == VersionLockedType.Both)) {
+ versions.add(version);
+ } else if ((!version.isVersionLocked() && lockType == VersionLockedType.UnLocked) || lockType == VersionLockedType.Both) {
+ versions.add(version);
+ }
+ }
+ return versions;
+ }
+
+ public boolean isTeamUsesVersions() throws OseeCoreException {
+ return getSoleAttributeValue(AtsAttributeTypes.TeamUsesVersions, false);
+ }
+
+ public boolean isActionable() throws OseeCoreException {
+ return getSoleAttributeValue(AtsAttributeTypes.Actionable, false);
+ }
+
+ public List<RuleDefinition> getWorkRules() throws OseeCoreException {
+ List<RuleDefinition> rules = new ArrayList<RuleDefinition>();
+ for (String ruleId : getAttributesToStringList(AtsAttributeTypes.RuleDefinition)) {
+ RuleDefinition ruleDef = RuleManager.getOrCreateRule(ruleId);
+ rules.add(ruleDef);
+ }
+ return rules;
+ }
+
+ public void addRule(RuleDefinitionOption option) throws OseeCoreException {
+ addRule(option.name());
+ }
+
+ public void addRule(String ruleId) throws OseeCoreException {
+ if (!hasRule(ruleId)) {
+ addAttribute(AtsAttributeTypes.RuleDefinition, ruleId);
+ }
+ }
+
+ public boolean hasRule(RuleDefinitionOption option) throws OseeCoreException {
+ return hasRule(option.name());
+ }
+
+ public boolean hasRule(String ruleId) throws OseeCoreException {
+ return getAttributesToStringList(AtsAttributeTypes.RuleDefinition).contains(ruleId);
+ }
+
+ /**
+ * Returns the branch associated with this team. If this team does not have a branch associated then the parent team
+ * will be asked, this results in a recursive look at parent teams until a parent artifact has a related branch or
+ * the parent of a team is not a team. <br/>
+ * <br/>
+ * If no branch is associated then null will be returned.
+ */
+ public Branch getTeamBranch() throws OseeCoreException {
+ String guid = getSoleAttributeValue(AtsAttributeTypes.BaselineBranchGuid, null);
+ if (GUID.isValid(guid)) {
+ return BranchManager.getBranchByGuid(guid);
+ } else {
+ Artifact parent = getParent();
+ if (parent instanceof TeamDefinitionArtifact) {
+ return ((TeamDefinitionArtifact) parent).getTeamBranch();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getFullDisplayName() {
+ return getName();
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManager.java
new file mode 100644
index 00000000000..65965cc1b5b
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManager.java
@@ -0,0 +1,111 @@
+/*
+ * Created on Mar 24, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.config;
+
+import static org.eclipse.osee.framework.core.enums.DeletionFlag.EXCLUDE_DELETED;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsCacheManager;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.enums.Active;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+
+public class TeamDefinitionManager {
+ public static List<TeamDefinitionArtifact> getTopLevelTeamDefinitions(Active active) throws OseeCoreException {
+ TeamDefinitionArtifact topTeamDef = getTopTeamDefinition();
+ if (topTeamDef == null) {
+ return java.util.Collections.emptyList();
+ }
+ return Collections.castAll(AtsUtilCore.getActive(
+ Artifacts.getChildrenOfTypeSet(topTeamDef, TeamDefinitionArtifact.class, false), active,
+ TeamDefinitionArtifact.class));
+ }
+
+ public static List<TeamDefinitionArtifact> getTeamDefinitions(Active active) throws OseeCoreException {
+ return Collections.castAll(AtsCacheManager.getArtifactsByActive(AtsArtifactTypes.TeamDefinition, active));
+ }
+
+ public static List<TeamDefinitionArtifact> getTeamTopLevelDefinitions(Active active) throws OseeCoreException {
+ TeamDefinitionArtifact topTeamDef = getTopTeamDefinition();
+ if (topTeamDef == null) {
+ return java.util.Collections.emptyList();
+ }
+ return Collections.castAll(AtsUtilCore.getActive(
+ Artifacts.getChildrenOfTypeSet(topTeamDef, TeamDefinitionArtifact.class, false), active,
+ TeamDefinitionArtifact.class));
+ }
+
+ public static TeamDefinitionArtifact getTopTeamDefinition() {
+ return (TeamDefinitionArtifact) AtsUtilCore.getFromToken(AtsArtifactToken.TopTeamDefinition);
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamReleaseableDefinitions(Active active) throws OseeCoreException {
+ Set<TeamDefinitionArtifact> teamDefs = new HashSet<TeamDefinitionArtifact>();
+ for (TeamDefinitionArtifact teamDef : getTeamDefinitions(active)) {
+ if (teamDef.getVersionsArtifacts().size() > 0) {
+ teamDefs.add(teamDef);
+ }
+ }
+ return teamDefs;
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamsFromItemAndChildren(ActionableItemArtifact aia) throws OseeCoreException {
+ Set<TeamDefinitionArtifact> aiaTeams = new HashSet<TeamDefinitionArtifact>();
+ getTeamFromItemAndChildren(aia, aiaTeams);
+ return aiaTeams;
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamsFromItemAndChildren(TeamDefinitionArtifact teamDef) throws OseeCoreException {
+ Set<TeamDefinitionArtifact> teamDefs = new HashSet<TeamDefinitionArtifact>();
+ teamDefs.add(teamDef);
+ for (Artifact art : teamDef.getChildren()) {
+ if (art instanceof TeamDefinitionArtifact) {
+ teamDefs.addAll(getTeamsFromItemAndChildren((TeamDefinitionArtifact) art));
+ }
+ }
+ return teamDefs;
+ }
+
+ private static void getTeamFromItemAndChildren(ActionableItemArtifact aia, Set<TeamDefinitionArtifact> aiaTeams) throws OseeCoreException {
+ if (aia.getRelatedArtifacts(AtsRelationTypes.TeamActionableItem_Team).size() > 0) {
+ aiaTeams.addAll(aia.getRelatedArtifacts(AtsRelationTypes.TeamActionableItem_Team, TeamDefinitionArtifact.class));
+ }
+ for (Artifact childArt : aia.getChildren()) {
+ if (childArt instanceof ActionableItemArtifact) {
+ getTeamFromItemAndChildren((ActionableItemArtifact) childArt, aiaTeams);
+ }
+ }
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamDefinitions(Collection<String> teamDefNames) {
+ Set<TeamDefinitionArtifact> teamDefs = new HashSet<TeamDefinitionArtifact>();
+ for (String teamDefName : teamDefNames) {
+ for (Artifact artifact : AtsCacheManager.getArtifactsByName(AtsArtifactTypes.TeamDefinition, teamDefName)) {
+ teamDefs.add((TeamDefinitionArtifact) artifact);
+ }
+ }
+ return teamDefs;
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamDefinitionsNameStartsWith(String prefix) throws OseeCoreException {
+ Set<TeamDefinitionArtifact> artifacts = new HashSet<TeamDefinitionArtifact>();
+ for (Artifact art : ArtifactQuery.getArtifactListFromName(prefix + "%", AtsUtilCore.getAtsBranch(),
+ EXCLUDE_DELETED)) {
+ if (art instanceof TeamDefinitionArtifact) {
+ artifacts.add((TeamDefinitionArtifact) art);
+ }
+ }
+ return artifacts;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManagerCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManagerCore.java
new file mode 100644
index 00000000000..3bce9897728
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionManagerCore.java
@@ -0,0 +1,40 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.config;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TeamDefinitionManagerCore {
+
+ public static Collection<TeamDefinitionArtifact> getImpactedTeamDefs(Collection<ActionableItemArtifact> aias) throws OseeCoreException {
+ Set<TeamDefinitionArtifact> resultTeams = new HashSet<TeamDefinitionArtifact>();
+ for (ActionableItemArtifact aia : aias) {
+ resultTeams.addAll(getImpactedTeamDefInherited(aia));
+ }
+ return resultTeams;
+ }
+
+ private static List<TeamDefinitionArtifact> getImpactedTeamDefInherited(ActionableItemArtifact aia) throws OseeCoreException {
+ if (aia.getRelatedArtifacts(AtsRelationTypes.TeamActionableItem_Team).size() > 0) {
+ return aia.getRelatedArtifacts(AtsRelationTypes.TeamActionableItem_Team, TeamDefinitionArtifact.class);
+ }
+ Artifact parentArt = aia.getParent();
+ if (parentArt instanceof ActionableItemArtifact) {
+ return getImpactedTeamDefInherited((ActionableItemArtifact) parentArt);
+ }
+ return java.util.Collections.emptyList();
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionOptions.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionOptions.java
new file mode 100644
index 00000000000..b94262db6d3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/config/TeamDefinitionOptions.java
@@ -0,0 +1,6 @@
+package org.eclipse.osee.ats.core.config;
+
+public enum TeamDefinitionOptions {
+ TeamUsesVersions,
+ RequireTargetedVersion
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/Activator.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/Activator.java
new file mode 100644
index 00000000000..6806f806edc
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/Activator.java
@@ -0,0 +1,33 @@
+package org.eclipse.osee.ats.core.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+ public static final String PLUGIN_ID = "org.eclipse.osee.ats.core";
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/AbstractReviewArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/AbstractReviewArtifact.java
new file mode 100644
index 00000000000..df9d4b0082c
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/AbstractReviewArtifact.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.defect.DefectManager;
+import org.eclipse.osee.ats.core.review.role.UserRole;
+import org.eclipse.osee.ats.core.review.role.UserRoleManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.workdef.ReviewBlockType;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.ActionableItemManagerCore;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class AbstractReviewArtifact extends AbstractTaskableArtifact {
+
+ protected DefectManager defectManager;
+ protected UserRoleManager userRoleManager;
+ private ActionableItemManagerCore actionableItemsDam;
+ private Collection<UserRole> preSaveReviewRoleComplete;
+ private Boolean standAlone = null;
+
+ public AbstractReviewArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ @Override
+ public void onInitializationComplete() throws OseeCoreException {
+ super.onInitializationComplete();
+ initializeSMA();
+ };
+
+ @Override
+ public void onAttributePersist(SkynetTransaction transaction) {
+ super.onAttributePersist(transaction);
+ // Since multiple ways exist to change the assignees, notification is performed on the persist
+ if (isDeleted()) {
+ return;
+ }
+ try {
+ notifyReviewersComplete();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ @Override
+ public void initalizePreSaveCache() {
+ super.initalizePreSaveCache();
+ try {
+ preSaveReviewRoleComplete = getRoleUsersReviewComplete();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ private Collection<UserRole> getRoleUsersReviewComplete() throws OseeCoreException {
+ return this.getUserRoleManager().getRoleUsersReviewComplete();
+ }
+
+ public void notifyReviewersComplete() throws OseeCoreException {
+ UserRoleManager userRoleManager = this.getUserRoleManager();
+ //all reviewers are complete; send notification to author/moderator
+ // TODO Add this back in once move to ats.core
+ // if (!preSaveReviewRoleComplete.equals(userRoleManager.getRoleUsersReviewComplete()) && userRoleManager.getUserRoles(
+ // Role.Reviewer).equals(userRoleManager.getRoleUsersReviewComplete())) {
+ // AtsNotifyUsers.getInstance().notify(this, AtsNotifyUsers.NotifyType.Reviewed);
+ // }
+ preSaveReviewRoleComplete = userRoleManager.getRoleUsersReviewComplete();
+ }
+
+ /**
+ * Reset managers for case where artifact is re-loaded/initialized
+ *
+ * @see org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact#initialize()
+ */
+ @Override
+ protected void initializeSMA() throws OseeCoreException {
+ super.initializeSMA();
+ defectManager = new DefectManager(this);
+ userRoleManager = new UserRoleManager(this);
+ actionableItemsDam = new ActionableItemManagerCore(this);
+ }
+
+ @Override
+ public String getArtifactSuperTypeName() {
+ return "Review";
+ }
+
+ public boolean isBlocking() throws OseeCoreException {
+ return getReviewBlockType() != ReviewBlockType.None;
+ }
+
+ public ReviewBlockType getReviewBlockType() throws OseeCoreException {
+ String typeStr = getSoleAttributeValue(AtsAttributeTypes.ReviewBlocks, null);
+ if (typeStr == null) {
+ // Check old attribute value
+ if (getSoleAttributeValue(AtsAttributeTypes.BlockingReview, false)) {
+ return ReviewBlockType.Transition;
+ }
+ return ReviewBlockType.None;
+ }
+ return ReviewBlockType.valueOf(typeStr);
+ }
+
+ public DefectManager getDefectManager() {
+ if (defectManager == null) {
+ defectManager = new DefectManager(this);
+ }
+ return defectManager;
+ }
+
+ public UserRoleManager getUserRoleManager() {
+ if (userRoleManager == null) {
+ return userRoleManager = new UserRoleManager(this);
+ }
+ return userRoleManager;
+ }
+
+ public Set<TeamDefinitionArtifact> getCorrespondingTeamDefinitionArtifact() throws OseeCoreException {
+ Set<TeamDefinitionArtifact> teamDefs = new HashSet<TeamDefinitionArtifact>();
+ if (getParentTeamWorkflow() != null) {
+ teamDefs.add(getParentTeamWorkflow().getTeamDefinition());
+ }
+ if (getActionableItemsDam().getActionableItems().size() > 0) {
+ teamDefs.addAll(ActionableItemManagerCore.getImpactedTeamDefs(getActionableItemsDam().getActionableItems()));
+ }
+ return teamDefs;
+ }
+
+ /**
+ * @return the actionableItemsDam
+ */
+ public ActionableItemManagerCore getActionableItemsDam() throws OseeCoreException {
+ if (actionableItemsDam == null) {
+ actionableItemsDam = new ActionableItemManagerCore(this);
+ }
+ return actionableItemsDam;
+ }
+
+ @Override
+ public AbstractWorkflowArtifact getParentAWA() throws OseeCoreException {
+ if (isStandAloneReview()) {
+ return null;
+ }
+ if (parentAwa != null) {
+ return parentAwa;
+ }
+ parentAwa = getParentTeamWorkflow();
+ return parentAwa;
+ }
+
+ @Override
+ public Artifact getParentActionArtifact() throws OseeCoreException {
+ if (isStandAloneReview()) {
+ return null;
+ }
+ if (parentAction != null) {
+ return parentAction;
+ }
+ parentTeamArt = getParentTeamWorkflow();
+ if (parentTeamArt != null) {
+ parentAction = parentTeamArt.getParentActionArtifact();
+ }
+ return parentAction;
+ }
+
+ @Override
+ public TeamWorkFlowArtifact getParentTeamWorkflow() throws OseeCoreException {
+ if (isStandAloneReview()) {
+ return null;
+ }
+ if (parentTeamArt != null) {
+ return parentTeamArt;
+ }
+ List<TeamWorkFlowArtifact> teams =
+ getRelatedArtifacts(AtsRelationTypes.TeamWorkflowToReview_Team, TeamWorkFlowArtifact.class);
+ if (teams.size() > 1) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ getArtifactTypeName() + " " + getHumanReadableId() + " has multiple parent workflows");
+ } else if (!isStandAloneReview() && teams.isEmpty()) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ getArtifactTypeName() + " " + getHumanReadableId() + " has no parent workflow");
+ }
+ if (!teams.isEmpty()) {
+ parentTeamArt = teams.iterator().next();
+ }
+ return parentTeamArt;
+ }
+
+ public boolean isStandAloneReview() throws OseeCoreException {
+ if (standAlone == null) {
+ standAlone = getActionableItemsDam().getActionableItemGuids().size() > 0;
+ }
+ return standAlone;
+ }
+
+ @Override
+ public double getWorldViewWeeklyBenefit() {
+ return 0;
+ }
+
+ public Artifact getArtifact() {
+ return this;
+ }
+
+ public static AbstractReviewArtifact cast(Artifact artifact) {
+ if (artifact instanceof AbstractReviewArtifact) {
+ return (AbstractReviewArtifact) artifact;
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionOption.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionOption.java
new file mode 100644
index 00000000000..f95c75552af
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionOption.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+
+public class DecisionOption {
+ private String name;
+ private Collection<User> assignees = new HashSet<User>();
+ private boolean followupRequired;
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + name.hashCode();
+
+ return result;
+ }
+
+ public DecisionOption(String name, Collection<User> assignees, boolean followup) {
+ this.name = name;
+ this.followupRequired = followup;
+ if (assignees != null) {
+ this.assignees = assignees;
+ }
+ }
+
+ public DecisionOption(String name, User assignee, boolean followup) {
+ this.name = name;
+ this.followupRequired = followup;
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ public DecisionOption(String name) {
+ this(name, (User) null, false);
+ }
+
+ public DecisionOption() {
+ this("", (User) null, false);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DecisionOption) {
+ DecisionOption state = (DecisionOption) obj;
+ if (!state.name.equals(name)) {
+ return false;
+ }
+ return true;
+ }
+ return super.equals(obj);
+ }
+
+ public Collection<User> getAssignees() {
+ return assignees;
+ }
+
+ /**
+ * Sets the assigness but DOES NOT write to SMA. This method should NOT be called outside the StateMachineArtifact.
+ */
+ public void setAssignees(Collection<User> assignees) {
+ this.assignees.clear();
+ if (assignees != null) {
+ this.assignees.addAll(assignees);
+ }
+ }
+
+ /**
+ * Sets the assignes but DOES NOT write to SMA. This method should NOT be called outside the StateMachineArtifact.
+ */
+ public void setAssignee(User assignee) {
+ this.assignees.clear();
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ public void addAssignee(User assignee) {
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toXml() throws OseeCoreException {
+ StringBuffer sb = new StringBuffer(name);
+ sb.append(";");
+ for (User u : assignees) {
+ sb.append("<" + u.getUserId() + ">");
+ }
+ sb.append(";");
+ sb.append(followupRequired);
+ return sb.toString();
+ }
+
+ public Result setFromXml(String xml) {
+ Matcher m = Pattern.compile("^(.*?);(.*?);(.*)$").matcher(xml);
+ if (m.find()) {
+ String toState = m.group(2).toLowerCase();
+ name = m.group(1);
+ if (name.equals("")) {
+ return new Result("Invalid name");
+ }
+ if (toState.equals("followup")) {
+ followupRequired = true;
+ } else if (toState.equals("completed")) {
+ followupRequired = false;
+ } else {
+ return new Result("Invalid followup string \"" + m.group(2) + "\"\nShould be followup or completed");
+ }
+ m = Pattern.compile("<(.*?)>").matcher(m.group(3));
+ while (m.find()) {
+ try {
+ assignees.add(UserManager.getUserByUserId(m.group(1)));
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+ if (followupRequired && assignees.isEmpty()) {
+ return new Result("If followup is specified, must set assignees.\nShould be: <userid><userid>");
+ } else if (!followupRequired && assignees.size() > 0) {
+ return new Result("If completed is specified, don't specify assigness. Leave blank.\n");
+ }
+ } else {
+ return new Result(
+ "Can't unpack decision option data => " + xml + "\n\n" + "must be in format: \"Name;(followup|completed);<userid1><userid2>\"" + "where true if followup is required; false if not. If followup required, assignees will be userid1, userid2.");
+ }
+ return Result.TrueResult;
+ }
+
+ /**
+ * @return the followupRequired
+ */
+ public boolean isFollowupRequired() {
+ return followupRequired;
+ }
+
+ /**
+ * @param followupRequired the followupRequired to set
+ */
+ public void setFollowupRequired(boolean followupRequired) {
+ this.followupRequired = followupRequired;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewArtifact.java
new file mode 100644
index 00000000000..a057752eb69
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewArtifact.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.workflow.StateManager;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.IATSStateMachineArtifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class DecisionReviewArtifact extends AbstractReviewArtifact implements IReviewArtifact, IATSStateMachineArtifact {
+
+ public XDecisionOptions decisionOptions;
+
+ public DecisionReviewArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ decisionOptions = new XDecisionOptions(this);
+ }
+
+ @Override
+ public Collection<User> getImplementers() throws OseeCoreException {
+ return StateManager.getImplementersByState(this, DecisionReviewState.Decision);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewManager.java
new file mode 100644
index 00000000000..0a120d533c7
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewManager.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.review;
+
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionOption;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * Methods in support of programatically transitioning the Decision Review Workflow through it's states. Only to be used
+ * for the DefaultReviewWorkflow of Prepare->Decision->ReWork->Complete
+ *
+ * @author Donald G. Dunne
+ */
+public final class DecisionReviewManager {
+
+ private DecisionReviewManager() {
+ // private constructor
+ }
+
+ /**
+ * Quickly transition to a state with minimal metrics and data entered. Should only be used for automated
+ * transitioning for things such as developmental testing and demos.
+ *
+ * @param user User to transition to OR null if should use user of current state
+ */
+ public static Result transitionTo(DecisionReviewArtifact reviewArt, DecisionReviewState toState, User user, boolean popup, SkynetTransaction transaction) throws OseeCoreException {
+ Result result = Result.TrueResult;
+ // If in Prepare state, set data and transition to Decision
+ if (reviewArt.isInState(DecisionReviewState.Prepare)) {
+ result = setPrepareStateData(popup, reviewArt, 100, 3, .2);
+ if (result.isFalse()) {
+ return result;
+ }
+ result =
+ transitionToState(toState.getWorkPageType(), popup, DecisionReviewState.Decision, reviewArt, user,
+ transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ }
+ if (toState == DecisionReviewState.Decision) {
+ return Result.TrueResult;
+ }
+
+ // If desired to transition to follow-up, then decision is false
+ boolean decision = toState != DecisionReviewState.Followup;
+
+ result = setDecisionStateData(popup, reviewArt, decision, 100, .2);
+ if (result.isFalse()) {
+ return result;
+ }
+
+ result = transitionToState(toState.getWorkPageType(), popup, toState, reviewArt, user, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ public static Result setPrepareStateData(boolean popup, DecisionReviewArtifact reviewArt, int statePercentComplete, double estimateHours, double stateHoursSpent) throws OseeCoreException {
+ if (!reviewArt.isInState(DecisionReviewState.Prepare)) {
+ Result result = new Result("Action not in Prepare state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ reviewArt.setSoleAttributeValue(AtsAttributeTypes.EstimatedHours, estimateHours);
+ reviewArt.getStateMgr().updateMetrics(stateHoursSpent, statePercentComplete, true);
+ return Result.TrueResult;
+ }
+
+ public static Result transitionToState(WorkPageType workPageType, boolean popup, IWorkPage toState, DecisionReviewArtifact reviewArt, User user, SkynetTransaction transaction) throws OseeCoreException {
+ TransitionManager transitionMgr = new TransitionManager(reviewArt);
+ Result result =
+ transitionMgr.transition(toState,
+ (user == null ? reviewArt.getStateMgr().getAssignees().iterator().next() : user), transaction,
+ TransitionOption.None);
+ return result;
+ }
+
+ public static Result setDecisionStateData(boolean popup, DecisionReviewArtifact reviewArt, boolean decision, int statePercentComplete, double stateHoursSpent) throws OseeCoreException {
+ if (!reviewArt.isInState(DecisionReviewState.Decision)) {
+ Result result = new Result("Action not in Decision state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ reviewArt.setSoleAttributeValue(AtsAttributeTypes.Decision, decision ? "Yes" : "No");
+ reviewArt.getStateMgr().updateMetrics(stateHoursSpent, statePercentComplete, true);
+ return Result.TrueResult;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewState.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewState.java
new file mode 100644
index 00000000000..2426aea0400
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/DecisionReviewState.java
@@ -0,0 +1,25 @@
+package org.eclipse.osee.ats.core.review;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.util.WorkPageAdapter;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+
+public class DecisionReviewState extends WorkPageAdapter {
+ public static DecisionReviewState Prepare = new DecisionReviewState("Prepare", WorkPageType.Working);
+ public static DecisionReviewState Decision = new DecisionReviewState("Decision", WorkPageType.Working);
+ public static DecisionReviewState Followup = new DecisionReviewState("Followup", WorkPageType.Working);
+ public static DecisionReviewState Completed = new DecisionReviewState("Completed", WorkPageType.Completed);
+
+ private DecisionReviewState(String pageName, WorkPageType workPageType) {
+ super(DecisionReviewState.class, pageName, workPageType);
+ }
+
+ public static DecisionReviewState valueOf(String pageName) {
+ return WorkPageAdapter.valueOfPage(DecisionReviewState.class, pageName);
+ }
+
+ public static List<DecisionReviewState> values() {
+ return WorkPageAdapter.pages(DecisionReviewState.class);
+ }
+
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/IReviewArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/IReviewArtifact.java
new file mode 100644
index 00000000000..3fd417d7d25
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/IReviewArtifact.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import org.eclipse.osee.ats.core.review.defect.DefectManager;
+import org.eclipse.osee.ats.core.review.role.UserRoleManager;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public interface IReviewArtifact {
+
+ boolean isBlocking() throws OseeCoreException;
+
+ DefectManager getDefectManager();
+
+ UserRoleManager getUserRoleManager();
+
+ Artifact getArtifact();
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewArtifact.java
new file mode 100644
index 00000000000..bf9d46376d0
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewArtifact.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.review.defect.DefectManager;
+import org.eclipse.osee.ats.core.review.role.UserRole;
+import org.eclipse.osee.ats.core.workflow.StateManager;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.IATSStateMachineArtifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class PeerToPeerReviewArtifact extends AbstractReviewArtifact implements IReviewArtifact, IATSStateMachineArtifact {
+
+ public PeerToPeerReviewArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ defectManager = new DefectManager(this);
+ }
+
+ @Override
+ public Collection<User> getImplementers() throws OseeCoreException {
+ Collection<User> users = StateManager.getImplementersByState(this, PeerToPeerReviewState.Review);
+ for (UserRole role : userRoleManager.getUserRoles()) {
+ users.add(role.getUser());
+ }
+ return users;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewManager.java
new file mode 100644
index 00000000000..62ac2e9353a
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewManager.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.review;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.review.defect.DefectItem;
+import org.eclipse.osee.ats.core.review.role.UserRole;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionOption;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * Methods in support of programatically transitioning the Peer Review Workflow through it's states. Only to be used for
+ * the DefaultReviewWorkflow of Prepare->Review->Complete
+ *
+ * @author Donald G. Dunne
+ */
+public final class PeerToPeerReviewManager {
+
+ public static String getDefaultReviewTitle(TeamWorkFlowArtifact teamArt) {
+ return "Review \"" + teamArt.getArtifactTypeName() + "\" titled \"" + teamArt.getName() + "\"";
+ }
+
+ private PeerToPeerReviewManager() {
+ // private constructor
+ }
+
+ /**
+ * Quickly transition to a state with minimal metrics and data entered. Should only be used for automated transition
+ * for things such as developmental testing and demos.
+ *
+ * @param user User to transition to OR null if should use user of current state
+ */
+ public static Result transitionTo(PeerToPeerReviewArtifact reviewArt, PeerToPeerReviewState toState, Collection<UserRole> roles, Collection<DefectItem> defects, User user, boolean popup, SkynetTransaction transaction) throws OseeCoreException {
+ Result result = setPrepareStateData(popup, reviewArt, roles, "DoThis.java", 100, .2, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ result =
+ transitionToState(PeerToPeerReviewState.Review.getWorkPageType(), popup, reviewArt,
+ PeerToPeerReviewState.Review, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ if (toState == PeerToPeerReviewState.Review) {
+ return Result.TrueResult;
+ }
+
+ result = setReviewStateData(popup, reviewArt, roles, defects, 100, .2, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+
+ result =
+ transitionToState(PeerToPeerReviewState.Completed.getWorkPageType(), popup, reviewArt,
+ PeerToPeerReviewState.Completed, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ private static Result transitionToState(WorkPageType workPageType, boolean popup, PeerToPeerReviewArtifact reviewArt, IWorkPage toState, SkynetTransaction transaction) throws OseeCoreException {
+ TransitionManager transitionMgr = new TransitionManager(reviewArt);
+ Result result =
+ transitionMgr.transition(toState, reviewArt.getStateMgr().getAssignees().iterator().next(), transaction,
+ TransitionOption.None);
+ return result;
+ }
+
+ public static Result setPrepareStateData(boolean popup, PeerToPeerReviewArtifact reviewArt, Collection<UserRole> roles, String reviewMaterials, int statePercentComplete, double stateHoursSpent, SkynetTransaction transaction) throws OseeCoreException {
+ if (!reviewArt.isInState(PeerToPeerReviewState.Prepare)) {
+ Result result = new Result("Action not in Prepare state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+
+ }
+ if (roles != null) {
+ for (UserRole role : roles) {
+ reviewArt.getUserRoleManager().addOrUpdateUserRole(role, false, transaction);
+ }
+ }
+ reviewArt.setSoleAttributeValue(AtsAttributeTypes.Location, reviewMaterials);
+ reviewArt.getStateMgr().updateMetrics(stateHoursSpent, statePercentComplete, true);
+ return Result.TrueResult;
+ }
+
+ public static Result setReviewStateData(boolean popup, PeerToPeerReviewArtifact reviewArt, Collection<UserRole> roles, Collection<DefectItem> defects, int statePercentComplete, double stateHoursSpent, SkynetTransaction transaction) throws OseeCoreException {
+ if (roles != null) {
+ for (UserRole role : roles) {
+ reviewArt.getUserRoleManager().addOrUpdateUserRole(role, false, transaction);
+ }
+ }
+ if (defects != null) {
+ for (DefectItem defect : defects) {
+ reviewArt.getDefectManager().addOrUpdateDefectItem(defect, false, transaction);
+ }
+ }
+ reviewArt.getStateMgr().updateMetrics(stateHoursSpent, statePercentComplete, true);
+ return Result.TrueResult;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewState.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewState.java
new file mode 100644
index 00000000000..cc99c85b3d3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/PeerToPeerReviewState.java
@@ -0,0 +1,25 @@
+package org.eclipse.osee.ats.core.review;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.util.WorkPageAdapter;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+
+public class PeerToPeerReviewState extends WorkPageAdapter {
+ public static PeerToPeerReviewState Prepare = new PeerToPeerReviewState("Prepare", WorkPageType.Working);
+ public static PeerToPeerReviewState Review = new PeerToPeerReviewState("Review", WorkPageType.Working);
+ public static PeerToPeerReviewState Meeting = new PeerToPeerReviewState("Meeting", WorkPageType.Working);
+ public static PeerToPeerReviewState Completed = new PeerToPeerReviewState("Completed", WorkPageType.Completed);
+
+ private PeerToPeerReviewState(String pageName, WorkPageType workPageType) {
+ super(PeerToPeerReviewState.class, pageName, workPageType);
+ }
+
+ public static PeerToPeerReviewState valueOf(String pageName) {
+ return WorkPageAdapter.valueOfPage(PeerToPeerReviewState.class, pageName);
+ }
+
+ public static List<PeerToPeerReviewState> values() {
+ return WorkPageAdapter.pages(PeerToPeerReviewState.class);
+ }
+
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewFormalType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewFormalType.java
new file mode 100644
index 00000000000..16658d436ca
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewFormalType.java
@@ -0,0 +1,6 @@
+package org.eclipse.osee.ats.core.review;
+
+public enum ReviewFormalType {
+ InFormal,
+ Formal
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewManager.java
new file mode 100644
index 00000000000..42a6eabb790
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/ReviewManager.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.workdef.DecisionReviewOption;
+import org.eclipse.osee.ats.core.workdef.ReviewBlockType;
+import org.eclipse.osee.ats.core.workdef.RuleDefinitionOption;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workflow.HoursSpentUtil;
+import org.eclipse.osee.ats.core.workflow.PercentCompleteTotalUtil;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionOption;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactTypeManager;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.utility.UsersByIds;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ReviewManager {
+
+ private final static String VALIDATE_REVIEW_TITLE = "Is the resolution of this Action valid?";
+
+ public ReviewManager() {
+ super();
+ }
+
+ public static boolean isValidatePage(StateDefinition stateDefinition) {
+ if (stateDefinition.hasRule(RuleDefinitionOption.AddDecisionValidateBlockingReview)) {
+ return true;
+ }
+ if (stateDefinition.hasRule(RuleDefinitionOption.AddDecisionValidateNonBlockingReview)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Create a new decision review configured and transitioned to handle action validation
+ *
+ * @param force will force the creation of the review without checking that a review should be created
+ */
+ public static DecisionReviewArtifact createValidateReview(TeamWorkFlowArtifact teamArt, boolean force, Date createdDate, User createdBy, SkynetTransaction transaction) throws OseeCoreException {
+ // If not validate page, don't do anything
+ if (!force && !isValidatePage(teamArt.getStateDefinition())) {
+ return null;
+ }
+ // If validate review already created for this state, return
+ if (!force && getReviewsFromCurrentState(teamArt).size() > 0) {
+ for (AbstractReviewArtifact rev : getReviewsFromCurrentState(teamArt)) {
+ if (rev.getName().equals(VALIDATE_REVIEW_TITLE)) {
+ return null;
+ }
+ }
+ }
+ // Create validate review
+ try {
+
+ DecisionReviewArtifact decRev =
+ ReviewManager.createNewDecisionReview(
+ teamArt,
+ isValidateReviewBlocking(teamArt.getStateDefinition()) ? ReviewBlockType.Transition : ReviewBlockType.None,
+ true, createdDate, createdBy);
+ decRev.setName(VALIDATE_REVIEW_TITLE);
+ decRev.setSoleAttributeValue(AtsAttributeTypes.DecisionReviewOptions,
+ "No;Followup;" + getValidateReviewFollowupUsersStr(teamArt) + "\n" + "Yes;Completed;");
+
+ TransitionManager transitionMgr = new TransitionManager(decRev);
+ transitionMgr.transition(DecisionReviewState.Decision, teamArt.getCreatedBy(), transaction,
+ TransitionOption.Persist);
+
+ return decRev;
+
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ }
+ return null;
+ }
+
+ public static boolean isValidateReviewBlocking(StateDefinition stateDefinition) {
+ return stateDefinition.hasRule(RuleDefinitionOption.AddDecisionValidateBlockingReview);
+ }
+
+ public static DecisionReviewArtifact createNewDecisionReview(TeamWorkFlowArtifact teamArt, String reviewTitle, String description, String againstState, ReviewBlockType reviewBlockType, Collection<DecisionReviewOption> options, Collection<User> assignees, Date createdDate, User createdBy, SkynetTransaction transaction) throws OseeCoreException {
+ DecisionReviewArtifact decRev =
+ ReviewManager.createNewDecisionReview(teamArt, reviewBlockType, reviewTitle, againstState, description,
+ options, assignees, createdDate, createdBy);
+ return decRev;
+ }
+
+ public static DecisionReviewArtifact createNewDecisionReviewAndTransitionToDecision(TeamWorkFlowArtifact teamArt, String reviewTitle, String description, String againstState, ReviewBlockType reviewBlockType, Collection<DecisionReviewOption> options, Collection<User> assignees, Date createdDate, User createdBy, SkynetTransaction transaction) throws OseeCoreException {
+ DecisionReviewArtifact decRev =
+ ReviewManager.createNewDecisionReview(teamArt, reviewBlockType, reviewTitle, againstState, description,
+ options, assignees, createdDate, createdBy);
+ decRev.persist(transaction);
+
+ TransitionManager transitionMgr = new TransitionManager(decRev);
+ Result result =
+ transitionMgr.transition(DecisionReviewState.Decision, assignees, transaction, TransitionOption.Persist,
+ TransitionOption.OverrideAssigneeCheck);
+ if (result.isFalse()) {
+ throw new OseeStateException("Error auto-transitioning review %s to Decision state", decRev.toStringWithId());
+ }
+ return decRev;
+ }
+
+ public static PeerToPeerReviewArtifact createNewPeerToPeerReview(TeamWorkFlowArtifact teamArt, String reviewTitle, String againstState, SkynetTransaction transaction) throws OseeCoreException {
+ return createNewPeerToPeerReview(teamArt, reviewTitle, againstState, new Date(), UserManager.getUser(),
+ transaction);
+ }
+
+ public static PeerToPeerReviewArtifact createNewPeerToPeerReview(TeamWorkFlowArtifact teamArt, String reviewTitle, String againstState, Date createdDate, User createdBy, SkynetTransaction transaction) throws OseeCoreException {
+ PeerToPeerReviewArtifact peerToPeerRev =
+ (PeerToPeerReviewArtifact) ArtifactTypeManager.addArtifact(AtsArtifactTypes.PeerToPeerReview,
+ AtsUtilCore.getAtsBranch(), reviewTitle == null ? "Peer to Peer Review" : reviewTitle);
+ // Initialize state machine
+ peerToPeerRev.initializeNewStateMachine(null, new Date(), createdBy);
+
+ if (teamArt != null) {
+ teamArt.addRelation(AtsRelationTypes.TeamWorkflowToReview_Review, peerToPeerRev);
+ if (againstState != null) {
+ peerToPeerRev.setSoleAttributeValue(AtsAttributeTypes.RelatedToState, againstState);
+ }
+ }
+ peerToPeerRev.setSoleAttributeValue(AtsAttributeTypes.ReviewBlocks, ReviewBlockType.None.name());
+ peerToPeerRev.setSoleAttributeValue(AtsAttributeTypes.ReviewFormalType, ReviewFormalType.InFormal.name());
+ peerToPeerRev.persist(transaction);
+ return peerToPeerRev;
+ }
+
+ /**
+ * Return Remain Hours for all reviews
+ */
+ public static double getRemainHours(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ double hours = 0;
+ for (AbstractReviewArtifact reviewArt : getReviews(teamArt)) {
+ hours += reviewArt.getRemainHoursFromArtifact();
+ }
+ return hours;
+
+ }
+
+ /**
+ * Return Estimated Review Hours of "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ */
+ public static double getEstimatedHours(TeamWorkFlowArtifact teamArt, IWorkPage relatedToState) throws OseeCoreException {
+ double hours = 0;
+ for (AbstractReviewArtifact revArt : getReviews(teamArt, relatedToState)) {
+ hours += revArt.getEstimatedHoursTotal();
+ }
+ return hours;
+ }
+
+ /**
+ * Return Estimated Hours for all reviews
+ */
+ public static double getEstimatedHours(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ double hours = 0;
+ for (AbstractReviewArtifact revArt : getReviews(teamArt)) {
+ hours += revArt.getEstimatedHoursTotal();
+ }
+ return hours;
+
+ }
+
+ public static String getValidateReviewFollowupUsersStr(TeamWorkFlowArtifact teamArt) {
+ try {
+ return UsersByIds.getStorageString(getValidateReviewFollowupUsers(teamArt));
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return ex.getLocalizedMessage();
+ }
+ }
+
+ public static Collection<User> getValidateReviewFollowupUsers(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ Collection<User> users = teamArt.getStateMgr().getAssignees(TeamState.Implement);
+ if (users.size() > 0) {
+ return users;
+ }
+
+ // Else if Team Workflow , return it to the leads of this team
+ return teamArt.getTeamDefinition().getLeads();
+
+ }
+
+ public static Collection<AbstractReviewArtifact> getReviews(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ return teamArt.getRelatedArtifacts(AtsRelationTypes.TeamWorkflowToReview_Review, AbstractReviewArtifact.class);
+ }
+
+ public static Collection<AbstractReviewArtifact> getReviewsFromCurrentState(TeamWorkFlowArtifact teamArt) throws OseeCoreException {
+ return getReviews(teamArt, teamArt.getStateMgr().getCurrentState());
+ }
+
+ public static Collection<AbstractReviewArtifact> getReviews(TeamWorkFlowArtifact teamArt, IWorkPage state) throws OseeCoreException {
+ Set<AbstractReviewArtifact> arts = new HashSet<AbstractReviewArtifact>();
+ for (AbstractReviewArtifact revArt : getReviews(teamArt)) {
+ if (revArt.getSoleAttributeValue(AtsAttributeTypes.RelatedToState, "").equals(state.getPageName())) {
+ arts.add(revArt);
+ }
+ }
+ return arts;
+ }
+
+ public static boolean hasReviews(TeamWorkFlowArtifact teamArt) {
+ return teamArt.getRelatedArtifactsCount(AtsRelationTypes.TeamWorkflowToReview_Review) > 0;
+ }
+
+ public static Result areReviewsComplete(TeamWorkFlowArtifact teamArt) {
+ return areReviewsComplete(teamArt, true);
+ }
+
+ public static Result areReviewsComplete(TeamWorkFlowArtifact teamArt, boolean popup) {
+ try {
+ for (AbstractReviewArtifact reviewArt : getReviews(teamArt)) {
+ if (!reviewArt.isCompleted() && reviewArt.isCancelled()) {
+ return new Result("Not Complete");
+ }
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return Result.TrueResult;
+ }
+
+ /**
+ * Return Hours Spent for Reviews of "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ */
+ public static double getHoursSpent(TeamWorkFlowArtifact teamArt, IWorkPage relatedToState) throws OseeCoreException {
+ double spent = 0;
+ for (AbstractReviewArtifact reviewArt : getReviews(teamArt, relatedToState)) {
+ spent += HoursSpentUtil.getHoursSpentTotal(reviewArt);
+ }
+ return spent;
+ }
+
+ /**
+ * Return Total Percent Complete / # Reviews for "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ */
+ public static int getPercentComplete(TeamWorkFlowArtifact teamArt, IWorkPage relatedToState) throws OseeCoreException {
+ int spent = 0;
+ Collection<AbstractReviewArtifact> reviewArts = getReviews(teamArt, relatedToState);
+ for (AbstractReviewArtifact reviewArt : reviewArts) {
+ spent += PercentCompleteTotalUtil.getPercentCompleteTotal(reviewArt);
+ }
+ if (spent == 0) {
+ return 0;
+ }
+ return spent / reviewArts.size();
+ }
+
+ public static DecisionReviewArtifact createNewDecisionReview(TeamWorkFlowArtifact teamArt, ReviewBlockType reviewBlockType, boolean againstCurrentState, Date createdDate, User createdBy) throws OseeCoreException {
+ return createNewDecisionReview(teamArt, reviewBlockType,
+ "Should we do this? Yes will require followup, No will not",
+ againstCurrentState ? teamArt.getStateMgr().getCurrentStateName() : null,
+ "Enter description of the decision, if any", getDefaultDecisionReviewOptions(), null, createdDate, createdBy);
+ }
+
+ public static List<DecisionReviewOption> getDefaultDecisionReviewOptions() throws OseeCoreException {
+ List<DecisionReviewOption> options = new ArrayList<DecisionReviewOption>();
+ options.add(new DecisionReviewOption("Yes", true, Arrays.asList(UserManager.getUser().getUserId())));
+ options.add(new DecisionReviewOption("No", false, null));
+ return options;
+ }
+
+ public static String getDecisionReviewOptionsString(Collection<DecisionReviewOption> options) {
+ StringBuffer sb = new StringBuffer();
+ for (DecisionReviewOption opt : options) {
+ sb.append(opt.getName());
+ sb.append(";");
+ sb.append(opt.isFollowupRequired() ? "Followup" : "Completed");
+ sb.append(";");
+ for (String userId : opt.getUserIds()) {
+ sb.append("<" + userId + ">");
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ public static DecisionReviewArtifact createNewDecisionReview(TeamWorkFlowArtifact teamArt, ReviewBlockType reviewBlockType, String title, String relatedToState, String description, Collection<DecisionReviewOption> options, Collection<User> assignees, Date createdDate, User createdBy) throws OseeCoreException {
+ DecisionReviewArtifact decRev =
+ (DecisionReviewArtifact) ArtifactTypeManager.addArtifact(AtsArtifactTypes.DecisionReview,
+ AtsUtilCore.getAtsBranch(), title);
+
+ // Initialize state machine
+ decRev.initializeNewStateMachine(assignees, createdDate, createdBy);
+
+ if (teamArt != null) {
+ teamArt.addRelation(AtsRelationTypes.TeamWorkflowToReview_Review, decRev);
+ }
+ if (Strings.isValid(relatedToState)) {
+ decRev.setSoleAttributeValue(AtsAttributeTypes.RelatedToState, relatedToState);
+ }
+ if (Strings.isValid(description)) {
+ decRev.setSoleAttributeValue(AtsAttributeTypes.Description, description);
+ }
+ decRev.setSoleAttributeValue(AtsAttributeTypes.DecisionReviewOptions, getDecisionReviewOptionsString(options));
+ if (reviewBlockType != null) {
+ decRev.setSoleAttributeFromString(AtsAttributeTypes.ReviewBlocks, reviewBlockType.name());
+ }
+
+ return decRev;
+ }
+
+ public static AbstractReviewArtifact cast(Artifact artifact) {
+ if (artifact instanceof AbstractReviewArtifact) {
+ return (AbstractReviewArtifact) artifact;
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/XDecisionOptions.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/XDecisionOptions.java
new file mode 100644
index 00000000000..d64fe230bca
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/XDecisionOptions.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review;
+
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.logging.OseeLog;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XDecisionOptions {
+
+ private final WeakReference<AbstractWorkflowArtifact> smaRef;
+ private final IAttributeType attributeType;
+
+ public XDecisionOptions(AbstractWorkflowArtifact sma) {
+ this.smaRef = new WeakReference<AbstractWorkflowArtifact>(sma);
+ this.attributeType = AtsAttributeTypes.DecisionReviewOptions;
+ }
+
+ public IAttributeType getAttributeType() {
+ return attributeType;
+ }
+
+ public Set<DecisionOption> getDecisionOptions() throws OseeCoreException {
+ String decString = getSma().getSoleAttributeValue(getAttributeType(), "");
+ return getDecisionOptions(decString);
+ }
+
+ public AbstractWorkflowArtifact getSma() throws OseeStateException {
+ if (smaRef.get() == null) {
+ throw new OseeStateException("Artifact has been garbage collected");
+ }
+ return smaRef.get();
+ }
+
+ public static Set<DecisionOption> getDecisionOptions(String decisionOptions) {
+ Set<DecisionOption> decOptions = new HashSet<DecisionOption>();
+ for (String decsionOpt : decisionOptions.split("[\n\r]+")) {
+ DecisionOption state = new DecisionOption();
+ Result result = state.setFromXml(decsionOpt);
+ if (result.isFalse()) {
+ OseeLog.log(Activator.class, Level.SEVERE, result.getText());
+ } else {
+ decOptions.add(state);
+ }
+ }
+ return decOptions;
+ }
+
+ public DecisionOption getDecisionOption(String name) throws OseeCoreException {
+ for (DecisionOption opt : getDecisionOptions()) {
+ if (opt.getName().equals(name)) {
+ return opt;
+ }
+ }
+ return null;
+ }
+
+ public Result validateDecisionOptions() throws OseeCoreException {
+ return validateDecisionOptions(getSma().getSoleAttributeValue(getAttributeType(), ""));
+ }
+
+ public static Result validateDecisionOptions(String decisionOptions) {
+ for (String decsionOpt : decisionOptions.split("[\n\r]+")) {
+ DecisionOption state = new DecisionOption();
+ Result result = state.setFromXml(decsionOpt);
+ if (result.isFalse()) {
+ return new Result("Invalid Decision Option \"" + decsionOpt + "\" " + result.getText());
+ }
+ }
+ return Result.TrueResult;
+ }
+
+ public String toXml(Set<DecisionOption> opts) throws OseeCoreException {
+ StringBuffer sb = new StringBuffer();
+ for (DecisionOption opt : opts) {
+ sb.append(opt.toXml());
+ sb.append("\n");
+ }
+ return sb.toString().replaceFirst("\n$", "");
+ }
+
+ public void setDecisionOptions(String decisionOptions) throws OseeCoreException {
+ getSma().setSoleAttributeValue(getAttributeType(), toXml(getDecisionOptions(decisionOptions)));
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectItem.java
new file mode 100644
index 00000000000..9e458efc27f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectItem.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review.defect;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class DefectItem {
+
+ private Date date = new Date();
+ private String description = "";
+ private String location = "";
+ private String resolution = "";
+ private User user;
+ private String guid = GUID.create();
+ private Severity severity = Severity.None;
+ private Disposition disposition = Disposition.None;
+ private InjectionActivity injectionActivity = InjectionActivity.None;
+ private boolean closed = false;
+ public static enum Severity {
+ None,
+ Major,
+ Minor,
+ Issue;
+ public static Collection<String> strValues() {
+ Set<String> values = new HashSet<String>();
+ for (Enum<Severity> e : values()) {
+ values.add(e.name());
+ }
+ return values;
+ }
+
+ };
+
+ public DefectItem() throws OseeCoreException {
+ user = UserManager.getUser();
+ }
+
+ public DefectItem(User user, Severity severity, Disposition disposition, InjectionActivity injectionActivity, String description, String resolution, String location, Date date) {
+ this.user = user;
+ if (severity != null) {
+ this.severity = severity;
+ }
+ if (disposition != null) {
+ this.disposition = disposition;
+ }
+ if (injectionActivity != null) {
+ this.injectionActivity = injectionActivity;
+ }
+ if (description != null) {
+ this.description = description;
+ }
+ if (resolution != null) {
+ this.resolution = resolution;
+ }
+ if (location != null) {
+ this.location = location;
+ }
+ if (date != null) {
+ this.date = date;
+ }
+ }
+
+ public DefectItem(String xml) throws OseeCoreException {
+ fromXml(xml);
+ }
+
+ public void update(DefectItem dItem) throws OseeCoreException {
+ fromXml(dItem.toXml());
+ }
+
+ public static enum Disposition {
+ None,
+ Accept,
+ Reject,
+ Duplicate;
+ public static Collection<String> strValues() {
+ Set<String> values = new HashSet<String>();
+ for (Enum<Disposition> e : values()) {
+ values.add(e.name());
+ }
+ return values;
+ }
+
+ };
+ public static enum InjectionActivity {
+ None,
+ Planning,
+ System_Level_Requirements,
+ System_Design,
+ Software_Requirements,
+ Software_Design,
+ Code,
+ Test,
+ Other;
+ public static Collection<String> strValues() {
+ Set<String> values = new HashSet<String>();
+ for (Enum<InjectionActivity> e : values()) {
+ values.add(e.name());
+ }
+ return values;
+ }
+ };
+
+ public String getDate(String pattern) {
+ if (pattern != null) {
+ return new SimpleDateFormat(pattern).format(date);
+ }
+ return date.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DefectItem) {
+ DefectItem di = (DefectItem) obj;
+ return di.guid.equals(getGuid());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return guid.hashCode();
+ }
+
+ public String toXml() throws OseeCoreException {
+ return "<severity>" + severity.name() + "</severity><disposition>" + disposition.name() +
+ //
+ "</disposition><injectionActivity>" + injectionActivity.name() + "</injectionActivity><date>" + date.getTime() +
+ //
+ "</date><user>" + user.getUserId() + "</user><description>" + description + "</description><location>" + location +
+ //
+ "</location><resolution>" + resolution + "</resolution><closed>" + closed + "</closed><guid>" + guid + "</guid>";
+ }
+
+ private void fromXml(String xml) throws OseeCoreException {
+ this.severity = Severity.valueOf(AXml.getTagData(xml, "severity"));
+ this.disposition = Disposition.valueOf(AXml.getTagData(xml, "disposition"));
+ this.injectionActivity = InjectionActivity.valueOf(AXml.getTagData(xml, "injectionActivity"));
+ Date date = new Date();
+ date.setTime(new Long(AXml.getTagData(xml, "date")));
+ this.date = date;
+ this.user = UserManager.getUserByUserId(AXml.getTagData(xml, "user"));
+ this.description = AXml.getTagData(xml, "description");
+ this.location = AXml.getTagData(xml, "location");
+ this.resolution = AXml.getTagData(xml, "resolution");
+ this.closed = AXml.getTagBooleanData(xml, "closed");
+ this.guid = AXml.getTagData(xml, "guid");
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ @Override
+ public String toString() {
+ return severity + " - " + disposition + " - " + injectionActivity + " - " + user + " on " + DateUtil.getMMDDYYHHMM(date) + "\n";
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public String toHTML(String labelFont) {
+ return "DEFECT (" + severity + "): " + description + " (" + user.getName() + ")";
+ }
+
+ /**
+ * @param user The user to set.
+ */
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getResolution() {
+ return resolution;
+ }
+
+ public void setResolution(String resolution) {
+ this.resolution = resolution;
+ }
+
+ public Severity getSeverity() {
+ return severity;
+ }
+
+ public void setSeverity(Severity severity) {
+ this.severity = severity;
+ }
+
+ public Disposition getDisposition() {
+ return disposition;
+ }
+
+ public void setDisposition(Disposition disposition) {
+ this.disposition = disposition;
+ }
+
+ public InjectionActivity getInjectionActivity() {
+ return injectionActivity;
+ }
+
+ public void setInjectionActivity(InjectionActivity injectionActivity) {
+ this.injectionActivity = injectionActivity;
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ public void setClosed(boolean closed) {
+ this.closed = closed;
+ }
+
+ /**
+ * @return the guid
+ */
+ public String getGuid() {
+ return guid;
+ }
+
+ /**
+ * @param guid the guid to set
+ */
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectManager.java
new file mode 100644
index 00000000000..ce92b2cc6e8
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/defect/DefectManager.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review.defect;
+
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.defect.DefectItem.Severity;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.jdk.core.util.AHTML;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.Attribute;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class DefectManager {
+
+ private final WeakReference<Artifact> artifactRef;
+ private boolean enabled = true;
+ private final static String DEFECT_ITEM_TAG = "Item";
+ private static final IAttributeType REVIEW_STORAGE_TYPE = AtsAttributeTypes.ReviewDefect;
+
+ private final Matcher defectMatcher = java.util.regex.Pattern.compile(
+ "<" + DEFECT_ITEM_TAG + ">(.*?)</" + DEFECT_ITEM_TAG + ">", Pattern.DOTALL | Pattern.MULTILINE).matcher("");
+
+ public DefectManager(Artifact artifact) {
+ this.artifactRef = new WeakReference<Artifact>(artifact);
+ }
+
+ public Artifact getArtifact() throws OseeStateException {
+ if (artifactRef.get() == null) {
+ throw new OseeStateException("Artifact has been garbage collected");
+ }
+ return artifactRef.get();
+ }
+
+ public String getHtml() throws OseeCoreException {
+ if (getDefectItems().isEmpty()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.append(AHTML.addSpace(1) + AHTML.getLabelStr(AHTML.LABEL_FONT, "Defects"));
+ sb.append(getTable());
+ return sb.toString();
+ }
+
+ public Set<DefectItem> getDefectItems() throws OseeCoreException {
+ Set<DefectItem> defectItems = new HashSet<DefectItem>();
+ for (String xml : getArtifact().getAttributesToStringList(REVIEW_STORAGE_TYPE)) {
+ defectMatcher.reset(xml);
+ while (defectMatcher.find()) {
+ DefectItem item = new DefectItem(defectMatcher.group());
+ defectItems.add(item);
+ }
+ }
+ return defectItems;
+ }
+
+ public int getNumMajor() throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Major) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ public int getNumMinor() throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Minor) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ public int getNumIssues() throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Issue) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ private void saveDefectItems(Set<DefectItem> defectItems, boolean persist, SkynetTransaction transaction) {
+ try {
+ // Change existing ones
+ for (Attribute<?> attr : getArtifact().getAttributes(REVIEW_STORAGE_TYPE)) {
+ DefectItem dbPromoteItem = new DefectItem((String) attr.getValue());
+ for (DefectItem pItem : defectItems) {
+ if (pItem.equals(dbPromoteItem)) {
+ attr.setFromString(AXml.addTagData(DEFECT_ITEM_TAG, pItem.toXml()));
+ }
+ }
+ }
+ Set<DefectItem> dbPromoteItems = getDefectItems();
+ // Remove deleted ones; items in dbPromoteItems that are not in promoteItems
+ for (DefectItem delPromoteItem : org.eclipse.osee.framework.jdk.core.util.Collections.setComplement(
+ dbPromoteItems, defectItems)) {
+ for (Attribute<?> attr : getArtifact().getAttributes(REVIEW_STORAGE_TYPE)) {
+ DefectItem dbPromoteItem = new DefectItem((String) attr.getValue());
+ if (dbPromoteItem.equals(delPromoteItem)) {
+ attr.delete();
+ }
+ }
+ }
+ // Add new ones: items in promoteItems that are not in dbPromoteItems
+ for (DefectItem newPromoteItem : org.eclipse.osee.framework.jdk.core.util.Collections.setComplement(
+ defectItems, dbPromoteItems)) {
+ getArtifact().addAttributeFromString(REVIEW_STORAGE_TYPE,
+ AXml.addTagData(DEFECT_ITEM_TAG, newPromoteItem.toXml()));
+ }
+ if (persist) {
+ getArtifact().persist(transaction);
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't create ats review defect document", ex);
+ }
+ }
+
+ public void addOrUpdateDefectItem(DefectItem defectItem, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ Set<DefectItem> defectItems = getDefectItems();
+ boolean found = false;
+ for (DefectItem dItem : defectItems) {
+ if (defectItem.equals(dItem)) {
+ dItem.update(defectItem);
+ found = true;
+ }
+ }
+ if (!found) {
+ defectItems.add(defectItem);
+ }
+ saveDefectItems(defectItems, persist, transaction);
+ }
+
+ public void removeDefectItem(DefectItem defectItem, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ Set<DefectItem> defectItems = getDefectItems();
+ defectItems.remove(defectItem);
+ saveDefectItems(defectItems, persist, transaction);
+ }
+
+ public void addDefectItem(String description, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ DefectItem item = new DefectItem();
+ item.setDescription(description);
+ addOrUpdateDefectItem(item, persist, transaction);
+ }
+
+ public String getTable() throws OseeCoreException {
+ StringBuilder builder = new StringBuilder();
+ builder.append("<TABLE BORDER=\"1\" cellspacing=\"1\" cellpadding=\"3%\" width=\"100%\"><THEAD><TR><TH>Severity</TH>" + "<TH>Disposition</TH><TH>Injection</TH><TH>User</TH><TH>Date</TH><TH>Description</TH><TH>Location</TH>" + "<TH>Resolution</TH><TH>Guid</TH><TH>Completed</TH></THEAD></TR>");
+ for (DefectItem item : getDefectItems()) {
+ User user = item.getUser();
+ builder.append("<TR>");
+ builder.append("<TD>" + item.getSeverity() + "</TD>");
+ builder.append("<TD>" + item.getDisposition() + "</TD>");
+ builder.append("<TD>" + item.getInjectionActivity() + "</TD>");
+ if (user != null && user.equals(UserManager.getUser())) {
+ builder.append("<TD bgcolor=\"#CCCCCC\">" + user.getName() + "</TD>");
+ } else {
+ builder.append("<TD>NONE</TD>");
+ }
+ builder.append("<TD>" + DateUtil.getMMDDYYHHMM(item.getDate()) + "</TD>");
+ builder.append("<TD>" + item.getDescription() + "</TD>");
+ builder.append("<TD>" + item.getLocation() + "</TD>");
+ builder.append("<TD>" + item.getResolution() + "</TD>");
+ builder.append("<TD>" + item.getGuid() + "</TD>");
+ builder.append("<TD>" + item.isClosed() + "</TD>");
+ builder.append("</TR>");
+
+ }
+ builder.append("</TABLE>");
+ return builder.toString();
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/Role.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/Role.java
new file mode 100644
index 00000000000..1c822efa70f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/Role.java
@@ -0,0 +1,18 @@
+package org.eclipse.osee.ats.core.review.role;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public enum Role {
+ Moderator,
+ Reviewer,
+ Author;
+ public static Collection<String> strValues() {
+ Set<String> values = new HashSet<String>();
+ for (Enum<Role> e : values()) {
+ values.add(e.name());
+ }
+ return values;
+ }
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRole.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRole.java
new file mode 100644
index 00000000000..46377fde16e
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRole.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review.role;
+
+import java.text.NumberFormat;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class UserRole {
+
+ private Role role = Role.Reviewer;
+ private User user;
+ private Double hoursSpent = null;
+ private String guid = GUID.create();
+ private Boolean completed = false;
+
+ public UserRole() throws OseeCoreException {
+ this(Role.Reviewer, UserManager.getUser(), null, false);
+ }
+
+ public UserRole(Role role, User user) {
+ this(role, user, 0.0, false);
+ }
+
+ public UserRole(Role role, User user, Double hoursSpent, Boolean completed) {
+ this.role = role;
+ this.user = user;
+ this.hoursSpent = hoursSpent;
+ this.completed = completed;
+ }
+
+ public UserRole(String xml) {
+ fromXml(xml);
+ }
+
+ public void update(UserRole dItem) throws OseeCoreException {
+ fromXml(dItem.toXml());
+ }
+
+ public String toXml() throws OseeCoreException {
+ StringBuffer sb = new StringBuffer();
+ sb.append(AXml.addTagData("role", role.name()));
+ sb.append(AXml.addTagData("userId", user.getUserId()));
+ sb.append(AXml.addTagData("hoursSpent", hoursSpent == null ? "" : String.valueOf(hoursSpent)));
+ sb.append(AXml.addTagData("completed", String.valueOf(completed)));
+ sb.append(AXml.addTagData("guid", guid));
+ return sb.toString();
+ }
+
+ public void fromXml(String xml) {
+ try {
+ this.role = Role.valueOf(AXml.getTagData(xml, "role"));
+ this.user = UserManager.getUserByUserId(AXml.getTagData(xml, "userId"));
+ String hoursSpent = AXml.getTagData(xml, "hoursSpent");
+ if (Strings.isValid(hoursSpent)) {
+ this.hoursSpent = NumberFormat.getInstance().parse(hoursSpent).doubleValue();
+ } else {
+ this.hoursSpent = null;
+ }
+ String completedStr = AXml.getTagData(xml, "completed");
+ if (Strings.isValid(completedStr)) {
+ this.completed = completedStr.equals("true");
+ } else {
+ this.completed = false;
+ }
+ this.guid = AXml.getTagData(xml, "guid");
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof UserRole) {
+ UserRole userRole = (UserRole) obj;
+ return userRole.getGuid().equals(getGuid());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return getGuid().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return role + " - " + user + " - " + hoursSpent + " - " + (completed ? "Completed" : "InWork");
+ }
+
+ /**
+ * @return the role
+ */
+ public Role getRole() {
+ return role;
+ }
+
+ /**
+ * @param role the role to set
+ */
+ public void setRole(Role role) {
+ this.role = role;
+ }
+
+ /**
+ * @return the user
+ */
+ public User getUser() {
+ return user;
+ }
+
+ /**
+ * @param user the user to set
+ */
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ /**
+ * @return the hoursSpent
+ */
+ public Double getHoursSpent() {
+ return hoursSpent;
+ }
+
+ public String getHoursSpentStr() {
+ return hoursSpent == null ? "" : AtsUtilCore.doubleToI18nString(hoursSpent, true);
+ }
+
+ /**
+ * @param hoursSpent the hoursSpent to set
+ */
+ public void setHoursSpent(Double hoursSpent) {
+ this.hoursSpent = hoursSpent;
+ }
+
+ /**
+ * @return the guid
+ */
+ public String getGuid() {
+ return guid;
+ }
+
+ /**
+ * @param guid the guid to set
+ */
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+ /**
+ * @return the completed
+ */
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ /**
+ * @param completed the completed to set
+ */
+ public void setCompleted(boolean completed) {
+ this.completed = completed;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleError.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleError.java
new file mode 100644
index 00000000000..8a6247f3226
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleError.java
@@ -0,0 +1,33 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.review.role;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum UserRoleError {
+
+ None(""),
+ OneRoleEntryRequired("At least one role entry is required."),
+ ExceptionValidatingRoles("Exception validating roles. See log for details."),
+ MustHaveAtLeastOneAuthor("Must have at least one Author"),
+ MustHaveAtLeastOneReviewer("Must have at least one Reviewer"),
+ HoursSpentMustBeEnteredForEachRole("Hours spent must be entered for each role.");
+
+ private final String error;
+
+ private UserRoleError(String error) {
+ this.error = error;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public boolean isOK() {
+ return this == None;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleManager.java
new file mode 100644
index 00000000000..4805afd407a
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleManager.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.review.role;
+
+import java.lang.ref.WeakReference;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.AbstractReviewArtifact;
+import org.eclipse.osee.ats.core.review.IReviewArtifact;
+import org.eclipse.osee.ats.core.review.defect.DefectItem;
+import org.eclipse.osee.ats.core.review.defect.DefectItem.Severity;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.jdk.core.util.AHTML;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Attribute;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class UserRoleManager {
+
+ private final WeakReference<AbstractReviewArtifact> artifactRef;
+ private boolean enabled = true;
+ private final static String ROLE_ITEM_TAG = "Role";
+ private static final IAttributeType ATS_ROLE_STORAGE_TYPE = AtsAttributeTypes.Role;
+
+ private final Matcher roleMatcher = java.util.regex.Pattern.compile(
+ "<" + ROLE_ITEM_TAG + ">(.*?)</" + ROLE_ITEM_TAG + ">", Pattern.DOTALL | Pattern.MULTILINE).matcher("");
+
+ public UserRoleManager(AbstractReviewArtifact artifact) {
+ this.artifactRef = new WeakReference<AbstractReviewArtifact>(artifact);
+ }
+
+ public String getHtml() throws OseeCoreException {
+ if (getUserRoles().isEmpty()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.append(AHTML.addSpace(1) + AHTML.getLabelStr(AHTML.LABEL_FONT, "Defects"));
+ sb.append(getTable());
+ return sb.toString();
+ }
+
+ public AbstractReviewArtifact getArtifact() throws OseeStateException {
+ if (artifactRef.get() == null) {
+ throw new OseeStateException("Artifact has been garbage collected");
+ }
+ return artifactRef.get();
+ }
+
+ public Set<UserRole> getUserRoles() throws OseeCoreException {
+ Set<UserRole> roles = new HashSet<UserRole>();
+ for (String xml : getArtifact().getAttributesToStringList(ATS_ROLE_STORAGE_TYPE)) {
+ roleMatcher.reset(xml);
+ while (roleMatcher.find()) {
+ UserRole item = new UserRole(roleMatcher.group());
+ roles.add(item);
+ }
+ }
+ return roles;
+ }
+
+ public Set<UserRole> getRoleUsersReviewComplete() throws OseeCoreException {
+ Set<UserRole> cRoles = new HashSet<UserRole>();
+ for (UserRole role : getUserRoles(Role.Reviewer)) {
+ if (role.isCompleted()) {
+ cRoles.add(role);
+ }
+ }
+ return cRoles;
+ }
+
+ public Set<User> getRoleUsersAuthorModerator() throws OseeCoreException {
+ Set<User> roles = getRoleUsers(Role.Author);
+ if (roles.isEmpty()) {
+ roles = getRoleUsers(Role.Moderator);
+ roles.add(UserManager.getUser());
+ }
+
+ return roles;
+ }
+
+ public Set<UserRole> getUserRoles(Role role) throws OseeCoreException {
+ Set<UserRole> roles = new HashSet<UserRole>();
+ for (UserRole uRole : getUserRoles()) {
+ if (uRole.getRole() == role) {
+ roles.add(uRole);
+ }
+ }
+ return roles;
+ }
+
+ public Set<User> getRoleUsers(Role role) throws OseeCoreException {
+ Set<User> users = new HashSet<User>();
+ for (UserRole uRole : getUserRoles()) {
+ if (uRole.getRole() == role) {
+ users.add(uRole.getUser());
+ }
+ }
+ return users;
+ }
+
+ private void saveRoleItems(Set<UserRole> defectItems, boolean persist, SkynetTransaction transaction) {
+ try {
+ // Change existing ones
+ for (Attribute<?> attr : getArtifact().getAttributes(ATS_ROLE_STORAGE_TYPE)) {
+ UserRole dbPromoteItem = new UserRole((String) attr.getValue());
+ for (UserRole pItem : defectItems) {
+ if (pItem.equals(dbPromoteItem)) {
+ attr.setFromString(AXml.addTagData(ROLE_ITEM_TAG, pItem.toXml()));
+ }
+ }
+ }
+ Set<UserRole> dbPromoteItems = getUserRoles();
+ // Remove deleted ones; items in dbPromoteItems that are not in promoteItems
+ for (UserRole delPromoteItem : org.eclipse.osee.framework.jdk.core.util.Collections.setComplement(
+ dbPromoteItems, defectItems)) {
+ for (Attribute<?> attr : getArtifact().getAttributes(ATS_ROLE_STORAGE_TYPE)) {
+ UserRole dbPromoteItem = new UserRole((String) attr.getValue());
+ if (dbPromoteItem.equals(delPromoteItem)) {
+ attr.delete();
+ }
+ }
+ }
+ // Add new ones: items in promoteItems that are not in dbPromoteItems
+ for (UserRole newPromoteItem : org.eclipse.osee.framework.jdk.core.util.Collections.setComplement(defectItems,
+ dbPromoteItems)) {
+ getArtifact().addAttributeFromString(ATS_ROLE_STORAGE_TYPE,
+ AXml.addTagData(ROLE_ITEM_TAG, newPromoteItem.toXml()));
+ }
+ updateAssignees();
+ if (persist) {
+ getArtifact().persist(transaction);
+ }
+ rollupHoursSpentToReviewState(persist, transaction);
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't create ats review role document", ex);
+ }
+ }
+
+ public void addOrUpdateUserRole(UserRole userRole, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ Set<UserRole> roleItems = getUserRoles();
+ boolean found = false;
+ for (UserRole uRole : roleItems) {
+ if (userRole.equals(uRole)) {
+ uRole.update(userRole);
+ found = true;
+ }
+ }
+ if (!found) {
+ roleItems.add(userRole);
+ }
+ saveRoleItems(roleItems, persist, transaction);
+ }
+
+ private void updateAssignees() throws OseeCoreException {
+ // Set assignees based on roles that are not set as completed
+ Set<User> assignees = new HashSet<User>();
+ for (UserRole uRole : getUserRoles()) {
+ if (!uRole.isCompleted() && uRole.getUser() != null) {
+ assignees.add(uRole.getUser());
+ }
+ }
+ // If roles are all completed, then still need to select a user to assign to SMA
+ if (assignees.isEmpty()) {
+ if (getUserRoles(Role.Author).size() > 0) {
+ for (UserRole role : getUserRoles(Role.Author)) {
+ assignees.add(role.getUser());
+ }
+ } else if (getUserRoles(Role.Moderator).size() > 0) {
+ for (UserRole role : getUserRoles(Role.Moderator)) {
+ assignees.add(role.getUser());
+ }
+ } else {
+ assignees.add(UserManager.getUser());
+ }
+ }
+ // Set assignees based on roles
+ getArtifact().getStateMgr().setAssignees(assignees);
+ }
+
+ public void removeUserRole(UserRole userRole, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ Set<UserRole> roleItems = getUserRoles();
+ roleItems.remove(userRole);
+ saveRoleItems(roleItems, persist, transaction);
+ }
+
+ public String getTable() throws OseeCoreException {
+ StringBuilder builder = new StringBuilder();
+ builder.append("<TABLE BORDER=\"1\" cellspacing=\"1\" cellpadding=\"3%\" width=\"100%\"><THEAD><TR><TH>Role</TH>" + "<TH>User</TH><TH>Hours</TH><TH>Major</TH><TH>Minor</TH><TH>Issues</TH>");
+ for (UserRole item : getUserRoles()) {
+ User user = item.getUser();
+ String name = "";
+ if (user != null) {
+ name = user.getName();
+ if (!Strings.isValid(name)) {
+ name = user.getName();
+ }
+ }
+ builder.append("<TR>");
+ builder.append("<TD>" + item.getRole().name() + "</TD>");
+ builder.append("<TD>" + item.getUser().getName() + "</TD>");
+ builder.append("<TD>" + item.getHoursSpentStr() + "</TD>");
+ builder.append("<TD>" + getNumMajor(item.getUser()) + "</TD>");
+ builder.append("<TD>" + getNumMinor(item.getUser()) + "</TD>");
+ builder.append("<TD>" + getNumIssues(item.getUser()) + "</TD>");
+ builder.append("</TR>");
+ }
+ builder.append("</TABLE>");
+ return builder.toString();
+ }
+
+ public int getNumMajor(User user) throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : ((IReviewArtifact) getArtifact()).getDefectManager().getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Major && dItem.getUser() == user) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ public int getNumMinor(User user) throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : ((IReviewArtifact) getArtifact()).getDefectManager().getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Minor && dItem.getUser() == user) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ public int getNumIssues(User user) throws OseeCoreException {
+ int x = 0;
+ for (DefectItem dItem : ((IReviewArtifact) getArtifact()).getDefectManager().getDefectItems()) {
+ if (dItem.getSeverity() == Severity.Issue && dItem.getUser() == user) {
+ x++;
+ }
+ }
+ return x;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public void rollupHoursSpentToReviewState(boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ double hoursSpent = 0.0;
+ for (UserRole role : getUserRoles()) {
+ hoursSpent += role.getHoursSpent() == null ? 0 : role.getHoursSpent();
+ }
+ AbstractWorkflowArtifact awa = getArtifact();
+ awa.getStateMgr().setMetrics(hoursSpent, awa.getStateMgr().getPercentComplete(), true, UserManager.getUser(),
+ new Date());
+ if (persist) {
+ getArtifact().persist(transaction);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleValidator.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleValidator.java
new file mode 100644
index 00000000000..8aa4a29e8ed
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/review/role/UserRoleValidator.java
@@ -0,0 +1,62 @@
+/*
+ * Created on May 10, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.review.role;
+
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.PeerToPeerReviewArtifact;
+import org.eclipse.osee.ats.core.review.PeerToPeerReviewState;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class UserRoleValidator {
+
+ public static UserRoleError isValid(Artifact artifact) {
+ try {
+ if (artifact.isOfType(AtsArtifactTypes.PeerToPeerReview)) {
+ if (artifact.getAttributeCount(AtsAttributeTypes.Role) == 0) {
+ return UserRoleError.OneRoleEntryRequired;
+ }
+ UserRoleError result = isUserRoleValid(artifact, UserRoleValidator.class.getSimpleName());
+ if (!result.isOK()) {
+ return result;
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return UserRoleError.ExceptionValidatingRoles;
+ }
+ return UserRoleError.None;
+ }
+
+ private static UserRoleError isUserRoleValid(Artifact artifact, String namespace) throws OseeCoreException {
+ if (artifact instanceof PeerToPeerReviewArtifact) {
+ PeerToPeerReviewArtifact peerToPeerReviewArtifact = (PeerToPeerReviewArtifact) artifact;
+ if (peerToPeerReviewArtifact.getUserRoleManager().getUserRoles(Role.Author).size() <= 0) {
+ return UserRoleError.MustHaveAtLeastOneAuthor;
+ }
+ if (peerToPeerReviewArtifact.getUserRoleManager().getUserRoles(Role.Reviewer).size() <= 0) {
+ return UserRoleError.MustHaveAtLeastOneReviewer;
+ }
+ // If in review state, all roles must have hours spent entered
+ if (peerToPeerReviewArtifact.isInState(PeerToPeerReviewState.Review) || peerToPeerReviewArtifact.isInState(PeerToPeerReviewState.Meeting)) {
+ for (UserRole uRole : peerToPeerReviewArtifact.getUserRoleManager().getUserRoles()) {
+ if (uRole.getHoursSpent() == null) {
+ return UserRoleError.HoursSpentMustBeEnteredForEachRole;
+ }
+ }
+ }
+ }
+ return UserRoleError.None;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/AbstractTaskableArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/AbstractTaskableArtifact.java
new file mode 100644
index 00000000000..738c09b9880
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/AbstractTaskableArtifact.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.task;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsCacheManager;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.PercentCompleteTotalUtil;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactTypeManager;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class AbstractTaskableArtifact extends AbstractWorkflowArtifact {
+
+ public AbstractTaskableArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ registerAtsWorldRelation(AtsRelationTypes.SmaToTask_Task);
+ }
+
+ @Override
+ public void getSmaArtifactsOneLevel(AbstractWorkflowArtifact smaArtifact, Set<Artifact> artifacts) throws OseeCoreException {
+ super.getSmaArtifactsOneLevel(smaArtifact, artifacts);
+ artifacts.addAll(getTaskArtifacts());
+ }
+
+ @Override
+ public void atsDelete(Set<Artifact> deleteArts, Map<Artifact, Object> allRelated) throws OseeCoreException {
+ super.atsDelete(deleteArts, allRelated);
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ taskArt.atsDelete(deleteArts, allRelated);
+ }
+ }
+
+ @Override
+ public void transitioned(StateDefinition fromState, StateDefinition toState, Collection<User> toAssignees, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ super.transitioned(fromState, toState, toAssignees, persist, transaction);
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ taskArt.parentWorkFlowTransitioned(fromState, toState, toAssignees, persist, transaction);
+ }
+ }
+
+ public Collection<TaskArtifact> getTaskArtifacts() throws OseeCoreException {
+ return AtsCacheManager.getTaskArtifacts(this);
+ }
+
+ public Collection<TaskArtifact> getTaskArtifactsSorted() throws OseeCoreException {
+ return AtsCacheManager.getTaskArtifacts(this);
+ }
+
+ public Collection<TaskArtifact> getTaskArtifactsFromCurrentState() throws OseeCoreException {
+ return getTaskArtifacts(getStateMgr().getCurrentState());
+ }
+
+ public Collection<TaskArtifact> getTaskArtifacts(IWorkPage state) throws OseeCoreException {
+ List<TaskArtifact> arts = new ArrayList<TaskArtifact>();
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ if (taskArt.getSoleAttributeValue(AtsAttributeTypes.RelatedToState, "").equals(state.getPageName())) {
+ arts.add(taskArt);
+ }
+ }
+ return arts;
+ }
+
+ public boolean hasTaskArtifacts() {
+ return getRelatedArtifactsCount(AtsRelationTypes.SmaToTask_Task) > 0;
+ }
+
+ public TaskArtifact createNewTask(String title, Date createdDate, User createdBy) throws OseeCoreException {
+ return createNewTask(Arrays.asList(UserManager.getUser()), title, createdDate, createdBy);
+ }
+
+ public TaskArtifact createNewTask(Collection<User> assignees, String title, Date createdDate, User createdBy) throws OseeCoreException {
+ TaskArtifact taskArt = null;
+ taskArt =
+ (TaskArtifact) ArtifactTypeManager.addArtifact(AtsArtifactTypes.Task, AtsUtilCore.getAtsBranch(), title);
+
+ addRelation(AtsRelationTypes.SmaToTask_Task, taskArt);
+ taskArt.initializeNewStateMachine(assignees, new Date(), UserManager.getUser());
+
+ // Set parent state task is related to
+ taskArt.setSoleAttributeValue(AtsAttributeTypes.RelatedToState, getStateMgr().getCurrentStateName());
+
+ return taskArt;
+ }
+
+ public Result areTasksComplete() {
+ try {
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ if (taskArt.isInWork()) {
+ return new Result(false, "Task " + taskArt.getGuid() + " Not Complete");
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return new Result(false, "Exception " + ex.getLocalizedMessage());
+ }
+ return Result.TrueResult;
+ }
+
+ public Result areTasksComplete(IWorkPage state) {
+ try {
+ for (TaskArtifact taskArt : getTaskArtifacts(state)) {
+ if (taskArt.isInWork()) {
+ return new Result(false, "Task " + taskArt.getGuid() + " Not Complete");
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return new Result(false, "Exception " + ex.getLocalizedMessage());
+ }
+ return Result.TrueResult;
+ }
+
+ public int getNumTasksInWork() {
+ int num = 0;
+ try {
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ if (taskArt.isInWork()) {
+ num++;
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return num;
+ }
+
+ /**
+ * Return Estimated Task Hours of "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ * @return Returns the Estimated Hours
+ */
+ @Override
+ public double getEstimatedHoursFromTasks(IWorkPage relatedToState) throws OseeCoreException {
+ double hours = 0;
+ for (TaskArtifact taskArt : getTaskArtifacts(relatedToState)) {
+ hours += taskArt.getEstimatedHoursTotal();
+ }
+ return hours;
+ }
+
+ /**
+ * Return Estimated Hours for all tasks
+ */
+ @Override
+ public double getEstimatedHoursFromTasks() throws OseeCoreException {
+ double hours = 0;
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ hours += taskArt.getEstimatedHoursFromArtifact();
+ }
+ return hours;
+
+ }
+
+ /**
+ * Return Remain Task Hours of "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ * @return Returns the Remain Hours
+ */
+ public double getRemainHoursFromTasks(IWorkPage relatedToState) throws OseeCoreException {
+ double hours = 0;
+ for (TaskArtifact taskArt : getTaskArtifacts(relatedToState)) {
+ hours += taskArt.getRemainHoursFromArtifact();
+ }
+ return hours;
+ }
+
+ /**
+ * Return Remain Hours for all tasks
+ */
+ public double getRemainHoursFromTasks() throws OseeCoreException {
+ double hours = 0;
+ for (TaskArtifact taskArt : getTaskArtifacts()) {
+ hours += taskArt.getRemainHoursFromArtifact();
+ }
+ return hours;
+
+ }
+
+ /**
+ * Return Total Percent Complete / # Tasks for "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ * @return Returns the Percent Complete.
+ */
+ public int getPercentCompleteFromTasks(IWorkPage relatedToState) throws OseeCoreException {
+ int spent = 0;
+ Collection<TaskArtifact> taskArts = getTaskArtifacts(relatedToState);
+ for (TaskArtifact taskArt : taskArts) {
+ spent += PercentCompleteTotalUtil.getPercentCompleteTotal(taskArt);
+ }
+ if (spent == 0) {
+ return 0;
+ }
+ return spent / taskArts.size();
+ }
+
+ public Collection<TaskArtifact> createTasks(List<String> titles, List<User> assignees, Date createdDate, User createdBy, SkynetTransaction transaction) throws OseeCoreException {
+ List<TaskArtifact> tasks = new ArrayList<TaskArtifact>();
+ for (String title : titles) {
+ TaskArtifact taskArt = createNewTask(title, createdDate, createdBy);
+ if (assignees != null && !assignees.isEmpty()) {
+ Set<User> users = new HashSet<User>(); // NOPMD by b0727536 on 9/29/10 8:51 AM
+ for (User art : assignees) {
+ users.add(art);
+ }
+ taskArt.getStateMgr().setAssignees(users);
+ }
+ tasks.add(taskArt);
+ taskArt.persist(transaction);
+ }
+ return tasks;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskArtifact.java
new file mode 100644
index 00000000000..4c635fa358f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskArtifact.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.task;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.EstimatedHoursUtil;
+import org.eclipse.osee.ats.core.workflow.PercentCompleteTotalUtil;
+import org.eclipse.osee.ats.core.workflow.StateManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionOption;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.IATSStateMachineArtifact;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TaskArtifact extends AbstractWorkflowArtifact implements IATSStateMachineArtifact {
+
+ public TaskArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ public boolean isRelatedToParentWorkflowCurrentState() throws OseeCoreException {
+ return getSoleAttributeValueAsString(AtsAttributeTypes.RelatedToState, "").equals(
+ getParentAWA().getStateMgr().getCurrentStateName());
+ }
+
+ public boolean isUsingTaskResolutionOptions() throws OseeCoreException {
+ return getTaskResolutionOptionDefintions().size() > 0;
+ }
+
+ public List<TaskResOptionDefinition> getTaskResolutionOptionDefintions() throws OseeCoreException {
+ TeamWorkFlowArtifact team = getParentTeamWorkflow();
+ if (team == null) {
+ return TaskResolutionOptionRule.EMPTY_TASK_RESOLUTION_OPTIONS;
+ }
+ return TaskResolutionOptionRule.getTaskResolutionOptions(team.getStateDefinition());
+ }
+
+ public TaskResOptionDefinition getTaskResolutionOptionDefinition(String optionName) throws OseeCoreException {
+ for (TaskResOptionDefinition def : getTaskResolutionOptionDefintions()) {
+ if (def.getName().equals(optionName)) {
+ return def;
+ }
+ }
+ return null;
+ }
+
+ public List<TaskResOptionDefinition> getTaskResolutionOptionDefintions(String stateName) throws OseeCoreException {
+ TeamWorkFlowArtifact team = getParentTeamWorkflow();
+ if (team == null) {
+ return TaskResolutionOptionRule.EMPTY_TASK_RESOLUTION_OPTIONS;
+ }
+ return TaskResolutionOptionRule.getTaskResolutionOptions(team.getStateDefinitionByName(stateName));
+ }
+
+ public TaskResOptionDefinition getTaskResolutionOptionDefinition(String stateName, String optionName) throws OseeCoreException {
+ for (TaskResOptionDefinition def : getTaskResolutionOptionDefintions(stateName)) {
+ if (def.getName().equals(optionName)) {
+ return def;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ try {
+ return getSoleAttributeValue(AtsAttributeTypes.Description, "");
+ } catch (Exception ex) {
+ return "Error: " + ex.getLocalizedMessage();
+ }
+ }
+
+ public Result transitionToCompleted(double additionalHours, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ if (isInState(TeamState.Completed)) {
+ return Result.TrueResult;
+ }
+ // Assign current user if unassigned
+ try {
+ if (getStateMgr().isUnAssigned()) {
+ getStateMgr().setAssignee(UserManager.getUser());
+ }
+ getStateMgr().updateMetrics(additionalHours, 100, true);
+ setSoleAttributeValue(AtsAttributeTypes.PercentComplete, 100);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ TransitionManager transitionMgr = new TransitionManager(this);
+ Result result = transitionMgr.transition(TaskStates.Completed, (User) null, transaction, transitionOption);
+ return result;
+ }
+
+ public Result transitionToInWork(User toUser, int percentComplete, double additionalHours, SkynetTransaction transaction, TransitionOption... transitionOption) throws OseeCoreException {
+ if (isInState(TaskStates.InWork)) {
+ return Result.TrueResult;
+ }
+ TransitionManager transitionMgr = new TransitionManager(this);
+ Result result = transitionMgr.transition(TaskStates.InWork, toUser, transaction, transitionOption);
+ if (getStateMgr().getPercentComplete() != percentComplete || additionalHours > 0) {
+ getStateMgr().updateMetrics(additionalHours, percentComplete, true);
+ setSoleAttributeValue(AtsAttributeTypes.PercentComplete, percentComplete);
+ }
+ if (Collections.getAggregate(transitionOption).contains(TransitionOption.Persist)) {
+ saveSMA(transaction);
+ }
+ return result;
+ }
+
+ /**
+ * Tasks must transition in/out of completed when percent changes between 100 and <100. This method will handle these
+ * cases.
+ */
+ public Result statusPercentChanged(double additionalHours, int percentComplete, SkynetTransaction transaction) throws OseeCoreException {
+ if (percentComplete == 100 && !isCompleted()) {
+ Result result = transitionToCompleted(additionalHours, transaction, TransitionOption.None);
+ return result;
+ } else if (percentComplete != 100 && isCompleted()) {
+ Result result =
+ transitionToInWork(UserManager.getUser(), percentComplete, additionalHours, transaction,
+ TransitionOption.Persist);
+ return result;
+ }
+ // Case where already completed and statusing, just add additional hours to InWork state
+ else if (percentComplete == 100 && isCompleted()) {
+ if (additionalHours > 0) {
+ getStateMgr().updateMetrics(TaskStates.InWork, additionalHours, percentComplete, true);
+ setSoleAttributeValue(AtsAttributeTypes.PercentComplete, percentComplete);
+ }
+ } else {
+ getStateMgr().updateMetrics(additionalHours, percentComplete, true);
+ setSoleAttributeValue(AtsAttributeTypes.PercentComplete, percentComplete);
+ }
+ return Result.TrueResult;
+ }
+
+ public Result parentWorkFlowTransitioned(StateDefinition fromState, StateDefinition toState, Collection<User> toAssignees, boolean persist, SkynetTransaction transaction, TransitionOption... transitionOption) throws OseeCoreException {
+ if (toState.getPageName().equals(TeamState.Cancelled.getPageName()) && isInWork()) {
+ TransitionManager transitionMgr = new TransitionManager(this);
+ Result result = transitionMgr.transitionToCancelled("Parent Cancelled", transaction, transitionOption);
+ return result;
+ } else if (fromState.getPageName().equals(TeamState.Cancelled.getPageName()) && isCancelled()) {
+ Result result = transitionToInWork(UserManager.getUser(), 99, 0, transaction, transitionOption);
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ @Override
+ public double getManHrsPerDayPreference() throws OseeCoreException {
+ return getParentAWA().getManHrsPerDayPreference();
+ }
+
+ @Override
+ public AbstractWorkflowArtifact getParentAWA() throws OseeCoreException {
+ if (parentAwa != null) {
+ return parentAwa;
+ }
+ Collection<AbstractWorkflowArtifact> awas =
+ getRelatedArtifacts(AtsRelationTypes.SmaToTask_Sma, AbstractWorkflowArtifact.class);
+ if (awas.isEmpty()) {
+ throw new OseeStateException("Task has no parent [%s]", getHumanReadableId());
+ }
+ parentAwa = awas.iterator().next();
+ return parentAwa;
+ }
+
+ @Override
+ public Artifact getParentActionArtifact() throws OseeCoreException {
+ if (parentAction != null) {
+ return parentAction;
+ }
+ parentAction = getParentTeamWorkflow().getParentActionArtifact();
+ return parentAction;
+ }
+
+ @Override
+ public TeamWorkFlowArtifact getParentTeamWorkflow() throws OseeCoreException {
+ if (parentTeamArt != null) {
+ return parentTeamArt;
+ }
+ AbstractWorkflowArtifact awa = getParentAWA();
+ if (awa.isTeamWorkflow()) {
+ parentTeamArt = (TeamWorkFlowArtifact) awa;
+ }
+ return parentTeamArt;
+ }
+
+ @Override
+ public Collection<User> getImplementers() throws OseeCoreException {
+ return StateManager.getImplementersByState(this, TaskStates.InWork);
+ }
+
+ @Override
+ public double getWorldViewWeeklyBenefit() {
+ return 0;
+ }
+
+ @Override
+ public String getWorldViewSWEnhancement() throws OseeCoreException {
+ AbstractWorkflowArtifact awa = getParentAWA();
+ if (awa != null) {
+ return awa.getWorldViewSWEnhancement();
+ }
+ return "";
+ }
+
+ @Override
+ public double getRemainHoursFromArtifact() throws OseeCoreException {
+ if (isCompleted() || isCancelled()) {
+ return 0;
+ }
+ double est = EstimatedHoursUtil.getEstimatedHours(this);
+ if (PercentCompleteTotalUtil.getPercentCompleteTotal(this) == 0) {
+ return est;
+ }
+ double percent = getStateMgr().getPercentComplete(TaskStates.InWork);
+ if (percent == 0) {
+ return est;
+ }
+ return est - ((est * percent) / 100.0);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResOptionDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResOptionDefinition.java
new file mode 100644
index 00000000000..921922d3f3f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResOptionDefinition.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.task;
+
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TaskResOptionDefinition {
+
+ private String name;
+ private String desc;
+ private boolean completeable;
+ private String color;
+ private String percent;
+ public final static String ATS_TASK_OPTION_TAG = "AtsTaskOption";
+
+ public TaskResOptionDefinition() {
+ name = "";
+ desc = "";
+ percent = "";
+ completeable = false;
+ }
+
+ /**
+ * @param completeable true/false of whether option allows task to be transitioned to complete
+ */
+ public TaskResOptionDefinition(String name, String desc, String completeable, String color, String defaultPercent) {
+ this(name, desc, completeable.equals("true"), color, defaultPercent);
+ }
+
+ public TaskResOptionDefinition(String name, String desc, boolean completeable, String defaultPercent) {
+ this(name, desc, completeable, "", defaultPercent);
+ }
+
+ public void setFromElement(Element element) throws OseeCoreException {
+ for (int x = 0; x < element.getAttributes().getLength(); x++) {
+ Node node = element.getAttributes().item(x);
+ String nodeName = node.getNodeName();
+ if (nodeName.equals(Field.name.name())) {
+ name = node.getNodeValue();
+ } else if (nodeName.equals(Field.desc.name())) {
+ desc = node.getNodeValue();
+ } else if (nodeName.equals(Field.complete.name())) {
+ completeable = Boolean.parseBoolean(node.getNodeValue());
+ } else if (nodeName.equals(Field.color.name())) {
+ color = node.getNodeValue();
+ } else if (nodeName.equals(Field.percent.name())) {
+ percent = node.getNodeValue();
+ } else {
+ throw new OseeArgumentException("Unknow Task Resolution Option Attribute [%s]", nodeName);
+ }
+ }
+ }
+
+ /**
+ * @param completeable true if option allows task to be transitioned to complete
+ * @param color BLUE, RED, etc...; "" for black
+ */
+ public TaskResOptionDefinition(String name, String desc, boolean completeable, String color, String defaultPercent) {
+ this.name = name;
+ this.desc = desc;
+ this.completeable = completeable;
+ this.color = color;
+ this.percent = defaultPercent;
+ }
+
+ /**
+ * @return true if resolution option allows task to be transitioned to complete
+ */
+ public boolean isCompleteable() {
+ return completeable;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private enum Field {
+ name,
+ desc,
+ complete,
+ percent,
+ color
+ };
+
+ public void setFromXml(String xml) throws OseeCoreException {
+ for (Field field : Field.values()) {
+ String data = AXml.getTagData(xml, field.name());
+ if (field == Field.name) {
+ setName(data);
+ } else if (field == Field.color) {
+ setColor(data);
+ } else if (field == Field.desc) {
+ setDesc(data);
+ } else if (field == Field.percent) {
+ setPercent(data);
+ } else if (field == Field.complete) {
+ setComplete(data.equals("true"));
+ } else {
+ throw new OseeArgumentException("Unexpected field");
+ }
+ }
+ }
+
+ public String toXml() throws OseeCoreException {
+ StringBuffer sb = new StringBuffer("<" + ATS_TASK_OPTION_TAG + ">");
+ for (Field field : Field.values()) {
+ String str = "";
+ if (field == Field.name) {
+ str = getName();
+ } else if (field == Field.color) {
+ str = getColor();
+ } else if (field == Field.desc) {
+ str = getDesc();
+ } else if (field == Field.percent) {
+ str = getPercent();
+ } else if (field == Field.complete) {
+ str = isCompleteable() ? "true" : "false";
+ } else {
+ throw new OseeCoreException("Unexpected field");
+ }
+ sb.append(AXml.addTagData(field.name(), str));
+ }
+ sb.append("</" + ATS_TASK_OPTION_TAG + ">");
+ return sb.toString();
+ }
+
+ public void setComplete(boolean complete) {
+ this.completeable = complete;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String getPercent() {
+ return percent;
+ }
+
+ public void setPercent(String defaultPercent) {
+ this.percent = defaultPercent;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResolutionOptionRule.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResolutionOptionRule.java
new file mode 100644
index 00000000000..e8eaac6eddb
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskResolutionOptionRule.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.task;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.workdef.RuleDefinition;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.framework.core.enums.CoreArtifactTypes;
+import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
+import org.eclipse.osee.framework.core.exception.ArtifactDoesNotExist;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeExceptions;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.jdk.core.util.xml.Jaxp;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TaskResolutionOptionRule {
+
+ private final List<TaskResOptionDefinition> options = new ArrayList<TaskResOptionDefinition>();
+ public final static String ATS_TASK_OPTIONS_TAG = "AtsTaskOptions";
+ public final static String WORK_TYPE = "AtsTaskResolutionOptions";
+ public final static List<TaskResOptionDefinition> EMPTY_TASK_RESOLUTION_OPTIONS =
+ new ArrayList<TaskResOptionDefinition>();
+
+ public static List<TaskResOptionDefinition> getTaskResolutionOptions(StateDefinition stateDefinition) throws OseeCoreException {
+ TaskResolutionOptionRule taskResolutionOptionRule = getTaskResolutionOptionRule(stateDefinition);
+ if (taskResolutionOptionRule != null) {
+ return taskResolutionOptionRule.getOptions();
+ }
+ return EMPTY_TASK_RESOLUTION_OPTIONS;
+ }
+
+ public static TaskResolutionOptionRule getTaskResolutionOptionRule(StateDefinition stateDefinition) throws OseeCoreException {
+ List<RuleDefinition> wids = new ArrayList<RuleDefinition>();
+ for (RuleDefinition ruleDef : stateDefinition.getRules()) {
+ if (ruleDef.getName().contains("taskResolutionOptions")) {
+ wids.add(ruleDef);
+ }
+ }
+ if (wids.isEmpty()) {
+ return null;
+ }
+ RuleDefinition ruleDefinition = wids.iterator().next();
+ if (ruleDefinition != null) {
+ TaskResolutionOptionRule taskResolutionOptionRule = new TaskResolutionOptionRule();
+ taskResolutionOptionRule.fromXml(getTaskResolutionRuleXml(ruleDefinition));
+ return taskResolutionOptionRule;
+ }
+ return null;
+ }
+
+ public static String getTaskResolutionRuleXml(RuleDefinition ruleDefinition) throws OseeCoreException {
+ // If this rule was converted from WorkRuleDefinition, it will have task options
+ String xml = ruleDefinition.getWorkDataValue(ATS_TASK_OPTIONS_TAG);
+ if (Strings.isValid(xml)) {
+ return xml;
+ }
+ // Else, look for a GeneralData artifact of same name as rule to retrieve options xml string
+ Artifact artifact = null;
+ try {
+ artifact =
+ ArtifactQuery.getArtifactFromTypeAndName(CoreArtifactTypes.GeneralData, ruleDefinition.getName(),
+ AtsUtilCore.getAtsBranch());
+ return artifact.getSoleAttributeValue(CoreAttributeTypes.GeneralStringData, "");
+ } catch (ArtifactDoesNotExist ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex, "GeneralData artifact named [%s] does not exist",
+ ruleDefinition.getName());
+ }
+ return "";
+ }
+
+ public void setFromDoc(Document doc) throws OseeCoreException {
+ NodeList nodes = doc.getElementsByTagName(TaskResOptionDefinition.ATS_TASK_OPTION_TAG);
+ if (nodes.getLength() > 0) {
+ for (int x = 0; x < nodes.getLength(); x++) {
+ Element element = (Element) nodes.item(x);
+ TaskResOptionDefinition trd = new TaskResOptionDefinition();
+ trd.setFromElement(element);
+ options.add(trd);
+ }
+ }
+ }
+
+ public void fromXml(String xmlStr) throws OseeCoreException {
+ try {
+ setFromDoc(Jaxp.readXmlDocument(xmlStr));
+ } catch (Exception ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ }
+ }
+
+ public String toXml() throws OseeCoreException {
+ StringBuffer sb = new StringBuffer();
+ sb.append("<" + TaskResOptionDefinition.ATS_TASK_OPTION_TAG + ">\n");
+ for (TaskResOptionDefinition def : options) {
+ sb.append(def.toXml());
+ sb.append("\n");
+ }
+ sb.append("</");
+ sb.append(TaskResOptionDefinition.ATS_TASK_OPTION_TAG);
+ sb.append(">\n");
+ return sb.toString();
+ }
+
+ public List<TaskResOptionDefinition> getOptions() {
+ return options;
+ }
+
+ /**
+ * Return the order index number of the given option name. Used for comparisons of resolutions like < and > by
+ * getting both indexes and doing a mathmatical comparison.
+ *
+ * @return index number (starting at 1) or null if not found
+ */
+ public Integer getResolutionOptionOrderIndex(String name) {
+ int x = 1;
+ for (TaskResOptionDefinition option : options) {
+ if (option.getName().equals(name)) {
+ return x;
+ }
+ x++;
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskStates.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskStates.java
new file mode 100644
index 00000000000..12f12389bdf
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/task/TaskStates.java
@@ -0,0 +1,24 @@
+package org.eclipse.osee.ats.core.task;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.util.WorkPageAdapter;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+
+public class TaskStates extends WorkPageAdapter {
+ public static TaskStates InWork = new TaskStates("InWork", WorkPageType.Working);
+ public static TaskStates Completed = new TaskStates("Completed", WorkPageType.Completed);
+ public static TaskStates Cancelled = new TaskStates("Cancelled", WorkPageType.Cancelled);
+
+ private TaskStates(String pageName, WorkPageType workPageType) {
+ super(TaskStates.class, pageName, workPageType);
+ }
+
+ public static TaskStates valueOf(String pageName) {
+ return WorkPageAdapter.valueOfPage(TaskStates.class, pageName);
+ }
+
+ public List<TaskStates> values() {
+ return WorkPageAdapter.pages(TaskStates.class);
+ }
+
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/SimpleTeamState.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/SimpleTeamState.java
new file mode 100644
index 00000000000..442ccb5df98
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/SimpleTeamState.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.team;
+
+import org.eclipse.osee.framework.core.util.WorkPageAdapter;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+
+public class SimpleTeamState extends WorkPageAdapter {
+ private final String name;
+
+ public SimpleTeamState(String name, WorkPageType workPageType) {
+ super(SimpleTeamState.class, name, workPageType);
+ this.name = name;
+ }
+
+ @Override
+ public String getPageName() {
+ return name;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamState.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamState.java
new file mode 100644
index 00000000000..8d27fe68b57
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamState.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.team;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.util.WorkPageAdapter;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+
+public class TeamState extends WorkPageAdapter {
+ public static TeamState Endorse = new TeamState("Endorse", WorkPageType.Working);
+ public static TeamState Analyze = new TeamState("Analyze", WorkPageType.Working);
+ public static TeamState Authorize = new TeamState("Authorize", WorkPageType.Working);
+ public static TeamState Implement = new TeamState("Implement", WorkPageType.Working);
+ public static TeamState Completed = new TeamState("Completed", WorkPageType.Completed);
+ public static TeamState Cancelled = new TeamState("Cancelled", WorkPageType.Cancelled);
+
+ private TeamState(String pageName, WorkPageType workPageType) {
+ super(TeamState.class, pageName, workPageType);
+ }
+
+ public static TeamState valueOf(String pageName) {
+ return WorkPageAdapter.valueOfPage(TeamState.class, pageName);
+ }
+
+ public static List<TeamState> values() {
+ return WorkPageAdapter.pages(TeamState.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowArtifact.java
new file mode 100644
index 00000000000..efac1fe38a9
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowArtifact.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.team;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.branch.AtsBranchManagerCore;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.AbstractReviewArtifact;
+import org.eclipse.osee.ats.core.review.ReviewManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.util.AtsCacheManager;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.ActionArtifact;
+import org.eclipse.osee.ats.core.workflow.ActionArtifactRollup;
+import org.eclipse.osee.ats.core.workflow.ActionableItemManagerCore;
+import org.eclipse.osee.ats.core.workflow.StateManager;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.IATSStateMachineArtifact;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TeamWorkFlowArtifact extends AbstractTaskableArtifact implements IATSStateMachineArtifact {
+
+ private ActionableItemManagerCore actionableItemsDam;
+
+ public TeamWorkFlowArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ registerAtsWorldRelation(AtsRelationTypes.TeamWorkflowToReview_Review);
+ }
+
+ @Override
+ public void getSmaArtifactsOneLevel(AbstractWorkflowArtifact smaArtifact, Set<Artifact> artifacts) throws OseeCoreException {
+ super.getSmaArtifactsOneLevel(smaArtifact, artifacts);
+ try {
+ if (getTargetedVersion() != null) {
+ artifacts.add(getTargetedVersion());
+ }
+ artifacts.addAll(ReviewManager.getReviews(this));
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ @Override
+ public String getArtifactSuperTypeName() {
+ return "Team Workflow";
+ }
+
+ @Override
+ public void saveSMA(SkynetTransaction transaction) {
+ super.saveSMA(transaction);
+ try {
+ ActionArtifactRollup rollup = new ActionArtifactRollup(getParentActionArtifact(), transaction);
+ rollup.resetAttributesOffChildren();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't reset Action parent of children", ex);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ try {
+ return getSoleAttributeValue(AtsAttributeTypes.Description, "");
+ } catch (Exception ex) {
+ return "Error: " + ex.getLocalizedMessage();
+ }
+ }
+
+ @Override
+ public boolean isValidationRequired() throws OseeCoreException {
+ return getSoleAttributeValue(AtsAttributeTypes.ValidationRequired, false);
+ }
+
+ @Override
+ public String getEditorTitle() throws OseeCoreException {
+ try {
+ if (getTargetedVersion() != null) {
+ return getType() + ": " + "[" + getTargetedVersionStr() + "] - " + getName();
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return super.getEditorTitle();
+ }
+
+ @Override
+ public void onInitializationComplete() throws OseeCoreException {
+ super.onInitializationComplete();
+ initializeSMA();
+ }
+
+ @Override
+ protected void initializeSMA() throws OseeCoreException {
+ super.initializeSMA();
+ actionableItemsDam = new ActionableItemManagerCore(this);
+ }
+
+ public ActionableItemManagerCore getActionableItemsDam() {
+ return actionableItemsDam;
+ }
+
+ public void setTeamDefinition(TeamDefinitionArtifact tda) throws OseeCoreException {
+ this.setSoleAttributeValue(AtsAttributeTypes.TeamDefinition, tda.getGuid());
+ }
+
+ public TeamDefinitionArtifact getTeamDefinition() throws OseeCoreException, OseeCoreException {
+ String guid = this.getSoleAttributeValue(AtsAttributeTypes.TeamDefinition, "");
+ if (!Strings.isValid(guid)) {
+ throw new OseeArgumentException("TeamWorkflow [%s] has no TeamDefinition associated.", getHumanReadableId());
+ }
+ return AtsCacheManager.getTeamDefinitionArtifact(guid);
+ }
+
+ public String getTeamName() {
+ try {
+ return getTeamDefinition().getName();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return "!Error";
+ }
+ }
+
+ @Override
+ public String getType() {
+ return getTeamName() + " Workflow";
+ }
+
+ @Override
+ public void atsDelete(Set<Artifact> deleteArts, Map<Artifact, Object> allRelated) throws OseeCoreException {
+ super.atsDelete(deleteArts, allRelated);
+ for (AbstractReviewArtifact reviewArt : ReviewManager.getReviews(this)) {
+ reviewArt.atsDelete(deleteArts, allRelated);
+ }
+ }
+
+ @Override
+ public TeamWorkFlowArtifact getParentTeamWorkflow() {
+ parentTeamArt = this;
+ return parentTeamArt;
+ }
+
+ @Override
+ public Artifact getParentAtsArtifact() throws OseeCoreException {
+ return getParentActionArtifact();
+ }
+
+ @Override
+ public ActionArtifact getParentActionArtifact() throws OseeCoreException {
+ if (parentAction != null) {
+ return parentAction;
+ }
+ Collection<Artifact> arts = getRelatedArtifacts(AtsRelationTypes.ActionToWorkflow_Action);
+ if (arts.isEmpty()) {
+ throw new OseeStateException("Team [%s] has no parent Action", getGuid());
+ } else if (arts.size() > 1) {
+ throw new OseeStateException("Team [%s] has multiple parent Actions", getGuid());
+ }
+ parentAction = (ActionArtifact) arts.iterator().next();
+ return parentAction;
+ }
+
+ @Override
+ public AbstractWorkflowArtifact getParentAWA() {
+ return null;
+ }
+
+ @Override
+ public double getManHrsPerDayPreference() throws OseeCoreException {
+ try {
+ return getTeamDefinition().getManDayHrsFromItemAndChildren();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return super.getManHrsPerDayPreference();
+ }
+
+ @Override
+ public Collection<User> getImplementers() throws OseeCoreException {
+ return StateManager.getImplementersByState(this, TeamState.Implement);
+ }
+
+ @Override
+ public double getWorldViewWeeklyBenefit() throws OseeCoreException {
+ if (isAttributeTypeValid(AtsAttributeTypes.WeeklyBenefit)) {
+ return 0;
+ }
+ String value = getSoleAttributeValue(AtsAttributeTypes.WeeklyBenefit, "");
+ if (!Strings.isValid(value)) {
+ return 0;
+ }
+ return new Float(value).doubleValue();
+ }
+
+ public Branch getWorkingBranch() throws OseeCoreException {
+ return AtsBranchManagerCore.getWorkingBranch(this);
+ }
+
+ public String getBranchName() {
+ String smaTitle = getName();
+ if (smaTitle.length() > 40) {
+ smaTitle = smaTitle.substring(0, 39) + "...";
+ }
+ String typeName = TeamWorkFlowManager.getArtifactTypeShortName(this);
+ if (Strings.isValid(typeName)) {
+ return String.format("%s - %s - %s", getHumanReadableId(), typeName, smaTitle);
+ } else {
+ return String.format("%s - %s", getHumanReadableId(), smaTitle);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowManager.java
new file mode 100644
index 00000000000..bdd48c0314b
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkFlowManager.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.team;
+
+import java.util.Date;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.ITeamWorkflowProvider;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionOption;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * Methods in support of programatically transitioning the DefaultWorkFlow through it's states. Only to be used for the
+ * DefaultTeamWorkflow of Endorse->Analyze->Auth->Implement->Complete
+ *
+ * @author Donald G. Dunne
+ */
+public class TeamWorkFlowManager {
+
+ private final TeamWorkFlowArtifact teamArt;
+
+ public TeamWorkFlowManager(TeamWorkFlowArtifact teamArt) {
+ this.teamArt = teamArt;
+ }
+
+ /**
+ * Quickly transition to a state with minimal metrics and data entered. Should only be used for automated transition
+ * for things such as developmental testing and demos.
+ *
+ * @param user User to transition to OR null if should use user of current state
+ */
+ public Result transitionTo(TeamState toState, User user, boolean popup, SkynetTransaction transaction) throws OseeCoreException {
+ Date date = new Date();
+ if (teamArt.isInState(TeamState.Endorse)) {
+ Result result = processEndorseState(popup, teamArt, user, date, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ }
+ if (toState == TeamState.Analyze) {
+ return Result.TrueResult;
+ }
+
+ Result result = processAnalyzeState(popup, teamArt, user, date, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (toState == TeamState.Authorize) {
+ return Result.TrueResult;
+ }
+
+ result = processAuthorizeState(popup, teamArt, user, date, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (toState == TeamState.Implement) {
+ return Result.TrueResult;
+ }
+
+ result = transitionToState(popup, teamArt, TeamState.Completed, user, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+
+ }
+
+ private User getUserOrDefault(User user) throws OseeCoreException {
+ if (user == null) {
+ return UserManager.getUser();
+ }
+ return user;
+ }
+
+ private Result processAuthorizeState(boolean popup, TeamWorkFlowArtifact teamArt, User user, Date date, SkynetTransaction transaction) throws OseeCoreException {
+ Result result = setAuthorizeData(popup, 100, .2, getUserOrDefault(user), date);
+ if (result.isFalse()) {
+ return result;
+ }
+ result = transitionToState(popup, teamArt, TeamState.Implement, user, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ private Result processAnalyzeState(boolean popup, TeamWorkFlowArtifact teamArt, User user, Date date, SkynetTransaction transaction) throws OseeCoreException {
+ Result result = setAnalyzeData(popup, null, null, 1, 100, .2, getUserOrDefault(user), date);
+ if (result.isFalse()) {
+ return result;
+ }
+ result = transitionToState(popup, teamArt, TeamState.Authorize, user, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ private Result processEndorseState(boolean popup, TeamWorkFlowArtifact teamArt, User user, Date date, SkynetTransaction transaction) throws OseeCoreException {
+ Result result = setEndorseData(popup, null, 100, .2, getUserOrDefault(user), date);
+ if (result.isFalse()) {
+ return result;
+ }
+ result = transitionToState(popup, teamArt, TeamState.Analyze, user, transaction);
+ if (result.isFalse()) {
+ return result;
+ }
+ return Result.TrueResult;
+ }
+
+ private Result transitionToState(boolean popup, TeamWorkFlowArtifact teamArt, IWorkPage toState, User user, SkynetTransaction transaction) throws OseeCoreException {
+ TransitionManager transitionMgr = new TransitionManager(teamArt);
+ Result result =
+ transitionMgr.transition(toState,
+ (user == null ? teamArt.getStateMgr().getAssignees().iterator().next() : user), transaction,
+ TransitionOption.None);
+ return result;
+ }
+
+ public Result setEndorseData(boolean popup, String propRes, int statePercentComplete, double stateHoursSpent, User user, Date date) throws OseeCoreException {
+ if (!teamArt.isInState(TeamState.Endorse)) {
+ Result result = new Result("Action not in Endorse state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ teamArt.getStateMgr().setMetrics(TeamState.Endorse, stateHoursSpent, statePercentComplete, true, user, date);
+ return Result.TrueResult;
+ }
+
+ public Result setAnalyzeData(boolean popup, String problem, String propRes, double hourEstimate, int statePercentComplete, double stateHoursSpent, User user, Date date) throws OseeCoreException {
+ if (!teamArt.isInState(TeamState.Analyze)) {
+ Result result = new Result("Action not in Analyze state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ teamArt.setSoleAttributeValue(AtsAttributeTypes.EstimatedHours, hourEstimate);
+ teamArt.getStateMgr().setMetrics(TeamState.Analyze, stateHoursSpent, statePercentComplete, true, user, date);
+ return Result.TrueResult;
+ }
+
+ public Result setAuthorizeData(boolean popup, int statePercentComplete, double stateHoursSpent, User user, Date date) throws OseeCoreException {
+ if (!teamArt.isInState(TeamState.Authorize)) {
+ Result result = new Result("Action not in Authorize state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ teamArt.getStateMgr().setMetrics(TeamState.Authorize, stateHoursSpent, statePercentComplete, true, user, date);
+ return Result.TrueResult;
+ }
+
+ public Result setImplementData(boolean popup, String resolution, int statePercentComplete, double stateHoursSpent, User user, Date date) throws OseeCoreException {
+ if (!teamArt.isInState(TeamState.Implement)) {
+ Result result = new Result("Action not in Implement state");
+ if (result.isFalse() && popup) {
+ return result;
+ }
+ }
+ teamArt.getStateMgr().setMetrics(TeamState.Implement, stateHoursSpent, statePercentComplete, true, user, date);
+ return Result.TrueResult;
+ }
+
+ /**
+ * Assigned or computed Id that will show at the top of the editor
+ */
+ public static String getPcrId(AbstractWorkflowArtifact awa) throws OseeCoreException {
+ TeamWorkFlowArtifact teamArt = awa.getParentTeamWorkflow();
+ if (teamArt != null) {
+ for (ITeamWorkflowProvider atsTeamWorkflow : TeamWorkflowProviders.getAtsTeamWorkflowExtensions()) {
+ String pcrId = atsTeamWorkflow.getPcrId(teamArt);
+ if (Strings.isValid(pcrId)) {
+ return pcrId;
+ }
+ }
+ return teamArt.getTeamName() + " " + awa.getHumanReadableId();
+ }
+ return "";
+ }
+
+ public static String getArtifactTypeShortName(TeamWorkFlowArtifact teamArt) {
+ for (ITeamWorkflowProvider atsTeamWorkflow : TeamWorkflowProviders.getAtsTeamWorkflowExtensions()) {
+ String typeName = atsTeamWorkflow.getArtifactTypeShortName(teamArt);
+ if (Strings.isValid(typeName)) {
+ return typeName;
+ }
+ }
+ return null;
+ }
+
+ public static TeamWorkFlowArtifact cast(Artifact artifact) {
+ if (artifact instanceof AbstractWorkflowArtifact) {
+ return (TeamWorkFlowArtifact) artifact;
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkflowProviders.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkflowProviders.java
new file mode 100644
index 00000000000..98a992755c5
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/team/TeamWorkflowProviders.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.team;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.workflow.ITeamWorkflowProvider;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class TeamWorkflowProviders {
+
+ private static Set<ITeamWorkflowProvider> teamWorkflowProvider;
+
+ private TeamWorkflowProviders() {
+ // private constructor
+ }
+
+ public static Set<IArtifactType> getAllTeamWorkflowArtifactTypes() throws OseeCoreException {
+ Set<IArtifactType> artifactTypes = new HashSet<IArtifactType>();
+ artifactTypes.add(AtsArtifactTypes.TeamWorkflow);
+ for (ITeamWorkflowProvider ext : getAtsTeamWorkflowExtensions()) {
+ artifactTypes.addAll(ext.getTeamWorkflowArtifactTypes());
+ }
+ return artifactTypes;
+ }
+
+ /*
+ * due to lazy initialization, this function is non-reentrant therefore, the synchronized keyword is necessary
+ */
+ public synchronized static Set<ITeamWorkflowProvider> getAtsTeamWorkflowExtensions() {
+ if (teamWorkflowProvider != null) {
+ return teamWorkflowProvider;
+ }
+ teamWorkflowProvider = new HashSet<ITeamWorkflowProvider>();
+
+ IExtensionPoint point =
+ Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.osee.ats.core.AtsTeamWorkflowProvider");
+ if (point == null) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't access AtsTeamWorkflowProvider extension point");
+ return teamWorkflowProvider;
+ }
+ IExtension[] extensions = point.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ String classname = null;
+ String bundleName = null;
+ for (IConfigurationElement el : elements) {
+ if (el.getName().equals("AtsTeamWorkflowProvider")) {
+ classname = el.getAttribute("classname");
+ bundleName = el.getContributor().getName();
+ if (classname != null && bundleName != null) {
+ Bundle bundle = Platform.getBundle(bundleName);
+ try {
+ Class<?> taskClass = bundle.loadClass(classname);
+ Object obj = taskClass.newInstance();
+ teamWorkflowProvider.add((ITeamWorkflowProvider) obj);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP,
+ "Error loading AtsTeamWorkflowProvider extension", ex);
+ }
+ }
+ }
+ }
+ }
+ return teamWorkflowProvider;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/ATSAttributes.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/ATSAttributes.java
new file mode 100644
index 00000000000..c292f2666ed
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/ATSAttributes.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.type;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ATSAttributes {
+ private static final Map<String, ATSAttributes> WORK_ITEM_ID_TO_ATS_ATTRIBUTE_MAP =
+ new HashMap<String, ATSAttributes>();
+
+ // @formatter:off
+ public static final ATSAttributes WORKING_BRANCH_WIDGET = new ATSAttributes("Working Branch");
+ public static final ATSAttributes VALIDATE_REQ_CHANGES_WIDGET = new ATSAttributes("Validate Requirement Changes");
+ public static final ATSAttributes CREATE_CODE_TEST_TASKS_OFF_REQUIREMENTS = new ATSAttributes("Create Code/Test Tasks");
+ public static final ATSAttributes CHECK_SIGNALS_VIA_CDB_WIDGET = new ATSAttributes("Check Signals Via CDB");
+ public static final ATSAttributes SHOW_CDB_DIFF_REPORT_WIDGET = new ATSAttributes("Show CDB Differences Report");
+ public static final ATSAttributes COMMIT_MANAGER_WIDGET = new ATSAttributes("Commit Manager", "Commit branches to parent and parallel branches.");
+ // @formatter:on
+
+ private final String displayName;
+ private final String description;
+ private final String workItemId;
+
+ protected ATSAttributes(String displayName, String workItemId, String description) {
+ this.displayName = displayName;
+ this.workItemId = workItemId;
+ this.description = description;
+ WORK_ITEM_ID_TO_ATS_ATTRIBUTE_MAP.put(workItemId, this);
+ }
+
+ private ATSAttributes(String displayName) {
+ this(displayName, "");
+ }
+
+ private ATSAttributes(String displayName, String description) {
+ this(displayName, "ats." + displayName, description);
+ }
+
+ public static ATSAttributes getAtsAttributeByStoreName(String workItemId) {
+ return WORK_ITEM_ID_TO_ATS_ATTRIBUTE_MAP.get(workItemId);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+
+ @Override
+ public final int hashCode() {
+ return super.hashCode();
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getWorkItemId() {
+ return workItemId;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsArtifactTypes.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsArtifactTypes.java
new file mode 100644
index 00000000000..de0fff009bc
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsArtifactTypes.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.type;
+
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+
+public final class AtsArtifactTypes {
+
+ // @formatter:off
+ public static final IArtifactType Action = TokenFactory.createArtifactType("AAMFDhY_rns71KvX14QA", "Action");
+ public static final IArtifactType ActionableItem = TokenFactory.createArtifactType("AAMFDhW2LmhtRFsVyzwA", "Actionable Item");
+ public static final IArtifactType DecisionReview = TokenFactory.createArtifactType("AAMFDhfrdR7BGTL7H_wA", "Decision Review");
+ public static final IArtifactType PeerToPeerReview = TokenFactory.createArtifactType("AAMFDhh_300dpgmNtRAA", "PeerToPeer Review");
+ public static final IArtifactType Task = TokenFactory.createArtifactType("AAMFDhbTAAB6h+06fuAA", "Task");
+ public static final IArtifactType AbstractWorkflowArtifact = TokenFactory.createArtifactType("ABMfXC+LFBn31ZZbvjAA", "Abstract State Machine Artifact");
+ public static final IArtifactType ReviewArtifact = TokenFactory.createArtifactType("ABMa6P4TwzXA1b8K3RAA", "Abstract Review Artifact");
+ public static final IArtifactType TeamDefinition = TokenFactory.createArtifactType("AAMFDhUrlytusKbaQGAA", "Team Definition");
+ public static final IArtifactType TeamWorkflow = TokenFactory.createArtifactType("AAMFDhSiF2OD+wiUqugA", "Team Workflow");
+ public static final IArtifactType Version = TokenFactory.createArtifactType("AAMFDhder0oETnv14xQA", "Version");
+ public static final IArtifactType Goal = TokenFactory.createArtifactType("ABMgU119UjI_Q23Yu+gA", "Goal");
+ public static final IArtifactType AtsArtifact = TokenFactory.createArtifactType("ABMaLS0jvw92SE+4ZJQA", "ats.Ats Artifact");
+ public static final IArtifactType WorkDefinition = TokenFactory.createArtifactType("AGrU8fWa3AJ6uoWYP7wA", "Work Definition");
+ // @formatter:on
+
+ private AtsArtifactTypes() {
+ // Constants
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsAttributeTypes.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsAttributeTypes.java
new file mode 100644
index 00000000000..5b836a925c9
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsAttributeTypes.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.type;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
+
+/**
+ * @author Ryan D. Brooks
+ * @author Donald G. Dunne
+ */
+public final class AtsAttributeTypes {
+
+ public static final Map<String, IAttributeType> nameToTypeMap = new HashMap<String, IAttributeType>();
+ // @formatter:off
+ public static final IAttributeType Actionable = createType("AAMFEcvDtBiaJ3TMatAA", "Actionable", "True if item can have Action written against or assigned to.");
+ public static final IAttributeType ActionableItem = createType("AAMFEdbcR2zpGzFOLOQA", "Actionable Item", "Actionable Items that are impacted by this change.");
+ public static final IAttributeType ActionDetailsFormat = createType("Aij_PfM7wCsEA2Z720wA", "Action Details Format", "Format of string when push Action Details Copy button on SMA Workflow Editor.");
+ public static final IAttributeType Active = createType("AAMFEclQOVmzkIvzyWwA", "Active", "Active ATS configuration object.");
+ public static final IAttributeType AllowCommitBranch = createType("AAMFEbCZCkwgj73BsQgA", "Allow Commit Branch");
+ public static final IAttributeType AllowCreateBranch = createType("AAMFEbARuQEvi6rtY5gA", "Allow Create Branch");
+ public static final IAttributeType BaselineBranchGuid = createType("AAMFEdIjJ2za2fblEVgA", "Baseline Branch Guid", "Basline branch associated with ATS object.");
+ public static final IAttributeType BlockingReview = createType("AAMFEctKkjMRrIy1C7gA", "Blocking Review");
+
+ public static final IAttributeType Category1 = createType("AAMFEdrYniOQYrYUKKQA", "Category", "Open field for user to be able to enter text to use for categorizing/sorting.");
+ public static final IAttributeType Category2 = createType("AAMFEdthBkolbJKLXuAA", "Category2", Category1.getDescription());
+ public static final IAttributeType Category3 = createType("AAMFEd06oxr8LMzZxdgA", "Category3", Category1.getDescription());
+
+ public static final IAttributeType ChangeType = createType("AAMFEc+MwGHnPCv7HlgA", "Change Type", "Type of change.");
+
+ public static final IAttributeType CancelledDate = createType("AXnyKG1waCcPPHHGEFQA", "Cancelled Date", "Date the workflow was cancelled.");
+ public static final IAttributeType CancelledBy = createType("AXpNsieBHnqaJJfduGgA", "Cancelled By", "UserId of the user who cancelled workflow.");
+ public static final IAttributeType CancelledReason = createType("AXqJE0SmwRQzvzlqC9gA", "Cancelled Reason", "Explanation of why worklfow was cancelled.");
+ public static final IAttributeType CancelledFromState = createType("AXrxlXOwGiAnlaUNX6AA", "Cancelled From State", "State workflow was in when cancelled.");
+
+ public static final IAttributeType CreatedDate = createType("AXny90bBpmfNkLpNhqwA", "Created Date", "Date the workflow was created.");
+ public static final IAttributeType CreatedBy = createType("AXpTVIExV1p0kp9IKKQA", "Created By", "UserId of the user who created the workflow.");
+
+ public static final IAttributeType CompletedDate = createType("AXnxSfRg6UhirNzaZnQA", "Completed Date", "Date the workflow was completed.");
+ public static final IAttributeType CompletedBy = createType("AXo6tqxrOStgd9P16XQA", "Completed By", "UserId of the user who completed workflow.");
+ public static final IAttributeType CompletedFromState = createType("AXr9OO909xRiI3MFNOwA", "Completed From State", "State workflow was in when completed.");
+
+ public static final IAttributeType CurrentState = createType("AAMFEdOWL3u6hmX2VbwA", "Current State", "Current state of workflow state machine.");
+ public static final IAttributeType CurrentStateType = createType("ATOWheEyGUJmPmPuqyAA", "Current State Type", "Type of Current State: InWork, Completed or Cancelled.");
+ public static final IAttributeType Decision = createType("AAMFEd7uDXcmqq_FrCQA", "Decision", "Option selected during decision review.");
+
+ public static final IAttributeType DecisionReviewOptions = createType("AAMFEd5hRy1+SRJRqfwA", "Decision Review Options", "Options available for selection in review. Each line is a separate option. Format: <option name>;<state to transition to>;<assignee>");
+ public static final IAttributeType Description = createType("AAMFEdWJ_ChxX6+YKbwA", "Description", "Detailed explanation.");
+ public static final IAttributeType DslSheet = createType("AGrqojZDowPDaLh4kBAA", "DSL Sheet", "XText DSL Sheet for ATS");
+ public static final IAttributeType EstimatedCompletionDate = createType("AAMFEc18k3Gh+GP7zqAA", "Estimated Completion Date", "Date the changes will be completed.");
+ public static final IAttributeType EstimatedHours = createType("AAMFEdCSqBh+cPyadiwA", "Estimated Hours", "Hours estimated to implement the changes associated with this Action.\nIncludes estimated hours for workflows, tasks and reviews.");
+ public static final IAttributeType EstimatedReleaseDate = createType("AAMFEcy6VB7Ble5SP1QA", "Estimated Release Date", "Date the changes will be made available to the users.");
+ public static final IAttributeType FullName = createType("AAMFEdZI9XLT34cTonAA", "Full Name", "Expanded and descriptive name.");
+ public static final IAttributeType GoalOrderVote = createType("Aiecsz9pP1CRoQdaYRAA", "Goal Order Vote", "Vote for order item belongs to within goal.");
+ public static final IAttributeType HoursPerWorkDay = createType("AAMFEdGlqFsZp22RMdAA", "Hours Per Work Day");
+ public static final IAttributeType LegacyPcrId = createType("AAMFEd3TakphMtQX1zgA", "Legacy PCR Id", "Field to register problem change report id from legacy items imported into ATS.");
+ public static final IAttributeType Location = createType("AAMFEeAW4QBlesdfacwA", "Location", "Enter location of materials to review.");
+ public static final IAttributeType LocChanged= createType("AQR27biJiQlOKTEKCvwA", "LOC Changed", "Total Lines of Code Changed");
+ public static final IAttributeType LocReviewed = createType("AQR5ckRsrh4PpayYGAgA", "LOC Reviewed", "Total Lines of Code Reviewed");
+ public static final IAttributeType Log = createType("AAMFEdgB1DX3eJSZb0wA", "Log");
+
+ public static final IAttributeType MeetingLocation = createType("APom8wytSX0G3mcb3qQA", "Meeting Location", "Location meeting is held.");
+ public static final IAttributeType MeetingAttendee = createType("APrZQQaOlFcX1CxbO6QA", "Meeting Attendee", "Attendee of meeting.");
+ public static final IAttributeType MeetingLength = createType("APoxOFjXzV49ZmO3CfwA", "Meeting Length", "Length of meeting.");
+
+ public static final IAttributeType NeedBy = createType("AAMFEcxAGzHAKfDNAIwA", "Need By", "Hard schedule date that workflow must be completed.");
+ public static final IAttributeType NextVersion = createType("AAMFEcpH8Xb72hsF5AwA", "Next Version", "True if version artifact is \"Next\" version to be released.");
+ public static final IAttributeType Numeric1 = createType("AABY2xxQsDm811kCViwA", "Numeric1", "Open field for user to be able to enter numbers for sorting.");
+ public static final IAttributeType Numeric2 = createType("AABiRtvZsAEkU4BS9qwA", "Numeric2", Numeric1.getDescription());
+ public static final IAttributeType OperationalImpact = createType("ADTfjCBpFxlyV3o1wLwA", "Operational Impact");
+ public static final IAttributeType OperationalImpactDescription = createType("ADTfjCDvUF5PtiKdQ3wA", "Operational Impact Description");
+ public static final IAttributeType OperationalImpactWorkaround = createType("AbMqFfIwQHRbmzT_VTAA", "Operational Impact Workaround");
+ public static final IAttributeType OperationalImpactWorkaroundDescription = createType("AbMo7PoIukFDhQFJxKwA", "Operational Impact Workaround Description");
+ public static final IAttributeType PagesChanged= createType("AQR8yMuv4W84UwvSJAQA", "Pages Changed", "Total Pages of Changed");
+ public static final IAttributeType PagesReviewed = createType("AQR9qM8TTyCMb7sf4cQA", "Pages Reviewed", "Total Pages Reviewed");
+ public static final IAttributeType PercentRework = createType("AAMFEdKfjl2TII9+tuwA", "Percent Rework");
+ public static final IAttributeType PercentComplete = createType("AALLbOZiBBDN39YsRSAA", "Percent Complete");
+
+ public static final IAttributeType Points = createType("AY2EeqhzcDEGtXtREkAA", "Points", "Abstract value that describes risk, complexity, and size of Actions.");
+ public static final IAttributeType PriorityType = createType("AAMFEc8JzH1U6XGD59QA", "Priority", "1 = High; 5 = Low");
+ public static final IAttributeType Problem = createType("AAMFEdQUxRyevvTu+bwA", "Problem", "Problem found during analysis.");
+ public static final IAttributeType ProposedResolution = createType("AAMFEdSSRDGgBQ5tctAA", "Proposed Resolution", "Recommended resolution.");
+ public static final IAttributeType RelatedToState = createType("AAMFEdkwHULOmHbMbGgA", "Related To State", "State of parent workflow this object is related to.");
+ public static final IAttributeType Released = createType("AAMFEcnMoUZMLA2zB1AA", "Released", "True if object is in a released state.");
+ public static final IAttributeType ReleaseDate = createType("AAMFEc3+cGcMDOCdmdAA", "Release Date", "Date the changes were made available to the users.");
+ public static final IAttributeType Resolution = createType("AAMFEdUMfV1KdbQNaKwA", "Resolution", "Implementation details.");
+ public static final IAttributeType ReviewBlocks = createType("AAMFEc6G2A8jmRWJgagA", "Review Blocks", "Review Completion will block it's parent workflow in this manner.");
+ public static final IAttributeType ReviewDefect = createType("AAMFEd+MSVAb8JQ6f5gA", "Review Defect");
+ public static final IAttributeType ReviewFormalType = createType("AOwrClAkonFC_UKqyJAA", "Review Formal Type");
+ public static final IAttributeType Role = createType("AAMFEeCqMz0XCSBJ+IQA", "Role");
+ public static final IAttributeType RuleDefinition = createType("AEqAJNnkyW4_d5_WhpgA", "Rule Definition");
+ public static final IAttributeType SmaNote = createType("AAMFEdm7ywte8qayfbAA", "SMA Note", "Notes applicable to ATS object");
+ public static final IAttributeType State = createType("AAMFEdMa3wzVvp60xLQA", "State", "States of workflow state machine.");
+ public static final IAttributeType StateNotes = createType("AAMFEdiWPm7M_xV1EswA", "State Notes");
+ public static final IAttributeType TeamDefinition = createType("AAMFEdd5bFEe18bd0lQA", "Team Definition");
+ public static final IAttributeType TeamUsesVersions = createType("AAMFEcrHnzPxQ7w3ligA", "Team Uses Versions", "True if Team Workflow uses versioning/releasing option.");
+ public static final IAttributeType Title = createType(CoreAttributeTypes.Name.getGuid(), CoreAttributeTypes.Name.getName(), "Enter clear and consise title that can be generally understood.");
+ public static final IAttributeType UserCommunity = createType("AAMFEdAPtAq1IEwiCQAA", "User Community", "If working in one of these communities resulted in the creation of this Action, please select. Otherwise, select Other.");
+ public static final IAttributeType ValidationRequired = createType("AAMFEcjT0TwkD2R4w1QA", "Validation Required", "If selected, originator will be asked to validate the implementation.");
+ public static final IAttributeType VersionLocked = createType("AAzRtEJXbjzR5jySOZgA", "Version Locked", "True if version artifact is locked.");
+ public static final IAttributeType WeeklyBenefit = createType("AAMFEdEnEU9AecOHMOwA", "Weekly Benefit", "Estimated number of hours that will be saved over a single year if this change is completed.");
+ public static final IAttributeType WorkflowDefinitionOld = createType("ADG50fkFrQIxmfZgk3gA", "Workflow Definition Old", "Used in 0.9.8 - Unused in 0.9.9 - Specific work flow definition id used by this Workflow artifact");
+ public static final IAttributeType WorkflowDefinition = createType("AbksV06OrBP_ceKCeSQA", "Workflow Definition", "Specific work flow definition id used by this Workflow artifact");
+ public static final IAttributeType RelatedTaskWorkflowDefinitionOld = createType("AdR02A0xcUq4arK58BAA", "Used in 0.9.8 - Unused in 0.9.9 - Related Task Workflow Definition", "Specific work flow definition id used by Tasks related to this Workflow");
+ public static final IAttributeType RelatedTaskWorkDefinition = createType("AblApNMuhjVuyDRq6VgA", "Related Task Workflow Definition", "Specific work flow definition id used by Tasks related to this Workflow");
+ public static final IAttributeType WorkPackage = createType("AAMFEdpJqRp2wvA2qvAA", "Work Package", "Designated accounting work package for completing workflow.");
+
+
+ // @formatter:on
+
+ private static IAttributeType createType(String guid, String name) {
+ IAttributeType type = TokenFactory.createAttributeType(guid, "ats." + name);
+ nameToTypeMap.put(type.getName(), type);
+ return type;
+ }
+
+ private static IAttributeType createType(String guid, String name, String description) {
+ IAttributeType type = TokenFactory.createAttributeType(guid, "ats." + name, description);
+ nameToTypeMap.put(type.getName(), type);
+ return type;
+ }
+
+ public static IAttributeType getTypeByName(String name) {
+ return nameToTypeMap.get(name);
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsRelationTypes.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsRelationTypes.java
new file mode 100644
index 00000000000..14f5b858262
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/type/AtsRelationTypes.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.type;
+
+import org.eclipse.osee.framework.core.data.IRelationTypeSide;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+import org.eclipse.osee.framework.core.enums.RelationSide;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class AtsRelationTypes {
+
+ public static final IRelationTypeSide ActionToWorkflow_Action = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE953ixQThusHUPwA", "ActionToWorkflow");
+ public static final IRelationTypeSide ActionToWorkflow_WorkFlow = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE953ixQThusHUPwA", "ActionToWorkflow");
+ public static final IRelationTypeSide FavoriteUser_Artifact = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE+NegDLK1g2ph+AA", "FavoriteUser");
+ public static final IRelationTypeSide FavoriteUser_User = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "AAMFE+NegDLK1g2ph+AA", "FavoriteUser");
+ public static final IRelationTypeSide Goal_Goal = TokenFactory.createRelationTypeSide(RelationSide.SIDE_A,
+ "ABMn0wPKdyN+Mfo5nwgA", "Goal");
+ public static final IRelationTypeSide Goal_Member = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "ABMn0wPKdyN+Mfo5nwgA", "Goal");
+ public static final IRelationTypeSide ParallelVersion_Child = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE_EJHSBGb9msPXQA", "ParallelVersion");
+ public static final IRelationTypeSide ParallelVersion_Parent = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE_EJHSBGb9msPXQA", "ParallelVersion");
+ public static final IRelationTypeSide PrivilegedMember_Member = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE9XfiibyK1x2FiwA", "PrivilegedMember");
+ public static final IRelationTypeSide PrivilegedMember_Team = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE9XfiibyK1x2FiwA", "PrivilegedMember");
+ public static final IRelationTypeSide SmaToTask_Sma = TokenFactory.createRelationTypeSide(RelationSide.SIDE_A,
+ "AAMFE97xw1BM5l+GxKAA", "SmaToTask");
+ public static final IRelationTypeSide SmaToTask_Task = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "AAMFE97xw1BM5l+GxKAA", "SmaToTask");
+ public static final IRelationTypeSide SubscribedUser_Artifact = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE+LkSAkfUWoTHdwA", "SubscribedUser");
+ public static final IRelationTypeSide SubscribedUser_User = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "AAMFE+LkSAkfUWoTHdwA", "SubscribedUser");
+ public static final IRelationTypeSide TeamActionableItem_ActionableItem = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE939Ul9Oenq9wWgA", "TeamActionableItem");
+ public static final IRelationTypeSide TeamActionableItem_Team = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE939Ul9Oenq9wWgA", "TeamActionableItem");
+ public static final IRelationTypeSide TeamDefinitionToDecisionReviewWorkflowDiagram_TeamDefinition =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_A, "AAMFE+Fg4RmKrda_jJQA",
+ "TeamDefinitionToDecisionReviewWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToDecisionReviewWorkflowDiagram_WorkflowDiagram =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_B, "AAMFE+Fg4RmKrda_jJQA",
+ "TeamDefinitionToDecisionReviewWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToPeerToPeerReviewWorkflowDiagram_TeamDefinition =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_A, "AAMFE+HqYUG262IxMFwA",
+ "TeamDefinitionToPeerToPeerReviewWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToPeerToPeerReviewWorkflowDiagram_WorkflowDiagram =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_B, "AAMFE+HqYUG262IxMFwA",
+ "TeamDefinitionToPeerToPeerReviewWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToTaskWorkflowDiagram_TeamDefinition =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_A, "AAMFE+DkeQ9mRBPca0QA",
+ "TeamDefinitionToTaskWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToTaskWorkflowDiagram_WorkflowDiagram =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_B, "AAMFE+DkeQ9mRBPca0QA",
+ "TeamDefinitionToTaskWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToVersion_TeamDefinition = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE9_i7zG3lR1kGWQA", "TeamDefinitionToVersion");
+ public static final IRelationTypeSide TeamDefinitionToVersion_Version = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE9_i7zG3lR1kGWQA", "TeamDefinitionToVersion");
+ public static final IRelationTypeSide TeamDefinitionToWorkflowDiagram_TeamDefinition =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_A, "AAMFE+BpKTGewbN8c3gA",
+ "TeamDefinitionToWorkflowDiagram");
+ public static final IRelationTypeSide TeamDefinitionToWorkflowDiagram_WorkflowDiagram =
+ TokenFactory.createRelationTypeSide(RelationSide.SIDE_B, "AAMFE+BpKTGewbN8c3gA",
+ "TeamDefinitionToWorkflowDiagram");
+ public static final IRelationTypeSide TeamLead_Lead = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "AAMFE90HyTZPyHuQWOQA", "TeamLead");
+ public static final IRelationTypeSide TeamLead_Team = TokenFactory.createRelationTypeSide(RelationSide.SIDE_A,
+ "AAMFE90HyTZPyHuQWOQA", "TeamLead");
+ public static final IRelationTypeSide TeamMember_Member = TokenFactory.createRelationTypeSide(RelationSide.SIDE_B,
+ "AAMFE92A6gCO9WJ2ijQA", "TeamMember");
+ public static final IRelationTypeSide TeamMember_Team = TokenFactory.createRelationTypeSide(RelationSide.SIDE_A,
+ "AAMFE92A6gCO9WJ2ijQA", "TeamMember");
+ public static final IRelationTypeSide TeamWorkflowTargetedForVersion_Version = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE99pzm4zSibDT9gA", "TeamWorkflowTargetedForVersion");
+ public static final IRelationTypeSide TeamWorkflowTargetedForVersion_Workflow = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE99pzm4zSibDT9gA", "TeamWorkflowTargetedForVersion");
+ public static final IRelationTypeSide TeamWorkflowToReview_Review = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_B, "AAMFE+JqDz+8tuRDdIwA", "TeamWorkflowToReview");
+ public static final IRelationTypeSide TeamWorkflowToReview_Team = TokenFactory.createRelationTypeSide(
+ RelationSide.SIDE_A, "AAMFE+JqDz+8tuRDdIwA", "TeamWorkflowToReview");
+
+ private AtsRelationTypes() {
+ // Constants
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsCacheManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsCacheManager.java
new file mode 100644
index 00000000000..bffcea6ddf8
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsCacheManager.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
+import org.eclipse.osee.ats.core.config.AtsBulkLoad;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.enums.Active;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactCache;
+import org.eclipse.osee.framework.skynet.core.event.OseeEventManager;
+import org.eclipse.osee.framework.skynet.core.event.filter.IEventFilter;
+import org.eclipse.osee.framework.skynet.core.event.listener.IArtifactEventListener;
+import org.eclipse.osee.framework.skynet.core.event.model.ArtifactEvent;
+import org.eclipse.osee.framework.skynet.core.event.model.EventBasicGuidArtifact;
+import org.eclipse.osee.framework.skynet.core.event.model.EventBasicGuidRelation;
+import org.eclipse.osee.framework.skynet.core.event.model.EventModType;
+import org.eclipse.osee.framework.skynet.core.event.model.Sender;
+import org.eclipse.osee.framework.skynet.core.utility.DbUtil;
+
+/**
+ * Common cache storage for ATS configuration artifacts:<br>
+ * TeamDefinitionArtifact<br>
+ * VersionArtifact<br>
+ * ActionableItemArtifact<br>
+ * All other artifact types will silently not cached<br>
+ *
+ * @author Donald G. Dunne
+ */
+public class AtsCacheManager implements IArtifactEventListener {
+
+ private static Map<AbstractTaskableArtifact, Collection<TaskArtifact>> teamTasksCache =
+ new HashMap<AbstractTaskableArtifact, Collection<TaskArtifact>>();
+
+ public static void start() {
+ new AtsCacheManager();
+ }
+
+ private AtsCacheManager() {
+ OseeEventManager.addPriorityListener(this);
+ }
+
+ public static synchronized void decacheTaskArtifacts(AbstractTaskableArtifact sma) {
+ teamTasksCache.remove(sma);
+ }
+
+ public static synchronized Collection<TaskArtifact> getTaskArtifacts(AbstractTaskableArtifact sma) throws OseeCoreException {
+ if (!teamTasksCache.containsKey(sma)) {
+ Collection<TaskArtifact> taskArtifacts =
+ sma.getRelatedArtifacts(AtsRelationTypes.SmaToTask_Task, TaskArtifact.class);
+ if (taskArtifacts.isEmpty()) {
+ return taskArtifacts;
+ }
+ teamTasksCache.put(sma, taskArtifacts);
+ }
+ return teamTasksCache.get(sma);
+ }
+
+ public static List<Artifact> getArtifactsByName(IArtifactType artifactType, String name) {
+ AtsBulkLoad.loadConfig(true);
+ return ArtifactCache.getArtifactsByName(artifactType, name);
+ }
+
+ public static ActionableItemArtifact getActionableItemByGuid(String guid) throws OseeCoreException {
+ AtsBulkLoad.loadConfig(true);
+ return (ActionableItemArtifact) ArtifactCache.getActive(guid, AtsUtilCore.getAtsBranch().getId());
+ }
+
+ public static TeamDefinitionArtifact getTeamDefinitionArtifact(String guid) throws OseeCoreException {
+ AtsBulkLoad.loadConfig(true);
+ return (TeamDefinitionArtifact) ArtifactCache.getActive(guid, AtsUtilCore.getAtsBranch().getId());
+ }
+
+ public static List<Artifact> getArtifactsByActive(IArtifactType artifactType, Active active) throws OseeCoreException {
+ AtsBulkLoad.loadConfig(true);
+ return AtsUtilCore.getActive(ArtifactCache.getArtifactsByType(artifactType), active, null);
+ }
+
+ public static Artifact getSoleArtifactByName(IArtifactType artifactType, String name) {
+ AtsBulkLoad.loadConfig(true);
+ List<Artifact> arts = ArtifactCache.getArtifactsByName(artifactType, name);
+ if (arts.size() == 1) {
+ return arts.iterator().next();
+ }
+ return null;
+ }
+
+ @Override
+ public void handleArtifactEvent(ArtifactEvent artifactEvent, Sender sender) {
+ if (DbUtil.isDbInit()) {
+ OseeEventManager.removeListener(this);
+ return;
+ }
+ processArtifacts(artifactEvent);
+ processRelations(artifactEvent);
+ }
+
+ private void processRelations(ArtifactEvent artifactEvent) {
+ for (EventBasicGuidRelation guidRel : artifactEvent.getRelations()) {
+ try {
+ if (guidRel.is(AtsRelationTypes.SmaToTask_Task)) {
+ for (TaskArtifact taskArt : ArtifactCache.getActive(guidRel, TaskArtifact.class)) {
+ teamTasksCache.remove(taskArt.getParent());
+ }
+ for (Artifact artifact : ArtifactCache.getActive(guidRel)) {
+ if (artifact instanceof AbstractTaskableArtifact) {
+ teamTasksCache.remove(artifact);
+ }
+ }
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+ }
+
+ private void processArtifacts(ArtifactEvent artifactEvent) {
+ for (EventBasicGuidArtifact guidArt : artifactEvent.getArtifacts()) {
+ try {
+ if (guidArt.is(EventModType.Deleted, EventModType.Purged)) {
+ if (guidArt.is(AtsArtifactTypes.Task) && guidArt.is(EventModType.Deleted)) {
+ Artifact artifact = ArtifactCache.getActive(guidArt);
+ if (artifact != null) {
+ teamTasksCache.remove(artifact.getParent());
+ }
+ }
+ Artifact artifact = ArtifactCache.getActive(guidArt);
+ if (artifact instanceof AbstractTaskableArtifact) {
+ teamTasksCache.remove(artifact);
+ }
+ }
+ if (guidArt.is(EventModType.Added, EventModType.Modified)) {
+ // Only process if in cache
+ Artifact artifact = ArtifactCache.getActive(guidArt);
+ if (artifact != null && guidArt.is(EventModType.Added)) {
+ if (artifact.isOfType(AtsArtifactTypes.Task)) {
+ teamTasksCache.remove(artifact.getParent());
+ }
+ if (artifact instanceof AbstractTaskableArtifact) {
+ teamTasksCache.remove(artifact);
+ }
+ }
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+ }
+
+ @Override
+ public List<? extends IEventFilter> getEventFilters() {
+ return Arrays.asList(OseeEventManager.getCommonBranchFilter());
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsUtilCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsUtilCore.java
new file mode 100644
index 00000000000..efacf94f7cc
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/AtsUtilCore.java
@@ -0,0 +1,111 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.data.IArtifactToken;
+import org.eclipse.osee.framework.core.data.IOseeBranch;
+import org.eclipse.osee.framework.core.enums.Active;
+import org.eclipse.osee.framework.core.enums.CoreBranches;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.OseeGroup;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsUtilCore {
+ public final static double DEFAULT_HOURS_PER_WORK_DAY = 8;
+ private static OseeGroup atsAdminGroup = new OseeGroup("AtsAdmin");
+
+ /**
+ * TODO Remove duplicate Active flags, need to convert all ats.Active to Active in DB
+ *
+ * @param artifacts to iterate through
+ * @param active state to validate against; Both will return all artifacts matching type
+ * @param clazz type of artifacts to consider; null for all
+ * @return set of Artifacts of type clazz that match the given active state of the "Active" or "ats.Active" attribute
+ * value. If no attribute exists, Active == true; If does exist then attribute value "yes" == true, "no" == false.
+ */
+ @SuppressWarnings("unchecked")
+ public static <A extends Artifact> List<A> getActive(Collection<A> artifacts, Active active, Class<? extends Artifact> clazz) throws OseeCoreException {
+ List<A> results = new ArrayList<A>();
+ Collection<? extends Artifact> artsOfClass =
+ clazz != null ? Collections.castMatching(clazz, artifacts) : artifacts;
+ for (Artifact art : artsOfClass) {
+ if (active == Active.Both) {
+ results.add((A) art);
+ } else {
+ // assume active unless otherwise specified
+ boolean attributeActive = ((A) art).getSoleAttributeValue(AtsAttributeTypes.Active, false);
+ if (active == Active.Active && attributeActive) {
+ results.add((A) art);
+ } else if (active == Active.InActive && !attributeActive) {
+ results.add((A) art);
+ }
+ }
+ }
+ return results;
+ }
+
+ public static boolean isAtsAdmin() {
+ try {
+ return getAtsAdminGroup().isCurrentUserMember();
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return false;
+ }
+ }
+
+ public static OseeGroup getAtsAdminGroup() {
+ return atsAdminGroup;
+ }
+
+ public static String doubleToI18nString(double d) {
+ return doubleToI18nString(d, false);
+ }
+
+ public static String doubleToI18nString(double d, boolean blankIfZero) {
+ if (blankIfZero && d == 0) {
+ return "";
+ }
+ // This enables java to use same string for all 0 cases instead of creating new one
+ else if (d == 0) {
+ return "0.00";
+ } else {
+ return String.format("%4.2f", d);
+ }
+ }
+
+ public static Branch getAtsBranch() throws OseeCoreException {
+ return BranchManager.getCommonBranch();
+ }
+
+ public static IOseeBranch getAtsBranchToken() {
+ return CoreBranches.COMMON;
+ }
+
+ public static Artifact getFromToken(IArtifactToken token) {
+ Artifact toReturn = null;
+ try {
+ toReturn = ArtifactQuery.getArtifactFromToken(token, getAtsBranchToken());
+ } catch (OseeCoreException ex) {
+ // Do Nothing;
+ }
+ return toReturn;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/WorkflowManagerCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/WorkflowManagerCore.java
new file mode 100644
index 00000000000..ba70926b6fb
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/util/WorkflowManagerCore.java
@@ -0,0 +1,103 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.util;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.workdef.RuleDefinitionOption;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.StateManager;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class WorkflowManagerCore {
+
+ public static StateManager getStateManager(Artifact artifact) {
+ return cast(artifact).getStateMgr();
+ }
+
+ public static AbstractWorkflowArtifact cast(Artifact artifact) {
+ if (artifact instanceof AbstractWorkflowArtifact) {
+ return (AbstractWorkflowArtifact) artifact;
+ }
+ return null;
+ }
+
+ public static boolean isEditable(AbstractWorkflowArtifact sma, StateDefinition stateDef, boolean priviledgedEditEnabled) throws OseeCoreException {
+ // must be writeable
+ return !sma.isReadOnly() &&
+ // and access control writeable
+ sma.isAccessControlWrite() &&
+ // and current state
+ (stateDef == null || sma.isInState(stateDef)) &&
+ // and one of these
+ //
+ // page is define to allow anyone to edit
+ (sma.getStateDefinition().hasRule(RuleDefinitionOption.AllowEditToAll) ||
+ // team definition has allowed anyone to edit
+ sma.teamDefHasRule(RuleDefinitionOption.AllowEditToAll) ||
+ // priviledged edit mode is on
+ priviledgedEditEnabled ||
+ // current user is assigned
+ sma.isAssigneeMe() ||
+ // current user is ats admin
+ AtsUtilCore.isAtsAdmin());
+ }
+
+ public static AbstractWorkflowArtifact getParentAWA(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Task)) {
+ Collection<Artifact> awas = artifact.getRelatedArtifacts(AtsRelationTypes.SmaToTask_Sma);
+ if (awas.isEmpty()) {
+ throw new OseeStateException("Task has no parent [%s]", artifact.getHumanReadableId());
+ }
+ return (AbstractWorkflowArtifact) awas.iterator().next();
+ } else if (artifact.isOfType(AtsArtifactTypes.ReviewArtifact)) {
+ Collection<Artifact> awas = artifact.getRelatedArtifacts(AtsRelationTypes.TeamWorkflowToReview_Team);
+ if (!awas.isEmpty()) {
+ return (AbstractWorkflowArtifact) awas.iterator().next();
+ }
+ }
+ return null;
+ }
+
+ public static Artifact getTeamDefinition(Artifact artifact) throws OseeCoreException {
+ Artifact team = getParentTeamWorkflow(artifact);
+ if (team != null) {
+ String teamDefGuid = team.getSoleAttributeValue(AtsAttributeTypes.TeamDefinition);
+ return ArtifactQuery.getArtifactFromId(teamDefGuid, BranchManager.getCommonBranch());
+ }
+ return null;
+ }
+
+ public static Artifact getParentActionArtifact(Artifact artifact) throws OseeCoreException {
+ Artifact team = getParentTeamWorkflow(artifact);
+ if (team != null) {
+ return artifact.getRelatedArtifact(AtsRelationTypes.ActionToWorkflow_Action);
+ }
+ return null;
+ }
+
+ public static Artifact getParentTeamWorkflow(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.TeamWorkflow)) {
+ return artifact;
+ } else if (artifact.isOfType(AtsArtifactTypes.Task)) {
+ return getParentAWA(artifact);
+ } else if (artifact.isOfType(AtsArtifactTypes.ReviewArtifact)) {
+ return getParentAWA(artifact);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/TargetedVersionUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/TargetedVersionUtil.java
new file mode 100644
index 00000000000..45406010a77
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/TargetedVersionUtil.java
@@ -0,0 +1,78 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.version;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TargetedVersionUtil {
+
+ public static VersionArtifact getTargetedVersion(Object object) throws OseeCoreException {
+ if (object instanceof AbstractWorkflowArtifact) {
+ TeamWorkFlowArtifact teamArt = ((AbstractWorkflowArtifact) object).getParentTeamWorkflow();
+ if (teamArt != null) {
+ if (teamArt.getRelatedArtifactsCount(AtsRelationTypes.TeamWorkflowTargetedForVersion_Version) > 0) {
+ List<Artifact> verArts =
+ teamArt.getRelatedArtifacts(AtsRelationTypes.TeamWorkflowTargetedForVersion_Version);
+ if (verArts.size() > 1) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ "Multiple targeted versions for artifact " + teamArt.toStringWithId());
+ return (VersionArtifact) verArts.iterator().next();
+ } else {
+ return (VersionArtifact) verArts.iterator().next();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static String getTargetedVersionStr(Object object) throws OseeCoreException {
+ if (object instanceof AbstractWorkflowArtifact) {
+ TeamWorkFlowArtifact teamArt = ((AbstractWorkflowArtifact) object).getParentTeamWorkflow();
+ if (teamArt != null) {
+ Collection<Artifact> verArts =
+ teamArt.getRelatedArtifacts(AtsRelationTypes.TeamWorkflowTargetedForVersion_Version);
+ if (verArts.isEmpty()) {
+ return "";
+ }
+ if (verArts.size() > 1) {
+ String errStr =
+ "Workflow " + teamArt.getHumanReadableId() + " targeted for multiple versions: " + Artifacts.commaArts(verArts);
+ OseeLog.log(Activator.class, Level.SEVERE, errStr, null);
+ return "!Error " + errStr;
+ }
+ Artifact verArt = verArts.iterator().next();
+ if (!teamArt.isCompleted() && !teamArt.isCancelled() && verArt.getSoleAttributeValue(
+ AtsAttributeTypes.Released, false)) {
+ String errStr =
+ "Workflow " + teamArt.getHumanReadableId() + " targeted for released version, but not completed: " + verArt;
+ if (!teamArt.isTargetedErrorLogged()) {
+ OseeLog.log(Activator.class, Level.SEVERE, errStr, null);
+ teamArt.setTargetedErrorLogged(true);
+ }
+ return "!Error " + errStr;
+ }
+ return verArt.getName();
+ }
+ }
+ return "";
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionArtifact.java
new file mode 100644
index 00000000000..82ea2de73fd
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionArtifact.java
@@ -0,0 +1,163 @@
+/*
+ * Created on Mar 24, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.version;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.commit.ICommitConfigArtifact;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.ArtifactDoesNotExist;
+import org.eclipse.osee.framework.core.exception.BranchDoesNotExist;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+
+public class VersionArtifact extends org.eclipse.osee.framework.skynet.core.artifact.Artifact implements ICommitConfigArtifact {
+
+ public VersionArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ public TeamDefinitionArtifact getParentTeamDefinition() throws OseeCoreException {
+ return this.getRelatedArtifacts(AtsRelationTypes.TeamDefinitionToVersion_TeamDefinition,
+ TeamDefinitionArtifact.class).iterator().next();
+ }
+
+ public void getParallelVersions(Set<ICommitConfigArtifact> configArts) throws OseeCoreException {
+ configArts.add(this);
+ for (VersionArtifact childArt : this.getRelatedArtifacts(AtsRelationTypes.ParallelVersion_Child,
+ VersionArtifact.class)) {
+ childArt.getParallelVersions(configArts);
+ }
+ }
+
+ public Collection<TeamWorkFlowArtifact> getTargetedForTeamArtifacts() throws OseeCoreException {
+ return this.getRelatedArtifacts(AtsRelationTypes.TeamWorkflowTargetedForVersion_Workflow,
+ TeamWorkFlowArtifact.class);
+ }
+
+ public void ensureVersionArtifact() throws OseeCoreException {
+ if (!this.isOfType(AtsArtifactTypes.Version)) {
+ throw new OseeArgumentException("Artifact should be Version not [%s]", this.getArtifactTypeName());
+ }
+ }
+
+ public Boolean isVersionLocked() throws OseeCoreException {
+ return this.getSoleAttributeValue(AtsAttributeTypes.VersionLocked, false);
+ }
+
+ public void setVersionLocked(boolean locked) throws OseeCoreException {
+ this.setSoleAttributeValue(AtsAttributeTypes.VersionLocked, locked);
+ }
+
+ public Boolean isNextVersion() throws OseeCoreException {
+ return this.getSoleAttributeValue(AtsAttributeTypes.NextVersion, false);
+ }
+
+ public void setNextVersion(boolean nextVersion) throws OseeCoreException {
+ this.setSoleAttributeValue(AtsAttributeTypes.NextVersion, nextVersion);
+ }
+
+ public Boolean isReleased() throws OseeCoreException {
+ return this.getSoleAttributeValue(AtsAttributeTypes.Released, false);
+ }
+
+ public void setReleased(boolean released) throws OseeCoreException {
+ this.setSoleAttributeValue(AtsAttributeTypes.Released, released);
+ }
+
+ public TeamDefinitionArtifact getTeamDefinitionArtifact() throws OseeCoreException {
+ try {
+ return (TeamDefinitionArtifact) this.getRelatedArtifact(AtsRelationTypes.TeamDefinitionToVersion_TeamDefinition);
+ } catch (ArtifactDoesNotExist ex) {
+ return null;
+ }
+ }
+
+ public Branch getBaselineBranch() throws OseeCoreException {
+ String branchGuid = this.getSoleAttributeValue(AtsAttributeTypes.BaselineBranchGuid, "");
+ if (Strings.isValid(branchGuid)) {
+ return BranchManager.getBranchByGuid(branchGuid);
+ } else {
+ return getTeamDefinitionArtifact().getTeamBranch();
+ }
+ }
+
+ @Override
+ public Result isCreateBranchAllowed() throws OseeCoreException {
+ if (!getSoleAttributeValue(AtsAttributeTypes.AllowCreateBranch, false)) {
+ return new Result(false, "Branch creation disabled for Version [" + this + "]");
+ }
+ if (getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Version [" + this + "]");
+ }
+ return Result.TrueResult;
+ }
+
+ @Override
+ public Result isCommitBranchAllowed() throws OseeCoreException {
+ if (!getSoleAttributeValue(AtsAttributeTypes.AllowCommitBranch, false)) {
+ return new Result(false, "Version [" + this + "] not configured to allow branch commit.");
+ }
+ if (getParentBranch() == null) {
+ return new Result(false, "Parent Branch not configured for Version [" + this + "]");
+ }
+ return Result.TrueResult;
+ }
+
+ @Override
+ public Branch getParentBranch() throws OseeCoreException {
+ try {
+ String guid = getSoleAttributeValue(AtsAttributeTypes.BaselineBranchGuid, "");
+ if (GUID.isValid(guid)) {
+ return BranchManager.getBranchByGuid(guid);
+ }
+ } catch (BranchDoesNotExist ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return null;
+ }
+
+ @Override
+ public String getFullDisplayName() throws OseeCoreException {
+ List<String> strs = new ArrayList<String>();
+ if (!getName().equals(Artifact.UNNAMED)) {
+ strs.add(getName());
+ }
+ String fullName = getSoleAttributeValue(AtsAttributeTypes.FullName, "");
+ if (Strings.isValid(fullName)) {
+ strs.add(fullName);
+ }
+ String description = getSoleAttributeValue(AtsAttributeTypes.Description, "");
+ if (Strings.isValid(description)) {
+ strs.add(description);
+ }
+ return Collections.toString(" - ", strs);
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionLockedType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionLockedType.java
new file mode 100644
index 00000000000..59dbf795879
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionLockedType.java
@@ -0,0 +1,7 @@
+package org.eclipse.osee.ats.core.version;
+
+public enum VersionLockedType {
+ Locked,
+ UnLocked,
+ Both
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionReleaseType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionReleaseType.java
new file mode 100644
index 00000000000..5f7cbd076de
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/version/VersionReleaseType.java
@@ -0,0 +1,7 @@
+package org.eclipse.osee.ats.core.version;
+
+public enum VersionReleaseType {
+ Released,
+ UnReleased,
+ Both
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AbstractWorkDefItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AbstractWorkDefItem.java
new file mode 100644
index 00000000000..e61c331b3eb
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AbstractWorkDefItem.java
@@ -0,0 +1,59 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class AbstractWorkDefItem {
+
+ private String name;
+ protected String description;
+ protected Map<String, String> workDataKeyValueMap = new HashMap<String, String>();
+ private final Pattern keyValuePattern = Pattern.compile("^(.*?)=(.*)$", Pattern.MULTILINE | Pattern.DOTALL);
+
+ public AbstractWorkDefItem(String name) {
+ this.name = name;
+ }
+
+ public String getWorkDataValue(String key) {
+ return workDataKeyValueMap.get(key);
+ }
+
+ public void addWorkDataKeyValue(String key, String value) {
+ workDataKeyValueMap.put(key, value);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Pattern getKeyValuePattern() {
+ return keyValuePattern;
+ }
+
+ public Map<String, String> getWorkDataKeyValueMap() {
+ return workDataKeyValueMap;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/CompositeStateItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/CompositeStateItem.java
new file mode 100644
index 00000000000..c3ed2c685ff
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/CompositeStateItem.java
@@ -0,0 +1,41 @@
+/*
+ * Created on Dec 16, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CompositeStateItem extends StateItem {
+
+ private int numColumns;
+ private final List<StateItem> stateItems = new ArrayList<StateItem>(5);
+
+ public CompositeStateItem() {
+ this(2);
+ }
+
+ public CompositeStateItem(int numColumns) {
+ super("Composite");
+ this.numColumns = numColumns;
+ }
+
+ public int getNumColumns() {
+ return numColumns;
+ }
+
+ public void setNumColumns(int numColumns) {
+ this.numColumns = numColumns;
+ }
+
+ public List<StateItem> getStateItems() {
+ return stateItems;
+ }
+
+ @Override
+ public String toString() {
+ return "Composite " + numColumns;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ConvertAtsDslToWorkDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ConvertAtsDslToWorkDefinition.java
new file mode 100644
index 00000000000..adc69f95c67
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ConvertAtsDslToWorkDefinition.java
@@ -0,0 +1,407 @@
+/*
+ * Created on Feb 15, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workdef.provider.BooleanDefUtil;
+import org.eclipse.osee.ats.core.workdef.provider.UserRefUtil;
+import org.eclipse.osee.ats.dsl.atsDsl.AtsDsl;
+import org.eclipse.osee.ats.dsl.atsDsl.AttrWidget;
+import org.eclipse.osee.ats.dsl.atsDsl.Composite;
+import org.eclipse.osee.ats.dsl.atsDsl.DecisionReviewDef;
+import org.eclipse.osee.ats.dsl.atsDsl.DecisionReviewOpt;
+import org.eclipse.osee.ats.dsl.atsDsl.DecisionReviewRef;
+import org.eclipse.osee.ats.dsl.atsDsl.FollowupRef;
+import org.eclipse.osee.ats.dsl.atsDsl.LayoutCopy;
+import org.eclipse.osee.ats.dsl.atsDsl.LayoutDef;
+import org.eclipse.osee.ats.dsl.atsDsl.LayoutItem;
+import org.eclipse.osee.ats.dsl.atsDsl.LayoutType;
+import org.eclipse.osee.ats.dsl.atsDsl.PeerReviewDef;
+import org.eclipse.osee.ats.dsl.atsDsl.PeerReviewRef;
+import org.eclipse.osee.ats.dsl.atsDsl.StateDef;
+import org.eclipse.osee.ats.dsl.atsDsl.ToState;
+import org.eclipse.osee.ats.dsl.atsDsl.UserByName;
+import org.eclipse.osee.ats.dsl.atsDsl.UserByUserId;
+import org.eclipse.osee.ats.dsl.atsDsl.UserRef;
+import org.eclipse.osee.ats.dsl.atsDsl.WidgetDef;
+import org.eclipse.osee.ats.dsl.atsDsl.WidgetRef;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.type.AttributeType;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.attribute.AttributeTypeManager;
+import org.eclipse.osee.framework.skynet.core.utility.AttributeTypeToXWidgetName;
+
+public class ConvertAtsDslToWorkDefinition {
+
+ private final String name;
+ private final AtsDsl atsDsl;
+
+ public ConvertAtsDslToWorkDefinition(String name, AtsDsl atsDsl) {
+ this.name = name;
+ this.atsDsl = atsDsl;
+ }
+
+ public WorkDefinition convert() {
+ if (atsDsl.getWorkDef() == null) {
+ return null;
+ }
+ WorkDefinition workDef = new WorkDefinition(Strings.unquote(atsDsl.getWorkDef().getName()));
+ for (String id : atsDsl.getWorkDef().getId()) {
+ workDef.getIds().add(id);
+ }
+
+ List<WidgetDefinition> widgetDefs = retrieveWigetDefs(atsDsl, name);
+ Map<StateDefinition, String> copyLayoutFromMap = new HashMap<StateDefinition, String>();
+
+ // Process and define all states
+ for (StateDef dslState : atsDsl.getWorkDef().getStates()) {
+ String stateName = Strings.unquote(dslState.getName());
+ StateDefinition stateDef = workDef.getOrCreateState(stateName);
+ stateDef.setWorkDefinition(workDef);
+ stateDef.setDescription(dslState.getDescription());
+
+ // Process state settings
+ stateDef.setOrdinal(dslState.getOrdinal());
+ WorkPageType workPageType = WorkPageType.Working;
+ try {
+ workPageType = WorkPageType.valueOf(dslState.getPageType());
+ } catch (IllegalArgumentException ex) {
+ // do nothing
+ }
+ stateDef.setWorkPageType(workPageType);
+ stateDef.setPercentWeight(dslState.getPercentWeight());
+ stateDef.setRecommendedPercentComplete(dslState.getRecommendedPercentComplete());
+ StateColor color = StateColor.BLACK;
+ try {
+ if (Strings.isValid(dslState.getColor())) {
+ color = StateColor.valueOf(dslState.getColor());
+ }
+ } catch (IllegalArgumentException ex) {
+ // do nothing
+ }
+ stateDef.setColor(color);
+
+ // Process widgets
+ LayoutType layout = dslState.getLayout();
+ if (layout instanceof LayoutDef) {
+ processLayoutItems(name, widgetDefs, stateDef.getStateItems(), ((LayoutDef) layout).getLayoutItems());
+ } else if (layout instanceof LayoutCopy) {
+ copyLayoutFromMap.put(stateDef, Strings.unquote(((LayoutCopy) layout).getState().getName()));
+ }
+
+ // process rules
+ for (String ruleName : dslState.getRules()) {
+ stateDef.addRule(new RuleDefinition(Strings.unquote(ruleName)), "Dsl StateDef Rule");
+ }
+
+ }
+
+ // Process States needing layoutCopy
+ for (Entry<StateDefinition, String> entry : copyLayoutFromMap.entrySet()) {
+ StateDefinition fromStateDef = workDef.getStateByName(entry.getValue());
+ StateDefinition toStateDef = entry.getKey();
+ for (StateItem item : fromStateDef.getStateItems()) {
+ toStateDef.getStateItems().add(item);
+ }
+ }
+
+ // Process and define all transitions
+ for (StateDef dslState : atsDsl.getWorkDef().getStates()) {
+ StateDefinition stateDef = workDef.getStateByName(Strings.unquote(dslState.getName()));
+ // Process transitions
+ for (ToState dslToState : dslState.getTransitionStates()) {
+ StateDefinition toStateDef = workDef.getStateByName(Strings.unquote(dslToState.getState().getName()));
+ stateDef.getToStates().add(toStateDef);
+ for (String dslTransOption : dslToState.getOptions()) {
+ if ("AsDefault".equals(dslTransOption)) {
+ stateDef.setDefaultToState(toStateDef);
+ }
+ if ("OverrideAttributeValidation".equals(dslTransOption)) {
+ stateDef.getOverrideAttributeValidationStates().add(toStateDef);
+ }
+ }
+ }
+ }
+
+ // Process all decision reviews
+ for (StateDef dslState : atsDsl.getWorkDef().getStates()) {
+ StateDefinition stateDef = workDef.getStateByName(Strings.unquote(dslState.getName()));
+ for (DecisionReviewRef dslRevRef : dslState.getDecisionReviews()) {
+ DecisionReviewDef dslRevDef = dslRevRef.getDecisionReview();
+ DecisionReviewDefinition revDef = convertDslDecisionReview(dslRevDef);
+ if (!Strings.isValid(revDef.getRelatedToState())) {
+ revDef.setRelatedToState(stateDef.getName());
+ }
+ stateDef.getDecisionReviews().add(revDef);
+ }
+ }
+
+ // Process all peer reviews
+ for (StateDef dslState : atsDsl.getWorkDef().getStates()) {
+ StateDefinition stateDef = workDef.getStateByName(Strings.unquote(dslState.getName()));
+ for (PeerReviewRef peerRevRef : dslState.getPeerReviews()) {
+ PeerReviewDef dslRevDef = peerRevRef.getPeerReview();
+ PeerReviewDefinition revDef = convertDslPeerReview(dslRevDef);
+ if (!Strings.isValid(revDef.getRelatedToState())) {
+ revDef.setRelatedToState(stateDef.getName());
+ }
+ stateDef.getPeerReviews().add(revDef);
+ }
+ }
+
+ // Set the start state
+ workDef.setStartState(workDef.getStateByName(Strings.unquote(atsDsl.getWorkDef().getStartState().getName())));
+
+ return workDef;
+ }
+
+ private DecisionReviewDefinition convertDslDecisionReview(DecisionReviewDef dslRevDef) {
+ DecisionReviewDefinition revDef = new DecisionReviewDefinition(dslRevDef.getName());
+ revDef.setReviewTitle(dslRevDef.getTitle());
+ revDef.setDescription(dslRevDef.getDescription());
+
+ String dslBlockType = dslRevDef.getBlockingType().getName();
+ ReviewBlockType blockType = ReviewBlockType.None;
+ try {
+ blockType = ReviewBlockType.valueOf(dslBlockType);
+ } catch (IllegalArgumentException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("Unknown ReviewBlockType [%s]; Defaulting to None", dslBlockType));
+ }
+ revDef.setBlockingType(blockType);
+
+ String dslEventType = dslRevDef.getStateEvent().getName();
+ StateEventType eventType = StateEventType.None;
+ try {
+ eventType = StateEventType.valueOf(dslEventType);
+ } catch (IllegalArgumentException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("Unknown StateEventType [%s]; Defaulting to None", dslEventType));
+ }
+ revDef.setStateEventType(eventType);
+ revDef.setAutoTransitionToDecision(BooleanDefUtil.get(dslRevDef.getAutoTransitionToDecision(), false));
+
+ for (DecisionReviewOpt dslOpt : dslRevDef.getOptions()) {
+ DecisionReviewOption revOpt = new DecisionReviewOption(dslOpt.getName());
+ FollowupRef followupRef = dslOpt.getFollowup();
+ if (followupRef == null) {
+ revOpt.setFollowupRequired(false);
+ } else {
+ revOpt.getUserIds().addAll(UserRefUtil.getUserIds(followupRef.getAssigneeRefs()));
+ revOpt.getUserNames().addAll(UserRefUtil.getUserNames(followupRef.getAssigneeRefs()));
+ }
+ revDef.getOptions().add(revOpt);
+ }
+
+ Collection<String> userIds = getAssigneesFromUserRefs(dslRevDef.getAssigneeRefs());
+ revDef.getAssignees().addAll(userIds);
+ return revDef;
+ }
+
+ private void processLayoutItems(String SHEET_NAME, List<WidgetDefinition> widgetDefs, List<StateItem> stateItems, EList<LayoutItem> layoutItems) {
+ for (LayoutItem layoutItem : layoutItems) {
+ if (layoutItem instanceof WidgetDef) {
+ WidgetDefinition widgetDef = convertDslWidgetDef((WidgetDef) layoutItem, SHEET_NAME);
+ stateItems.add(widgetDef);
+ } else if (layoutItem instanceof WidgetRef) {
+ String widgetName = Strings.unquote(((WidgetRef) layoutItem).getWidget().getName());
+ boolean found = false;
+ for (WidgetDefinition wd : widgetDefs) {
+ if (wd.getName().equals(widgetName)) {
+ stateItems.add(wd);
+ found = true;
+ }
+ }
+ if (!found) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ String.format("Could not find WidgetRef [%s] in WidgetDefs", widgetName));
+ }
+ } else if (layoutItem instanceof AttrWidget) {
+ AttrWidget attrWidget = (AttrWidget) layoutItem;
+ String attributeName = attrWidget.getAttributeName();
+ try {
+ AttributeType attributeType = AttributeTypeManager.getType(attributeName);
+ if (attributeType == null) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ String.format("Invalid attribute name [%s] in WorkDefinition [%s]", attributeName, SHEET_NAME));
+ } else {
+ WidgetDefinition widgetDef = new WidgetDefinition(attributeType.getUnqualifiedName());
+ widgetDef.setAttributeName(attributeType.getName());
+ setXWidgetNameBasedOnAttribute(attributeType, widgetDef);
+ extractDslWidgetDefOptions(attrWidget.getOption(), SHEET_NAME, widgetDef);
+ stateItems.add(widgetDef);
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex,
+ "Error resolving attribute [%s] to WorkDefinition in [%s]", attributeName, SHEET_NAME);
+ }
+ } else if (layoutItem instanceof Composite) {
+ Composite composite = (Composite) layoutItem;
+ CompositeStateItem compStateItem = new CompositeStateItem(composite.getNumColumns());
+ if (!composite.getLayoutItems().isEmpty()) {
+ processLayoutItems(SHEET_NAME, widgetDefs, compStateItem.getStateItems(), composite.getLayoutItems());
+ }
+ stateItems.add(compStateItem);
+ }
+ }
+
+ }
+
+ private PeerReviewDefinition convertDslPeerReview(PeerReviewDef dslRevDef) {
+ PeerReviewDefinition revDef = new PeerReviewDefinition(dslRevDef.getName());
+ revDef.setReviewTitle(dslRevDef.getTitle());
+ revDef.setDescription(dslRevDef.getDescription());
+ revDef.setLocation(dslRevDef.getLocation());
+
+ String dslBlockType = dslRevDef.getBlockingType().getName();
+ ReviewBlockType blockType = ReviewBlockType.None;
+ try {
+ blockType = ReviewBlockType.valueOf(dslBlockType);
+ } catch (IllegalArgumentException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("Unknown ReviewBlockType [%s]; Defaulting to None", dslBlockType));
+ }
+ revDef.setBlockingType(blockType);
+
+ String dslEventType = dslRevDef.getStateEvent().getName();
+ StateEventType eventType = StateEventType.None;
+ try {
+ eventType = StateEventType.valueOf(dslEventType);
+ } catch (IllegalArgumentException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("Unknown StateEventType [%s]; Defaulting to None", dslEventType));
+ }
+ revDef.setStateEventType(eventType);
+ Collection<String> userIds = getAssigneesFromUserRefs(dslRevDef.getAssigneeRefs());
+ revDef.getAssignees().addAll(userIds);
+ return revDef;
+ }
+
+ private Collection<String> getAssigneesFromUserRefs(EList<UserRef> UserRefs) {
+ Set<String> userIds = new HashSet<String>();
+ for (UserRef UserRef : UserRefs) {
+ if (UserRef instanceof UserByName) {
+ UserByName byName = (UserByName) UserRef;
+ String name = Strings.unquote(byName.getUserName());
+ if (!Strings.isValid(name)) {
+ OseeLog.log(Activator.class, Level.WARNING, String.format("Unhandled UserByName name [%s]", name));
+ continue;
+ }
+ try {
+ User user = UserManager.getUserByName(name);
+ userIds.add(user.getUserId());
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("No user by name [%s] [%s]", name, ex.getLocalizedMessage()));
+ }
+ } else if (UserRef instanceof UserByUserId) {
+ UserByUserId byUserId = (UserByUserId) UserRef;
+ String userId = byUserId.getUserId();
+ if (!Strings.isValid(userId)) {
+ OseeLog.log(Activator.class, Level.WARNING, String.format("Unhandled UserByUserId id [%s]", userId));
+ continue;
+ }
+ try {
+ User user = UserManager.getUserByUserId(userId);
+ userIds.add(user.getUserId());
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.WARNING,
+ String.format("No user by id [%s] [%s]", userId, ex.getLocalizedMessage()));
+ }
+ } else {
+ OseeLog.log(Activator.class, Level.WARNING, String.format("Unhandled UserRef type [%s]", UserRef));
+ }
+ }
+ return userIds;
+ }
+
+ private void setXWidgetNameBasedOnAttribute(AttributeType attributeType, WidgetDefinition widgetDef) throws OseeCoreException {
+ if (!Strings.isValid(widgetDef.getXWidgetName())) {
+ widgetDef.setXWidgetName(AttributeTypeToXWidgetName.getXWidgetName(attributeType));
+ }
+ }
+
+ private List<WidgetDefinition> retrieveWigetDefs(AtsDsl atsDsl, String SHEET_NAME) {
+ List<WidgetDefinition> widgetDefs = new ArrayList<WidgetDefinition>();
+ for (WidgetDef dslWidgetDef : atsDsl.getWorkDef().getWidgetDefs()) {
+ WidgetDefinition widgetDef = convertDslWidgetDef(dslWidgetDef, SHEET_NAME);
+ widgetDefs.add(widgetDef);
+ }
+ return widgetDefs;
+ }
+
+ private WidgetDefinition convertDslWidgetDef(WidgetDef dslWidgetDef, String SHEET_NAME) {
+ WidgetDefinition widgetDef = new WidgetDefinition(Strings.unquote(dslWidgetDef.getName()));
+ widgetDef.setAttributeName(dslWidgetDef.getAttributeName());
+ // Set description if model defines it
+ if (Strings.isValid(dslWidgetDef.getDescription())) {
+ widgetDef.setDescription(dslWidgetDef.getDescription());
+ }
+ // Else, set if AtsAttributeTypes defines it
+ else if (Strings.isValid(dslWidgetDef.getAttributeName()) && AtsAttributeTypes.getTypeByName(dslWidgetDef.getAttributeName()) != null && Strings.isValid(AtsAttributeTypes.getTypeByName(
+ dslWidgetDef.getAttributeName()).getDescription())) {
+ widgetDef.setDescription(AtsAttributeTypes.getTypeByName(dslWidgetDef.getAttributeName()).getDescription());
+ }
+ if (Strings.isValid(dslWidgetDef.getXWidgetName())) {
+ widgetDef.setXWidgetName(dslWidgetDef.getXWidgetName());
+ } else {
+ String attributeName = dslWidgetDef.getAttributeName();
+ if (Strings.isValid(attributeName)) {
+ try {
+ AttributeType attributeType = AttributeTypeManager.getType(attributeName);
+ if (attributeType == null) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ String.format("Invalid attribute name [%s] in WorkDefinition [%s]", attributeName, SHEET_NAME));
+ } else {
+ setXWidgetNameBasedOnAttribute(attributeType, widgetDef);
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(
+ Activator.class,
+ Level.SEVERE,
+ String.format("Error resolving attribute name [%s] in WorkDefinition [%s]", attributeName, SHEET_NAME));
+ }
+ } else {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ String.format("Invalid attribute name [%s] in WorkDefinition [%s]", attributeName, SHEET_NAME));
+ }
+ }
+
+ widgetDef.setHeight(dslWidgetDef.getHeight());
+ widgetDef.setDefaultValue(dslWidgetDef.getDefaultValue());
+ extractDslWidgetDefOptions(dslWidgetDef.getOption(), SHEET_NAME, widgetDef);
+ return widgetDef;
+ }
+
+ private void extractDslWidgetDefOptions(EList<String> options, String SHEET_NAME, WidgetDefinition widgetDef) {
+ for (String value : options) {
+ WidgetOption option = null;
+ try {
+ option = WidgetOption.valueOf(value);
+ widgetDef.getOptions().add(option);
+ } catch (IllegalArgumentException ex) {
+ OseeLog.log(Activator.class, Level.WARNING, ex, "Unexpected value [%s] in WorkDefinition [%s] ", value,
+ SHEET_NAME);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewDefinition.java
new file mode 100644
index 00000000000..ac0fc0c967a
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewDefinition.java
@@ -0,0 +1,96 @@
+/*
+ * Created on Jan 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DecisionReviewDefinition {
+
+ public String name;
+ public String reviewTitle;
+ public String description = "";
+ public String relatedToState;
+ public ReviewBlockType blockingType;
+ public StateEventType stateEventType;
+ public List<String> assignees = new ArrayList<String>();
+ public boolean autoTransitionToDecision = false;
+ public List<DecisionReviewOption> options = new ArrayList<DecisionReviewOption>();
+
+ public DecisionReviewDefinition(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public ReviewBlockType getBlockingType() {
+ return blockingType;
+ }
+
+ public void setBlockingType(ReviewBlockType blockingType) {
+ this.blockingType = blockingType;
+ }
+
+ public StateEventType getStateEventType() {
+ return stateEventType;
+ }
+
+ public void setStateEventType(StateEventType stateEventType) {
+ this.stateEventType = stateEventType;
+ }
+
+ public boolean isAutoTransitionToDecision() {
+ return autoTransitionToDecision;
+ }
+
+ public void setAutoTransitionToDecision(boolean autoTransitionToDecision) {
+ this.autoTransitionToDecision = autoTransitionToDecision;
+ }
+
+ public List<String> getAssignees() {
+ return assignees;
+ }
+
+ public List<DecisionReviewOption> getOptions() {
+ return options;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String getTitle() {
+ return reviewTitle;
+ }
+
+ public void setReviewTitle(String reviewTitle) {
+ this.reviewTitle = reviewTitle;
+ }
+
+ public String getRelatedToState() {
+ return relatedToState;
+ }
+
+ public void setRelatedToState(String relatedToState) {
+ this.relatedToState = relatedToState;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewOption.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewOption.java
new file mode 100644
index 00000000000..9a9e51eeb00
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/DecisionReviewOption.java
@@ -0,0 +1,69 @@
+/*
+ * Created on Jan 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DecisionReviewOption {
+
+ public String name;
+ public boolean followupRequired;
+ public List<String> userIds;
+ public List<String> userNames;
+
+ public DecisionReviewOption(String name) {
+ this(name, false, new ArrayList<String>());
+ }
+
+ public DecisionReviewOption(String name, boolean isFollowupRequired, List<String> userIds) {
+ this.name = name;
+ this.followupRequired = isFollowupRequired;
+ if (userIds == null) {
+ this.userIds = new ArrayList<String>();
+ } else {
+ this.userIds = userIds;
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<String> getUserIds() {
+ return userIds;
+ }
+
+ public void setUserIds(List<String> userIds) {
+ this.userIds = userIds;
+ }
+
+ public boolean isFollowupRequired() {
+ return followupRequired;
+ }
+
+ public void setFollowupRequired(boolean followupRequired) {
+ this.followupRequired = followupRequired;
+ }
+
+ @Override
+ public String toString() {
+ return name + (followupRequired ? " - Followup Required" : " - No Followup Required");
+ }
+
+ public List<String> getUserNames() {
+ return userNames;
+ }
+
+ public void setUserNames(List<String> userNames) {
+ this.userNames = userNames;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/IWorkDefintionFactoryLegacyMgr.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/IWorkDefintionFactoryLegacyMgr.java
new file mode 100644
index 00000000000..5e53d400874
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/IWorkDefintionFactoryLegacyMgr.java
@@ -0,0 +1,27 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public interface IWorkDefintionFactoryLegacyMgr {
+
+ public WorkDefinitionMatch getWorkFlowDefinitionFromId(String id) throws OseeCoreException;
+
+ public WorkDefinitionMatch getWorkFlowDefinitionFromReverseId(String id) throws OseeCoreException;
+
+ public WorkDefinitionMatch getWorkFlowDefinitionFromArtifact(Artifact artifact) throws OseeCoreException;
+
+ public WorkDefinitionMatch getWorkFlowDefinitionFromTeamDefition(TeamDefinitionArtifact teamDefinition) throws OseeCoreException;
+
+ public String getOverrideId(String legacyId);
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ModelUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ModelUtil.java
new file mode 100644
index 00000000000..8d8170e0a6c
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ModelUtil.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workdef;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.osee.ats.dsl.AtsDslStandaloneSetup;
+import org.eclipse.osee.ats.dsl.atsDsl.AtsDsl;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeExceptions;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.xtext.resource.SaveOptions;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.resource.XtextResourceSet;
+import com.google.inject.Injector;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class ModelUtil {
+
+ private ModelUtil() {
+ // Utility Class
+ }
+
+ public static AtsDsl loadModel(InputStream inputStream, boolean isZipped) throws OseeCoreException {
+ Injector injector = new AtsDslStandaloneSetup().createInjectorAndDoEMFRegistration();
+ XtextResource resource = injector.getInstance(XtextResource.class);
+
+ Map<String, Boolean> options = new HashMap<String, Boolean>();
+ options.put(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
+ if (isZipped) {
+ options.put(Resource.OPTION_ZIP, Boolean.TRUE);
+ }
+ try {
+ resource.setURI(URI.createURI("http://www.eclipse.org/osee/ats/dsl/AtsDsl"));
+ resource.load(inputStream, options);
+ } catch (IOException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ }
+ AtsDsl model = (AtsDsl) resource.getContents().get(0);
+ for (Diagnostic diagnostic : resource.getErrors()) {
+ throw new OseeStateException(diagnostic.toString());
+ }
+ return model;
+ }
+
+ public static AtsDsl loadModel(String uri, String xTextData) throws OseeCoreException {
+ try {
+ AtsDslStandaloneSetup setup = new AtsDslStandaloneSetup();
+ Injector injector = setup.createInjectorAndDoEMFRegistration();
+ XtextResourceSet set = injector.getInstance(XtextResourceSet.class);
+
+ // set.setClasspathURIContext(ModelUtil.class);
+ set.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
+
+ Resource resource = set.createResource(URI.createURI(uri));
+ resource.load(new ByteArrayInputStream(xTextData.getBytes("UTF-8")), set.getLoadOptions());
+ AtsDsl model = (AtsDsl) resource.getContents().get(0);
+ for (Diagnostic diagnostic : resource.getErrors()) {
+ throw new OseeStateException(diagnostic.toString());
+ }
+ return model;
+ } catch (IOException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ return null; // unreachable since wrapAndThrow() always throws an exception
+ }
+ }
+
+ public static void saveModel(AtsDsl model, String uri, OutputStream outputStream, boolean isZipped) throws IOException {
+ AtsDslStandaloneSetup.doSetup();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ Resource resource = resourceSet.createResource(URI.createURI(uri));
+ resource.getContents().add(model);
+
+ Map<String, Boolean> options = new HashMap<String, Boolean>();
+ // options.put(XtextResource.OPTION_FORMAT, Boolean.TRUE);
+ if (isZipped) {
+ options.put(Resource.OPTION_ZIP, Boolean.TRUE);
+ }
+ SaveOptions saveOptions = SaveOptions.getOptions(options);
+ resource.save(outputStream, saveOptions.toOptionsMap());
+ }
+
+ private static void storeModel(Resource resource, OutputStream outputStream, EObject object, String uri, Map<String, Boolean> options) throws OseeCoreException {
+ try {
+ resource.setURI(URI.createURI(uri));
+ resource.getContents().add(object);
+ resource.save(outputStream, options);
+ } catch (IOException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ }
+ }
+
+ public static String modelToStringXML(EObject object, String uri, Map<String, Boolean> options) throws OseeCoreException {
+ return modelToString(new XMLResourceImpl(), object, uri, options);
+ }
+
+ public static String modelToStringXText(EObject object, String uri, Map<String, Boolean> options) throws OseeCoreException {
+ AtsDslStandaloneSetup setup = new AtsDslStandaloneSetup();
+ Injector injector = setup.createInjectorAndDoEMFRegistration();
+ Resource resource = injector.getInstance(XtextResource.class);
+ Map<String, Boolean> options2 = new HashMap<String, Boolean>();
+ options2.put(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
+ return modelToString(resource, object, uri, options2);
+ }
+
+ private static String modelToString(Resource resource, EObject object, String uri, Map<String, Boolean> options) throws OseeCoreException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ storeModel(resource, outputStream, object, uri, options);
+ try {
+ return outputStream.toString("UTF-8");
+ } catch (UnsupportedEncodingException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ return null; // unreachable since wrapAndThrow() always throws an exception
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/PeerReviewDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/PeerReviewDefinition.java
new file mode 100644
index 00000000000..058b6bf0e14
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/PeerReviewDefinition.java
@@ -0,0 +1,91 @@
+/*
+ * Created on Jan 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PeerReviewDefinition {
+
+ public String name;
+ public String reviewTitle;
+ public String description = "";
+ public String location = "";
+ public String relatedToState;
+ public ReviewBlockType blockingType;
+ public StateEventType stateEventType;
+ public List<String> assignees = new ArrayList<String>();
+
+ public PeerReviewDefinition(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public ReviewBlockType getBlockingType() {
+ return blockingType;
+ }
+
+ public void setBlockingType(ReviewBlockType blockingType) {
+ this.blockingType = blockingType;
+ }
+
+ public StateEventType getStateEventType() {
+ return stateEventType;
+ }
+
+ public void setStateEventType(StateEventType stateEventType) {
+ this.stateEventType = stateEventType;
+ }
+
+ public List<String> getAssignees() {
+ return assignees;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String getTitle() {
+ return reviewTitle;
+ }
+
+ public void setReviewTitle(String reviewTitle) {
+ this.reviewTitle = reviewTitle;
+ }
+
+ public String getRelatedToState() {
+ return relatedToState;
+ }
+
+ public void setRelatedToState(String relatedToState) {
+ this.relatedToState = relatedToState;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ReviewBlockType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ReviewBlockType.java
new file mode 100644
index 00000000000..c4436e5f1e9
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/ReviewBlockType.java
@@ -0,0 +1,7 @@
+package org.eclipse.osee.ats.core.workdef;
+
+public enum ReviewBlockType {
+ None,
+ Transition,
+ Commit
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinition.java
new file mode 100644
index 00000000000..527577b5844
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinition.java
@@ -0,0 +1,23 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+public class RuleDefinition extends AbstractWorkDefItem {
+
+ public RuleDefinition(String id) {
+ super(id);
+ }
+
+ public RuleDefinition(RuleDefinitionOption ruleOption) {
+ super(ruleOption.name());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%s]", getName());
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinitionOption.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinitionOption.java
new file mode 100644
index 00000000000..0a56cc8534c
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleDefinitionOption.java
@@ -0,0 +1,31 @@
+/*
+ * Created on Jan 26, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+public enum RuleDefinitionOption {
+
+ RequireStateHourSpentPrompt("Work Page Option: Will popup a dialog to prompt user for time spent in this state."),
+ AddDecisionValidateBlockingReview("Work Page Option: Will auto-create a blocking decision review for this state requesting validation for this workflow."),
+ AddDecisionValidateNonBlockingReview("Work Page Option: Will auto-create a non blocking decision review requesting validation of workflow changes."),
+ AllowTransitionWithWorkingBranch("Work Page Option: Will allow transition to next state without committing current working branch."),
+ ForceAssigneesToTeamLeads("Work Page Option: Will force this state to be assigned back to the configured team leads. Useful for authorization state."),
+ RequireTargetedVersion("Work Page and Team Definition Option: Requires workflow to be targeted for version before transition is allowed."),
+ AllowPriviledgedEditToTeamMember("Work Page and Team Definition Option: Allow team member to priviledged edit workflow assigned to team."),
+ AllowPriviledgedEditToTeamMemberAndOriginator("Work Page and Team Definition Option: Allow team member to priviledged edit workflow assigned to team if user is originator."),
+ AllowPriviledgedEditToAll("Work Page and Team Definition Option: Allow anyone to priviledged edit workflow assigned to team."),
+ AllowEditToAll("Work Page and Team Definition Option: Allow anyone to edit workflow without being assignee."),
+ AllowAssigneeToAll("Work Page and Team Definition Option: Allow anyone to change workflow assignee without being assignee.");
+
+ public final String description;
+
+ public String getDescription() {
+ return description;
+ }
+
+ private RuleDefinitionOption(String description) {
+ this.description = description;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleManager.java
new file mode 100644
index 00000000000..2527f960f38
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/RuleManager.java
@@ -0,0 +1,32 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.logging.OseeLog;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class RuleManager {
+
+ static Map<String, RuleDefinition> ruleMap = new HashMap<String, RuleDefinition>(30);
+
+ public static RuleDefinition getOrCreateRule(String ruleId) {
+ if (!ruleMap.containsKey(ruleId)) {
+ try {
+ RuleDefinitionOption ruleOption = RuleDefinitionOption.valueOf(ruleId);
+ ruleMap.put(ruleId, new RuleDefinition(ruleOption));
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, null, "Unrecognized rule definition [%s]", ruleId);
+ }
+ }
+ return ruleMap.get(ruleId);
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateColor.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateColor.java
new file mode 100644
index 00000000000..77d9db99d75
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateColor.java
@@ -0,0 +1,29 @@
+/*
+ * Created on May 4, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum StateColor {
+ BLACK,
+ WHITE,
+ RED,
+ DARK_RED,
+ GREEN,
+ DARK_GREEN,
+ YELLOW,
+ DARK_YELLOW,
+ BLUE,
+ DARK_BLUE,
+ MAGENTA,
+ DARK_MAGENTA,
+ CYAN,
+ DARK_CYAN,
+ GRAY,
+ DARK_GRAY;
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateDefinition.java
new file mode 100644
index 00000000000..82aaa3bcd7b
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateDefinition.java
@@ -0,0 +1,249 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.jdk.core.type.HashCollection;
+
+public class StateDefinition extends AbstractWorkDefItem implements IWorkPage {
+
+ private WorkPageType workPageType;
+ private int ordinal = 0;
+ private final List<StateItem> stateItems = new ArrayList<StateItem>(5);
+ private final List<RuleDefinition> rules = new ArrayList<RuleDefinition>(5);
+ private final HashCollection<RuleDefinition, String> ruleToLocations = new HashCollection<RuleDefinition, String>();
+ private final List<StateDefinition> toStates = new ArrayList<StateDefinition>(5);
+ private StateDefinition defaultToState;
+ private final List<StateDefinition> overrideAttributeValidationStates = new ArrayList<StateDefinition>(5);
+ private final List<DecisionReviewDefinition> decisionReviews = new ArrayList<DecisionReviewDefinition>();
+ private final List<PeerReviewDefinition> peerReviews = new ArrayList<PeerReviewDefinition>();
+ private WorkDefinition workDefinition;
+ private int percentWeight = 0;
+ private int recommendedPercentComplete = 0;
+ private StateColor color = null;
+
+ public StateDefinition(String name) {
+ super(name);
+ }
+
+ public List<StateItem> getStateItems() {
+ return stateItems;
+ }
+
+ public void addRule(RuleDefinition ruleDef, String location) {
+ rules.add(ruleDef);
+ ruleToLocations.put(ruleDef, location);
+ }
+
+ public Collection<String> getRuleLocations(RuleDefinition ruleDef) {
+ return ruleToLocations.getValues(ruleDef);
+ }
+
+ public List<RuleDefinition> getRules() {
+ return rules;
+ }
+
+ @Override
+ public WorkPageType getWorkPageType() {
+ return workPageType;
+ }
+
+ public void setWorkPageType(WorkPageType workPageType) {
+ this.workPageType = workPageType;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ @Override
+ public boolean isCompletedOrCancelledPage() {
+ return getWorkPageType().isCompletedOrCancelledPage();
+ }
+
+ @Override
+ public boolean isCompletedPage() {
+ return getWorkPageType().isCompletedPage();
+ }
+
+ @Override
+ public boolean isCancelledPage() {
+ return getWorkPageType().isCancelledPage();
+ }
+
+ @Override
+ public boolean isWorkingPage() {
+ return getWorkPageType().isWorkingPage();
+ }
+
+ public List<StateDefinition> getToStates() {
+ return toStates;
+ }
+
+ @Override
+ public String getPageName() {
+ return getName();
+ }
+
+ @Override
+ public Integer getDefaultPercent() {
+ return null;
+ }
+
+ public WorkDefinition getWorkDefinition() {
+ return workDefinition;
+ }
+
+ public void setWorkDefinition(WorkDefinition workDefinition) {
+ this.workDefinition = workDefinition;
+ }
+
+ public boolean hasRule(RuleDefinitionOption option) {
+ return hasRule(option.name());
+ }
+
+ public boolean hasRule(String name) {
+ for (RuleDefinition rule : rules) {
+ if (rule.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List<RuleDefinition> getRulesStartsWith(String name) {
+ List<RuleDefinition> results = new ArrayList<RuleDefinition>();
+ for (RuleDefinition rule : rules) {
+ if (rule.getName().startsWith(name)) {
+ results.add(rule);
+ }
+ }
+ return results;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%s][%s]", getName(), getWorkPageType());
+ }
+
+ /**
+ * Returns fully qualified name of <work definition name>.<this state name
+ */
+ public String getFullName() {
+ if (workDefinition != null) {
+ return workDefinition.getName() + "." + getName();
+ }
+ return getName();
+ }
+
+ public List<StateDefinition> getOverrideAttributeValidationStates() {
+ return overrideAttributeValidationStates;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((getFullName() == null) ? 0 : getFullName().hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ StateDefinition other = (StateDefinition) obj;
+ if (getFullName() == null) {
+ if (other.getFullName() != null) {
+ return false;
+ }
+ } else if (!getFullName().equals(other.getFullName())) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Recursively decend StateItems and grab all widgetDefs
+ */
+ public List<WidgetDefinition> getWidgets() {
+ List<WidgetDefinition> widgets = new ArrayList<WidgetDefinition>();
+ getWidgets(widgets, getStateItems());
+ return widgets;
+ }
+
+ private void getWidgets(List<WidgetDefinition> widgets, List<StateItem> stateItems) {
+ for (StateItem stateItem : stateItems) {
+ if (stateItem instanceof CompositeStateItem) {
+ getWidgets(widgets, ((CompositeStateItem) stateItem).getStateItems());
+ } else if (stateItem instanceof WidgetDefinition) {
+ widgets.add((WidgetDefinition) stateItem);
+ }
+ }
+ }
+
+ public StateDefinition getDefaultToState() {
+ return defaultToState;
+ }
+
+ public void setDefaultToState(StateDefinition defaultToState) {
+ this.defaultToState = defaultToState;
+ }
+
+ public List<DecisionReviewDefinition> getDecisionReviews() {
+ return decisionReviews;
+ }
+
+ public List<PeerReviewDefinition> getPeerReviews() {
+ return peerReviews;
+ }
+
+ public int getStateWeight() {
+ return percentWeight;
+ }
+
+ /**
+ * Set how much (of 100%) this state's percent complete will contribute to the full percent complete of work
+ * definitions.
+ *
+ * @param percentWeight int value where all stateWeights in workdefinition == 100
+ */
+ public void setPercentWeight(int percentWeight) {
+ this.percentWeight = percentWeight;
+ }
+
+ public void setRecommendedPercentComplete(int recommendedPercentComplete) {
+ this.recommendedPercentComplete = recommendedPercentComplete;
+ }
+
+ public int getRecommendedPercentComplete() {
+ return recommendedPercentComplete;
+ }
+
+ public void setColor(StateColor stateColor) {
+ this.color = stateColor;
+ }
+
+ public StateColor getColor() {
+ return color;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateEventType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateEventType.java
new file mode 100644
index 00000000000..07c2a64e882
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateEventType.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workdef;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum StateEventType {
+ None,
+ TransitionTo,
+ CreateBranch,
+ CommitBranch;
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateItem.java
new file mode 100644
index 00000000000..086bc3571dd
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/StateItem.java
@@ -0,0 +1,14 @@
+/*
+ * Created on Dec 16, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+public class StateItem extends AbstractWorkDefItem {
+
+ public StateItem(String name) {
+ super(name);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetDefinition.java
new file mode 100644
index 00000000000..9e01e5dcd82
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetDefinition.java
@@ -0,0 +1,89 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+public class WidgetDefinition extends StateItem {
+
+ private String attributeName;
+ private String toolTip;
+ private String description;
+ private int height;
+ private String xWidgetName;
+ private String defaultValue;
+ private final WidgetOptionHandler options = new WidgetOptionHandler();
+
+ public WidgetDefinition(String name) {
+ super(name);
+ }
+
+ public String getAtrributeName() {
+ return attributeName;
+ }
+
+ public void setAttributeName(String storeName) {
+ this.attributeName = storeName;
+ }
+
+ public String getToolTip() {
+ return toolTip;
+ }
+
+ public void setToolTip(String toolTip) {
+ this.toolTip = toolTip;
+ }
+
+ public boolean is(WidgetOption widgetOption) {
+ return options.contains(widgetOption);
+ }
+
+ public void set(WidgetOption widgetOption) {
+ options.add(widgetOption);
+ }
+
+ public String getXWidgetName() {
+ return xWidgetName;
+ }
+
+ public void setXWidgetName(String xWidgetName) {
+ this.xWidgetName = xWidgetName;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("[%s][%s]", getName(), getAtrributeName());
+ }
+
+ public WidgetOptionHandler getOptions() {
+ return options;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOption.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOption.java
new file mode 100644
index 00000000000..cbaec87cb9f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOption.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workdef;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum WidgetOption {
+ NONE,
+
+ REQUIRED_FOR_TRANSITION,
+ NOT_REQUIRED_FOR_TRANSITION,
+
+ REQUIRED_FOR_COMPLETION,
+ NOT_REQUIRED_FOR_COMPLETION,
+
+ ENABLED,
+ NOT_ENABLED,
+
+ EDITABLE,
+ NOT_EDITABLE,
+
+ MULTI_SELECT,
+
+ HORIZONTAL_LABEL,
+ VERTICAL_LABEL,
+
+ LABEL_AFTER,
+ LABEL_BEFORE,
+
+ NO_LABEL,
+
+ SORTED,
+
+ ADD_DEFAULT_VALUE,
+ NO_DEFAULT_VALUE,
+
+ BEGIN_COMPOSITE_4,
+ BEGIN_COMPOSITE_6,
+ BEGIN_COMPOSITE_8,
+ BEGIN_COMPOSITE_10,
+ END_COMPOSITE,
+
+ // Fill Options
+ FILL_NONE,
+ FILL_HORIZONTALLY,
+ FILL_VERTICALLY,
+
+ // Align Options
+ ALIGN_LEFT,
+ ALIGN_RIGHT,
+ ALIGN_CENTER;
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOptionHandler.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOptionHandler.java
new file mode 100644
index 00000000000..4f0bb9660f0
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WidgetOptionHandler.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class WidgetOptionHandler {
+
+ private final Set<WidgetOption> options = new HashSet<WidgetOption>();
+
+ public WidgetOptionHandler(WidgetOption... xOption) {
+ set(xOption);
+ }
+
+ public static Collection<WidgetOption> getCollection(WidgetOption... ats) {
+ Set<WidgetOption> items = new HashSet<WidgetOption>();
+ for (WidgetOption item : ats) {
+ items.add(item);
+ }
+ return items;
+ }
+
+ public void add(WidgetOption xOption) {
+ if (xOption.name().startsWith("ALIGN_")) {
+ options.remove(WidgetOption.ALIGN_CENTER);
+ options.remove(WidgetOption.ALIGN_LEFT);
+ options.remove(WidgetOption.ALIGN_RIGHT);
+ } else if (xOption == WidgetOption.HORIZONTAL_LABEL) {
+ options.remove(WidgetOption.VERTICAL_LABEL);
+ } else if (xOption == WidgetOption.EDITABLE) {
+ options.remove(WidgetOption.NOT_EDITABLE);
+ } else if (xOption == WidgetOption.NOT_EDITABLE) {
+ options.remove(WidgetOption.EDITABLE);
+ } else if (xOption == WidgetOption.NOT_REQUIRED_FOR_COMPLETION) {
+ options.remove(WidgetOption.REQUIRED_FOR_COMPLETION);
+ } else if (xOption == WidgetOption.REQUIRED_FOR_COMPLETION) {
+ options.remove(WidgetOption.NOT_REQUIRED_FOR_COMPLETION);
+ } else if (xOption == WidgetOption.NOT_REQUIRED_FOR_TRANSITION) {
+ options.remove(WidgetOption.REQUIRED_FOR_TRANSITION);
+ } else if (xOption == WidgetOption.REQUIRED_FOR_TRANSITION) {
+ options.remove(WidgetOption.NOT_REQUIRED_FOR_TRANSITION);
+ } else if (xOption == WidgetOption.NOT_ENABLED) {
+ options.remove(WidgetOption.ENABLED);
+ } else if (xOption == WidgetOption.ENABLED) {
+ options.remove(WidgetOption.NOT_ENABLED);
+ } else if (xOption == WidgetOption.FILL_NONE) {
+ options.remove(WidgetOption.FILL_HORIZONTALLY);
+ options.remove(WidgetOption.FILL_VERTICALLY);
+ } else if (xOption == WidgetOption.VERTICAL_LABEL) {
+ options.remove(WidgetOption.HORIZONTAL_LABEL);
+ }
+ options.add(xOption);
+ }
+
+ public void add(WidgetOption... xOption) {
+ for (WidgetOption xOpt : xOption) {
+ add(xOpt);
+ }
+ }
+
+ public void add(Collection<WidgetOption> xOption) {
+ for (WidgetOption xOpt : xOption) {
+ add(xOpt);
+ }
+ }
+
+ public boolean contains(WidgetOption xOption) {
+ return options.contains(xOption);
+ }
+
+ public Set<WidgetOption> getXOptions() {
+ return options;
+ }
+
+ public void set(Set<WidgetOption> options) {
+ this.options.clear();
+ // Must go through the add method to ensure values set properly
+ for (WidgetOption xOption : options) {
+ add(xOption);
+ }
+ }
+
+ public void set(WidgetOption options[]) {
+ this.options.clear();
+ // Must go through the add method to ensure values set properly
+ for (WidgetOption xOption : options) {
+ add(xOption);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(options);
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinition.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinition.java
new file mode 100644
index 00000000000..769dd52c5e5
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinition.java
@@ -0,0 +1,205 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osee.ats.core.internal.Activator;
+
+public class WorkDefinition extends AbstractWorkDefItem {
+
+ private final List<StateDefinition> states = new ArrayList<StateDefinition>(5);
+ private final List<RuleDefinition> rules = new ArrayList<RuleDefinition>(5);
+ private final Set<String> ids = new HashSet<String>();
+ private StateDefinition startState;
+ private String version;
+
+ public WorkDefinition(String name) {
+ super(name);
+ ids.add(name);
+ }
+
+ public List<StateDefinition> getStates() {
+ return states;
+ }
+
+ public List<StateDefinition> getStatesOrdered() {
+ if (startState == null) {
+ throw new IllegalArgumentException("Can't locate Start State for workflow " + getName());
+ }
+
+ // Get ordered pages starting with start page
+ List<StateDefinition> orderedPages = new ArrayList<StateDefinition>();
+ getOrderedStates(startState, orderedPages);
+
+ // Move completed to the end if it exists
+ StateDefinition completedPage = null;
+ for (StateDefinition stateDefinition : orderedPages) {
+ if (stateDefinition.isCompletedPage()) {
+ completedPage = stateDefinition;
+ }
+ }
+ if (completedPage != null) {
+ orderedPages.remove(completedPage);
+ orderedPages.add(completedPage);
+ }
+ // for (WorkPage wPage : orderedPages)
+ // System.out.println("Ordered Page: - " + wPage);
+ return orderedPages;
+ }
+
+ private void getOrderedStates(StateDefinition stateDefinition, List<StateDefinition> pages) {
+ if (pages.contains(stateDefinition)) {
+ return;
+ }
+ // Add this page first
+ pages.add(stateDefinition);
+ // Add default page
+ StateDefinition defaultToState = getDefaultToState(stateDefinition);
+ if (defaultToState != null && !defaultToState.getName().equals(stateDefinition.getName())) {
+ getOrderedStates(getDefaultToState(stateDefinition), pages);
+ }
+ // Add remaining pages
+ for (StateDefinition stateDef : stateDefinition.getToStates()) {
+ if (!pages.contains(stateDef)) {
+ getOrderedStates(stateDef, pages);
+ }
+ }
+ }
+
+ public StateDefinition getDefaultToState(StateDefinition stateDefinition) {
+ return stateDefinition.getDefaultToState();
+ }
+
+ public Collection<String> getStateNames() {
+ List<String> names = new ArrayList<String>();
+ for (StateDefinition state : states) {
+ names.add(state.getName());
+ }
+ return names;
+ }
+
+ public StateDefinition getStateByName(String name) {
+ for (StateDefinition state : states) {
+ if (state.getName().equals(name)) {
+ return state;
+ }
+ }
+ return null;
+ }
+
+ public boolean hasRule(String name) {
+ for (RuleDefinition rule : rules) {
+ if (rule.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List<RuleDefinition> getRulesStartsWith(String name) {
+ List<RuleDefinition> results = new ArrayList<RuleDefinition>();
+ for (RuleDefinition rule : rules) {
+ if (rule.getName().startsWith(name)) {
+ results.add(rule);
+ }
+ }
+ return results;
+ }
+
+ public List<RuleDefinition> getRules() {
+ return rules;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ AbstractWorkDefItem other = (AbstractWorkDefItem) obj;
+ if (getName() == null) {
+ if (other.getName() != null) {
+ return false;
+ }
+ } else if (!getName().equals(other.getName())) {
+ return false;
+ }
+ return true;
+ }
+
+ public StateDefinition getOrCreateState(String name) {
+ StateDefinition stateDef = getStateByName(name);
+ if (stateDef == null) {
+ stateDef = new StateDefinition(name);
+ getStates().add(stateDef);
+ }
+ return stateDef;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public StateDefinition getStartState() {
+ return startState;
+ }
+
+ public void setStartState(StateDefinition startState) {
+ this.startState = startState;
+ }
+
+ public Set<String> getIds() {
+ return ids;
+ }
+
+ public boolean isStateWeightingEnabled() {
+ for (StateDefinition stateDef : getStates()) {
+ if (stateDef.getStateWeight() != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public IStatus validateStateWeighting() {
+ if (!isStateWeightingEnabled()) {
+ return Status.OK_STATUS;
+ }
+ int total = 0;
+ for (StateDefinition stateDef : getStates()) {
+ total += stateDef.getStateWeight();
+ }
+ if (total != 100) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format(
+ "Total weight only %d, needs to equal 100 for all states", total));
+ }
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactory.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactory.java
new file mode 100644
index 00000000000..473d1382ae3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactory.java
@@ -0,0 +1,256 @@
+/*
+ * Created on Dec 15, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkflowProviders;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.util.WorkflowManagerCore;
+import org.eclipse.osee.ats.core.workdef.provider.AtsWorkDefinitionProviderCore;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.ITeamWorkflowProvider;
+import org.eclipse.osee.framework.core.enums.DeletionFlag;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+
+public class WorkDefinitionFactory {
+
+ // Cache the WorkDefinition used for each AbstractWorkflowId so don't have to recompute each time
+ private static final Map<String, WorkDefinitionMatch> awaHridToWorkDefinitions =
+ new HashMap<String, WorkDefinitionMatch>();
+ // Cache the WorkDefinition object for each WorkDefinition id so don't have to reload
+ // This grows as WorkDefinitions are requested/loaded
+ private static final Map<String, WorkDefinitionMatch> workDefIdToWorkDefintion =
+ new HashMap<String, WorkDefinitionMatch>();
+ public static final String TaskWorkflowDefinitionId = "osee.ats.taskWorkflow";
+ public static final String GoalWorkflowDefinitionId = "osee.ats.goalWorkflow";
+ public static final String PeerToPeerWorkflowDefinitionId = "osee.ats.peerToPeerReview";
+ public static final String DecisionWorkflowDefinitionId = "osee.ats.decisionReview";
+
+ public static void clearCaches() {
+ awaHridToWorkDefinitions.clear();
+ workDefIdToWorkDefintion.clear();
+ }
+
+ public static WorkDefinitionMatch getWorkDefinition(Artifact artifact) throws OseeCoreException {
+ if (!awaHridToWorkDefinitions.containsKey(artifact.getHumanReadableId())) {
+ WorkDefinitionMatch match = getWorkDefinitionNew(artifact);
+ if (!match.isMatched()) {
+ match = WorkDefinitionFactoryLegacyMgr.getWorkFlowDefinitionFromArtifact(artifact);
+ }
+ awaHridToWorkDefinitions.put(artifact.getHumanReadableId(), match);
+ }
+ return awaHridToWorkDefinitions.get(artifact.getHumanReadableId());
+ }
+
+ public static WorkDefinitionMatch getWorkDefinition(String id) throws OseeCoreException {
+ if (!workDefIdToWorkDefintion.containsKey(id)) {
+ WorkDefinitionMatch match = new WorkDefinitionMatch();
+ String translatedId = WorkDefinitionFactory.getOverrideWorkDefId(id);
+ // Try to get from new DSL provider if configured to use it
+ if (!match.isMatched()) {
+ WorkDefinition workDef = AtsWorkDefinitionProviderCore.get().getWorkFlowDefinition(translatedId);
+ if (workDef != null) {
+ match.setWorkDefinition(workDef);
+ match.addTrace((String.format("from DSL provider loaded id [%s] and override translated Id [%s]", id,
+ translatedId)));
+ }
+ }
+ // Otherwise, just translate legacy WorkFlowDefinition from artifact
+ if (!match.isMatched()) {
+ match = WorkDefinitionFactoryLegacyMgr.getWorkFlowDefinitionFromId(id);
+ }
+ // If still no match, configuration may have new workdef id but not set to use them
+ // Attempt to get back to original id and load through WorkFlowDefinition translate
+ if (!match.isMatched()) {
+ match = WorkDefinitionFactoryLegacyMgr.getWorkFlowDefinitionFromReverseId(id);
+ }
+ if (match.isMatched()) {
+ System.out.println("Loaded " + match);
+ workDefIdToWorkDefintion.put(id, match);
+ }
+ }
+ WorkDefinitionMatch match = workDefIdToWorkDefintion.get(id);
+ if (match == null) {
+ match = new WorkDefinitionMatch();
+ }
+ return match;
+ }
+
+ private static WorkDefinitionMatch getWorkDefinitionFromArtifactsAttributeValue(Artifact artifact) throws OseeCoreException {
+ // If this artifact specifies it's own workflow definition, use it
+ String workFlowDefId = artifact.getSoleAttributeValue(AtsAttributeTypes.WorkflowDefinition, null);
+ if (Strings.isValid(workFlowDefId)) {
+ String translatedId = WorkDefinitionFactory.getOverrideWorkDefId(workFlowDefId);
+ WorkDefinitionMatch match = getWorkDefinition(translatedId);
+ if (match.isMatched()) {
+ match.addTrace(String.format("from artifact [%s] for id [%s] and override translated Id [%s]", artifact,
+ workFlowDefId, translatedId));
+ return match;
+ }
+ }
+ return new WorkDefinitionMatch();
+ }
+
+ private static WorkDefinitionMatch getTaskWorkDefinitionFromArtifactsAttributeValue(Artifact artifact) throws OseeCoreException {
+ // If this artifact specifies it's own workflow definition, use it
+ String workFlowDefId = artifact.getSoleAttributeValue(AtsAttributeTypes.RelatedTaskWorkDefinition, null);
+ if (Strings.isValid(workFlowDefId)) {
+ String translatedId = WorkDefinitionFactory.getOverrideWorkDefId(workFlowDefId);
+ WorkDefinitionMatch match = getWorkDefinition(translatedId);
+ if (match.isMatched()) {
+ match.addTrace(String.format("from artifact [%s] for id [%s] and override translated Id [%s]", artifact,
+ workFlowDefId, translatedId));
+ return match;
+ }
+ }
+ return new WorkDefinitionMatch();
+ }
+
+ /**
+ * Look at team def's attribute for Work Definition setting, otherwise, walk up team tree for setting
+ */
+ private static WorkDefinitionMatch getWorkDefinitionFromTeamDefinitionAttributeInherited(TeamDefinitionArtifact teamDef) throws OseeCoreException {
+ WorkDefinitionMatch match = getWorkDefinitionFromArtifactsAttributeValue(teamDef);
+ if (match.isMatched()) {
+ return match;
+ }
+ Artifact parentArt = teamDef.getParent();
+ if (parentArt != null && parentArt instanceof TeamDefinitionArtifact) {
+ return getWorkDefinitionFromTeamDefinitionAttributeInherited((TeamDefinitionArtifact) parentArt);
+ }
+ return new WorkDefinitionMatch();
+ }
+
+ private static WorkDefinitionMatch getWorkDefinitionForTask(Artifact taskArt) throws OseeCoreException {
+ WorkDefinitionMatch match = new WorkDefinitionMatch();
+ AbstractWorkflowArtifact parentAwa = WorkflowManagerCore.getParentAWA(taskArt);
+ for (ITeamWorkflowProvider provider : TeamWorkflowProviders.getAtsTeamWorkflowExtensions()) {
+ String workFlowDefId = provider.getRelatedTaskWorkflowDefinitionId(parentAwa);
+ if (Strings.isValid(workFlowDefId)) {
+ String translatedId = getOverrideWorkDefId(workFlowDefId);
+ match = WorkDefinitionFactory.getWorkDefinition(translatedId);
+ match.addTrace((String.format("from provider [%s] for id [%s] and override translated Id [%s]",
+ provider.getClass().getSimpleName(), workFlowDefId, translatedId)));
+ break;
+ }
+ }
+ if (!match.isMatched()) {
+ // If task specifies it's own workflow id, use it
+ match = getWorkDefinitionFromArtifactsAttributeValue(taskArt);
+ }
+ if (!match.isMatched()) {
+ // Else If parent SMA has a related task definition workflow id specified, use it
+ WorkDefinitionMatch match2 = getTaskWorkDefinitionFromArtifactsAttributeValue(parentAwa);
+ if (match2.isMatched()) {
+ match2.addTrace(String.format("from task parent SMA [%s]", parentAwa));
+ match = match2;
+ }
+ }
+ if (!match.isMatched()) {
+ // Else If parent TeamWorkflow's TeamDefinition has a related task definition workflow id, use it
+ match = getTaskWorkDefinitionFromArtifactsAttributeValue(WorkflowManagerCore.getTeamDefinition(taskArt));
+ }
+ if (!match.isMatched()) {
+ // Else, use default Task workflow
+ String translatedId = getOverrideWorkDefId(TaskWorkflowDefinitionId);
+ match = getWorkDefinition(translatedId);
+ if (match.isMatched()) {
+ match.addTrace(String.format("default TaskWorkflowDefinition ID [%s] and override translated Id [%s]",
+ TaskWorkflowDefinitionId, translatedId));
+ }
+ }
+ return match;
+ }
+
+ private static WorkDefinitionMatch getWorkDefinitionNew(Artifact artifact) throws OseeCoreException {
+ WorkDefinitionMatch match = new WorkDefinitionMatch();
+ if (artifact.isOfType(AtsArtifactTypes.Task)) {
+ match = getWorkDefinitionForTask(artifact);
+ }
+ if (!match.isMatched() && artifact instanceof AbstractWorkflowArtifact) {
+ AbstractWorkflowArtifact aba = (AbstractWorkflowArtifact) artifact;
+ // Check extensions for definition handling
+ for (ITeamWorkflowProvider provider : TeamWorkflowProviders.getAtsTeamWorkflowExtensions()) {
+ String workFlowDefId = provider.getWorkflowDefinitionId(aba);
+ if (Strings.isValid(workFlowDefId)) {
+ match =
+ WorkDefinitionFactory.getWorkDefinition(WorkDefinitionFactory.getOverrideWorkDefId(workFlowDefId));
+ }
+ }
+ if (!match.isMatched()) {
+ // If this artifact specifies it's own workflow definition, use it
+ match = getWorkDefinitionFromArtifactsAttributeValue(artifact);
+ if (!match.isMatched()) {
+ // Otherwise, use workflow defined by attribute of WorkflowDefinition
+ // Note: This is new. Old TeamDefs got workflow off relation
+ if (artifact.isOfType(AtsArtifactTypes.TeamWorkflow)) {
+ TeamDefinitionArtifact teamDef = ((TeamWorkFlowArtifact) artifact).getTeamDefinition();
+ match = getWorkDefinitionFromTeamDefinitionAttributeInherited(teamDef);
+ if (!match.isMatched()) {
+ match = ((TeamWorkFlowArtifact) artifact).getTeamDefinition().getWorkDefinition();
+ }
+ } else if (artifact.isOfType(AtsArtifactTypes.Goal)) {
+ match = getWorkDefinition(getOverrideWorkDefId(GoalWorkflowDefinitionId));
+ match.addTrace(String.format("Override translated from id [%s]", GoalWorkflowDefinitionId));
+ } else if (artifact.isOfType(AtsArtifactTypes.PeerToPeerReview)) {
+ match = getWorkDefinition(getOverrideWorkDefId(PeerToPeerWorkflowDefinitionId));
+ match.addTrace(String.format("Override translated from id [%s]", PeerToPeerWorkflowDefinitionId));
+ } else if (artifact.isOfType(AtsArtifactTypes.DecisionReview)) {
+ match = getWorkDefinition(getOverrideWorkDefId(DecisionWorkflowDefinitionId));
+ match.addTrace(String.format("Override translated from id [%s]", DecisionWorkflowDefinitionId));
+ }
+ }
+ }
+ }
+ return match;
+ }
+
+ public static Set<String> errorDisplayed = new HashSet<String>();
+
+ public static String getOverrideWorkDefId(String id) {
+ // Don't override if no providers available (dsl plugins not released)
+ String overrideId = WorkDefinitionFactoryLegacyMgr.getOverrideId(id);
+ if (Strings.isValid(overrideId)) {
+ // Only display this override once in log
+ if (!errorDisplayed.contains(overrideId)) {
+ OseeLog.log(Activator.class, Level.INFO,
+ String.format("Override WorkDefinition [%s] with [%s]", id, overrideId));
+ errorDisplayed.add(overrideId);
+ }
+ return overrideId;
+ }
+ return id;
+ }
+
+ public static Set<WorkDefinition> loadAllDefinitions() throws OseeCoreException {
+ Set<WorkDefinition> workDefs = new HashSet<WorkDefinition>();
+ // This load is faster than loading each by artifact type
+ for (Artifact art : ArtifactQuery.getArtifactListFromType(AtsArtifactTypes.WorkDefinition,
+ AtsUtilCore.getAtsBranch(), DeletionFlag.EXCLUDE_DELETED)) {
+ try {
+ WorkDefinition workDef = AtsWorkDefinitionProviderCore.get().loadWorkDefinitionFromArtifact(art);
+ workDefs.add(workDef);
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE,
+ "Error loading WorkDefinition from artifact " + art.toStringWithId(), ex);
+ }
+ }
+ return workDefs;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactoryLegacyMgr.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactoryLegacyMgr.java
new file mode 100644
index 00000000000..1aacd542296
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionFactoryLegacyMgr.java
@@ -0,0 +1,91 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class WorkDefinitionFactoryLegacyMgr {
+
+ public static WorkDefinitionMatch getWorkFlowDefinitionFromId(String id) throws OseeCoreException {
+ ensureLoaded();
+ return legacyMgr.getWorkFlowDefinitionFromId(id);
+ }
+
+ public static WorkDefinitionMatch getWorkFlowDefinitionFromReverseId(String id) throws OseeCoreException {
+ ensureLoaded();
+ return legacyMgr.getWorkFlowDefinitionFromReverseId(id);
+ }
+
+ public static WorkDefinitionMatch getWorkFlowDefinitionFromArtifact(Artifact artifact) throws OseeCoreException {
+ ensureLoaded();
+ return legacyMgr.getWorkFlowDefinitionFromArtifact(artifact);
+ }
+
+ public static WorkDefinitionMatch getWorkFlowDefinitionFromTeamDefinition(TeamDefinitionArtifact teamDefinition) throws OseeCoreException {
+ ensureLoaded();
+ return legacyMgr.getWorkFlowDefinitionFromTeamDefition(teamDefinition);
+ }
+
+ public static String getOverrideId(String legacyId) {
+ ensureLoaded();
+ return legacyMgr.getOverrideId(legacyId);
+ }
+
+ private static IWorkDefintionFactoryLegacyMgr legacyMgr;
+
+ /*
+ * due to lazy initialization, this function is non-reentrant therefore, the synchronized keyword is necessary
+ */
+ public synchronized static void ensureLoaded() {
+ if (legacyMgr == null) {
+
+ IExtensionPoint point =
+ Platform.getExtensionRegistry().getExtensionPoint(
+ "org.eclipse.osee.ats.core.AtsLegacyWorkDefinitionProvider");
+ if (point == null) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP,
+ "Can't access AtsLegacyWorkDefinitionProvider extension point");
+ }
+ IExtension[] extensions = point.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ String classname = null;
+ String bundleName = null;
+ for (IConfigurationElement el : elements) {
+ if (el.getName().equals("AtsLegacyWorkDefinitionProvider")) {
+ classname = el.getAttribute("classname");
+ bundleName = el.getContributor().getName();
+ if (classname != null && bundleName != null) {
+ Bundle bundle = Platform.getBundle(bundleName);
+ try {
+ Class<?> taskClass = bundle.loadClass(classname);
+ Object obj = taskClass.newInstance();
+ legacyMgr = (IWorkDefintionFactoryLegacyMgr) obj;
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP,
+ "Error loading AtsLegacyWorkDefinitionProvider extension", ex);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionMatch.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionMatch.java
new file mode 100644
index 00000000000..9e1aaeeedd4
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionMatch.java
@@ -0,0 +1,54 @@
+/*
+ * Created on Jan 10, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+
+public class WorkDefinitionMatch {
+
+ private WorkDefinition workDefinition;
+ private final List<String> trace = new ArrayList<String>();
+
+ public WorkDefinitionMatch() {
+ this(null, null);
+ }
+
+ public WorkDefinitionMatch(WorkDefinition WorkDefinition, String trace) {
+ this.workDefinition = WorkDefinition;
+ if (Strings.isValid(trace)) {
+ this.trace.add(trace);
+ }
+ }
+
+ public WorkDefinition getWorkDefinition() {
+ return workDefinition;
+ }
+
+ public void setWorkDefinition(WorkDefinition WorkDefinition) {
+ this.workDefinition = WorkDefinition;
+ }
+
+ public void addTrace(String traceStr) {
+ if (trace.size() == 0 || (trace.size() >= 1 && !trace.get(trace.size() - 1).equals(traceStr))) {
+ trace.add(traceStr);
+ }
+ }
+
+ public List<String> getTrace() {
+ return trace;
+ }
+
+ public boolean isMatched() {
+ return workDefinition != null;
+ }
+
+ @Override
+ public String toString() {
+ return workDefinition.getName();
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionSheet.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionSheet.java
new file mode 100644
index 00000000000..cc953d065d6
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefinitionSheet.java
@@ -0,0 +1,39 @@
+/*
+ * Created on Jan 19, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef;
+
+import java.io.File;
+
+public class WorkDefinitionSheet {
+
+ public File file;
+ public String name;
+ public String legacyOverrideId;
+
+ public WorkDefinitionSheet(String name, String legacyOverrideId, File file) {
+ super();
+ this.file = file;
+ this.name = name;
+ this.legacyOverrideId = legacyOverrideId;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getLegacyOverrideId() {
+ return legacyOverrideId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s filename[%s] overrideId[%s]", name, file, legacyOverrideId);
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/AtsWorkDefinitionProviderCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/AtsWorkDefinitionProviderCore.java
new file mode 100644
index 00000000000..ab152d15ab9
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/AtsWorkDefinitionProviderCore.java
@@ -0,0 +1,65 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef.provider;
+
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workdef.ConvertAtsDslToWorkDefinition;
+import org.eclipse.osee.ats.core.workdef.ModelUtil;
+import org.eclipse.osee.ats.core.workdef.WorkDefinition;
+import org.eclipse.osee.ats.dsl.atsDsl.AtsDsl;
+import org.eclipse.osee.framework.core.exception.ArtifactDoesNotExist;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeWrappedException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsWorkDefinitionProviderCore {
+
+ private static AtsWorkDefinitionProviderCore provider = new AtsWorkDefinitionProviderCore();
+
+ public static AtsWorkDefinitionProviderCore get() {
+ return provider;
+ }
+
+ public WorkDefinition getWorkFlowDefinition(String id) throws OseeCoreException {
+ WorkDefinition workDef = loadWorkDefinitionFromArtifact(id);
+ return workDef;
+ }
+
+ private WorkDefinition loadWorkDefinitionFromArtifact(String name) throws OseeCoreException {
+ Artifact artifact = null;
+ try {
+ artifact =
+ ArtifactQuery.getArtifactFromTypeAndName(AtsArtifactTypes.WorkDefinition, name,
+ BranchManager.getCommonBranch());
+ return loadWorkDefinitionFromArtifact(artifact);
+ } catch (ArtifactDoesNotExist ex) {
+ // do nothing
+ } catch (Exception ex) {
+ throw new OseeWrappedException(String.format("Error loading AtsDsl [%s] from Artifact", name), ex);
+ }
+ return null;
+ }
+
+ public WorkDefinition loadWorkDefinitionFromArtifact(Artifact artifact) throws OseeCoreException {
+ String modelText = artifact.getAttributesToString(AtsAttributeTypes.DslSheet);
+ String modelName = artifact.getName() + ".ats";
+ AtsDsl atsDsl = loadAtsDsl(modelName, modelText);
+ ConvertAtsDslToWorkDefinition converter = new ConvertAtsDslToWorkDefinition(modelName, atsDsl);
+ return converter.convert();
+ };
+
+ public static AtsDsl loadAtsDsl(String name, String modelText) throws OseeCoreException {
+ AtsDsl atsDsl = ModelUtil.loadModel(name, modelText);
+ return atsDsl;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/BooleanDefUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/BooleanDefUtil.java
new file mode 100644
index 00000000000..03ba022805d
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/BooleanDefUtil.java
@@ -0,0 +1,22 @@
+/*
+ * Created on Feb 2, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef.provider;
+
+import org.eclipse.osee.ats.dsl.atsDsl.BooleanDef;
+
+public class BooleanDefUtil {
+
+ /**
+ * @return if BooleanDef == null return defaultValue, else true or false
+ */
+ public static boolean get(BooleanDef booleanDef, boolean defaultValue) {
+ if (booleanDef != null && booleanDef != BooleanDef.NONE) {
+ return booleanDef == BooleanDef.TRUE;
+ }
+ return defaultValue;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/UserRefUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/UserRefUtil.java
new file mode 100644
index 00000000000..5ba71ff57d2
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/provider/UserRefUtil.java
@@ -0,0 +1,56 @@
+/*
+ * Created on Feb 2, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workdef.provider;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.osee.ats.dsl.atsDsl.UserByName;
+import org.eclipse.osee.ats.dsl.atsDsl.UserByUserId;
+import org.eclipse.osee.ats.dsl.atsDsl.UserRef;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+public class UserRefUtil {
+
+ public static Set<String> getUserIds(EList<UserRef> userRefs) {
+ Set<String> userIds = new HashSet<String>();
+ for (UserRef UserRef : userRefs) {
+ if (UserRef instanceof UserByUserId) {
+ userIds.add(((UserByUserId) UserRef).getUserId());
+ }
+ }
+ return userIds;
+ }
+
+ public static Set<String> getUserNames(EList<UserRef> userRefs) {
+ Set<String> userNames = new HashSet<String>();
+ for (UserRef UserRef : userRefs) {
+ if (UserRef instanceof UserByName) {
+ userNames.add(Strings.unquote(((UserByName) UserRef).getUserName()));
+ }
+ }
+ return userNames;
+ }
+
+ public static Set<Artifact> getUsers(EList<UserRef> userRefs) throws OseeCoreException {
+ Set<Artifact> users = new HashSet<Artifact>();
+ if (userRefs != null) {
+ for (String userId : getUserIds(userRefs)) {
+ User user = UserManager.getUserByUserId(userId);
+ users.add(user);
+ }
+ for (String userName : getUserNames(userRefs)) {
+ User user = UserManager.getUserByName(Strings.unquote(userName));
+ users.add(user);
+ }
+ }
+ return users;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AbstractWorkflowArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AbstractWorkflowArtifact.java
new file mode 100644
index 00000000000..72ff4c48af1
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AbstractWorkflowArtifact.java
@@ -0,0 +1,822 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osee.ats.core.artifact.AbstractAtsArtifact;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.AbstractReviewArtifact;
+import org.eclipse.osee.ats.core.review.ReviewManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.version.TargetedVersionUtil;
+import org.eclipse.osee.ats.core.version.VersionArtifact;
+import org.eclipse.osee.ats.core.workdef.RuleDefinitionOption;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workdef.WorkDefinition;
+import org.eclipse.osee.ats.core.workdef.WorkDefinitionFactory;
+import org.eclipse.osee.ats.core.workdef.WorkDefinitionMatch;
+import org.eclipse.osee.ats.core.workflow.log.ArtifactLog;
+import org.eclipse.osee.ats.core.workflow.log.AtsLog;
+import org.eclipse.osee.ats.core.workflow.log.LogItem;
+import org.eclipse.osee.ats.core.workflow.log.LogType;
+import org.eclipse.osee.ats.core.workflow.note.ArtifactNote;
+import org.eclipse.osee.ats.core.workflow.note.AtsNote;
+import org.eclipse.osee.ats.core.workflow.transition.TransitionManager;
+import org.eclipse.osee.framework.access.AccessControlManager;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.data.IRelationTypeSide;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.enums.DeletionFlag;
+import org.eclipse.osee.framework.core.enums.PermissionEnum;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.core.services.CmAccessControl;
+import org.eclipse.osee.framework.core.services.HasCmAccessControl;
+import org.eclipse.osee.framework.core.util.IGroupExplorerProvider;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+import org.eclipse.osee.framework.skynet.core.artifact.Attribute;
+import org.eclipse.osee.framework.skynet.core.relation.RelationLink;
+import org.eclipse.osee.framework.skynet.core.relation.RelationManager;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class AbstractWorkflowArtifact extends AbstractAtsArtifact implements HasCmAccessControl, IGroupExplorerProvider {
+
+ private final Set<IRelationTypeSide> atsWorldRelations = new HashSet<IRelationTypeSide>();
+ private Collection<User> transitionAssignees;
+ protected AbstractWorkflowArtifact parentAwa;
+ protected TeamWorkFlowArtifact parentTeamArt;
+ protected ActionArtifact parentAction;
+ private StateManager stateMgr;
+ private AtsLog atsLog;
+ private AtsNote atsNote;
+ private boolean inTransition = false;
+ private boolean targetedErrorLogged = false;
+
+ public AbstractWorkflowArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ @Override
+ public void onBirth() throws OseeCoreException {
+ super.onBirth();
+ if (getSoleAttributeValue(AtsAttributeTypes.CurrentStateType, null) == null) {
+ if (getSoleAttributeValue(AtsAttributeTypes.CurrentState, null) == null) {
+ setSoleAttributeValue(AtsAttributeTypes.CurrentState, "");
+ }
+ if (isAttributeTypeValid(AtsAttributeTypes.CurrentStateType)) {
+ setSoleAttributeValue(AtsAttributeTypes.CurrentStateType, WorkPageType.Working.name());
+ }
+ }
+ }
+
+ @Override
+ public void onInitializationComplete() throws OseeCoreException {
+ super.onInitializationComplete();
+ initializeSMA();
+ }
+
+ @SuppressWarnings("unused")
+ protected void initializeSMA() throws OseeCoreException {
+ initalizePreSaveCache();
+ }
+
+ public void initalizePreSaveCache() {
+ try {
+ stateMgr = new StateManager(this);
+ atsLog = new AtsLog(new ArtifactLog(this));
+ atsNote = new AtsNote(new ArtifactNote(this));
+ // TODO Add this back in
+ // AtsNotification.notifyNewAssigneesAndReset(this, true);
+ // AtsNotification.notifyOriginatorAndReset(this, true);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ public void initializeNewStateMachine(Collection<User> assignees, Date createdDate, User createdBy) throws OseeCoreException {
+ StateDefinition startState = getWorkDefinition().getStartState();
+ initializeNewStateMachine(startState, assignees, createdDate, createdBy);
+ }
+
+ public void initializeNewStateMachine(IWorkPage state, Collection<User> assignees, Date createdDate, User createdBy) throws OseeCoreException {
+ getStateMgr().initializeStateMachine(state, assignees);
+ setCreatedBy(createdBy, true, createdDate);
+ (new TransitionManager(this)).logStateStartedEvent(state, createdDate, createdBy);
+ }
+
+ public boolean isTargetedVersionable() throws OseeCoreException {
+ if (!isTeamWorkflow()) {
+ return false;
+ }
+ return ((TeamWorkFlowArtifact) this).getTeamDefinition().getTeamDefinitionHoldingVersions() != null && ((TeamWorkFlowArtifact) this).getTeamDefinition().getTeamDefinitionHoldingVersions().isTeamUsesVersions();
+ }
+
+ public String getArtifactSuperTypeName() {
+ return getArtifactTypeName();
+ }
+
+ @SuppressWarnings("unused")
+ public Collection<User> getImplementers() throws OseeCoreException {
+ return Collections.emptyList();
+ }
+
+ @SuppressWarnings("unused")
+ public double getWorldViewWeeklyBenefit() throws OseeCoreException {
+ return 0;
+ }
+
+ @Override
+ public void onAttributePersist(SkynetTransaction transaction) {
+ // Since multiple ways exist to change the assignees, notification is performed on the persist
+ if (isDeleted()) {
+ return;
+ }
+ try {
+ // TODO Add this back in
+ // AtsNotification.notifyNewAssigneesAndReset(this, false);
+ // AtsNotification.notifyOriginatorAndReset(this, false);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public boolean isValidationRequired() throws OseeCoreException {
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @SuppressWarnings("unused")
+ public AbstractWorkflowArtifact getParentAWA() throws OseeCoreException {
+ return parentAwa;
+ }
+
+ @SuppressWarnings("unused")
+ public Artifact getParentActionArtifact() throws OseeCoreException {
+ return parentAction;
+ }
+
+ @SuppressWarnings("unused")
+ public TeamWorkFlowArtifact getParentTeamWorkflow() throws OseeCoreException {
+ return parentTeamArt;
+ }
+
+ @SuppressWarnings("unused")
+ public String getEditorTitle() throws OseeCoreException {
+ return getType() + ": " + getName();
+ }
+
+ /**
+ * Registers relation as part of the parent/child hierarchy in ATS World
+ */
+ public void registerAtsWorldRelation(IRelationTypeSide typeSideToken) {
+ atsWorldRelations.add(typeSideToken);
+ }
+
+ public void clearCaches() {
+ implementersStr = null;
+ }
+
+ public void atsDelete(Set<Artifact> deleteArts, Map<Artifact, Object> allRelated) throws OseeCoreException {
+ deleteArts.add(this);
+ for (Artifact relative : getBSideArtifacts()) {
+ allRelated.put(relative, this);
+ }
+ }
+
+ private List<Artifact> getBSideArtifacts() throws OseeCoreException {
+ List<Artifact> sideBArtifacts = new ArrayList<Artifact>();
+ List<RelationLink> relatives = getRelationsAll(DeletionFlag.EXCLUDE_DELETED);
+ for (RelationLink link : relatives) {
+ Artifact sideB = link.getArtifactB();
+ if (!sideB.equals(this)) {
+ sideBArtifacts.add(sideB);
+ }
+ }
+
+ return sideBArtifacts;
+ }
+
+ public String getType() {
+ return getArtifactTypeName();
+ }
+
+ public String getCurrentStateName() {
+ return getStateMgr().getCurrentStateName();
+ }
+
+ public boolean isInState(IWorkPage state) {
+ return getStateMgr().isInState(state);
+ }
+
+ public String implementersStr = null;
+
+ public double getEstimatedHoursFromArtifact() throws OseeCoreException {
+ if (isAttributeTypeValid(AtsAttributeTypes.EstimatedHours)) {
+ return getSoleAttributeValue(AtsAttributeTypes.EstimatedHours, 0.0);
+ }
+ return 0;
+ }
+
+ public double getEstimatedHoursFromTasks(IWorkPage relatedToState) throws OseeCoreException {
+ if (!(this instanceof AbstractTaskableArtifact)) {
+ return 0;
+ }
+ return ((AbstractTaskableArtifact) this).getEstimatedHoursFromTasks(relatedToState);
+ }
+
+ public double getEstimatedHoursFromTasks() throws OseeCoreException {
+ if (!(this instanceof AbstractTaskableArtifact)) {
+ return 0;
+ }
+ return ((AbstractTaskableArtifact) this).getEstimatedHoursFromTasks();
+ }
+
+ public double getEstimatedHoursFromReviews() throws OseeCoreException {
+ if (isTeamWorkflow()) {
+ return ReviewManager.getEstimatedHours((TeamWorkFlowArtifact) this);
+ }
+ return 0;
+ }
+
+ public double getEstimatedHoursFromReviews(IWorkPage relatedToState) throws OseeCoreException {
+ if (isTeamWorkflow()) {
+ return ReviewManager.getEstimatedHours((TeamWorkFlowArtifact) this, relatedToState);
+ }
+ return 0;
+ }
+
+ public double getEstimatedHoursTotal(IWorkPage relatedToState) throws OseeCoreException {
+ return getEstimatedHoursFromArtifact() + getEstimatedHoursFromTasks(relatedToState) + getEstimatedHoursFromReviews(relatedToState);
+ }
+
+ public double getEstimatedHoursTotal() throws OseeCoreException {
+ return getEstimatedHoursFromArtifact() + getEstimatedHoursFromTasks() + getEstimatedHoursFromReviews();
+ }
+
+ public double getRemainHoursFromArtifact() throws OseeCoreException {
+ if (isCompleted() || isCancelled()) {
+ return 0;
+ }
+ double est = getSoleAttributeValue(AtsAttributeTypes.EstimatedHours, 0.0);
+ if (est == 0) {
+ return getEstimatedHoursFromArtifact();
+ }
+ return est - est * PercentCompleteTotalUtil.getPercentCompleteTotal(this) / 100.0;
+ }
+
+ public double getRemainHoursTotal() throws OseeCoreException {
+ return getRemainHoursFromArtifact() + getRemainFromTasks() + getRemainFromReviews();
+ }
+
+ public double getRemainFromTasks() throws OseeCoreException {
+ if (!(this instanceof AbstractTaskableArtifact)) {
+ return 0;
+ }
+ return ((AbstractTaskableArtifact) this).getRemainHoursFromTasks();
+ }
+
+ public double getRemainFromReviews() throws OseeCoreException {
+ if (isTeamWorkflow()) {
+ return ReviewManager.getRemainHours((TeamWorkFlowArtifact) this);
+ }
+ return 0;
+ }
+
+ @SuppressWarnings("unused")
+ public double getManHrsPerDayPreference() throws OseeCoreException {
+ return AtsUtilCore.DEFAULT_HOURS_PER_WORK_DAY;
+ }
+
+ /**
+ * Return true if this artifact, it's ATS relations and any of the other side artifacts are dirty
+ *
+ * @return true if any object in SMA tree is dirty
+ */
+ public Result isSMAEditorDirty() {
+ try {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ getSmaArtifactsOneLevel(this, artifacts);
+ for (Artifact artifact : artifacts) {
+ if (artifact.isDirty()) {
+ String rString = null;
+ for (Attribute<?> attribute : artifact.internalGetAttributes()) {
+ if (attribute.isDirty()) {
+ rString = "Attribute: " + attribute.getNameValueDescription();
+ break;
+ }
+ }
+
+ if (rString == null) {
+ rString = RelationManager.reportHasDirtyLinks(artifact);
+ }
+ return new Result(true, String.format("Artifact [%s][%s] is dirty\n\n%s", artifact.getHumanReadableId(),
+ artifact, rString));
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't save artifact " + getHumanReadableId(), ex);
+ }
+ return Result.FalseResult;
+ }
+
+ public void saveSMA(SkynetTransaction transaction) {
+ try {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ getSmaArtifactsOneLevel(this, artifacts);
+ for (Artifact artifact : artifacts) {
+ artifact.persist(transaction);
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't save artifact " + getHumanReadableId(), ex);
+ }
+ }
+
+ public void revertSMA() {
+ try {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ getSmaArtifactsOneLevel(this, artifacts);
+ for (Artifact artifact : artifacts) {
+ artifact.reloadAttributesAndRelations();
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't revert artifact " + getHumanReadableId(), ex);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public void getSmaArtifactsOneLevel(AbstractWorkflowArtifact smaArtifact, Set<Artifact> artifacts) throws OseeCoreException {
+ artifacts.add(smaArtifact);
+ }
+
+ /**
+ * Called at the end of a transition just before transaction manager persist. SMAs can override to perform tasks due
+ * to transition.
+ */
+ @SuppressWarnings("unused")
+ public void transitioned(StateDefinition fromState, StateDefinition toState, Collection<User> toAssignees, boolean persist, SkynetTransaction transaction) throws OseeCoreException {
+ // provided for subclass implementation
+ }
+
+ @Override
+ public Artifact getParentAtsArtifact() throws OseeCoreException {
+ return getParentAWA();
+ }
+
+ /**
+ * Return Percent Complete ONLY on tasks related to stateName. Total Percent / # Tasks
+ */
+ public int getPercentCompleteSMAStateTasks(IWorkPage state) throws OseeCoreException {
+ if (!(this instanceof AbstractTaskableArtifact)) {
+ return 0;
+ }
+ return ((AbstractTaskableArtifact) this).getPercentCompleteFromTasks(state);
+ }
+
+ public Set<IRelationTypeSide> getAtsWorldRelations() {
+ return atsWorldRelations;
+ }
+
+ public String getWorldViewLastUpdated() throws OseeCoreException {
+ return DateUtil.getMMDDYYHHMM(getLastModified());
+ }
+
+ @SuppressWarnings("unused")
+ public String getWorldViewSWEnhancement() throws OseeCoreException {
+ return "";
+ }
+
+ @Override
+ public String getGroupExplorerName() {
+ return String.format("[%s] %s", getStateMgr().getCurrentStateName(), getName());
+ }
+
+ public AtsLog getLog() {
+ return atsLog;
+ }
+
+ public AtsNote getNotes() {
+ return atsNote;
+ }
+
+ public Result getUserInputNeeded() {
+ return Result.FalseResult;
+ }
+
+ public WorkDefinition getWorkDefinition() {
+ return getWorkDefinitionMatch().getWorkDefinition();
+ }
+
+ public WorkDefinitionMatch getWorkDefinitionMatch() {
+ try {
+ return WorkDefinitionFactory.getWorkDefinition(this);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return null;
+ }
+
+ public StateDefinition getStateDefinition() {
+ if (getStateMgr().getCurrentStateName() == null) {
+ return null;
+ }
+ return getWorkDefinition().getStateByName(getStateMgr().getCurrentStateName());
+ }
+
+ public StateDefinition getStateDefinitionByName(String name) {
+ return getWorkDefinition().getStateByName(name);
+ }
+
+ public boolean isHistoricalVersion() {
+ return isHistorical();
+ }
+
+ public List<StateDefinition> getToStates() {
+ return getStateDefinition().getToStates();
+ }
+
+ public boolean isAccessControlWrite() throws OseeCoreException {
+ return AccessControlManager.hasPermission(this, PermissionEnum.WRITE);
+ }
+
+ /**
+ * @return true if this is a TeamWorkflow and it uses versions
+ */
+ public boolean isTeamUsesVersions() {
+ if (!isTeamWorkflow()) {
+ return false;
+ }
+ try {
+ return ((TeamWorkFlowArtifact) this).getTeamDefinition().isTeamUsesVersions();
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return false;
+ }
+ }
+
+ /**
+ * Return true if awa is TeamWorkflowArtifact or review of a team workflow and it's TeamDefinitionArtifact has rule
+ * set
+ */
+ public boolean teamDefHasRule(RuleDefinitionOption option) throws OseeCoreException {
+ TeamWorkFlowArtifact teamArt = null;
+ if (isTeamWorkflow()) {
+ teamArt = (TeamWorkFlowArtifact) this;
+ }
+ if (this instanceof AbstractReviewArtifact) {
+ teamArt = ((AbstractReviewArtifact) this).getParentTeamWorkflow();
+ }
+ if (teamArt == null) {
+ return false;
+ }
+ try {
+ return teamArt.getTeamDefinition().hasRule(option);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ return false;
+ }
+ }
+
+ /**
+ * @return true if this is a TeamWorkflow and the version it's been targeted for has been released
+ */
+ public boolean isReleased() {
+ try {
+ VersionArtifact verArt = getTargetedVersion();
+ if (verArt != null) {
+ return verArt.isReleased();
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return false;
+ }
+
+ public boolean isVersionLocked() {
+ try {
+ VersionArtifact verArt = getTargetedVersion();
+ if (verArt != null) {
+ return verArt.isVersionLocked();
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return false;
+ }
+
+ public VersionArtifact getTargetedVersion() throws OseeCoreException {
+ return TargetedVersionUtil.getTargetedVersion(this);
+ }
+
+ public String getTargetedVersionStr() throws OseeCoreException {
+ return TargetedVersionUtil.getTargetedVersionStr(this);
+ }
+
+ public void setCreatedBy(User user, boolean logChange, Date date) throws OseeCoreException {
+ if (logChange) {
+ if (getSoleAttributeValue(AtsAttributeTypes.CreatedBy, null) == null) {
+ atsLog.addLog(LogType.Originated, "", "", date, user);
+ } else {
+ atsLog.addLog(LogType.Originated, "", "Changed by " + UserManager.getUser().getName(), date, user);
+ atsLog.internalResetOriginator(user);
+ }
+ }
+ if (isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ setSoleAttributeValue(AtsAttributeTypes.CreatedBy, user.getUserId());
+ }
+ if (isAttributeTypeValid(AtsAttributeTypes.CreatedDate)) {
+ setSoleAttributeValue(AtsAttributeTypes.CreatedDate, date);
+ }
+ }
+
+ public void internalSetCreatedBy(User user) throws OseeCoreException {
+ atsLog.internalResetOriginator(user);
+ if (isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ setSoleAttributeValue(AtsAttributeTypes.CreatedBy, user.getUserId());
+ }
+ }
+
+ public void internalSetCreatedDate(Date date) throws OseeCoreException {
+ atsLog.internalResetCreatedDate(date);
+ if (isAttributeTypeValid(AtsAttributeTypes.CreatedDate)) {
+ setSoleAttributeValue(AtsAttributeTypes.CreatedDate, date);
+ }
+ }
+
+ public Date getCreatedDate() throws OseeCoreException {
+ Date date = getSoleAttributeValue(AtsAttributeTypes.CreatedDate, null);
+ if (date == null) {
+ // Keep this for backward compatibility
+ return getLog().internalGetCreationDate();
+ }
+ return date;
+ }
+
+ public User getCreatedBy() throws OseeCoreException {
+ String userId = getSoleAttributeValue(AtsAttributeTypes.CreatedBy, null);
+ if (!Strings.isValid(userId)) {
+ return getLog().internalGetOriginator();
+ } else {
+ return UserManager.getUserByUserId(userId);
+ }
+ }
+
+ public Date internalGetCancelledDate() throws OseeCoreException {
+ Date date = getSoleAttributeValue(AtsAttributeTypes.CancelledDate, null);
+ if (date == null) {
+ // Keep this for backward compatibility
+ LogItem item = getLog().internalGetCancelledLogItem();
+ if (item != null) {
+ return item.getDate();
+ }
+ return null;
+ }
+ return date;
+ }
+
+ public User getCancelledBy() throws OseeCoreException {
+ String userId = getSoleAttributeValue(AtsAttributeTypes.CancelledBy, null);
+ if (!Strings.isValid(userId)) {
+ // Keep this for backward compatibility
+ LogItem item = getLog().internalGetCancelledLogItem();
+ if (item != null) {
+ return item.getUser();
+ }
+ return null;
+ } else {
+ return UserManager.getUserByUserId(userId);
+ }
+ }
+
+ public String getCancelledReason() throws OseeCoreException {
+ String reason = getSoleAttributeValue(AtsAttributeTypes.CancelledReason, null);
+ if (!Strings.isValid(reason)) {
+ reason = getLog().internalGetCancelledReason();
+ }
+ return reason;
+ }
+
+ public void setCancellationReason(String reason) throws OseeCoreException {
+ // Keep this for backward compatibility
+ getLog().internalSetCancellationReason(reason);
+ if (isAttributeTypeValid(AtsAttributeTypes.CancelledReason)) {
+ setSoleAttributeValue(AtsAttributeTypes.CancelledReason, reason);
+ }
+ }
+
+ public String getCancelledFromState() throws OseeCoreException {
+ String fromState = getSoleAttributeValue(AtsAttributeTypes.CancelledFromState, null);
+ if (!Strings.isValid(fromState)) {
+ // Keep this for backward compatibility
+ return getLog().internalGetCancelledFromState();
+ }
+ return fromState;
+ }
+
+ public Date getCompletedDate() throws OseeCoreException {
+ Date date = getSoleAttributeValue(AtsAttributeTypes.CompletedDate, null);
+ if (date == null) {
+ // Keep this for backward compatibility
+ LogItem item = getLog().internalGetCompletedLogItem();
+ if (item != null) {
+ return item.getDate();
+ }
+ return null;
+ }
+ return date;
+ }
+
+ public User getCompletedBy() throws OseeCoreException {
+ String userId = getSoleAttributeValue(AtsAttributeTypes.CompletedBy, null);
+ if (!Strings.isValid(userId)) {
+ // Keep this for backward compatibility
+ LogItem item = getLog().internalGetCompletedLogItem();
+ if (item != null) {
+ return item.getUser();
+ }
+ return null;
+ } else {
+ return UserManager.getUserByUserId(userId);
+ }
+ }
+
+ public LogItem getStateCompletedData(IWorkPage state) throws OseeCoreException {
+ return getLog().getStateEvent(LogType.StateComplete, state.getPageName());
+ }
+
+ public LogItem getStateCancelledData(IWorkPage state) throws OseeCoreException {
+ return getLog().getStateEvent(LogType.StateCancelled, state.getPageName());
+ }
+
+ public LogItem getStateStartedData(IWorkPage state) throws OseeCoreException {
+ return getLog().getStateEvent(LogType.StateEntered, state.getPageName());
+ }
+
+ public String getCompletedFromState() throws OseeCoreException {
+ String fromState = getSoleAttributeValue(AtsAttributeTypes.CompletedFromState, null);
+ if (!Strings.isValid(fromState)) {
+ return getLog().internalGetCompletedFromState();
+ }
+ return fromState;
+ }
+
+ public boolean isInWork() throws OseeCoreException {
+ // Backward compatibility; remove this once 0.9.7 released
+ if (isAttributeTypeValid(AtsAttributeTypes.CurrentStateType) && getSoleAttributeValue(
+ AtsAttributeTypes.CurrentStateType, null) != null) {
+ return getSoleAttributeValue(AtsAttributeTypes.CurrentStateType, "").equals(WorkPageType.Working.name());
+ } else {
+ return !isCompletedOrCancelled();
+ }
+
+ }
+
+ public boolean isCompleted() throws OseeCoreException {
+ if (isAttributeTypeValid(AtsAttributeTypes.CurrentStateType) && getSoleAttributeValue(
+ AtsAttributeTypes.CurrentStateType, null) != null) {
+ return getSoleAttributeValue(AtsAttributeTypes.CurrentStateType, "").equals(WorkPageType.Completed.name());
+ } else {
+ return getCurrentStateName().equals(TeamState.Completed.getPageName());
+ }
+ }
+
+ public boolean isCancelled() throws OseeCoreException {
+ // Backward compatibility; remove this once 0.9.7 released
+ if (isAttributeTypeValid(AtsAttributeTypes.CurrentStateType) && getSoleAttributeValue(
+ AtsAttributeTypes.CurrentStateType, null) != null) {
+ return getSoleAttributeValue(AtsAttributeTypes.CurrentStateType, "").equals(WorkPageType.Cancelled.name());
+ } else {
+ return getCurrentStateName().equals(TeamState.Cancelled.getPageName());
+ }
+ }
+
+ public boolean isCompletedOrCancelled() throws OseeCoreException {
+ return isCompleted() || isCancelled();
+ }
+
+ public void setTransitionAssignees(Collection<User> assignees) throws OseeCoreException {
+ if (assignees.contains(UserManager.getUser(SystemUser.OseeSystem)) || assignees.contains(UserManager.getUser(SystemUser.Guest))) {
+ throw new OseeArgumentException("Can not assign workflow to OseeSystem or Guest");
+ }
+ if (assignees.size() > 1 && assignees.contains(UserManager.getUser(SystemUser.UnAssigned))) {
+ throw new OseeArgumentException("Can not assign to user and UnAssigned");
+ }
+ transitionAssignees = assignees;
+ }
+
+ public boolean isAssigneeMe() throws OseeCoreException {
+ return stateMgr.getAssignees().contains(UserManager.getUser());
+ }
+
+ public Collection<User> getTransitionAssignees() throws OseeCoreException {
+ if (transitionAssignees != null) {
+ if (!transitionAssignees.isEmpty() && transitionAssignees.contains(UserManager.getUser(SystemUser.UnAssigned))) {
+ transitionAssignees.remove(UserManager.getUser(SystemUser.UnAssigned));
+ }
+ if (!transitionAssignees.isEmpty()) {
+ return transitionAssignees;
+ }
+ }
+ return stateMgr.getAssignees();
+ }
+
+ public String getTransitionAssigneesStr() throws OseeCoreException {
+ return Artifacts.toTextList(getTransitionAssignees(), ";");
+ }
+
+ public boolean isInTransition() {
+ return inTransition;
+ }
+
+ public void setInTransition(boolean inTransition) {
+ this.inTransition = inTransition;
+ }
+
+ public StateManager getStateMgr() {
+ return stateMgr;
+ }
+
+ public boolean isTeamWorkflow() {
+ return this.isOfType(AtsArtifactTypes.TeamWorkflow);
+ }
+
+ public boolean isTask() {
+ return this.isOfType(AtsArtifactTypes.Task);
+ }
+
+ public boolean isReview() {
+ return this instanceof AbstractReviewArtifact;
+ }
+
+ protected void addPriviledgedUsersUpTeamDefinitionTree(TeamDefinitionArtifact tda, Set<User> users) throws OseeCoreException {
+ users.addAll(tda.getLeads());
+ users.addAll(tda.getPrivilegedMembers());
+
+ // Walk up tree to get other editors
+ if (tda.getParent() != null && tda.getParent() instanceof TeamDefinitionArtifact) {
+ addPriviledgedUsersUpTeamDefinitionTree((TeamDefinitionArtifact) tda.getParent(), users);
+ }
+ }
+
+ @Override
+ public CmAccessControl getAccessControl() {
+ Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
+ BundleContext context = bundle.getBundleContext();
+ ServiceReference reference = context.getServiceReference(CmAccessControl.class.getName());
+ return (CmAccessControl) context.getService(reference);
+ }
+
+ public boolean isTargetedErrorLogged() {
+ return targetedErrorLogged;
+ }
+
+ public void setTargetedErrorLogged(boolean targetedErrorLogged) {
+ this.targetedErrorLogged = targetedErrorLogged;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifact.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifact.java
new file mode 100644
index 00000000000..e40fb64d878
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifact.java
@@ -0,0 +1,45 @@
+/*
+ * Created on Mar 24, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.model.Branch;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactFactory;
+
+public class ActionArtifact extends Artifact {
+
+ public ActionArtifact(ArtifactFactory parentFactory, String guid, String humanReadableId, Branch branch, IArtifactType artifactType) throws OseeCoreException {
+ super(parentFactory, guid, humanReadableId, branch, artifactType);
+ }
+
+ public Set<ActionableItemArtifact> getActionableItems() throws OseeCoreException {
+ Set<ActionableItemArtifact> aias = new HashSet<ActionableItemArtifact>();
+ for (TeamWorkFlowArtifact team : getTeams()) {
+ aias.addAll(team.getActionableItemsDam().getActionableItems());
+ }
+ return aias;
+ }
+
+ public Collection<TeamWorkFlowArtifact> getTeams() throws OseeCoreException {
+ return getRelatedArtifactsUnSorted(AtsRelationTypes.ActionToWorkflow_WorkFlow, TeamWorkFlowArtifact.class);
+ }
+
+ public TeamWorkFlowArtifact getFirstTeam() throws OseeCoreException {
+ if (getRelatedArtifactsCount(AtsRelationTypes.ActionToWorkflow_WorkFlow) > 0) {
+ return getTeams().iterator().next();
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifactRollup.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifactRollup.java
new file mode 100644
index 00000000000..d8f8b2e2256
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionArtifactRollup.java
@@ -0,0 +1,148 @@
+/*
+ * Created on Mar 7, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+public class ActionArtifactRollup {
+
+ private final ActionArtifact action;
+ private final SkynetTransaction transaction;
+
+ public ActionArtifactRollup(ActionArtifact action, SkynetTransaction transaction) throws OseeArgumentException {
+ this.action = action;
+ this.transaction = transaction;
+ if (!action.isOfType(AtsArtifactTypes.Action)) {
+ throw new OseeArgumentException("Artifact must be an Action instead of [%s]", action.getArtifactTypeName());
+ }
+ }
+
+ public void resetAttributesOffChildren() throws OseeCoreException {
+ resetChangeTypeOffChildren(action);
+ resetPriorityOffChildren();
+ resetUserCommunityOffChildren();
+ resetTitleOffChildren();
+ resetValidationOffChildren();
+ resetDescriptionOffChildren();
+ action.persist(transaction);
+ }
+
+ public static void resetChangeTypeOffChildren(Artifact actionArt) throws OseeCoreException {
+ if (!actionArt.isOfType(AtsArtifactTypes.Action)) {
+ throw new OseeArgumentException("Artifact must be an Action instead of [%s]", actionArt.getArtifactTypeName());
+ }
+ ChangeType changeType = null;
+ Collection<TeamWorkFlowArtifact> teamArts = ActionManagerCore.getTeams(actionArt);
+ if (teamArts.size() == 1) {
+ changeType = ChangeTypeUtil.getChangeType(teamArts.iterator().next());
+ } else {
+ for (TeamWorkFlowArtifact team : teamArts) {
+ if (!team.isCancelled()) {
+ if (changeType == null) {
+ changeType = ChangeTypeUtil.getChangeType(team);
+ } else if (changeType != ChangeTypeUtil.getChangeType(team)) {
+ return;
+ }
+ }
+ }
+ }
+ if (changeType != null && ChangeTypeUtil.getChangeType(actionArt) != changeType) {
+ ChangeTypeUtil.setChangeType(actionArt, changeType);
+ }
+ }
+
+ /**
+ * Reset Action title only if all children are titled the same
+ */
+ private void resetTitleOffChildren() throws OseeCoreException {
+ String title = "";
+ for (TeamWorkFlowArtifact team : action.getTeams()) {
+ if (title.isEmpty()) {
+ title = team.getName();
+ } else if (!title.equals(team.getName())) {
+ return;
+ }
+ }
+ if (!title.equals(action.getName())) {
+ action.setName(title);
+ }
+ }
+
+ // Set validation to true if any require validation
+ private void resetValidationOffChildren() throws OseeCoreException {
+ boolean validationRequired = false;
+ for (TeamWorkFlowArtifact team : action.getTeams()) {
+ if (team.getSoleAttributeValue(AtsAttributeTypes.ValidationRequired, false)) {
+ validationRequired = true;
+ }
+ }
+ if (validationRequired != action.getSoleAttributeValue(AtsAttributeTypes.ValidationRequired, false)) {
+ action.setSoleAttributeValue(AtsAttributeTypes.ValidationRequired, validationRequired);
+ }
+ }
+
+ /**
+ * Reset Action title only if all children are titled the same
+ */
+ private void resetDescriptionOffChildren() throws OseeCoreException {
+ String desc = "";
+ for (TeamWorkFlowArtifact team : action.getTeams()) {
+ if (desc.isEmpty()) {
+ desc = team.getSoleAttributeValue(AtsAttributeTypes.Description, "");
+ } else if (!desc.equals(team.getSoleAttributeValue(AtsAttributeTypes.Description, ""))) {
+ return;
+ }
+ }
+ if (!desc.equals(action.getSoleAttributeValue(AtsAttributeTypes.Description, ""))) {
+ action.setSoleAttributeValue(AtsAttributeTypes.Description, desc);
+ }
+ if (desc.isEmpty()) {
+ action.deleteSoleAttribute(AtsAttributeTypes.Description);
+ }
+ }
+
+ private void resetPriorityOffChildren() throws OseeCoreException {
+ String priorityType = null;
+ Collection<TeamWorkFlowArtifact> teamArts = action.getTeams();
+ if (teamArts.size() == 1) {
+ priorityType = PriorityUtil.getPriorityStr(teamArts.iterator().next());
+ } else {
+ for (TeamWorkFlowArtifact team : teamArts) {
+ if (!team.isCancelled()) {
+ if (priorityType == null) {
+ priorityType = PriorityUtil.getPriorityStr(team);
+ } else if (!priorityType.equals(PriorityUtil.getPriorityStr(team))) {
+ return;
+ }
+ }
+ }
+ }
+ if (Strings.isValid(priorityType)) {
+ action.setSoleAttributeValue(AtsAttributeTypes.PriorityType, priorityType);
+ }
+ }
+
+ private void resetUserCommunityOffChildren() throws OseeCoreException {
+ Set<String> userComs = new HashSet<String>();
+ for (TeamWorkFlowArtifact team : action.getTeams()) {
+ if (!team.isCancelled()) {
+ userComs.addAll(team.getAttributesToStringList(AtsAttributeTypes.UserCommunity));
+ }
+ }
+ action.setAttributeValues(AtsAttributeTypes.UserCommunity, userComs);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionManagerCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionManagerCore.java
new file mode 100644
index 00000000000..609e37e75ad
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionManagerCore.java
@@ -0,0 +1,36 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsRelationTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ActionManagerCore {
+
+ public static Collection<TeamWorkFlowArtifact> getTeams(Object object) throws OseeCoreException {
+ if (object instanceof Artifact && ((Artifact) object).isOfType(AtsArtifactTypes.Action)) {
+ return ((Artifact) object).getRelatedArtifacts(AtsRelationTypes.ActionToWorkflow_WorkFlow,
+ TeamWorkFlowArtifact.class);
+ }
+ return java.util.Collections.emptyList();
+ }
+
+ public static TeamWorkFlowArtifact getFirstTeam(Object object) throws OseeCoreException {
+ Collection<TeamWorkFlowArtifact> arts = getTeams(object);
+ if (arts.size() > 0) {
+ return arts.iterator().next();
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionableItemManagerCore.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionableItemManagerCore.java
new file mode 100644
index 00000000000..747de313b91
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ActionableItemManagerCore.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
+import org.eclipse.osee.ats.core.config.AtsArtifactToken;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.config.TeamDefinitionManager;
+import org.eclipse.osee.ats.core.config.TeamDefinitionManagerCore;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsCacheManager;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.enums.Active;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.ArtifactCache;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ActionableItemManagerCore {
+
+ private final Artifact artifact;
+
+ public ActionableItemManagerCore(Artifact artifact) {
+ this.artifact = artifact;
+ }
+
+ public Set<ActionableItemArtifact> getActionableItems() throws OseeCoreException {
+ Set<ActionableItemArtifact> ais = new HashSet<ActionableItemArtifact>();
+ for (String guid : getActionableItemGuids()) {
+ try {
+ ActionableItemArtifact aia =
+ (ActionableItemArtifact) ArtifactCache.getActive(guid, AtsUtilCore.getAtsBranch());
+ if (aia == null) {
+ OseeLog.log(Activator.class, Level.SEVERE, "Can't find Actionable Item for guid " + guid);
+ } else {
+ ais.add(aia);
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, "Error getting actionable item for guid " + guid, ex);
+ }
+ }
+ return ais;
+ }
+
+ public String getActionableItemsStr() throws OseeCoreException {
+ return Artifacts.toString("; ", getActionableItems());
+ }
+
+ public List<String> getActionableItemGuids() throws OseeCoreException {
+ return artifact.getAttributesToStringList(AtsAttributeTypes.ActionableItem);
+ }
+
+ public void addActionableItem(ActionableItemArtifact aia) throws OseeCoreException {
+ if (!getActionableItemGuids().contains(aia.getGuid())) {
+ artifact.addAttribute(AtsAttributeTypes.ActionableItem, aia.getGuid());
+ }
+ }
+
+ public void removeActionableItem(ActionableItemArtifact aia) throws OseeCoreException {
+ artifact.deleteAttribute(AtsAttributeTypes.ActionableItem, aia.getGuid());
+ }
+
+ public Result setActionableItems(Collection<ActionableItemArtifact> newItems) throws OseeCoreException {
+ Set<ActionableItemArtifact> existingAias = getActionableItems();
+
+ // Remove non-selected items
+ for (ActionableItemArtifact existingAia : existingAias) {
+ if (!newItems.contains(existingAia)) {
+ removeActionableItem(existingAia);
+ }
+ }
+
+ // Add newly-selected items
+ for (ActionableItemArtifact newItem : newItems) {
+ if (!existingAias.contains(newItem)) {
+ addActionableItem(newItem);
+ }
+ }
+
+ return Result.TrueResult;
+ }
+
+ public static Set<TeamDefinitionArtifact> getTeamsFromItemAndChildren(ActionableItemArtifact aia) throws OseeCoreException {
+ return TeamDefinitionManager.getTeamsFromItemAndChildren(aia);
+ }
+
+ public static Set<ActionableItemArtifact> getActionableItemsFromItemAndChildren(ActionableItemArtifact aia) throws OseeCoreException {
+ Set<ActionableItemArtifact> aias = new HashSet<ActionableItemArtifact>();
+ getActionableItemsFromItemAndChildren(aia, aias);
+ return aias;
+ }
+
+ public static void getActionableItemsFromItemAndChildren(ActionableItemArtifact aia, Set<ActionableItemArtifact> aiaTeams) throws OseeCoreException {
+ for (Artifact art : aia.getChildren()) {
+ if (art instanceof ActionableItemArtifact) {
+ aiaTeams.add((ActionableItemArtifact) art);
+ for (Artifact childArt : aia.getChildren()) {
+ if (childArt instanceof ActionableItemArtifact) {
+ getActionableItemsFromItemAndChildren((ActionableItemArtifact) childArt, aiaTeams);
+ }
+ }
+ }
+ }
+ }
+
+ public static Set<ActionableItemArtifact> getActionableItems(Collection<String> actionableItemNames) {
+ Set<ActionableItemArtifact> aias = new HashSet<ActionableItemArtifact>();
+ for (String actionableItemName : actionableItemNames) {
+ for (Artifact artifact : AtsCacheManager.getArtifactsByName(AtsArtifactTypes.ActionableItem,
+ actionableItemName)) {
+ aias.add((ActionableItemArtifact) artifact);
+ }
+ }
+ return aias;
+ }
+
+ public static Collection<TeamDefinitionArtifact> getImpactedTeamDefs(Collection<ActionableItemArtifact> aias) throws OseeCoreException {
+ return TeamDefinitionManagerCore.getImpactedTeamDefs(aias);
+ }
+
+ public static List<ActionableItemArtifact> getActionableItems(Active active) throws OseeCoreException {
+ return Collections.castAll(AtsCacheManager.getArtifactsByActive(AtsArtifactTypes.ActionableItem, active));
+ }
+
+ public static String getNotActionableItemError(Artifact aia) {
+ return "Action can not be written against " + aia.getArtifactTypeName() + " \"" + aia + "\" (" + aia.getHumanReadableId() + ").\n\nChoose another item.";
+ }
+
+ public static ActionableItemArtifact getTopActionableItem() {
+ return (ActionableItemArtifact) AtsUtilCore.getFromToken(AtsArtifactToken.TopActionableItem);
+ }
+
+ public static List<ActionableItemArtifact> getActionableItemsAll() throws OseeCoreException {
+ return Collections.castAll(AtsCacheManager.getArtifactsByActive(AtsArtifactTypes.ActionableItem, Active.Both));
+ }
+
+ public static List<ActionableItemArtifact> getTopLevelActionableItems(Active active) throws OseeCoreException {
+ ActionableItemArtifact topAi = getTopActionableItem();
+ if (topAi == null) {
+ return java.util.Collections.emptyList();
+ }
+ return Collections.castAll(AtsUtilCore.getActive(
+ Artifacts.getChildrenOfTypeSet(topAi, ActionableItemArtifact.class, false), active,
+ ActionableItemArtifact.class));
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeType.java
new file mode 100644
index 00000000000..f4f970abee2
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeType.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.ArrayList;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum ChangeType {
+
+ None,
+ Support,
+ Problem,
+ Improvement,
+ Refinement;
+
+ public static String[] getChangeTypes() {
+ ArrayList<String> types = new ArrayList<String>();
+ for (ChangeType type : values()) {
+ if (type != None) {
+ types.add(type.name());
+ }
+ }
+ return types.toArray(new String[types.size()]);
+ }
+
+ public static ChangeType getChangeType(String name) {
+ for (ChangeType type : values()) {
+ if (type.name().equals(name)) {
+ return type;
+ }
+ }
+ return None;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeTypeUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeTypeUtil.java
new file mode 100644
index 00000000000..97bef53354d
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ChangeTypeUtil.java
@@ -0,0 +1,37 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class ChangeTypeUtil {
+
+ public static String getChangeTypeStr(Artifact artifact) throws OseeCoreException {
+ ChangeType changeType = getChangeType(artifact);
+ if (changeType == ChangeType.None) {
+ return "";
+ }
+ return changeType.name();
+ }
+
+ public static ChangeType getChangeType(Artifact artifact) throws OseeCoreException {
+ return ChangeType.getChangeType(artifact.getSoleAttributeValue(AtsAttributeTypes.ChangeType, ""));
+ }
+
+ public static void setChangeType(Artifact artifact, ChangeType changeType) throws OseeCoreException {
+ if (changeType == ChangeType.None) {
+ artifact.deleteSoleAttribute(AtsAttributeTypes.ChangeType);
+ } else {
+ artifact.setSoleAttributeValue(AtsAttributeTypes.ChangeType, changeType.name());
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/EstimatedHoursUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/EstimatedHoursUtil.java
new file mode 100644
index 00000000000..d287d440b7d
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/EstimatedHoursUtil.java
@@ -0,0 +1,31 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class EstimatedHoursUtil {
+
+ public static double getEstimatedHours(Object object) throws OseeCoreException {
+ if (object instanceof AbstractWorkflowArtifact) {
+ return ((AbstractWorkflowArtifact) object).getEstimatedHoursTotal();
+ } else if (Artifacts.isOfType(object, AtsArtifactTypes.Action)) {
+ double total = 0;
+ for (Artifact team : ActionManagerCore.getTeams(object)) {
+ total += getEstimatedHours(team);
+ }
+ return total;
+ }
+ return 0.0;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/HoursSpentUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/HoursSpentUtil.java
new file mode 100644
index 00000000000..5fa472cf7d3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/HoursSpentUtil.java
@@ -0,0 +1,185 @@
+/*
+ * Created on May 11, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.review.ReviewManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.core.team.SimpleTeamState;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowManager;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.util.WorkflowManagerCore;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class HoursSpentUtil {
+
+ /**
+ * Return hours spent working states, reviews and tasks (not children SMAs)
+ */
+ public static double getHoursSpentTotal(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ double hours = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ hours += getHoursSpentTotal(team);
+ }
+ }
+ return hours;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getHoursSpentTotal(artifact, new StateManager((AbstractWorkflowArtifact) artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working all states, reviews and tasks (not children SMAs)
+ */
+ public static double getHoursSpentTotal(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) artifact;
+ double hours = 0.0;
+ for (String stateName : awa.getStateMgr().getVisitedStateNames()) {
+ hours += getHoursSpentStateTotal(awa, new SimpleTeamState(stateName, WorkPageType.Working));
+ }
+ return hours;
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working SMA state, state tasks and state reviews (not children SMAs)
+ */
+ public static double getHoursSpentStateTotal(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ double hours = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ hours += getHoursSpentStateTotal(team);
+ }
+ }
+ return hours;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getHoursSpentStateTotal(artifact, WorkflowManagerCore.getStateManager(artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working SMA state, state tasks and state reviews (not children SMAs)
+ */
+ public static double getHoursSpentStateTotal(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ AbstractWorkflowArtifact awa = WorkflowManagerCore.cast(artifact);
+ return getHoursSpentSMAState(awa, state) + getHoursSpentFromStateTasks(awa, state) + getHoursSpentStateReview(
+ awa, state);
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working ONLY the SMA stateName (not children SMAs)
+ */
+ public static double getHoursSpentStateReview(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ double hours = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ hours += getHoursSpentStateReview(team);
+ }
+ }
+ return hours;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getHoursSpentStateReview(artifact, WorkflowManagerCore.getStateManager(artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working ONLY the SMA stateName (not children SMAs)
+ */
+ public static double getHoursSpentStateReview(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.TeamWorkflow)) {
+ return ReviewManager.getHoursSpent(TeamWorkFlowManager.cast(artifact), state);
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working ONLY the SMA stateName (not children SMAs)
+ */
+ public static double getHoursSpentSMAState(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ double hours = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ hours += getHoursSpentSMAState(team);
+ }
+ }
+ return hours;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getHoursSpentSMAState(artifact, WorkflowManagerCore.getStateManager(artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working ONLY the SMA stateName (not children SMAs)
+ */
+ public static double getHoursSpentSMAState(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return WorkflowManagerCore.getStateManager(artifact).getHoursSpent(state);
+ }
+ return 0;
+ }
+
+ /**
+ * Return hours spent working ONLY on tasks related to stateName
+ */
+ public static double getHoursSpentFromStateTasks(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ double hours = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ hours += getHoursSpentFromStateTasks(team);
+ }
+ }
+ return hours;
+ }
+ if (artifact instanceof AbstractTaskableArtifact) {
+ return getHoursSpentFromStateTasks(artifact,
+ ((AbstractWorkflowArtifact) artifact).getStateMgr().getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return Hours Spent for Tasks of "Related to State" stateName
+ *
+ * @param relatedToState state name of parent workflow's state
+ * @return Returns the Hours Spent
+ */
+ public static double getHoursSpentFromStateTasks(Artifact artifact, IWorkPage relatedToState) throws OseeCoreException {
+ double spent = 0;
+ if (artifact instanceof AbstractTaskableArtifact) {
+ for (TaskArtifact taskArt : ((AbstractTaskableArtifact) artifact).getTaskArtifacts(relatedToState)) {
+ spent += HoursSpentUtil.getHoursSpentTotal(taskArt);
+ }
+ }
+ return spent;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ITeamWorkflowProvider.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ITeamWorkflowProvider.java
new file mode 100644
index 00000000000..760079f3c95
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/ITeamWorkflowProvider.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
+import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.framework.core.data.IArtifactType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+
+/**
+ * @author Donald G. Dunne
+ */
+public interface ITeamWorkflowProvider {
+
+ /**
+ * Return true if this class/plugin is responsible for the creation of the Team Workflow that will be created for the
+ * given Team Definition. This should be a light-weight check.
+ *
+ * @param teamDef related to the workflow to be created
+ * @param actionableItems that were selected for the creation
+ * @return true if responsible, false if not
+ */
+ public boolean isResponsibleForTeamWorkflowCreation(TeamDefinitionArtifact teamDef, Collection<ActionableItemArtifact> actionableItems) throws OseeCoreException;
+
+ /**
+ * Same as @link getTeamWorkflowArtifactName() but returns the IArtifactType instead of String name.
+ */
+ public IArtifactType getTeamWorkflowArtifactType(TeamDefinitionArtifact teamDef, Collection<ActionableItemArtifact> actionableItems) throws OseeCoreException;
+
+ /**
+ * Notification that a teamWorkflow is being duplicated. This allows the extension to do necessary changes to
+ * duplicated workflow.
+ */
+ public void teamWorkflowDuplicating(TeamWorkFlowArtifact teamArt, TeamWorkFlowArtifact dupTeamArt) throws OseeCoreException;
+
+ /**
+ * Notification that a teamWorkflow was created. This allows the extension to do necessary initial tasks after the
+ * team workflow artifact is created. All changes made to dupTeamArt will be persisted after this call.
+ */
+ public void teamWorkflowCreated(TeamWorkFlowArtifact teamArt);
+
+ /**
+ * Return a collection of all team workflow artifact type names. These are used by ATS when searching is performed
+ * since there is no "inheritance" in the DB model.
+ *
+ * @return collection of all team workflow artifact type names
+ */
+ public Collection<? extends IArtifactType> getTeamWorkflowArtifactTypes() throws OseeCoreException;
+
+ public String getWorkflowDefinitionId(AbstractWorkflowArtifact artifact) throws OseeCoreException;
+
+ public String getRelatedTaskWorkflowDefinitionId(AbstractWorkflowArtifact artifact) throws OseeCoreException;
+
+ /**
+ * Assigned or computed Id that will show at the top of the editor
+ */
+ public String getPcrId(TeamWorkFlowArtifact teamArt) throws OseeCoreException;
+
+ /**
+ * 5-9 character short name for UI and display purposes
+ */
+ public String getArtifactTypeShortName(TeamWorkFlowArtifact teamArt);
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteSMAStateUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteSMAStateUtil.java
new file mode 100644
index 00000000000..00ffe8118f1
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteSMAStateUtil.java
@@ -0,0 +1,59 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.util.WorkflowManagerCore;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class PercentCompleteSMAStateUtil {
+
+ /**
+ * Return Percent Complete working ONLY the current state (not children SMAs)
+ */
+ public static int getPercentCompleteSMAState(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ if (ActionManagerCore.getTeams(artifact).size() == 1) {
+ return getPercentCompleteSMAState(ActionManagerCore.getFirstTeam(artifact));
+ } else {
+ double percent = 0;
+ int items = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ percent += getPercentCompleteSMAState(team);
+ items++;
+ }
+ }
+ if (items > 0) {
+ Double rollPercent = percent / items;
+ return rollPercent.intValue();
+ }
+ }
+ return 0;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getPercentCompleteSMAState(artifact, WorkflowManagerCore.getStateManager(artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return Percent Complete working ONLY the SMA stateName (not children SMAs)
+ */
+ public static int getPercentCompleteSMAState(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return WorkflowManagerCore.getStateManager(artifact).getPercentComplete(state);
+ }
+ return 0;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteTotalUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteTotalUtil.java
new file mode 100644
index 00000000000..999741c1e2f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PercentCompleteTotalUtil.java
@@ -0,0 +1,204 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.review.AbstractReviewArtifact;
+import org.eclipse.osee.ats.core.review.ReviewManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.WorkflowManagerCore;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class PercentCompleteTotalUtil {
+
+ /**
+ * Return Percent Complete on all things (including children SMAs) for this SMA<br>
+ * <br>
+ * percent = all state's percents / number of states (minus completed/canceled)
+ */
+ public static int getPercentCompleteTotal(Artifact artifact) throws OseeCoreException {
+ if (!(artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact))) {
+ return 0;
+ }
+ AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) artifact;
+ if (awa.isCompletedOrCancelled()) {
+ return 100;
+ }
+ if (awa.getWorkDefinition().isStateWeightingEnabled()) {
+ // Calculate total percent using configured weighting
+ int percent = 0;
+ for (StateDefinition stateDef : awa.getWorkDefinition().getStates()) {
+ if (!stateDef.isCompletedPage() && !stateDef.isCancelledPage()) {
+ double stateWeightInt = stateDef.getStateWeight();
+ double weight = stateWeightInt / 100;
+ int percentCompleteForState = getPercentCompleteSMAStateTotal(awa, stateDef);
+ percent += weight * percentCompleteForState;
+ }
+ }
+ return percent;
+ } else {
+ int percent = getPercentCompleteSMASinglePercent(awa);
+ if (percent > 0) {
+ return percent;
+ }
+ if (awa.isCompletedOrCancelled()) {
+ return 100;
+ }
+ if (awa.getStateMgr().isAnyStateHavePercentEntered()) {
+ int numStates = 0;
+ for (StateDefinition state : awa.getWorkDefinition().getStates()) {
+ if (!state.isCompletedPage() && !state.isCancelledPage()) {
+ percent += getPercentCompleteSMAStateTotal(awa, state);
+ numStates++;
+ }
+ }
+ if (numStates == 0) {
+ return 0;
+ }
+ return percent / numStates;
+ }
+
+ }
+ return 0;
+ }
+
+ /**
+ * Add percent represented by percent attribute, percent for reviews and tasks divided by number of objects.
+ */
+ private static int getPercentCompleteSMASinglePercent(Artifact artifact) throws OseeCoreException {
+ if (!(artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact))) {
+ return 0;
+ }
+ AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) artifact;
+ int numObjects = 1;
+ int percent = awa.getSoleAttributeValue(AtsAttributeTypes.PercentComplete, 0);
+ if (awa.isOfType(AtsArtifactTypes.TeamWorkflow)) {
+ for (AbstractReviewArtifact revArt : ReviewManager.getReviews((TeamWorkFlowArtifact) awa)) {
+ percent += getPercentCompleteTotal(revArt);
+ numObjects++;
+ }
+ }
+ if (awa instanceof AbstractTaskableArtifact) {
+ for (TaskArtifact taskArt : ((AbstractTaskableArtifact) awa).getTaskArtifacts()) {
+ percent += getPercentCompleteTotal(taskArt);
+ numObjects++;
+ }
+ }
+ if (percent > 0) {
+ if (numObjects == 0) {
+ return 0;
+ }
+ return percent / numObjects;
+ }
+ return percent;
+ }
+
+ /**
+ * Return Percent Complete on all things (including children SMAs) related to stateName. Total Percent for state,
+ * tasks and reviews / 1 + # Tasks + # Reviews
+ */
+ public static int getPercentCompleteSMAStateTotal(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ return getStateMetricsData(artifact, state).getResultingPercent();
+ }
+
+ private static StateMetricsData getStateMetricsData(Artifact artifact, IWorkPage teamState) throws OseeCoreException {
+ if (!(artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact))) {
+ return null;
+ }
+ AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) artifact;
+ // Add percent and bump objects 1 for state percent
+ int percent = getPercentCompleteSMAState(awa, teamState);
+ int numObjects = 1; // the state itself is one object
+
+ // Add percent for each task and bump objects for each task
+ if (awa instanceof AbstractTaskableArtifact) {
+ Collection<TaskArtifact> tasks = ((AbstractTaskableArtifact) awa).getTaskArtifacts(teamState);
+ for (TaskArtifact taskArt : tasks) {
+ percent += getPercentCompleteTotal(taskArt);
+ }
+ numObjects += tasks.size();
+ }
+
+ // Add percent for each review and bump objects for each review
+ if (awa.isOfType(AtsArtifactTypes.TeamWorkflow)) {
+ Collection<AbstractReviewArtifact> reviews = ReviewManager.getReviews((TeamWorkFlowArtifact) awa, teamState);
+ for (AbstractReviewArtifact reviewArt : reviews) {
+ percent += getPercentCompleteTotal(reviewArt);
+ }
+ numObjects += reviews.size();
+ }
+
+ return new StateMetricsData(percent, numObjects);
+ }
+ private static class StateMetricsData {
+ public int numObjects = 0;
+ public int percent = 0;
+
+ public StateMetricsData(int percent, int numObjects) {
+ this.numObjects = numObjects;
+ this.percent = percent;
+ }
+
+ public int getResultingPercent() {
+ return percent / numObjects;
+ }
+
+ @Override
+ public String toString() {
+ return "Percent: " + getResultingPercent() + " NumObjs: " + numObjects + " Total Percent: " + percent;
+ }
+ }
+
+ /**
+ * Return Percent Complete working ONLY the current state (not children SMAs)
+ */
+ public static int getPercentCompleteSMAState(Artifact artifact) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.Action)) {
+ if (ActionManagerCore.getTeams(artifact).size() == 1) {
+ return getPercentCompleteSMAState(ActionManagerCore.getFirstTeam(artifact));
+ } else {
+ double percent = 0;
+ int items = 0;
+ for (TeamWorkFlowArtifact team : ActionManagerCore.getTeams(artifact)) {
+ if (!team.isCancelled()) {
+ percent += getPercentCompleteSMAState(team);
+ items++;
+ }
+ }
+ if (items > 0) {
+ Double rollPercent = percent / items;
+ return rollPercent.intValue();
+ }
+ }
+ return 0;
+ }
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return getPercentCompleteSMAState(artifact, WorkflowManagerCore.getStateManager(artifact).getCurrentState());
+ }
+ return 0;
+ }
+
+ /**
+ * Return Percent Complete working ONLY the SMA stateName (not children SMAs)
+ */
+ public static int getPercentCompleteSMAState(Artifact artifact, IWorkPage state) throws OseeCoreException {
+ if (artifact.isOfType(AtsArtifactTypes.AbstractWorkflowArtifact)) {
+ return WorkflowManagerCore.getStateManager(artifact).getPercentComplete(state);
+ }
+ return 0;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PriorityUtil.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PriorityUtil.java
new file mode 100644
index 00000000000..b8a82113eef
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/PriorityUtil.java
@@ -0,0 +1,24 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class PriorityUtil {
+
+ public static String getPriorityStr(Object object) throws OseeCoreException {
+ if (object instanceof Artifact) {
+ return ((Artifact) object).getSoleAttributeValue(AtsAttributeTypes.PriorityType, "");
+ }
+ return "";
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/SMAState.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/SMAState.java
new file mode 100644
index 00000000000..b3f5677cc75
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/SMAState.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.utility.UsersByIds;
+
+public class SMAState {
+ private String name;
+ private Collection<User> assignees = new HashSet<User>();
+ private int percentComplete = 0;
+ private double hoursSpent = 0;
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = result * 31 + name.hashCode();
+ result = result * 31 + assignees.hashCode();
+
+ return result;
+ }
+
+ public SMAState(String name, Collection<User> assignees) {
+ this.name = Strings.intern(name);
+ if (assignees != null) {
+ this.assignees = assignees;
+ }
+ }
+
+ public SMAState(String name, User assignee) {
+ this.name = Strings.intern(name);
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ public SMAState(String name) {
+ this(name, (User) null);
+ }
+
+ public SMAState() {
+ this("", (User) null);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof SMAState) {
+ SMAState state = (SMAState) obj;
+ if (!state.name.equals(name)) {
+ return false;
+ }
+ if (!state.assignees.equals(this.assignees)) {
+ return false;
+ }
+ return true;
+ }
+ return super.equals(obj);
+ }
+
+ public Collection<User> getAssignees() {
+ return assignees;
+ }
+
+ /**
+ * Sets the assignees but DOES NOT write to SMA. This method should NOT be called outside the StateMachineArtifact.
+ */
+ public void setAssignees(Collection<User> assignees) throws OseeCoreException {
+ if (assignees != null) {
+ if (assignees.contains(UserManager.getUser(SystemUser.OseeSystem)) || assignees.contains(UserManager.getUser(SystemUser.Guest))) {
+ throw new OseeArgumentException("Can not assign workflow to OseeSystem or Guest");
+ }
+ if (assignees.size() > 1 && assignees.contains(UserManager.getUser(SystemUser.UnAssigned))) {
+ throw new OseeArgumentException("Can not assign to user and UnAssigned");
+ }
+ if (assignees.size() > 0 && (name.equals(TeamState.Completed.getPageName()) || name.equals(TeamState.Cancelled.getPageName()))) {
+ throw new OseeStateException("Can't assign completed/cancelled states.");
+ }
+ } else {
+ assignees = new HashSet<User>();
+ }
+ this.assignees.clear();
+ this.assignees.addAll(assignees);
+
+ }
+
+ public void clearAssignees() {
+ this.assignees.clear();
+ }
+
+ /**
+ * Sets the assignees but DOES NOT write to SMA. This method should NOT be called outside the StateMachineArtifact.
+ */
+ public void setAssignee(User assignee) throws OseeCoreException {
+ if (assignee != null && (name.equals(TeamState.Completed.getPageName()) || name.equals(TeamState.Cancelled.getPageName()))) {
+ throw new OseeStateException("Can't assign completed/cancelled states.");
+ }
+ if (assignee == UserManager.getUser(SystemUser.OseeSystem) || assignee == UserManager.getUser(SystemUser.Guest)) {
+ throw new OseeArgumentException("Can not assign workflow to OseeSystem or Guest");
+ }
+ this.assignees.clear();
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ public void addAssignee(User assignee) throws OseeCoreException {
+ if (assignee == UserManager.getUser(SystemUser.OseeSystem) || assignee == UserManager.getUser(SystemUser.Guest)) {
+ throw new OseeArgumentException("Can not assign workflow to OseeSystem or Guest");
+ }
+ if (assignee != null) {
+ this.assignees.add(assignee);
+ }
+ }
+
+ public void removeAssignee(User assignee) {
+ if (assignee != null) {
+ this.assignees.remove(assignee);
+ }
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toXml() throws OseeCoreException {
+ StringBuffer sb = new StringBuffer(name);
+ sb.append(";");
+ sb.append(UsersByIds.getStorageString(assignees));
+ sb.append(";");
+ if (hoursSpent > 0) {
+ sb.append(getHoursSpentStr());
+ }
+ sb.append(";");
+ if (percentComplete > 0) {
+ sb.append(percentComplete);
+ }
+ return sb.toString();
+ }
+
+ public static Pattern storagePattern = Pattern.compile("^(.*?);(.*?);(.*?);(.*?)$");
+
+ public void setFromXml(String xml) throws OseeCoreException {
+ if (!Strings.isValid(xml)) {
+ name = "Unknown";
+ return;
+ }
+ Matcher m = storagePattern.matcher(xml);
+ if (m.find()) {
+ name = m.group(1);
+ if (!m.group(3).equals("")) {
+ hoursSpent = new Float(m.group(3)).doubleValue();
+ }
+ if (!m.group(4).equals("")) {
+ percentComplete = Integer.valueOf(m.group(4)).intValue();
+ }
+ assignees = UsersByIds.getUsers(m.group(2));
+ } else {
+ throw new OseeArgumentException("Can't unpack state data [%s]", xml);
+ }
+ }
+
+ public double getHoursSpent() {
+ return hoursSpent;
+ }
+
+ public String getHoursSpentStr() {
+ return AtsUtilCore.doubleToI18nString(hoursSpent, true);
+ }
+
+ public void setHoursSpent(double hoursSpent) {
+ this.hoursSpent = hoursSpent;
+ }
+
+ public int getPercentComplete() {
+ return percentComplete;
+ }
+
+ public void setPercentComplete(int percentComplete) {
+ this.percentComplete = percentComplete;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/StateManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/StateManager.java
new file mode 100644
index 00000000000..95236b723e3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/StateManager.java
@@ -0,0 +1,448 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.team.SimpleTeamState;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workflow.log.LogItem;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class StateManager {
+
+ private final XCurrentStateDam currentStateDam;
+ private final XStateDam stateDam;
+ private final AbstractWorkflowArtifact sma;
+ private static final Set<String> notValidAttributeType = new HashSet<String>();
+
+ public StateManager(AbstractWorkflowArtifact sma) {
+ super();
+ this.sma = sma;
+ currentStateDam = new XCurrentStateDam(sma);
+ stateDam = new XStateDam(sma);
+ }
+
+ /**
+ * Get state and create if not there.
+ */
+ private SMAState getSMAState(IWorkPage state, boolean create) throws OseeCoreException {
+ if (currentStateDam.getState().getName().equals(state.getPageName())) {
+ return currentStateDam.getState();
+ } else {
+ return stateDam.getState(state, create);
+ }
+ }
+
+ public boolean isAnyStateHavePercentEntered() throws OseeCoreException {
+ if (currentStateDam.getState().getPercentComplete() > 0) {
+ return true;
+ }
+ for (SMAState state : stateDam.getStates()) {
+ if (state.getPercentComplete() > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isInState(IWorkPage state) {
+ return (getCurrentStateName().equals(state.getPageName()));
+ }
+
+ /**
+ * Discouraged Access. This method should not normally be called except in cases were state data is being manually
+ * created.
+ */
+ public void internalCreateIfNotExists(IWorkPage state) throws OseeCoreException {
+ if (isStateVisited(state)) {
+ return;
+ }
+ SMAState smaState = getSMAState(state, true);
+ putState(smaState);
+ }
+
+ /**
+ * @return true if UnAssigned user is currently an assignee
+ */
+ public boolean isUnAssigned() throws OseeCoreException {
+ return getAssignees().contains(UserManager.getUser(SystemUser.UnAssigned));
+ }
+
+ public boolean isUnAssignedSolely() throws OseeCoreException {
+ return getAssignees().size() == 1 && isUnAssigned();
+ }
+
+ /**
+ * Return Hours Spent for State
+ *
+ * @return hours spent or 0 if none
+ */
+ public double getHoursSpent(IWorkPage state) throws OseeCoreException {
+ SMAState smaState = getSMAState(state, false);
+ if (smaState == null) {
+ return 0.0;
+ }
+ return smaState.getHoursSpent();
+ }
+
+ public double getHoursSpent() throws OseeCoreException {
+ return getHoursSpent(getCurrentState());
+ }
+
+ /**
+ * Return Percent Complete for State
+ *
+ * @return percent complete or 0 if none
+ */
+ public int getPercentComplete(IWorkPage teamState) throws OseeCoreException {
+ if (teamState.getWorkPageType().isCompletedOrCancelledPage()) {
+ return 100;
+ }
+ SMAState state = getSMAState(teamState, false);
+ if (state == null) {
+ return 0;
+ }
+ return state.getPercentComplete();
+
+ }
+
+ public int getPercentComplete() throws OseeCoreException {
+ return getPercentComplete(getCurrentState());
+ }
+
+ public String getCurrentStateName() {
+ try {
+ return currentStateDam.getState().getName();
+ } catch (OseeCoreException ex) {
+ return ex.getLocalizedMessage();
+ }
+ }
+
+ public IWorkPage getCurrentState() {
+ return new SimpleTeamState(getCurrentStateName(), getCurrentWorkPageType());
+ }
+
+ public WorkPageType getCurrentWorkPageType() {
+ try {
+ if (sma.isAttributeTypeValid(AtsAttributeTypes.CurrentStateType)) {
+ // backward compatibility
+ if (sma.getSoleAttributeValueAsString(AtsAttributeTypes.CurrentStateType, null) == null) {
+ if (getCurrentStateName().equals(TeamState.Completed.getPageName())) {
+ return WorkPageType.Completed;
+ } else if (getCurrentStateName().equals(TeamState.Cancelled.getPageName())) {
+ return WorkPageType.Cancelled;
+ } else {
+ return WorkPageType.Working;
+ }
+ } else {
+ return WorkPageType.valueOf(sma.getSoleAttributeValueAsString(AtsAttributeTypes.CurrentStateType, null));
+ }
+ } else {
+ // display console error, but only once
+ if (!notValidAttributeType.contains(sma.getArtifactTypeName())) {
+ notValidAttributeType.add(sma.getArtifactTypeName());
+ System.err.println("CurrentStateType not valid for " + sma.getArtifactTypeName());
+ }
+ // TODO get rid of this once database configured for new types (or leave for backward compatibility?
+ if (getCurrentStateName().equals(TeamState.Completed.getPageName())) {
+ return WorkPageType.Completed;
+ } else if (getCurrentStateName().equals(TeamState.Cancelled.getPageName())) {
+ return WorkPageType.Cancelled;
+ } else {
+ return WorkPageType.Working;
+ }
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return null;
+ }
+
+ public String getAssigneesStr() throws OseeCoreException {
+ return Artifacts.toString("; ", sma.getStateMgr().getAssignees());
+ }
+
+ public String getAssigneesStr(int length) throws OseeCoreException {
+ String str = getAssigneesStr();
+ if (str.length() > length) {
+ return str.substring(0, length - 1) + "...";
+ }
+ return str;
+ }
+
+ public Collection<User> getAssignees() throws OseeCoreException {
+ return getAssignees(getCurrentState());
+ }
+
+ public Collection<User> getAssignees(IWorkPage state) throws OseeCoreException {
+ SMAState smaState = getSMAState(state, false);
+ if (smaState == null) {
+ return Collections.emptyList();
+ } else {
+ return smaState.getAssignees();
+ }
+ }
+
+ public void updateMetrics(double additionalHours, int percentComplete, boolean logMetrics) throws OseeCoreException {
+ updateMetrics(getCurrentState(), additionalHours, percentComplete, logMetrics);
+ }
+
+ public void updateMetrics(IWorkPage state, double additionalHours, int percentComplete, boolean logMetrics) throws OseeCoreException {
+ if (sma.isInState(state)) {
+ currentStateDam.updateMetrics(additionalHours, percentComplete, logMetrics);
+ } else {
+ stateDam.updateMetrics(state, additionalHours, percentComplete, logMetrics);
+ }
+ }
+
+ public void setMetrics(double hours, int percentComplete, boolean logMetrics, User user, Date date) throws OseeCoreException {
+ setMetrics(getCurrentState(), hours, percentComplete, logMetrics, user, date);
+ }
+
+ public void setMetrics(IWorkPage state, double hours, int percentComplete, boolean logMetrics, User user, Date date) throws OseeCoreException {
+ if (state.getPageName().equals(getCurrentStateName())) {
+ currentStateDam.setMetrics(hours, percentComplete, logMetrics, user, date);
+ } else {
+ stateDam.setMetrics(state, hours, percentComplete, logMetrics, user, date);
+ }
+ }
+
+ /**
+ * Sets the assignees as attributes and relations AND writes to SMA. Does not persist.
+ */
+ public void setAssignees(Collection<User> assignees) throws OseeCoreException {
+ SMAState state = getSMAState(getCurrentState(), false);
+ state.setAssignees(assignees);
+ putState(state);
+ }
+
+ /**
+ * Sets the assignee AND writes to SMA. Does not persist.
+ */
+ public void setAssignee(IWorkPage state, User assignee) throws OseeCoreException {
+ if (!isStateVisited(state)) {
+ throw new OseeArgumentException("State [%s] does not exist.", state);
+ }
+ SMAState smaState = getSMAState(state, false);
+ smaState.setAssignee(assignee);
+ putState(smaState);
+ }
+
+ /**
+ * Sets the assignee AND writes to SMA. Does not persist.
+ */
+ public void setAssignee(User assignee) throws OseeCoreException {
+ SMAState smaState = getSMAState(getCurrentState(), false);
+ smaState.setAssignee(assignee);
+ putState(smaState);
+ }
+
+ /**
+ * Removes the assignee from stateName state AND writes to SMA. Does not persist.
+ */
+ public void removeAssignee(IWorkPage state, User assignee) throws OseeCoreException {
+ if (!isStateVisited(state)) {
+ return;
+ }
+ SMAState smaState = getSMAState(state, false);
+ smaState.removeAssignee(assignee);
+ putState(smaState);
+ }
+
+ /**
+ * Removes the assignee AND writes to SMA. Does not persist.
+ */
+ public void removeAssignee(User assignee) throws OseeCoreException {
+ SMAState smaState = getSMAState(getCurrentState(), false);
+ smaState.removeAssignee(assignee);
+ putState(smaState);
+ }
+
+ /**
+ * Adds the assignee AND writes to SMA. Does not persist. Will remove UnAssigned user if another assignee exists.
+ */
+ public void addAssignee(User assignee) throws OseeCoreException {
+ SMAState smaState = getSMAState(getCurrentState(), false);
+ smaState.addAssignee(assignee);
+ if (smaState.getAssignees().size() > 1 && smaState.getAssignees().contains(
+ UserManager.getUser(SystemUser.UnAssigned))) {
+ smaState.removeAssignee(UserManager.getUser(SystemUser.UnAssigned));
+ }
+ putState(smaState);
+ }
+
+ /**
+ * Removes ALL assignees AND writes to SMA. Does not persist.
+ */
+ public void clearAssignees() throws OseeCoreException {
+ SMAState smaState = getSMAState(getCurrentState(), false);
+ smaState.clearAssignees();
+ putState(smaState);
+ }
+
+ public boolean isStateVisited(IWorkPage state) {
+ return getVisitedStateNames().contains(state.getPageName());
+ }
+
+ public void transitionHelper(Collection<User> toAssignees, StateDefinition fromState, StateDefinition toState, String cancelReason) throws OseeCoreException {
+ // Set XCurrentState info to XState
+ stateDam.setState(currentStateDam.getState());
+
+ // Set XCurrentState; If been to this state, copy state info from prev state; else create new
+ SMAState previousState = stateDam.getState(toState, false);
+ if (previousState == null) {
+ currentStateDam.setState(new SMAState(toState.getPageName(), toAssignees));
+ } else {
+ if (!org.eclipse.osee.framework.jdk.core.util.Collections.isEqual(previousState.getAssignees(), toAssignees)) {
+ previousState.setAssignees(toAssignees);
+ }
+ currentStateDam.setState(previousState);
+ }
+ sma.setSoleAttributeValue(AtsAttributeTypes.CurrentStateType, toState.getWorkPageType().name());
+ }
+
+ /**
+ * Initializes state machine and sets the current state to stateName
+ */
+ public void initializeStateMachine(IWorkPage state) throws OseeCoreException {
+ initializeStateMachine(state, null);
+ }
+
+ /**
+ * Initializes state machine and sets the current state to stateName
+ */
+ public void initializeStateMachine(IWorkPage state, Collection<User> assignees) throws OseeCoreException {
+ SMAState smaState = null;
+ if (getVisitedStateNames().contains(state.getPageName())) {
+ smaState = getSMAState(state, false);
+ } else {
+ if (assignees == null) {
+ smaState = new SMAState(state.getPageName(), UserManager.getUser());
+ } else {
+ smaState = new SMAState(state.getPageName(), assignees);
+ }
+ }
+ currentStateDam.setState(smaState);
+ if (sma.isAttributeTypeValid(AtsAttributeTypes.CurrentStateType)) {
+ sma.setSoleAttributeValue(AtsAttributeTypes.CurrentStateType, state.getWorkPageType().name());
+ }
+ }
+
+ private void putState(SMAState state) throws OseeCoreException {
+ if (getCurrentStateName().equals(state.getName())) {
+ currentStateDam.setState(state);
+ } else {
+ stateDam.setState(state);
+ }
+ }
+
+ public Collection<String> getVisitedStateNames() {
+ Set<String> names = new HashSet<String>();
+ for (SMAState state : stateDam.getStates()) {
+ names.add(state.getName());
+ }
+ names.add(getCurrentStateName());
+ return names;
+ }
+
+ public long getTimeInState() throws OseeCoreException {
+ return getTimeInState(getCurrentState());
+ }
+
+ public long getTimeInState(IWorkPage state) throws OseeCoreException {
+ if (state == null) {
+ return 0;
+ }
+ LogItem logItem = sma.getStateStartedData(state);
+ if (logItem == null) {
+ return 0;
+ }
+ return new Date().getTime() - logItem.getDate().getTime();
+ }
+
+ /**
+ * return currently assigned state machine artifacts
+ */
+ public static Set<Artifact> getAssigned(User user) throws OseeCoreException {
+ return getAssigned(user, null);
+ }
+
+ /**
+ * return currently assigned state machine artifacts that match clazz
+ *
+ * @param clazz to match or all if null
+ */
+ public static Set<Artifact> getAssigned(User user, Class<?> clazz) throws OseeCoreException {
+ return getAssigned(user.getUserId(), clazz);
+ }
+
+ /**
+ * return currently assigned state machine artifacts that match clazz
+ *
+ * @param clazz to match or all if null
+ */
+ public static Set<Artifact> getAssigned(String userId, Class<?> clazz) throws OseeCoreException {
+ Set<Artifact> assigned = new HashSet<Artifact>();
+ for (Artifact artifact : ArtifactQuery.getArtifactListFromAttribute(AtsAttributeTypes.CurrentState,
+ "%<" + userId + ">%", AtsUtilCore.getAtsBranch())) {
+ if (clazz == null || clazz.isInstance(artifact)) {
+ assigned.add(artifact);
+ }
+ }
+ return assigned;
+
+ }
+
+ public static Collection<User> getImplementersByState(AbstractWorkflowArtifact workflow, IWorkPage state) throws OseeCoreException {
+ Set<User> users = new HashSet<User>();
+ if (workflow.isCancelled()) {
+ users.add(workflow.getCancelledBy());
+ } else {
+ users.addAll(workflow.getStateMgr().getAssignees(state));
+ User user = workflow.getCompletedBy();
+ if (user != null) {
+ users.add(user);
+ }
+ }
+ return users;
+ }
+
+ public void internalSetCurrentStateName(String stateName) throws OseeCoreException {
+ SMAState state = currentStateDam.getState();
+ if (state != null && !state.getName().equals(stateName)) {
+ state.setName(stateName);
+ }
+ currentStateDam.setState(state);
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XCurrentStateDam.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XCurrentStateDam.java
new file mode 100644
index 00000000000..cbdb6b95649
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XCurrentStateDam.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Date;
+import java.util.Set;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.workflow.log.LogItem;
+import org.eclipse.osee.ats.core.workflow.log.LogType;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XCurrentStateDam extends XStateAssigneesDam {
+
+ public XCurrentStateDam(AbstractWorkflowArtifact awa) {
+ super(awa, AtsAttributeTypes.CurrentState);
+ }
+
+ public SMAState getState() throws OseeCoreException {
+ Set<SMAState> states = getStates();
+ if (states.size() != 1) {
+ throw new OseeArgumentException("Must be one current state. Found %d for %s", states.size(), awa.getGuid());
+ }
+ return states.iterator().next();
+ }
+
+ @Override
+ public void setState(SMAState state) throws OseeCoreException {
+ awa.setSoleAttributeValue(attributeType, state.toXml());
+ }
+
+ public void updateMetrics(double additionalHours, int percentComplete, boolean logMetrics) throws OseeCoreException {
+ SMAState currState = getState();
+ currState.setHoursSpent(currState.getHoursSpent() + additionalHours);
+ currState.setPercentComplete(percentComplete);
+ setState(currState);
+ if (logMetrics) {
+ logMetrics(awa.getStateMgr().getCurrentState(), UserManager.getUser(), new Date());
+ }
+ }
+
+ public void setMetrics(double hours, int percentComplete, boolean logMetrics, User user, Date date) throws OseeCoreException {
+ SMAState currState = getState();
+ currState.setHoursSpent(hours);
+ currState.setPercentComplete(percentComplete);
+ setState(currState);
+ if (logMetrics) {
+ logMetrics(awa.getStateMgr().getCurrentState(), user, date);
+ }
+ }
+
+ public static void logMetrics(AbstractWorkflowArtifact sma, String percent, String hours, IWorkPage state, User user, Date date) throws OseeCoreException {
+ LogItem logItem =
+ new LogItem(LogType.Metrics, date, user, state.getPageName(), String.format("Percent %s Hours %s", percent,
+ hours), sma.getHumanReadableId());
+ sma.getLog().addLogItem(logItem);
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateAssigneesDam.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateAssigneesDam.java
new file mode 100644
index 00000000000..9f98968f709
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateAssigneesDam.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Attribute;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class XStateAssigneesDam {
+
+ protected final IAttributeType attributeType;
+ protected final AbstractWorkflowArtifact awa;
+
+ public XStateAssigneesDam(AbstractWorkflowArtifact awa, IAttributeType attributeType) {
+ this.awa = awa;
+ this.attributeType = attributeType;
+ }
+
+ public SMAState getState(IWorkPage state, boolean create) {
+ try {
+ for (String stateXml : awa.getAttributesToStringList(attributeType)) {
+ if (stateXml.startsWith(state.getPageName() + ";")) {
+ SMAState smaState = new SMAState();
+ smaState.setFromXml(stateXml);
+ return smaState;
+ }
+ }
+ if (create) {
+ return new SMAState(state.getPageName());
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, "Error parsing state data for " + awa.getGuid(), ex);
+ }
+ return null;
+ }
+
+ public void updateMetrics(IWorkPage state, double additionalHours, int percentComplete, boolean logMetrics) throws OseeCoreException {
+ SMAState smaState = getState(state, false);
+ smaState.setHoursSpent(smaState.getHoursSpent() + additionalHours);
+ smaState.setPercentComplete(percentComplete);
+ setState(smaState);
+ if (logMetrics) {
+ logMetrics(state, UserManager.getUser(), new Date());
+ }
+ }
+
+ public void setMetrics(IWorkPage state, double hours, int percentComplete, boolean logMetrics, User user, Date date) throws OseeCoreException {
+ SMAState currState = getState(state, false);
+ currState.setHoursSpent(hours);
+ currState.setPercentComplete(percentComplete);
+ setState(currState);
+ if (logMetrics) {
+ logMetrics(state, user, date);
+ }
+ }
+
+ protected void logMetrics(IWorkPage state, User user, Date date) throws OseeCoreException {
+ String hoursSpent = AtsUtilCore.doubleToI18nString(HoursSpentUtil.getHoursSpentTotal(awa));
+ XCurrentStateDam.logMetrics(awa, PercentCompleteTotalUtil.getPercentCompleteTotal(awa) + "", hoursSpent, state,
+ user, date);
+ }
+
+ public Set<SMAState> getStates() {
+ Set<SMAState> states = new HashSet<SMAState>();
+ try {
+ for (String stateXml : awa.getAttributesToStringList(attributeType)) {
+ SMAState state = new SMAState();
+ state.setFromXml(stateXml);
+ states.add(state);
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, "Error parsing state data for " + awa.getGuid(), ex);
+ }
+ return states;
+ }
+
+ @SuppressWarnings("unused")
+ public void setState(SMAState state) throws OseeCoreException {
+ // Update attribute if it already exists
+ try {
+ Collection<Attribute<String>> attrs = awa.getAttributes(attributeType);
+ for (Attribute<String> attr : attrs) {
+ SMAState storedState = new SMAState();
+ storedState.setFromXml(attr.getValue());
+ if (state.getName().equals(storedState.getName())) {
+ attr.setValue(state.toXml());
+ return;
+ }
+ }
+ // Else, doesn't exist yet, create
+ awa.addAttribute(attributeType, state.toXml());
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, "Error setting state data for " + awa.getGuid(), ex);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateDam.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateDam.java
new file mode 100644
index 00000000000..4bfc7497392
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/XStateDam.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow;
+
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XStateDam extends XStateAssigneesDam {
+
+ public XStateDam(AbstractWorkflowArtifact sma) {
+ super(sma, AtsAttributeTypes.State);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ArtifactLog.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ArtifactLog.java
new file mode 100644
index 00000000000..d3af7df5dbe
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ArtifactLog.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.log;
+
+import java.lang.ref.WeakReference;
+import java.util.logging.Level;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+public class ArtifactLog implements ILogStorageProvider {
+ private final WeakReference<Artifact> artifactRef;
+
+ public ArtifactLog(Artifact artifact) {
+ this.artifactRef = new WeakReference<Artifact>(artifact);
+ }
+
+ @Override
+ public String getLogXml() {
+ try {
+ return getArtifact().getSoleAttributeValue(AtsAttributeTypes.Log, "");
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return "getLogXml exception " + ex.getLocalizedMessage();
+ }
+ }
+
+ @Override
+ public IStatus saveLogXml(String xml) {
+ try {
+ getArtifact().setSoleAttributeValue(AtsAttributeTypes.Log, xml);
+ return Status.OK_STATUS;
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "saveLogXml exception " + ex.getLocalizedMessage());
+ }
+ }
+
+ public Artifact getArtifact() throws OseeStateException {
+ if (artifactRef.get() == null) {
+ throw new OseeStateException("Artifact has been garbage collected");
+ }
+ return artifactRef.get();
+ }
+
+ @Override
+ public String getLogTitle() {
+ try {
+ return "History for \"" + getArtifact().getArtifactTypeName() + "\" - " + getArtifact().getHumanReadableId() + " - titled \"" + getArtifact().getName() + "\"";
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return "getLogTitle exception " + ex.getLocalizedMessage();
+ }
+ }
+
+ @Override
+ public String getLogId() {
+ try {
+ return getArtifact().getHumanReadableId();
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return "unknown";
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/AtsLog.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/AtsLog.java
new file mode 100644
index 00000000000..0ae36718521
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/AtsLog.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.workflow.log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.AHTML;
+import org.eclipse.osee.framework.jdk.core.util.AXml;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.jdk.core.util.xml.Jaxp;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsLog {
+
+ private boolean enabled = true;
+ private final static String ATS_LOG_TAG = "AtsLog";
+ private final static String LOG_ITEM_TAG = "Item";
+ private LogItem cancelledLogItem;
+ private LogItem completedLogItem;
+ private final ILogStorageProvider storeProvider;
+ private final static Pattern LOG_ITEM_PATTERN =
+ Pattern.compile("<Item date=\"(.*?)\" msg=\"(.*?)\" state=\"(.*?)\" type=\"(.*?)\" userId=\"(.*?)\"/>");
+ private final static Pattern LOG_ITEM_TAG_PATTERN = Pattern.compile("<Item ");
+
+ public AtsLog(ILogStorageProvider storeProvider) {
+ this.storeProvider = storeProvider;
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return org.eclipse.osee.framework.jdk.core.util.Collections.toString("\n", getLogItems());
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return ex.getLocalizedMessage();
+ }
+ }
+
+ public String getHtml() throws OseeCoreException {
+ return getHtml(true);
+ }
+
+ public String getHtml(boolean showLog) throws OseeCoreException {
+ if (getLogItems().isEmpty()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ if (showLog) {
+ sb.append(AHTML.addSpace(1) + AHTML.getLabelStr(AHTML.LABEL_FONT, storeProvider.getLogTitle()));
+ }
+ sb.append(getTable());
+ return sb.toString();
+ }
+
+ public List<LogItem> getLogItems() throws OseeCoreException {
+ String xml = storeProvider.getLogXml();
+ return getLogItems(xml, storeProvider.getLogId());
+ }
+
+ private List<LogItem> getLogItems(String xml, String id) throws OseeCoreException {
+ List<LogItem> logItems = new ArrayList<LogItem>();
+ if (!xml.isEmpty()) {
+ Matcher m = LOG_ITEM_PATTERN.matcher(xml);
+ while (m.find()) {
+ LogItem item = new LogItem(m.group(4), m.group(1), Strings.intern(m.group(5)), Strings.intern(m.group(3)), // NOPMD by b0727536 on 9/29/10 8:52 AM
+ AXml.xmlToText(m.group(2)), id);
+ logItems.add(item);
+ }
+
+ Matcher m2 = LOG_ITEM_TAG_PATTERN.matcher(xml);
+ int openTagsFound = 0;
+ while (m2.find()) {
+ openTagsFound++;
+ }
+ if (logItems.size() != openTagsFound) {
+ OseeLog.log(Activator.class, Level.SEVERE, String.format(
+ "ATS Log: open tags found %d doesn't match log items parsed %d for %s", openTagsFound, logItems.size(),
+ id));
+ }
+ }
+ return logItems;
+ }
+
+ public Date getLastStatusedDate() throws OseeCoreException {
+ LogItem logItem = getLastEvent(LogType.Metrics);
+ if (logItem == null) {
+ return null;
+ }
+ return logItem.getDate();
+ }
+
+ public void putLogItems(List<LogItem> items) {
+ try {
+ Document doc = Jaxp.newDocumentNamespaceAware();
+ Element rootElement = doc.createElement(ATS_LOG_TAG);
+ doc.appendChild(rootElement);
+ for (LogItem item : items) {
+ Element element = doc.createElement(LOG_ITEM_TAG);
+ element.setAttribute("type", item.getType().name());
+ element.setAttribute("date", String.valueOf(item.getDate().getTime()));
+ element.setAttribute("userId", item.getUser().getUserId());
+ element.setAttribute("state", item.getState());
+ element.setAttribute("msg", item.getMsg());
+ rootElement.appendChild(element);
+ }
+ storeProvider.saveLogXml(Jaxp.getDocumentXml(doc));
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't create ats log document", ex);
+ }
+ }
+
+ public List<LogItem> getLogItemsReversed() throws OseeCoreException {
+ List<LogItem> logItems = getLogItems();
+ Collections.reverse(logItems);
+ return logItems;
+ }
+
+ /**
+ * Used to reset the original originated user. Only for internal use. Kept for backward compatibility.
+ */
+ public void internalResetOriginator(User user) throws OseeCoreException {
+ List<LogItem> logItems = getLogItems();
+ for (LogItem item : logItems) {
+ if (item.getType() == LogType.Originated) {
+ item.setUser(user);
+ putLogItems(logItems);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Used to reset the original originated user. Only for internal use. Kept for backward compatibility.
+ */
+ public void internalResetCreatedDate(Date date) throws OseeCoreException {
+ List<LogItem> logItems = getLogItems();
+ for (LogItem item : logItems) {
+ if (item.getType() == LogType.Originated) {
+ item.setDate(date);
+ putLogItems(logItems);
+ return;
+ }
+ }
+ }
+
+ /**
+ * This method is replaced by AbstractWorkflowArtifact.getCancelledFromState. Kept for backward compatibility.
+ */
+ public String internalGetCancelledFromState() throws OseeCoreException {
+ LogItem item = getStateEvent(LogType.StateCancelled);
+ if (item == null) {
+ return "";
+ }
+ return item.getState();
+ }
+
+ public String internalGetCancelledReason() throws OseeCoreException {
+ LogItem item = getStateEvent(LogType.StateCancelled);
+ if (item == null) {
+ return "";
+ }
+ return item.getMsg();
+ }
+
+ /**
+ * This method is replaced by AbstractWorkflowArtifact.getCompletedFromState. Kept for backward compatibility.
+ */
+ public String internalGetCompletedFromState() throws OseeCoreException {
+ LogItem item = getStateEvent(LogType.StateComplete);
+ if (item == null) {
+ return "";
+ }
+ return item.getState();
+ }
+
+ /**
+ * This method is replaced by AbstractWorkflowArtifact.setCompletedFromState. Kept for backward compatibility.
+ */
+ public void internalSetCancellationReason(String reason) throws OseeCoreException {
+ List<LogItem> logItems = getLogItemsReversed();
+ for (LogItem item : logItems) {
+ if (item.getType() == LogType.StateCancelled) {
+ item.setMsg(reason);
+ putLogItems(logItems);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Since originator can be changed, return the date of the first originated log item. Kept for backward
+ * compatibility.
+ */
+ public Date internalGetCreationDate() throws OseeCoreException {
+ LogItem logItem = getEvent(LogType.Originated);
+ if (logItem == null) {
+ return null;
+ }
+ return logItem.getDate();
+ }
+
+ /**
+ * Since originator change be changed, return the last originated event's user. Kept for backward compatibility.
+ */
+ public User internalGetOriginator() throws OseeCoreException {
+ LogItem logItem = getLastEvent(LogType.Originated);
+ if (logItem == null) {
+ return null;
+ }
+ return logItem.getUser();
+ }
+
+ /**
+ * Overwrite the first logItem to match type and state with newItem data
+ */
+ public void overrideStateItemData(LogType matchType, String matchState, LogItem newItem) throws OseeCoreException {
+ List<LogItem> logItems = getLogItems();
+ for (LogItem item : logItems) {
+ if (item.getType() == matchType && item.getState().equals(matchState)) {
+ item.setUser(newItem.getUser());
+ item.setDate(newItem.getDate());
+ item.setMsg(newItem.getMsg());
+ item.setState(newItem.getState());
+ putLogItems(logItems);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Overwrite the first logItem to match matchType with newItem data
+ */
+ public void overrideItemData(LogType matchType, LogItem newItem) throws OseeCoreException {
+ List<LogItem> logItems = getLogItems();
+ for (LogItem item : logItems) {
+ if (item.getType() == matchType) {
+ item.setState(newItem.getState());
+ item.setUser(newItem.getUser());
+ item.setDate(newItem.getDate());
+ item.setMsg(newItem.getMsg());
+ putLogItems(logItems);
+ return;
+ }
+ }
+ }
+
+ /**
+ * @param state name of state or null
+ */
+ public void addLog(LogType type, String state, String msg) throws OseeCoreException {
+ addLog(type, state, msg, new Date(), UserManager.getUser());
+ }
+
+ /**
+ * @param state name of state or null
+ */
+ public void addLog(LogType type, String state, String msg, User user) throws OseeCoreException {
+ addLog(type, state, msg, new Date(), user);
+ }
+
+ public void addLogItem(LogItem item) throws OseeCoreException {
+ addLog(item.getType(), item.getState(), item.getMsg(), item.getDate(), item.getUser());
+ }
+
+ public void addLog(LogType type, String state, String msg, Date date, User user) throws OseeCoreException {
+ if (!enabled) {
+ return;
+ }
+ LogItem logItem = new LogItem(type, date, user, state, msg, storeProvider.getLogId());
+ List<LogItem> logItems = getLogItems();
+ logItems.add(logItem);
+ putLogItems(logItems);
+ }
+
+ public void clearLog() {
+ putLogItems(new ArrayList<LogItem>());
+ }
+
+ public String getTable() throws OseeCoreException {
+ StringBuilder builder = new StringBuilder();
+ List<LogItem> logItems = getLogItems();
+ builder.append(AHTML.beginMultiColumnTable(100, 1));
+ builder.append(AHTML.addHeaderRowMultiColumnTable(Arrays.asList("Event", "State", "Message", "User", "Date")));
+ for (LogItem item : logItems) {
+ User user = item.getUser();
+ String userStr = null;
+ if (user == null) {
+ userStr = item.getUserId();
+ } else {
+ userStr = user.getName();
+ }
+ builder.append(AHTML.addRowMultiColumnTable(String.valueOf(item.getType()),
+ (item.getState().equals("") ? "." : item.getState()), (item.getMsg().equals("") ? "." : item.getMsg()),
+ userStr, item.getDate(DateUtil.MMDDYYHHMM)));
+ }
+ builder.append(AHTML.endMultiColumnTable());
+ return builder.toString();
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public LogItem getEvent(LogType type) throws OseeCoreException {
+ for (LogItem item : getLogItems()) {
+ if (item.getType() == type) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ public LogItem getLastEvent(LogType type) throws OseeCoreException {
+ for (LogItem item : getLogItemsReversed()) {
+ if (item.getType() == type) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ public LogItem getStateEvent(LogType type, String stateName) throws OseeCoreException {
+ for (LogItem item : getLogItemsReversed()) {
+ if (item.getType() == type && item.getState().equals(stateName)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ public LogItem getStateEvent(LogType type) throws OseeCoreException {
+ for (LogItem item : getLogItemsReversed()) {
+ if (item.getType() == type) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This method is replaced by Cancelled Date, By and Reason attributes. It will not work with multiple cancelled
+ * state design
+ */
+ public LogItem internalGetCancelledLogItem() throws OseeCoreException {
+ if (cancelledLogItem == null) {
+ cancelledLogItem = getStateEvent(LogType.StateEntered, "Cancelled");
+ }
+ return cancelledLogItem;
+ }
+
+ /**
+ * This method is replaced by Completed Date, By attributes. It will not work with multiple completed state design
+ */
+ public LogItem internalGetCompletedLogItem() throws OseeCoreException {
+ if (completedLogItem == null) {
+ completedLogItem = getStateEvent(LogType.StateEntered, "Completed");
+ }
+ return completedLogItem;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ILogStorageProvider.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ILogStorageProvider.java
new file mode 100644
index 00000000000..18e3e802ace
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/ILogStorageProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.log;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface ILogStorageProvider {
+
+ String getLogXml();
+
+ IStatus saveLogXml(String xml);
+
+ String getLogTitle();
+
+ String getLogId();
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogItem.java
new file mode 100644
index 00000000000..7f2534c6d8e
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogItem.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.log;
+
+import static org.eclipse.osee.framework.jdk.core.util.Strings.intern;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.UserNotInDatabase;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class LogItem {
+
+ private Date date;
+ private String msg;
+ private String state;
+ private User user;
+ private LogType type = LogType.None;
+ private final String userId;
+
+ public LogItem(LogType type, Date date, User user, String state, String msg, String hrid) throws OseeCoreException {
+ this(type.name(), String.valueOf(date.getTime()), user.getUserId(), state, msg, hrid);
+ }
+
+ public LogItem(LogType type, String date, String userId, String state, String msg, String hrid) throws OseeCoreException {
+ Long dateLong = Long.valueOf(date);
+ this.date = new Date(dateLong.longValue());
+ this.msg = msg;
+ this.state = intern(state);
+ this.userId = intern(userId);
+ try {
+ this.user = UserManager.getUserByUserId(userId);
+ } catch (UserNotInDatabase ex) {
+ this.user = UserManager.getUser(SystemUser.Guest);
+ OseeLog.log(Activator.class, Level.SEVERE,
+ String.format("Error parsing ATS Log for %s - %s", hrid, ex.getLocalizedMessage()), ex);
+ }
+ this.type = type;
+ }
+
+ public LogItem(String type, String date, String userId, String state, String msg, String hrid) throws OseeCoreException {
+ this(LogType.getType(type), date, userId, state, msg, hrid);
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public String getDate(String pattern) {
+ if (pattern != null) {
+ return new SimpleDateFormat(pattern, Locale.US).format(date);
+ }
+ return date.toString();
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s (%s)%s by %s on %s", getToStringMsg(), type, getToStringState(), getToStringUser(),
+ DateUtil.getMMDDYYHHMM(date));
+ }
+
+ private String getToStringUser() {
+ return user == null ? "unknown" : user.getName();
+ }
+
+ private String getToStringState() {
+ return state.isEmpty() ? "" : "from " + state;
+ }
+
+ private String getToStringMsg() {
+ return msg.isEmpty() ? "" : msg;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public LogType getType() {
+ return type;
+ }
+
+ public void setType(LogType type) {
+ this.type = type;
+ }
+
+ public String toHTML(String labelFont) {
+ return "NOTE (" + type + "): " + msg + " (" + user.getName() + ")";
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogType.java
new file mode 100644
index 00000000000..f0216514bf5
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/log/LogType.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.log;
+
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+
+public enum LogType {
+ None,
+ Assign,
+ Released,
+ Originated,
+ StateComplete,
+ StateCancelled,
+ StateEntered,
+ Error,
+ Note,
+ Metrics;
+
+ public static LogType getType(String type) throws OseeArgumentException {
+ for (Enum<LogType> e : LogType.values()) {
+ if (e.name().equals(type)) {
+ return (LogType) e;
+ }
+ }
+ throw new OseeArgumentException("Unhandled LogType: [%s]", type);
+ }
+
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/ArtifactNote.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/ArtifactNote.java
new file mode 100644
index 00000000000..abdb2938300
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/ArtifactNote.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.note;
+
+import java.lang.ref.WeakReference;
+import java.util.logging.Level;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+
+public class ArtifactNote implements INoteStorageProvider {
+ private final WeakReference<Artifact> artifactRef;
+
+ public ArtifactNote(Artifact artifact) {
+ this.artifactRef = new WeakReference<Artifact>(artifact);
+ }
+
+ @Override
+ public String getNoteXml() {
+ try {
+ return getArtifact().getSoleAttributeValue(AtsAttributeTypes.StateNotes, "");
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return "getLogXml exception " + ex.getLocalizedMessage();
+ }
+ }
+
+ @Override
+ public IStatus saveNoteXml(String xml) {
+ try {
+ getArtifact().setSoleAttributeValue(AtsAttributeTypes.StateNotes, xml);
+ return Status.OK_STATUS;
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "saveLogXml exception " + ex.getLocalizedMessage());
+ }
+ }
+
+ public Artifact getArtifact() throws OseeStateException {
+ if (artifactRef.get() == null) {
+ throw new OseeStateException("Artifact has been garbage collected");
+ }
+ return artifactRef.get();
+ }
+
+ @Override
+ public String getNoteTitle() {
+ try {
+ return "History for \"" + getArtifact().getArtifactTypeName() + "\" - " + getArtifact().getHumanReadableId() + " - titled \"" + getArtifact().getName() + "\"";
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ return "getLogTitle exception " + ex.getLocalizedMessage();
+ }
+ }
+
+ @Override
+ public String getNoteId() {
+ try {
+ return getArtifact().getHumanReadableId();
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return "unknown";
+ }
+
+ @Override
+ public boolean isNoteable() {
+ try {
+ return getArtifact().isAttributeTypeValid(AtsAttributeTypes.StateNotes);
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex);
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/AtsNote.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/AtsNote.java
new file mode 100644
index 00000000000..4875a0f4ce8
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/AtsNote.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.note;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.jdk.core.util.AHTML;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsNote {
+ private boolean enabled = true;
+ private final INoteStorageProvider storeProvder;
+
+ public AtsNote(INoteStorageProvider storeProvder) {
+ this.storeProvder = storeProvder;
+ }
+
+ public void addNote(NoteType type, String state, String msg, User user) {
+ addNote(type, state, msg, new Date(), user);
+ }
+
+ public void addNoteItem(NoteItem noteItem) {
+ addNote(noteItem.getType(), noteItem.getState(), noteItem.getMsg(), noteItem.getDate(), noteItem.getUser());
+ }
+
+ public void addNote(NoteType type, String state, String msg, Date date, User user) {
+ if (!enabled) {
+ return;
+ }
+ NoteItem logItem = new NoteItem(type, state, String.valueOf(date.getTime()), user, msg);
+ List<NoteItem> logItems = getNoteItems();
+ if (logItems.isEmpty()) {
+ logItems = Arrays.asList(logItem);
+ } else {
+ logItems.add(logItem);
+ }
+ saveNoteItems(logItems);
+ }
+
+ public List<NoteItem> getNoteItems() {
+ try {
+ String xml = storeProvder.getNoteXml();
+ if (Strings.isValid(xml)) {
+ return NoteItem.fromXml(xml, storeProvder.getNoteId());
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ }
+ return Collections.emptyList();
+ }
+
+ public void saveNoteItems(List<NoteItem> items) {
+ try {
+ String xml = NoteItem.toXml(items);
+ storeProvder.saveNoteXml(xml);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't create ats note document", ex);
+ }
+ }
+
+ /**
+ * Display Note Table; If state == null, only display non-state notes Otherwise, show only notes associated with
+ * state
+ */
+ public String getTable(String state) {
+ if (!storeProvder.isNoteable()) {
+ return "";
+ }
+ ArrayList<NoteItem> showNotes = new ArrayList<NoteItem>();
+ List<NoteItem> noteItems = getNoteItems();
+
+ for (NoteItem li : noteItems) {
+ if (state == null && li.getState().equals("")) {
+ showNotes.add(li);
+ } else if (state != null && ("ALL".equals(state) || li.getState().equals(state))) {
+ showNotes.add(li);
+ }
+ }
+ if (showNotes.isEmpty()) {
+ return "";
+ }
+ return buildTable(showNotes);
+ }
+
+ private String buildTable(List<NoteItem> showNotes) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(AHTML.beginMultiColumnTable(100, 1));
+ builder.append(AHTML.addHeaderRowMultiColumnTable(Arrays.asList("Type", "State", "Message", "User", "Date")));
+ DateFormat dateFormat = getDateFormat();
+ for (NoteItem note : showNotes) {
+ User user = note.getUser();
+ String name = "";
+ if (user != null) {
+ name = user.getName();
+ if (!Strings.isValid(name)) {
+ name = user.getName();
+ }
+ }
+ builder.append(AHTML.addRowMultiColumnTable(String.valueOf(note.getType()),
+ (note.getState().isEmpty() ? "," : note.getState()), (note.getMsg().equals("") ? "," : note.getMsg()),
+ name, dateFormat.format(note.getDate())));
+ }
+ builder.append(AHTML.endMultiColumnTable());
+ return builder.toString();
+ }
+
+ public DateFormat getDateFormat() {
+ return new SimpleDateFormat("MM/dd/yyyy h:mm a", Locale.US);
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/INoteStorageProvider.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/INoteStorageProvider.java
new file mode 100644
index 00000000000..3899ff51c2f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/INoteStorageProvider.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.note;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface INoteStorageProvider {
+
+ String getNoteXml();
+
+ IStatus saveNoteXml(String xml);
+
+ String getNoteTitle();
+
+ String getNoteId();
+
+ boolean isNoteable();
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteItem.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteItem.java
new file mode 100644
index 00000000000..14cf5207879
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteItem.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.ats.core.workflow.note;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.UserNotInDatabase;
+import org.eclipse.osee.framework.jdk.core.util.DateUtil;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.jdk.core.util.xml.Jaxp;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class NoteItem {
+
+ private Date date;
+ private final String state;
+ private String msg;
+ private User user;
+ private NoteType type = NoteType.Other;
+ protected final static String LOG_ITEM_TAG = "Item";
+ private final static String ATS_NOTE_TAG = "AtsNote";
+
+ public NoteItem(NoteType type, String state, String date, User user, String msg) {
+ Long l = Long.valueOf(date);
+ this.date = new Date(l.longValue());
+ this.state = Strings.intern(state);
+ this.msg = msg;
+ this.user = user;
+ this.type = type;
+ }
+
+ public NoteItem(String type, String state, String date, User user, String msg) throws OseeCoreException {
+ this(NoteType.getType(type), state, date, user, msg);
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Note: %s from %s%s on %s - %s", type, user.getName(), toStringState(),
+ DateUtil.getMMDDYYHHMM(date), msg);
+ }
+
+ private String toStringState() {
+ return (state.isEmpty() ? "" : " for \"" + state + "\"");
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public NoteType getType() {
+ return type;
+ }
+
+ public void setType(NoteType type) {
+ this.type = type;
+ }
+
+ public String toHTML() {
+ return toString().replaceFirst("^Note: ", "<b>Note:</b>");
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public static List<NoteItem> fromXml(String xml, String hrid) {
+ List<NoteItem> logItems = new ArrayList<NoteItem>();
+ try {
+ if (Strings.isValid(xml)) {
+ NodeList nodes = Jaxp.readXmlDocument(xml).getElementsByTagName(LOG_ITEM_TAG);
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Element element = (Element) nodes.item(i);
+ try {
+ User user = UserManager.getUserByUserId(element.getAttribute("userId"));
+ NoteItem item = new NoteItem(element.getAttribute("type"), element.getAttribute("state"), // NOPMD by b0727536 on 9/29/10 8:52 AM
+ element.getAttribute("date"), user, element.getAttribute("msg"));
+ logItems.add(item);
+ } catch (UserNotInDatabase ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, String.format("Error parsing notes for [%s]", hrid), ex);
+ NoteItem item = new NoteItem(element.getAttribute("type"), element.getAttribute("state"), // NOPMD by b0727536 on 9/29/10 8:52 AM
+ element.getAttribute("date"), UserManager.getUser(SystemUser.Guest), element.getAttribute("msg"));
+ logItems.add(item);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ }
+ return logItems;
+ }
+
+ public static String toXml(List<NoteItem> items) {
+ try {
+ Document doc = Jaxp.newDocumentNamespaceAware();
+ Element rootElement = doc.createElement(ATS_NOTE_TAG);
+ doc.appendChild(rootElement);
+ for (NoteItem item : items) {
+ Element element = doc.createElement(NoteItem.LOG_ITEM_TAG);
+ element.setAttribute("type", item.getType().name());
+ element.setAttribute("state", item.getState());
+ element.setAttribute("date", String.valueOf(item.getDate().getTime()));
+ element.setAttribute("userId", item.getUser().getUserId());
+ element.setAttribute("msg", item.getMsg());
+ rootElement.appendChild(element);
+ }
+ return Jaxp.getDocumentXml(doc);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't create ats note document", ex);
+ }
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteType.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteType.java
new file mode 100644
index 00000000000..813bd7e0d78
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/note/NoteType.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.note;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+
+/**
+ * @author Donald G. Dunne
+ */
+public enum NoteType {
+ Comment,
+ Question,
+ Error,
+ Other;
+
+ public static NoteType getType(String type) throws OseeArgumentException {
+ for (NoteType e : NoteType.values()) {
+ if (e.name().equals(type)) {
+ return e;
+ }
+ }
+ throw new OseeArgumentException("Unhandled NoteType");
+ }
+
+ public static List<String> getNames() {
+ List<String> names = new ArrayList<String>();
+ for (NoteType e : NoteType.values()) {
+ names.add(e.name());
+ }
+ return names;
+ }
+
+};
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/ITransitionListener.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/ITransitionListener.java
new file mode 100644
index 00000000000..ce8b1aa92b7
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/ITransitionListener.java
@@ -0,0 +1,28 @@
+/*
+ * Created on May 12, 2011
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow.transition;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+
+/**
+ * @author Donald G. Dunne
+ */
+public interface ITransitionListener {
+
+ /**
+ * @return Result of operation. If Result.isFalse(), transition will not continue and Result.popup will occur.
+ */
+ public Result transitioning(AbstractWorkflowArtifact sma, IWorkPage fromState, IWorkPage toState, Collection<User> toAssignees) throws OseeCoreException;
+
+ public void transitioned(AbstractWorkflowArtifact sma, IWorkPage fromState, IWorkPage toState, Collection<User> toAssignees, SkynetTransaction transaction) throws OseeCoreException;
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionListeners.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionListeners.java
new file mode 100644
index 00000000000..3894c051d22
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionListeners.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.transition;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class TransitionListeners {
+
+ private static Set<ITransitionListener> listeners;
+
+ private TransitionListeners() {
+ // private constructor
+ }
+
+ /*
+ * due to lazy initialization, this function is non-reentrant therefore, the synchronized keyword is necessary
+ */
+ private synchronized static Set<ITransitionListener> ensureLoaded() {
+ if (listeners != null) {
+ return listeners;
+ }
+ listeners = new HashSet<ITransitionListener>();
+
+ IExtensionPoint point =
+ Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.osee.ats.core.AtsTransitionListener");
+ if (point == null) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Can't access AtsTransitionListener extension point");
+ return listeners;
+ }
+ IExtension[] extensions = point.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ String classname = null;
+ String bundleName = null;
+ for (IConfigurationElement el : elements) {
+ if (el.getName().equals("AtsTransitionListener")) {
+ classname = el.getAttribute("classname");
+ bundleName = el.getContributor().getName();
+ if (classname != null && bundleName != null) {
+ Bundle bundle = Platform.getBundle(bundleName);
+ try {
+ Class<?> taskClass = bundle.loadClass(classname);
+ Object obj = taskClass.newInstance();
+ listeners.add((ITransitionListener) obj);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP,
+ "Error loading AtsTransitionListener extension", ex);
+ }
+ }
+ }
+ }
+ }
+ return listeners;
+ }
+
+ public static Set<ITransitionListener> getListeners() {
+ ensureLoaded();
+ return listeners;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java
new file mode 100644
index 00000000000..6f266ac0c8f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java
@@ -0,0 +1,495 @@
+/*
+ * Created on Nov 17, 2010
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.ats.core.workflow.transition;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.logging.Level;
+import org.eclipse.osee.ats.core.branch.AtsBranchManagerCore;
+import org.eclipse.osee.ats.core.internal.Activator;
+import org.eclipse.osee.ats.core.review.AbstractReviewArtifact;
+import org.eclipse.osee.ats.core.review.ReviewManager;
+import org.eclipse.osee.ats.core.task.AbstractTaskableArtifact;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.core.team.TeamState;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.ATSAttributes;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.util.WorkflowManagerCore;
+import org.eclipse.osee.ats.core.workdef.ReviewBlockType;
+import org.eclipse.osee.ats.core.workdef.RuleDefinitionOption;
+import org.eclipse.osee.ats.core.workdef.StateDefinition;
+import org.eclipse.osee.ats.core.workdef.WidgetDefinition;
+import org.eclipse.osee.ats.core.workdef.WidgetOption;
+import org.eclipse.osee.ats.core.workflow.AbstractWorkflowArtifact;
+import org.eclipse.osee.ats.core.workflow.log.LogType;
+import org.eclipse.osee.framework.core.data.SystemUser;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.IWorkPage;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.core.util.WorkPageType;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.User;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.attribute.AttributeTypeManager;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.validation.OseeXWidgetValidateManager;
+
+public class TransitionManager {
+
+ private final AbstractWorkflowArtifact awa;
+ private StateDefinition toStateDefinition;
+ private final boolean priviledgedEditEnabled;
+ private String cancellationReason;
+
+ public TransitionManager(AbstractWorkflowArtifact awa) {
+ this(awa, false);
+ }
+
+ public TransitionManager(AbstractWorkflowArtifact awa, boolean priviledgedEditEnabled) {
+ this.awa = awa;
+ this.priviledgedEditEnabled = priviledgedEditEnabled;
+ }
+
+ public Result handleTransition(StateDefinition toStateDefinition, String cancellationReason) {
+ this.toStateDefinition = toStateDefinition;
+ this.cancellationReason = cancellationReason;
+ try {
+
+ if (!WorkflowManagerCore.isEditable(awa, awa.getStateDefinition(), priviledgedEditEnabled) && !awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.UnAssigned))) {
+ return new Result(
+ "You must be assigned to transition this workflow.\nContact Assignee or Select Priviledged Edit for Authorized Overriders.");
+ }
+
+ Result result = isWorkingBranchTransitionable();
+ if (result.isFalse()) {
+ return result;
+ }
+
+ if (toStateDefinition == null) {
+ return new Result("No Transition State Selected");
+ }
+ if (toStateDefinition.isCancelledPage()) {
+ return handleTransitionToCancelled(awa);
+ }
+
+ // Validate assignees
+ if (awa.getStateMgr().getAssignees().contains(UserManager.getUser(SystemUser.OseeSystem)) || awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.Guest)) || awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.UnAssigned))) {
+ return new Result("Can not transition with \"Guest\", \"UnAssigned\" or \"OseeSystem\" user as assignee.");
+ }
+
+ awa.setInTransition(true);
+
+ // As a convenience, if assignee is UnAssigned and user selects to transition, make user current assignee
+ if (awa.getStateMgr().getAssignees().contains(UserManager.getUser(SystemUser.UnAssigned))) {
+ awa.getStateMgr().removeAssignee(UserManager.getUser(SystemUser.UnAssigned));
+ awa.getStateMgr().addAssignee(UserManager.getUser());
+ }
+
+ // Get transition to assignees
+ Collection<User> toAssignees;
+ if (toStateDefinition.isCancelledPage() || toStateDefinition.isCompletedPage()) {
+ toAssignees = new HashSet<User>();
+ } else {
+ toAssignees = awa.getTransitionAssignees();
+ if (toAssignees.isEmpty()) {
+ toAssignees.add(UserManager.getUser());
+ }
+ }
+
+ // If overrideAttributeValidation state, don't require page/tasks to be complete
+ boolean isOverrideAttributeValidationState =
+ awa.getStateDefinition().getOverrideAttributeValidationStates().contains(toStateDefinition);
+ if (!isOverrideAttributeValidationState) {
+ result = isStateTransitionable(awa.getStateDefinition(), toStateDefinition, toAssignees);
+ if (result.isFalse()) {
+ return result;
+ }
+ }
+
+ // Persist must be done prior and separate from transition
+ awa.persist();
+
+ // Perform transition separate from persist of previous changes to state machine artifact
+ SkynetTransaction transaction = new SkynetTransaction(AtsUtilCore.getAtsBranch(), "ATS Transition");
+ result = transition(toStateDefinition, toAssignees, transaction, TransitionOption.Persist);
+ transaction.execute();
+ if (result.isFalse()) {
+ return result;
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ } finally {
+ awa.setInTransition(false);
+ }
+ return Result.TrueResult;
+ }
+
+ private Result isWorkingBranchTransitionable() throws OseeCoreException {
+ if (awa.isTeamWorkflow() && AtsBranchManagerCore.isWorkingBranchInWork(((TeamWorkFlowArtifact) awa))) {
+
+ if (toStateDefinition.getPageName().equals(TeamState.Cancelled.getPageName())) {
+ new Result("Working Branch exists.\n\nPlease delete working branch before transition to cancel.");
+ }
+ if (AtsBranchManagerCore.isBranchInCommit(((TeamWorkFlowArtifact) awa))) {
+ new Result("Working Branch is being Committed.\n\nPlease wait till commit completes to transition.");
+ }
+ if (!isAllowTransitionWithWorkingBranch(toStateDefinition)) {
+ new Result("Working Branch exists.\n\nPlease commit or delete working branch before transition.");
+ }
+ }
+ return Result.TrueResult;
+ }
+
+ public static boolean isAllowTransitionWithWorkingBranch(StateDefinition stateDefinition) {
+ return stateDefinition.hasRule(RuleDefinitionOption.AllowTransitionWithWorkingBranch);
+ }
+
+ /**
+ * Return collection of problems with state widgets and artifact model storage
+ */
+ private Collection<ValidResult> isStateValid(AbstractWorkflowArtifact awa, StateDefinition stateDef) throws OseeCoreException {
+ List<ValidResult> results = new ArrayList<ValidResult>();
+ for (WidgetDefinition widgetDef : stateDef.getWidgets()) {
+ ValidResult result = isWidgetValid(awa, widgetDef);
+ if (result != null) {
+ results.add(result);
+ }
+ }
+ return results;
+ }
+
+ private static enum ValidType {
+ RequiredForCompletion,
+ RequiredForTransition;
+ }
+
+ private static class ValidResult {
+ public ValidType type;
+ public WidgetDefinition widgetDef;
+
+ public ValidResult(ValidType type, WidgetDefinition widgetDef) {
+ super();
+ this.type = type;
+ this.widgetDef = widgetDef;
+ }
+ }
+
+ /**
+ * Return result of validity between widget and artifact model storage
+ */
+ public static ValidResult isWidgetValid(AbstractWorkflowArtifact awa, WidgetDefinition widgetDef) throws OseeCoreException {
+ // validate first with providers of validation
+ if (Strings.isValid(widgetDef.getXWidgetName())) {
+ OseeXWidgetValidateManager.instance.validate(awa, widgetDef.getXWidgetName(), widgetDef.getName());
+ }
+
+ // else fallback on attribute validation if this is an artifact stored widget
+ if (Strings.isValid(widgetDef.getAtrributeName())) {
+ if (widgetDef.getOptions().contains(WidgetOption.REQUIRED_FOR_COMPLETION)) {
+ if (awa.getAttributesToStringList(AttributeTypeManager.getType(widgetDef.getAtrributeName())).isEmpty()) {
+ return new ValidResult(ValidType.RequiredForCompletion, widgetDef);
+ }
+ } else if (widgetDef.getOptions().contains(WidgetOption.REQUIRED_FOR_TRANSITION)) {
+ if (awa.getAttributesToStringList(AttributeTypeManager.getType(widgetDef.getAtrributeName())).isEmpty()) {
+ return new ValidResult(ValidType.RequiredForTransition, widgetDef);
+ }
+ }
+ }
+ return null;
+ }
+
+ private Result isStateTransitionable(StateDefinition fromStateDefinition, StateDefinition toStateDefinition, Collection<User> toAssignees) throws OseeCoreException {
+ // Validate XWidgets for transition
+ Collection<ValidResult> stateValid = isStateValid(awa, fromStateDefinition);
+ StringBuffer sb = new StringBuffer();
+ for (ValidResult validResult : stateValid) {
+ // Stop transition if any errors exist
+ if (validResult.type == ValidType.RequiredForTransition) {
+ sb.append(String.format("[%s] required for transition\n", validResult.widgetDef.getName()));
+ }
+ // Only stop transition on warning if transitioning to completed state and REQUIRED_FOR_COMPLETION
+ else if (validResult.type == ValidType.RequiredForCompletion) {
+ boolean reqForCompletion =
+ validResult.widgetDef.getOptions().contains(WidgetOption.REQUIRED_FOR_COMPLETION);
+ if (reqForCompletion && toStateDefinition.getWorkPageType() == WorkPageType.Completed) {
+ sb.append(String.format("[%s] required for completion\n", validResult.widgetDef.getName()));
+ }
+ }
+ }
+ if (!sb.toString().isEmpty()) {
+ return new Result(sb.toString());
+ }
+
+ // Loop through this state's tasks to confirm complete
+ if (awa instanceof AbstractTaskableArtifact && !awa.isCompletedOrCancelled()) {
+ for (TaskArtifact taskArt : ((AbstractTaskableArtifact) awa).getTaskArtifactsFromCurrentState()) {
+ if (taskArt.isInWork()) {
+ return new Result(
+ "Transition Blocked: Task Not Complete\n\nTitle: " + taskArt.getName() + "\n\nHRID: " + taskArt.getHumanReadableId());
+ }
+ }
+ }
+
+ // Don't transition without targeted version if so configured
+ boolean teamDefRequiresTargetedVersion = awa.teamDefHasRule(RuleDefinitionOption.RequireTargetedVersion);
+ boolean pageRequiresTargetedVersion =
+ awa.getStateDefinition().hasRule(RuleDefinitionOption.RequireTargetedVersion);
+
+ // Only check this if TeamWorkflow, not for reviews
+ if (awa.isOfType(AtsArtifactTypes.TeamWorkflow) && (teamDefRequiresTargetedVersion || pageRequiresTargetedVersion) && //
+ awa.getTargetedVersion() == null && //
+ !toStateDefinition.isCancelledPage()) {
+ return new Result(
+ "Transition Blocked: Actions must be targeted for a Version.\nPlease set \"Target Version\" before transition.");
+ }
+
+ // Loop through this state's blocking reviews to confirm complete
+ if (awa.isTeamWorkflow()) {
+ for (AbstractReviewArtifact reviewArt : ReviewManager.getReviewsFromCurrentState((TeamWorkFlowArtifact) awa)) {
+ if (reviewArt.getReviewBlockType() == ReviewBlockType.Transition && !reviewArt.isCompletedOrCancelled()) {
+ return new Result("Transition Blocked: All Blocking Reviews must be completed before transition.");
+ }
+ }
+ }
+
+ // Check extension points for valid transition
+ for (ITransitionListener listener : TransitionListeners.getListeners()) {
+ try {
+ Result result =
+ listener.transitioning(awa, awa.getStateMgr().getCurrentState(), toStateDefinition, toAssignees);
+ if (result.isFalse()) {
+ return result;
+ }
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, "Exception occurred during transition; Aborting.", ex);
+ return new Result(String.format("Exception occurred during transition; Aborting. [%s]",
+ ex.getLocalizedMessage()));
+ }
+ }
+
+ return Result.TrueResult;
+ }
+
+ private Result handleTransitionToCancelled(AbstractWorkflowArtifact awa) throws OseeCoreException {
+ SkynetTransaction transaction = new SkynetTransaction(AtsUtilCore.getAtsBranch(), "ATS Transition to Cancelled");
+ TransitionManager transitionMgr = new TransitionManager(awa);
+ Result result = transitionMgr.transitionToCancelled(cancellationReason, transaction, TransitionOption.Persist);
+ if (result.isFalse()) {
+ return result;
+ }
+ awa.setInTransition(false);
+ transaction.execute();
+ return Result.TrueResult;
+ }
+
+ public Result isTransitionValid(final IWorkPage toState, final Collection<User> toAssignees, TransitionOption... transitionOption) throws OseeCoreException {
+ boolean overrideTransitionCheck =
+ org.eclipse.osee.framework.jdk.core.util.Collections.getAggregate(transitionOption).contains(
+ TransitionOption.OverrideTransitionValidityCheck);
+ boolean overrideAssigneeCheck =
+ org.eclipse.osee.framework.jdk.core.util.Collections.getAggregate(transitionOption).contains(
+ TransitionOption.OverrideAssigneeCheck);
+ // Validate assignees
+ if (!overrideAssigneeCheck && (awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.OseeSystem)) || awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.Guest)) || awa.getStateMgr().getAssignees().contains(
+ UserManager.getUser(SystemUser.UnAssigned)))) {
+ return new Result("Can not transition with \"Guest\", \"UnAssigned\" or \"OseeSystem\" user as assignee.");
+ }
+
+ // Validate toState name
+ final StateDefinition fromStateDefinition = awa.getStateDefinition();
+ final StateDefinition toStateDefinition = awa.getStateDefinitionByName(toState.getPageName());
+ if (toStateDefinition == null) {
+ return new Result(String.format("Transition-To State [%s] does not exist for Work Definition [%s]",
+ toState.getPageName(), awa.getWorkDefinition().getName()));
+ }
+
+ // Validate transition from fromPage to toPage
+ if (!overrideTransitionCheck && !fromStateDefinition.getToStates().contains(toStateDefinition) && !fromStateDefinition.isCompletedOrCancelledPage()) {
+ String errStr =
+ String.format("Work Definition [%s] is not configured to transition from \"[%s]\" to \"[%s]\"",
+ toStateDefinition.getName(), fromStateDefinition.getPageName(), toState.getPageName());
+ OseeLog.log(Activator.class, Level.SEVERE, errStr);
+ return new Result(errStr);
+ }
+ // Don't transition with existing working branch
+ if (toStateDefinition.isCancelledPage() && awa.isTeamWorkflow() && AtsBranchManagerCore.isWorkingBranchInWork(((TeamWorkFlowArtifact) awa))) {
+ return new Result("Working Branch exists. Please delete working branch before cancelling.");
+ }
+
+ // Don't transition with uncommitted branch if this is a commit state
+ if (isAllowCommitBranch(awa.getStateDefinition()) && awa.isTeamWorkflow() && AtsBranchManagerCore.isWorkingBranchInWork(((TeamWorkFlowArtifact) awa))) {
+ return new Result("Working Branch exists. Please commit or delete working branch before transition.");
+ }
+
+ // Check extension points for valid transition
+ for (ITransitionListener listener : TransitionListeners.getListeners()) {
+ Result result = listener.transitioning(awa, fromStateDefinition, toState, toAssignees);
+ if (result.isFalse()) {
+ return result;
+ }
+ }
+ // Check again in case first check made changes that would now keep transition from happening
+ for (ITransitionListener listener : TransitionListeners.getListeners()) {
+ Result result = listener.transitioning(awa, fromStateDefinition, toState, toAssignees);
+ if (result.isFalse()) {
+ return result;
+ }
+ }
+ return Result.TrueResult;
+ }
+
+ public static boolean isAllowCommitBranch(StateDefinition stateDefinition) {
+ return stateDefinition.hasRule(ATSAttributes.COMMIT_MANAGER_WIDGET.getWorkItemId());
+ }
+
+ public Result transition(IWorkPage toState, User toAssignee, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ List<User> users = new ArrayList<User>();
+ if (toAssignee != null && !toState.getWorkPageType().isCompletedOrCancelledPage()) {
+ users.add(toAssignee);
+ }
+ return transition(toState, users, transaction, transitionOption);
+ }
+
+ public Result transition(IWorkPage toState, Collection<User> toAssignees, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ return transition(toState, toAssignees, (String) null, transaction, transitionOption);
+ }
+
+ private Result transition(final IWorkPage toState, final Collection<User> toAssignees, final String completeOrCancelReason, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ try {
+ final boolean persist =
+ org.eclipse.osee.framework.jdk.core.util.Collections.getAggregate(transitionOption).contains(
+ TransitionOption.Persist);
+
+ Result result = isTransitionValid(toState, toAssignees, transitionOption);
+ if (result.isFalse()) {
+ return result;
+ }
+
+ final StateDefinition fromStateDefinition = awa.getStateDefinition();
+ final StateDefinition toStateDefinition = awa.getStateDefinitionByName(toState.getPageName());
+
+ transitionHelper(toAssignees, persist, fromStateDefinition, toStateDefinition, completeOrCancelReason,
+ transaction);
+ } catch (Exception ex) {
+ OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+ return new Result("Transaction failed " + ex.getLocalizedMessage());
+ }
+ return Result.TrueResult;
+ }
+
+ private void transitionHelper(Collection<User> toAssignees, boolean persist, StateDefinition fromState, StateDefinition toState, String completeOrCancelReason, SkynetTransaction transaction) throws OseeCoreException {
+ Date transitionDate = new Date();
+ User transitionUser = UserManager.getUser();
+ // Log transition
+ if (toState.isCancelledPage()) {
+ logWorkflowCancelledEvent(awa.getStateMgr().getCurrentStateName(), completeOrCancelReason, transitionDate,
+ transitionUser);
+ } else if (toState.isCompletedPage()) {
+ logWorkflowCompletedEvent(awa.getStateMgr().getCurrentStateName(), completeOrCancelReason, transitionDate,
+ transitionUser);
+ } else {
+ logStateCompletedEvent(awa.getStateMgr().getCurrentStateName(), completeOrCancelReason, transitionDate,
+ transitionUser);
+ }
+ if (fromState.isCancelledPage()) {
+ logWorkflowUnCancelledEvent();
+ } else if (fromState.isCompletedPage()) {
+ logWorkflowUnCompletedEvent();
+ }
+ logStateStartedEvent(toState, transitionDate, transitionUser);
+
+ awa.getStateMgr().transitionHelper(toAssignees, fromState, toState, completeOrCancelReason);
+
+ if (awa.isValidationRequired() && awa.isTeamWorkflow()) {
+ ReviewManager.createValidateReview((TeamWorkFlowArtifact) awa, false, transitionDate, transitionUser,
+ transaction);
+ }
+
+ // Persist
+ if (persist) {
+ awa.persist(transaction);
+ }
+
+ awa.transitioned(fromState, toState, toAssignees, true, transaction);
+
+ // Notify extension points of transition
+ for (ITransitionListener listener : TransitionListeners.getListeners()) {
+ listener.transitioned(awa, fromState, toState, toAssignees, transaction);
+ }
+ }
+
+ public Result transitionToCancelled(String reason, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ Result result =
+ transition(TeamState.Cancelled, Arrays.asList(new User[] {}), reason, transaction, transitionOption);
+ return result;
+ }
+
+ public Result transitionToCompleted(String reason, SkynetTransaction transaction, TransitionOption... transitionOption) {
+ Result result =
+ transition(TeamState.Completed, Arrays.asList(new User[] {}), reason, transaction, transitionOption);
+ return result;
+ }
+
+ public void logWorkflowCancelledEvent(String fromStateName, String reason, Date cancelDate, User cancelBy) throws OseeCoreException {
+ awa.getLog().addLog(LogType.StateCancelled, fromStateName, reason, cancelDate, cancelBy);
+ if (awa.isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ awa.setSoleAttributeValue(AtsAttributeTypes.CancelledBy, cancelBy.getUserId());
+ awa.setSoleAttributeValue(AtsAttributeTypes.CancelledDate, cancelDate);
+ awa.setSoleAttributeValue(AtsAttributeTypes.CancelledReason, reason);
+ awa.setSoleAttributeValue(AtsAttributeTypes.CancelledFromState, fromStateName);
+ }
+ }
+
+ public void logWorkflowUnCancelledEvent() throws OseeCoreException {
+ if (awa.isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ awa.deleteSoleAttribute(AtsAttributeTypes.CancelledBy);
+ awa.deleteSoleAttribute(AtsAttributeTypes.CancelledDate);
+ awa.deleteSoleAttribute(AtsAttributeTypes.CancelledReason);
+ awa.deleteSoleAttribute(AtsAttributeTypes.CancelledFromState);
+ }
+ }
+
+ public void logWorkflowCompletedEvent(String fromStateName, String reason, Date cancelDate, User cancelBy) throws OseeCoreException {
+ awa.getLog().addLog(LogType.StateComplete, fromStateName, Strings.isValid(reason) ? reason : "", cancelDate,
+ cancelBy);
+ if (awa.isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ awa.setSoleAttributeValue(AtsAttributeTypes.CompletedBy, cancelBy.getUserId());
+ awa.setSoleAttributeValue(AtsAttributeTypes.CompletedDate, cancelDate);
+ awa.setSoleAttributeValue(AtsAttributeTypes.CompletedFromState, fromStateName);
+ }
+ }
+
+ public void logWorkflowUnCompletedEvent() throws OseeCoreException {
+ if (awa.isAttributeTypeValid(AtsAttributeTypes.CreatedBy)) {
+ awa.deleteSoleAttribute(AtsAttributeTypes.CompletedBy);
+ awa.deleteSoleAttribute(AtsAttributeTypes.CompletedDate);
+ awa.deleteSoleAttribute(AtsAttributeTypes.CompletedFromState);
+ }
+ }
+
+ public void logStateCompletedEvent(String fromStateName, String reason, Date date, User user) throws OseeCoreException {
+ awa.getLog().addLog(LogType.StateComplete, fromStateName, Strings.isValid(reason) ? reason : "");
+ }
+
+ public void logStateStartedEvent(IWorkPage state, Date date, User user) throws OseeCoreException {
+ awa.getLog().addLog(LogType.StateEntered, state.getPageName(), "");
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionOption.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionOption.java
new file mode 100644
index 00000000000..afa03b678fa
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionOption.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.core.workflow.transition;
+
+public enum TransitionOption {
+ None,
+ Persist,
+ // Override check whether workflow allows transition to state
+ OverrideTransitionValidityCheck,
+ // Allows transition to occur with UnAssigned, OseeSystem or Guest
+ OverrideAssigneeCheck
+};

Back to the top