blob: 0f0febf6e04575fdcc01ac5a4fc376b33109b0d2 [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2016 Boeing
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Boeing - initial API and implementation
**********************************************************************/
package org.eclipse.osee.ats.rest.internal.util;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.osee.ats.api.AtsApi;
import org.eclipse.osee.ats.api.IAtsObject;
import org.eclipse.osee.ats.api.IAtsWorkItem;
import org.eclipse.osee.ats.api.user.AtsUser;
import org.eclipse.osee.ats.api.util.IExecuteListener;
import org.eclipse.osee.ats.api.workdef.IAttributeResolver;
import org.eclipse.osee.ats.api.workflow.log.IAtsLogFactory;
import org.eclipse.osee.ats.api.workflow.state.IAtsStateFactory;
import org.eclipse.osee.ats.core.util.AbstractAtsChangeSet;
import org.eclipse.osee.framework.core.data.ArtifactId;
import org.eclipse.osee.framework.core.data.ArtifactToken;
import org.eclipse.osee.framework.core.data.ArtifactTypeToken;
import org.eclipse.osee.framework.core.data.AttributeId;
import org.eclipse.osee.framework.core.data.AttributeTypeGeneric;
import org.eclipse.osee.framework.core.data.AttributeTypeId;
import org.eclipse.osee.framework.core.data.AttributeTypeToken;
import org.eclipse.osee.framework.core.data.BranchId;
import org.eclipse.osee.framework.core.data.IAttribute;
import org.eclipse.osee.framework.core.data.RelationId;
import org.eclipse.osee.framework.core.data.RelationTypeSide;
import org.eclipse.osee.framework.core.data.TransactionId;
import org.eclipse.osee.framework.core.data.TransactionToken;
import org.eclipse.osee.framework.jdk.core.type.OseeArgumentException;
import org.eclipse.osee.framework.jdk.core.type.OseeStateException;
import org.eclipse.osee.framework.jdk.core.util.Conditions;
import org.eclipse.osee.orcs.OrcsApi;
import org.eclipse.osee.orcs.data.ArtifactReadable;
import org.eclipse.osee.orcs.data.AttributeReadable;
import org.eclipse.osee.orcs.transaction.TransactionBuilder;
/**
* @author Donald G. Dunne
*/
public class AtsChangeSet extends AbstractAtsChangeSet {
private TransactionBuilder transaction;
private final OrcsApi orcsApi;
private final AtsApi atsApi;
public AtsChangeSet(AtsApi atsApi, IAttributeResolver attributeResolver, OrcsApi orcsApi, IAtsStateFactory stateFactory, IAtsLogFactory logFactory, String comment, AtsUser user, BranchId branch) {
super(comment, branch, user);
this.atsApi = atsApi;
this.orcsApi = orcsApi;
}
public TransactionBuilder getTransaction() {
if (transaction == null) {
if (branch == null) {
branch = atsApi.getAtsBranch();
}
transaction = orcsApi.getTransactionFactory().createTransaction(branch, asUser, comment);
}
return transaction;
}
@Override
public TransactionId execute() {
Conditions.checkNotNull(comment, "comment");
if (isEmpty() && execptionIfEmpty) {
throw new OseeArgumentException("objects/deleteObjects cannot be empty");
}
// 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()) {
atsApi.getStateFactory().writeToStore(asUser, workItem, this);
}
if (workItem.getLog().isDirty()) {
atsApi.getLogFactory().writeToStore(workItem, atsApi.getAttributeResolver(), this);
}
}
}
TransactionToken tx = getTransaction().commit();
for (IExecuteListener listener : listeners) {
listener.changesStored(this);
}
atsApi.getNotificationService().sendNotifications(getNotifications());
for (IAtsObject atsObject : new ArrayList<>(atsObjects)) {
if (atsObject instanceof IAtsWorkItem) {
atsApi.getStoreService().clearCaches((IAtsWorkItem) atsObject);
}
}
/*
* TODO: 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()) {
// WorkflowRuleRunner runner = new WorkflowRuleRunner(RuleEventType.CreateWorkflow, workItemsCreated, atsApi);
// runner.run();
// }
return tx;
}
@Override
public void deleteSoleAttribute(IAtsWorkItem workItem, AttributeTypeToken attributeType) {
getTransaction().deleteSoleAttribute(getArtifact(workItem), attributeType);
add(workItem);
}
@Override
public void setSoleAttributeValue(IAtsWorkItem workItem, AttributeTypeToken attributeType, String value) {
ArtifactReadable artifact = getArtifact(workItem);
setSoleAttributeValue(artifact, attributeType, value);
}
@Override
public void setSoleAttributeValue(IAtsObject atsObject, AttributeTypeToken attributeType, Object value) {
getTransaction().setSoleAttributeValue(getArtifact(atsObject), attributeType, value);
add(atsObject);
}
@Override
public void deleteAttribute(IAtsObject atsObject, AttributeTypeToken attributeType, Object value) {
getTransaction().deleteAttributesWithValue(getArtifact(atsObject), attributeType, value);
add(atsObject);
}
@Override
public <T> void setValue(IAtsWorkItem workItem, IAttribute<T> attr, AttributeTypeId attributeType, T value) {
ArtifactId artifactId = getArtifact(workItem);
getTransaction().setAttributeById(artifactId, attr, value);
add(workItem);
}
@Override
public <T> void deleteAttribute(IAtsWorkItem workItem, IAttribute<T> attr) {
getTransaction().deleteByAttributeId(getArtifact(workItem), attr);
add(workItem);
}
@Override
public boolean isAttributeTypeValid(IAtsWorkItem workItem, AttributeTypeId attributeType) {
ArtifactReadable artifact = getArtifact(workItem);
return artifact.getValidAttributeTypes().contains(attributeType);
}
@Override
public void addAttribute(IAtsObject atsObject, AttributeTypeToken attributeType, Object value) {
getTransaction().createAttribute(getArtifact(atsObject), attributeType, value);
add(atsObject);
}
@Override
public ArtifactToken createArtifact(ArtifactTypeToken artifactType, String name) {
ArtifactToken artifact = getTransaction().createArtifact(artifactType, name);
add(artifact);
return artifact;
}
@Override
public ArtifactToken createArtifact(ArtifactTypeToken artifactType, String name, Long artifactId) {
ArtifactToken artifact = getTransaction().createArtifact(artifactType, name, artifactId);
add(artifact);
return artifact;
}
@Override
public ArtifactToken createArtifact(ArtifactTypeToken artifactType, String name, Long id, String guid) {
ArtifactToken artifact = getTransaction().createArtifact(artifactType, name, id, guid);
add(artifact);
return artifact;
}
@Override
public void deleteAttributes(IAtsObject atsObject, AttributeTypeToken attributeType) {
ArtifactReadable artifact = getArtifact(atsObject);
getTransaction().deleteAttributes(artifact, attributeType);
add(atsObject);
}
@Override
public void relate(Object object1, RelationTypeSide relationSide, Object object2) {
ArtifactId artifact = getArtifact(object1);
ArtifactId artifact2 = getArtifact(object2);
if (relationSide.getSide().isSideA()) {
getTransaction().relate(artifact2, relationSide, artifact);
} else {
getTransaction().relate(artifact, relationSide, artifact2);
}
add(artifact);
add(artifact2);
}
private ArtifactReadable getArtifact(Object object) {
ArtifactReadable artifact = null;
if (object instanceof ArtifactReadable) {
artifact = (ArtifactReadable) object;
} else if (object instanceof IAtsObject) {
IAtsObject atsObject = (IAtsObject) object;
if (atsObject.getStoreObject() instanceof ArtifactReadable) {
artifact = (ArtifactReadable) atsObject.getStoreObject();
} else {
artifact = (ArtifactReadable) atsApi.getQueryService().getArtifact(atsObject.getId());
}
} else if (object instanceof ArtifactToken) {
artifact = (ArtifactReadable) atsApi.getQueryService().getArtifact(((ArtifactToken) object).getId());
}
return artifact;
}
@Override
public void unrelateAll(Object object, RelationTypeSide relationType) {
ArtifactReadable artifact = getArtifact(object);
add(artifact);
for (ArtifactReadable otherArt : artifact.getRelated(relationType)) {
if (relationType.getSide().isSideA()) {
getTransaction().unrelate(otherArt, relationType, artifact);
} else {
getTransaction().unrelate(artifact, relationType, otherArt);
}
add(otherArt);
}
}
@Override
public void setRelationsAndOrder(Object object, RelationTypeSide relationSide, Collection<? extends Object> objects) {
ArtifactReadable artifact = getArtifact(object);
List<ArtifactReadable> artifacts = new LinkedList<>();
for (Object obj : objects) {
ArtifactReadable art = getArtifact(obj);
if (art != null) {
artifacts.add(art);
}
}
getTransaction().setRelationsAndOrder(artifact, relationSide, artifacts);
artifacts.add(artifact);
}
@Override
public void setRelations(Object object, RelationTypeSide relationSide, Collection<? extends Object> objects) {
ArtifactReadable artifact = getArtifact(object);
List<ArtifactReadable> artifacts = new LinkedList<>();
for (Object obj : objects) {
ArtifactReadable art = getArtifact(obj);
if (art != null) {
artifacts.add(art);
}
}
// unrelate all objects that are not in set
for (ArtifactReadable art : artifact.getRelated(relationSide)) {
if (!artifacts.contains(art)) {
unrelate(artifact, relationSide, art);
}
}
// add all relations that do not exist
for (Object obj : objects) {
ArtifactReadable art = getArtifact(obj);
if (!artifact.areRelated(relationSide, art)) {
relate(object, relationSide, obj);
}
}
}
public void unrelate(Object object1, RelationTypeSide relationType, Object object2) {
getTransaction().unrelate(getArtifact(object1), relationType, getArtifact(object2));
add(object1);
}
@Override
public <T> void setAttribute(IAtsWorkItem workItem, AttributeId attributeId, T value) {
Conditions.checkExpressionFailOnTrue(attributeId.isInvalid(),
"Can not set attribute by id that has not be persisted. Attribute Id [%s] Work Item [%s]", attributeId,
workItem.toStringWithId());
ArtifactReadable artifact = getArtifact(workItem);
boolean found = false;
for (AttributeReadable<Object> attribute : artifact.getAttributes()) {
if (attributeId.equals(attribute)) {
getTransaction().setAttributeById(artifact, attribute, value);
found = true;
break;
}
}
if (!found) {
throw new OseeStateException("Attribute Id %d does not exist on Artifact %s", attributeId, workItem);
}
add(workItem);
}
@Override
public void deleteArtifact(ArtifactId artifact) {
getTransaction().deleteArtifact(artifact);
add(artifact);
}
@Override
public void setAttributeValues(IAtsObject atsObject, AttributeTypeToken attrType, List<Object> values) {
ArtifactReadable artifact = getArtifact(atsObject);
getTransaction().setAttributesFromValues(artifact, attrType, values);
add(artifact);
}
@Override
public void setAttributeValues(ArtifactId artifact, AttributeTypeToken attrType, List<Object> values) {
getTransaction().setAttributesFromValues(artifact, 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());
for (AttributeReadable<?> attribute : getArtifact(artifact).getAttributes()) {
if (attrId.equals(attribute)) {
getTransaction().setAttributeById(getArtifact(artifact), attribute, value);
}
}
}
@Override
public void setSoleAttributeValue(ArtifactId artifact, AttributeTypeToken attrType, Object value) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().setSoleAttributeValue(art, attrType, value);
add(art);
}
@Override
public void deleteAttribute(ArtifactId artifact, IAttribute<?> attr) {
AttributeId attribute = ((ArtifactReadable) artifact).getAttributeById(attr);
getTransaction().deleteByAttributeId(artifact, attribute);
add(artifact);
}
@Override
public void unrelate(ArtifactId artifact, RelationTypeSide relationSide, ArtifactId artifact2) {
ArtifactReadable art = getArtifact(artifact);
ArtifactReadable art2 = getArtifact(artifact2);
if (relationSide.getSide().isSideA()) {
getTransaction().unrelate(art2, relationSide, art);
} else {
getTransaction().unrelate(art, relationSide, art2);
}
add(art);
add(art2);
}
@Override
public void addAttribute(ArtifactId artifact, AttributeTypeToken attrType, Object value) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().createAttribute(artifact, attrType, value);
add(art);
}
@Override
public void setSoleAttributeFromString(ArtifactId artifact, AttributeTypeGeneric<?> attributeType, String value) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().setSoleAttributeFromString(artifact, attributeType, value);
add(art);
}
@Override
public void setSoleAttributeFromStream(ArtifactId artifact, AttributeTypeGeneric<?> attributeType, InputStream inputStream) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().setSoleAttributeFromStream(art, attributeType, inputStream);
add(art);
}
@Override
public void unrelateFromAll(RelationTypeSide relationSide, ArtifactId artifact) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().unrelateFromAll(relationSide, art);
add(art);
}
@Override
public void deleteAttributes(ArtifactId artifact, AttributeTypeToken attributeType) {
ArtifactReadable art = getArtifact(artifact);
getTransaction().deleteAttributes(art, attributeType);
add(art);
}
@Override
public void setAttributeValuesAsStrings(IAtsObject atsObject, AttributeTypeToken attributeType, List<String> values) {
List<Object> objValues = new LinkedList<>();
for (String value : values) {
if (attributeType.isString()) {
try {
objValues.add(value);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid value [%s]; must be string", value);
}
} else if (attributeType.isDate()) {
try {
Date date = new Date(Long.valueOf(value));
objValues.add(date);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid date value [%s]; must be long date", value);
}
} else if (attributeType.isDouble()) {
try {
Double double1 = Double.valueOf(value);
objValues.add(double1);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid double value [%s]", value);
}
} else if (attributeType.isInteger()) {
try {
Integer integer = Integer.valueOf(value);
objValues.add(integer);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid integer value [%s]", value);
}
} else if (attributeType.isLong()) {
try {
Long longVal = Long.valueOf(value);
objValues.add(longVal);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid long value [%s]", value);
}
} else if (attributeType.isBoolean()) {
try {
Boolean bool = Boolean.valueOf(value);
objValues.add(bool);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid boolean value [%s]", value);
}
} else if (attributeType.isEnumerated()) {
try {
objValues.add(value);
} catch (Exception ex) {
throw new OseeArgumentException(ex, "Invalid value [%s]; must be string", value);
}
} else {
throw new OseeArgumentException("Unsupported attribute value [%s] for type [%s] and artifact %s", value,
attributeType, atsObject.toStringWithId());
}
}
ArtifactReadable art = getArtifact(atsObject);
setAttributeValues(art, attributeType, objValues);
}
@Override
public void addArtifactReferencedAttribute(ArtifactId artifact, AttributeTypeToken attributeType, ArtifactId artifactRef) {
addAttribute(artifact, attributeType, artifactRef.getIdString());
}
@Override
public ArtifactToken createArtifact(ArtifactToken parent, ArtifactTypeToken artType, String name) {
ArtifactToken artifact = getTransaction().createArtifact(artType, name);
addChild(parent, artifact);
add(artifact);
return artifact;
}
@Override
public void deleteRelation(RelationId relation) {
throw new UnsupportedOperationException("Unsupported on Server");
}
@Override
public void clear() {
super.clear();
transaction = null;
}
}