Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordonald.g.dunne2016-10-07 15:07:59 -0400
committerDonald Dunne2016-10-11 20:55:57 -0400
commit17ad6692663d22337f4b1fbcb4c89aa763f70ef0 (patch)
tree5f18daa74d33cf6fe4635c1a88b197eeb7d0bdd0
parent031796ae3a21f954e7428903cca305aae7cc0e9c (diff)
downloadorg.eclipse.osee-17ad6692663d22337f4b1fbcb4c89aa763f70ef0.tar.gz
org.eclipse.osee-17ad6692663d22337f4b1fbcb4c89aa763f70ef0.tar.xz
org.eclipse.osee-17ad6692663d22337f4b1fbcb4c89aa763f70ef0.zip
bug[ats_ATS318913]: ATS Workflows have duplicate attributes
-rw-r--r--plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionByIdAction.java154
-rw-r--r--plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionsAction.java124
-rw-r--r--plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/AtsNavigateViewItems.java4
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/AttributeRow.java74
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/RelationRow.java91
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/transaction/TransactionManager.java185
6 files changed, 632 insertions, 0 deletions
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionByIdAction.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionByIdAction.java
new file mode 100644
index 0000000000..aee02c2796
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionByIdAction.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.actions;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osee.ats.AtsImage;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.internal.Activator;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.data.TransactionId;
+import org.eclipse.osee.framework.core.operation.AbstractOperation;
+import org.eclipse.osee.framework.core.operation.Operations;
+import org.eclipse.osee.framework.core.util.XResultData;
+import org.eclipse.osee.framework.jdk.core.util.Conditions;
+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.artifact.Attribute;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
+import org.eclipse.osee.framework.ui.plugin.util.AWorkbench;
+import org.eclipse.osee.framework.ui.skynet.results.XResultDataUI;
+import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryCheckDialog;
+import org.eclipse.osee.framework.ui.swt.ImageManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class RevertDuplicateTransitionByIdAction extends Action {
+
+ public RevertDuplicateTransitionByIdAction() {
+ this("Revert Duplicate Transition by ID");
+ }
+
+ public RevertDuplicateTransitionByIdAction(String name) {
+ super(name);
+ setToolTipText(getText());
+ }
+
+ @Override
+ public void run() {
+ final String title = getText();
+ EntryCheckDialog dialog = new EntryCheckDialog(title, "Enter ATS Ids", "Persist");
+ if (dialog.open() == 0) {
+
+ final boolean persist = dialog.isChecked();
+ AbstractOperation operation =
+ new org.eclipse.osee.framework.core.operation.AbstractOperation(title, Activator.PLUGIN_ID) {
+
+ @Override
+ protected void doWork(IProgressMonitor monitor) throws Exception {
+ List<String> atsIds = new LinkedList<>();
+ List<Integer> artIds = new LinkedList<>();
+ for (String id : dialog.getEntry().split(",")) {
+ id = id.replaceAll(" ", "");
+ if (Strings.isNumeric(id)) {
+ artIds.add(Integer.valueOf(id));
+ } else {
+ atsIds.add(id);
+ }
+ }
+ XResultData results = new XResultData();
+ SkynetTransaction trans = TransactionManager.createTransaction(AtsUtilCore.getAtsBranch(), getName());
+
+ boolean changed = false;
+ for (Artifact art : ArtifactQuery.getArtifactListFromIds(artIds, AtsUtilCore.getAtsBranch())) {
+ results.logf("\n\nReverting transition for %s\n\n", art.toStringWithId());
+ if (revertTransition(art, results, persist, trans)) {
+ changed = true;
+ } else {
+ results.log("Nothing to change.");
+ }
+ }
+
+ if (!atsIds.isEmpty()) {
+ for (Artifact art : ArtifactQuery.getArtifactListFromAttributeValues(AtsAttributeTypes.AtsId,
+ atsIds, AtsUtilCore.getAtsBranch(), 50)) {
+ results.logf("\n\nReverting transition for %s\n\n", art.toStringWithId());
+ if (revertTransition(art, results, persist, trans)) {
+ changed = true;
+ } else {
+ results.log("Nothing to change");
+ }
+ }
+ }
+
+ if (persist && !results.isErrors() && changed) {
+ trans.execute();
+ }
+ if (!changed) {
+ results.error("Nothing changed");
+ }
+ XResultDataUI.report(results, getName());
+ if (results.isErrors()) {
+ AWorkbench.popup(
+ "Errors found, search Error in results. Restart before re-running if you persisted");
+ }
+ }
+ };
+ Operations.executeAsJob(operation, true);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ protected static boolean revertTransition(Artifact art, XResultData results, boolean persist, SkynetTransaction persistTransaction) {
+ List<Attribute<Object>> attributes = null;
+ for (IAttributeType attrType : Arrays.asList(AtsAttributeTypes.CompletedDate, AtsAttributeTypes.CancelledDate)) {
+ attributes = art.getAttributes(attrType);
+ if (attributes.size() > 1) {
+ break;
+ }
+ }
+ if (attributes.isEmpty()) {
+ results.errorf("Unable to find duplicate completed/cancelled dates for artifact %s", art.toStringWithId());
+ return false;
+ }
+ TransactionId earlyTrans, lateTrans, trans1 = null, trans2 = null;
+ for (Attribute<Object> attr : attributes) {
+ TransactionId transId = TransactionManager.getTransaction(art.getBranch(), attr);
+ if (trans1 == null) {
+ trans1 = transId;
+ } else {
+ trans2 = transId;
+ }
+ }
+ earlyTrans = trans1.getId() < trans2.getId() ? trans1 : trans2;
+ lateTrans = trans2.getId() < trans1.getId() ? trans1 : trans2;
+ Conditions.assertNotNull(earlyTrans, "Can not find early transaction");
+ Conditions.assertNotNull(lateTrans, "Can not find late transaction");
+
+ return TransactionManager.revertArtifactFromTransaction(art, lateTrans, results, persist, persistTransaction);
+
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return ImageManager.getImageDescriptor(AtsImage.TASK);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionsAction.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionsAction.java
new file mode 100644
index 0000000000..051ed04588
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/RevertDuplicateTransitionsAction.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.actions;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osee.ats.AtsImage;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.internal.Activator;
+import org.eclipse.osee.ats.internal.AtsClientService;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.operation.AbstractOperation;
+import org.eclipse.osee.framework.core.operation.Operations;
+import org.eclipse.osee.framework.core.util.XResultData;
+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.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
+import org.eclipse.osee.framework.ui.plugin.util.AWorkbench;
+import org.eclipse.osee.framework.ui.skynet.results.XResultDataUI;
+import org.eclipse.osee.framework.ui.skynet.widgets.dialog.CheckBoxDialog;
+import org.eclipse.osee.framework.ui.swt.ImageManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class RevertDuplicateTransitionsAction extends Action {
+
+ public RevertDuplicateTransitionsAction() {
+ this("Revert Duplicate Transitions");
+ }
+
+ public RevertDuplicateTransitionsAction(String name) {
+ super(name);
+ setToolTipText(getText());
+ }
+
+ @Override
+ public void run() {
+ final String title = getText();
+ CheckBoxDialog dialog = new CheckBoxDialog(title, "Fix all duplicate transitions?", "Persist");
+ if (dialog.open() == 0) {
+
+ final boolean persist = dialog.isChecked();
+ AbstractOperation operation =
+ new org.eclipse.osee.framework.core.operation.AbstractOperation(title, Activator.PLUGIN_ID) {
+
+ @Override
+ protected void doWork(IProgressMonitor monitor) throws Exception {
+ List<Integer> artIds = getArtIdsWithDuplicateTransitions();
+ XResultData results = new XResultData();
+ SkynetTransaction trans = TransactionManager.createTransaction(AtsUtilCore.getAtsBranch(), getName());
+
+ boolean changed = false;
+ for (Artifact art : ArtifactQuery.getArtifactListFromIds(artIds, AtsUtilCore.getAtsBranch())) {
+ results.logf("\n\nReverting transition for %s\n\n", art.toStringWithId());
+ if (RevertDuplicateTransitionByIdAction.revertTransition(art, results, persist, trans)) {
+ changed = true;
+ } else {
+ results.log("Nothing to change.");
+ }
+ }
+ if (persist && !results.isErrors() && changed) {
+ trans.execute();
+ }
+ if (!changed) {
+ results.error("Nothing changed");
+ }
+ XResultDataUI.report(results, getName());
+ if (results.isErrors()) {
+ AWorkbench.popup(
+ "Errors found, search Error in results. Restart before re-running if you persisted");
+ }
+ }
+ };
+ Operations.executeAsJob(operation, true);
+ }
+ }
+
+ protected List<Integer> getArtIdsWithDuplicateTransitions() {
+ List<Integer> artIds = new LinkedList<>();
+ for (IAttributeType attrType : Arrays.asList(AtsAttributeTypes.CompletedDate, AtsAttributeTypes.CancelledDate)) {
+ for (IAtsWorkItem workItem : AtsClientService.get().getQueryService().runQuery(DUPLICATE_TRANSITION_QUERY,
+ AtsUtilCore.getAtsBranch().getId(), attrType.getId())) {
+ artIds.add(workItem.getUuid().intValue());
+ }
+ }
+ return artIds;
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return ImageManager.getImageDescriptor(AtsImage.TASK);
+ }
+
+ private static String DUPLICATE_TRANSITION_QUERY = //
+ "select art_id, transaction_id " + //
+ "from " + //
+ " (SELECT" + //
+ " art.art_id, attr.attr_id, attr.value, attr.gamma_id, txs.tx_current, " + //
+ " txs.transaction_id, count(distinct attr.attr_id) over (partition by art.art_id) attr_id_cnt" + //
+ " FROM" + //
+ " osee_artifact art, osee_attribute attr, osee_txs txs" + //
+ " WHERE" + //
+ " txs.branch_id = ? and txs.gamma_id = attr.gamma_id and art.art_id = " + //
+ " attr.art_id and attr.attr_type_id = ? and " + //
+ " txs.tx_current = 1) t1 " + //
+ "where t1.attr_id_cnt > 1";
+
+}
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/AtsNavigateViewItems.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/AtsNavigateViewItems.java
index 79fa6b45ef..a4c1f28dab 100644
--- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/AtsNavigateViewItems.java
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/AtsNavigateViewItems.java
@@ -28,6 +28,8 @@ import org.eclipse.osee.ats.actions.NewAction;
import org.eclipse.osee.ats.actions.NewGoal;
import org.eclipse.osee.ats.actions.OpenArtifactEditorById;
import org.eclipse.osee.ats.actions.OpenOrphanedTasks;
+import org.eclipse.osee.ats.actions.RevertDuplicateTransitionByIdAction;
+import org.eclipse.osee.ats.actions.RevertDuplicateTransitionsAction;
import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
import org.eclipse.osee.ats.api.query.AtsSearchData;
import org.eclipse.osee.ats.api.user.IAtsUser;
@@ -226,6 +228,8 @@ public final class AtsNavigateViewItems implements XNavigateViewItems, IXNavigat
new ValidateWorkspaceToDatabaseWorkDefinitions(healthItems);
new CleanupOseeSystemAssignedWorkflows(healthItems);
new XNavigateItemAction(adminItems, new OpenOrphanedTasks(), AtsImage.TASK);
+ new XNavigateItemAction(adminItems, new RevertDuplicateTransitionByIdAction(), AtsImage.TASK);
+ new XNavigateItemAction(adminItems, new RevertDuplicateTransitionsAction(), AtsImage.TASK);
XNavigateItem extra = new XNavigateItemFolder(adminItems, "Other");
Set<XNavigateExtensionPointData> extraItems =
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/AttributeRow.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/AttributeRow.java
new file mode 100644
index 0000000000..d1dad85b32
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/AttributeRow.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.framework.skynet.core.attribute;
+
+import org.eclipse.osee.framework.core.data.BranchId;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.enums.ModificationType;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class AttributeRow {
+
+ private final BranchId branch;
+ private final Long gammaId;
+ private final Integer artId;
+ private final ModificationType modType;
+ private final String value;
+ private final Integer attrId;
+ private final IAttributeType attributeType;
+
+ public AttributeRow(BranchId branch, Long gammaId, Integer artId, ModificationType modType, String value, Integer attrId, IAttributeType attributeType) {
+ this.branch = branch;
+ this.gammaId = gammaId;
+ this.artId = artId;
+ this.modType = modType;
+ this.value = value;
+ this.attrId = attrId;
+ this.attributeType = attributeType;
+ }
+
+ public BranchId getBranch() {
+ return branch;
+ }
+
+ public Long getGammaId() {
+ return gammaId;
+ }
+
+ public Integer getArtId() {
+ return artId;
+ }
+
+ public ModificationType getModType() {
+ return modType;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public Integer getAttrId() {
+ return attrId;
+ }
+
+ public IAttributeType getAttributeType() {
+ return attributeType;
+ }
+
+ @Override
+ public String toString() {
+ return "Attribute [attrId=" + attrId + ", type=" + attributeType + ", gammaId=" + gammaId + ", artId=" + artId + ", modType=" + modType + ", value=" + value + "]";
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/RelationRow.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/RelationRow.java
new file mode 100644
index 0000000000..f4350e72eb
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/attribute/RelationRow.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.framework.skynet.core.attribute;
+
+import org.eclipse.osee.framework.core.data.BranchId;
+import org.eclipse.osee.framework.core.data.IRelationType;
+
+/**
+ * @author Donald G. Dunne
+ */
+public final class RelationRow {
+
+ private final BranchId branch;
+ private Long rel_id;
+ private IRelationType relationType;
+ private Long a_art_id, b_art_id;
+ private String rationale;
+ private Long gamma_id;
+
+ public RelationRow(BranchId branch, Long rel_id, IRelationType relationType, Long a_art_id, Long b_art_id, String rationale, Long gamma_id) {
+ super();
+ this.branch = branch;
+ this.rel_id = rel_id;
+ this.relationType = relationType;
+ this.a_art_id = a_art_id;
+ this.b_art_id = b_art_id;
+ this.rationale = rationale;
+ this.gamma_id = gamma_id;
+ }
+
+ public Long getA_art_id() {
+ return a_art_id;
+ }
+
+ public void setA_art_id(Long a_art_id) {
+ this.a_art_id = a_art_id;
+ }
+
+ public Long getB_art_id() {
+ return b_art_id;
+ }
+
+ public void setB_art_id(Long b_art_id) {
+ this.b_art_id = b_art_id;
+ }
+
+ public String getRationale() {
+ return rationale;
+ }
+
+ public void setRationale(String rationale) {
+ this.rationale = rationale;
+ }
+
+ public Long getGamma_id() {
+ return gamma_id;
+ }
+
+ public void setGamma_id(Long gamma_id) {
+ this.gamma_id = gamma_id;
+ }
+
+ public BranchId getBranch() {
+ return branch;
+ }
+
+ public Long getRel_id() {
+ return rel_id;
+ }
+
+ public void setRel_id(Long rel_id) {
+ this.rel_id = rel_id;
+ }
+
+ public IRelationType getRelationType() {
+ return relationType;
+ }
+
+ public void setRelationType(IRelationType relationType) {
+ this.relationType = relationType;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/transaction/TransactionManager.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/transaction/TransactionManager.java
index fcd8acc84f..db0db64eb5 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/transaction/TransactionManager.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/transaction/TransactionManager.java
@@ -21,15 +21,29 @@ import java.util.List;
import java.util.Set;
import org.eclipse.osee.framework.core.data.ArtifactId;
import org.eclipse.osee.framework.core.data.BranchId;
+import org.eclipse.osee.framework.core.data.IAttributeType;
+import org.eclipse.osee.framework.core.data.IRelationType;
import org.eclipse.osee.framework.core.data.TokenFactory;
import org.eclipse.osee.framework.core.data.TransactionId;
import org.eclipse.osee.framework.core.data.TransactionToken;
+import org.eclipse.osee.framework.core.enums.DeletionFlag;
+import org.eclipse.osee.framework.core.enums.ModificationType;
import org.eclipse.osee.framework.core.enums.TransactionDetailsType;
import org.eclipse.osee.framework.core.exception.TransactionDoesNotExist;
import org.eclipse.osee.framework.core.model.TransactionRecord;
+import org.eclipse.osee.framework.core.model.type.AttributeType;
+import org.eclipse.osee.framework.core.util.XResultData;
import org.eclipse.osee.framework.jdk.core.type.HashCollection;
import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.AHTML;
import org.eclipse.osee.framework.jdk.core.util.Conditions;
+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.artifact.search.ArtifactQuery;
+import org.eclipse.osee.framework.skynet.core.attribute.AttributeRow;
+import org.eclipse.osee.framework.skynet.core.attribute.AttributeTypeManager;
+import org.eclipse.osee.framework.skynet.core.attribute.RelationRow;
+import org.eclipse.osee.framework.skynet.core.relation.RelationTypeManager;
import org.eclipse.osee.framework.skynet.core.types.IArtifact;
import org.eclipse.osee.framework.skynet.core.utility.ConnectionHandler;
import org.eclipse.osee.jdbc.JdbcClient;
@@ -71,6 +85,18 @@ public final class TransactionManager {
private static final String TX_GET_TRANSACTION_BY_ID = "SELECT * FROM osee_tx_details WHERE transaction_id = ?";
+ private static final String TX_GET_TRANSACTION_FROM_ATTR_ID =
+ "select transaction_id from osee_attribute attr, osee_txs txs where txs.branch_id = ? and attr.gamma_id = ? and attr.gamma_id = txs.gamma_id";
+
+ private static final String SELECT_ATTRIBUTES_FROM_ART_IN_TRANS_ID =
+ "select * from osee_attribute attr, osee_txs txs where txs.branch_id = ? and attr.ART_ID = ? and txs.TRANSACTION_ID = ? and attr.gamma_id = txs.GAMMA_ID";
+
+ private static final String SELECT_RELATIONS_FROM_ART_IN_TRANS_ID =
+ "select * from osee_relation_link rel, osee_txs txs where txs.branch_id = ? and (rel.a_art_id = ? or rel.b_art_id = ?) and txs.TRANSACTION_ID = ? and rel.gamma_id = txs.GAMMA_ID";
+
+ private static final String SELECT_ART_TRANSACTION_IDS =
+ "select distinct txs.transaction_id from osee_attribute attr, osee_txs txs where txs.branch_id = ? and art_id = ? and attr.GAMMA_ID = txs.gamma_id order by txs.transaction_id desc";
+
private static final TxMonitorImpl<BranchId> txMonitor = new TxMonitorImpl<>(new TxMonitorCache<>());
private static final HashCollection<ArtifactId, TransactionRecord> commitArtifactIdMap =
new HashCollection<>(true, HashSet.class);
@@ -225,4 +251,163 @@ public final class TransactionManager {
}
return transactions;
}
+
+ public static TransactionId getTransaction(BranchId branch, Attribute<Object> attr) {
+ JdbcClient jdbcClient = ConnectionHandler.getJdbcClient();
+ return jdbcClient.fetchOrException(
+ () -> new TransactionDoesNotExist("A transaction from attr gamma id %d was not found.", attr.getGammaId()),
+ stmt -> TransactionId.valueOf(stmt.getLong("transaction_id")), TX_GET_TRANSACTION_FROM_ATTR_ID, branch.getId(),
+ attr.getGammaId());
+ }
+
+ /**
+ * This method will attempt to revert the changes made to the given artifact in the revertTransaction. It does not
+ * handle ARTIFACT_DELETED or relations and only handles NEW and MODIFIED ModTypes. Those cases should be added as
+ * needed.
+ *
+ * @param results - contains the changes that need to be made (if persist == false) or changes that were made (if
+ * persist == true)
+ * @param persist - if true, changes will be made to attributes and artifact and added to persistTransaction
+ * @return true if changes were found
+ */
+ public static boolean revertArtifactFromTransaction(Artifact art, TransactionId revertTransaction, XResultData results, boolean persist, SkynetTransaction persistTransaction) {
+ List<AttributeRow> attributesFromArtifactAndTransaction =
+ getAttributesFromArtifactAndTransaction(art, revertTransaction);
+ for (AttributeRow attr : attributesFromArtifactAndTransaction) {
+ if (attr.getModType() == ModificationType.ARTIFACT_DELETED) {
+ throw new UnsupportedOperationException(
+ "Revert of Artifact Deleted is not supported (but could be added as needed)");
+ }
+ }
+
+ List<RelationRow> relations = getRelationsFromArtifactAndTransaction(art, revertTransaction);
+ if (!relations.isEmpty()) {
+ throw new UnsupportedOperationException(
+ "Revert of Relations Modified is not supported (but could be added as needed)");
+ }
+
+ TransactionId prevTransId = getPreviousTransactionId(art, revertTransaction);
+ Artifact prevArt = ArtifactQuery.getHistoricalArtifactFromId(art.getId().intValue(),
+ TransactionToken.valueOf(prevTransId, art.getBranch()), DeletionFlag.EXCLUDE_DELETED);
+
+ boolean changed = false;
+ for (AttributeRow attr : attributesFromArtifactAndTransaction) {
+ AttributeType type = AttributeTypeManager.getType(attr.getAttributeType());
+ if (attr.getModType() == ModificationType.NEW) {
+ changed = true;
+ if (persist) {
+ art.deleteAttribute(attr.getAttrId());
+ }
+ results.logf("Deleting created attribute type [%s]\n", type);
+ } else if (attr.getModType() == ModificationType.MODIFIED) {
+ if (type.getMaxOccurrences() == 1) {
+ Object curValue = art.getSoleAttributeValue(type, null);
+ Object prevValue = getPreviousValue(prevArt, attr.getAttrId());
+ changed = true;
+ if (persist) {
+ art.setSoleAttributeValue(type, prevValue);
+ }
+ String currValueAsText = curValue.toString();
+ currValueAsText = AHTML.textToHtml(currValueAsText);
+ String prevValueAsText = prevValue.toString();
+ prevValueAsText = AHTML.textToHtml(prevValueAsText);
+ results.logf("Setting modified type [%s] from [%s] to [%s]\n", type, currValueAsText, prevValueAsText);
+ } else {
+ results.errorf("Max Occurrences > 1 not supported for attribute %s (but could be added as needed)\n",
+ attr);
+ }
+ } else {
+ results.errorf("Mod Type %s not supported for attribute %s (but could be added as needed)\n",
+ attr.getModType(), attr);
+ }
+ }
+ if (persist && changed) {
+ art.persist(persistTransaction);
+ }
+ return changed;
+ }
+
+ private static Object getPreviousValue(Artifact prevArt, Integer attrId) {
+ for (Attribute<?> attr : prevArt.getAttributes()) {
+ if (attrId.equals(attr.getId())) {
+ return attr.getValue();
+ }
+ }
+ return null;
+ }
+
+ public static TransactionId getPreviousTransactionId(Artifact art, TransactionId trans) {
+ boolean found = false;
+ JdbcStatement chStmt = ConnectionHandler.getStatement();
+ try {
+ chStmt.runPreparedQuery(SELECT_ART_TRANSACTION_IDS, art.getBranch().getId(), art.getArtId());
+ while (chStmt.next()) {
+ Integer transId = chStmt.getInt("transaction_id");
+ if (transId.equals(trans.getId().intValue())) {
+ found = true;
+ }
+ if (found && !transId.equals(trans.getId().intValue())) {
+ return TransactionId.valueOf(transId);
+ }
+ }
+ } finally {
+ chStmt.close();
+ }
+ return null;
+ }
+
+ public static List<RelationRow> getRelationsFromArtifactAndTransaction(Artifact art, TransactionId trans) {
+ List<RelationRow> relationChanges = new LinkedList<RelationRow>();
+ JdbcStatement chStmt = ConnectionHandler.getStatement();
+ try {
+ chStmt.runPreparedQuery(SELECT_RELATIONS_FROM_ART_IN_TRANS_ID, art.getBranch().getId(), art.getArtId(),
+ art.getArtId(), trans.getId());
+ while (chStmt.next()) {
+ relationChanges.add(loadRelationChange(chStmt));
+ }
+ } finally {
+ chStmt.close();
+ }
+ return relationChanges;
+
+ }
+
+ public static List<AttributeRow> getAttributesFromArtifactAndTransaction(Artifact art, TransactionId trans) {
+ List<AttributeRow> attributeChanges = new LinkedList<AttributeRow>();
+ JdbcStatement chStmt = ConnectionHandler.getStatement();
+ try {
+ chStmt.runPreparedQuery(SELECT_ATTRIBUTES_FROM_ART_IN_TRANS_ID, art.getBranch().getId(), art.getArtId(),
+ trans.getId());
+ while (chStmt.next()) {
+ attributeChanges.add(loadAttributeChange(chStmt));
+ }
+ } finally {
+ chStmt.close();
+ }
+ return attributeChanges;
+
+ }
+
+ private static RelationRow loadRelationChange(JdbcStatement chStmt) {
+ IRelationType relationType = RelationTypeManager.getTypeByGuid(chStmt.getLong("rel_link_type_id"));
+ BranchId branch = BranchId.valueOf(chStmt.getLong("branch_id"));
+ Long gammaId = Long.valueOf(chStmt.getLong("gamma_id"));
+ Long aArtId = Long.valueOf(chStmt.getInt("a_art_id"));
+ Long bArtId = Long.valueOf(chStmt.getInt("b_art_id"));
+ Long relId = Long.valueOf(chStmt.getInt("rel_link_id"));
+ String rationale = chStmt.getString("rationale");
+ return new RelationRow(branch, relId, relationType, aArtId, bArtId, rationale, gammaId);
+ }
+
+ private static AttributeRow loadAttributeChange(JdbcStatement chStmt) {
+ IAttributeType attributeType = AttributeTypeManager.getTypeByGuid(chStmt.getLong("attr_type_id"));
+ BranchId branch = BranchId.valueOf(chStmt.getLong("branch_id"));
+ Long gammaId = Long.valueOf(chStmt.getLong("gamma_id"));
+ Integer artId = Integer.valueOf(chStmt.getInt("art_id"));
+ ModificationType modType = ModificationType.getMod(chStmt.getInt("mod_type"));
+ Integer attrId = Integer.valueOf(chStmt.getInt("attr_id"));
+ String value = chStmt.getString("value");
+ return new AttributeRow(branch, gammaId, artId, modType, value, attrId, attributeType);
+ }
+
} \ No newline at end of file

Back to the top