diff options
author | Roberto E. Escobar | 2013-07-16 03:18:44 +0000 |
---|---|---|
committer | Roberto E. Escobar | 2013-09-17 23:28:56 +0000 |
commit | 46b4f19063bd42368afd178eb90436381bc9582b (patch) | |
tree | 151a749a1a71185753a3fbf67a0c9cb21d482159 | |
parent | 361e47e07c06baaaffdc32d0c7350af13e00a5be (diff) | |
download | org.eclipse.osee-46b4f19063bd42368afd178eb90436381bc9582b.tar.gz org.eclipse.osee-46b4f19063bd42368afd178eb90436381bc9582b.tar.xz org.eclipse.osee-46b4f19063bd42368afd178eb90436381bc9582b.zip |
feature[ats_7SNLZ]: Create RelationManager
Change-Id: I635d0a9c92ff814dd65a0112c0ff3cd54ec364dc
65 files changed, 4529 insertions, 218 deletions
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/InternalTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/InternalTestSuite.java index d80e8c767d3..8ed221c763d 100644 --- a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/InternalTestSuite.java +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/InternalTestSuite.java @@ -13,6 +13,7 @@ package org.eclipse.osee.orcs.core.internal; import org.eclipse.osee.orcs.core.internal.artifact.ArtifactTestSuite; import org.eclipse.osee.orcs.core.internal.attribute.AttributeTestSuite; import org.eclipse.osee.orcs.core.internal.branch.BranchTestSuite; +import org.eclipse.osee.orcs.core.internal.graph.GraphTestSuite; import org.eclipse.osee.orcs.core.internal.loader.LoaderTestSuite; import org.eclipse.osee.orcs.core.internal.proxy.ProxyTestSuite; import org.eclipse.osee.orcs.core.internal.relation.RelationTestSuite; @@ -31,6 +32,7 @@ import org.junit.runners.Suite; ArtifactTestSuite.class, AttributeTestSuite.class, BranchTestSuite.class, + GraphTestSuite.class, LoaderTestSuite.class, ProxyTestSuite.class, RelationTestSuite.class, diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphTestSuite.java new file mode 100644 index 00000000000..ebdae56b324 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphTestSuite.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.orcs.core.internal.graph.impl.GraphImplTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author Roberto E. Escobar + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({GraphImplTestSuite.class, GraphUtilTest.class}) +public class GraphTestSuite { + // Test Suite +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtilTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtilTest.java new file mode 100644 index 00000000000..5ff98dfac56 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtilTest.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.enums.CoreBranches; +import org.eclipse.osee.framework.core.exception.OseeArgumentException; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; + +/** + * Test Case for {@link GraphUtil} + * + * @author Megumi Telles + */ +public class GraphUtilTest { + + private static final IOseeBranch BRANCH = CoreBranches.COMMON; + private static final int TRANSACTION_ID = 231214214; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private OrcsSession session; + @Mock private GraphData graph; + // @formatter:on + + private GraphProvider provider; + + @Before + public void setUp() { + initMocks(this); + provider = GraphUtil.asProvider(graph); + + when(graph.getBranch()).thenReturn(BRANCH); + when(graph.getTransaction()).thenReturn(TRANSACTION_ID); + } + + @Test + public void testAsProviderNullBranch() throws OseeCoreException { + assertNotNull(provider); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("branch cannot be null - Invalid branch - can't provide graph"); + provider.getGraph(session, null, TRANSACTION_ID); + } + + @Test + public void testAsProviderBranchNotSame() throws OseeCoreException { + assertNotNull(provider); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("Invalid branch - Graph's branch[Common] does not equals requested branch[System Root Branch]"); + provider.getGraph(session, CoreBranches.SYSTEM_ROOT, TRANSACTION_ID); + } + + @Test + public void testAsProviderTxIdNotSame() throws OseeCoreException { + assertNotNull(provider); + + int txId = 123456789; + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("Invalid transactionId - Graph's transactionId[231214214] does not equals requested transactionId[123456789]"); + provider.getGraph(session, BRANCH, txId); + } + + @Test + public void testAsProviderGetName() throws OseeCoreException { + assertNotNull(provider); + assertEquals(graph, provider.getGraph(session, BRANCH, TRANSACTION_ID)); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImplTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImplTest.java new file mode 100644 index 00000000000..be9c1d7e3a2 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImplTest.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.TokenFactory; +import org.eclipse.osee.framework.core.enums.CoreBranches; +import org.eclipse.osee.framework.core.exception.OseeArgumentException; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.ds.ArtifactData; +import org.eclipse.osee.orcs.core.ds.AttributeData; +import org.eclipse.osee.orcs.core.ds.LoadDescription; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.internal.artifact.Artifact; +import org.eclipse.osee.orcs.core.internal.artifact.ArtifactFactory; +import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilder; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.graph.GraphProvider; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationNodeAdjacencies; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; + +/** + * Test Case for @{link GraphBuilderImpl} + * + * @author Megumi Telles + */ +public class GraphBuilderImplTest { + + private static final IRelationType TYPE_1 = TokenFactory.createRelationType(123456789L, "TYPE_1"); + private static final IOseeBranch BRANCH = CoreBranches.COMMON; + private static final int TRANSACTION_ID = 231214214; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private Log logger; + @Mock private ArtifactFactory artifactFactory; + @Mock private AttributeFactory attributeFactory; + @Mock private RelationFactory relationFactory; + + @Mock private OrcsSession session; + @Mock private GraphProvider graphProvider; + @Mock private GraphData graphData; + + @Mock private LoadDescription description; + + @Mock private ArtifactData artifactData; + @Mock private AttributeData attributeData; + @Mock private RelationData relationData; + + @Mock private Artifact artifact; + @Mock private Artifact container; + @Mock private Relation relation; + + // @formatter:on + + private GraphBuilder builder; + + private final RelationNodeAdjacencies adjacencies = new RelationNodeAdjacencies(); + + @Before + public void setUp() throws Exception { + initMocks(this); + + builder = new GraphBuilderImpl(logger, artifactFactory, attributeFactory, relationFactory, graphProvider); + + when(description.getSession()).thenReturn(session); + when(description.getBranch()).thenReturn(BRANCH); + when(description.getTransaction()).thenReturn(TRANSACTION_ID); + when(graphProvider.getGraph(session, BRANCH, TRANSACTION_ID)).thenReturn(graphData); + + when(relationFactory.createRelationContainer()).thenReturn(adjacencies); + when(relationFactory.createRelation(relationData)).thenReturn(relation); + when(relation.getRelationType()).thenReturn(TYPE_1); + + when(attributeData.getArtifactId()).thenReturn(60); + } + + @Test + public void testGraphNull() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("graph cannot be null"); + + builder.onLoadStart(); + builder.onData(artifactData); + builder.onData(attributeData); + builder.onData(relationData); + builder.onLoadEnd(); + } + + @Test + public void testOnLoadDescription() throws OseeCoreException { + builder.onLoadStart(); + builder.onLoadDescription(description); + builder.onLoadEnd(); + + verify(description).getBranch(); + verify(description).getTransaction(); + } + + @Test + public void testGetNodeOrAdjanciesNull() throws OseeCoreException { + when(graphData.getNode(artifactData)).thenReturn(null); + when(artifactFactory.createArtifact(artifactData)).thenReturn(artifact); + + when(graphData.getNode(60)).thenReturn(null); + when(graphData.getNode(relationData)).thenReturn(null); + + builder.onLoadStart(); + builder.onLoadDescription(description); + + builder.onData(artifactData); + verify(graphData).addNode(artifact); + verify(artifactFactory).createArtifact(artifactData); + verify(relationFactory, times(1)).createRelationContainer(); + + reset(relationFactory); + when(relationFactory.createRelationContainer()).thenReturn(adjacencies); + when(relationFactory.createRelation(relationData)).thenReturn(relation); + + builder.onData(attributeData); + verify(logger).warn("Orphaned attribute detected - data[%s]", attributeData); + + builder.onData(relationData); + verify(relationFactory, times(2)).createRelationContainer(); + + builder.onLoadEnd(); + verify(relationFactory, times(1)).createRelation(relationData); + } + + @Test + public void testOnData() throws OseeCoreException { + when(graphData.getNode(artifactData)).thenReturn(artifact); + when(graphData.getNode(60)).thenReturn(container); + when(graphData.getAdjacencies(59)).thenReturn(adjacencies); + + builder.onLoadStart(); + builder.onLoadDescription(description); + builder.onData(artifactData); + builder.onData(attributeData); + builder.onData(relationData); + builder.onLoadEnd(); + + verify(attributeFactory).createAttribute(container, attributeData); + verify(relationFactory).createRelation(relationData); + + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImplTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImplTest.java new file mode 100644 index 00000000000..2afc6c8f996 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImplTest.java @@ -0,0 +1,290 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Allocation__Component; +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.CodeRequirement_CodeUnit; +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Child; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.Collection; +import java.util.List; +import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.Branch; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.core.ds.ArtifactData; +import org.eclipse.osee.orcs.core.ds.AttributeData; +import org.eclipse.osee.orcs.core.ds.LoadDescription; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.internal.artifact.Artifact; +import org.eclipse.osee.orcs.core.internal.artifact.ArtifactFactory; +import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.graph.GraphProvider; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationNodeAdjacencies; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * @author Megumi Telles + */ +public class GraphDataImplTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private Log logger; + @Mock private Branch branch; + @Mock private ArtifactFactory artifactFactory; + @Mock private AttributeFactory attributeFactory; + @Mock private RelationFactory relationFactory; + + @Mock private GraphProvider graphProvider; + @Mock private GraphData graphData; + + @Mock private LoadDescription description; + + @Mock private ArtifactData artifactData; + @Mock private ArtifactData artifactData1; + @Mock private ArtifactData artifactData2; + @Mock private AttributeData attributeData; + @Mock private AttributeData attributeData1; + @Mock private AttributeData attributeData2; + @Mock private RelationData relationData; + + @Mock private Artifact artifact; + @Mock private Artifact artifact1; + @Mock private Artifact artifact2; + @Mock private Artifact container; + @Mock private Artifact container1; + @Mock private Artifact container2; + + @Mock private Relation relation; + @Mock private Relation relation1; + @Mock private Relation relation2; + @Mock private Relation relation3; + + // @formatter:on + + private GraphDataImpl graph; + private static final int TRANSACTION_ID = 231214214; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + graph = new GraphDataImpl(branch, TRANSACTION_ID); + } + + @Test + public void testGetBranch() { + assertEquals(branch, graph.getBranch()); + } + + @Test + public void testGetTransaction() { + assertEquals(TRANSACTION_ID, graph.getTransaction()); + } + + @Test + public void testAddNodeArtifact() throws OseeCoreException { + when(artifact.getLocalId()).thenReturn(10); + when(artifact.getBranch()).thenReturn(branch); + when(artifactData.getLocalId()).thenReturn(10); + + graph.addNode(artifact); + assertEquals(artifact, graph.getNode(10)); + assertEquals(artifact, graph.getNode(artifactData)); + } + + @Test + public void testAddNodeAttribute() throws OseeCoreException { + when(container.getLocalId()).thenReturn(11); + when(container.getBranch()).thenReturn(branch); + when(attributeData.getLocalId()).thenReturn(11); + + graph.addNode(container); + assertEquals(container, graph.getNode(11)); + assertEquals(container, graph.getNode(attributeData)); + } + + @Test + public void testGetNodeId() throws OseeCoreException { + when(artifact1.getLocalId()).thenReturn(20); + when(artifact2.getLocalId()).thenReturn(21); + when(container1.getLocalId()).thenReturn(30); + when(container2.getLocalId()).thenReturn(31); + + when(artifact1.getBranch()).thenReturn(branch); + when(artifact2.getBranch()).thenReturn(branch); + when(container1.getBranch()).thenReturn(branch); + when(container2.getBranch()).thenReturn(branch); + + graph.addNode(artifact1); + graph.addNode(artifact2); + graph.addNode(container1); + graph.addNode(container2); + + verify(artifact1).getLocalId(); + verify(artifact2).getLocalId(); + verify(container1).getLocalId(); + verify(container2).getLocalId(); + + assertEquals(artifact1, graph.getNode(20)); + assertEquals(artifact2, graph.getNode(21)); + assertEquals(container1, graph.getNode(30)); + assertEquals(container2, graph.getNode(31)); + } + + @Test + public void testGetNodeData() throws OseeCoreException { + when(artifact1.getLocalId()).thenReturn(20); + when(artifact2.getLocalId()).thenReturn(21); + when(container1.getLocalId()).thenReturn(30); + when(container2.getLocalId()).thenReturn(31); + + when(artifactData1.getLocalId()).thenReturn(20); + when(artifactData2.getLocalId()).thenReturn(21); + when(attributeData1.getLocalId()).thenReturn(30); + when(attributeData2.getLocalId()).thenReturn(31); + + when(artifact1.getBranch()).thenReturn(branch); + when(artifact2.getBranch()).thenReturn(branch); + when(container1.getBranch()).thenReturn(branch); + when(container2.getBranch()).thenReturn(branch); + + graph.addNode(artifact1); + graph.addNode(artifact2); + graph.addNode(container1); + graph.addNode(container2); + + verify(artifact1).getLocalId(); + verify(artifact2).getLocalId(); + verify(container1).getLocalId(); + verify(container2).getLocalId(); + + assertEquals(artifact1, graph.getNode(artifactData1)); + assertEquals(artifact2, graph.getNode(artifactData2)); + assertEquals(container1, graph.getNode(attributeData1)); + assertEquals(container2, graph.getNode(attributeData2)); + } + + @Test + public void testRemoveNode() throws OseeCoreException { + when(artifact1.getLocalId()).thenReturn(20); + when(artifact2.getLocalId()).thenReturn(21); + when(container1.getLocalId()).thenReturn(30); + when(container2.getLocalId()).thenReturn(31); + + when(artifactData1.getLocalId()).thenReturn(20); + when(artifactData2.getLocalId()).thenReturn(21); + when(attributeData1.getLocalId()).thenReturn(30); + when(attributeData2.getLocalId()).thenReturn(31); + + when(artifact1.getBranch()).thenReturn(branch); + when(artifact2.getBranch()).thenReturn(branch); + when(container1.getBranch()).thenReturn(branch); + when(container2.getBranch()).thenReturn(branch); + + graph.addNode(artifact1); + graph.addNode(artifact2); + graph.addNode(container1); + graph.addNode(container2); + + verify(artifact1).getLocalId(); + verify(artifact2).getLocalId(); + verify(container1).getLocalId(); + verify(container2).getLocalId(); + + assertEquals(artifact1, graph.removeNode(artifactData1)); + assertNull(graph.getNode(artifactData1)); + assertEquals(artifact2, graph.removeNode(artifact2)); + assertNull(graph.getNode(artifactData2)); + assertEquals(container1, graph.removeNode(30)); + assertNull(graph.getNode(attributeData1)); + assertEquals(container2, graph.removeNode(container2)); + assertNull(graph.getNode(attributeData2)); + } + + @Test + public void testAddAdjacencies() throws OseeCoreException { + RelationNodeAdjacencies adjacencies = new RelationNodeAdjacencies(); + RelationNodeAdjacencies adj; + Collection<Relation> all; + + when(artifact1.getLocalId()).thenReturn(20); + when(artifact2.getLocalId()).thenReturn(21); + + adjacencies.add(Allocation__Component.getGuid(), relation1); + graph.addAdjacencies(artifact1, adjacencies); + adj = graph.getAdjacencies(20); + List<Relation> list = adj.getList(Allocation__Component, DeletionFlag.EXCLUDE_DELETED); + assertFalse(list.isEmpty()); + assertTrue(list.size() == 1); + + adjacencies.add(CodeRequirement_CodeUnit.getGuid(), relation2); + graph.addAdjacencies(20, adjacencies); + adj = graph.getAdjacencies(artifact1); + all = adj.getAll(); + assertFalse(all.isEmpty()); + assertTrue(all.size() == 2); + assertTrue(adj.getList(Allocation__Component, DeletionFlag.EXCLUDE_DELETED).size() == 1); + assertTrue(adj.getList(CodeRequirement_CodeUnit, DeletionFlag.EXCLUDE_DELETED).size() == 1); + + adjacencies.add(Default_Hierarchical__Child.getGuid(), relation3); + graph.addAdjacencies(21, adjacencies); + adj = graph.getAdjacencies(artifact2); + all = adj.getAll(); + assertFalse(all.isEmpty()); + assertTrue(all.size() == 3); + assertTrue(adj.getList(Allocation__Component, DeletionFlag.EXCLUDE_DELETED).size() == 1); + assertTrue(adj.getList(CodeRequirement_CodeUnit, DeletionFlag.EXCLUDE_DELETED).size() == 1); + assertTrue(adj.getList(Default_Hierarchical__Child, DeletionFlag.EXCLUDE_DELETED).size() == 1); + } + + @Test + public void testRemoveAdjacencies() { + RelationNodeAdjacencies adjacencies = new RelationNodeAdjacencies(); + RelationNodeAdjacencies adj; + + when(artifact1.getLocalId()).thenReturn(20); + when(artifact2.getLocalId()).thenReturn(21); + + adjacencies.add(Allocation__Component.getGuid(), relation1); + adjacencies.add(CodeRequirement_CodeUnit.getGuid(), relation2); + adjacencies.add(Default_Hierarchical__Child.getGuid(), relation3); + + graph.addAdjacencies(artifact1, adjacencies); + graph.addAdjacencies(20, adjacencies); + graph.addAdjacencies(artifact2, adjacencies); + + graph.removeAdjacencies(artifact2); + adj = graph.getAdjacencies(21); + assertNull(adj); + + graph.removeAdjacencies(20); + adj = graph.getAdjacencies(20); + assertNull(adj); + + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphImplTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphImplTestSuite.java new file mode 100644 index 00000000000..5e2daaf1f5f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphImplTestSuite.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author Roberto E. Escobar + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({GraphBuilderImplTest.class, GraphDataImplTest.class}) +public class GraphImplTestSuite { + // Test Suite +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImplTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImplTest.java index dcc9b0e3a32..fc37cb8e2f6 100644 --- a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImplTest.java +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImplTest.java @@ -40,6 +40,7 @@ import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; import org.eclipse.osee.orcs.core.internal.proxy.ExternalArtifactManager; import org.eclipse.osee.orcs.core.internal.relation.RelationContainer; import org.eclipse.osee.orcs.core.internal.relation.RelationContainerImpl; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; import org.eclipse.osee.orcs.data.RelationTypes; import org.junit.Assert; import org.junit.Before; @@ -62,6 +63,7 @@ public class ArtifactBuilderImplTest { @Mock private ExternalArtifactManager proxyFactory; @Mock private ArtifactFactory artifactFactory; @Mock private AttributeFactory attributeFactory; + @Mock private RelationFactory relationFactory; @Mock private OrcsSession session; @Mock private Artifact artifact; @@ -74,8 +76,8 @@ public class ArtifactBuilderImplTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - builder = new ArtifactBuilderImpl(logger, proxyFactory, artifactFactory, attributeFactory, session); - + builder = + new ArtifactBuilderImpl(logger, proxyFactory, artifactFactory, attributeFactory, relationFactory, session); } @Test @@ -105,6 +107,7 @@ public class ArtifactBuilderImplTest { verify(logger).warn("Orphaned attribute detected - [%s]", attributeData); } + @Ignore @Test public void testRelationCountMatches() throws OseeCoreException { RelationTypes cache = createAndPopulate(); @@ -142,18 +145,22 @@ public class ArtifactBuilderImplTest { private void doSetup(List<RelationData> datas, Map<Integer, RelationContainer> containers) throws OseeCoreException { for (RelationData data : datas) { - Artifact artifact = Mockito.mock(Artifact.class); - ArtifactData artData = Mockito.mock(ArtifactData.class); - int id = data.getParentId(); - when(artifactFactory.createArtifact(artData)).thenReturn(artifact); - when(artifact.getLocalId()).thenReturn(id); - when(artData.getLocalId()).thenReturn(id); + createAndDispatchArtifact(containers, data.getArtIdA()); + createAndDispatchArtifact(containers, data.getArtIdB()); + } + } - RelationContainer container = containers.get(id); - when(artifact.getRelationContainer()).thenReturn(container); + private void createAndDispatchArtifact(Map<Integer, RelationContainer> containers, int id) throws OseeCoreException { + Artifact artifact = Mockito.mock(Artifact.class); + ArtifactData artData = Mockito.mock(ArtifactData.class); + when(artifactFactory.createArtifact(artData)).thenReturn(artifact); + when(artifact.getLocalId()).thenReturn(id); + when(artData.getLocalId()).thenReturn(id); - builder.onData(artData); - } + RelationContainer container = containers.get(id); + when(artifact.getRelationContainer()).thenReturn(container); + + builder.onData(artData); } private void checkRelatedArtifacts(RelationContainer relationContainer, RelationSide side, int... expected) { @@ -206,29 +213,29 @@ public class ArtifactBuilderImplTest { List<RelationData> datas = new ArrayList<RelationData>(); RelationCsvReader csvReader = new RelationCsvReader(datas); // #ArtIdA ArtIdB BranchId GammaId ModType Rationale RelationId RelationTypeId - csvReader.onRow(1, 1, 2, 1, 1L, ModificationType.NEW, "yay", 1, 1L); - csvReader.onRow(1, 1, 3, 1, 1L, ModificationType.NEW, "yay", 2, 1L); - csvReader.onRow(1, 1, 4, 1, 1L, ModificationType.NEW, "yay", 3, 1L); - csvReader.onRow(1, 1, 5, 1, 1L, ModificationType.NEW, "yay", 4, 1L); - csvReader.onRow(1, 1, 6, 1, 1L, ModificationType.NEW, "yay", 5, 1L); - csvReader.onRow(1, 1, 7, 1, 1L, ModificationType.NEW, "yay", 6, 1L); - csvReader.onRow(1, 1, 8, 1, 1L, ModificationType.NEW, "yay", 7, 1L); - csvReader.onRow(1, 1, 9, 1, 1L, ModificationType.NEW, "yay", 8, 1L); - csvReader.onRow(1, 1, 10, 1, 1L, ModificationType.NEW, "yay", 9, 1L); - csvReader.onRow(3, 3, 11, 1, 1L, ModificationType.NEW, "yay", 10, 1L); - csvReader.onRow(3, 1, 3, 1, 1L, ModificationType.NEW, "yay", 10, 1L); - csvReader.onRow(3, 3, 12, 1, 1L, ModificationType.NEW, "yay", 11, 1L); - csvReader.onRow(3, 3, 13, 1, 1L, ModificationType.NEW, "yay", 12, 1L); - csvReader.onRow(3, 3, 14, 1, 1L, ModificationType.NEW, "yay", 13, 1L); - csvReader.onRow(3, 3, 15, 1, 1L, ModificationType.NEW, "yay", 14, 1L); - csvReader.onRow(3, 3, 16, 1, 1L, ModificationType.NEW, "yay", 15, 1L); - csvReader.onRow(4, 4, 17, 1, 1L, ModificationType.NEW, "yay", 16, 1L); - csvReader.onRow(4, 4, 18, 1, 1L, ModificationType.NEW, "yay", 17, 1L); - csvReader.onRow(4, 4, 19, 1, 1L, ModificationType.NEW, "yay", 18, 1L); - csvReader.onRow(4, 4, 20, 1, 1L, ModificationType.NEW, "yay", 19, 1L); - csvReader.onRow(4, 4, 21, 1, 1L, ModificationType.NEW, "yay", 20, 1L); - csvReader.onRow(4, 4, 22, 1, 1L, ModificationType.NEW, "yay", 21, 1L); - csvReader.onRow(4, 4, 2, 1, 1L, ModificationType.NEW, "yay", 21, 1L); + csvReader.onRow(1, 2, 1, 1L, ModificationType.NEW, "yay", 1, 1L); + csvReader.onRow(1, 3, 1, 1L, ModificationType.NEW, "yay", 2, 1L); + csvReader.onRow(1, 4, 1, 1L, ModificationType.NEW, "yay", 3, 1L); + csvReader.onRow(1, 5, 1, 1L, ModificationType.NEW, "yay", 4, 1L); + csvReader.onRow(1, 6, 1, 1L, ModificationType.NEW, "yay", 5, 1L); + csvReader.onRow(1, 7, 1, 1L, ModificationType.NEW, "yay", 6, 1L); + csvReader.onRow(1, 8, 1, 1L, ModificationType.NEW, "yay", 7, 1L); + csvReader.onRow(1, 9, 1, 1L, ModificationType.NEW, "yay", 8, 1L); + csvReader.onRow(1, 10, 1, 1L, ModificationType.NEW, "yay", 9, 1L); + csvReader.onRow(3, 11, 1, 1L, ModificationType.NEW, "yay", 10, 1L); + csvReader.onRow(1, 3, 1, 1L, ModificationType.NEW, "yay", 10, 1L); + csvReader.onRow(3, 12, 1, 1L, ModificationType.NEW, "yay", 11, 1L); + csvReader.onRow(3, 13, 1, 1L, ModificationType.NEW, "yay", 12, 1L); + csvReader.onRow(3, 14, 1, 1L, ModificationType.NEW, "yay", 13, 1L); + csvReader.onRow(3, 15, 1, 1L, ModificationType.NEW, "yay", 14, 1L); + csvReader.onRow(3, 16, 1, 1L, ModificationType.NEW, "yay", 15, 1L); + csvReader.onRow(4, 17, 1, 1L, ModificationType.NEW, "yay", 16, 1L); + csvReader.onRow(4, 18, 1, 1L, ModificationType.NEW, "yay", 17, 1L); + csvReader.onRow(4, 19, 1, 1L, ModificationType.NEW, "yay", 18, 1L); + csvReader.onRow(4, 20, 1, 1L, ModificationType.NEW, "yay", 19, 1L); + csvReader.onRow(4, 21, 1, 1L, ModificationType.NEW, "yay", 20, 1L); + csvReader.onRow(4, 22, 1, 1L, ModificationType.NEW, "yay", 21, 1L); + csvReader.onRow(4, 2, 1, 1L, ModificationType.NEW, "yay", 21, 1L); return datas; } @@ -242,23 +249,22 @@ public class ArtifactBuilderImplTest { public void onRow(Object... row) { //ArtIdA,ArtIdB,BranchId,GammaId,ModType,Rationale,RelationId,RelationTypeId - if (row.length != 9) { + if (row.length != 8) { Assert.assertTrue("Data file is not formatted correctly", false); } VersionData version = mock(VersionData.class); RelationData relationRow = Mockito.mock(RelationData.class); - when(version.getBranchId()).thenReturn((Integer) row[3]); - when(version.getGammaId()).thenReturn((Long) row[4]); - - when(relationRow.getParentId()).thenReturn((Integer) row[0]); - when(relationRow.getArtIdA()).thenReturn((Integer) row[1]); - when(relationRow.getArtIdB()).thenReturn((Integer) row[2]); - when(relationRow.getModType()).thenReturn((ModificationType) row[5]); - when(relationRow.getRationale()).thenReturn((String) row[6]); - when(relationRow.getLocalId()).thenReturn((Integer) row[7]); - when(relationRow.getTypeUuid()).thenReturn((Long) row[8]); + int index = 0; + when(relationRow.getArtIdA()).thenReturn((Integer) row[index++]); + when(relationRow.getArtIdB()).thenReturn((Integer) row[index++]); + when(version.getBranchId()).thenReturn((Integer) row[index++]); + when(version.getGammaId()).thenReturn((Long) row[index++]); + when(relationRow.getModType()).thenReturn((ModificationType) row[index++]); + when(relationRow.getRationale()).thenReturn((String) row[index++]); + when(relationRow.getLocalId()).thenReturn((Integer) row[index++]); + when(relationRow.getTypeUuid()).thenReturn((Long) row[index++]); when(relationRow.getVersion()).thenReturn(version); data.add(relationRow); diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerTest.java new file mode 100644 index 00000000000..79e101890db --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerTest.java @@ -0,0 +1,287 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Parent; +import static org.eclipse.osee.framework.core.enums.DeletionFlag.INCLUDE_DELETED; +import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyCollectionOf; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.data.TokenFactory; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.jdk.core.util.GUID; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationNodeAdjacencies; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; +import org.eclipse.osee.orcs.data.RelationTypes; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Test Case for {@link RelationManagerFactory} + * + * @author Megumi Telles + */ +public class RelationManagerTest { + + private static final IRelationType DEFAULT_HIERARCHY = TokenFactory.createRelationType( + Default_Hierarchical__Parent.getGuid(), Default_Hierarchical__Parent.getName()); + private static final RelationSide IS_PARENT = RelationSide.SIDE_A; + private static final RelationSide IS_CHILD = RelationSide.SIDE_B; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private Log logger; + @Mock private RelationTypes types; + @Mock private RelationFactory relationFactory; + + @Mock private RelationNodeLoader loader; + @Mock private OrcsSession session; + @Mock private GraphData graph; + + @Mock private RelationNode node1; + @Mock private RelationNode node2; + @Mock private RelationNode node3; + @Mock private RelationNode node4; + @Mock private RelationNode node5; + @Mock private RelationNode node6; + + @Mock private Relation relation1; + @Mock private Relation relation2; + @Mock private Relation relation3; + @Mock private Relation relation4; + @Mock private IRelationType relationType; + + @Captor private ArgumentCaptor<Collection<Integer>> captor; + // @formatter:on + + private RelationManager manager; + private Map<Integer, RelationNode> mockDb; + + @Before + public void setUp() throws OseeCoreException { + MockitoAnnotations.initMocks(this); + + String sessionId = GUID.create(); + when(session.getGuid()).thenReturn(sessionId); + + manager = RelationManagerFactory.createRelationManager(logger, types, relationFactory, loader); + + when(loader.loadNodes(eq(session), eq(graph), anyCollectionOf(Integer.class), eq(LoadLevel.FULL))).thenAnswer( + new LoaderAnswer()); + + when(node1.getLocalId()).thenReturn(11); + when(node2.getLocalId()).thenReturn(22); + when(node3.getLocalId()).thenReturn(33); + when(node4.getLocalId()).thenReturn(44); + when(node5.getLocalId()).thenReturn(55); + when(node6.getLocalId()).thenReturn(66); + + when(node1.getName()).thenReturn("z"); + when(node2.getName()).thenReturn("y"); + when(node3.getName()).thenReturn("x"); + when(node4.getName()).thenReturn("w"); + when(node5.getName()).thenReturn("v"); + when(node6.getName()).thenReturn("u"); + + when(node1.getGraph()).thenReturn(graph); + when(node2.getGraph()).thenReturn(graph); + when(node3.getGraph()).thenReturn(graph); + when(node4.getGraph()).thenReturn(graph); + when(node5.getGraph()).thenReturn(graph); + when(node6.getGraph()).thenReturn(graph); + + mockDb = new HashMap<Integer, RelationNode>(); + mockDb.put(11, node1); + mockDb.put(22, node2); + mockDb.put(33, node3); + mockDb.put(44, node4); + mockDb.put(55, node5); + mockDb.put(66, node6); + + when(relation1.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation1.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(22); + when(relation1.getRelationType()).thenReturn(DEFAULT_HIERARCHY); + when(relation1.getRationale()).thenReturn("rationale on relation1"); + + when(relation2.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation2.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(33); + when(relation2.getRelationType()).thenReturn(DEFAULT_HIERARCHY); + when(relation2.getRationale()).thenReturn("rationale on relation2"); + + when(relation3.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(44); + when(relation3.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(11); + when(relation3.getRelationType()).thenReturn(DEFAULT_HIERARCHY); + when(relation3.getRationale()).thenReturn("rationale on relation3"); + + when(relation4.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation4.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(55); + when(relation4.getRelationType()).thenReturn(DEFAULT_HIERARCHY); + when(relation4.getRationale()).thenReturn("rationale on relation4"); + + setupAdjacencies(node1, relation1, relation2, relation3, relation4); + setupAdjacencies(node2, relation1); + setupAdjacencies(node3, relation1); + setupAdjacencies(node4, relation3); + setupAdjacencies(node5, relation4); + setupAdjacencies(node6); + + when(types.getByUuid(DEFAULT_HIERARCHY.getGuid())).thenReturn(relationType); + when(types.getDefaultOrderTypeGuid(DEFAULT_HIERARCHY)).thenReturn(LEXICOGRAPHICAL_DESC.getGuid()); + when(types.getDefaultOrderTypeGuid(relationType)).thenReturn(LEXICOGRAPHICAL_DESC.getGuid()); + } + + private void setupAdjacencies(RelationNode node, Relation... relations) throws OseeCoreException { + RelationNodeAdjacencies adjacents = new RelationNodeAdjacencies(); + graph.addAdjacencies(node, adjacents); + when(graph.getAdjacencies(node)).thenReturn(adjacents); + for (Relation relation : relations) { + adjacents.add(relation.getRelationType().getGuid(), relation); + } + } + + @Test + public void testGetRelatedOnSideA() throws OseeCoreException { + ResultSet<RelationNode> nodes = manager.getRelated(session, graph, DEFAULT_HIERARCHY, node1, IS_PARENT); + + verify(loader).loadNodes(eq(session), eq(graph), captor.capture(), eq(LoadLevel.FULL)); + + Collection<Integer> toLoad = captor.getValue(); + assertEquals(3, toLoad.size()); + Iterator<Integer> iterator = toLoad.iterator(); + assertEquals(22, iterator.next().intValue()); + assertEquals(33, iterator.next().intValue()); + assertEquals(55, iterator.next().intValue()); + + assertEquals(3, nodes.size()); + Iterator<RelationNode> iterator2 = nodes.iterator(); + assertEquals(node2, iterator2.next()); + assertEquals(node3, iterator2.next()); + assertEquals(node5, iterator2.next()); + } + + @Test + public void testGetRelatedOnSideB() throws OseeCoreException { + ResultSet<RelationNode> readables = manager.getRelated(session, graph, DEFAULT_HIERARCHY, node1, IS_CHILD); + + verify(loader).loadNodes(eq(session), eq(graph), captor.capture(), eq(LoadLevel.FULL)); + + Collection<Integer> toLoad = captor.getValue(); + assertEquals(1, toLoad.size()); + Iterator<Integer> iterator = toLoad.iterator(); + assertEquals(44, iterator.next().intValue()); + + assertEquals(1, readables.size()); + Iterator<RelationNode> iterator2 = readables.iterator(); + assertEquals(node4, iterator2.next()); + } + + @Test + public void testGetParent() throws OseeCoreException { + RelationNode actual = manager.getParent(session, graph, node1); + assertEquals(node4, actual); + } + + @Test + public void testGetChildren() throws OseeCoreException { + ResultSet<RelationNode> actual = manager.getChildren(session, graph, node1); + + assertEquals(3, actual.size()); + Iterator<RelationNode> iterator = actual.iterator(); + assertEquals(node2, iterator.next()); + assertEquals(node3, iterator.next()); + assertEquals(node5, iterator.next()); + } + + @Test + public void testGetRationale() throws OseeCoreException { + String rationale = manager.getRationale(session, graph, node4, DEFAULT_HIERARCHY, node1); + assertEquals("rationale on relation3", rationale); + } + + @Test + public void testGetRelatedCount() throws OseeCoreException { + int actual = manager.getRelatedCount(session, graph, DEFAULT_HIERARCHY, node1, IS_PARENT); + assertEquals(3, actual); + + when(relation2.isDeleted()).thenReturn(true); + + int actual2 = manager.getRelatedCount(session, graph, DEFAULT_HIERARCHY, node1, IS_PARENT); + assertEquals(2, actual2); + + int actual3 = manager.getRelatedCount(session, graph, DEFAULT_HIERARCHY, node1, IS_PARENT, INCLUDE_DELETED); + assertEquals(3, actual3); + } + + @Test + public void testAreRelated() throws OseeCoreException { + assertTrue(manager.areRelated(session, graph, node4, DEFAULT_HIERARCHY, node1)); + + assertTrue(manager.areRelated(session, graph, node1, DEFAULT_HIERARCHY, node2)); + assertTrue(manager.areRelated(session, graph, node1, DEFAULT_HIERARCHY, node3)); + assertTrue(manager.areRelated(session, graph, node1, DEFAULT_HIERARCHY, node5)); + + assertFalse(manager.areRelated(session, graph, node1, DEFAULT_HIERARCHY, node4)); + assertFalse(manager.areRelated(session, graph, node2, DEFAULT_HIERARCHY, node1)); + assertFalse(manager.areRelated(session, graph, node3, DEFAULT_HIERARCHY, node1)); + assertFalse(manager.areRelated(session, graph, node5, DEFAULT_HIERARCHY, node1)); + + assertFalse(manager.areRelated(session, graph, node4, DEFAULT_HIERARCHY, node2)); + assertFalse(manager.areRelated(session, graph, node4, DEFAULT_HIERARCHY, node3)); + assertFalse(manager.areRelated(session, graph, node4, DEFAULT_HIERARCHY, node5)); + } + + private class LoaderAnswer implements Answer<Iterable<RelationNode>> { + + @SuppressWarnings("unchecked") + @Override + public Iterable<RelationNode> answer(InvocationOnMock invocation) throws Throwable { + List<RelationNode> artLoaded = new ArrayList<RelationNode>(); + + Collection<Integer> toLoad = (Collection<Integer>) invocation.getArguments()[2]; + artLoaded.clear(); + for (Integer item : toLoad) { + RelationNode node = mockDb.get(item); + if (node != null) { + artLoaded.add(node); + } + } + return ResultSets.newResultSet(artLoaded); + } + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTest.java new file mode 100644 index 00000000000..b1df7111ed8 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTest.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.enums.ModificationType; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.Branch; +import org.eclipse.osee.orcs.core.ds.OrcsData; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.internal.util.ValueProvider; +import org.eclipse.osee.orcs.data.RelationTypes; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** + * Test Case for {@link Relation} + * + * @author Roberto E. Escobar + */ +public class RelationTest { + + private static final long TYPE_UUID = 123124514L; + + // @formatter:off + @Mock private ValueProvider<Branch, OrcsData> branchProvider; + @Mock private RelationTypes relationTypes; + @Mock RelationData data; + // @formatter:on + + private Relation relation; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + relation = new Relation(relationTypes, data, branchProvider); + + when(data.getTypeUuid()).thenReturn(TYPE_UUID); + } + + @Test + public void testDelete() { + assertFalse(relation.isDirty()); + relation.delete(); + + verify(data).setModType(ModificationType.DELETED); + assertTrue(relation.isDirty()); + } + + @Test + public void testGetSetRationale() { + assertFalse(relation.isDirty()); + Mockito.when(data.getRationale()).thenReturn("rationale"); + + String rationale = relation.getRationale(); + + verify(data).getRationale(); + assertEquals("rationale", rationale); + assertFalse(relation.isDirty()); + + relation.setRationale("new rationale"); + verify(data).setRationale("new rationale"); + verify(data).setModType(ModificationType.MODIFIED); + assertTrue(relation.isDirty()); + } + + @Test + public void testGetBranch() throws OseeCoreException { + relation.getBranch(); + verify(branchProvider).get(); + } + + @Test + public void testGetRelationType() throws OseeCoreException { + relation.getRelationType(); + + verify(relationTypes).getByUuid(TYPE_UUID); + } + + @Test + public void testGetModificationType() { + relation.getModificationType(); + verify(data).getModType(); + } + + @Test + public void testGetOrcsData() { + assertEquals(data, relation.getOrcsData()); + } + + @Test + public void testSetOrcsData() { + relation.setOrcsData(data); + + verify(branchProvider).setOrcsData(data); + } + + @Test + public void testDirty() { + relation.setDirty(); + assertTrue(relation.isDirty()); + + relation.clearDirty(); + assertFalse(relation.isDirty()); + } + + @Test + public void testGetLocalIdForSide() { + when(data.getArtIdOn(RelationSide.SIDE_A)).thenReturn(45); + when(data.getArtIdOn(RelationSide.SIDE_B)).thenReturn(33); + + assertEquals(45, relation.getLocalIdForSide(RelationSide.SIDE_A)); + assertEquals(33, relation.getLocalIdForSide(RelationSide.SIDE_B)); + } + + @Test + public void testIsDeleteD() { + when(data.getModType()).thenReturn(ModificationType.DELETED); + assertTrue(relation.isDeleted()); + + when(data.getModType()).thenReturn(ModificationType.ARTIFACT_DELETED); + assertTrue(relation.isDeleted()); + + when(data.getModType()).thenReturn(ModificationType.MODIFIED); + assertFalse(relation.isDeleted()); + } + + @Test + public void testIsOfType() throws OseeCoreException { + IRelationType type1 = mock(IRelationType.class); + IRelationType type2 = mock(IRelationType.class); + + when(relationTypes.getByUuid(TYPE_UUID)).thenReturn(type1); + + assertTrue(relation.isOfType(type1)); + assertFalse(relation.isOfType(type2)); + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.java index d92a06ce3d9..8d8d34e5239 100644 --- a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.java +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.osee.orcs.core.internal.relation; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationImplTestSuite; import org.eclipse.osee.orcs.core.internal.relation.order.OrderTestSuite; import org.eclipse.osee.orcs.core.internal.relation.sorter.SorterTestSuite; import org.junit.runner.RunWith; @@ -19,7 +20,13 @@ import org.junit.runners.Suite; * @author Roberto E. Escobar */ @RunWith(Suite.class) -@Suite.SuiteClasses({OrderTestSuite.class, SorterTestSuite.class, RelationTypeValidityTest.class}) +@Suite.SuiteClasses({ + RelationImplTestSuite.class, + OrderTestSuite.class, + SorterTestSuite.class, + RelationManagerTest.class, + RelationTest.class, + RelationTypeValidityTest.class}) public class RelationTestSuite { // Test Suite } diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidityTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidityTest.java index 7f1e29ca9cb..e5a4ceae5e8 100644 --- a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidityTest.java +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidityTest.java @@ -10,6 +10,12 @@ *******************************************************************************/ package org.eclipse.osee.orcs.core.internal.relation; +import static org.eclipse.osee.framework.core.enums.RelationSide.SIDE_A; +import static org.eclipse.osee.framework.core.enums.RelationSide.SIDE_B; +import static org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity.MANY_TO_MANY; +import static org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity.MANY_TO_ONE; +import static org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity.ONE_TO_MANY; +import static org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity.ONE_TO_ONE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -19,9 +25,7 @@ import java.util.Collection; import java.util.List; import org.eclipse.osee.framework.core.data.IArtifactType; import org.eclipse.osee.framework.core.data.IRelationType; -import org.eclipse.osee.framework.core.data.IRelationTypeSide; -import org.eclipse.osee.framework.core.enums.RelationSide; -import org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity; +import org.eclipse.osee.framework.core.data.TokenFactory; import org.eclipse.osee.framework.core.exception.OseeArgumentException; import org.eclipse.osee.framework.core.exception.OseeCoreException; import org.eclipse.osee.framework.core.exception.OseeStateException; @@ -44,6 +48,8 @@ import org.mockito.stubbing.Answer; */ public class RelationTypeValidityTest { + private static final IRelationType TYPE_1 = TokenFactory.createRelationType(123456789L, "TYPE_1"); + @Rule public ExpectedException thrown = ExpectedException.none(); @@ -52,11 +58,11 @@ public class RelationTypeValidityTest { @Mock private RelationNode node; @Mock private IArtifactType artifactType; @Mock private IArtifactType artifactType2; + @Mock private IRelationType relationType1; @Mock private IRelationType relationType2; @Mock private IRelationType relationType3; @Mock private IRelationType relationType4; - @Mock private IRelationTypeSide typeSide1; // @formatter:on private RelationTypeValidity validity; @@ -67,25 +73,41 @@ public class RelationTypeValidityTest { validity = new RelationTypeValidity(cache); - when(typeSide1.getGuid()).thenReturn(11L); - when(typeSide1.getSide()).thenReturn(RelationSide.SIDE_B); - when(typeSide1.getName()).thenReturn("typeSide1"); - - when(cache.getByUuid(typeSide1.getGuid())).thenReturn(relationType1); + when(cache.exists(TYPE_1)).thenReturn(true); + when(cache.exists(relationType1)).thenReturn(true); + when(cache.exists(relationType2)).thenReturn(true); + when(cache.exists(relationType3)).thenReturn(true); + when(cache.exists(relationType4)).thenReturn(true); } @Test public void testMaximumRelationAllowedNullArtifactType() throws OseeCoreException { thrown.expect(OseeArgumentException.class); thrown.expectMessage("artifactType cannot be null"); - validity.getMaximumRelationsAllowed(null, typeSide1); + validity.getMaximumRelationsAllowed(TYPE_1, null, SIDE_A); + } + + @Test + public void testMaximumRelationAllowedNullRelationType() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("relationType cannot be null"); + validity.getMaximumRelationsAllowed(null, artifactType, SIDE_B); } @Test - public void testMaximumRelationAllowedNullRelationTypeSide() throws OseeCoreException { + public void testMaximumRelationAllowedNullRelationSide() throws OseeCoreException { thrown.expect(OseeArgumentException.class); - thrown.expectMessage("relationTypeSide cannot be null"); - validity.getMaximumRelationsAllowed(artifactType, null); + thrown.expectMessage("relationSide cannot be null"); + validity.getMaximumRelationsAllowed(TYPE_1, artifactType, null); + } + + @Test + public void testMaximumRelationAllowedTypeDoesNotExist() throws OseeCoreException { + when(cache.exists(TYPE_1)).thenReturn(false); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage(String.format("relationType [%s] does not exist", TYPE_1)); + validity.getMaximumRelationsAllowed(TYPE_1, artifactType, SIDE_A); } @Test @@ -97,27 +119,27 @@ public class RelationTypeValidityTest { @Test public void testMaximumRelationAllowed1() throws OseeCoreException { - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_B, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.MANY_TO_MANY); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_B, artifactType)).thenReturn(true); + when(cache.getMultiplicity(TYPE_1)).thenReturn(MANY_TO_MANY); - int actual = validity.getMaximumRelationsAllowed(artifactType, typeSide1); + int actual = validity.getMaximumRelationsAllowed(TYPE_1, artifactType, SIDE_B); assertEquals(Integer.MAX_VALUE, actual); } @Test public void testMaximumRelationAllowed2() throws OseeCoreException { - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_B, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.MANY_TO_ONE); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_B, artifactType)).thenReturn(true); + when(cache.getMultiplicity(TYPE_1)).thenReturn(MANY_TO_ONE); - int actual = validity.getMaximumRelationsAllowed(artifactType, typeSide1); + int actual = validity.getMaximumRelationsAllowed(TYPE_1, artifactType, SIDE_B); assertEquals(1, actual); } @Test public void testMaximumRelationAllowed3() throws OseeCoreException { - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_A, artifactType)).thenReturn(true); + when(cache.isArtifactTypeAllowed(relationType1, SIDE_A, artifactType)).thenReturn(true); - int actual = validity.getMaximumRelationsAllowed(artifactType, typeSide1); + int actual = validity.getMaximumRelationsAllowed(TYPE_1, artifactType, SIDE_B); assertEquals(0, actual); } @@ -133,17 +155,17 @@ public class RelationTypeValidityTest { } }); - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_B, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.MANY_TO_MANY); + when(cache.isArtifactTypeAllowed(relationType1, SIDE_B, artifactType)).thenReturn(true); + when(cache.getMultiplicity(relationType1)).thenReturn(MANY_TO_MANY); - when(cache.isArtifactTypeAllowed(relationType2, RelationSide.SIDE_A, artifactType)).thenReturn(false); - when(cache.getMultiplicity(relationType2)).thenReturn(RelationTypeMultiplicity.MANY_TO_ONE); + when(cache.isArtifactTypeAllowed(relationType2, SIDE_A, artifactType)).thenReturn(false); + when(cache.getMultiplicity(relationType2)).thenReturn(MANY_TO_ONE); - when(cache.isArtifactTypeAllowed(relationType3, RelationSide.SIDE_A, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType3)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.isArtifactTypeAllowed(relationType3, SIDE_A, artifactType)).thenReturn(true); + when(cache.getMultiplicity(relationType3)).thenReturn(ONE_TO_ONE); - when(cache.isArtifactTypeAllowed(relationType4, RelationSide.SIDE_A, artifactType)).thenReturn(false); - when(cache.getMultiplicity(relationType4)).thenReturn(RelationTypeMultiplicity.ONE_TO_MANY); + when(cache.isArtifactTypeAllowed(relationType4, SIDE_A, artifactType)).thenReturn(false); + when(cache.getMultiplicity(relationType4)).thenReturn(ONE_TO_MANY); List<IRelationType> actual = validity.getValidRelationTypes(artifactType); @@ -156,50 +178,50 @@ public class RelationTypeValidityTest { @Test public void testGetRelationMultiplicityState() throws OseeCoreException { - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.getMultiplicity(TYPE_1)).thenReturn(ONE_TO_ONE); - MultiplicityState state = validity.getRelationMultiplicityState(typeSide1, 0); + MultiplicityState state = validity.getRelationMultiplicityState(TYPE_1, SIDE_B, 0); assertEquals(MultiplicityState.IS_VALID, state); - state = validity.getRelationMultiplicityState(typeSide1, 1); + state = validity.getRelationMultiplicityState(TYPE_1, SIDE_B, 1); assertEquals(MultiplicityState.IS_VALID, state); - state = validity.getRelationMultiplicityState(typeSide1, 2); + state = validity.getRelationMultiplicityState(TYPE_1, SIDE_B, 2); assertEquals(MultiplicityState.MAX_VIOLATION, state); } @Test public void testCheckRelationTypeMultiplicity() throws OseeCoreException { - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.getMultiplicity(TYPE_1)).thenReturn(ONE_TO_ONE); when(node.getExceptionString()).thenReturn("node message"); thrown.expect(OseeStateException.class); - thrown.expectMessage(String.format("Relation type [%s] exceeds max occurrence rule on [node message]", typeSide1, - node.getExceptionString())); + thrown.expectMessage(String.format("Relation type [%s] on [%s] exceeds max occurrence rule on [node message]", + TYPE_1, SIDE_A, node.getExceptionString())); - validity.checkRelationTypeMultiplicity(node, typeSide1, 2); + validity.checkRelationTypeMultiplicity(TYPE_1, node, SIDE_A, 2); } @Test public void testCheckRelationTypeMultiplicityNoException() throws OseeCoreException { - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.getMultiplicity(TYPE_1)).thenReturn(ONE_TO_ONE); when(node.getExceptionString()).thenReturn("node message"); ExpectedException.none(); - validity.checkRelationTypeMultiplicity(node, typeSide1, 0); + validity.checkRelationTypeMultiplicity(TYPE_1, node, SIDE_A, 0); } @Test public void testIsRelationTypeValid() throws OseeCoreException { - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_A, artifactType)).thenReturn(true); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_A, artifactType)).thenReturn(true); - boolean actual = validity.isRelationTypeValid(artifactType, typeSide1); + boolean actual = validity.isRelationTypeValid(TYPE_1, artifactType, SIDE_B); assertEquals(false, actual); - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_B, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_B, artifactType)).thenReturn(true); + when(cache.getMultiplicity(TYPE_1)).thenReturn(ONE_TO_ONE); - actual = validity.isRelationTypeValid(artifactType, typeSide1); + actual = validity.isRelationTypeValid(TYPE_1, artifactType, SIDE_B); assertEquals(true, actual); } @@ -208,27 +230,25 @@ public class RelationTypeValidityTest { when(artifactType.toString()).thenReturn("artType1"); when(artifactType2.toString()).thenReturn("artType2"); - when(relationType1.toString()).thenReturn("relationType1Name"); - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_A, artifactType)).thenReturn(true); - - when(cache.getArtifactType(relationType1, RelationSide.SIDE_B)).thenReturn(artifactType2); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_A, artifactType)).thenReturn(true); + when(cache.getArtifactType(TYPE_1, SIDE_B)).thenReturn(artifactType2); when(node.getArtifactType()).thenReturn(artifactType); when(node.getExceptionString()).thenReturn("node message"); thrown.expect(OseeArgumentException.class); - thrown.expectMessage("Relation validity error for [node message] - ArtifactType [artType1] does not belong on side [SIDE_B] of relation [relationType1Name] - only items of type [artType2] are allowed"); - validity.checkRelationTypeValid(node, typeSide1); + thrown.expectMessage("Relation validity error for [node message] - ArtifactType [artType1] does not belong on side [SIDE_B] of relation [TYPE_1] - only items of type [artType2] are allowed"); + validity.checkRelationTypeValid(TYPE_1, node, SIDE_B); } @Test public void testCheckRelationTypeValidNoException() throws OseeCoreException { when(node.getArtifactType()).thenReturn(artifactType); - when(cache.isArtifactTypeAllowed(relationType1, RelationSide.SIDE_B, artifactType)).thenReturn(true); - when(cache.getMultiplicity(relationType1)).thenReturn(RelationTypeMultiplicity.ONE_TO_ONE); + when(cache.isArtifactTypeAllowed(TYPE_1, SIDE_B, artifactType)).thenReturn(true); + when(cache.getMultiplicity(TYPE_1)).thenReturn(ONE_TO_ONE); ExpectedException.none(); - validity.checkRelationTypeValid(node, typeSide1); + validity.checkRelationTypeValid(TYPE_1, node, SIDE_B); } } diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationImplTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationImplTestSuite.java new file mode 100644 index 00000000000..63c10835035 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationImplTestSuite.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author Roberto E. Escobar + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + RelationNodeAdjacenciesTest.class, + RelationManagerImplTest.class, + RelationResolverTest.class, + RelationNodeLoaderImplTest.class}) +public class RelationImplTestSuite { + // Test Suite +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImplTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImplTest.java new file mode 100644 index 00000000000..4279cfebff4 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImplTest.java @@ -0,0 +1,811 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import static org.eclipse.osee.framework.core.enums.CoreBranches.COMMON; +import static org.eclipse.osee.framework.core.enums.CoreBranches.SYSTEM_ROOT; +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Child; +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Parent; +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.RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC; +import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.PREEXISTING; +import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.UNORDERED; +import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.USER_DEFINED; +import static org.eclipse.osee.framework.core.enums.RelationSide.SIDE_A; +import static org.eclipse.osee.framework.core.enums.RelationSide.SIDE_B; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.eclipse.osee.framework.core.data.IArtifactType; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.IRelationTypeSide; +import org.eclipse.osee.framework.core.data.Identifiable; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.data.TokenFactory; +import org.eclipse.osee.framework.core.enums.CoreRelationTypes; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeArgumentException; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.RelationTypeSide; +import org.eclipse.osee.framework.jdk.core.util.GUID; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; +import org.eclipse.osee.orcs.core.internal.relation.RelationManager; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationResolver; +import org.eclipse.osee.orcs.core.internal.relation.RelationTypeValidity; +import org.eclipse.osee.orcs.core.internal.relation.RelationVisitor; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderManager; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderManagerFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Test Case for {@link RelationManagerImpl} + * + * @author Roberto E. Escobar + */ +public class RelationManagerImplTest { + + private static final IRelationType TYPE_1 = TokenFactory.createRelationType(123456789L, "TYPE_1"); + + private static final IRelationType DEFAULT_HIERARCHY = Default_Hierarchical__Parent; + private static final RelationSide IS_PARENT = Default_Hierarchical__Parent.getSide(); + private static final RelationSide IS_CHILD = Default_Hierarchical__Child.getSide(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private Log logger; + @Mock private RelationTypeValidity validity; + @Mock private RelationResolver resolver; + @Mock private OrderManagerFactory orderFactory; + + @Mock private RelationFactory relationFactory; + @Mock private OrcsSession session; + + @Mock private GraphData graph; + + @Mock private RelationNode node1; + @Mock private RelationNode node2; + @Mock private RelationNode node3; + @Mock private RelationNode node4; + @Mock private RelationNode node5; + @Mock private RelationNode node6; + + @Mock private RelationNodeAdjacencies container1; + @Mock private RelationNodeAdjacencies container2; + + @Mock private IArtifactType artifactType1; + @Mock private IArtifactType artifactType2; + + @Mock private Relation relation1; + @Mock private Relation relation2; + @Mock private Relation relation3; + @Mock private Relation relation4; + + @Mock private IRelationType relType1; + @Mock private IRelationType relType2; + + @Mock private IRelationTypeSide typeAndSide1; + + @Mock private ResultSet<Relation> rSet1; + @Mock private ResultSet<Relation> rSet2; + + @Mock private OrderManager orderManager1; + @Captor private ArgumentCaptor<List<? extends Identifiable>> sortedListCaptor; + // @formatter:on + + private RelationManager manager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + manager = new RelationManagerImpl(logger, validity, resolver, relationFactory, orderFactory); + + String sessionId = GUID.create(); + when(session.getGuid()).thenReturn(sessionId); + + when(node1.getLocalId()).thenReturn(11); + when(node2.getLocalId()).thenReturn(22); + when(node3.getLocalId()).thenReturn(33); + when(node4.getLocalId()).thenReturn(44); + when(node5.getLocalId()).thenReturn(55); + when(node6.getLocalId()).thenReturn(66); + + when(node1.getGraph()).thenReturn(graph); + when(node2.getGraph()).thenReturn(graph); + when(node3.getGraph()).thenReturn(graph); + when(node4.getGraph()).thenReturn(graph); + when(node5.getGraph()).thenReturn(graph); + when(node6.getGraph()).thenReturn(graph); + + when(graph.getAdjacencies(node1)).thenReturn(container1); + when(graph.getAdjacencies(node2)).thenReturn(container2); + + when(relation1.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation1.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(22); + + when(relation2.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(33); + when(relation2.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(44); + + when(relation3.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(55); + when(relation3.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(66); + + when(relation4.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation4.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(66); + } + + @Test + public void testGetValidRelationTypes() throws OseeCoreException { + final List<IRelationType> expected = new ArrayList<IRelationType>(); + when(node1.getArtifactType()).thenReturn(artifactType1); + when(node2.getArtifactType()).thenReturn(artifactType2); + when(validity.getValidRelationTypes(artifactType1)).thenAnswer(new Answer<List<IRelationType>>() { + @Override + public List<IRelationType> answer(InvocationOnMock invocation) throws Throwable { + return expected; + } + }); + + Collection<? extends IRelationType> actual = manager.getValidRelationTypes(session, node1); + + assertEquals(expected, actual); + verify(validity).getValidRelationTypes(artifactType1); + } + + @Test + public void testGetMaximumRelationAllowed() throws OseeCoreException { + when(node1.getArtifactType()).thenReturn(artifactType1); + when(node2.getArtifactType()).thenReturn(artifactType2); + when(validity.getMaximumRelationsAllowed(TYPE_1, artifactType1, SIDE_A)).thenReturn(11); + + int actual = manager.getMaximumRelationAllowed(session, TYPE_1, node1, SIDE_A); + + assertEquals(11, actual); + verify(validity).getMaximumRelationsAllowed(TYPE_1, artifactType1, SIDE_A); + } + + @Test + public void testAccept() throws OseeCoreException { + RelationVisitor visitor = mock(RelationVisitor.class); + + manager.accept(session, graph, node1, visitor); + + verify(container1).accept(visitor); + } + + @Test + public void testHasDirtyRelations() throws OseeCoreException { + when(graph.getAdjacencies(node1)).thenReturn(null); + assertFalse(manager.hasDirtyRelations(session, graph, node1)); + + when(container1.hasDirty()).thenReturn(true); + when(graph.getAdjacencies(node1)).thenReturn(container1); + assertTrue(manager.hasDirtyRelations(session, graph, node1)); + + when(container1.hasDirty()).thenReturn(false); + assertFalse(manager.hasDirtyRelations(session, graph, node1)); + } + + @Test + public void testGetExistingRelationTypeNullGraph() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("graph cannot be null"); + manager.getExistingRelationTypes(session, null, node1); + } + + @Test + public void testGetExistingRelationTypeNullNode() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("node cannot be null"); + manager.getExistingRelationTypes(session, graph, null); + } + + @Test + public void testGetExistingRelationType() throws OseeCoreException { + when(graph.getAdjacencies(node1)).thenReturn(null); + Collection<? extends IRelationType> actuals = manager.getExistingRelationTypes(session, graph, node1); + assertEquals(Collections.emptyList(), actuals); + + final List<IRelationType> types = Arrays.asList(relType1, relType2); + when(graph.getAdjacencies(node1)).thenReturn(container1); + when(container1.getExistingTypes(EXCLUDE_DELETED)).thenAnswer(new Answer<List<IRelationType>>() { + + @Override + public List<IRelationType> answer(InvocationOnMock invocation) throws Throwable { + return types; + } + + }); + actuals = manager.getExistingRelationTypes(session, graph, node1); + verify(container1).getExistingTypes(EXCLUDE_DELETED); + assertEquals(2, actuals.size()); + Iterator<? extends IRelationType> iterator = actuals.iterator(); + assertEquals(relType1, iterator.next()); + assertEquals(relType2, iterator.next()); + } + + @Test + public void testGetParentNullGraph() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("graph cannot be null"); + manager.getParent(session, null, node1); + } + + @Test + public void testGetParentNullNode() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("node cannot be null"); + manager.getParent(session, graph, null); + } + + @Test + public void testGetParent() throws OseeCoreException { + List<Relation> relations = Arrays.asList(relation1); + List<RelationNode> nodes = Arrays.asList(node1); + + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_CHILD)).thenReturn(relations); + when(resolver.resolve(session, graph, relations, SIDE_A)).thenReturn(nodes); + + RelationNode parentNode = manager.getParent(session, graph, node1); + + assertEquals(node1, parentNode); + verify(resolver).resolve(session, graph, relations, SIDE_A); + } + + @Test + public void testGetParentMoreThanOne() throws OseeCoreException { + List<Relation> relations = Arrays.asList(relation1, relation4); + List<RelationNode> arts = Arrays.asList(node1, node3); + + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_CHILD)).thenReturn(relations); + when(resolver.resolve(session, graph, relations, SIDE_A)).thenReturn(arts); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + RelationNode parent = manager.getParent(session, graph, node1); + assertEquals(node1, parent); + + verify(resolver).resolve(session, graph, relations, SIDE_A); + verify(orderManager1).sort(CoreRelationTypes.Default_Hierarchical__Parent, arts); + } + + @Test + public void testGetChildrenNullGraph() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("graph cannot be null"); + manager.getChildren(session, null, node1); + } + + @Test + public void testGetChildrenNullNode() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("node cannot be null"); + manager.getChildren(session, graph, null); + } + + @Test + public void testGetChildren() throws OseeCoreException { + List<Relation> relations = Arrays.asList(relation1, relation4); + List<RelationNode> nodes = Arrays.asList(node2, node6); + + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT)).thenReturn(relations); + when(resolver.resolve(session, graph, relations, SIDE_B)).thenReturn(nodes); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + ResultSet<RelationNode> result = manager.getChildren(session, graph, node1); + assertEquals(2, result.size()); + Iterator<RelationNode> iterator = result.iterator(); + assertEquals(node2, iterator.next()); + assertEquals(node6, iterator.next()); + + verify(resolver).resolve(session, graph, relations, SIDE_B); + verify(orderManager1).sort(CoreRelationTypes.Default_Hierarchical__Child, nodes); + } + + @Test + public void testGetRelatedNullGraph() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("graph cannot be null"); + manager.getRelated(session, null, TYPE_1, node1, SIDE_A); + } + + @Test + public void testGetRelatedNullNode() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("node cannot be null"); + manager.getRelated(session, graph, TYPE_1, null, SIDE_A); + } + + @Test + public void testGetRelatedNullType() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("relationType cannot be null"); + manager.getRelated(session, graph, null, node1, SIDE_A); + } + + @Test + public void testGetRelatedNullSide() throws OseeCoreException { + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("relationSide cannot be null"); + manager.getRelated(session, graph, TYPE_1, node1, null); + } + + @Test + public void testGetRelated() throws OseeCoreException { + List<Relation> relations = Arrays.asList(relation1, relation2, relation3); + List<RelationNode> nodes = Arrays.asList(node2, node3, node5); + + when(container1.getList(TYPE_1, EXCLUDE_DELETED, node1, SIDE_B)).thenReturn(relations); + + when(resolver.resolve(session, graph, relations, SIDE_A)).thenReturn(nodes); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + ResultSet<RelationNode> result = manager.getRelated(session, graph, TYPE_1, node1, SIDE_B); + assertEquals(3, result.size()); + Iterator<RelationNode> iterator = result.iterator(); + assertEquals(node2, iterator.next()); + assertEquals(node3, iterator.next()); + assertEquals(node5, iterator.next()); + + verify(resolver).resolve(session, graph, relations, SIDE_A); + + IRelationTypeSide typeSide = TokenFactory.createRelationTypeSide(SIDE_A, TYPE_1.getGuid(), TYPE_1.getName()); + verify(orderManager1).sort(typeSide, nodes); + } + + @Test + public void testAreRelated() throws OseeCoreException { + when(container1.getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED)).thenReturn(relation1); + + boolean value = manager.areRelated(session, graph, node1, TYPE_1, node2); + assertTrue(value); + + when(container1.getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED)).thenReturn(null); + + boolean value2 = manager.areRelated(session, graph, node1, TYPE_1, node2); + assertFalse(value2); + } + + @Test + public void testGetRationale() throws OseeCoreException { + when(container1.getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED)).thenReturn(relation1); + when(relation1.getRationale()).thenReturn("Hello rationale"); + + String value = manager.getRationale(session, graph, node1, TYPE_1, node2); + assertEquals("Hello rationale", value); + + verify(container1).getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED); + verify(relation1).getRationale(); + } + + @Test + public void testGetRelatedCount() throws OseeCoreException { + List<Relation> list = Arrays.asList(relation1, relation2, relation3); + + when(container1.getList(TYPE_1, EXCLUDE_DELETED, node1, SIDE_B)).thenReturn(list); + + int actual = manager.getRelatedCount(session, graph, TYPE_1, node1, SIDE_B); + Assert.assertEquals(3, actual); + + verify(container1).getList(TYPE_1, EXCLUDE_DELETED, node1, SIDE_B); + } + + @Test + public void testGetRelatedCountIncludeDeleted() throws OseeCoreException { + List<Relation> list = Arrays.asList(relation1, relation2); + + when(container1.getList(TYPE_1, INCLUDE_DELETED, node1, SIDE_A)).thenReturn(list); + + int actual = manager.getRelatedCount(session, graph, TYPE_1, node1, SIDE_A, INCLUDE_DELETED); + Assert.assertEquals(2, actual); + + verify(container1).getList(TYPE_1, INCLUDE_DELETED, node1, SIDE_A); + } + + @Test + public void testRelateErrorOnDifferentBranches() throws OseeCoreException { + when(node1.getBranch()).thenReturn(SYSTEM_ROOT); + when(node2.getBranch()).thenReturn(COMMON); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage("Cross branch linking is not yet supported."); + manager.relate(session, graph, node1, typeAndSide1, node2); + } + + @Test + public void testRelateErrorCycle() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage(String.format("Not valid to relate [%s] to itself", node1)); + manager.relate(session, graph, node1, typeAndSide1, node1); + } + + @Test + public void testRelateErrorMultiplicityInvalid() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + thrown.expect(OseeArgumentException.class); + thrown.expectMessage(String.format("Not valid to relate [%s] to itself", node1)); + manager.relate(session, graph, node1, typeAndSide1, node1); + } + + @Test + public void testRelateErrorTypeInvalidNode1() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + OseeCoreException myException = new OseeCoreException("Test Type Exception"); + + doThrow(myException).when(validity).checkRelationTypeValid(TYPE_1, node1, SIDE_A); + + thrown.expect(OseeCoreException.class); + thrown.expectMessage("Test Type Exception"); + manager.relate(session, graph, node1, TYPE_1, node2); + + verify(validity).checkRelationTypeValid(TYPE_1, node1, SIDE_A); + verify(validity, times(0)).checkRelationTypeValid(TYPE_1, node2, SIDE_B); + } + + @Test + public void testRelateErrorTypeInvalidNode2() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(relationFactory.createRelation(node1, TYPE_1, node2)).thenReturn(relation1); + when(container1.getResultSet(TYPE_1, INCLUDE_DELETED, node1, SIDE_A)).thenReturn(rSet1); + when(rSet1.getOneOrNull()).thenReturn(relation1); + + OseeCoreException myException = new OseeCoreException("Test Type Exception"); + + doThrow(myException).when(validity).checkRelationTypeValid(TYPE_1, node2, SIDE_B); + + thrown.expect(OseeCoreException.class); + thrown.expectMessage("Test Type Exception"); + manager.relate(session, graph, node1, TYPE_1, node2); + + verify(validity).checkRelationTypeValid(TYPE_1, node1, SIDE_A); + verify(validity).checkRelationTypeValid(TYPE_1, node2, SIDE_B); + } + + @Test + public void testRelateErrorMultiplicityNode1() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + OseeCoreException myException = new OseeCoreException("Test Multiplicity Exception"); + + doThrow(myException).when(validity).checkRelationTypeMultiplicity(TYPE_1, node1, SIDE_A, 1); + + thrown.expect(OseeCoreException.class); + thrown.expectMessage("Test Multiplicity Exception"); + manager.relate(session, graph, node1, TYPE_1, node2); + + verify(validity).checkRelationTypeValid(TYPE_1, node1, SIDE_A); + verify(validity).checkRelationTypeMultiplicity(TYPE_1, node1, SIDE_A, 1); + verify(validity, times(0)).checkRelationTypeValid(TYPE_1, node2, SIDE_B); + } + + @Test + public void testRelateErrorMultiplicityNode2() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(relationFactory.createRelation(node1, TYPE_1, node2)).thenReturn(relation1); + when(container1.getResultSet(TYPE_1, INCLUDE_DELETED, node1, SIDE_A)).thenReturn(rSet1); + when(rSet1.getOneOrNull()).thenReturn(relation1); + + OseeCoreException myException = new OseeCoreException("Test Multiplicity Exception"); + + doThrow(myException).when(validity).checkRelationTypeMultiplicity(TYPE_1, node2, SIDE_B, 1); + + thrown.expect(OseeCoreException.class); + thrown.expectMessage("Test Multiplicity Exception"); + manager.relate(session, graph, node1, TYPE_1, node2); + + verify(validity).checkRelationTypeValid(TYPE_1, node1, SIDE_A); + verify(validity).checkRelationTypeMultiplicity(TYPE_1, node1, SIDE_A, 1); + verify(validity).checkRelationTypeValid(TYPE_1, node2, SIDE_B); + verify(validity).checkRelationTypeMultiplicity(TYPE_1, node2, SIDE_B, 1); + } + + @Test + public void testSetRationale() throws OseeCoreException { + String rationale = "New Rationale"; + + when(container2.getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED)).thenReturn(relation1); + + manager.setRationale(session, graph, node1, TYPE_1, node2, rationale); + + verify(container1).getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED); + verify(container2).getRelation(node1, TYPE_1, node2, EXCLUDE_DELETED); + verify(relation1).setRationale(rationale); + } + + @Test + public void testRelateWithSorting() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + + when(relationFactory.createRelation(node1, TYPE_1, node2)).thenReturn(relation1); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + manager.relate(session, graph, node1, TYPE_1, node2, LEXICOGRAPHICAL_ASC); + + IRelationTypeSide typeSide = new RelationTypeSide(TYPE_1, SIDE_B); + + verify(container1).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(container2).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(relationFactory).createRelation(node1, TYPE_1, node2); + verify(orderManager1).setOrder(eq(typeSide), eq(LEXICOGRAPHICAL_ASC), anyListOf(Identifiable.class)); + verify(container1).add(TYPE_1.getGuid(), relation1); + verify(container2).add(TYPE_1.getGuid(), relation1); + } + + @Test + public void testRelateNoSorting() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + + when(relationFactory.createRelation(node1, TYPE_1, node2)).thenReturn(relation1); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + IRelationTypeSide typeSide = new RelationTypeSide(TYPE_1, SIDE_B); + when(orderManager1.getSorterId(typeSide)).thenReturn(UNORDERED); + + manager.relate(session, graph, node1, TYPE_1, node2); + + verify(container1).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(container2).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(relationFactory).createRelation(node1, TYPE_1, node2); + verify(orderManager1).getSorterId(typeSide); + verify(orderManager1).setOrder(eq(typeSide), eq(UNORDERED), anyListOf(Identifiable.class)); + verify(container1).add(TYPE_1.getGuid(), relation1); + verify(container2).add(TYPE_1.getGuid(), relation1); + } + + @Test + public void testRelateWithSortingUserDefined() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + + when(relationFactory.createRelation(node1, TYPE_1, node2)).thenReturn(relation1); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + List<Relation> toOrder = Arrays.asList(relation3, relation4); + when(container1.getList(TYPE_1, EXCLUDE_DELETED, node1, SIDE_A)).thenReturn(toOrder); + + List<RelationNode> nodesToOrder = Arrays.asList(node3, node4, node5, node6); + when(resolver.resolve(session, graph, toOrder, SIDE_B)).thenReturn(nodesToOrder); + + manager.relate(session, graph, node1, TYPE_1, node2, USER_DEFINED); + + verify(container1).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(container2).getRelation(node1, TYPE_1, node2, INCLUDE_DELETED); + verify(container1).add(TYPE_1.getGuid(), relation1); + verify(container2).add(TYPE_1.getGuid(), relation1); + + verify(resolver).resolve(session, graph, toOrder, SIDE_B); + + IRelationTypeSide typeSide = new RelationTypeSide(TYPE_1, SIDE_B); + verify(orderManager1).sort(typeSide, nodesToOrder); + verify(orderManager1).setOrder(eq(typeSide), eq(USER_DEFINED), sortedListCaptor.capture()); + + Iterator<? extends Identifiable> iterator = sortedListCaptor.getValue().iterator(); + assertEquals(node3, iterator.next()); + assertEquals(node4, iterator.next()); + assertEquals(node5, iterator.next()); + assertEquals(node6, iterator.next()); + assertEquals(node2, iterator.next()); + } + + @Test + public void testAddChild() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED)).thenReturn(null); + + when(relationFactory.createRelation(node1, DEFAULT_HIERARCHY, node2)).thenReturn(relation1); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(UNORDERED); + + manager.addChild(session, graph, node1, node2); + + verify(container1).getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED); + verify(container2).getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED); + verify(orderManager1).getSorterId(Default_Hierarchical__Child); + verify(orderManager1).setOrder(eq(Default_Hierarchical__Child), eq(UNORDERED), anyListOf(Identifiable.class)); + verify(container1).add(DEFAULT_HIERARCHY.getGuid(), relation1); + verify(container2).add(DEFAULT_HIERARCHY.getGuid(), relation1); + } + + @Test + public void testAddChildren() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, TYPE_1, node2, INCLUDE_DELETED)).thenReturn(null); + + when(relationFactory.createRelation(node1, DEFAULT_HIERARCHY, node2)).thenReturn(relation1); + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(UNORDERED); + + List<? extends RelationNode> children = Arrays.asList(node2); + manager.addChildren(session, graph, node1, children); + + verify(container1).getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED); + verify(container2).getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED); + + verify(orderManager1).getSorterId(Default_Hierarchical__Child); + verify(orderManager1).setOrder(eq(Default_Hierarchical__Child), eq(UNORDERED), anyListOf(Identifiable.class)); + verify(container1).add(DEFAULT_HIERARCHY.getGuid(), relation1); + verify(container2).add(DEFAULT_HIERARCHY.getGuid(), relation1); + } + + @Test + public void testAddPreviouslyDeletedChild() throws OseeCoreException { + when(node1.getBranch()).thenReturn(COMMON); + when(node2.getBranch()).thenReturn(COMMON); + + when(container1.getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED)).thenReturn(null); + when(container2.getRelation(node1, DEFAULT_HIERARCHY, node2, INCLUDE_DELETED)).thenReturn(relation1); + + when(relation1.isDeleted()).thenReturn(true); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(UNORDERED); + + manager.addChild(session, graph, node1, node2); + + verify(orderManager1).getSorterId(Default_Hierarchical__Child); + verify(orderManager1).setOrder(eq(Default_Hierarchical__Child), eq(UNORDERED), anyListOf(Identifiable.class)); + verify(container1, times(1)).add(DEFAULT_HIERARCHY.getGuid(), relation1); + verify(container2, times(0)).add(DEFAULT_HIERARCHY.getGuid(), relation1); + + verify(relation1).unDelete(); + } + + @Test + public void testUnrelate() throws OseeCoreException { + when(container1.getRelation(node1, DEFAULT_HIERARCHY, node2, EXCLUDE_DELETED)).thenReturn(relation1); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(USER_DEFINED); + + List<Relation> relations = Arrays.asList(relation1); + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT)).thenReturn(relations); + + List<RelationNode> nodesToOrder = Arrays.asList(node3, node2, node5, node6); + when(resolver.resolve(session, graph, relations, SIDE_B)).thenReturn(nodesToOrder); + + manager.unrelate(session, graph, node1, DEFAULT_HIERARCHY, node2); + + verify(relation1).delete(); + + verify(orderManager1).getSorterId(Default_Hierarchical__Child); + + verify(container1, times(0)).remove(DEFAULT_HIERARCHY.getGuid(), relation1); + + verify(resolver).resolve(session, graph, relations, SIDE_B); + + verify(orderManager1).setOrder(eq(Default_Hierarchical__Child), eq(USER_DEFINED), sortedListCaptor.capture()); + + assertEquals(3, sortedListCaptor.getValue().size()); + Iterator<? extends Identifiable> iterator = sortedListCaptor.getValue().iterator(); + assertEquals(node3, iterator.next()); + assertEquals(node5, iterator.next()); + assertEquals(node6, iterator.next()); + } + + @Test + public void testUnrelateFromAllByType() throws OseeCoreException { + List<Relation> relations1 = Arrays.asList(relation1); + + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT)).thenReturn(relations1); + + when(relation1.getLocalIdForSide(SIDE_B)).thenReturn(22); + when(graph.getNode(22)).thenReturn(node2); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(PREEXISTING); + + manager.unrelateFromAll(session, graph, DEFAULT_HIERARCHY, node1, IS_PARENT); + + verify(relation1).getLocalIdForSide(SIDE_B); + verify(graph).getNode(22); + verify(container1).getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT); + verify(resolver).resolve(session, graph, relations1, SIDE_B); + verify(relation1).delete(); + verify(orderManager1).getSorterId(Default_Hierarchical__Child); + } + + @Test + public void testUnrelateFromAll() throws OseeCoreException { + List<Relation> allRelations = Arrays.asList(relation1); + List<Relation> asAParent = Collections.emptyList(); + List<Relation> asAChild = Arrays.asList(relation2); + List<RelationNode> children = Arrays.asList(node2); + + when(relation1.getRelationType()).thenReturn(DEFAULT_HIERARCHY); + when(node1.isDeleteAllowed()).thenReturn(true); + when(container1.getList(EXCLUDE_DELETED)).thenReturn(allRelations); + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT)).thenReturn(allRelations); + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT)).thenReturn(asAParent); + when(container1.getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_CHILD)).thenReturn(asAChild); + + when(relation1.getLocalIdForSide(SIDE_A)).thenReturn(11); + + when(orderFactory.createOrderManager(node1)).thenReturn(orderManager1); + + when(resolver.resolve(session, graph, asAChild, IS_CHILD)).thenReturn(children); + when(orderManager1.getSorterId(Default_Hierarchical__Child)).thenReturn(PREEXISTING); + + manager.unrelateFromAll(session, graph, node1); + + verify(container1).getList(EXCLUDE_DELETED); + verify(resolver).resolve(session, graph, allRelations, SIDE_A, SIDE_B); + verify(container1).getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_PARENT); + verify(node1).delete(); + + verify(relation1).getLocalIdForSide(SIDE_A); + verify(relation1).delete(); + verify(container1).getList(DEFAULT_HIERARCHY, EXCLUDE_DELETED, node1, IS_CHILD); + verify(resolver).resolve(session, graph, asAChild, SIDE_B); + + verify(orderManager1).setOrder(Default_Hierarchical__Child, children); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacenciesTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacenciesTest.java new file mode 100644 index 00000000000..6ee048839d1 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacenciesTest.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.Collection; +import java.util.List; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.data.TokenFactory; +import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationVisitor; +import org.eclipse.osee.orcs.data.HasLocalId; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import com.google.common.collect.Iterables; + +/** + * Test Case for {@link RelationNodeAdjacencies} + * + * @author Roberto E. Escobar + */ +public class RelationNodeAdjacenciesTest { + + private static final IRelationType TYPE_1 = TokenFactory.createRelationType(123456789L, "TYPE_1"); + private static final IRelationType TYPE_2 = TokenFactory.createRelationType(987654321L, "TYPE_2"); + private static final IRelationType TYPE_3 = TokenFactory.createRelationType(678912345L, "TYPE_3"); + + // @formatter:off + @Mock Relation dirty; + @Mock Relation clean; + @Mock Relation deleted; + + @Mock Relation relation; + @Mock HasLocalId localId; + // @formatter:on + + private RelationNodeAdjacencies collection; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + collection = new RelationNodeAdjacencies(); + + collection.add(TYPE_1.getGuid(), dirty); + collection.add(TYPE_2.getGuid(), clean); + collection.add(TYPE_3.getGuid(), deleted); + + when(dirty.isDirty()).thenReturn(true); + when(deleted.isDeleted()).thenReturn(true); + } + + @Test + public void testGetRelationsDirty() throws OseeCoreException { + assertEquals(1, collection.getDirties().size()); + assertEquals(dirty, collection.getDirties().iterator().next()); + } + + @Test + public void testHasRelationsDirty() { + boolean actual1 = collection.hasDirty(); + assertTrue(actual1); + + collection.remove(TYPE_1.getGuid(), dirty); + + boolean actual2 = collection.hasDirty(); + assertFalse(actual2); + } + + @Test + public void testGetAllRelations() { + Collection<Relation> relations = collection.getAll(); + assertEquals(3, relations.size()); + + assertTrue(relations.contains(dirty)); + assertTrue(relations.contains(clean)); + assertTrue(relations.contains(deleted)); + } + + @Test + public void testGetExistingTypes() throws OseeCoreException { + IRelationType typeA = mock(IRelationType.class); + IRelationType typeB = mock(IRelationType.class); + IRelationType typeC = mock(IRelationType.class); + + when(dirty.getRelationType()).thenReturn(typeA); + when(dirty.isDeleted()).thenReturn(true); + + when(clean.getRelationType()).thenReturn(typeB); + when(clean.isDeleted()).thenReturn(true); + + when(deleted.getRelationType()).thenReturn(typeC); + when(deleted.isDeleted()).thenReturn(false); + + Collection<? extends IRelationType> types = collection.getExistingTypes(DeletionFlag.INCLUDE_DELETED); + + assertEquals(3, types.size()); + + assertTrue(types.contains(typeA)); + assertTrue(types.contains(typeB)); + assertTrue(types.contains(typeC)); + + Collection<? extends IRelationType> types2 = collection.getExistingTypes(DeletionFlag.EXCLUDE_DELETED); + assertEquals(1, types2.size()); + + assertFalse(types2.contains(typeA)); + assertFalse(types2.contains(typeB)); + assertTrue(types2.contains(typeC)); + } + + @Test + public void testGetListDeletionFlag() throws OseeCoreException { + List<Relation> list1 = collection.getList(DeletionFlag.INCLUDE_DELETED); + + assertEquals(3, list1.size()); + assertTrue(list1.contains(dirty)); + assertTrue(list1.contains(clean)); + assertTrue(list1.contains(deleted)); + + List<Relation> list2 = collection.getList(DeletionFlag.EXCLUDE_DELETED); + assertEquals(2, list2.size()); + + assertTrue(list2.contains(dirty)); + assertTrue(list2.contains(clean)); + assertFalse(list2.contains(deleted)); + } + + @Test + public void testGetSetDeletionFlag() throws OseeCoreException { + ResultSet<Relation> set1 = collection.getResultSet(DeletionFlag.INCLUDE_DELETED); + + assertEquals(3, set1.size()); + checkContains(set1, dirty, true); + checkContains(set1, clean, true); + checkContains(set1, deleted, true); + + ResultSet<Relation> set2 = collection.getResultSet(DeletionFlag.EXCLUDE_DELETED); + assertEquals(2, set2.size()); + + checkContains(set2, dirty, true); + checkContains(set2, clean, true); + checkContains(set2, deleted, false); + } + + @Test + public void testGetListTypeAndDelete() throws OseeCoreException { + List<Relation> list1 = collection.getList(TYPE_3, DeletionFlag.INCLUDE_DELETED); + assertEquals(1, list1.size()); + assertTrue(list1.contains(deleted)); + + List<Relation> list2 = collection.getList(TYPE_3, DeletionFlag.EXCLUDE_DELETED); + assertEquals(0, list2.size()); + } + + @Test + public void testGetSetTypeAndDelete() throws OseeCoreException { + ResultSet<Relation> set1 = collection.getResultSet(TYPE_3, DeletionFlag.INCLUDE_DELETED); + + assertEquals(1, set1.size()); + checkContains(set1, deleted, true); + + ResultSet<Relation> set2 = collection.getResultSet(TYPE_3, DeletionFlag.EXCLUDE_DELETED); + assertEquals(0, set2.size()); + } + + @Test + public void testAccept() throws OseeCoreException { + RelationVisitor visitor = Mockito.mock(RelationVisitor.class); + collection.accept(visitor); + + verify(visitor).visit(dirty); + verify(visitor).visit(clean); + verify(visitor).visit(deleted); + } + + @Test + public void testLocalIdOnSide() throws OseeCoreException { + when(relation.isDeleted()).thenReturn(false); + when(relation.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(22); + + collection.add(TYPE_1.getGuid(), relation); + + when(localId.getLocalId()).thenReturn(22); + Relation actual = + collection.getResultSet(TYPE_1, DeletionFlag.EXCLUDE_DELETED, localId, RelationSide.SIDE_A).getOneOrNull(); + assertNull(actual); + actual = + collection.getResultSet(TYPE_1, DeletionFlag.EXCLUDE_DELETED, localId, RelationSide.SIDE_B).getOneOrNull(); + assertEquals(relation, actual); + + when(localId.getLocalId()).thenReturn(11); + actual = + collection.getResultSet(TYPE_1, DeletionFlag.EXCLUDE_DELETED, localId, RelationSide.SIDE_A).getOneOrNull(); + assertEquals(relation, actual); + actual = + collection.getResultSet(TYPE_1, DeletionFlag.EXCLUDE_DELETED, localId, RelationSide.SIDE_B).getOneOrNull(); + assertNull(actual); + } + + private void checkContains(Iterable<Relation> items, Relation toFind, boolean findExpected) { + boolean actual = Iterables.contains(items, toFind); + assertEquals(findExpected, actual); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImplTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImplTest.java new file mode 100644 index 00000000000..3c00ceb8c77 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImplTest.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import java.util.Arrays; +import java.util.Collection; +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.enums.CoreBranches; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.ds.DataLoader; +import org.eclipse.osee.orcs.core.ds.DataLoaderFactory; +import org.eclipse.osee.orcs.core.internal.artifact.Artifact; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilder; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilderFactory; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; + +/** + * @author Megumi Telles + */ +public class RelationNodeLoaderImplTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + // @formatter:off + @Mock private DataLoaderFactory dataLoaderFactory; + @Mock private GraphBuilderFactory graphBuilderFactory; + + @Mock private OrcsSession session; + @Mock private GraphData graph; + @Mock private GraphBuilder builder; + @Mock private DataLoader loader; + + @Mock private Artifact artifact; + // @formatter:on + + private static final IOseeBranch BRANCH = CoreBranches.COMMON; + private static final int TRANSACTION_ID = 231214214; + private static final Collection<Integer> ids = Arrays.asList(4, 5, 6, 7); + + private RelationNodeLoaderImpl relationNode; + + @Before + public void setUp() throws Exception { + initMocks(this); + + relationNode = new RelationNodeLoaderImpl(dataLoaderFactory, graphBuilderFactory); + + when(graph.getBranch()).thenReturn(BRANCH); + when(graph.getTransaction()).thenReturn(TRANSACTION_ID); + } + + @Test + public void testLoadNodes() throws OseeCoreException { + Iterable<Artifact> artifacts = Arrays.asList(artifact); + + when(dataLoaderFactory.fromBranchAndArtifactIds(session, BRANCH, ids)).thenReturn(loader); + when(graphBuilderFactory.createBuilderForGraph(graph)).thenReturn(builder); + when(builder.getArtifacts()).thenReturn(artifacts); + + Iterable<RelationNode> actual = relationNode.loadNodes(session, graph, ids, LoadLevel.FULL); + + verify(dataLoaderFactory).fromBranchAndArtifactIds(session, BRANCH, ids); + verify(graphBuilderFactory).createBuilderForGraph(graph); + + verify(loader).setLoadLevel(LoadLevel.FULL); + verify(loader).fromTransaction(TRANSACTION_ID); + verify(loader).load(null, builder); + verify(builder).getArtifacts(); + + assertEquals(artifacts, actual); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverTest.java new file mode 100644 index 00000000000..47f37803915 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverTest.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyCollectionOf; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.jdk.core.util.GUID; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationNodeLoader; +import org.eclipse.osee.orcs.core.internal.relation.RelationResolver; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Test Case for {@link RelationResolver} + * + * @author Roberto E. Escobar + */ +public class RelationResolverTest { + + // @formatter:off + @Mock private RelationNodeLoader loader; + @Mock private OrcsSession session; + @Mock private GraphData graphData; + + @Mock private Relation relation1; + @Mock private Relation relation2; + @Mock private Relation relation3; + @Mock private Relation relation4; + + @Mock private RelationNode node1; + @Mock private RelationNode node2; + @Mock private RelationNode node3; + @Mock private RelationNode node4; + @Mock private RelationNode node5; + @Mock private RelationNode node6; + + @Mock private ResultSet<RelationNode> resultSet; + @Captor private ArgumentCaptor<Collection<Integer>> captor; + // @formatter:on + + private RelationResolver resolver; + private List<Relation> links; + + @Before + public void init() throws OseeCoreException { + MockitoAnnotations.initMocks(this); + + resolver = new RelationResolverImpl(loader); + + links = Arrays.asList(relation1, relation2, relation3, relation4); + + String sessionId = GUID.create(); + when(session.getGuid()).thenReturn(sessionId); + + when(node1.getLocalId()).thenReturn(11); + when(node2.getLocalId()).thenReturn(22); + when(node3.getLocalId()).thenReturn(33); + when(node4.getLocalId()).thenReturn(44); + when(node5.getLocalId()).thenReturn(55); + when(node6.getLocalId()).thenReturn(66); + + when(relation1.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation1.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(22); + + when(relation2.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(33); + when(relation2.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(44); + + when(relation3.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(55); + when(relation3.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(66); + + when(relation4.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation4.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(66); + + when(loader.loadNodes(eq(session), eq(graphData), anyCollectionOf(Integer.class), eq(LoadLevel.FULL))).thenReturn( + resultSet); + } + + @Test + public void testLoadAll() throws OseeCoreException { + List<RelationNode> loaded = Arrays.asList(node1, node2, node3, node4, node5, node6); + + when(resultSet.iterator()).thenReturn(loaded.iterator()); + + List<RelationNode> arts = resolver.resolve(session, graphData, links, RelationSide.SIDE_A, RelationSide.SIDE_B); + + verify(loader).loadNodes(eq(session), eq(graphData), captor.capture(), eq(LoadLevel.FULL)); + assertCollection(captor.getValue(), 11, 22, 33, 44, 55, 66); + assertCollection(arts, node1, node2, node3, node4, node5, node6); + } + + @Test + public void testLoadSideAOnly() throws OseeCoreException { + List<RelationNode> loaded = Arrays.asList(node1, node3, node5); + + when(resultSet.iterator()).thenReturn(loaded.iterator()); + + List<RelationNode> arts = resolver.resolve(session, graphData, links, RelationSide.SIDE_A); + + verify(loader).loadNodes(eq(session), eq(graphData), captor.capture(), eq(LoadLevel.FULL)); + + assertCollection(captor.getValue(), 11, 33, 55); + assertCollection(arts, node1, node3, node5); + } + + @Test + public void testLoadSideBOnly() throws OseeCoreException { + List<RelationNode> loaded = Arrays.asList(node2, node4, node6); + + when(resultSet.iterator()).thenReturn(loaded.iterator()); + + List<RelationNode> arts = resolver.resolve(session, graphData, links, RelationSide.SIDE_B); + + verify(loader).loadNodes(eq(session), eq(graphData), captor.capture(), eq(LoadLevel.FULL)); + + assertCollection(captor.getValue(), 22, 44, 66); + assertCollection(arts, node2, node4, node6); + } + + @Test + public void testLoadSideAFromCacheAndSideBFromLoader() throws OseeCoreException { + List<RelationNode> loaded = Arrays.asList(node2, node4, node6); + + when(graphData.getNode(11)).thenReturn(node1); + when(graphData.getNode(33)).thenReturn(node3); + when(graphData.getNode(55)).thenReturn(node5); + + when(resultSet.iterator()).thenReturn(loaded.iterator()); + + List<RelationNode> arts = resolver.resolve(session, graphData, links, RelationSide.SIDE_A, RelationSide.SIDE_B); + + verify(graphData, times(2)).getNode(11); + verify(graphData).getNode(33); + verify(graphData).getNode(55); + + verify(loader).loadNodes(eq(session), eq(graphData), captor.capture(), eq(LoadLevel.FULL)); + + assertCollection(captor.getValue(), 22, 44, 66); + assertCollection(arts, node1, node2, node3, node4, node5, node6); + } + + private static <T> void assertCollection(Collection<T> actual, T... expecteds) { + assertEquals(expecteds.length, actual.size()); + int index = 0; + for (Iterator<T> iterator = actual.iterator(); iterator.hasNext();) { + T value = iterator.next(); + assertEquals(expecteds[index++], value); + } + } +} diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicatesTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicatesTest.java index 57f6556c71f..5a4ae1924d9 100644 --- a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicatesTest.java +++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicatesTest.java @@ -20,14 +20,19 @@ import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.excludeDel import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.includeDeleted; import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.isDirty; import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.isNotDirty; +import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.nodeIdOnSideEquals; +import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.nodeIdsEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import java.util.Date; import java.util.regex.Pattern; +import org.eclipse.osee.framework.core.enums.RelationSide; import org.eclipse.osee.framework.core.exception.OseeCoreException; import org.eclipse.osee.orcs.core.internal.attribute.Attribute; +import org.eclipse.osee.orcs.core.internal.relation.Relation; import org.eclipse.osee.orcs.data.HasDeleteState; +import org.eclipse.osee.orcs.data.HasLocalId; import org.eclipse.osee.orcs.data.Modifiable; import org.junit.Before; import org.junit.Test; @@ -59,6 +64,11 @@ public class OrcsPredicatesTest { @Mock private Attribute attribute4; @SuppressWarnings("rawtypes") @Mock private Attribute attribute5; + + @Mock private HasLocalId localId1; + @Mock private HasLocalId localId2; + + @Mock private Relation relation1; // @formatter:on private Date date; @@ -80,6 +90,12 @@ public class OrcsPredicatesTest { when(attribute3.getValue()).thenReturn(date); when(attribute4.getValue()).thenReturn("Hello"); when(attribute5.getValue()).thenReturn(true); + + when(localId1.getLocalId()).thenReturn(11); + when(localId2.getLocalId()).thenReturn(22); + + when(relation1.getLocalIdForSide(RelationSide.SIDE_A)).thenReturn(11); + when(relation1.getLocalIdForSide(RelationSide.SIDE_B)).thenReturn(22); } @Test @@ -180,4 +196,18 @@ public class OrcsPredicatesTest { assertFalse(telAttribute.apply(attribute1)); assertTrue(telAttribute.apply(attribute1)); } + + @Test + public void testNodeIdOnSideEquals() { + assertTrue(nodeIdOnSideEquals(localId1, RelationSide.SIDE_A).apply(relation1)); + assertTrue(nodeIdOnSideEquals(localId2, RelationSide.SIDE_B).apply(relation1)); + assertFalse(nodeIdOnSideEquals(localId2, RelationSide.SIDE_A).apply(relation1)); + assertFalse(nodeIdOnSideEquals(localId1, RelationSide.SIDE_B).apply(relation1)); + } + + @Test + public void testNodeIdEquals() { + assertTrue(nodeIdsEquals(localId1, localId2).apply(relation1)); + assertFalse(nodeIdsEquals(localId2, localId1).apply(relation1)); + } } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationData.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationData.java index 3b0a81a8e4d..993dbf07211 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationData.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationData.java @@ -17,10 +17,6 @@ import org.eclipse.osee.framework.core.enums.RelationSide; */ public interface RelationData extends OrcsData { - int getParentId(); - - void setParentId(int parentId); - int getArtIdA(); void setArtIdA(int artIdA); diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationDataFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationDataFactory.java index c7ac918fff4..8760a6a4699 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationDataFactory.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/ds/RelationDataFactory.java @@ -20,7 +20,7 @@ import org.eclipse.osee.orcs.data.HasLocalId; */ public interface RelationDataFactory { - RelationData createRelationData(IRelationType relationType, HasLocalId parent, IOseeBranch branch, HasLocalId aArt, HasLocalId bArt, String rationale) throws OseeCoreException; + RelationData createRelationData(IRelationType relationType, IOseeBranch branch, HasLocalId aArt, HasLocalId bArt, String rationale) throws OseeCoreException; RelationData clone(RelationData source) throws OseeCoreException; } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/OrcsApiImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/OrcsApiImpl.java index 5bdc97cbb50..5c3555215ec 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/OrcsApiImpl.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/OrcsApiImpl.java @@ -143,14 +143,15 @@ public class OrcsApiImpl implements OrcsApi { module = dataStore.createDataModule(orcsTypes.getArtifactTypes(), orcsTypes.getAttributeTypes()); - RelationFactory relationFactory = new RelationFactory(orcsTypes.getRelationTypes()); - AttributeClassResolver resolver = new AttributeClassResolver(registry, orcsTypes.getAttributeTypes()); AttributeFactory attributeFactory = new AttributeFactory(resolver, module.getDataFactory(), orcsTypes.getAttributeTypes()); ValueProviderFactory providerFactory = new ValueProviderFactory(cacheService.getBranchCache()); + RelationFactory relationFactory = + new RelationFactory(orcsTypes.getRelationTypes(), module.getDataFactory(), providerFactory); + ArtifactFactory artifactFactory = new ArtifactFactory(module.getDataFactory(), attributeFactory, relationFactory, orcsTypes.getArtifactTypes(), providerFactory); @@ -158,7 +159,7 @@ public class OrcsApiImpl implements OrcsApi { proxyManager = new ExternalArtifactManagerImpl(); ArtifactBuilderFactory builderFactory = - new ArtifactBuilderFactoryImpl(logger, proxyManager, artifactFactory, attributeFactory); + new ArtifactBuilderFactoryImpl(logger, proxyManager, artifactFactory, attributeFactory, relationFactory); loaderFactory = new ArtifactLoaderFactoryImpl(module.getDataLoaderFactory(), builderFactory); diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/Artifact.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/Artifact.java index 87b47f29633..4cdec8b32b0 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/Artifact.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/Artifact.java @@ -18,14 +18,12 @@ import org.eclipse.osee.orcs.core.internal.attribute.AttributeManager; import org.eclipse.osee.orcs.core.internal.relation.HasRelationContainer; import org.eclipse.osee.orcs.core.internal.relation.RelationNode; import org.eclipse.osee.orcs.data.ArtifactId; -import org.eclipse.osee.orcs.data.HasBranch; import org.eclipse.osee.orcs.data.HasTransaction; -import org.eclipse.osee.orcs.data.Modifiable; /** * @author Megumi Telles */ -public interface Artifact extends HasBranch, HasRelationContainer, ArtifactId, AttributeManager, HasTransaction, ArtifactVisitable, HasOrcsData<ArtifactData>, Modifiable, RelationNode { +public interface Artifact extends HasRelationContainer, ArtifactId, AttributeManager, HasTransaction, ArtifactVisitable, HasOrcsData<ArtifactData>, RelationNode { void setArtifactType(IArtifactType artifactType) throws OseeCoreException; diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/ArtifactImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/ArtifactImpl.java index 03417d0bb44..5e8434a3e5e 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/ArtifactImpl.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/artifact/ArtifactImpl.java @@ -25,6 +25,7 @@ import org.eclipse.osee.orcs.core.ds.OrcsData; import org.eclipse.osee.orcs.core.internal.attribute.Attribute; import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; import org.eclipse.osee.orcs.core.internal.attribute.AttributeManagerImpl; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; import org.eclipse.osee.orcs.core.internal.relation.RelationContainer; import org.eclipse.osee.orcs.core.internal.relation.order.OrderChange; import org.eclipse.osee.orcs.core.internal.util.ValueProvider; @@ -37,6 +38,7 @@ public class ArtifactImpl extends AttributeManagerImpl implements Artifact { private EditState objectEditState; private ArtifactData artifactData; + private GraphData graph; private final RelationContainer relationContainer; @@ -50,6 +52,16 @@ public class ArtifactImpl extends AttributeManagerImpl implements Artifact { } @Override + public void setGraph(GraphData graph) { + this.graph = graph; + } + + @Override + public GraphData getGraph() { + return graph; + } + + @Override public RelationContainer getRelationContainer() { return relationContainer; } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphAdjacencies.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphAdjacencies.java new file mode 100644 index 00000000000..ed579904d99 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphAdjacencies.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +/** + * @author Roberto E. Escobar + */ +public interface GraphAdjacencies { + // +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilder.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilder.java new file mode 100644 index 00000000000..b75cbb38759 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilder.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.orcs.core.ds.LoadDataHandler; +import org.eclipse.osee.orcs.core.internal.artifact.Artifact; + +/** + * @author Roberto E. Escobar + */ +public interface GraphBuilder extends LoadDataHandler { + + Iterable<GraphData> getGraphs(); + + Iterable<Artifact> getArtifacts(); + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilderFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilderFactory.java new file mode 100644 index 00000000000..680ef5144cb --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphBuilderFactory.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.core.internal.artifact.ArtifactFactory; +import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; +import org.eclipse.osee.orcs.core.internal.graph.impl.GraphBuilderImpl; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; + +/** + * @author Roberto E. Escobar + */ +public class GraphBuilderFactory { + + private final Log logger; + private final ArtifactFactory artifactFactory; + private final AttributeFactory attributeFactory; + private final RelationFactory relationFactory; + + public GraphBuilderFactory(Log logger, ArtifactFactory artifactFactory, AttributeFactory attributeFactory, RelationFactory relationFactory) { + super(); + this.logger = logger; + this.artifactFactory = artifactFactory; + this.attributeFactory = attributeFactory; + this.relationFactory = relationFactory; + } + + public GraphBuilder createBuilderForGraph(GraphData graph) { + return createGraphBuilder(GraphUtil.asProvider(graph)); + } + + public GraphBuilder createGraphBuilder(GraphProvider graphProvider) { + return new GraphBuilderImpl(logger, artifactFactory, attributeFactory, relationFactory, graphProvider); + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphData.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphData.java new file mode 100644 index 00000000000..ce71ac443bc --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphData.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.data.HasBranch; +import org.eclipse.osee.orcs.data.HasLocalId; +import org.eclipse.osee.orcs.data.HasTransaction; + +/** + * @author Roberto E. Escobar + */ +public interface GraphData extends HasBranch, HasTransaction { + + @Override + IOseeBranch getBranch(); + + <T extends GraphNode> T getNode(HasLocalId data); + + <T extends GraphNode> T getNode(int id); + + void addNode(GraphNode node) throws OseeCoreException; + + <T extends GraphNode> T removeNode(HasLocalId node); + + <T extends GraphNode> T removeNode(int id); + + <T extends GraphAdjacencies> T getAdjacencies(HasLocalId node); + + <T extends GraphAdjacencies> T getAdjacencies(int id); + + void addAdjacencies(HasLocalId node, GraphAdjacencies adjacencies); + + void addAdjacencies(int id, GraphAdjacencies adjacencies); + + <T extends GraphAdjacencies> T removeAdjacencies(HasLocalId node); + + <T extends GraphAdjacencies> T removeAdjacencies(int id); + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphFactory.java new file mode 100644 index 00000000000..9b3bc3e5237 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphFactory.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; + +/** + * @author Roberto E. Escobar + */ +public interface GraphFactory { + + GraphData createGraph(IOseeBranch branch, int transactionId) throws OseeCoreException; + + GraphData createGraph(IOseeBranch branch) throws OseeCoreException; + + GraphData createGraphSetToHeadTx(IOseeBranch branch) throws OseeCoreException; + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphNode.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphNode.java new file mode 100644 index 00000000000..4ac8ff1b1cd --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphNode.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.framework.core.data.Identifiable; +import org.eclipse.osee.orcs.data.HasBranch; +import org.eclipse.osee.orcs.data.HasLocalId; + +/** + * @author Roberto E. Escobar + * @author Megumi Telles + */ +public interface GraphNode extends Identifiable, HasLocalId, HasBranch { + + void setGraph(GraphData graph); + + GraphData getGraph(); + + String getExceptionString(); +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphProvider.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphProvider.java new file mode 100644 index 00000000000..d167255417d --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphProvider.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; + +/** + * @author Roberto E. Escobar + */ +public interface GraphProvider { + + GraphData getGraph(OrcsSession session, IOseeBranch branch, int transactionId) throws OseeCoreException; + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtil.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtil.java new file mode 100644 index 00000000000..2be88b510b7 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/GraphUtil.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph; + +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.util.Conditions; +import org.eclipse.osee.orcs.OrcsSession; +import com.google.common.base.Objects; + +/** + * @author Roberto E. Escobar + */ +public final class GraphUtil { + + private GraphUtil() { + // Utility class + } + + public static GraphProvider asProvider(final GraphData graph) { + return new GraphProvider() { + + @Override + public GraphData getGraph(OrcsSession session, IOseeBranch branch, int transactionId) throws OseeCoreException { + Conditions.checkNotNull(branch, "branch", "Invalid branch - can't provide graph"); + Conditions.checkExpressionFailOnTrue(!Objects.equal(graph.getBranch(), branch), + "Invalid branch - Graph's branch[%s] does not equals requested branch[%s]", graph.getBranch(), branch); + Conditions.checkExpressionFailOnTrue(!Objects.equal(graph.getTransaction(), transactionId), + "Invalid transactionId - Graph's transactionId[%s] does not equals requested transactionId[%s]", + graph.getTransaction(), transactionId); + return graph; + } + }; + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImpl.java new file mode 100644 index 00000000000..d9e7fee6c7f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphBuilderImpl.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.util.Conditions; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.core.ds.ArtifactData; +import org.eclipse.osee.orcs.core.ds.AttributeData; +import org.eclipse.osee.orcs.core.ds.LoadDataHandlerAdapter; +import org.eclipse.osee.orcs.core.ds.LoadDescription; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.internal.artifact.Artifact; +import org.eclipse.osee.orcs.core.internal.artifact.ArtifactFactory; +import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; +import org.eclipse.osee.orcs.core.internal.attribute.AttributeManager; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilder; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.graph.GraphProvider; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationNodeAdjacencies; + +/** + * @author Roberto E. Escobar + */ +public class GraphBuilderImpl extends LoadDataHandlerAdapter implements GraphBuilder { + + private final Log logger; + private final ArtifactFactory artifactFactory; + private final AttributeFactory attributeFactory; + private final RelationFactory relationFactory; + private final GraphProvider graphProvider; + + private final Set<Artifact> updated = new LinkedHashSet<Artifact>(); + private GraphData graph; + + public GraphBuilderImpl(Log logger, ArtifactFactory artifactFactory, AttributeFactory attributeFactory, RelationFactory relationFactory, GraphProvider graphProvider) { + super(); + this.logger = logger; + this.graphProvider = graphProvider; + this.artifactFactory = artifactFactory; + this.attributeFactory = attributeFactory; + this.relationFactory = relationFactory; + } + + @Override + public void onLoadStart() { + graph = null; + } + + private GraphData getGraph() throws OseeCoreException { + Conditions.checkNotNull(graph, "graph"); + return graph; + } + + @Override + public void onLoadDescription(LoadDescription data) throws OseeCoreException { + graph = graphProvider.getGraph(data.getSession(), data.getBranch(), data.getTransaction()); + Conditions.checkNotNull(graph, "graph"); + }; + + @Override + public void onData(ArtifactData data) throws OseeCoreException { + GraphData graph = getGraph(); + Artifact artifact = graph.getNode(data); + if (artifact == null) { + artifact = artifactFactory.createArtifact(data); + graph.addNode(artifact); + + RelationNodeAdjacencies adjacencies = relationFactory.createRelationContainer(); + graph.addAdjacencies(data.getLocalId(), adjacencies); + } + updated.add(artifact); + } + + @Override + public void onData(AttributeData data) throws OseeCoreException { + GraphData graph = getGraph(); + AttributeManager container = graph.getNode(data.getArtifactId()); + if (container == null) { + logger.warn("Orphaned attribute detected - data[%s]", data); + } else { + attributeFactory.createAttribute(container, data); + } + } + + @Override + public void onData(RelationData data) throws OseeCoreException { + GraphData graph = getGraph(); + + RelationNodeAdjacencies aAdjacencies = getAdjacencies(graph, data.getArtIdA()); + RelationNodeAdjacencies bAdjacencies = getAdjacencies(graph, data.getArtIdB()); + Relation relation = findRelation(aAdjacencies, data); + if (relation == null) { + relation = findRelation(bAdjacencies, data); + } + if (relation == null) { + relation = relationFactory.createRelation(data); + } + aAdjacencies.add(data.getTypeUuid(), relation); + bAdjacencies.add(data.getTypeUuid(), relation); + } + + private Relation findRelation(RelationNodeAdjacencies adjacencies, RelationData data) throws OseeCoreException { + return adjacencies.getRelation(data.getArtIdA(), data.getTypeUuid(), data.getArtIdB()); + } + + private RelationNodeAdjacencies getAdjacencies(GraphData graph, int id) { + RelationNodeAdjacencies adjacencies = graph.getAdjacencies(id); + if (adjacencies == null) { + adjacencies = relationFactory.createRelationContainer(); + graph.addAdjacencies(id, adjacencies); + } + return adjacencies; + } + + @Override + public void onLoadEnd() { + // + } + + @Override + public Iterable<Artifact> getArtifacts() { + return updated; + } + + @Override + public Iterable<GraphData> getGraphs() { + return graph != null ? Collections.<GraphData> singleton(graph) : Collections.<GraphData> emptyList(); + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImpl.java new file mode 100644 index 00000000000..fa7e2c53747 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphDataImpl.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.util.Conditions; +import org.eclipse.osee.orcs.core.internal.graph.GraphAdjacencies; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.graph.GraphNode; +import org.eclipse.osee.orcs.data.HasLocalId; + +/** + * @author Roberto E. Escobar + */ +public class GraphDataImpl implements GraphData { + + private final Map<Integer, GraphNode> nodesById = new ConcurrentHashMap<Integer, GraphNode>(); + private final Map<Integer, GraphAdjacencies> adjacenciesById = new ConcurrentHashMap<Integer, GraphAdjacencies>(); + + private final IOseeBranch branch; + private final int txId; + + public GraphDataImpl(IOseeBranch branch, int txId) { + super(); + this.branch = branch; + this.txId = txId; + } + + @Override + public IOseeBranch getBranch() { + return branch; + } + + @Override + public int getTransaction() { + return txId; + } + + @Override + public <T extends GraphNode> T getNode(HasLocalId data) { + return getNode(data.getLocalId()); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends GraphNode> T getNode(int id) { + return (T) nodesById.get(id); + } + + @Override + public void addNode(GraphNode node) throws OseeCoreException { + boolean sameBranches = getBranch().equals(node.getBranch()); + Conditions.checkExpressionFailOnTrue(!sameBranches, "Invalid node added to graph. Graph[%s] Node[%s]", this, + node.getExceptionString()); + + GraphData oldGraph = node.getGraph(); + if (!this.equals(oldGraph)) { + if (oldGraph != null) { + oldGraph.removeNode(node); + } + nodesById.put(node.getLocalId(), node); + node.setGraph(this); + } + } + + @Override + public <T extends GraphNode> T removeNode(HasLocalId node) { + return removeNode(node.getLocalId()); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends GraphNode> T removeNode(int id) { + T removed = (T) nodesById.remove(id); + removeAdjacencies(id); + return removed; + } + + @Override + public <T extends GraphAdjacencies> T getAdjacencies(HasLocalId node) { + return getAdjacencies(node.getLocalId()); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends GraphAdjacencies> T getAdjacencies(int id) { + return (T) adjacenciesById.get(id); + } + + @Override + public void addAdjacencies(HasLocalId node, GraphAdjacencies adjacencies) { + addAdjacencies(node.getLocalId(), adjacencies); + } + + @Override + public void addAdjacencies(int id, GraphAdjacencies adjacencies) { + adjacenciesById.put(id, adjacencies); + } + + @Override + public <T extends GraphAdjacencies> T removeAdjacencies(HasLocalId node) { + return removeAdjacencies(node.getLocalId()); + } + + @SuppressWarnings("unchecked") + @Override + public <T extends GraphAdjacencies> T removeAdjacencies(int id) { + return (T) adjacenciesById.remove(id); + } + + @Override + public String toString() { + return String.format("Graph - branch[%s] txId[%s] nodes[%s] adjacencies[%s]", getBranch(), getTransaction(), + nodesById.size(), adjacenciesById.size()); + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphFactoryImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphFactoryImpl.java new file mode 100644 index 00000000000..ed69bf235eb --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/graph/impl/GraphFactoryImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.orcs.core.internal.graph.impl; + +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.Branch; +import org.eclipse.osee.framework.core.model.TransactionRecord; +import org.eclipse.osee.framework.core.model.cache.BranchCache; +import org.eclipse.osee.framework.core.model.cache.TransactionCache; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.graph.GraphFactory; + +/** + * @author Roberto E. Escobar + */ +public class GraphFactoryImpl implements GraphFactory { + + private final BranchCache branchCache; + private final TransactionCache txCache; + + public GraphFactoryImpl(BranchCache branchCache, TransactionCache txCache) { + super(); + this.branchCache = branchCache; + this.txCache = txCache; + } + + @Override + public GraphData createGraph(IOseeBranch branch, int transactionId) { + return new GraphDataImpl(branch, transactionId); + } + + @Override + public GraphData createGraph(IOseeBranch branch) { + return new GraphDataImpl(branch, Integer.MIN_VALUE); + } + + @Override + public GraphData createGraphSetToHeadTx(IOseeBranch branch) throws OseeCoreException { + Branch fullBranch = branchCache.get(branch); + TransactionRecord headTransaction = txCache.getHeadTransaction(fullBranch); + return createGraph(branch, headTransaction.getId()); + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderFactoryImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderFactoryImpl.java index 26d8a6c4fb3..3c28ba94655 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderFactoryImpl.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderFactoryImpl.java @@ -17,6 +17,7 @@ import org.eclipse.osee.orcs.core.internal.ArtifactBuilderFactory; import org.eclipse.osee.orcs.core.internal.artifact.ArtifactFactory; import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; import org.eclipse.osee.orcs.core.internal.proxy.ExternalArtifactManager; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; /** * @author Andrew M. Finkbeiner @@ -28,18 +29,20 @@ public class ArtifactBuilderFactoryImpl implements ArtifactBuilderFactory { private final ArtifactFactory artifactFactory; private final AttributeFactory attributeFactory; + private final RelationFactory relationFactory; - public ArtifactBuilderFactoryImpl(Log logger, ExternalArtifactManager proxyFactory, ArtifactFactory artifactFactory, AttributeFactory attributeFactory) { + public ArtifactBuilderFactoryImpl(Log logger, ExternalArtifactManager proxyFactory, ArtifactFactory artifactFactory, AttributeFactory attributeFactory, RelationFactory relationFactory) { super(); this.logger = logger; this.proxyFactory = proxyFactory; this.artifactFactory = artifactFactory; this.attributeFactory = attributeFactory; + this.relationFactory = relationFactory; } @Override public ArtifactBuilder createArtifactBuilder(OrcsSession session) { - return new ArtifactBuilderImpl(logger, proxyFactory, artifactFactory, attributeFactory, session); + return new ArtifactBuilderImpl(logger, proxyFactory, artifactFactory, attributeFactory, relationFactory, session); } } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImpl.java index 1d550e11149..92ce2fca06b 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImpl.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactBuilderImpl.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.osee.framework.core.exception.OseeCoreException; -import org.eclipse.osee.framework.core.util.Conditions; import org.eclipse.osee.logger.Log; import org.eclipse.osee.orcs.OrcsSession; import org.eclipse.osee.orcs.core.ds.ArtifactData; @@ -34,6 +33,7 @@ import org.eclipse.osee.orcs.core.internal.attribute.AttributeFactory; import org.eclipse.osee.orcs.core.internal.attribute.AttributeManager; import org.eclipse.osee.orcs.core.internal.proxy.ExternalArtifactManager; import org.eclipse.osee.orcs.core.internal.relation.RelationContainer; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; import org.eclipse.osee.orcs.data.ArtifactReadable; /** @@ -45,6 +45,7 @@ public class ArtifactBuilderImpl extends LoadDataHandlerAdapter implements Artif private final ExternalArtifactManager proxyFactory; private final ArtifactFactory artifactFactory; private final AttributeFactory attributeFactory; + private final RelationFactory relationFactory; private final OrcsSession session; private final Set<Artifact> created = new HashSet<Artifact>(); @@ -53,12 +54,13 @@ public class ArtifactBuilderImpl extends LoadDataHandlerAdapter implements Artif private final Map<Integer, Artifact> artifacts = new LinkedHashMap<Integer, Artifact>(); private List<ArtifactReadable> readables; - public ArtifactBuilderImpl(Log logger, ExternalArtifactManager proxyFactory, ArtifactFactory artifactFactory, AttributeFactory attributeFactory, OrcsSession session) { + public ArtifactBuilderImpl(Log logger, ExternalArtifactManager proxyFactory, ArtifactFactory artifactFactory, AttributeFactory attributeFactory, RelationFactory relationFactory, OrcsSession session) { super(); this.logger = logger; this.proxyFactory = proxyFactory; this.artifactFactory = artifactFactory; this.attributeFactory = attributeFactory; + this.relationFactory = relationFactory; this.session = session; } @@ -139,9 +141,15 @@ public class ArtifactBuilderImpl extends LoadDataHandlerAdapter implements Artif @Override public void onData(RelationData data) throws OseeCoreException { - RelationContainer container = relations.get(data.getParentId()); - Conditions.checkNotNull(container, "RelationContainer", - "Invalid relation data container not found - data[%s]. . ", data); + addRelationFor(data.getArtIdA(), data); + addRelationFor(data.getArtIdB(), data); + } + + private void addRelationFor(int id, RelationData data) throws OseeCoreException { + RelationContainer container = relations.get(id); + if (container == null) { + container = relationFactory.createRelationContainer(id); + } container.add(data); } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactLoaderInvocationHandler.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactLoaderInvocationHandler.java index a070a093b9d..f177c3cc554 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactLoaderInvocationHandler.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/loader/ArtifactLoaderInvocationHandler.java @@ -15,12 +15,12 @@ import java.lang.reflect.Method; import java.util.List; import org.eclipse.osee.executor.admin.HasCancellation; import org.eclipse.osee.framework.core.data.ResultSet; -import org.eclipse.osee.framework.core.data.ResultSetList; import org.eclipse.osee.framework.core.exception.OseeCoreException; import org.eclipse.osee.orcs.OrcsSession; import org.eclipse.osee.orcs.core.ds.DataLoader; import org.eclipse.osee.orcs.core.internal.ArtifactBuilder; import org.eclipse.osee.orcs.core.internal.ArtifactBuilderFactory; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; import org.eclipse.osee.orcs.data.ArtifactReadable; /** @@ -66,7 +66,7 @@ public class ArtifactLoaderInvocationHandler implements InvocationHandler { private ResultSet<ArtifactReadable> getResults(HasCancellation cancellation) throws OseeCoreException { List<ArtifactReadable> data = load(cancellation); - return new ResultSetList<ArtifactReadable>(data); + return ResultSets.newResultSet(data); } private boolean isLoad(Method method) { diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/Relation.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/Relation.java new file mode 100644 index 00000000000..3e78e92390c --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/Relation.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.enums.ModificationType; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.Branch; +import org.eclipse.osee.orcs.core.ds.HasOrcsData; +import org.eclipse.osee.orcs.core.ds.OrcsData; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.internal.util.OrcsWriteable; +import org.eclipse.osee.orcs.core.internal.util.ValueProvider; +import org.eclipse.osee.orcs.data.RelationTypes; + +/** + * @author Roberto E. Escobar + */ +public class Relation implements HasOrcsData<RelationData>, OrcsWriteable { + + private final RelationTypes relationTypes; + private final ValueProvider<Branch, OrcsData> branchProvider; + + private RelationData relationData; + private boolean isDirty; + + public Relation(RelationTypes relationTypes, RelationData relationData, ValueProvider<Branch, OrcsData> branchProvider) { + super(); + this.relationTypes = relationTypes; + this.relationData = relationData; + this.branchProvider = branchProvider; + } + + @Override + public RelationData getOrcsData() { + return relationData; + } + + @Override + public void setOrcsData(RelationData data) { + this.relationData = data; + branchProvider.setOrcsData(data); + } + + public IRelationType getRelationType() throws OseeCoreException { + return relationTypes.getByUuid(getOrcsData().getTypeUuid()); + } + + public ModificationType getModificationType() { + return getOrcsData().getModType(); + } + + @Override + public boolean isDeleted() { + return getModificationType().isDeleted(); + } + + @Override + public void delete() { + markAsChanged(ModificationType.DELETED); + } + + public Branch getBranch() throws OseeCoreException { + return branchProvider.get(); + } + + @Override + public boolean isDirty() { + return isDirty; + } + + public void clearDirty() { + setDirtyFlag(false); + } + + public void setDirty() { + setDirtyFlag(true); + } + + private void setDirtyFlag(boolean dirty) { + this.isDirty = dirty; + } + + public String getRationale() { + return getOrcsData().getRationale(); + } + + public boolean isOfType(IRelationType oseeType) throws OseeCoreException { + return getRelationType().equals(oseeType); + } + + public void setRationale(String rationale) { + String toSet = rationale; + if (toSet == null) { + toSet = ""; + } + if (!toSet.equals(getOrcsData().getRationale())) { + getOrcsData().setRationale(rationale); + markAsChanged(ModificationType.MODIFIED); + } + } + + protected void markAsChanged(ModificationType modificationType) { + ModificationType modType = computeModType(getOrcsData().getModType(), modificationType); + getOrcsData().setModType(modType); + setDirty(); + } + + private ModificationType computeModType(ModificationType original, ModificationType newModType) { + ModificationType toReturn = original; + if (original != ModificationType.DELETED || original != ModificationType.ARTIFACT_DELETED) { + toReturn = newModType; + } + return toReturn; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((relationData == null) ? 0 : relationData.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Relation other = (Relation) obj; + if (relationData == null) { + if (other.relationData != null) { + return false; + } + } else if (!relationData.equals(other.relationData)) { + return false; + } + return true; + } + + public int getLocalIdForSide(RelationSide side) { + return getOrcsData().getArtIdOn(side); + } + + @Override + public boolean isDeleteAllowed() { + return !isDeleted(); + } + + @Override + public void unDelete() { + getOrcsData().setModType(ModificationType.UNDELETED); + } + + @Override + public String toString() { + return "Relation [relationData=" + relationData + ", isDirty=" + isDirty + "]"; + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationFactory.java index 39cbeeb30de..c63167c953b 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationFactory.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Boeing. + * 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 @@ -10,18 +10,58 @@ *******************************************************************************/ package org.eclipse.osee.orcs.core.internal.relation; +import org.eclipse.osee.framework.core.data.IOseeBranch; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.Branch; +import org.eclipse.osee.framework.jdk.core.util.Strings; +import org.eclipse.osee.orcs.core.ds.OrcsData; +import org.eclipse.osee.orcs.core.ds.RelationData; +import org.eclipse.osee.orcs.core.ds.RelationDataFactory; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationNodeAdjacencies; +import org.eclipse.osee.orcs.core.internal.util.OrcsConditions; +import org.eclipse.osee.orcs.core.internal.util.ValueProvider; +import org.eclipse.osee.orcs.core.internal.util.ValueProviderFactory; import org.eclipse.osee.orcs.data.RelationTypes; +/** + * @author Roberto E. Escobar + */ public class RelationFactory { - private final RelationTypes relationTypeCache; + private final RelationTypes relationTypes; + private final RelationDataFactory relationDataFactory; + private final ValueProviderFactory providerFactory; - public RelationFactory(RelationTypes relationTypeCache) { - this.relationTypeCache = relationTypeCache; + public RelationFactory(RelationTypes relationTypes, RelationDataFactory relationDataFactory, ValueProviderFactory providerFactory) { + this.relationTypes = relationTypes; + this.relationDataFactory = relationDataFactory; + this.providerFactory = providerFactory; } public RelationContainer createRelationContainer(int artId) { - return new RelationContainerImpl(artId, relationTypeCache); + return new RelationContainerImpl(artId, relationTypes); } + public RelationNodeAdjacencies createRelationContainer() { + return new RelationNodeAdjacencies(); + } + + public Relation createRelation(RelationData data) { + ValueProvider<Branch, OrcsData> branch = providerFactory.createBranchProvider(data); + return new Relation(relationTypes, data, branch); + } + + public Relation createRelation(RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException { + OrcsConditions.checkBranch(aNode, bNode); + OrcsConditions.checkRelateSelf(aNode, bNode); + IOseeBranch branch = aNode.getBranch(); + RelationData data = relationDataFactory.createRelationData(type, branch, aNode, bNode, Strings.emptyString()); + return createRelation(data); + } + + public Relation clone(Relation src) throws OseeCoreException { + RelationData data = relationDataFactory.clone(src.getOrcsData()); + return createRelation(data); + } } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationGraphImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationGraphImpl.java index 389788e1868..abde78f60c4 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationGraphImpl.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationGraphImpl.java @@ -20,7 +20,6 @@ import org.eclipse.osee.framework.core.data.IOseeBranch; import org.eclipse.osee.framework.core.data.IRelationType; import org.eclipse.osee.framework.core.data.IRelationTypeSide; import org.eclipse.osee.framework.core.data.ResultSet; -import org.eclipse.osee.framework.core.data.ResultSetList; import org.eclipse.osee.framework.core.enums.CoreRelationTypes; import org.eclipse.osee.framework.core.enums.LoadLevel; import org.eclipse.osee.framework.core.enums.RelationSide; @@ -28,6 +27,7 @@ import org.eclipse.osee.framework.core.exception.OseeCoreException; import org.eclipse.osee.orcs.OrcsSession; import org.eclipse.osee.orcs.core.internal.ArtifactLoaderFactory; import org.eclipse.osee.orcs.core.internal.proxy.ExternalArtifactManager; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; import org.eclipse.osee.orcs.data.ArtifactReadable; import org.eclipse.osee.orcs.data.GraphReadable; import org.eclipse.osee.orcs.data.RelationTypes; @@ -95,7 +95,7 @@ public class RelationGraphImpl implements GraphReadable { } else { toReturn = loadRelated(art.getBranch(), artIds); } - return new ResultSetList<ArtifactReadable>(toReturn); + return ResultSets.newResultSet(toReturn); } @Override diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManager.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManager.java new file mode 100644 index 00000000000..4901328e372 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManager.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2012 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.orcs.core.internal.relation; + +import java.util.Collection; +import java.util.List; +import org.eclipse.osee.framework.core.data.IRelationSorterId; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; + +/** + * @author Andrew M. Finkbeiner + * @author Roberto E. Escobar + * @author Megumi Telles + */ +public interface RelationManager { + + int getMaximumRelationAllowed(OrcsSession session, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException; + + Collection<? extends IRelationType> getValidRelationTypes(OrcsSession session, RelationNode node) throws OseeCoreException; + + /////////////////////////////////////// + + void accept(OrcsSession session, GraphData graph, RelationNode node, RelationVisitor visitor) throws OseeCoreException; + + /////////////////////////////////////// + + boolean hasDirtyRelations(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException; + + Collection<? extends IRelationType> getExistingRelationTypes(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException; + + int getRelatedCount(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException; + + int getRelatedCount(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side, DeletionFlag includeDeleted) throws OseeCoreException; + + boolean areRelated(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException; + + String getRationale(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException; + + /////////////////////////////////////// + + <T extends RelationNode> T getParent(OrcsSession session, GraphData graph, RelationNode child) throws OseeCoreException; + + <T extends RelationNode> ResultSet<T> getChildren(OrcsSession session, GraphData graph, RelationNode parent) throws OseeCoreException; + + <T extends RelationNode> ResultSet<T> getRelated(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException; + + /////////////////////////////////////// + + void addChild(OrcsSession session, GraphData graph, RelationNode parent, RelationNode child) throws OseeCoreException; + + void addChildren(OrcsSession session, GraphData graph, RelationNode parent, List<? extends RelationNode> children) throws OseeCoreException; + + void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException; + + void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale) throws OseeCoreException; + + void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, IRelationSorterId sortType) throws OseeCoreException; + + void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale, IRelationSorterId sortType) throws OseeCoreException; + + void setRationale(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale) throws OseeCoreException; + + void unrelate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException; + + void unrelateFromAll(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException; + + void unrelateFromAll(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException; + + void cloneRelations(OrcsSession session, RelationNode source, RelationNode destination) throws OseeCoreException; + + /////////////////////////////////////// +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerFactory.java new file mode 100644 index 00000000000..ef270d8227f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationManagerFactory.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationManagerImpl; +import org.eclipse.osee.orcs.core.internal.relation.impl.RelationResolverImpl; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderManagerFactory; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderParser; +import org.eclipse.osee.orcs.core.internal.relation.sorter.SorterProvider; +import org.eclipse.osee.orcs.data.RelationTypes; + +/** + * @author Roberto E. Escobar + */ +public final class RelationManagerFactory { + + private RelationManagerFactory() { + // Static Factory + } + + public static RelationManager createRelationManager(Log logger, RelationTypes relationTypes, RelationFactory relationFactory, RelationNodeLoader loader) { + OrderParser orderParser = new OrderParser(relationTypes); + SorterProvider sorterProvider = new SorterProvider(relationTypes); + OrderManagerFactory orderManagerFactory = new OrderManagerFactory(orderParser, sorterProvider); + + RelationResolver resolver = new RelationResolverImpl(loader); + RelationTypeValidity validity = new RelationTypeValidity(relationTypes); + + return new RelationManagerImpl(logger, validity, resolver, relationFactory, orderManagerFactory); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNode.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNode.java index 2b5f09768af..518fb80befd 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNode.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNode.java @@ -11,21 +11,17 @@ package org.eclipse.osee.orcs.core.internal.relation; import org.eclipse.osee.framework.core.data.IArtifactType; -import org.eclipse.osee.framework.core.data.Identifiable; import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.core.internal.graph.GraphNode; import org.eclipse.osee.orcs.core.internal.relation.order.OrderStore; -import org.eclipse.osee.orcs.data.CanDelete; -import org.eclipse.osee.orcs.data.HasLocalId; +import org.eclipse.osee.orcs.core.internal.util.OrcsWriteable; /** * @author Roberto E. Escobar * @author Megumi Telles */ - -public interface RelationNode extends Identifiable, CanDelete, HasLocalId, OrderStore { +public interface RelationNode extends OrcsWriteable, GraphNode, OrderStore { IArtifactType getArtifactType() throws OseeCoreException; - String getExceptionString(); - }
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNodeLoader.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNodeLoader.java new file mode 100644 index 00000000000..2acb5ae58c5 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationNodeLoader.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import java.util.Collection; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; + +/** + * @author Roberto E. Escobar + */ +public interface RelationNodeLoader { + + <T extends RelationNode> Iterable<T> loadNodes(OrcsSession session, GraphData graph, Collection<Integer> ids, LoadLevel level) throws OseeCoreException; + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationResolver.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationResolver.java new file mode 100644 index 00000000000..95310c9fe04 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationResolver.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import java.util.List; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; + +/** + * @author Roberto E. Escobar + */ +public interface RelationResolver { + + <T extends RelationNode> List<T> resolve(OrcsSession session, GraphData graph, List<Relation> links, RelationSide... sides) throws OseeCoreException; + + void resolve(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException; + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidity.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidity.java index 71f1a686b60..56a28ceaeaa 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidity.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationTypeValidity.java @@ -15,7 +15,6 @@ import java.util.Collection; import java.util.List; import org.eclipse.osee.framework.core.data.IArtifactType; import org.eclipse.osee.framework.core.data.IRelationType; -import org.eclipse.osee.framework.core.data.IRelationTypeSide; import org.eclipse.osee.framework.core.enums.RelationSide; import org.eclipse.osee.framework.core.enums.RelationTypeMultiplicity; import org.eclipse.osee.framework.core.exception.OseeCoreException; @@ -37,57 +36,54 @@ public class RelationTypeValidity { this.relationTypes = relationTypes; } - public void checkRelationTypeMultiplicity(RelationNode node, IRelationTypeSide typeAndSide, int count) throws OseeCoreException { - MultiplicityState state = getRelationMultiplicityState(typeAndSide, count); + public void checkRelationTypeMultiplicity(IRelationType type, RelationNode node, RelationSide side, int count) throws OseeCoreException { + MultiplicityState state = getRelationMultiplicityState(type, side, count); switch (state) { case MAX_VIOLATION: - throw new OseeStateException("Relation type [%s] exceeds max occurrence rule on [%s]", typeAndSide, + throw new OseeStateException("Relation type [%s] on [%s] exceeds max occurrence rule on [%s]", type, side, node.getExceptionString()); case MIN_VIOLATION: - throw new OseeStateException("Relation type [%s] is less than min occurrence rule on [%s]", typeAndSide, - node.getExceptionString()); + throw new OseeStateException("Relation type [%s] on [%s] is less than min occurrence rule on [%s]", type, + side, node.getExceptionString()); default: break; } } - public boolean isRelationTypeValid(IArtifactType artifactType, IRelationTypeSide relationTypeSide) throws OseeCoreException { - IRelationType relationType = relationTypes.getByUuid(relationTypeSide.getGuid()); - RelationSide relationSide = relationTypeSide.getSide(); - return isRelationTypeValid(artifactType, relationType, relationSide); - } + public void checkRelationTypeValid(IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + Conditions.checkNotNull(type, "type"); + Conditions.checkNotNull(node, "node"); + Conditions.checkNotNull(side, "relationSide"); - public void checkRelationTypeValid(RelationNode node, IRelationTypeSide relationTypeSide) throws OseeCoreException { - IRelationType relationType = relationTypes.getByUuid(relationTypeSide.getGuid()); - RelationSide relationSide = relationTypeSide.getSide(); IArtifactType artifactType = node.getArtifactType(); - boolean isValid = isRelationTypeValid(artifactType, relationType, relationSide); + boolean isValid = isRelationTypeValid(type, artifactType, side); Conditions.checkExpressionFailOnTrue( !isValid, "Relation validity error for [%s] - ArtifactType [%s] does not belong on side [%s] of relation [%s] - only items of type [%s] are allowed", - node.getExceptionString(), artifactType, relationSide.name(), relationType, - relationTypes.getArtifactType(relationType, relationSide)); + node.getExceptionString(), artifactType, side.name(), type, relationTypes.getArtifactType(type, side)); } - public int getMaximumRelationsAllowed(IArtifactType artifactType, IRelationTypeSide relationTypeSide) throws OseeCoreException { + public int getMaximumRelationsAllowed(IRelationType type, IArtifactType artifactType, RelationSide side) throws OseeCoreException { + Conditions.checkNotNull(type, "relationType"); Conditions.checkNotNull(artifactType, "artifactType"); - Conditions.checkNotNull(relationTypeSide, "relationTypeSide"); + Conditions.checkNotNull(side, "relationSide"); + checkTypeExists(type); + int toReturn = 0; - IRelationType relationType = relationTypes.getByUuid(relationTypeSide.getGuid()); - RelationSide relationSide = relationTypeSide.getSide(); - if (relationTypes.isArtifactTypeAllowed(relationType, relationSide, artifactType)) { - toReturn = relationTypes.getMultiplicity(relationType).getLimit(relationSide); + if (relationTypes.isArtifactTypeAllowed(type, side, artifactType)) { + toReturn = relationTypes.getMultiplicity(type).getLimit(side); } return toReturn; } - public MultiplicityState getRelationMultiplicityState(IRelationTypeSide relationTypeSide, int count) throws OseeCoreException { - IRelationType relationType = relationTypes.getByUuid(relationTypeSide.getGuid()); - RelationSide relationSide = relationTypeSide.getSide(); - RelationTypeMultiplicity multiplicity = relationTypes.getMultiplicity(relationType); + public MultiplicityState getRelationMultiplicityState(IRelationType type, RelationSide side, int count) throws OseeCoreException { + Conditions.checkNotNull(type, "type"); + Conditions.checkNotNull(side, "relationSide"); + + RelationTypeMultiplicity multiplicity = relationTypes.getMultiplicity(type); MultiplicityState toReturn = MultiplicityState.IS_VALID; - int limit = multiplicity.getLimit(relationSide); + int limit = multiplicity.getLimit(side); if (count > limit) { toReturn = MultiplicityState.MAX_VIOLATION; } @@ -106,14 +102,22 @@ public class RelationTypeValidity { return toReturn; } - private boolean isRelationTypeValid(IArtifactType artifactType, IRelationType relationType, RelationSide relationSide) throws OseeCoreException { - return getRelationSideMax(artifactType, relationType, relationSide) > 0; + public boolean isRelationTypeValid(IRelationType relationType, IArtifactType artifactType, RelationSide relationSide) throws OseeCoreException { + checkTypeExists(relationType); + Conditions.checkNotNull(artifactType, "artifactType"); + Conditions.checkNotNull(relationSide, "relationSide"); + return getRelationSideMax(relationType, artifactType, relationSide) > 0; + } + + private void checkTypeExists(IRelationType type) throws OseeCoreException { + Conditions.checkExpressionFailOnTrue(!relationTypes.exists(type), "relationType [%s] does not exist", type); } private boolean isTypeAllowed(IArtifactType artifactType, IRelationType relationType) throws OseeCoreException { boolean result = false; + checkTypeExists(relationType); for (RelationSide side : RelationSide.values()) { - int sideMax = getRelationSideMax(artifactType, relationType, side); + int sideMax = getRelationSideMax(relationType, artifactType, side); if (sideMax > 0) { result = true; break; @@ -122,7 +126,7 @@ public class RelationTypeValidity { return result; } - private int getRelationSideMax(IArtifactType artifactType, IRelationType relationType, RelationSide relationSide) throws OseeCoreException { + private int getRelationSideMax(IRelationType relationType, IArtifactType artifactType, RelationSide relationSide) throws OseeCoreException { int toReturn = 0; if (relationTypes.isArtifactTypeAllowed(relationType, relationSide, artifactType)) { toReturn = relationTypes.getMultiplicity(relationType).getLimit(relationSide); diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationVisitor.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationVisitor.java new file mode 100644 index 00000000000..ee793716bd1 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/RelationVisitor.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation; + +import org.eclipse.osee.framework.core.exception.OseeCoreException; + +/** + * @author Roberto E. Escobar + */ +public interface RelationVisitor { + + void visit(Relation relation) throws OseeCoreException; + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImpl.java new file mode 100644 index 00000000000..dc4dccacdac --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationManagerImpl.java @@ -0,0 +1,444 @@ +/******************************************************************************* + * Copyright (c) 2012 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.orcs.core.internal.relation.impl; + +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Child; +import static org.eclipse.osee.framework.core.enums.CoreRelationTypes.Default_Hierarchical__Parent; +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.RelationSide.SIDE_A; +import static org.eclipse.osee.framework.core.enums.RelationSide.SIDE_B; +import static org.eclipse.osee.framework.core.util.Conditions.checkNotNull; +import static org.eclipse.osee.framework.jdk.core.util.Strings.emptyString; +import static org.eclipse.osee.orcs.core.internal.util.OrcsConditions.checkBranch; +import static org.eclipse.osee.orcs.core.internal.util.OrcsConditions.checkOnGraph; +import static org.eclipse.osee.orcs.core.internal.util.OrcsConditions.checkRelateSelf; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +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.IRelationSorterId; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.IRelationTypeSide; +import org.eclipse.osee.framework.core.data.Identifiable; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.framework.core.model.RelationTypeSide; +import org.eclipse.osee.framework.core.util.Conditions; +import org.eclipse.osee.logger.Log; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationFactory; +import org.eclipse.osee.orcs.core.internal.relation.RelationManager; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationResolver; +import org.eclipse.osee.orcs.core.internal.relation.RelationTypeValidity; +import org.eclipse.osee.orcs.core.internal.relation.RelationVisitor; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderManager; +import org.eclipse.osee.orcs.core.internal.relation.order.OrderManagerFactory; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; + +/** + * @author Andrew M. Finkbeiner + * @author Roberto E. Escobar + */ +public class RelationManagerImpl implements RelationManager { + + private static final IRelationType DEFAULT_HIERARCHY = Default_Hierarchical__Parent; + private static final RelationSide IS_PARENT = Default_Hierarchical__Parent.getSide(); + private static final RelationSide IS_CHILD = Default_Hierarchical__Child.getSide(); + + private final Log logger; + private final RelationTypeValidity validity; + private final RelationResolver resolver; + private final RelationFactory relationFactory; + private final OrderManagerFactory orderFactory; + + public RelationManagerImpl(Log logger, RelationTypeValidity validity, RelationResolver resolver, RelationFactory relationFactory, OrderManagerFactory orderFactory) { + super(); + this.logger = logger; + this.validity = validity; + this.resolver = resolver; + this.relationFactory = relationFactory; + this.orderFactory = orderFactory; + } + + @Override + public int getMaximumRelationAllowed(OrcsSession session, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + Conditions.checkNotNull(node, "node"); + return validity.getMaximumRelationsAllowed(type, node.getArtifactType(), side); + } + + @Override + public Collection<? extends IRelationType> getValidRelationTypes(OrcsSession session, RelationNode node) throws OseeCoreException { + Conditions.checkNotNull(node, "node"); + return validity.getValidRelationTypes(node.getArtifactType()); + } + + @Override + public void accept(OrcsSession session, GraphData graph, RelationNode node, RelationVisitor visitor) throws OseeCoreException { + checkOnGraph(graph, node); + ensureRelationsInitialized(session, graph, node); + RelationNodeAdjacencies container = graph.getAdjacencies(node); + if (container != null) { + container.accept(visitor); + } else { + logger.warn("Unable to find relation container for [%s]", node.getExceptionString()); + } + } + + @Override + public boolean hasDirtyRelations(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException { + checkOnGraph(graph, node); + ensureRelationsInitialized(session, graph, node); + RelationNodeAdjacencies container = graph.getAdjacencies(node); + return container != null ? container.hasDirty() : false; + } + + @Override + public Collection<? extends IRelationType> getExistingRelationTypes(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException { + checkOnGraph(graph, node); + ensureRelationsInitialized(session, graph, node); + RelationNodeAdjacencies container = graph.getAdjacencies(node); + Collection<? extends IRelationType> toReturn = null; + if (container != null) { + toReturn = container.getExistingTypes(DeletionFlag.EXCLUDE_DELETED); + } else { + logger.warn("Unable to find relation container for [%s]", node.getExceptionString()); + toReturn = Collections.<IRelationType> emptyList(); + } + return toReturn; + } + + @Override + public int getRelatedCount(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + return getRelatedCount(session, graph, type, node, side, EXCLUDE_DELETED); + } + + @Override + public int getRelatedCount(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side, DeletionFlag includeDeleted) throws OseeCoreException { + return getRelations(session, graph, type, node, side, includeDeleted).size(); + } + + @Override + public boolean areRelated(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException { + return getRelation(session, graph, aNode, type, bNode, EXCLUDE_DELETED).size() > 0; + } + + @Override + public <T extends RelationNode> T getParent(OrcsSession session, GraphData graph, RelationNode child) throws OseeCoreException { + ResultSet<T> toReturn = getRelated(session, graph, DEFAULT_HIERARCHY, child, IS_CHILD); + return toReturn.getOneOrNull(); + } + + @Override + public <T extends RelationNode> ResultSet<T> getChildren(OrcsSession session, GraphData graph, RelationNode parent) throws OseeCoreException { + return getRelated(session, graph, DEFAULT_HIERARCHY, parent, IS_PARENT); + } + + @Override + public <T extends RelationNode> ResultSet<T> getRelated(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + List<Relation> links = getRelations(session, graph, type, node, side, EXCLUDE_DELETED); + List<T> result = null; + if (links.isEmpty()) { + result = Collections.emptyList(); + } else { + RelationSide otherSide = side.oppositeSide(); + result = resolver.resolve(session, graph, links, otherSide); + if (result.size() > 1) { + OrderManager orderManager = orderFactory.createOrderManager(node); + IRelationTypeSide key = asTypeSide(type, otherSide); + orderManager.sort(key, result); + } + } + return ResultSets.newResultSet(result); + } + + @Override + public String getRationale(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException { + ResultSet<Relation> result = getRelation(session, graph, aNode, type, bNode, EXCLUDE_DELETED); + return result.getExactlyOne().getRationale(); + } + + @Override + public void setRationale(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale) throws OseeCoreException { + ResultSet<Relation> result = getRelation(session, graph, aNode, type, bNode, EXCLUDE_DELETED); + Relation relation = result.getExactlyOne(); + relation.setRationale(rationale); + } + + ///////////////////////// RELATE NODES /////////////////// + @Override + public void addChild(OrcsSession session, GraphData graph, RelationNode parent, RelationNode child) throws OseeCoreException { + unrelateFromAll(session, graph, DEFAULT_HIERARCHY, child, IS_CHILD); + relate(session, graph, parent, DEFAULT_HIERARCHY, child); + } + + @Override + public void addChildren(OrcsSession session, GraphData graph, RelationNode parent, List<? extends RelationNode> children) throws OseeCoreException { + for (RelationNode child : children) { + addChild(session, graph, parent, child); + } + } + + @Override + public void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException { + relate(session, graph, aNode, type, bNode, emptyString(), RelationOrderBaseTypes.PREEXISTING); + } + + @Override + public void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale) throws OseeCoreException { + relate(session, graph, aNode, type, bNode, rationale, RelationOrderBaseTypes.PREEXISTING); + } + + @Override + public void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, IRelationSorterId sortType) throws OseeCoreException { + relate(session, graph, aNode, type, bNode, emptyString(), sortType); + } + + @Override + public void relate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, String rationale, IRelationSorterId sortType) throws OseeCoreException { + checkOnGraph(graph, aNode, bNode); + checkBranch(aNode, bNode); + checkRelateSelf(aNode, bNode); + + checkTypeAndCanAdd(session, graph, type, aNode, SIDE_A); + checkTypeAndCanAdd(session, graph, type, bNode, SIDE_B); + + Relation relation = getRelation(session, graph, aNode, type, bNode, INCLUDE_DELETED).getOneOrNull(); + boolean updated = false; + if (relation == null) { + relation = relationFactory.createRelation(aNode, type, bNode); + graph.<RelationNodeAdjacencies> getAdjacencies(aNode).add(type.getGuid(), relation); + graph.<RelationNodeAdjacencies> getAdjacencies(bNode).add(type.getGuid(), relation); + updated = true; + } + if (relation.isDeleted()) { + relation.unDelete(); + updated = true; + } + if (updated) { + relation.setDirty(); + order(session, graph, type, aNode, SIDE_A, sortType, OrderOp.ADD_TO_ORDER, Collections.singleton(bNode)); + } + } + + private void checkTypeAndCanAdd(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + validity.checkRelationTypeValid(type, node, side); + checkMultiplicityCanAdd(session, graph, type, node, side); + } + + private void checkMultiplicityCanAdd(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + int currentCount = getRelatedCount(session, graph, type, node, side); + validity.checkRelationTypeMultiplicity(type, node, side, currentCount + 1); + } + + ///////////////////////// UNRELATE NODES /////////////////// + @Override + public void unrelate(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode) throws OseeCoreException { + Relation relation = getRelation(session, graph, aNode, type, bNode, EXCLUDE_DELETED).getOneOrNull(); + boolean modified = false; + if (relation != null) { + relation.delete(); + modified = true; + } + if (modified) { + order(session, graph, type, aNode, SIDE_A, OrderOp.REMOVE_FROM_ORDER, Collections.singleton(bNode)); + } + } + + @Override + public void unrelateFromAll(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side) throws OseeCoreException { + List<Relation> relations = getRelations(session, graph, type, node, side, EXCLUDE_DELETED); + + RelationSide otherSide = side.oppositeSide(); + resolver.resolve(session, graph, relations, otherSide); + + boolean modified = false; + Set<RelationNode> otherNodes = new LinkedHashSet<RelationNode>(); + for (Relation relation : relations) { + relation.delete(); + Integer artId = relation.getLocalIdForSide(otherSide); + RelationNode otherNode = graph.getNode(artId); + otherNodes.add(otherNode); + modified = true; + } + if (modified) { + order(session, graph, type, node, side, OrderOp.REMOVE_FROM_ORDER, otherNodes); + } + } + + @Override + public void unrelateFromAll(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException { + unrelate(session, graph, node, true); + } + + private void unrelate(OrcsSession session, GraphData graph, RelationNode node, boolean reorderRelations) throws OseeCoreException { + checkNotNull(node, "node"); + if (node.isDeleteAllowed()) { + + List<Relation> relations = getRelations(session, graph, node, EXCLUDE_DELETED); + resolver.resolve(session, graph, relations, RelationSide.values()); + + ResultSet<RelationNode> children = getChildren(session, graph, node); + for (RelationNode child : children) { + unrelate(session, graph, child, false); + } + + try { + node.delete(); + + if (relations != null && !relations.isEmpty()) { + Map<IRelationType, RelationSide> typesToRemove = new HashMap<IRelationType, RelationSide>(); + for (Relation relation : relations) { + relation.delete(); + IRelationType type = relation.getRelationType(); + RelationSide otherSide = relation.getLocalIdForSide(SIDE_A) == node.getLocalId() ? SIDE_B : SIDE_A; + typesToRemove.put(type, otherSide); + } + + if (!typesToRemove.isEmpty()) { + OrderManager orderManager = orderFactory.createOrderManager(node); + + for (Entry<IRelationType, RelationSide> entry : typesToRemove.entrySet()) { + IRelationType type = entry.getKey(); + RelationSide side = entry.getValue(); + + List<Relation> sideLinks = getRelations(session, graph, type, node, side, EXCLUDE_DELETED); + List<RelationNode> nodes = resolver.resolve(session, graph, sideLinks, side); + + IRelationTypeSide asTypeSide = asTypeSide(type, side); + orderManager.setOrder(asTypeSide, nodes); + } + } + } + } catch (OseeCoreException ex) { + node.unDelete(); + throw ex; + } + } + } + + ///////////////////////// READ HELPERS /////////////////// + @SuppressWarnings("unused") + private void ensureRelationsInitialized(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException { + if (graph.getAdjacencies(node) == null) { + RelationNodeAdjacencies container = relationFactory.createRelationContainer(); + graph.addAdjacencies(node, container); + } + } + + private ResultSet<Relation> getRelation(OrcsSession session, GraphData graph, RelationNode aNode, IRelationType type, RelationNode bNode, DeletionFlag inludeDeleted) throws OseeCoreException { + checkNotNull(session, "session"); + checkOnGraph(graph, aNode, bNode); + checkNotNull(type, "relationType"); + + ensureRelationsInitialized(session, graph, aNode); + ensureRelationsInitialized(session, graph, bNode); + + RelationNodeAdjacencies aAdjacencies = graph.getAdjacencies(aNode); + RelationNodeAdjacencies bAdjacencies = graph.getAdjacencies(bNode); + + Relation relation = aAdjacencies.getRelation(aNode, type, bNode, inludeDeleted); + if (relation != null) { + bAdjacencies.add(type.getGuid(), relation); + } else { + relation = bAdjacencies.getRelation(aNode, type, bNode, inludeDeleted); + if (relation != null) { + aAdjacencies.add(type.getGuid(), relation); + } + } + return ResultSets.singleton(relation); + } + + private List<Relation> getRelations(OrcsSession session, GraphData graph, IRelationType type, RelationNode node, RelationSide side, DeletionFlag includeDeleted) throws OseeCoreException { + checkNotNull(session, "session"); + checkOnGraph(graph, node); + checkNotNull(type, "relationType"); + checkNotNull(side, "relationSide"); + + ensureRelationsInitialized(session, graph, node); + RelationNodeAdjacencies adjacencies = graph.getAdjacencies(node); + return adjacencies.getList(type, includeDeleted, node, side); + } + + private List<Relation> getRelations(OrcsSession session, GraphData graph, RelationNode node, DeletionFlag includeDeleted) throws OseeCoreException { + checkNotNull(session, "session"); + checkOnGraph(graph, node); + ensureRelationsInitialized(session, graph, node); + RelationNodeAdjacencies adjacencies = graph.getAdjacencies(node); + return adjacencies.getList(includeDeleted); + } + + private static enum OrderOp { + ADD_TO_ORDER, + REMOVE_FROM_ORDER; + } + + private void order(OrcsSession session, GraphData graph, IRelationType type, RelationNode node1, RelationSide side, OrderOp op, Collection<? extends RelationNode> node2) throws OseeCoreException { + order(session, graph, type, node1, side, RelationOrderBaseTypes.PREEXISTING, op, node2); + } + + private void order(OrcsSession session, GraphData graph, IRelationType type, RelationNode node1, RelationSide side, IRelationSorterId sorterId, OrderOp op, Collection<? extends RelationNode> node2) throws OseeCoreException { + OrderManager orderManager = orderFactory.createOrderManager(node1); + + RelationSide orderSide = side.oppositeSide(); + IRelationTypeSide key = asTypeSide(type, orderSide); + IRelationSorterId sorterIdToUse = sorterId; + if (sorterIdToUse == RelationOrderBaseTypes.PREEXISTING) { + sorterIdToUse = orderManager.getSorterId(key); + } + List<Identifiable> relatives = Collections.emptyList(); + if (RelationOrderBaseTypes.USER_DEFINED == sorterIdToUse) { + ResultSet<RelationNode> arts = getRelated(session, graph, type, node1, side); + relatives = new LinkedList<Identifiable>(); + for (RelationNode art : arts) { + relatives.add(art); + } + relatives.removeAll(node2); // ensure no duplicates + + if (OrderOp.ADD_TO_ORDER == op) { + relatives.addAll(node2); // always add to the end + } + } + orderManager.setOrder(key, sorterIdToUse, relatives); + } + + @Override + public void cloneRelations(OrcsSession session, RelationNode source, RelationNode destination) throws OseeCoreException { + ensureRelationsInitialized(session, source.getGraph(), source); + RelationNodeAdjacencies adjacencies1 = source.getGraph().getAdjacencies(source); + if (adjacencies1 != null) { + Collection<Relation> all = adjacencies1.getAll(); + if (!all.isEmpty()) { + RelationNodeAdjacencies adjacencies2 = relationFactory.createRelationContainer(); + destination.getGraph().addAdjacencies(destination, adjacencies2); + for (Relation relation : adjacencies1.getAll()) { + Relation newRel = relationFactory.clone(relation); + adjacencies2.add(newRel.getOrcsData().getTypeUuid(), newRel); + } + } + } + } + + private static IRelationTypeSide asTypeSide(IRelationType type, RelationSide side) { + return new RelationTypeSide(type, side); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacencies.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacencies.java new file mode 100644 index 00000000000..84f66b9006f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeAdjacencies.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import static com.google.common.base.Predicates.and; +import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.deletionFlagEquals; +import static org.eclipse.osee.orcs.core.internal.util.OrcsPredicates.nodeIdOnSideEquals; +import java.util.List; +import org.eclipse.osee.framework.core.data.IRelationType; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.core.internal.graph.GraphAdjacencies; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationVisitor; +import org.eclipse.osee.orcs.core.internal.util.AbstractTypeCollection; +import org.eclipse.osee.orcs.core.internal.util.OrcsPredicates; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; +import org.eclipse.osee.orcs.data.HasLocalId; +import com.google.common.base.Predicate; + +/** + * @author Roberto E. Escobar + */ +public class RelationNodeAdjacencies extends AbstractTypeCollection<IRelationType, Relation, Long, Relation> implements GraphAdjacencies { + + @Override + protected ResultSet<Relation> createResultSet(List<Relation> values) { + return ResultSets.newResultSet(values); + } + + @Override + protected <T extends Relation> ResultSet<T> createResultSet(Long type, List<T> values) { + return ResultSets.newResultSet(values); + } + + @Override + protected Relation asMatcherData(Relation data) { + return data; + } + + @Override + protected IRelationType getType(Relation data) throws OseeCoreException { + return data.getRelationType(); + } + + ////////////////////////////////////////////////////////////// + @SuppressWarnings({"unchecked", "rawtypes"}) + public List<Relation> getList(IRelationType type, DeletionFlag includeDeleted) throws OseeCoreException { + Predicate deletionFlagEquals = deletionFlagEquals(includeDeleted); + return getListByFilter(type.getGuid(), deletionFlagEquals); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public List<Relation> getList(IRelationType type, DeletionFlag includeDeleted, HasLocalId localId, RelationSide side) throws OseeCoreException { + Predicate deletionFlagEquals = deletionFlagEquals(includeDeleted); + Predicate relIdOnSide = nodeIdOnSideEquals(localId, side); + Predicate matcher = and(deletionFlagEquals, relIdOnSide); + return getListByFilter(type.getGuid(), matcher); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public ResultSet<Relation> getResultSet(IRelationType type, DeletionFlag includeDeleted) throws OseeCoreException { + Predicate deletionFlagEquals = deletionFlagEquals(includeDeleted); + return getSetByFilter(type.getGuid(), deletionFlagEquals); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public ResultSet<Relation> getResultSet(IRelationType type, DeletionFlag includeDeleted, HasLocalId localId, RelationSide side) throws OseeCoreException { + Predicate deletionFlagEquals = deletionFlagEquals(includeDeleted); + Predicate relIdOnSide = nodeIdOnSideEquals(localId, side); + Predicate matcher = and(deletionFlagEquals, relIdOnSide); + return getSetByFilter(type.getGuid(), matcher); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public Relation getRelation(RelationNode aNode, IRelationType type, RelationNode bNode, DeletionFlag excludeDeleted) throws OseeCoreException { + Predicate<Relation> nodeMatcher = OrcsPredicates.nodeIdsEquals(aNode, bNode); + Predicate deletionFlagEquals = deletionFlagEquals(excludeDeleted); + Predicate matcher = and(deletionFlagEquals, nodeMatcher); + List<Relation> listByFilter = getListByFilter(type.getGuid(), matcher); + return listByFilter.isEmpty() ? null : listByFilter.get(0); + } + + public Relation getRelation(int artIdA, long typeUuid, int artIdB) throws OseeCoreException { + Predicate<Relation> nodeMatcher = OrcsPredicates.nodeIdsEquals(artIdA, artIdB); + List<Relation> listByFilter = getListByFilter(typeUuid, nodeMatcher); + return listByFilter.isEmpty() ? null : listByFilter.get(0); + } + + public void accept(RelationVisitor visitor) throws OseeCoreException { + for (Relation relation : getAll()) { + visitor.visit(relation); + } + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImpl.java new file mode 100644 index 00000000000..f9867b54d38 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationNodeLoaderImpl.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import java.util.Collection; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.ds.DataLoader; +import org.eclipse.osee.orcs.core.ds.DataLoaderFactory; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilder; +import org.eclipse.osee.orcs.core.internal.graph.GraphBuilderFactory; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationNodeLoader; + +/** + * @author Roberto E. Escobar + */ +public class RelationNodeLoaderImpl implements RelationNodeLoader { + + private final DataLoaderFactory dataLoaderFactory; + private final GraphBuilderFactory graphBuilderFactory; + + public RelationNodeLoaderImpl(DataLoaderFactory dataLoaderFactory, GraphBuilderFactory graphBuilderFactory) { + super(); + this.dataLoaderFactory = dataLoaderFactory; + this.graphBuilderFactory = graphBuilderFactory; + } + + @Override + public <T extends RelationNode> Iterable<T> loadNodes(OrcsSession session, final GraphData graph, Collection<Integer> ids, LoadLevel level) throws OseeCoreException { + GraphBuilder builder = graphBuilderFactory.createBuilderForGraph(graph); + + DataLoader loader = dataLoaderFactory.fromBranchAndArtifactIds(session, graph.getBranch(), ids); + loader.setLoadLevel(level); + loader.fromTransaction(graph.getTransaction()); + loader.load(null, builder); + + return getResults(builder); + } + + @SuppressWarnings("unchecked") + private static <T> Iterable<T> getResults(GraphBuilder builder) { + return (Iterable<T>) builder.getArtifacts(); + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverImpl.java new file mode 100644 index 00000000000..78d8ed2c9d4 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/impl/RelationResolverImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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.orcs.core.internal.relation.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import org.eclipse.osee.framework.core.enums.LoadLevel; +import org.eclipse.osee.framework.core.enums.RelationSide; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.OrcsSession; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.Relation; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; +import org.eclipse.osee.orcs.core.internal.relation.RelationNodeLoader; +import org.eclipse.osee.orcs.core.internal.relation.RelationResolver; +import com.google.common.collect.Lists; + +/** + * @author Roberto E. Escobar + */ +public class RelationResolverImpl implements RelationResolver { + + private final RelationNodeLoader loader; + + public RelationResolverImpl(RelationNodeLoader loader) { + super(); + this.loader = loader; + } + + @SuppressWarnings("unchecked") + @Override + public <T extends RelationNode> List<T> resolve(OrcsSession session, GraphData graph, List<Relation> links, RelationSide... sides) throws OseeCoreException { + List<T> toReturn = Collections.emptyList(); + if (!links.isEmpty()) { + Set<Integer> toLoad = null; + LinkedHashMap<Integer, T> items = new LinkedHashMap<Integer, T>(); + for (Relation relation : links) { + for (RelationSide side : sides) { + int localId = relation.getLocalIdForSide(side); + RelationNode node = graph.getNode(localId); + if (node == null) { + if (toLoad == null) { + toLoad = new LinkedHashSet<Integer>(); + } + toLoad.add(localId); + } + items.put(localId, (T) node); + } + } + if (toLoad != null && !toLoad.isEmpty()) { + Iterable<T> result = loader.loadNodes(session, graph, toLoad, LoadLevel.FULL); + for (T item : result) { + items.put(item.getLocalId(), item); + } + } + toReturn = toList(items.values()); + } + return toReturn; + } + + private <T> List<T> toList(Collection<T> values) { + List<T> list; + if (values instanceof ArrayList) { + list = (ArrayList<T>) values; + } else if (values instanceof LinkedList) { + list = (LinkedList<T>) values; + } else if (values == null) { + list = Collections.emptyList(); + } else { + list = Lists.newLinkedList(values); + } + return list; + } + + @Override + public void resolve(OrcsSession session, GraphData graph, RelationNode node) throws OseeCoreException { + loader.loadNodes(session, graph, Collections.singleton(node.getLocalId()), LoadLevel.RELATION); + } + +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/search/CallableQueryFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/search/CallableQueryFactory.java index c25f568a77f..4584b725739 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/search/CallableQueryFactory.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/search/CallableQueryFactory.java @@ -14,7 +14,6 @@ import java.util.LinkedList; import java.util.List; import org.eclipse.osee.executor.admin.CancellableCallable; import org.eclipse.osee.framework.core.data.ResultSet; -import org.eclipse.osee.framework.core.data.ResultSetList; import org.eclipse.osee.framework.core.enums.LoadLevel; import org.eclipse.osee.framework.jdk.core.util.Lib; import org.eclipse.osee.logger.Log; @@ -27,6 +26,7 @@ import org.eclipse.osee.orcs.core.ds.QueryData; import org.eclipse.osee.orcs.core.ds.QueryEngine; import org.eclipse.osee.orcs.core.internal.ArtifactBuilder; import org.eclipse.osee.orcs.core.internal.ArtifactBuilderFactory; +import org.eclipse.osee.orcs.core.internal.util.ResultSets; import org.eclipse.osee.orcs.data.ArtifactReadable; import org.eclipse.osee.orcs.data.AttributeReadable; import org.eclipse.osee.orcs.data.HasLocalId; @@ -76,7 +76,7 @@ public class CallableQueryFactory { OptionsUtil.setLoadLevel(getQueryData().getOptions(), LoadLevel.ATTRIBUTE); queryEngine.createArtifactQuery(getSession(), getQueryData(), handler).call(); setItemsFound(results.size()); - return new ResultSetList<HasLocalId>(results); + return ResultSets.newResultSet(results); } }; } @@ -91,7 +91,7 @@ public class CallableQueryFactory { queryEngine.createArtifactQuery(getSession(), getQueryData(), handler).call(); List<ArtifactReadable> results = handler.getArtifacts(); setItemsFound(results.size()); - return new ResultSetList<ArtifactReadable>(results); + return ResultSets.newResultSet(results); } }; } @@ -108,7 +108,7 @@ public class CallableQueryFactory { List<Match<ArtifactReadable, AttributeReadable<?>>> results = handler.getResults(); setItemsFound(results.size()); - return new ResultSetList<Match<ArtifactReadable, AttributeReadable<?>>>(results); + return ResultSets.newResultSet(results); } }; } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/FilterableCollection.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/FilterableCollection.java index ace8e62b655..2ecea84b286 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/FilterableCollection.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/FilterableCollection.java @@ -135,4 +135,9 @@ public abstract class FilterableCollection<MATCH_DATA, KEY, DATA> { } protected abstract MATCH_DATA asMatcherData(DATA data); + + @Override + public String toString() { + return "FilterableCollection [map=" + map + "]"; + } } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsConditions.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsConditions.java new file mode 100644 index 00000000000..aceb391f2c6 --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsConditions.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.orcs.core.internal.util; + +import static org.eclipse.osee.framework.core.util.Conditions.checkExpressionFailOnTrue; +import static org.eclipse.osee.framework.core.util.Conditions.checkNotNull; +import org.eclipse.osee.framework.core.exception.OseeCoreException; +import org.eclipse.osee.orcs.core.internal.graph.GraphData; +import org.eclipse.osee.orcs.core.internal.relation.RelationNode; + +/** + * @author Roberto E. Escobar + */ +public final class OrcsConditions { + + private OrcsConditions() { + // Utility class + } + + public static void checkOnGraph(GraphData graph, RelationNode... nodes) throws OseeCoreException { + checkNotNull(graph, "graph"); + for (RelationNode node : nodes) { + checkNotNull(node, "node"); + GraphData graph2 = node.getGraph(); + checkExpressionFailOnTrue(!graph.equals(graph2), + "Error - Node[%s] is on graph[%s] but should be on graph[%s]", node, graph2, graph); + } + } + + public static void checkBranch(RelationNode node1, RelationNode node2) throws OseeCoreException { + boolean areEqual = node1.getBranch().equals(node2.getBranch()); + checkExpressionFailOnTrue(!areEqual, "Cross branch linking is not yet supported."); + } + + public static void checkRelateSelf(RelationNode node1, RelationNode node2) throws OseeCoreException { + checkExpressionFailOnTrue(node1.equals(node2), "Not valid to relate [%s] to itself", node1); + } +} diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicates.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicates.java index 315374738dc..e836ce77994 100644 --- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicates.java +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/OrcsPredicates.java @@ -17,8 +17,10 @@ import static com.google.common.base.Predicates.equalTo; import static com.google.common.base.Predicates.not; import java.util.regex.Pattern; import org.eclipse.osee.framework.core.enums.DeletionFlag; +import org.eclipse.osee.framework.core.enums.RelationSide; import org.eclipse.osee.framework.core.exception.OseeCoreException; import org.eclipse.osee.orcs.core.internal.attribute.Attribute; +import org.eclipse.osee.orcs.core.internal.relation.Relation; import org.eclipse.osee.orcs.data.HasDeleteState; import org.eclipse.osee.orcs.data.HasLocalId; import org.eclipse.osee.orcs.data.Modifiable; @@ -144,4 +146,29 @@ public final class OrcsPredicates { return result; } } + + public static Predicate<Relation> nodeIdOnSideEquals(final HasLocalId localId, final RelationSide side) { + return new Predicate<Relation>() { + + @Override + public boolean apply(Relation relation) { + return relation.getLocalIdForSide(side) == localId.getLocalId(); + } + }; + } + + public static Predicate<Relation> nodeIdsEquals(final HasLocalId aId, final HasLocalId bId) { + return nodeIdsEquals(aId.getLocalId(), bId.getLocalId()); + } + + public static Predicate<Relation> nodeIdsEquals(final int aId, final int bId) { + return new Predicate<Relation>() { + + @Override + public boolean apply(Relation relation) { + return aId == relation.getLocalIdForSide(RelationSide.SIDE_A) && // + bId == relation.getLocalIdForSide(RelationSide.SIDE_B); + } + }; + } } diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/ResultSets.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/ResultSets.java new file mode 100644 index 00000000000..26d1c72223f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/util/ResultSets.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.orcs.core.internal.util; + +import java.util.Collections; +import java.util.List; +import org.eclipse.osee.framework.core.data.ResultSet; +import org.eclipse.osee.framework.core.data.ResultSetList; +import com.google.common.collect.Iterables; + +/** + * @author Roberto E. Escobar + */ +public final class ResultSets { + + @SuppressWarnings({"rawtypes", "unchecked"}) + private static final ResultSet EMPTY_RESULT_SET = new ResultSetList(Collections.emptyList()); + + private ResultSets() { + // Utility + } + + public static <T> ResultSet<T> singleton(T item) { + ResultSet<T> toReturn; + if (item == null) { + toReturn = emptyResultSet(); + } else { + toReturn = new ResultSetList<T>(Collections.singletonList(item)); + } + return toReturn; + } + + public static <T> ResultSet<T> newResultSet(List<T> list) { + ResultSet<T> toReturn; + if (list.isEmpty()) { + toReturn = emptyResultSet(); + } else { + toReturn = new ResultSetList<T>(list); + } + return toReturn; + } + + public static <T> ResultSet<T> newResultSet(Iterable<T> iterable) { + ResultSet<T> toReturn; + if (Iterables.isEmpty(iterable)) { + toReturn = emptyResultSet(); + } else { + toReturn = new ResultSetIterable<T>(iterable); + } + return toReturn; + } + + @SuppressWarnings("unchecked") + public static <T> ResultSet<T> emptyResultSet() { + return EMPTY_RESULT_SET; + } + +} diff --git a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/IntegrationUtil.java b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/IntegrationUtil.java index 1c02eac97d2..955a03995cb 100644 --- a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/IntegrationUtil.java +++ b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/IntegrationUtil.java @@ -69,7 +69,6 @@ public class IntegrationUtil { int index = 0; assertEquals(data.getLocalId(), values[index++]); - assertEquals(data.getParentId(), values[index++]); assertEquals(data.getArtIdA(), values[index++]); assertEquals(data.getArtIdB(), values[index++]); assertEquals(data.getRationale(), values[index++]); diff --git a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/LoaderTest.java b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/LoaderTest.java index 715337b42a9..57387ae3fb4 100644 --- a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/LoaderTest.java +++ b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/intergration/LoaderTest.java @@ -143,9 +143,9 @@ public class LoaderTest { Iterator<RelationData> rels = relationCaptor.getAllValues().iterator(); // @formatter:off - verifyData(rels.next(), 1, 7, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); - verifyData(rels.next(), 2, 7, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); - verifyData(rels.next(), 3, 7, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); + verifyData(rels.next(), 1, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); + verifyData(rels.next(), 2, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); + verifyData(rels.next(), 3, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); // @formatter:on } @@ -192,9 +192,9 @@ public class LoaderTest { Iterator<RelationData> rels = relationCaptor.getAllValues().iterator(); // @formatter:off - verifyData(rels.next(), 1, 7, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); - verifyData(rels.next(), 2, 7, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); - verifyData(rels.next(), 3, 7, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); + verifyData(rels.next(), 1, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); + verifyData(rels.next(), 2, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); + verifyData(rels.next(), 3, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); // @formatter:on } @@ -240,8 +240,8 @@ public class LoaderTest { Iterator<RelationData> rels = relationCaptor.getAllValues().iterator(); // @formatter:off - verifyData(rels.next(), 2, 7, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); - verifyData(rels.next(), 3, 7, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); + verifyData(rels.next(), 2, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); + verifyData(rels.next(), 3, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); // @formatter:on } @@ -291,9 +291,9 @@ public class LoaderTest { Iterator<RelationData> rels = relationCaptor.getAllValues().iterator(); // @formatter:off - verifyData(rels.next(), 1, 7, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); - verifyData(rels.next(), 2, 7, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); - verifyData(rels.next(), 3, 7, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); + verifyData(rels.next(), 1, 7, 8, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 53L); + verifyData(rels.next(), 2, 1, 7, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 52L); + verifyData(rels.next(), 3, 7, 15, "", NEW, Default_Hierarchical__Parent.getGuid(), 2, 6, -1, 54L); // @formatter:on } } diff --git a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImplTest.java b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImplTest.java index 2eab51e9f4a..c1ee85f3c7e 100644 --- a/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImplTest.java +++ b/plugins/org.eclipse.osee.orcs.db.test/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImplTest.java @@ -125,7 +125,6 @@ public class DataFactoryImplTest { when(relData.getBaseTypeUuid()).thenReturn(777L); when(relData.getArtIdA()).thenReturn(88); when(relData.getArtIdB()).thenReturn(99); - when(relData.getParentId()).thenReturn(1111); when(relData.getRationale()).thenReturn("this is the rationale"); when(idFactory.getBranchId(CoreBranches.COMMON)).thenReturn(657); @@ -281,7 +280,7 @@ public class DataFactoryImplTest { when(localId2.getLocalId()).thenReturn(9513); RelationData actual = - dataFactory.createRelationData(relationType, localId1, CoreBranches.COMMON, localId1, localId2, "My rationale"); + dataFactory.createRelationData(relationType, CoreBranches.COMMON, localId1, localId2, "My rationale"); VersionData actualVer = actual.getVersion(); assertEquals(657, actualVer.getBranchId()); @@ -299,7 +298,6 @@ public class DataFactoryImplTest { assertEquals(4562, actual.getArtIdA()); assertEquals(9513, actual.getArtIdB()); - assertEquals(4562, actual.getParentId()); assertEquals("My rationale", actual.getRationale()); } @@ -497,7 +495,6 @@ public class DataFactoryImplTest { assertEquals(88, actual.getArtIdA()); assertEquals(99, actual.getArtIdB()); - assertEquals(1111, actual.getParentId()); assertEquals("this is the rationale", actual.getRationale()); } diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImpl.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImpl.java index d9a3fd7172f..9721f9e8625 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImpl.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/DataFactoryImpl.java @@ -121,13 +121,13 @@ public class DataFactoryImpl implements DataFactory { } @Override - public RelationData createRelationData(IRelationType relationType, HasLocalId parent, IOseeBranch branch, HasLocalId aArt, HasLocalId bArt, String rationale) throws OseeCoreException { + public RelationData createRelationData(IRelationType relationType, IOseeBranch branch, HasLocalId aArt, HasLocalId bArt, String rationale) throws OseeCoreException { VersionData version = objectFactory.createDefaultVersionData(); version.setBranchId(idFactory.getBranchId(branch)); ModificationType modType = RelationalConstants.DEFAULT_MODIFICATION_TYPE; int relationId = RelationalConstants.DEFAULT_ITEM_ID; - return objectFactory.createRelationData(version, relationId, relationType, modType, parent.getLocalId(), - aArt.getLocalId(), bArt.getLocalId(), rationale); + return objectFactory.createRelationData(version, relationId, relationType, modType, aArt.getLocalId(), + bArt.getLocalId(), rationale); } @Override diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/OrcsObjectFactoryImpl.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/OrcsObjectFactoryImpl.java index bd32b46095f..9734ecd68f6 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/OrcsObjectFactoryImpl.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/OrcsObjectFactoryImpl.java @@ -126,15 +126,15 @@ public class OrcsObjectFactoryImpl implements OrcsObjectFactory { } @Override - public RelationData createRelationData(VersionData version, int localId, int localTypeID, ModificationType modType, int parentId, int aArtId, int bArtId, String rationale) throws OseeCoreException { + public RelationData createRelationData(VersionData version, int localId, int localTypeID, ModificationType modType, int aArtId, int bArtId, String rationale) throws OseeCoreException { long typeId = toUuid(localTypeID); - return createRelationData(version, localId, typeId, modType, typeId, modType, parentId, aArtId, bArtId, rationale); + return createRelationData(version, localId, typeId, modType, typeId, modType, aArtId, bArtId, rationale); } @Override - public RelationData createRelationData(VersionData version, int localId, IRelationType type, ModificationType modType, int parentId, int aArtId, int bArtId, String rationale) { + public RelationData createRelationData(VersionData version, int localId, IRelationType type, ModificationType modType, int aArtId, int bArtId, String rationale) { long typeId = type.getGuid(); - return createRelationData(version, localId, typeId, modType, typeId, modType, parentId, aArtId, bArtId, rationale); + return createRelationData(version, localId, typeId, modType, typeId, modType, aArtId, bArtId, rationale); } private ArtifactData createArtifactFromRow(VersionData version, int localId, long localTypeID, ModificationType modType, long baseLocalTypeID, ModificationType baseModType, String guid, String humanReadableId) { @@ -161,14 +161,13 @@ public class OrcsObjectFactoryImpl implements OrcsObjectFactory { return data; } - private RelationData createRelationData(VersionData version, int localId, long localTypeID, ModificationType modType, long baseLocalTypeID, ModificationType baseModType, int parentId, int aArtId, int bArtId, String rationale) { + private RelationData createRelationData(VersionData version, int localId, long localTypeID, ModificationType modType, long baseLocalTypeID, ModificationType baseModType, int aArtId, int bArtId, String rationale) { RelationData data = new RelationDataImpl(version); data.setLocalId(localId); data.setTypeUuid(localTypeID); data.setBaseTypeUuid(baseLocalTypeID); data.setModType(modType); data.setBaseModType(baseModType); - data.setParentId(parentId); data.setArtIdA(aArtId); data.setArtIdB(bArtId); data.setRationale(rationale); @@ -179,8 +178,8 @@ public class OrcsObjectFactoryImpl implements OrcsObjectFactory { public RelationData createCopy(RelationData source) { VersionData newVersion = createCopy(source.getVersion()); return createRelationData(newVersion, source.getLocalId(), source.getTypeUuid(), source.getModType(), - source.getBaseTypeUuid(), source.getBaseModType(), source.getParentId(), source.getArtIdA(), - source.getArtIdB(), source.getRationale()); + source.getBaseTypeUuid(), source.getBaseModType(), source.getArtIdA(), source.getArtIdB(), + source.getRationale()); } } diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationDataImpl.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationDataImpl.java index 79d9e3a09c6..f427037b3bd 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationDataImpl.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationDataImpl.java @@ -20,7 +20,6 @@ import org.eclipse.osee.orcs.db.internal.sql.RelationalConstants; */ public class RelationDataImpl extends OrcsVersionedObjectImpl implements RelationData { - private int parentId = RelationalConstants.ART_ID_SENTINEL; private int artIdA = RelationalConstants.ART_ID_SENTINEL; private int artIdB = RelationalConstants.ART_ID_SENTINEL; private String rationale = RelationalConstants.DEFAULT_RATIONALE; @@ -68,16 +67,6 @@ public class RelationDataImpl extends OrcsVersionedObjectImpl implements Relatio } @Override - public void setParentId(int parentId) { - this.parentId = parentId; - } - - @Override - public int getParentId() { - return parentId; - } - - @Override public int getArtIdOn(RelationSide side) { return RelationSide.SIDE_A == side ? getArtIdA() : getArtIdB(); } @@ -88,7 +77,6 @@ public class RelationDataImpl extends OrcsVersionedObjectImpl implements Relatio int result = super.hashCode(); result = prime * result + artIdA; result = prime * result + artIdB; - result = prime * result + parentId; result = prime * result + ((rationale == null) ? 0 : rationale.hashCode()); return result; } @@ -111,9 +99,6 @@ public class RelationDataImpl extends OrcsVersionedObjectImpl implements Relatio if (artIdB != other.artIdB) { return false; } - if (parentId != other.parentId) { - return false; - } if (rationale == null) { if (other.rationale != null) { return false; @@ -126,7 +111,7 @@ public class RelationDataImpl extends OrcsVersionedObjectImpl implements Relatio @Override public String toString() { - return "RelationData [parentId=" + parentId + ", artIdA=" + artIdA + ", artIdB=" + artIdB + ", rationale=" + rationale + " " + super.toString() + "]"; + return "RelationData [artIdA=" + artIdA + ", artIdB=" + artIdB + ", rationale=" + rationale + " " + super.toString() + "]"; } } diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationObjectFactory.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationObjectFactory.java index 14ca34b5e39..5eb0388fa27 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationObjectFactory.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/data/RelationObjectFactory.java @@ -21,9 +21,9 @@ import org.eclipse.osee.orcs.core.ds.VersionData; */ public interface RelationObjectFactory extends VersionObjectFactory { - RelationData createRelationData(VersionData version, int localId, int localTypeID, ModificationType modType, int parentId, int aArtId, int bArtId, String rationale) throws OseeCoreException; + RelationData createRelationData(VersionData version, int localId, int localTypeID, ModificationType modType, int aArtId, int bArtId, String rationale) throws OseeCoreException; - RelationData createRelationData(VersionData version, int localId, IRelationType type, ModificationType modType, int parentId, int aArtId, int bArtId, String rationale) throws OseeCoreException; + RelationData createRelationData(VersionData version, int localId, IRelationType type, ModificationType modType, int aArtId, int bArtId, String rationale) throws OseeCoreException; RelationData createCopy(RelationData source) throws OseeCoreException; } diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/processor/RelationLoadProcessor.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/processor/RelationLoadProcessor.java index 904ebe5026b..6402d157b08 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/processor/RelationLoadProcessor.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/loader/processor/RelationLoadProcessor.java @@ -44,11 +44,10 @@ public class RelationLoadProcessor extends LoadProcessor<RelationData, RelationO int typeId = chStmt.getInt("rel_link_type_id"); ModificationType modType = ModificationType.getMod(chStmt.getInt("mod_type")); - int parentId = chStmt.getInt("art_id"); int aArtId = chStmt.getInt("a_art_id"); int bArtId = chStmt.getInt("b_art_id"); String rationale = chStmt.getString("rationale"); - return factory.createRelationData(version, localId, typeId, modType, parentId, aArtId, bArtId, rationale); + return factory.createRelationData(version, localId, typeId, modType, aArtId, bArtId, rationale); } }
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/search/util/LoadDataBuffer.java b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/search/util/LoadDataBuffer.java index 57c26c3089b..cfc95e90d36 100644 --- a/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/search/util/LoadDataBuffer.java +++ b/plugins/org.eclipse.osee.orcs.db/src/org/eclipse/osee/orcs/db/internal/search/util/LoadDataBuffer.java @@ -58,7 +58,8 @@ public class LoadDataBuffer { public void addData(RelationData data) { synchronized (relations) { - relations.put(data.getParentId(), data); + relations.put(data.getArtIdA(), data); + relations.put(data.getArtIdB(), data); } } diff --git a/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/data/SortStyle.java b/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/data/SortStyle.java new file mode 100644 index 00000000000..8458e5cff0f --- /dev/null +++ b/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/data/SortStyle.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 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.orcs.data; + +/** + * @author Roberto E. Escobar + */ +public enum SortStyle { + SORTED, + UNSORTED; + + public boolean isSorted() { + return this == SORTED; + } +} |