blob: 27061b1eb46829f6d8980e31607f68c6b423723f [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2019 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.define.rest.importing.operations;
import static org.eclipse.osee.framework.core.enums.RelationSorter.USER_DEFINED;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.define.api.importing.IArtifactExtractor;
import org.eclipse.define.api.importing.RoughArtifact;
import org.eclipse.define.api.importing.RoughArtifactCollector;
import org.eclipse.define.api.importing.RoughRelation;
import org.eclipse.osee.define.rest.importing.resolvers.IArtifactImportResolver;
import org.eclipse.osee.framework.core.data.ArtifactId;
import org.eclipse.osee.framework.core.data.RelationTypeToken;
import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
import org.eclipse.osee.framework.core.enums.RelationSorter;
import org.eclipse.osee.framework.jdk.core.result.XResultData;
import org.eclipse.osee.framework.jdk.core.type.Pair;
import org.eclipse.osee.orcs.OrcsApi;
import org.eclipse.osee.orcs.data.ArtifactReadable;
import org.eclipse.osee.orcs.transaction.TransactionBuilder;
/**
* @author Roberto E. Escobar
* @author David W. Miller
*/
public class RoughToRealArtifactOperation {
private final OrcsApi orcsApi;
private final XResultData results;
private final RoughArtifactCollector rawData;
private final IArtifactImportResolver artifactResolver;
private final Map<RoughArtifact, ArtifactReadable> roughToRealArtifacts;
private final Collection<ArtifactId> createdArtifacts;
private final ArtifactReadable destinationArtifact;
private final RelationSorter importArtifactOrder;
private final boolean deleteUnmatchedArtifacts;
private Collection<ArtifactReadable> unmatchedArtifacts;
private final IArtifactExtractor extractor;
private final TransactionBuilder transaction;
private boolean addRelation = true;
private final List<Pair<ArtifactId, String>> artifactWordContent;
private final HashMap<String, HashMap<ArtifactReadable, ArtifactId>> doorsIdArtIdMap;
private static final Pattern referencePattern = Pattern.compile("\\[[^\\[]*\\]");
public RoughToRealArtifactOperation(OrcsApi orcsApi, XResultData results, TransactionBuilder transaction, ArtifactReadable destinationArtifact, RoughArtifactCollector rawData, IArtifactImportResolver artifactResolver, boolean deleteUnmatchedArtifacts, IArtifactExtractor extractor) {
this.results = results;
this.orcsApi = orcsApi;
this.rawData = rawData;
this.transaction = transaction;
this.artifactResolver = artifactResolver;
this.destinationArtifact = destinationArtifact;
this.importArtifactOrder = USER_DEFINED;
this.roughToRealArtifacts = new HashMap<>();
this.createdArtifacts = new LinkedList<>();
this.deleteUnmatchedArtifacts = deleteUnmatchedArtifacts;
this.extractor = extractor;
roughToRealArtifacts.put(rawData.getParentRoughArtifact(), this.destinationArtifact);
this.artifactWordContent = new LinkedList<>();
this.doorsIdArtIdMap = new HashMap<>();
}
public void doWork() {
if (deleteUnmatchedArtifacts) {
this.unmatchedArtifacts = destinationArtifact.getDescendants();
}
for (RoughArtifact roughArtifact : rawData.getParentRoughArtifact().getChildren()) {
ArtifactId child = createArtifact(roughArtifact, destinationArtifact);
createdArtifacts.add(child);
if (addRelation && child != null && noParent(child)) {
transaction.relate(destinationArtifact, CoreRelationTypes.DefaultHierarchical_Child, child,
importArtifactOrder);
}
for (RoughRelation roughRelation : rawData.getRoughRelations()) {
createRelation(roughRelation);
}
}
if (deleteUnmatchedArtifacts) {
for (ArtifactReadable toDelete : unmatchedArtifacts) {
transaction.deleteArtifact(toDelete);
}
}
}
private boolean noParent(ArtifactId artifact) {
ArtifactReadable art = getArtifactReadable(artifact);
ArtifactReadable parent = art.getParent();
if (parent == null) {
return true;
}
if (!parent.isValid()) {
return true;
}
return false;
}
private ArtifactId createArtifact(RoughArtifact roughArtifact, ArtifactId realParent) {
ArtifactReadable realArtifact = roughToRealArtifacts.get(roughArtifact);
if (realArtifact != null) {
return realArtifact;
}
ArtifactId realArtifactId =
artifactResolver.resolve(roughArtifact, transaction.getBranch(), realParent, destinationArtifact);
//creates list of artifacts and their word template content
String roughWTC = roughArtifact.getRoughAttribute(CoreAttributeTypes.WordTemplateContent.getName());
if (roughWTC != null) {
Matcher matcher = referencePattern.matcher(roughWTC);
if (matcher.find()) {
artifactWordContent.add(new Pair<>(realArtifactId, roughWTC));
}
}
//creates map of object ids to the artifacts that contain them and each destination folder
Collection<String> objIds = roughArtifact.getRoughAttributeAsList(CoreAttributeTypes.DoorsId.getName());
if (objIds != null) {
for (String objId : objIds) {
if (!doorsIdArtIdMap.containsKey(objId)) {
HashMap<ArtifactReadable, ArtifactId> artMap = new HashMap<>();
artMap.put(destinationArtifact, realArtifactId);
doorsIdArtIdMap.put(objId, artMap);
} else {
HashMap<ArtifactReadable, ArtifactId> artMap = doorsIdArtIdMap.get(objId);
if (!artMap.containsKey(destinationArtifact)) {
doorsIdArtIdMap.get(objId).put(destinationArtifact, realArtifactId);
}
}
}
}
if (deleteUnmatchedArtifacts) {
unmatchedArtifacts.remove(realArtifactId);
}
for (RoughArtifact childRoughArtifact : roughArtifact.getDescendants()) {
ArtifactId childArtifact = createArtifact(childRoughArtifact, realArtifactId);
if (areValid(realArtifactId, childArtifact)) {
replaceParent(childArtifact, realArtifactId);
}
extractor.artifactCreated(transaction, childArtifact, childRoughArtifact);
}
results.logf("Added Art: %s\n", realArtifactId.getIdString());
return realArtifactId;
}
private void replaceParent(ArtifactId childId, ArtifactId parentId) {
ArtifactReadable child = getArtifactReadable(childId);
ArtifactReadable parent = getArtifactReadable(parentId);
if (parent == null || child == null) {
return;
}
if (hasDifferentParent(child, parent)) {
transaction.unrelate(child.getParent(), CoreRelationTypes.DefaultHierarchical_Child, child);
}
transaction.relate(parent, CoreRelationTypes.DefaultHierarchical_Child, child, importArtifactOrder);
}
private ArtifactReadable getArtifactReadable(ArtifactId art) {
if (art instanceof ArtifactReadable) {
return (ArtifactReadable) art;
}
ArtifactReadable realArt = null;
try {
realArt = orcsApi.getQueryFactory().fromBranch(transaction.getBranch()).andId(art).getArtifact();
} catch (Exception ex) {
// leave null
}
return realArt;
}
private boolean hasDifferentParent(ArtifactReadable art, ArtifactReadable parent) {
ArtifactReadable knownParent = art.getParent();
return knownParent != null && knownParent.notEqual(parent);
}
private boolean isValid(ArtifactId art) {
return art != null;
}
private boolean areValid(ArtifactId... artifacts) {
boolean returnValue = true;
for (ArtifactId art : artifacts) {
returnValue &= isValid(art);
}
return returnValue;
}
private void createRelation(RoughRelation roughRelation) {
RelationTypeToken relationType = getRelationType(roughRelation.getRelationTypeName());
ArtifactReadable aArt = orcsApi.getQueryFactory().fromBranch(transaction.getBranch()).andGuid(
roughRelation.getAartifactGuid()).getArtifact();
ArtifactReadable bArt = orcsApi.getQueryFactory().fromBranch(transaction.getBranch()).andGuid(
roughRelation.getBartifactGuid()).getArtifact();
if (aArt == null || bArt == null) {
results.warningf("The relation of type %s could not be created.", roughRelation.getRelationTypeName());
if (aArt == null) {
results.warningf("The artifact with guid: %s does not exist.", roughRelation.getAartifactGuid());
}
if (bArt == null) {
results.warningf("The artifact with guid: %s does not exist.", roughRelation.getBartifactGuid());
}
} else {
try {
transaction.relate(aArt, relationType, bArt, roughRelation.getRationale(), importArtifactOrder);
} catch (IllegalArgumentException ex) {
results.error(ex.toString());
}
}
}
private RelationTypeToken getRelationType(String relationName) {
for (RelationTypeToken type : orcsApi.tokenService().getRelationTypes()) {
if (type.getName().equals(relationName)) {
return type;
}
}
return null;
}
public boolean isAddRelation() {
return addRelation;
}
public void setAddRelation(boolean addRelation) {
this.addRelation = addRelation;
}
public Collection<ArtifactId> getCreatedArtifacts() {
return createdArtifacts;
}
public List<Pair<ArtifactId, String>> getArtifactWordContent() {
return artifactWordContent;
}
public HashMap<String, HashMap<ArtifactReadable, ArtifactId>> getDoorsIdArtIdMap() {
return doorsIdArtIdMap;
}
}