| /********************************************************************* |
| * Copyright (c) 2004, 2007 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.framework.skynet.core.artifact.search; |
| |
| import static org.eclipse.osee.framework.core.enums.DeletionFlag.EXCLUDE_DELETED; |
| import static org.eclipse.osee.framework.core.enums.DeletionFlag.INCLUDE_DELETED; |
| import static org.eclipse.osee.framework.core.enums.LoadLevel.ALL; |
| import static org.eclipse.osee.framework.skynet.core.artifact.LoadType.INCLUDE_CACHE; |
| import java.lang.reflect.InvocationHandler; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Proxy; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import org.eclipse.osee.framework.core.data.ArtifactId; |
| import org.eclipse.osee.framework.core.data.ArtifactToken; |
| import org.eclipse.osee.framework.core.data.ArtifactTypeId; |
| import org.eclipse.osee.framework.core.data.ArtifactTypeToken; |
| 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.BranchToken; |
| import org.eclipse.osee.framework.core.data.HasBranch; |
| import org.eclipse.osee.framework.core.data.RelationTypeSide; |
| import org.eclipse.osee.framework.core.data.RelationTypeToken; |
| import org.eclipse.osee.framework.core.data.TransactionId; |
| import org.eclipse.osee.framework.core.data.TransactionToken; |
| import org.eclipse.osee.framework.core.enums.CoreAttributeTypes; |
| import org.eclipse.osee.framework.core.enums.DeletionFlag; |
| import org.eclipse.osee.framework.core.enums.LoadLevel; |
| import org.eclipse.osee.framework.core.enums.QueryOption; |
| import org.eclipse.osee.framework.core.enums.RelationSide; |
| import org.eclipse.osee.framework.core.exception.ArtifactDoesNotExist; |
| import org.eclipse.osee.framework.core.exception.MultipleArtifactsExist; |
| import org.eclipse.osee.framework.core.sql.OseeSql; |
| import org.eclipse.osee.framework.jdk.core.type.HashCollection; |
| import org.eclipse.osee.framework.jdk.core.type.ResultSet; |
| import org.eclipse.osee.framework.jdk.core.type.ResultSets; |
| 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.ArtifactCache; |
| import org.eclipse.osee.framework.skynet.core.artifact.ArtifactLoader; |
| import org.eclipse.osee.framework.skynet.core.artifact.ArtifactTypeManager; |
| import org.eclipse.osee.framework.skynet.core.event.OseeEventManager; |
| import org.eclipse.osee.framework.skynet.core.internal.ServiceUtil; |
| import org.eclipse.osee.framework.skynet.core.utility.ConnectionHandler; |
| import org.eclipse.osee.jdbc.JdbcClient; |
| import org.eclipse.osee.jdbc.JdbcStatement; |
| import org.eclipse.osee.orcs.rest.client.OseeClient; |
| import org.eclipse.osee.orcs.rest.client.QueryBuilder; |
| import org.eclipse.osee.orcs.rest.model.ArtifactEndpoint; |
| import org.eclipse.osee.orcs.rest.model.search.artifact.RequestType; |
| import org.eclipse.osee.orcs.rest.model.search.artifact.SearchMatch; |
| import org.eclipse.osee.orcs.rest.model.search.artifact.SearchParameters; |
| import org.eclipse.osee.orcs.rest.model.search.artifact.SearchResult; |
| |
| /** |
| * @author Ryan D. Brooks |
| */ |
| public class ArtifactQuery { |
| private static Map<Long, String> uuidToGuid; |
| |
| public static <T extends ArtifactId & HasBranch> Artifact getArtifactFromToken(T artifactToken, DeletionFlag deletionFlag) { |
| return getOrCheckArtifactFromId(artifactToken, artifactToken.getBranch(), deletionFlag, QueryType.GET); |
| } |
| |
| public static <T extends ArtifactId & HasBranch> Artifact getArtifactOrNull(T artifactToken, DeletionFlag deletionFlag) { |
| return getOrCheckArtifactFromId(artifactToken, artifactToken.getBranch(), deletionFlag, QueryType.CHECK); |
| } |
| |
| /** |
| * @return artifact unless it's been deleted |
| */ |
| public static <T extends ArtifactId & HasBranch> Artifact getArtifactFromToken(T artifactToken) { |
| Conditions.assertTrue(artifactToken.isValid(), "Valid artifact token must be specified."); |
| Conditions.assertTrue(artifactToken.getBranch().isValid(), "Branch must be specified."); |
| return getOrCheckArtifactFromId(artifactToken, artifactToken.getBranch(), EXCLUDE_DELETED, QueryType.GET); |
| } |
| |
| /** |
| * search for exactly one artifact by one its id - otherwise throw an exception |
| * |
| * @param artId the id of the desired artifact |
| * @return exactly one artifact by one its id - otherwise throw an exception |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| */ |
| public static Artifact getArtifactFromId(long artId, BranchId branch) { |
| return getOrCheckArtifactFromId(ArtifactId.valueOf(artId), branch, EXCLUDE_DELETED, QueryType.GET); |
| } |
| |
| public static Artifact getArtifactFromId(ArtifactId artId, BranchId branch) { |
| return getOrCheckArtifactFromId(artId, branch, EXCLUDE_DELETED, QueryType.GET); |
| } |
| |
| /** |
| * search for exactly one artifact by one its id - otherwise throw an exception |
| * |
| * @param artifactId the id of the desired artifact |
| * @param allowDeleted whether to return the artifact even if it has been deleted |
| * @return exactly one artifact by one its id - otherwise throw an exception |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| */ |
| public static Artifact getArtifactFromId(ArtifactId artifactId, BranchId branch, DeletionFlag allowDeleted) { |
| return getOrCheckArtifactFromId(artifactId, branch, allowDeleted, QueryType.GET); |
| } |
| |
| public static Artifact getArtifactOrNull(ArtifactId artifactId, BranchId branch, DeletionFlag deletionFlag) { |
| return getOrCheckArtifactFromId(artifactId, branch, deletionFlag, QueryType.CHECK); |
| } |
| |
| private static Artifact getOrCheckArtifactFromId(ArtifactId artifactId, BranchId branch, DeletionFlag allowDeleted, QueryType queryType) { |
| Conditions.assertNotSentinel(artifactId); |
| ArtifactToken artifactToken; |
| if (artifactId instanceof ArtifactToken) { |
| artifactToken = ArtifactToken.valueOf((ArtifactToken) artifactId, branch); |
| } else { |
| artifactToken = ArtifactToken.valueOf(artifactId, branch); |
| } |
| Artifact artifact = ArtifactCache.getActive(artifactToken); |
| if (artifact != null) { |
| if (artifact.isDeleted() && allowDeleted == EXCLUDE_DELETED) { |
| if (queryType == QueryType.CHECK) { |
| artifact = null; |
| } else { |
| throw new ArtifactDoesNotExist("Deleted artifact unexpectedly returned"); |
| } |
| } |
| } else { |
| artifact = new ArtifactQueryBuilder(artifactId, branch, allowDeleted, ALL).getOrCheckArtifact(queryType); |
| } |
| return artifact; |
| } |
| |
| /** |
| * Checks for existence of an artifact by id |
| * |
| * @param artifactId the id of the desired artifact |
| * @param allowDeleted whether to return the artifact even if it has been deleted |
| * @return one artifact by one its id if it exists, otherwise null |
| */ |
| public static Artifact checkArtifactFromId(ArtifactId artifactId, BranchId branch, DeletionFlag allowDeleted) { |
| return getOrCheckArtifactFromId(artifactId, branch, allowDeleted, QueryType.CHECK); |
| } |
| |
| /** |
| * Checks for existence of an artifact by one its guid - otherwise throw an exception |
| * |
| * @param guid either the guid of the desired artifact |
| * @param allowDeleted whether to return the artifact even if it has been deleted |
| * @return one artifact by one its id if it exists, otherwise null |
| */ |
| public static Artifact checkArtifactFromId(String guid, BranchId branch, DeletionFlag allowDeleted) { |
| return getOrCheckArtifactFromId(guid, branch, allowDeleted, QueryType.CHECK); |
| } |
| |
| /** |
| * Checks for existence of an artifact by one its guid or human readable id - otherwise throw an exception |
| * |
| * @param artifactId of the desired artifact |
| * @return one artifact by its guid if it exists, otherwise null |
| */ |
| public static Artifact checkArtifactFromId(ArtifactId artifactId, BranchId branch) { |
| return getOrCheckArtifactFromId(artifactId, branch, EXCLUDE_DELETED, QueryType.CHECK); |
| } |
| |
| /** |
| * search for exactly one artifact by one its guid - otherwise throw an exception |
| * |
| * @param guid of the desired artifact |
| * @return exactly one artifact by one its guid - otherwise throw an exception |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| * @throws MultipleArtifactsExist if more than one artifact is found |
| */ |
| public static Artifact getArtifactFromId(String guid, BranchId branch) { |
| return getOrCheckArtifactFromId(guid, branch, EXCLUDE_DELETED, QueryType.GET); |
| } |
| |
| /** |
| * search for exactly one artifact by one its guid or human readable id - otherwise throw an exception |
| * |
| * @param the guid of the desired artifact |
| * @param allowDeleted whether to return the artifact even if it has been deleted |
| * @return exactly one artifact by one its guid or human readable id - otherwise throw an exception |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| * @throws MultipleArtifactsExist if more than one artifact is found |
| */ |
| public static Artifact getArtifactFromId(String guid, BranchId branch, DeletionFlag allowDeleted) { |
| return getOrCheckArtifactFromId(guid, branch, allowDeleted, QueryType.GET); |
| } |
| |
| private static Artifact getOrCheckArtifactFromId(String guid, BranchId branch, DeletionFlag allowDeleted, QueryType queryType) { |
| Artifact artifact = ArtifactCache.getActive(guid, branch); |
| if (artifact != null) { |
| if (artifact.isDeleted() && allowDeleted == EXCLUDE_DELETED) { |
| if (queryType == QueryType.CHECK) { |
| return null; |
| } else { |
| throw new ArtifactDoesNotExist("Deleted artifact unexpectedly returned"); |
| } |
| } |
| return artifact; |
| } |
| return new ArtifactQueryBuilder(guid, branch, allowDeleted, ALL).getOrCheckArtifact(queryType); |
| } |
| |
| public static List<ArtifactId> getArtifactIdsFromTypeAndName(ArtifactTypeId artifactType, String artifactName, BranchId branch) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, |
| new AttributeCriteria(CoreAttributeTypes.Name, artifactName)).selectArtifacts(2); |
| } |
| |
| /** |
| * search for exactly one artifact based on its type and name - otherwise throw an exception |
| * |
| * @return exactly one artifact based on its type and name - otherwise throw an exception |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| * @throws MultipleArtifactsExist if more than one artifact is found |
| */ |
| public static Artifact getArtifactFromTypeAndName(ArtifactTypeId artifactType, String artifactName, BranchId branch) { |
| return getArtifactFromTypeAndAttribute(artifactType, CoreAttributeTypes.Name, artifactName, branch, |
| QueryType.GET); |
| } |
| |
| /** |
| * Checks for existence of an artifact based on its type and name |
| * |
| * @return one artifact based on its type and name if it exists, otherwise null |
| */ |
| public static Artifact checkArtifactFromTypeAndName(ArtifactTypeId artifactType, String artifactName, BranchId branch) { |
| return getArtifactFromTypeAndAttribute(artifactType, CoreAttributeTypes.Name, artifactName, branch, |
| QueryType.CHECK); |
| } |
| |
| /** |
| * search for exactly one artifact based on its type and an attribute of a given type and value - otherwise throw an |
| * exception |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| * @throws MultipleArtifactsExist if more than one artifact is found |
| */ |
| public static Artifact getArtifactFromTypeAndAttribute(ArtifactTypeId artifactType, AttributeTypeId attributeType, String attributeValue, BranchId branch) { |
| return getArtifactFromTypeAndAttribute(artifactType, attributeType, attributeValue, branch, QueryType.GET); |
| } |
| |
| private static Artifact getArtifactFromTypeAndAttribute(ArtifactTypeId artifactType, AttributeTypeId attributeType, String attributeValue, BranchId branch, QueryType queryType) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, |
| new AttributeCriteria(attributeType, attributeValue)).getOrCheckArtifact(queryType); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeAndName(ArtifactTypeId artifactType, String artifactName, BranchId branch) { |
| return getArtifactListFromTypeAndAttribute(artifactType, CoreAttributeTypes.Name, artifactName, branch); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeAndAttribute(ArtifactTypeId artifactType, AttributeTypeId attributeType, String attributeValue, BranchId branch) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, |
| new AttributeCriteria(attributeType, attributeValue)).getArtifacts(100, null); |
| } |
| |
| /** |
| * search for un-deleted artifacts with any of the given artifact ids |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFrom(Collection<? extends ArtifactId> artifactIds, BranchId branch) { |
| return ArtifactLoader.loadArtifacts(artifactIds, branch, LoadLevel.ALL, INCLUDE_CACHE, INCLUDE_DELETED); |
| } |
| |
| public static List<Artifact> getArtifactListFrom(Collection<? extends ArtifactId> artifactIds, BranchId branch, DeletionFlag allowDeleted) { |
| return ArtifactLoader.loadArtifacts(artifactIds, branch, LoadLevel.ALL, INCLUDE_CACHE, allowDeleted); |
| } |
| |
| /** |
| * search for artifacts with any of the given artifact guids |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromIds(List<String> guids, BranchId branch) { |
| return new ArtifactQueryBuilder(guids, branch, ALL).getArtifacts(30, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromIds(List<String> guids, BranchId branch, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(guids, branch, allowDeleted, ALL).getArtifacts(30, null); |
| } |
| |
| public static List<Artifact> getHistoricalArtifactListFromIds(List<String> guids, TransactionToken transactionId, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(guids, transactionId, allowDeleted, ALL).getArtifacts(30, null); |
| } |
| |
| public static List<Artifact> getHistoricalArtifactListFromIds(Collection<ArtifactId> artifactIds, TransactionToken transactionId, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(artifactIds, transactionId, allowDeleted, ALL).getArtifacts(30, null); |
| } |
| |
| public static Artifact getHistoricalArtifactFromId(ArtifactId artifactId, TransactionToken transactionId, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(artifactId, transactionId, allowDeleted, ALL).getOrCheckArtifact(QueryType.GET); |
| } |
| |
| public static Artifact getHistoricalArtifactOrNull(ArtifactId artifactId, TransactionToken transactionId, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(artifactId, transactionId, allowDeleted, ALL).getOrCheckArtifact(QueryType.CHECK); |
| } |
| |
| public static Artifact getHistoricalArtifactFromId(String guid, TransactionToken transactionId, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(Arrays.asList(guid), transactionId, allowDeleted, ALL).getOrCheckArtifact( |
| QueryType.GET); |
| } |
| |
| public static List<Artifact> getArtifactListFromName(String artifactName, BranchId branch, DeletionFlag allowDeleted, QueryOption[] options) { |
| return new ArtifactQueryBuilder(branch, ALL, allowDeleted, |
| new AttributeCriteria(CoreAttributeTypes.Name, artifactName, options)).getArtifacts(30, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromName(String artifactName, BranchId branch) { |
| return getArtifactListFromTypeAndAttribute(ArtifactTypeId.SENTINEL, CoreAttributeTypes.Name, artifactName, |
| branch); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeAndName(ArtifactTypeId artifactType, String artifactName, BranchId branch, QueryOption[] options) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, |
| new AttributeCriteria(CoreAttributeTypes.Name, artifactName, options)).getArtifacts(100, null); |
| } |
| |
| /** |
| * search for exactly one artifact based on its type and an attribute of a given type and value - otherwise throw an |
| * exception |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| * @throws ArtifactDoesNotExist if no artifacts are found |
| * @throws MultipleArtifactsExist if more than one artifact is found |
| */ |
| public static Artifact getArtifactFromAttribute(AttributeTypeId attributeType, String attributeValue, BranchId branch) { |
| return getOrCheckArtifact(QueryType.GET, getArtifactListFromAttribute(attributeType, attributeValue, branch)); |
| } |
| |
| public static List<Artifact> getArtifactListFromType(ArtifactTypeToken artifactTypeToken, BranchId branch) { |
| return getArtifactListFromType(artifactTypeToken, branch, EXCLUDE_DELETED); |
| } |
| |
| /** |
| * Does not return any inherited artifacts. Use getArtifactListFromTypeWithInheritence instead. |
| */ |
| public static List<Artifact> getArtifactListFromType(ArtifactTypeToken artifactType, BranchId branch, DeletionFlag allowDeleted) { |
| return getArtifactListFrom(getArtifactEndpoint(branch).getArtifactIdsByType(artifactType), branch, allowDeleted); |
| } |
| |
| public static List<Artifact> getArtifactListFromBranch(BranchId branch, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(branch, ALL, allowDeleted).getArtifacts(10000, null); |
| } |
| |
| public static List<Artifact> reloadArtifactListFromBranch(BranchId branch, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(branch, ALL, allowDeleted).reloadArtifacts(10000); |
| } |
| |
| /** |
| * do not use this method if searching for a super type and its descendants, instead use getArtifactListFromTypeAnd |
| */ |
| public static List<Artifact> getArtifactListFromTypes(Collection<? extends ArtifactTypeId> artifactTypes, BranchId branch, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(artifactTypes, branch, ALL, allowDeleted).getArtifacts(1000, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeWithInheritence(ArtifactTypeToken artifactType, BranchId branch, DeletionFlag allowDeleted) { |
| Collection<ArtifactTypeToken> artifactTypes = artifactType.getAllDescendantTypes(); |
| artifactTypes.add(artifactType); |
| return getArtifactListFromTypes(artifactTypes, branch, allowDeleted); |
| } |
| |
| public static int getArtifactCountFromTypeWithInheritence(ArtifactTypeToken artifactType, BranchId branch, DeletionFlag allowDeleted) { |
| Collection<ArtifactTypeToken> artifactTypes = artifactType.getAllDescendantTypes(); |
| artifactTypes.add(artifactType); |
| return getArtifactCountFromTypes(artifactTypes, branch, allowDeleted); |
| } |
| |
| public static int getArtifactCountFromTypes(Collection<? extends ArtifactTypeId> artifactTypes, BranchId branch, DeletionFlag allowDeleted) { |
| return new ArtifactQueryBuilder(artifactTypes, branch, ALL, allowDeleted).countArtifacts(); |
| } |
| |
| /** |
| * search for artifacts of the given type on a particular branch that satisfy the given criteria |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromTypeAnd(ArtifactTypeId artifactType, BranchId branch, int artifactCountEstimate, List<ArtifactSearchCriteria> criteria) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, criteria).getArtifacts(artifactCountEstimate, null); |
| } |
| |
| /** |
| * search for artifacts on a particular branch that satisfy the given criteria |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromCriteria(BranchId branch, int artifactCountEstimate, List<ArtifactSearchCriteria> criteria) { |
| return new ArtifactQueryBuilder(branch, ALL, criteria).getArtifacts(artifactCountEstimate, null); |
| } |
| |
| /** |
| * search for artifacts on a particular branch that satisfy the given criteria |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromCriteria(BranchId branch, int artifactCountEstimate, ArtifactSearchCriteria... criteria) { |
| return new ArtifactQueryBuilder(branch, ALL, EXCLUDE_DELETED, criteria).getArtifacts(artifactCountEstimate, null); |
| } |
| |
| /** |
| * search for artifacts related |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getRelatedArtifactList(Artifact artifact, RelationTypeToken relationType, RelationSide relationSide) { |
| return new ArtifactQueryBuilder(artifact.getBranch(), ALL, EXCLUDE_DELETED, |
| new RelationCriteria(artifact, relationType, relationSide)).getArtifacts(1000, null); |
| } |
| |
| /** |
| * search for artifacts by relation |
| * |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromRelation(RelationTypeToken relationType, RelationSide relationSide, BranchId branch) { |
| return new ArtifactQueryBuilder(branch, ALL, EXCLUDE_DELETED, |
| new RelationCriteria(relationType, relationSide)).getArtifacts(1000, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromAttribute(AttributeTypeId attributeType, String attributeValue, BranchId branch, QueryOption... options) { |
| return new ArtifactQueryBuilder(branch, ALL, EXCLUDE_DELETED, |
| new AttributeCriteria(attributeType, attributeValue, options)).getArtifacts(300, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromAttribute(AttributeTypeId attributeType, String attributeValue, BranchId branch) { |
| return getArtifactListFromTypeAndAttribute(ArtifactTypeId.SENTINEL, attributeType, attributeValue, branch); |
| } |
| |
| /** |
| * Return all artifacts that have one or more attributes of given type regardless of the value |
| */ |
| public static List<Artifact> getArtifactListFromAttributeType(AttributeTypeId attributeType, BranchId branch) { |
| return new ArtifactQueryBuilder(branch, ALL, EXCLUDE_DELETED, new AttributeCriteria(attributeType)).getArtifacts( |
| 300, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeAndAttribute(ArtifactTypeId artifactType, AttributeTypeId attributeType, Collection<ArtifactId> attributeValues, BranchId branch) { |
| Collection<String> idStrings = |
| org.eclipse.osee.framework.jdk.core.util.Collections.transform(attributeValues, String::valueOf); |
| return getArtifactListFromTypeAndAttribute(artifactType, attributeType, idStrings, branch, 10); |
| } |
| |
| public static List<Artifact> getArtifactListFromTypeAndAttribute(ArtifactTypeId artifactType, AttributeTypeId attributeType, Collection<String> attributeValues, BranchId branch, int artifactCountEstimate) { |
| return new ArtifactQueryBuilder(artifactType, branch, ALL, |
| new AttributeCriteria(attributeType, attributeValues)).getArtifacts(artifactCountEstimate, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromAttributeValues(AttributeTypeId attributeType, Collection<String> attributeValues, BranchId branch, int artifactCountEstimate) { |
| return new ArtifactQueryBuilder(branch, ALL, EXCLUDE_DELETED, |
| new AttributeCriteria(attributeType, attributeValues)).getArtifacts(artifactCountEstimate, null); |
| } |
| |
| public static List<Artifact> getArtifactListFromAttributeValues(AttributeTypeId attributeType, Collection<ArtifactId> attributeValues, BranchId branch) { |
| Collection<String> idStrings = |
| org.eclipse.osee.framework.jdk.core.util.Collections.transform(attributeValues, ArtifactId::getIdString); |
| return getArtifactListFromAttributeValues(attributeType, idStrings, branch, 10); |
| } |
| |
| /** |
| * Searches for artifacts having attributes which contain matching keywords entered in the query string. |
| * <p> |
| * Special characters such as (<b><code>' '</code>, <code>!</code>, <code>"</code>, <code>#</code>, <code>$</code>, |
| * <code>%</code>, <code>(</code>, <code>)</code>, <code>*</code>, <code>+</code>, <code>,</code>, <code>-</code>, |
| * <code>.</code>, <code>/</code>, <code>:</code>, <code>;</code>, <code><</code>, <code>></code>, |
| * <code>?</code>, <code>@</code>, <code>[</code>, <code>\</code>, <code>]</code>, <code>^</code>, <code>{</code>, |
| * <code>|</code>, <code>}</code>, <code>~</code>, <code>_</code></b>) are assumed to be word separators. |
| * </p> |
| * <p> |
| * For example: |
| * <ul> |
| * <li><b>'<code>hello.world</code>'</b> will be translated to <b>'<code>hello</code>'</b> and <b>'<code>world</code> |
| * '</b>. The search will match attributes with <b>'<code>hello</code>'</b> and <b>'<code>world</code>'</b> keywords. |
| * </li> |
| * </ul> |
| * </p> |
| * |
| * @param queryString keywords to match |
| * @param matchWordOrder <b>true</b> ensures the query string words exist in order; <b>false</b> matches words in any |
| * order |
| * @param nameOnly <b>true</b> searches in name attributes only; <b>false</b> includes all tagged attribute types |
| * @param allowDeleted <b>true</b> includes deleted artifacts in results; <b>false</b> omits deleted artifacts |
| * @return a collection of the artifacts found or an empty collection if none are found |
| */ |
| public static List<Artifact> getArtifactListFromAttributeKeywords(BranchId branch, String queryString, boolean isMatchWordOrder, DeletionFlag deletionFlag, boolean isCaseSensitive, AttributeTypeId... attributeTypes) { |
| QueryBuilderArtifact queryBuilder = createQueryBuilder(branch); |
| queryBuilder.includeDeleted(deletionFlag.areDeletedAllowed()); |
| QueryOption matchCase = QueryOption.getCaseType(isCaseSensitive); |
| QueryOption matchWordOrder = QueryOption.getTokenOrderType(isMatchWordOrder); |
| Collection<AttributeTypeId> typesToSearch = attributeTypes.length == 0 ? Collections.singleton( |
| QueryBuilder.ANY_ATTRIBUTE_TYPE) : Arrays.asList(attributeTypes); |
| queryBuilder.and(typesToSearch, queryString, matchCase, matchWordOrder); |
| return queryBuilder.getResults().getList(); |
| } |
| |
| /** |
| * Searches for keywords in attributes and returning match location information such as artifact where match was |
| * found, attribute containing the match and match location in attribute data. |
| * |
| * @see #getArtifactsFromAttributeWithKeywords |
| * @param findAllMatchLocations when set to <b>true</b> returns all match locations instead of just returning the |
| * first one. When returning all match locations, search performance may be slow. |
| */ |
| public static Iterable<ArtifactMatch> getArtifactMatchesFromAttributeKeywords(SearchRequest searchRequest) { |
| QueryBuilderArtifact queryBuilder = createQueryBuilder(searchRequest.getBranch()); |
| SearchOptions options = searchRequest.getOptions(); |
| queryBuilder.includeDeleted(options.getDeletionFlag().areDeletedAllowed()); |
| QueryOption matchCase = QueryOption.getCaseType(options.isCaseSensitive()); |
| QueryOption matchWordOrder = QueryOption.getTokenOrderType(options.isMatchWordOrder()); |
| QueryOption matchExact = QueryOption.TOKEN_DELIMITER__ANY; |
| if (options.isExactMatch()) { |
| matchCase = QueryOption.CASE__MATCH; |
| matchWordOrder = QueryOption.TOKEN_MATCH_ORDER__MATCH; |
| matchExact = QueryOption.TOKEN_DELIMITER__EXACT; |
| } |
| |
| Collection<AttributeTypeId> typesToSearch = Conditions.hasValues( |
| options.getAttributeTypeFilter()) ? options.getAttributeTypeFilter() : Collections.singleton( |
| QueryBuilder.ANY_ATTRIBUTE_TYPE); |
| queryBuilder.and(typesToSearch, searchRequest.getRawSearch(), matchCase, matchWordOrder, matchExact); |
| |
| if (Conditions.hasValues(options.getArtifactTypeFilter())) { |
| queryBuilder.andIsOfType(options.getArtifactTypeFilter()); |
| } |
| |
| return queryBuilder.getMatches(); |
| } |
| |
| public static Artifact reloadArtifactFromId(ArtifactId artId, BranchId branch) { |
| ArtifactQueryBuilder query = new ArtifactQueryBuilder(artId, branch, INCLUDE_DELETED, ALL); |
| Artifact artifact = query.reloadArtifact(); |
| OseeEventManager.kickLocalArtifactReloadEvent(query, Collections.singleton(artifact)); |
| return artifact; |
| } |
| |
| public static Collection<? extends Artifact> reloadArtifacts(Collection<? extends ArtifactToken> artifacts) { |
| Collection<Artifact> reloadedArts = new ArrayList<>(artifacts.size()); |
| HashCollection<BranchId, ArtifactToken> branchMap = new HashCollection<>(); |
| if (artifacts.isEmpty()) { |
| return reloadedArts; |
| } |
| for (ArtifactToken artifact : artifacts) { |
| // separate/group artifacts by branch since ArtifactQueryBuilder only supports a single branch |
| branchMap.put(artifact.getBranch(), artifact); |
| } |
| Set<ArtifactId> artIds = new HashSet<>(); |
| for (Entry<BranchId, List<ArtifactToken>> entrySet : branchMap.entrySet()) { |
| for (ArtifactToken artifact : entrySet.getValue()) { |
| artIds.add(artifact); |
| } |
| |
| ArtifactQueryBuilder query = new ArtifactQueryBuilder(artIds, entrySet.getKey(), INCLUDE_DELETED, ALL); |
| |
| reloadedArts.addAll(query.reloadArtifacts(artIds.size())); |
| OseeEventManager.kickLocalArtifactReloadEvent(query, reloadedArts); |
| artIds.clear(); |
| } |
| return reloadedArts; |
| } |
| |
| public static Artifact getOrCreate(String guid, ArtifactTypeToken type, BranchToken branch) { |
| Artifact artifact = ArtifactQuery.checkArtifactFromId(guid, branch, EXCLUDE_DELETED); |
| |
| if (artifact == null) { |
| artifact = ArtifactTypeManager.addArtifact(type, branch, null, guid); |
| } |
| if (artifact == null) { |
| throw new ArtifactDoesNotExist("Artifact of type [%s] does not exist on branch [%s]", type, branch); |
| } |
| return artifact; |
| } |
| |
| public static QueryBuilderArtifact createQueryBuilder(BranchId branch) { |
| OseeClient client = ServiceUtil.getOseeClient(); |
| QueryBuilder builder = client.createQueryBuilder(branch); |
| |
| QueryBuilderProxy handler = new QueryBuilderProxy(builder); |
| |
| Class<?>[] types = new Class<?>[] {QueryBuilderArtifact.class}; |
| QueryBuilderArtifact query = |
| (QueryBuilderArtifact) Proxy.newProxyInstance(QueryBuilderArtifact.class.getClassLoader(), types, handler); |
| |
| return query; |
| } |
| |
| private static final class QueryBuilderProxy implements InvocationHandler { |
| |
| private final QueryBuilder proxied; |
| |
| public QueryBuilderProxy(QueryBuilder proxied) { |
| super(); |
| this.proxied = proxied; |
| } |
| |
| @Override |
| public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
| Object toReturn = null; |
| Method localMethod = getMethodFor(this.getClass(), method); |
| try { |
| if (localMethod != null) { |
| toReturn = localMethod.invoke(this, args); |
| } else { |
| toReturn = invokeOnDelegate(proxied, method, args); |
| } |
| } catch (InvocationTargetException e) { |
| throw e.getCause(); |
| } |
| return toReturn; |
| } |
| |
| protected Object invokeOnDelegate(Object target, Method method, Object[] args) throws Throwable { |
| return method.invoke(target, args); |
| } |
| |
| private Method getMethodFor(Class<?> clazz, Method method) { |
| Method toReturn = null; |
| try { |
| toReturn = clazz.getMethod(method.getName(), method.getParameterTypes()); |
| } catch (Exception ex) { |
| // Do Nothing; |
| } |
| return toReturn; |
| } |
| |
| // this method is called from invoke in the localMethod case |
| @SuppressWarnings("unused") |
| public ResultSet<Artifact> getResults() { |
| SearchResult result = proxied.getSearchResult(RequestType.IDS); |
| SearchParameters searchParameters = result.getSearchParameters(); |
| |
| BranchId branch = searchParameters.getBranch(); |
| |
| TransactionId tx = TransactionId.SENTINEL; |
| if (searchParameters.getFromTx() > 0) { |
| tx = TransactionId.valueOf(searchParameters.getFromTx()); |
| } |
| DeletionFlag deletionFlag = |
| searchParameters.isIncludeDeleted() ? DeletionFlag.INCLUDE_DELETED : DeletionFlag.EXCLUDE_DELETED; |
| |
| List<ArtifactId> ids = result.getIds(); |
| ResultSet<Artifact> toReturn; |
| if (ids != null && !ids.isEmpty()) { |
| List<Artifact> loadedArtifacts = |
| ArtifactLoader.loadArtifacts(ids, branch, LoadLevel.ALL, INCLUDE_CACHE, deletionFlag, tx); |
| toReturn = ResultSets.newResultSet(loadedArtifacts); |
| } else { |
| toReturn = ResultSets.emptyResultSet(); |
| } |
| return toReturn; |
| } |
| |
| // this method is called from invoke in the localMethod case |
| @SuppressWarnings("unused") |
| public ResultSet<ArtifactMatch> getMatches() { |
| SearchResult result = proxied.getSearchResult(RequestType.MATCHES); |
| SearchParameters searchParameters = result.getSearchParameters(); |
| |
| BranchId branch = searchParameters.getBranch(); |
| |
| TransactionId tx = TransactionId.SENTINEL; |
| if (searchParameters.getFromTx() > 0) { |
| tx = TransactionId.valueOf(searchParameters.getFromTx()); |
| } |
| DeletionFlag deletionFlag = |
| searchParameters.isIncludeDeleted() ? DeletionFlag.INCLUDE_DELETED : DeletionFlag.EXCLUDE_DELETED; |
| |
| Map<Long, Artifact> artIdToArtifact = new HashMap<>(); |
| |
| List<Artifact> loadedArtifacts = |
| ArtifactLoader.loadArtifacts(result.getIds(), branch, LoadLevel.ALL, INCLUDE_CACHE, deletionFlag, tx); |
| |
| for (Artifact art : loadedArtifacts) { |
| artIdToArtifact.put(art.getId(), art); |
| } |
| |
| Map<Artifact, ArtifactMatch> matches = new HashMap<>(); |
| for (SearchMatch match : result.getSearchMatches()) { |
| ArtifactId artId = match.getArtId(); |
| Artifact art = artIdToArtifact.get(artId.getId()); |
| |
| if (art != null) { |
| ArtifactMatch toAddTo = matches.get(art); |
| if (toAddTo == null) { |
| toAddTo = new ArtifactMatch(art); |
| matches.put(art, toAddTo); |
| } |
| toAddTo.addMatchData(match.getAttrId(), match.getLocations()); |
| } |
| } |
| |
| return ResultSets.newResultSet(matches.values()); |
| } |
| } |
| |
| public static String getGuidFromId(long uuid, BranchId branch) { |
| if (uuidToGuid == null) { |
| uuidToGuid = new HashMap<>(200); |
| } |
| String result = null; |
| if (uuidToGuid.containsKey(uuid)) { |
| result = uuidToGuid.get(uuid); |
| } else { |
| Artifact art = getArtifactFromId(uuid, branch); |
| if (art != null) { |
| result = art.getGuid(); |
| uuidToGuid.put(uuid, result); |
| } |
| } |
| return result; |
| } |
| |
| public static Collection<ArtifactToken> getArtifactTokenListFromTypeAndActive(ArtifactTypeToken artifactType, AttributeTypeToken attributeType, BranchId branch) { |
| return getArtifactEndpoint(branch).getArtifactTokensByAttribute(attributeType, "false", false, artifactType); |
| } |
| |
| public static Collection<ArtifactToken> getArtifactTokenListFromTypeAndAttribute(ArtifactTypeToken artifactType, AttributeTypeToken attributeType, String value, BranchId branch) { |
| return getArtifactEndpoint(branch).getArtifactTokensByAttribute(attributeType, value, false, artifactType); |
| } |
| |
| public static Collection<ArtifactToken> getArtifactTokenListFromType(ArtifactTypeToken artifactType, BranchId branch) { |
| return getArtifactEndpoint(branch).getArtifactTokensByType(artifactType); |
| } |
| |
| private static List<ArtifactToken> extractTokensFromQuery(JdbcStatement chStmt, BranchId branch) { |
| List<ArtifactToken> tokens = new LinkedList<>(); |
| while (chStmt.next()) { |
| Long artId = chStmt.getLong("art_id"); |
| ArtifactTypeToken artTypeId = ServiceUtil.getOrcsTokenService().getArtifactType(chStmt.getLong("art_type_id")); |
| String name = chStmt.getString("value"); |
| String guid = chStmt.getString("guid"); |
| ArtifactToken token = ArtifactToken.valueOf(artId, guid, name, branch, artTypeId); |
| tokens.add(token); |
| } |
| return tokens; |
| } |
| |
| private static String attributeTokenQuery = "select art.art_id, art.art_type_id, art.guid, attr.value " + // |
| "from osee_txs txsArt, osee_txs txsAttr, osee_artifact art, osee_attribute attr where art.art_type_id in ( ART_IDS_HERE ) " + // |
| "and txsArt.BRANCH_ID = ? and art.GAMMA_ID = txsArt.GAMMA_ID and txsArt.TX_CURRENT = 1 " + // |
| "and txsAttr.BRANCH_ID = ? and attr.GAMMA_ID = txsAttr.GAMMA_ID and txsAttr.TX_CURRENT = 1 " + // |
| "and art.ART_ID = attr.art_id and attr.ATTR_TYPE_ID = ? and value = ? "; |
| |
| private static String artifactTokenByGuidQuery = |
| "select ART.ART_ID, attr.VALUE, art.art_type_id, art.guid from OSEE_ATTRIBUTE attr, OSEE_ARTIFACT art, OSEE_TXS txs where " // |
| + "txs.BRANCH_ID = ? and art.GUID in ( ART_GUIDS_HERE ) and txs.TX_CURRENT = 1 and attr.ATTR_TYPE_ID = 1152921504606847088 " // |
| + "and attr.ART_ID = art.ART_ID and txs.GAMMA_ID = ATTR.GAMMA_ID"; |
| |
| private static String artifactTokenByArtIdQuery = |
| "select ART.ART_ID, attr.VALUE, art.art_type_id, art.guid from OSEE_ATTRIBUTE attr, OSEE_ARTIFACT art, OSEE_TXS txs where " // |
| + "txs.BRANCH_ID = ? and art.art_id in ( ART_IDS_HERE ) and txs.TX_CURRENT = 1 and attr.ATTR_TYPE_ID = 1152921504606847088 " // |
| + "and attr.ART_ID = art.ART_ID and txs.GAMMA_ID = ATTR.GAMMA_ID"; |
| |
| public static List<ArtifactToken> getArtifactTokenListFromSoleAttributeInherited(ArtifactTypeToken artifactType, AttributeTypeId attributetype, String value, BranchId branch) { |
| List<Long> artTypeIds = new LinkedList<>(); |
| String ids = ""; |
| for (ArtifactTypeToken artType : artifactType.getAllDescendantTypes()) { |
| artTypeIds.add(artType.getId()); |
| ids += artType.getIdString() + ","; |
| } |
| artTypeIds.add(artifactType.getId()); |
| ids = ids.replaceFirst(",$", ""); |
| |
| JdbcStatement chStmt = ConnectionHandler.getStatement(); |
| try { |
| String query = attributeTokenQuery.replaceFirst("ART_IDS_HERE", ids); |
| chStmt.runPreparedQuery(query, branch, branch, attributetype, value); |
| List<ArtifactToken> tokens = extractTokensFromQuery(chStmt, branch); |
| return tokens; |
| } finally { |
| chStmt.close(); |
| } |
| } |
| |
| public static HashCollection<ArtifactId, ArtifactToken> getArtifactTokenListFromRelated(BranchId branch, Collection<ArtifactId> artifacts, ArtifactTypeId artifactType, RelationTypeSide relationType) { |
| List<Long> artIds = new LinkedList<>(); |
| String ids = ""; |
| for (ArtifactId art : artifacts) { |
| artIds.add(art.getId()); |
| ids += art.getId().toString() + ","; |
| } |
| ids = ids.replaceFirst(",$", ""); |
| |
| Map<Long, Long> artBIdToArtAId = new HashMap<>(); |
| Map<Long, Long> artAIdToArtBId = new HashMap<>(); |
| JdbcStatement chStmt = ConnectionHandler.getStatement(); |
| boolean isSideA = relationType.getSide().isSideA(); |
| try { |
| String query = OseeSql.ARTIFACT_TO_RELATED_B_ARTIFACT_ID.getSql().replaceFirst("ART_IDS_HERE", ids); |
| query = query.replaceAll("REL_SIDE_HERE", isSideA ? "b_art_id" : "a_art_id"); |
| query = query.replaceAll("REL_TYPE_LINKE_ID_HERE", relationType.getGuid().toString()); |
| query = query.replaceAll("BRANCH_ID_HERE", branch.getId().toString()); |
| chStmt.runPreparedQuery(query); |
| while (chStmt.next()) { |
| Long aArtId = chStmt.getLong("a_art_id"); |
| Long bArtId = chStmt.getLong("b_art_id"); |
| artBIdToArtAId.put(bArtId, aArtId); |
| artAIdToArtBId.put(aArtId, bArtId); |
| } |
| } finally { |
| chStmt.close(); |
| } |
| |
| chStmt = ConnectionHandler.getStatement(); |
| HashCollection<ArtifactId, ArtifactToken> artToRelatedTokens = new HashCollection<>(); |
| try { |
| String query = OseeSql.ARTIFACT_TOKENS_RELATED_TO_ARTIFACT_QUERY.getSql().replaceFirst("ART_IDS_HERE", ids); |
| query = query.replaceAll("OPPOSITE_REL_SIDE_HERE", isSideA ? "a_art_id" : "b_art_id"); |
| query = query.replaceAll("REL_SIDE_HERE", isSideA ? "b_art_id" : "a_art_id"); |
| query = query.replaceAll("REL_TYPE_LINKE_ID_HERE", relationType.getGuid().toString()); |
| query = query.replaceAll("BRANCH_ID_HERE", branch.getId().toString()); |
| chStmt.runPreparedQuery(query); |
| while (chStmt.next()) { |
| Long artId = chStmt.getLong("art_id"); |
| |
| ArtifactTypeToken artTypeId = |
| ServiceUtil.getOrcsTokenService().getArtifactType(chStmt.getLong("art_type_id")); |
| String name = chStmt.getString("value"); |
| ArtifactToken token = ArtifactToken.valueOf(artId, name, branch, artTypeId); |
| Long artIdLong = isSideA ? artAIdToArtBId.get(artId) : artBIdToArtAId.get(artId); |
| ArtifactId aArtId = ArtifactId.valueOf(artIdLong); |
| artToRelatedTokens.put(aArtId, token); |
| } |
| } finally { |
| chStmt.close(); |
| } |
| return artToRelatedTokens; |
| } |
| |
| public static Map<String, ArtifactToken> getArtifactTokensFromGuids(BranchId branch, List<String> guids) { |
| Map<String, ArtifactToken> guidToToken = new HashMap<>(); |
| if (!guids.isEmpty()) { |
| JdbcStatement chStmt = ConnectionHandler.getStatement(); |
| StringBuilder sb = new StringBuilder(); |
| for (String guid : guids) { |
| sb.append("'"); |
| sb.append(guid); |
| sb.append("',"); |
| } |
| try { |
| String query = |
| artifactTokenByGuidQuery.replaceFirst("ART_GUIDS_HERE", sb.toString().replaceFirst(",$", "")); |
| chStmt.runPreparedQuery(query, branch); |
| for (ArtifactToken token : extractTokensFromQuery(chStmt, branch)) { |
| guidToToken.put(token.getGuid(), token); |
| } |
| } finally { |
| chStmt.close(); |
| } |
| } |
| return guidToToken; |
| } |
| |
| public static ArtifactToken getArtifactTokenFromId(BranchId branch, ArtifactId artifactId) { |
| return getArtifactEndpoint(branch).getArtifactToken(artifactId); |
| } |
| |
| public static Map<String, ArtifactToken> getArtifactTokensFromIds(BranchId branch, Collection<String> artIds) { |
| Map<String, ArtifactToken> guidToToken = new HashMap<>(); |
| if (!artIds.isEmpty()) { |
| JdbcStatement chStmt = ConnectionHandler.getStatement(); |
| try { |
| String query = artifactTokenByArtIdQuery.replaceFirst("ART_IDS_HERE", |
| org.eclipse.osee.framework.jdk.core.util.Collections.toString(",", artIds)); |
| chStmt.runPreparedQuery(query, branch); |
| for (ArtifactToken token : extractTokensFromQuery(chStmt, branch)) { |
| guidToToken.put(token.getIdString(), token); |
| } |
| } finally { |
| chStmt.close(); |
| } |
| } |
| return guidToToken; |
| } |
| |
| /** |
| * Quick way to determine if artifact has changed. This first compares the number of current attributes against db, |
| * if not equal, return true. Then compares number of current relations against db, if not equal, true.<br/> |
| * <br/> |
| * NOTE: This is a fast check, but could be wrong if attribute/relation was added and another deleted. Use |
| * isArtifactChangedViaTransaction if you want to ensure accuracy. |
| */ |
| public static boolean isArtifactChangedViaEntries(Artifact artifact) { |
| JdbcClient jdbcClient = ConnectionHandler.getJdbcClient(); |
| int attrCount = |
| jdbcClient.fetch(-1, "select count(*) from OSEE_ATTRIBUTE attr, osee_txs txs where attr.art_id = ? and " // |
| + "txs.GAMMA_ID = ATTR.GAMMA_ID and txs.BRANCH_ID = ? and txs.TX_CURRENT = 1", artifact, |
| artifact.getBranch()); |
| if (artifact.getAttributes().size() != attrCount) { |
| return true; |
| } |
| int relCount = jdbcClient.fetch(-1, |
| "select count(*) from OSEE_RELATION_LINK rel, osee_txs txs where (rel.A_ART_ID = ? or rel.B_ART_ID = ?) " // |
| + "and txs.GAMMA_ID = rel.GAMMA_ID and txs.BRANCH_ID = ? and txs.TX_CURRENT = 1", |
| artifact, artifact, artifact.getBranch()); |
| if (!artifact.isHistorical() && artifact.getRelationsAll(DeletionFlag.EXCLUDE_DELETED).size() != relCount) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Long way to determine if artifact has changed. Return true if loaded transaction is different than database |
| * transaction. This is 100% accurate, but may take longer to compute. Use isArtifactChangedViaEntries if just quick |
| * check is desired. |
| */ |
| public static boolean isArtifactChangedViaTransaction(Artifact artifact) { |
| JdbcClient jdbcClient = ConnectionHandler.getJdbcClient(); |
| String query = |
| "select distinct transaction_id from (select txs.transaction_id from osee_artifact art, OSEE_RELATION_LINK rel, " + // |
| "osee_txs txs, osee_tx_details txd where art.art_id = ? and " + // |
| // check for relation transactions |
| "(art.art_id = rel.A_ART_ID or art.art_id = rel.B_ART_ID) and rel.GAMMA_ID = txs.gamma_id and txs.TRANSACTION_ID = txd.TRANSACTION_ID " + // |
| "and txs.BRANCH_ID = ? " + // |
| "union all " + // |
| // union attribute transactions |
| "select txs.transaction_id from osee_artifact art, osee_attribute attr, " + // |
| "osee_txs txs, osee_tx_details txd where art.art_id = ? and " + // |
| "art.art_id = attr.art_id and attr.GAMMA_ID = txs.gamma_id and txs.TRANSACTION_ID = txd.TRANSACTION_ID " + // |
| "and txs.BRANCH_ID = ?) att_alias " // |
| // order by latest transaction |
| + "order by transaction_id desc "; |
| long transactionId = jdbcClient.fetch(-1L, query, artifact, artifact.getBranch(), artifact, artifact.getBranch()); |
| return !artifact.getTransaction().getId().equals(transactionId); |
| } |
| |
| private static ArtifactEndpoint getArtifactEndpoint(BranchId branch) { |
| return ServiceUtil.getOseeClient().getArtifactEndpoint(branch); |
| } |
| |
| private static Artifact getOrCheckArtifact(QueryType queryType, Collection<Artifact> artifacts) { |
| if (queryType.equals(QueryType.CHECK)) { |
| return org.eclipse.osee.framework.jdk.core.util.Collections.oneOrSentinel(artifacts, null); |
| } |
| return org.eclipse.osee.framework.jdk.core.util.Collections.exactlyOne(artifacts); |
| } |
| } |