| /******************************************************************************* |
| * Copyright (c) 2013 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.client.internal.store; |
| |
| import static org.eclipse.osee.framework.core.enums.RelationSorter.PREEXISTING; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import org.eclipse.osee.ats.api.IAtsObject; |
| import org.eclipse.osee.ats.api.IAtsWorkItem; |
| import org.eclipse.osee.ats.api.user.IAtsUser; |
| import org.eclipse.osee.ats.api.util.IAtsChangeSet; |
| import org.eclipse.osee.ats.api.util.IExecuteListener; |
| import org.eclipse.osee.ats.api.workflow.IAttribute; |
| import org.eclipse.osee.ats.core.client.internal.AtsClientService; |
| import org.eclipse.osee.ats.core.client.search.AtsArtifactQuery; |
| import org.eclipse.osee.ats.core.util.AbstractAtsChangeSet; |
| import org.eclipse.osee.ats.core.util.AtsRelationChange; |
| import org.eclipse.osee.ats.core.util.AtsRelationChange.RelationOperation; |
| import org.eclipse.osee.framework.core.data.ArtifactId; |
| import org.eclipse.osee.framework.core.data.ArtifactToken; |
| import org.eclipse.osee.framework.core.data.AttributeId; |
| import org.eclipse.osee.framework.core.data.AttributeTypeId; |
| import org.eclipse.osee.framework.core.data.IArtifactType; |
| import org.eclipse.osee.framework.core.data.RelationTypeSide; |
| import org.eclipse.osee.framework.core.data.TransactionId; |
| import org.eclipse.osee.framework.jdk.core.type.OseeArgumentException; |
| import org.eclipse.osee.framework.jdk.core.type.OseeCoreException; |
| import org.eclipse.osee.framework.jdk.core.type.OseeStateException; |
| import org.eclipse.osee.framework.jdk.core.util.Conditions; |
| import org.eclipse.osee.framework.jdk.core.util.Lib; |
| 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.artifact.Attribute; |
| import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction; |
| import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager; |
| |
| /** |
| * @author Donald G. Dunne |
| */ |
| public class AtsChangeSet extends AbstractAtsChangeSet { |
| |
| public AtsChangeSet(String comment) { |
| this(comment, AtsClientService.get().getUserService().getCurrentUser()); |
| } |
| |
| public AtsChangeSet(String comment, IAtsUser asUser) { |
| super(comment, asUser); |
| } |
| |
| @Override |
| public TransactionId execute() throws OseeCoreException { |
| Conditions.checkNotNull(comment, "comment"); |
| if (isEmpty() && execptionIfEmpty) { |
| throw new OseeArgumentException("objects/deleteObjects cannot be empty"); |
| } |
| TransactionId transactionRecord; |
| SkynetTransaction transaction = |
| TransactionManager.createTransaction(AtsClientService.get().getAtsBranch(), comment); |
| try { |
| // First, create or update any artifacts that changed |
| for (IAtsObject atsObject : new ArrayList<>(atsObjects)) { |
| if (atsObject instanceof IAtsWorkItem) { |
| IAtsWorkItem workItem = (IAtsWorkItem) atsObject; |
| if (workItem.getStateMgr().isDirty()) { |
| AtsClientService.get().getStateFactory().writeToStore(asUser, workItem, this); |
| } |
| if (workItem.getLog().isDirty()) { |
| AtsClientService.get().getLogFactory().writeToStore(workItem, |
| AtsClientService.get().getAttributeResolver(), this); |
| } |
| } |
| transaction.addArtifact(AtsClientService.get().getArtifact(atsObject)); |
| } |
| for (ArtifactId artifact : artifacts) { |
| if (artifact instanceof Artifact) { |
| transaction.addArtifact((Artifact) artifact); |
| } |
| } |
| // Second, add or delete any relations; this has to be done separate so all artifacts are created |
| for (AtsRelationChange rel : relations) { |
| execute(rel, transaction); |
| } |
| // Third, delete any desired objects |
| for (ArtifactId artifact : deleteArtifacts) { |
| if (artifact instanceof Artifact) { |
| ((Artifact) artifact).deleteAndPersist(transaction); |
| } |
| } |
| for (IAtsObject atsObject : deleteAtsObjects) { |
| AtsClientService.get().getArtifact(atsObject).deleteAndPersist(transaction); |
| } |
| transactionRecord = transaction.execute(); |
| } catch (Exception ex) { |
| transaction.cancel(); |
| throw OseeCoreException.wrap(ex); |
| } |
| for (IExecuteListener listener : listeners) { |
| listener.changesStored(this); |
| } |
| AtsClientService.get().sendNotifications(getNotifications()); |
| |
| /** |
| * Commented out on 0.25.0 due to performance issues; No users are using this feature. Will be re-enabled on |
| * 0.26.0 where analysis can be done and all action creation can be moved to the server. Same change in both |
| * AtsChangeSets. See action TW1864. |
| */ |
| // if (!workItemsCreated.isEmpty()) { |
| // RunRuleData runRuleData = new RunRuleData(); |
| // runRuleData.setRuleEventType(RuleEventType.CreateWorkflow); |
| // runRuleData.getWorkItemUuids().addAll(AtsObjects.toUuids(workItemsCreated)); |
| // ElapsedTime time2 = new ElapsedTime("AtsChangeSet.runWorkflowRules"); |
| // RunRuleResults results = AtsClientService.getRuleEp().runWorkflowRules(runRuleData); |
| // time2.end(); |
| // |
| // List<Artifact> changedArts = new LinkedList<>(); |
| // for (Long changedUuid : results.getChangedWorkitemUuids()) { |
| // Artifact artifact = ArtifactCache.getActive(changedUuid, AtsClientService.get().getAtsBranch()); |
| // if (artifact != null) { |
| // changedArts.add(artifact); |
| // } |
| // } |
| // if (!changedArts.isEmpty()) { |
| // ArtifactQuery.reloadArtifacts(changedArts); |
| // } |
| // } |
| return transactionRecord; |
| } |
| |
| private void execute(AtsRelationChange relChange, SkynetTransaction transaction) { |
| Conditions.checkNotNull(relChange, "relChange"); |
| Conditions.checkNotNull(relChange.getRelationSide(), "relationSide"); |
| Object obj = relChange.getObject(); |
| Artifact art = getArtifact(obj); |
| Conditions.checkNotNull(art, "artifact"); |
| Collection<Object> objects = relChange.getObjects(); |
| Conditions.checkNotNullOrEmpty(objects, "objects"); |
| Set<Artifact> arts = new HashSet<>(); |
| for (Object obj2 : objects) { |
| Artifact art2 = getArtifact(obj2); |
| Conditions.checkNotNull(art2, "toArtifact"); |
| arts.add(art2); |
| } |
| for (Artifact artifact : arts) { |
| List<Artifact> relatedArtifacts = art.getRelatedArtifacts(relChange.getRelationSide()); |
| if (relChange.getOperation() == RelationOperation.Add && !relatedArtifacts.contains(artifact)) { |
| art.addRelation(relChange.getRelationSide(), artifact); |
| } else if (relChange.getOperation() == RelationOperation.Delete && relatedArtifacts.contains(artifact)) { |
| art.deleteRelation(relChange.getRelationSide(), artifact); |
| } |
| } |
| art.persist(transaction); |
| } |
| |
| private Artifact getArtifact(Object obj) { |
| Artifact art = null; |
| if (obj instanceof Artifact) { |
| art = (Artifact) obj; |
| } else if (obj instanceof IAtsObject) { |
| IAtsObject atsObject = (IAtsObject) obj; |
| Object storeObject = atsObject.getStoreObject(); |
| if (storeObject != null) { |
| art = getArtifact(storeObject); |
| } |
| if (art == null) { |
| art = AtsArtifactQuery.getArtifactFromId(atsObject.getId()); |
| } |
| } |
| return art; |
| } |
| |
| public static TransactionId execute(String comment, Object object, Object... objects) throws OseeCoreException { |
| IAtsChangeSet changes = AtsClientService.get().createChangeSet(comment); |
| changes.add(object); |
| for (Object obj : objects) { |
| changes.add(obj); |
| } |
| return changes.execute(); |
| } |
| |
| @Override |
| public void deleteSoleAttribute(IAtsWorkItem workItem, AttributeTypeId attributeType) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(workItem); |
| artifact.deleteSoleAttribute(attributeType); |
| add(artifact); |
| } |
| |
| @Override |
| public void setSoleAttributeValue(IAtsWorkItem workItem, AttributeTypeId attributeType, String value) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(workItem); |
| artifact.setSoleAttributeValue(attributeType, value); |
| add(artifact); |
| } |
| |
| @Override |
| public void setSoleAttributeValue(IAtsObject atsObject, AttributeTypeId attributeType, Object value) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(atsObject); |
| artifact.setSoleAttributeValue(attributeType, value); |
| add(artifact); |
| } |
| |
| @Override |
| public void addAttribute(IAtsObject atsObject, AttributeTypeId attributeType, Object value) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(atsObject); |
| artifact.addAttribute(attributeType, value); |
| add(artifact); |
| } |
| |
| @Override |
| public void deleteAttribute(IAtsObject atsObject, AttributeTypeId attributeType, Object value) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(atsObject); |
| artifact.deleteAttribute(attributeType, value); |
| add(artifact); |
| } |
| |
| @Override |
| public <T> void setValue(IAtsWorkItem workItem, IAttribute<String> attr, AttributeTypeId attributeType, T value) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(workItem); |
| @SuppressWarnings("unchecked") |
| Attribute<T> attribute = (Attribute<T>) attr.getData(); |
| attribute.setValue(value); |
| add(artifact); |
| } |
| |
| @Override |
| public <T> void deleteAttribute(IAtsWorkItem workItem, IAttribute<T> attr) throws OseeCoreException { |
| Artifact artifact = AtsClientService.get().getArtifact(workItem); |
| Attribute<?> attribute = (Attribute<?>) attr.getData(); |
| attribute.delete(); |
| add(artifact); |
| } |
| |
| @Override |
| public boolean isAttributeTypeValid(IAtsWorkItem workItem, AttributeTypeId attributeType) { |
| Artifact artifact = AtsClientService.get().getArtifact(workItem); |
| return artifact.getAttributeTypes().contains(attributeType); |
| } |
| |
| @Override |
| public ArtifactId createArtifact(IArtifactType artifactType, String name) { |
| Artifact artifact = ArtifactTypeManager.addArtifact(artifactType, AtsClientService.get().getAtsBranch(), name); |
| add(artifact); |
| return artifact; |
| } |
| |
| @Override |
| public void deleteAttributes(IAtsObject atsObject, AttributeTypeId attributeType) { |
| Artifact artifact = AtsClientService.get().getArtifact(atsObject); |
| artifact.deleteAttributes(attributeType); |
| add(artifact); |
| } |
| |
| @Override |
| public ArtifactToken createArtifact(IArtifactType artifactType, String name, String guid) { |
| return createArtifact(artifactType, name, guid, Lib.generateArtifactIdAsInt()); |
| } |
| |
| @Override |
| public ArtifactToken createArtifact(IArtifactType artifactType, String name, String guid, Long uuid) { |
| Artifact artifact = |
| ArtifactTypeManager.addArtifact(artifactType, AtsClientService.get().getAtsBranch(), name, guid, uuid); |
| add(artifact); |
| return artifact; |
| } |
| |
| @Override |
| public void relate(Object object1, RelationTypeSide relationSide, Object object2) { |
| Artifact artifact = getArtifact(object1); |
| Artifact artifact2 = getArtifact(object2); |
| artifact.addRelation(relationSide, artifact2); |
| add(artifact); |
| add(artifact2); |
| } |
| |
| @Override |
| public void unrelateAll(Object object, RelationTypeSide relationType) { |
| Artifact artifact = getArtifact(object); |
| artifact.deleteRelations(relationType); |
| add(artifact); |
| } |
| |
| @Override |
| public void setRelations(Object object, RelationTypeSide relationSide, Collection<? extends Object> objects) { |
| Artifact artifact = getArtifact(object); |
| Set<Artifact> artifacts = new HashSet<>(objects.size()); |
| for (Object obj : objects) { |
| Artifact art = getArtifact(obj); |
| if (art != null) { |
| artifacts.add(art); |
| add(art); |
| } |
| } |
| artifact.setRelations(PREEXISTING, relationSide, artifacts); |
| add(artifact); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> void setAttribute(IAtsWorkItem workItem, int attributeId, T value) { |
| Conditions.checkExpressionFailOnTrue(attributeId <= 0, |
| "Can not set attribute by id that has not be persisted. Atrribute Id [%s] Work Item [%s]", attributeId, |
| workItem.toStringWithId()); |
| Artifact artifact = getArtifact(workItem); |
| Conditions.checkNotNull(artifact, "artifact"); |
| boolean found = false; |
| for (Attribute<?> attribute : artifact.getAttributes()) { |
| if (attribute.getId() == attributeId) { |
| ((Attribute<T>) attribute).setValue(value); |
| found = true; |
| break; |
| } |
| } |
| if (!found) { |
| throw new OseeStateException("Attribute Id %d does not exist on Artifact %s", attributeId, workItem); |
| } |
| add(artifact); |
| } |
| |
| @Override |
| public void deleteArtifact(ArtifactId artifact) { |
| Artifact art = getArtifact(artifact); |
| art.delete(); |
| add(art); |
| } |
| |
| @Override |
| public void setAttributeValues(IAtsObject atsObject, AttributeTypeId attrType, List<Object> values) { |
| Artifact artifact = getArtifact(atsObject); |
| artifact.setAttributeFromValues(attrType, values); |
| add(artifact); |
| } |
| |
| @Override |
| public <T> void setAttribute(ArtifactId artifact, AttributeId attrId, T value) { |
| Conditions.checkExpressionFailOnTrue(attrId.isInvalid(), |
| "Can not set attribute by id that has not been persisted. Atrribute Id [%s] ArtifactId [%s]", attrId, |
| artifact.toString()); |
| boolean found = false; |
| for (Attribute<?> attribute : getArtifact(artifact).getAttributes()) { |
| if (attrId.equals(attribute)) { |
| attribute.setFromString(String.valueOf(value)); |
| found = true; |
| break; |
| } |
| } |
| if (!found) { |
| throw new OseeStateException("Attribute Id %d does not exist on Artifact %s", attrId, artifact); |
| } |
| add(artifact); |
| } |
| |
| @Override |
| public void deleteAttribute(ArtifactId userArt, IAttribute<?> attr) { |
| Artifact artifact = getArtifact(userArt); |
| artifact.deleteAttribute(attr); |
| add(artifact); |
| } |
| |
| @Override |
| public void setSoleAttributeValue(ArtifactId artifact, AttributeTypeId attrType, Object value) { |
| Artifact art = getArtifact(artifact); |
| art.setSoleAttributeValue(attrType, value); |
| add(artifact); |
| } |
| |
| @Override |
| public void unrelate(ArtifactId artifact, RelationTypeSide relationSide, ArtifactId artifact2) { |
| Artifact art = getArtifact(artifact); |
| Artifact art2 = getArtifact(artifact2); |
| art.deleteRelation(relationSide, art2); |
| add(art); |
| add(art2); |
| } |
| |
| @Override |
| public void addAttribute(ArtifactId artifact, AttributeTypeId attrType, Object value) { |
| Artifact art = getArtifact(artifact); |
| art.addAttribute(attrType, value); |
| add(art); |
| } |
| |
| @Override |
| public void setSoleAttributeFromString(ArtifactId artifact, AttributeTypeId attrType, String value) { |
| Artifact art = getArtifact(artifact); |
| art.setSoleAttributeFromString(attrType, value); |
| add(art); |
| } |
| |
| @Override |
| public void setSoleAttributeFromStream(ArtifactId artifact, AttributeTypeId attributeType, InputStream inputStream) { |
| Artifact art = getArtifact(artifact); |
| art.setSoleAttributeFromStream(attributeType, inputStream); |
| add(art); |
| } |
| |
| @Override |
| public void unrelateFromAll(RelationTypeSide relationSide, ArtifactId artifact) { |
| Artifact art = getArtifact(artifact); |
| art.deleteRelations(relationSide); |
| } |
| |
| @Override |
| public void addArtifactReferencedAttribute(ArtifactId artifact, AttributeTypeId attributeType, ArtifactId artifactRef) { |
| Artifact art = getArtifact(artifact); |
| art.addAttributeFromString(attributeType, artifactRef.getId().toString()); |
| } |
| |
| } |