Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto E. Escobar2013-07-10 01:27:06 +0000
committerGerrit Code Review @ Eclipse.org2013-09-13 21:09:04 +0000
commit98b93fa8d9dbe3c59778a779eecda5154eb44415 (patch)
tree784aace6883ff7720ce79b84f190abb94590ec14 /plugins
parent824718baa32a2c863ecb07a1f03aadc93cd4e75d (diff)
downloadorg.eclipse.osee-98b93fa8d9dbe3c59778a779eecda5154eb44415.tar.gz
org.eclipse.osee-98b93fa8d9dbe3c59778a779eecda5154eb44415.tar.xz
org.eclipse.osee-98b93fa8d9dbe3c59778a779eecda5154eb44415.zip
feature[ats_7SNLZ]: Add relation ordering and sorting
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/InternalTestSuite.java2
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.java25
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorTest.java106
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerTest.java337
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParserTest.java271
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderTestSuite.java23
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProviderTest.java143
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTest.java179
-rw-r--r--plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTestSuite.java23
-rw-r--r--plugins/org.eclipse.osee.orcs.core/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/HasOrderData.java32
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessor.java24
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorImpl.java48
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderChange.java18
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderData.java51
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEditState.java16
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEntryComparator.java56
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManager.java210
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerFactory.java37
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParser.java176
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderStore.java27
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/LexicographicalSorter.java48
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/Sorter.java25
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProvider.java89
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UnorderedSorter.java32
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedComparator.java54
-rw-r--r--plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedSorter.java35
-rw-r--r--plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/utility/NameComparator.java32
28 files changed, 2110 insertions, 12 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 714def3340..fd5c84ebca 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
@@ -15,6 +15,7 @@ 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.loader.LoaderTestSuite;
import org.eclipse.osee.orcs.core.internal.proxy.ProxyTestSuite;
+import org.eclipse.osee.orcs.core.internal.relation.RelationTestSuite;
import org.eclipse.osee.orcs.core.internal.search.QueryTestSuite;
import org.eclipse.osee.orcs.core.internal.transaction.TransactionTestSuite;
import org.eclipse.osee.orcs.core.internal.types.TypesTestSuite;
@@ -31,6 +32,7 @@ import org.junit.runners.Suite;
BranchTestSuite.class,
LoaderTestSuite.class,
ProxyTestSuite.class,
+ RelationTestSuite.class,
QueryTestSuite.class,
TransactionTestSuite.class,
TypesTestSuite.class})
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
new file mode 100644
index 0000000000..73c788b4b8
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/RelationTestSuite.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.relation;
+
+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;
+import org.junit.runners.Suite;
+
+/**
+ * @author Roberto E. Escobar
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({OrderTestSuite.class, SorterTestSuite.class})
+public class RelationTestSuite {
+ // Test Suite
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorTest.java
new file mode 100644
index 0000000000..51e51aefd7
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorTest.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+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;
+
+/**
+ * Test Case for {@link OrderAccessorImpl}
+ *
+ * @author Roberto E. Escobar
+ */
+public class OrderAccessorTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ // @formatter:off
+ @Mock private OrderStore storage;
+ @Mock private OrderParser parser;
+
+ @Mock private HasOrderData orderData;
+ // @formatter:on
+
+ private OrderAccessor accessor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ accessor = new OrderAccessorImpl(parser, storage);
+ }
+
+ @Test
+ public void testLoad() throws OseeCoreException {
+ String storedData = "data";
+ when(storage.getOrderData()).thenReturn(storedData);
+
+ accessor.load(orderData);
+
+ verify(storage).getOrderData();
+ verify(parser).loadFromXml(orderData, storedData);
+ }
+
+ @Test
+ public void testStoreNotAccessible() throws OseeCoreException {
+ String storedData = "data";
+
+ when(storage.isAccessible()).thenReturn(false);
+ when(orderData.isEmpty()).thenReturn(true);
+ when(parser.toXml(orderData)).thenReturn(storedData);
+
+ accessor.store(orderData, OrderChange.Forced);
+
+ verify(storage).isAccessible();
+ verify(parser, times(0)).toXml(orderData);
+ verify(storage, times(0)).storeOrderData(OrderChange.Forced, storedData);
+ }
+
+ @Test
+ public void testStoreEmptyData() throws OseeCoreException {
+ String storedData = "data";
+
+ when(storage.isAccessible()).thenReturn(true);
+ when(orderData.isEmpty()).thenReturn(true);
+ when(parser.toXml(orderData)).thenReturn(storedData);
+
+ accessor.store(orderData, OrderChange.Forced);
+
+ verify(storage).isAccessible();
+ verify(parser, times(0)).toXml(orderData);
+ verify(storage).storeOrderData(OrderChange.Forced, "");
+ }
+
+ @Test
+ public void testStore() throws OseeCoreException {
+ String storedData = "data";
+
+ when(storage.isAccessible()).thenReturn(true);
+ when(orderData.isEmpty()).thenReturn(false);
+ when(parser.toXml(orderData)).thenReturn(storedData);
+
+ accessor.store(orderData, OrderChange.Forced);
+
+ verify(storage).isAccessible();
+ verify(parser).toXml(orderData);
+ verify(storage).storeOrderData(OrderChange.Forced, storedData);
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerTest.java
new file mode 100644
index 0000000000..8297dab0b8
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerTest.java
@@ -0,0 +1,337 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC;
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.UNORDERED;
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.USER_DEFINED;
+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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.IRelationTypeSide;
+import org.eclipse.osee.framework.core.data.Identifiable;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+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.orcs.core.internal.relation.sorter.SorterProvider;
+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.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test Case for {@link OrderManager}
+ *
+ * @author Roberto E. Escobar
+ */
+public class OrderManagerTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ // @formatter:off
+ @Mock private OrderAccessor accessor;
+ @Mock private RelationTypes relationTypeCache;
+
+ @Mock private IRelationTypeSide typeSide1;
+ @Mock private IRelationTypeSide typeSide2;
+ @Mock private IRelationTypeSide typeSide3;
+
+ @Mock private OrderData orderData1;
+ @Mock private OrderData orderData2;
+ @Mock private OrderData orderData3;
+
+ @Mock private Identifiable mock1;
+ @Mock private Identifiable mock2;
+ @Mock private Identifiable mock3;
+ // @formatter:on
+
+ private OrderManager orderManager;
+ private List<Identifiable> items;
+
+ @Before
+ public void setUp() throws OseeCoreException {
+ MockitoAnnotations.initMocks(this);
+
+ orderManager = new OrderManager(new SorterProvider(relationTypeCache), accessor);
+
+ items = new ArrayList<Identifiable>();
+ items.add(mock1);
+ items.add(mock2);
+ items.add(mock3);
+
+ when(typeSide1.getGuid()).thenReturn(11L);
+ when(typeSide2.getGuid()).thenReturn(22L);
+ when(typeSide3.getGuid()).thenReturn(33L);
+
+ when(typeSide1.getSide()).thenReturn(RelationSide.SIDE_A);
+ when(typeSide2.getSide()).thenReturn(RelationSide.SIDE_B);
+ when(typeSide3.getSide()).thenReturn(RelationSide.SIDE_A);
+
+ when(relationTypeCache.getDefaultOrderTypeGuid(typeSide1)).thenReturn(USER_DEFINED.getGuid());
+ when(relationTypeCache.getDefaultOrderTypeGuid(typeSide2)).thenReturn(UNORDERED.getGuid());
+ when(relationTypeCache.getDefaultOrderTypeGuid(typeSide3)).thenReturn(LEXICOGRAPHICAL_ASC.getGuid());
+ }
+
+ @Test
+ public void testLoad() throws OseeCoreException {
+ orderManager.load();
+ verify(accessor).load(orderManager);
+ }
+
+ @Test
+ public void testStore() throws OseeCoreException {
+ orderManager.store();
+ verify(accessor).store(orderManager, OrderChange.Forced);
+ }
+
+ @Test
+ public void testAddNull1() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("type and side key cannot be null");
+ orderManager.remove(null);
+ orderManager.add(null, orderData1);
+ }
+
+ @Test
+ public void testAddNull2() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("orderData cannot be null");
+ orderManager.add(typeSide1, null);
+ }
+
+ @Test
+ public void testRemoveNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("type and side key cannot be null");
+ orderManager.remove(null);
+ }
+
+ @Test
+ public void testAddRemove() throws OseeCoreException {
+ orderManager.add(typeSide1, orderData1);
+ orderManager.add(typeSide2, orderData2);
+ orderManager.add(typeSide3, orderData3);
+
+ assertEquals(3, orderManager.size());
+ assertEquals(false, orderManager.isEmpty());
+
+ // Add again
+ orderManager.add(typeSide3, orderData3);
+ assertEquals(3, orderManager.size());
+ assertEquals(false, orderManager.isEmpty());
+
+ Collection<IRelationTypeSide> items = orderManager.getExistingTypes();
+ assertTrue(items.contains(typeSide1));
+ assertTrue(items.contains(typeSide2));
+ assertTrue(items.contains(typeSide3));
+
+ orderManager.remove(typeSide2);
+ assertEquals(2, orderManager.size());
+ assertEquals(false, orderManager.isEmpty());
+
+ // Add same one again
+ orderManager.add(typeSide1, orderData1);
+ assertEquals(2, orderManager.size());
+ assertEquals(false, orderManager.isEmpty());
+
+ items = orderManager.getExistingTypes();
+ assertTrue(items.contains(typeSide1));
+ assertFalse(items.contains(typeSide2));
+ assertTrue(items.contains(typeSide3));
+
+ orderManager.clear();
+ assertEquals(0, orderManager.size());
+ assertEquals(true, orderManager.isEmpty());
+ assertEquals(true, orderManager.getExistingTypes().isEmpty());
+ }
+
+ @Test
+ public void testGetSorterIdNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("type and side key cannot be null");
+
+ orderManager.getSorterId(null);
+ }
+
+ @Test
+ public void testGetSorterId() throws OseeCoreException {
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+ when(orderData2.getSorterId()).thenReturn(RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC);
+
+ orderManager.add(typeSide1, orderData1);
+ orderManager.add(typeSide2, orderData2);
+
+ assertEquals(RelationOrderBaseTypes.USER_DEFINED, orderManager.getSorterId(typeSide1));
+
+ assertEquals(RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC, orderManager.getSorterId(typeSide2));
+
+ IRelationSorterId actual = orderManager.getSorterId(typeSide3);
+ assertEquals(RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC, actual);
+ }
+
+ @Test
+ public void testGetOrderIdsNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("type and side key cannot be null");
+
+ orderManager.getOrderIds(null);
+ }
+
+ @Test
+ public void testGetOrderIds() throws OseeCoreException {
+ List<String> relatives1 = Arrays.asList("A", "B", "C");
+ List<String> relatives2 = Arrays.asList("1", "2", "3");
+
+ when(orderData1.getOrderIds()).thenReturn(relatives1);
+ when(orderData2.getOrderIds()).thenReturn(relatives2);
+
+ orderManager.add(typeSide1, orderData1);
+ orderManager.add(typeSide2, orderData2);
+
+ assertEquals(relatives1, orderManager.getOrderIds(typeSide1));
+ assertEquals(relatives2, orderManager.getOrderIds(typeSide2));
+
+ // Not Exists
+ assertEquals(Collections.emptyList(), orderManager.getOrderIds(typeSide3));
+ }
+
+ @Test
+ public void testIterator() throws OseeCoreException {
+ List<String> relatives1 = Arrays.asList("Z", "A", "X");
+ List<String> relatives2 = Arrays.asList("3", "2", "1");
+ List<String> relatives3 = Arrays.asList("c", "b", "a");
+
+ when(orderData1.getOrderIds()).thenReturn(relatives1);
+ when(orderData2.getOrderIds()).thenReturn(relatives2);
+ when(orderData3.getOrderIds()).thenReturn(relatives3);
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+ when(orderData2.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+ when(orderData3.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+
+ IRelationTypeSide typeSide4 = mock(IRelationTypeSide.class);
+ IRelationTypeSide typeSide5 = mock(IRelationTypeSide.class);
+ IRelationTypeSide typeSide6 = mock(IRelationTypeSide.class);
+
+ when(typeSide4.getGuid()).thenReturn(11L);
+ when(typeSide5.getGuid()).thenReturn(11L);
+ when(typeSide6.getGuid()).thenReturn(11L);
+
+ when(typeSide4.getSide()).thenReturn(RelationSide.SIDE_B);
+ when(typeSide5.getSide()).thenReturn(RelationSide.SIDE_A);
+ when(typeSide6.getSide()).thenReturn(RelationSide.SIDE_B);
+
+ orderManager.add(typeSide4, orderData1);
+ orderManager.add(typeSide5, orderData2);
+ orderManager.add(typeSide6, orderData3);
+
+ Iterator<Entry<IRelationTypeSide, OrderData>> iterator = orderManager.iterator();
+ Entry<IRelationTypeSide, OrderData> actual1 = iterator.next();
+ Entry<IRelationTypeSide, OrderData> actual2 = iterator.next();
+ Entry<IRelationTypeSide, OrderData> actual3 = iterator.next();
+
+ assertEquals(typeSide5, actual1.getKey());
+ assertEquals(typeSide4, actual2.getKey());
+ assertEquals(typeSide6, actual3.getKey());
+
+ assertEquals(orderData2, actual1.getValue());
+ assertEquals(orderData1, actual2.getValue());
+ assertEquals(orderData3, actual3.getValue());
+ }
+
+ @Test
+ public void testSort() throws OseeCoreException {
+ List<String> relatives1 = Arrays.asList("2", "1", "3");
+
+ when(orderData1.getOrderIds()).thenReturn(relatives1);
+ orderManager.add(typeSide1, orderData1);
+
+ when(mock1.getGuid()).thenReturn("3");
+ when(mock2.getGuid()).thenReturn("2");
+ when(mock3.getGuid()).thenReturn("1");
+
+ when(mock1.getName()).thenReturn("a");
+ when(mock2.getName()).thenReturn("1");
+ when(mock3.getName()).thenReturn("c");
+
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.UNORDERED);
+ orderManager.sort(typeSide1, items);
+ assertOrdered(items, mock1, mock2, mock3);
+
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+ Collections.shuffle(items);
+ orderManager.sort(typeSide1, items);
+ assertOrdered(items, mock2, mock3, mock1);
+
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC);
+ Collections.shuffle(items);
+ orderManager.sort(typeSide1, items);
+ assertOrdered(items, mock2, mock1, mock3);
+
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC);
+ Collections.shuffle(items);
+ orderManager.sort(typeSide1, items);
+ assertOrdered(items, mock3, mock1, mock2);
+ }
+
+ @Test
+ public void testSetOrder() throws OseeCoreException {
+ List<String> relatives1 = Arrays.asList("2", "1", "3");
+
+ when(mock1.getGuid()).thenReturn("2");
+ when(mock2.getGuid()).thenReturn("1");
+ when(mock3.getGuid()).thenReturn("3");
+
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.USER_DEFINED);
+ when(orderData1.getOrderIds()).thenReturn(relatives1);
+
+ orderManager.add(typeSide1, orderData1);
+
+ orderManager.setOrder(typeSide1, RelationOrderBaseTypes.USER_DEFINED, items);
+ verify(accessor).store(orderManager, OrderChange.NoChange);
+
+ orderManager.setOrder(typeSide1, RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC,
+ Collections.<Identifiable> emptyList());
+ verify(accessor).store(orderManager, OrderChange.OrderRequest);
+ verify(orderData1).setSorterId(RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC);
+ verify(orderData1).setOrderIds(Collections.<String> emptyList());
+
+ Collections.shuffle(items);
+ when(orderData1.getSorterId()).thenReturn(RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC);
+ orderManager.setOrder(typeSide1, RelationOrderBaseTypes.USER_DEFINED, items);
+ verify(accessor).store(orderManager, OrderChange.SetToDefault);
+ assertEquals(0, orderManager.size());
+ }
+
+ private void assertOrdered(List<Identifiable> items, Identifiable... expecteds) {
+ int index = 0;
+ assertEquals(expecteds.length, items.size());
+ for (Identifiable identifiable : expecteds) {
+ assertEquals(identifiable, items.get(index++));
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParserTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParserTest.java
new file mode 100644
index 0000000000..0e0ce40f9a
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParserTest.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.never;
+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 java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+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.TokenFactory;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+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.exception.OseeWrappedException;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+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 OrderParser}
+ *
+ * @author Roberto E. Escobar
+ */
+public class OrderParserTest {
+
+ private static final String REL_TYPE_1_NAME = "Default Hierarchical";
+ private static final Long REL_TYPE_1_ID = 4L;
+ private static final String REL_TYPE_2_NAME = "Another Type";
+ private static final Long REL_TYPE_2_ID = 1231L;
+
+ private static final List<String> ORDER_LIST_1 = Arrays.asList("AAABDEJ_mIQBf8VXVtGqvA", "AAABDEJ_nMkBf8VXVXptpg",
+ "AAABDEJ_oQ8Bf8VXLX7U_g");
+ private static final List<String> ORDER_LIST_2 = Arrays.asList("AAABDEJ_mIQBf8VXVtGqvA");
+ private static final List<String> ORDER_LIST_3 = Arrays.asList("AAABDEJ_mIQXf8VXVtGqvA", "AAABDEJ_oQVBf8VXLX7U_g");
+
+ //@formatter:off
+ private static final String ENTRY_PATTERN = "<Order relType=\"%s\" side=\"%s\" orderType=\"%s\" list=\"%s\"></Order>";
+ private static final String ENTRY_NO_LIST_PATTERN = "<Order relType=\"%s\" side=\"%s\" orderType=\"%s\"></Order>";
+ private static final String ONE_ENTRY_PATTERN = String.format("<OrderList>%s</OrderList>", ENTRY_PATTERN);
+ private static final String ONE_ENTRY_NO_LIST_PATTERN = String.format("<OrderList>%s</OrderList>", ENTRY_NO_LIST_PATTERN);
+ private static final String TWO_ENTRY_PATTERN = String.format("<OrderList>%s%s</OrderList>", ENTRY_PATTERN, ENTRY_PATTERN);
+
+ private static final String DATA_1 = String.format(ONE_ENTRY_PATTERN, REL_TYPE_1_NAME, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED.getGuid(), Collections.toString(",", ORDER_LIST_1));
+ private static final String DATA_2 = String.format(ONE_ENTRY_PATTERN, REL_TYPE_1_NAME, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED.getGuid(), Collections.toString(",", ORDER_LIST_2));
+ private static final String DATA_3 = String.format(TWO_ENTRY_PATTERN,
+ REL_TYPE_1_NAME, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED.getGuid(), Collections.toString(",", ORDER_LIST_2),
+ REL_TYPE_2_NAME, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC.getGuid(), Collections.toString(",", ORDER_LIST_3));
+ private static final String DATA_4 = String.format(ONE_ENTRY_NO_LIST_PATTERN, REL_TYPE_2_NAME, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC.getGuid());
+
+ private static final String EMPTY_TYPE = "<OrderList><Order side=\"SIDE_B\" orderType=\"AAT0xogoMjMBhARkBZQA\"></Order></OrderList>";
+ private static final String EMPTY_SIDE = "<OrderList><Order relType=\"X\" orderType=\"AAT0xogoMjMBhARkBZQA\"></Order></OrderList>";
+ private static final String EMPTY_ORDER_TYPE = "<OrderList><Order relType=\"X\" side=\"SIDE_B\"></Order></OrderList>";
+ private static final String NO_ENTRIES = "<OrderList></OrderList>";
+ //@formatter:on
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ // @formatter:off
+ @Mock private RelationTypes relationTypeCache;
+ @Mock private HasOrderData hasOrderData;
+
+ @Captor private ArgumentCaptor<IRelationTypeSide> typeSideCaptor;
+ @Captor private ArgumentCaptor<OrderData> orderDataCaptor;
+
+ @Mock private IRelationType relationType1;
+ @Mock private IRelationType relationType2;
+ // @formatter:on
+
+ private OrderParser parser;
+
+ @Before
+ public void setUp() throws OseeCoreException {
+ MockitoAnnotations.initMocks(this);
+
+ parser = new OrderParser(relationTypeCache);
+
+ when(relationType1.getName()).thenReturn(REL_TYPE_1_NAME);
+ when(relationType1.getGuid()).thenReturn(REL_TYPE_1_ID);
+
+ when(relationType2.getName()).thenReturn(REL_TYPE_2_NAME);
+ when(relationType2.getGuid()).thenReturn(REL_TYPE_2_ID);
+
+ final Collection<? extends IRelationType> types = Arrays.asList(relationType1, relationType2);
+
+ when(relationTypeCache.getAll()).thenAnswer(new Answer<Collection<? extends IRelationType>>() {
+
+ @Override
+ public Collection<? extends IRelationType> answer(InvocationOnMock invocation) throws Throwable {
+ return types;
+ }
+
+ });
+ }
+
+ @Test
+ public void testLoadFromXmlNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("orderData cannot be null");
+ parser.loadFromXml(null, "");
+ }
+
+ @Test
+ public void testToXmlNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("orderData cannot be null");
+ parser.toXml(null);
+ }
+
+ @Test
+ public void testInvalidXml() throws OseeCoreException {
+ thrown.expect(OseeWrappedException.class);
+ parser.loadFromXml(hasOrderData, "<OrderList");
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+ }
+
+ @Test
+ public void testInvalidData() throws OseeCoreException {
+ parser.loadFromXml(hasOrderData, null);
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ reset(hasOrderData);
+ parser.loadFromXml(hasOrderData, "");
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ reset(hasOrderData);
+ parser.loadFromXml(hasOrderData, NO_ENTRIES);
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ reset(hasOrderData);
+ parser.loadFromXml(hasOrderData, EMPTY_TYPE);
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ reset(hasOrderData);
+ parser.loadFromXml(hasOrderData, EMPTY_SIDE);
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ reset(hasOrderData);
+ parser.loadFromXml(hasOrderData, EMPTY_ORDER_TYPE);
+ verify(hasOrderData, never()).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+ }
+
+ @Test
+ public void testWithData1() throws OseeCoreException {
+ parser.loadFromXml(hasOrderData, DATA_1);
+
+ verify(hasOrderData, times(1)).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ verifyData(0, REL_TYPE_1_ID, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED, ORDER_LIST_1);
+ }
+
+ @Test
+ public void testWithData2() throws OseeCoreException {
+ parser.loadFromXml(hasOrderData, DATA_2);
+
+ verify(hasOrderData, times(1)).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ verifyData(0, REL_TYPE_1_ID, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED, ORDER_LIST_2);
+ }
+
+ @Test
+ public void testWithData3() throws OseeCoreException {
+ parser.loadFromXml(hasOrderData, DATA_3);
+
+ verify(hasOrderData, times(2)).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ verifyData(0, REL_TYPE_1_ID, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED, ORDER_LIST_2);
+ verifyData(1, REL_TYPE_2_ID, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC, ORDER_LIST_3);
+ }
+
+ @Test
+ public void testWithData4EmptyList() throws OseeCoreException {
+ parser.loadFromXml(hasOrderData, DATA_4);
+
+ verify(hasOrderData, times(1)).add(typeSideCaptor.capture(), orderDataCaptor.capture());
+
+ verifyData(0, REL_TYPE_2_ID, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC);
+ }
+
+ @Test
+ public void testToXml() throws OseeCoreException {
+ //@formatter:off
+ Map<IRelationTypeSide, OrderData> data = new LinkedHashMap<IRelationTypeSide, OrderData>();
+ add(data, REL_TYPE_1_ID, REL_TYPE_1_NAME, RelationSide.SIDE_B, RelationOrderBaseTypes.USER_DEFINED, ORDER_LIST_2);
+ add(data, REL_TYPE_2_ID, REL_TYPE_2_NAME, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC, ORDER_LIST_3);
+ //@formatter:on
+
+ when(hasOrderData.iterator()).thenReturn(data.entrySet().iterator());
+
+ String actual = parser.toXml(hasOrderData);
+ assertEquals(DATA_3, actual);
+ }
+
+ @Test
+ public void testToXmlEmptyEntries() throws OseeCoreException {
+ Map<IRelationTypeSide, OrderData> data = new LinkedHashMap<IRelationTypeSide, OrderData>();
+ when(hasOrderData.iterator()).thenReturn(data.entrySet().iterator());
+
+ String actual = parser.toXml(hasOrderData);
+ assertEquals(NO_ENTRIES, actual);
+ }
+
+ @Test
+ public void testToXmlEmptyList() throws OseeCoreException {
+ Map<IRelationTypeSide, OrderData> data = new LinkedHashMap<IRelationTypeSide, OrderData>();
+ add(data, REL_TYPE_1_ID, REL_TYPE_2_NAME, RelationSide.SIDE_A, RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC);
+ when(hasOrderData.iterator()).thenReturn(data.entrySet().iterator());
+
+ String actual = parser.toXml(hasOrderData);
+
+ assertEquals(DATA_4, actual);
+ }
+
+ private void add(Map<IRelationTypeSide, OrderData> data, Long typeId, String typeName, RelationSide side, IRelationSorterId sorter) {
+ add(data, typeId, typeName, side, sorter, java.util.Collections.<String> emptyList());
+ }
+
+ private void add(Map<IRelationTypeSide, OrderData> data, Long typeId, String typeName, RelationSide side, IRelationSorterId sorter, List<String> list) {
+ IRelationTypeSide typeSide = TokenFactory.createRelationTypeSide(side, typeId, typeName);
+ OrderData orderData = new OrderData(sorter, list);
+ data.put(typeSide, orderData);
+ }
+
+ private void verifyData(int index, Long typeId, RelationSide side, IRelationSorterId sorter) {
+ verifyData(index, typeId, side, sorter, java.util.Collections.<String> emptyList());
+ }
+
+ private void verifyData(int index, Long typeId, RelationSide side, IRelationSorterId sorter, List<String> list) {
+ IRelationTypeSide actualTypeSide = typeSideCaptor.getAllValues().get(index);
+ OrderData actualData = orderDataCaptor.getAllValues().get(index);
+
+ assertEquals(side, actualTypeSide.getSide());
+ assertEquals(typeId, actualTypeSide.getGuid());
+ assertEquals(sorter, actualData.getSorterId());
+
+ List<String> actualIds = actualData.getOrderIds();
+ assertEquals(list.size(), actualIds.size());
+
+ int itemIndex = 0;
+ for (String expectedId : list) {
+ assertEquals(expectedId, actualIds.get(itemIndex++));
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderTestSuite.java
new file mode 100644
index 0000000000..97e430c840
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderTestSuite.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.core.internal.relation.order;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Roberto E. Escobar
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({OrderAccessorTest.class, OrderManagerTest.class, OrderParserTest.class})
+public class OrderTestSuite {
+ // Test Suite
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProviderTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProviderTest.java
new file mode 100644
index 0000000000..0c6d6ee268
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProviderTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC;
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC;
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.UNORDERED;
+import static org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes.USER_DEFINED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.TokenFactory;
+import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+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.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test Case for {@link SorterProvider}
+ *
+ * @author Roberto E. Escobar
+ */
+public class SorterProviderTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ // @formatter:off
+ @Mock private RelationTypes relationTypeCache;
+ // @formatter:on
+
+ private SorterProvider provider;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ provider = new SorterProvider(relationTypeCache);
+ }
+
+ @Test
+ public void testGetDefaultSorterId() throws OseeCoreException {
+ when(relationTypeCache.getDefaultOrderTypeGuid(CoreRelationTypes.Default_Hierarchical__Child)).thenReturn(
+ RelationOrderBaseTypes.USER_DEFINED.getGuid());
+
+ IRelationSorterId actual1 = provider.getDefaultSorterId(CoreRelationTypes.Default_Hierarchical__Child);
+ assertEquals(RelationOrderBaseTypes.USER_DEFINED, actual1);
+
+ when(relationTypeCache.getDefaultOrderTypeGuid(CoreRelationTypes.Users_User)).thenReturn(
+ RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC.getGuid());
+
+ IRelationSorterId actual2 = provider.getDefaultSorterId(CoreRelationTypes.Users_User);
+ assertEquals(RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC, actual2);
+ }
+
+ @Test
+ public void testGetDefaultSorterIdNull() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("type cannot be null");
+
+ provider.getDefaultSorterId(null);
+ }
+
+ @Test
+ public void testGetDefaultSorterIdTypeNotfound() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage(String.format(
+ "defaultOrderTypeGuid cannot be null - Invalid default order type uuid for [%s]",
+ CoreRelationTypes.Allocation__Component));
+
+ provider.getDefaultSorterId(CoreRelationTypes.Allocation__Component);
+ }
+
+ @Test
+ public void testGetAllRelationOrderIds() {
+ List<IRelationSorterId> actual = provider.getSorterIds();
+
+ int index = 0;
+ assertEquals(RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC, actual.get(index++));
+ assertEquals(RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC, actual.get(index++));
+ assertEquals(RelationOrderBaseTypes.UNORDERED, actual.get(index++));
+ assertEquals(RelationOrderBaseTypes.USER_DEFINED, actual.get(index++));
+ }
+
+ @Test
+ public void testGetRelationOrder() throws OseeCoreException {
+ for (IRelationSorterId sorterId : RelationOrderBaseTypes.values()) {
+ Sorter actual = provider.getSorter(sorterId);
+ assertEquals(sorterId, actual.getId());
+ boolean matches = false;
+
+ if (sorterId == LEXICOGRAPHICAL_ASC) {
+ matches = actual instanceof LexicographicalSorter;
+ } else if (sorterId == LEXICOGRAPHICAL_DESC) {
+ matches = actual instanceof LexicographicalSorter;
+ } else if (sorterId == UNORDERED) {
+ matches = actual instanceof UnorderedSorter;
+ } else if (sorterId == USER_DEFINED) {
+ matches = actual instanceof UserDefinedSorter;
+ } else {
+ assertNull("This line should not be reached");
+ }
+ assertTrue(matches);
+ }
+ }
+
+ @Test
+ public void testArgumentExceptions() throws OseeCoreException {
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage("sorterId cannot be null");
+ provider.getSorter(null);
+ }
+
+ @Test
+ public void testNotFoundExceptions() throws OseeCoreException {
+ String randomGuid = GUID.create();
+ String idName = "TestSorterId";
+ IRelationSorterId sorterId = TokenFactory.createSorterId(randomGuid, "TestSorterId");
+ thrown.expect(OseeArgumentException.class);
+ thrown.expectMessage(String.format("sorter cannot be null - Unable to locate sorter with sorterId [%s:%s]",
+ idName, randomGuid));
+ provider.getSorter(sorterId);
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTest.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTest.java
new file mode 100644
index 0000000000..a36619e7e9
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTest.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.osee.framework.core.data.AbstractIdentity;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.Identifiable;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+import org.eclipse.osee.framework.jdk.core.util.GUID;
+import org.eclipse.osee.orcs.utility.SortOrder;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Test Case for {@link LexicographicalSorter}, {@link UnorderedSorter}, {@link UserDefinedSorter}, and
+ * {@link UserDefinedComparator}
+ *
+ * @author Roberto E. Escobar
+ */
+@RunWith(Parameterized.class)
+public class SorterTest {
+
+ private final String message;
+ private final Sorter sorter;
+ private final IRelationSorterId expectedOrderId;
+ private final List<Identifiable> expectedOrder;
+ private final List<String> currentItems;
+ private final List<Identifiable> itemsToOrder;
+
+ public SorterTest(String message, Sorter sorter, IRelationSorterId expectedOrderId, List<String> currentItems, List<Identifiable> itemsToOrder, List<Identifiable> expectedOrder) {
+ this.sorter = sorter;
+ this.message = message;
+ this.expectedOrderId = expectedOrderId;
+ this.currentItems = currentItems;
+ this.itemsToOrder = itemsToOrder;
+ this.expectedOrder = expectedOrder;
+ }
+
+ @Test
+ public void testSorterId() {
+ Assert.assertNotNull(message, sorter.getId());
+ Assert.assertEquals(message, expectedOrderId.getGuid(), sorter.getId().getGuid());
+ Assert.assertEquals(message, expectedOrderId.getName(), sorter.getId().getName());
+ }
+
+ @Test
+ public void testSort() {
+ List<Identifiable> actualToOrder = new ArrayList<Identifiable>();
+ actualToOrder.addAll(itemsToOrder);
+ sorter.sort(actualToOrder, currentItems);
+
+ Assert.assertEquals(message, expectedOrder.size(), actualToOrder.size());
+ for (int index = 0; index < expectedOrder.size(); index++) {
+ Assert.assertEquals(message + " - index:" + index, expectedOrder.get(index), actualToOrder.get(index));
+ }
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ Collection<Object[]> data = new ArrayList<Object[]>();
+ data.add(createUnorderedSortTest("4", "2", "1", "5"));
+ data.add(createUnorderedSortTest("$", "a", "!", "2"));
+ data.add(createUserDefinedTest("1", "2", "3", "4"));
+
+ data.add(createLexicographicalTest(SortOrder.ASCENDING, "1", "2", "3", "4"));
+ data.add(createLexicographicalTest(SortOrder.ASCENDING, "a", "b", "c", "d"));
+ data.add(createLexicographicalTest(SortOrder.ASCENDING, "!", "1", "a", "b"));
+
+ data.add(createLexicographicalTest(SortOrder.DESCENDING, "4", "3", "2", "1"));
+ data.add(createLexicographicalTest(SortOrder.DESCENDING, "d", "c", "b", "a"));
+ data.add(createLexicographicalTest(SortOrder.DESCENDING, "b", "a", "1", "!"));
+
+ return data;
+ }
+
+ private static Object[] createUnorderedSortTest(String... names) {
+ Identifiable art1 = createItem(names[0]);
+ Identifiable art2 = createItem(names[1]);
+ Identifiable art3 = createItem(names[2]);
+ Identifiable art4 = createItem(names[3]);
+
+ List<Identifiable> artifacts = Arrays.asList(art1, art2, art3, art4);
+ return new Object[] {
+ "Unordered Test",
+ new UnorderedSorter(),
+ RelationOrderBaseTypes.UNORDERED,
+ null,
+ artifacts,
+ artifacts};
+ }
+
+ private static Object[] createLexicographicalTest(SortOrder mode, String... names) {
+ Identifiable art1 = createItem(names[0]);
+ Identifiable art2 = createItem(names[1]);
+ Identifiable art3 = createItem(names[2]);
+ Identifiable art4 = createItem(names[3]);
+
+ IRelationSorterId orderId;
+ if (mode.isAscending()) {
+ orderId = RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC;
+ } else {
+ orderId = RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC;
+ }
+
+ List<Identifiable> itemsToOrder = Arrays.asList(art3, art1, art4, art2);
+ List<Identifiable> expectedOrder = Arrays.asList(art1, art2, art3, art4);
+ return new Object[] {
+ "Lex Test " + mode.name(),
+ new LexicographicalSorter(mode),
+ orderId,
+ null,
+ itemsToOrder,
+ expectedOrder};
+ }
+
+ private static Object[] createUserDefinedTest(String... names) {
+ Identifiable art1 = createItem(names[0]);
+ Identifiable art2 = createItem(names[1]);
+ Identifiable art3 = createItem(names[2]);
+ Identifiable art4 = createItem(names[3]);
+
+ List<Identifiable> itemsToOrder = Arrays.asList(art2, art1, art3, art4);
+ List<Identifiable> expectedOrder = Arrays.asList(art1, art2, art3, art4);
+
+ List<String> relatives = new ArrayList<String>();
+ for (Identifiable item : Arrays.asList(art1, art2, art3, art4)) {
+ relatives.add(item.getGuid());
+ }
+ return new Object[] {
+ "UserDefined",
+ new UserDefinedSorter(),
+ RelationOrderBaseTypes.USER_DEFINED,
+ relatives,
+ itemsToOrder,
+ expectedOrder};
+ }
+
+ private static Identifiable createItem(String name) {
+ return new TestItem(GUID.create(), name);
+ }
+
+ private static final class TestItem extends AbstractIdentity<String> implements Identifiable {
+
+ private final String guid;
+ private final String name;
+
+ public TestItem(String guid, String name) {
+ super();
+ this.guid = guid;
+ this.name = name;
+ }
+
+ @Override
+ public String getGuid() {
+ return guid;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTestSuite.java b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTestSuite.java
new file mode 100644
index 0000000000..e98b703f44
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core.test/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterTestSuite.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.core.internal.relation.sorter;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Roberto E. Escobar
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({SorterTest.class, SorterProviderTest.class})
+public class SorterTestSuite {
+ // Test Suite
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.orcs.core/META-INF/MANIFEST.MF
index b323841296..cb230c3682 100644
--- a/plugins/org.eclipse.osee.orcs.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.orcs.core/META-INF/MANIFEST.MF
@@ -6,7 +6,8 @@ Bundle-Version: 0.14.0.qualifier
Bundle-Vendor: Eclipse Open System Engineering Environment
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Service-Component: OSGI-INF/*.xml
-Import-Package: org.eclipse.emf.common.notify,
+Import-Package: com.google.common.base,
+ org.eclipse.emf.common.notify,
org.eclipse.emf.common.util,
org.eclipse.emf.ecore,
org.eclipse.emf.ecore.util,
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/HasOrderData.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/HasOrderData.java
new file mode 100644
index 0000000000..4db3473c9b
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/HasOrderData.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.order;
+
+import java.util.Map.Entry;
+import org.eclipse.osee.framework.core.data.IRelationTypeSide;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public interface HasOrderData extends Iterable<Entry<IRelationTypeSide, OrderData>> {
+
+ void add(IRelationTypeSide typeAndSide, OrderData data) throws OseeCoreException;
+
+ void remove(IRelationTypeSide typeAndSide) throws OseeCoreException;
+
+ void clear();
+
+ boolean isEmpty();
+
+ int size();
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessor.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessor.java
new file mode 100644
index 0000000000..e37e42061c
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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.order;
+
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public interface OrderAccessor {
+
+ void load(HasOrderData data) throws OseeCoreException;
+
+ void store(HasOrderData data, OrderChange changeType) 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/order/OrderAccessorImpl.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorImpl.java
new file mode 100644
index 0000000000..2230cbc317
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderAccessorImpl.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.order;
+
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderAccessorImpl implements OrderAccessor {
+
+ private final OrderParser parser;
+ private final OrderStore storage;
+
+ public OrderAccessorImpl(OrderParser parser, OrderStore storage) {
+ super();
+ this.parser = parser;
+ this.storage = storage;
+ }
+
+ @Override
+ public void load(HasOrderData data) throws OseeCoreException {
+ data.clear();
+ String value = storage.getOrderData();
+ parser.loadFromXml(data, value);
+ }
+
+ @Override
+ public void store(HasOrderData data, OrderChange changeType) throws OseeCoreException {
+ if (changeType != OrderChange.NoChange) {
+ if (storage.isAccessible()) {
+ String value = "";
+ if (!data.isEmpty()) {
+ value = parser.toXml(data);
+ }
+ storage.storeOrderData(changeType, value);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderChange.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderChange.java
new file mode 100644
index 0000000000..0a08899724
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderChange.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * 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.order;
+
+public enum OrderChange {
+ NoChange,
+ OrderRequest,
+ SetToDefault,
+ Forced;
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderData.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderData.java
new file mode 100644
index 0000000000..72e0356c2f
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderData.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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.order;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderData {
+
+ private IRelationSorterId sorterId;
+ private List<String> guids;
+
+ public OrderData(IRelationSorterId sorterId, List<String> guids) {
+ super();
+ this.sorterId = sorterId;
+ this.guids = guids;
+ }
+
+ public void setSorterId(IRelationSorterId sorterId) {
+ this.sorterId = sorterId;
+ }
+
+ public IRelationSorterId getSorterId() {
+ return sorterId;
+ }
+
+ public void setOrderIds(List<String> guids) {
+ this.guids = guids;
+ }
+
+ public List<String> getOrderIds() {
+ return guids != null ? guids : Collections.<String> emptyList();
+ }
+
+ @Override
+ public String toString() {
+ return "OrderData [sorterId=" + sorterId + ", guids=" + guids + "]";
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEditState.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEditState.java
new file mode 100644
index 0000000000..dfd48a3312
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEditState.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * 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.order;
+
+public enum OrderEditState {
+ Reorder,
+ SetToDefaults;
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEntryComparator.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEntryComparator.java
new file mode 100644
index 0000000000..650af7ac9a
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderEntryComparator.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.order;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map.Entry;
+import org.eclipse.osee.framework.core.data.IRelationTypeSide;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderEntryComparator implements Comparator<Entry<IRelationTypeSide, OrderData>> {
+
+ @Override
+ public int compare(Entry<IRelationTypeSide, OrderData> o1, Entry<IRelationTypeSide, OrderData> o2) {
+ IRelationTypeSide typeSide1 = o1.getKey();
+ IRelationTypeSide typeSide2 = o2.getKey();
+ OrderData orderData1 = o1.getValue();
+ OrderData orderData2 = o2.getValue();
+
+ int result = typeSide1.getGuid().compareTo(typeSide2.getGuid());
+ if (result == 0) {
+ result = typeSide1.getSide().compareTo(typeSide2.getSide());
+ }
+ if (result == 0) {
+ result = orderData1.getSorterId().getGuid().compareTo(orderData2.getSorterId().getGuid());
+ }
+ if (result == 0) {
+ List<String> guids1 = new ArrayList<String>(orderData1.getOrderIds());
+ List<String> guids2 = new ArrayList<String>(orderData2.getOrderIds());
+ result = guids1.size() - guids2.size();
+ if (result == 0) {
+ Collections.sort(guids1);
+ Collections.sort(guids2);
+ for (int index = 0; index < guids1.size(); index++) {
+ result = guids1.get(index).compareTo(guids2.get(index));
+ if (result != 0) {
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManager.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManager.java
new file mode 100644
index 0000000000..853747b612
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManager.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * 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.order;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+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.enums.RelationOrderBaseTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.Conditions;
+import org.eclipse.osee.orcs.core.internal.relation.sorter.Sorter;
+import org.eclipse.osee.orcs.core.internal.relation.sorter.SorterProvider;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderManager implements HasOrderData {
+
+ private static final OrderEntryComparator ENTRY_COMPARATOR = new OrderEntryComparator();
+
+ private final Map<IRelationTypeSide, OrderData> orderDataMap = new ConcurrentHashMap<IRelationTypeSide, OrderData>();
+ private final OrderAccessor accessor;
+ private final SorterProvider sorterProvider;
+
+ public OrderManager(SorterProvider sorterProvider, OrderAccessor accessor) {
+ super();
+ this.sorterProvider = sorterProvider;
+ this.accessor = accessor;
+ }
+
+ @Override
+ public void add(IRelationTypeSide typeAndSide, OrderData data) throws OseeCoreException {
+ Conditions.checkNotNull(typeAndSide, "type and side key");
+ Conditions.checkNotNull(data, "orderData");
+
+ orderDataMap.put(typeAndSide, data);
+ }
+
+ @Override
+ public void remove(IRelationTypeSide typeAndSide) throws OseeCoreException {
+ Conditions.checkNotNull(typeAndSide, "type and side key");
+
+ orderDataMap.remove(typeAndSide);
+ }
+
+ @Override
+ public Iterator<Entry<IRelationTypeSide, OrderData>> iterator() {
+ List<Entry<IRelationTypeSide, OrderData>> entries =
+ new ArrayList<Entry<IRelationTypeSide, OrderData>>(orderDataMap.entrySet());
+ Collections.sort(entries, ENTRY_COMPARATOR);
+ return entries.iterator();
+ }
+
+ @Override
+ public void clear() {
+ orderDataMap.clear();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return orderDataMap.isEmpty();
+ }
+
+ @Override
+ public int size() {
+ return orderDataMap.size();
+ }
+
+ public void load() throws OseeCoreException {
+ accessor.load(this);
+ }
+
+ public void store() throws OseeCoreException {
+ accessor.store(this, OrderChange.Forced);
+ }
+
+ public Collection<IRelationTypeSide> getExistingTypes() {
+ return orderDataMap.keySet();
+ }
+
+ private OrderData getOrderData(IRelationTypeSide typeAndSide) throws OseeCoreException {
+ Conditions.checkNotNull(typeAndSide, "type and side key");
+ return orderDataMap.get(typeAndSide);
+ }
+
+ public List<String> getOrderIds(IRelationTypeSide typeAndSide) throws OseeCoreException {
+ Conditions.checkNotNull(typeAndSide, "type and side key");
+ OrderData data = orderDataMap.get(typeAndSide);
+ return data != null ? data.getOrderIds() : Collections.<String> emptyList();
+ }
+
+ public IRelationSorterId getSorterId(IRelationTypeSide typeAndSide) throws OseeCoreException {
+ Conditions.checkNotNull(typeAndSide, "type and side key");
+ OrderData data = orderDataMap.get(typeAndSide);
+ IRelationSorterId sorterId = null;
+ if (data != null) {
+ sorterId = data.getSorterId();
+ } else {
+ sorterId = getDefaultSorterId(typeAndSide);
+ }
+ return sorterId;
+ }
+
+ private IRelationSorterId getDefaultSorterId(IRelationType type) throws OseeCoreException {
+ return sorterProvider.getDefaultSorterId(type);
+ }
+
+ public void sort(IRelationTypeSide typeAndSide, List<? extends Identifiable> listToOrder) throws OseeCoreException {
+ if (listToOrder.size() > 1) {
+ IRelationSorterId sorterId = getSorterId(typeAndSide);
+ List<String> relativeOrder = getOrderIds(typeAndSide);
+
+ Sorter order = sorterProvider.getSorter(sorterId);
+ order.sort(listToOrder, relativeOrder);
+ }
+ }
+
+ public void setOrder(IRelationTypeSide typeAndSide, List<? extends Identifiable> relativeSequence) throws OseeCoreException {
+ IRelationSorterId sorterId = getSorterId(typeAndSide);
+ setOrder(typeAndSide, sorterId, relativeSequence);
+ }
+
+ public void setOrder(IRelationTypeSide typeAndSide, IRelationSorterId sorterId, List<? extends Identifiable> relativeSequence) throws OseeCoreException {
+ List<String> sequence;
+ if (!relativeSequence.isEmpty()) {
+ sequence = new ArrayList<String>();
+ for (Identifiable item : relativeSequence) {
+ sequence.add(item.getGuid());
+ }
+ } else {
+ sequence = Collections.emptyList();
+ }
+ setAndStoreOrder(typeAndSide, sorterId, sequence);
+ }
+
+ private void setAndStoreOrder(IRelationTypeSide typeAndSide, IRelationSorterId requestedSorterId, List<String> relativeSequence) throws OseeCoreException {
+ boolean isDifferentSorterId = isDifferentSorterId(typeAndSide, requestedSorterId);
+ boolean changingRelatives = isRelativeOrderChange(typeAndSide, requestedSorterId, relativeSequence);
+
+ OrderChange changeType = OrderChange.NoChange;
+ if (isDifferentSorterId || changingRelatives) {
+ if (isDifferentSorterId && isSetToDefaultSorter(typeAndSide, requestedSorterId)) {
+ remove(typeAndSide);
+ changeType = OrderChange.SetToDefault;
+ } else {
+ OrderData orderData = getOrderData(typeAndSide);
+ if (orderData == null) {
+ orderData = new OrderData(requestedSorterId, relativeSequence);
+ add(typeAndSide, orderData);
+ } else {
+ orderData.setSorterId(requestedSorterId);
+ orderData.setOrderIds(relativeSequence);
+ }
+ changeType = OrderChange.OrderRequest;
+ }
+ }
+ accessor.store(this, changeType);
+ }
+
+ private boolean isDifferentSorterId(IRelationTypeSide typeAndSide, IRelationSorterId newSorterId) throws OseeCoreException {
+ IRelationSorterId currentSorter = getSorterId(typeAndSide);
+ return !currentSorter.equals(newSorterId);
+ }
+
+ private boolean isSetToDefaultSorter(IRelationTypeSide typeAndSide, IRelationSorterId sorterId) throws OseeCoreException {
+ IRelationSorterId defaultSorterId = getDefaultSorterId(typeAndSide);
+ return defaultSorterId.equals(sorterId);
+ }
+
+ private boolean isRelativeOrderChange(IRelationTypeSide typeAndSide, IRelationSorterId sorterId, List<String> relativeSequence) throws OseeCoreException {
+ boolean result = false;
+ if (sorterId.equals(RelationOrderBaseTypes.USER_DEFINED)) {
+ List<String> currentOrder = getOrderIds(typeAndSide);
+ result = !areSame(currentOrder, relativeSequence);
+ }
+ return result;
+ }
+
+ private boolean areSame(List<String> list1, List<String> list2) {
+ boolean result = list1.size() == list2.size();
+ if (result) {
+ for (int index = 0; index < list1.size(); index++) {
+ String obj1 = list1.get(index);
+ String obj2 = list2.get(index);
+ if (!obj1.equals(obj2)) {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerFactory.java
new file mode 100644
index 0000000000..4c3b71c849
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderManagerFactory.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.orcs.core.internal.relation.sorter.SorterProvider;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderManagerFactory {
+
+ private final OrderParser parser;
+ private final SorterProvider sorterProvider;
+
+ public OrderManagerFactory(OrderParser parser, SorterProvider sorterProvider) {
+ super();
+ this.parser = parser;
+ this.sorterProvider = sorterProvider;
+ }
+
+ public OrderManager createOrderManager(OrderStore store) throws OseeCoreException {
+ OrderAccessor accessor = new OrderAccessorImpl(parser, store);
+ OrderManager manager = new OrderManager(sorterProvider, accessor);
+ manager.load();
+ return manager;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParser.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParser.java
new file mode 100644
index 0000000000..9ca3006081
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderParser.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+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.TokenFactory;
+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.exception.OseeExceptions;
+import org.eclipse.osee.framework.core.util.Conditions;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.orcs.data.RelationTypes;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public class OrderParser {
+
+ private static final String ROOT_ELEMENT = "OrderList";
+ private static final String START_TAG = "Order";
+ private static final String RELATION_TYPE_TAG = "relType";
+ private static final String ORDER_TYPE_TAG = "orderType";
+ private static final String SIDE_TAG = "side";
+ private static final String LIST_TAG = "list";
+
+ private static final ThreadLocal<XMLInputFactory> inputFactory = new ThreadLocal<XMLInputFactory>() {
+
+ @Override
+ protected XMLInputFactory initialValue() {
+ return XMLInputFactory.newInstance();
+ }
+ };
+
+ private static final ThreadLocal<XMLOutputFactory> outputFactory = new ThreadLocal<XMLOutputFactory>() {
+
+ @Override
+ protected XMLOutputFactory initialValue() {
+ return XMLOutputFactory.newInstance();
+ }
+ };
+
+ private final RelationTypes relationCache;
+
+ public OrderParser(RelationTypes relationCache) {
+ this.relationCache = relationCache;
+ }
+
+ public void loadFromXml(HasOrderData hasOrderData, String rawData) throws OseeCoreException {
+ Conditions.checkNotNull(hasOrderData, "orderData");
+ if (Strings.isValid(rawData) && rawData.trim().length() > 0) {
+ Reader reader = new StringReader(rawData);
+ try {
+ XMLStreamReader streamReader = inputFactory.get().createXMLStreamReader(reader);
+ while (streamReader.hasNext()) {
+ process(streamReader, hasOrderData);
+ streamReader.next();
+ }
+ } catch (XMLStreamException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ } finally {
+ Lib.close(reader);
+ }
+ }
+ }
+
+ private void process(XMLStreamReader reader, HasOrderData hasOrderData) throws OseeCoreException {
+ int eventType = reader.getEventType();
+ switch (eventType) {
+ case XMLStreamConstants.START_ELEMENT:
+ String localName = reader.getLocalName();
+ String uri = reader.getNamespaceURI();
+ if (START_TAG.equals(localName)) {
+ final String relationTypeName = reader.getAttributeValue(uri, RELATION_TYPE_TAG);
+ String orderType = reader.getAttributeValue(uri, ORDER_TYPE_TAG);
+ String relationSide = reader.getAttributeValue(uri, SIDE_TAG);
+ String rawList = reader.getAttributeValue(uri, LIST_TAG);
+ if (relationTypeName != null && orderType != null && relationSide != null) {
+ List<String> list = Collections.emptyList();
+ if (rawList != null) {
+ list = new ArrayList<String>();
+ StringTokenizer tokenizer = new StringTokenizer(rawList, ",");
+ while (tokenizer.hasMoreTokens()) {
+ list.add(tokenizer.nextToken());
+ }
+ }
+
+ // TODO don't store relation type by name - use type UUID
+ IRelationType type = Iterables.find(relationCache.getAll(), new Predicate<IRelationType>() {
+ @Override
+ public boolean apply(IRelationType type) {
+ return type.getName().equalsIgnoreCase(relationTypeName);
+ }
+ });
+
+ RelationSide side = RelationSide.fromString(relationSide);
+ IRelationTypeSide typeSide =
+ TokenFactory.createRelationTypeSide(side, type.getGuid(), type.getName());
+ IRelationSorterId sorterId = RelationOrderBaseTypes.getFromGuid(orderType);
+ OrderData orderData = new OrderData(sorterId, list);
+ hasOrderData.add(typeSide, orderData);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ public String toXml(HasOrderData hasOrderData) throws OseeCoreException {
+ Conditions.checkNotNull(hasOrderData, "orderData");
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter xmlWriter = null;
+ try {
+ xmlWriter = outputFactory.get().createXMLStreamWriter(writer);
+ xmlWriter.writeStartElement(ROOT_ELEMENT);
+ for (Entry<IRelationTypeSide, OrderData> entry : hasOrderData) {
+ writeEntry(xmlWriter, entry.getKey(), entry.getValue());
+ }
+ xmlWriter.writeEndElement();
+ xmlWriter.writeEndDocument();
+ } catch (XMLStreamException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ } finally {
+ if (xmlWriter != null) {
+ try {
+ xmlWriter.close();
+ } catch (XMLStreamException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ }
+ }
+ }
+ return writer.toString();
+ }
+
+ private void writeEntry(XMLStreamWriter xmlWriter, IRelationTypeSide typeAndSide, OrderData orderData) throws XMLStreamException {
+ xmlWriter.writeStartElement(START_TAG);
+ // TODO don't store relation type by name - use type UUID
+ xmlWriter.writeAttribute(RELATION_TYPE_TAG, typeAndSide.getName());
+ xmlWriter.writeAttribute(SIDE_TAG, typeAndSide.getSide().name());
+ xmlWriter.writeAttribute(ORDER_TYPE_TAG, orderData.getSorterId().getGuid());
+
+ List<String> guids = orderData.getOrderIds();
+ if (!guids.isEmpty()) {
+ xmlWriter.writeAttribute(LIST_TAG, org.eclipse.osee.framework.jdk.core.util.Collections.toString(",", guids));
+ }
+ xmlWriter.writeEndElement();
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderStore.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderStore.java
new file mode 100644
index 0000000000..d115c2c073
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/order/OrderStore.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.core.internal.relation.order;
+
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+
+/**
+ * @author Roberto E. Escobar
+ */
+public interface OrderStore {
+
+ boolean isAccessible();
+
+ String getOrderData() throws OseeCoreException;
+
+ void storeOrderData(OrderChange changeType, String data) throws OseeCoreException;
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/LexicographicalSorter.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/LexicographicalSorter.java
new file mode 100644
index 0000000000..3c3ab8c330
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/LexicographicalSorter.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.Identifiable;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+import org.eclipse.osee.orcs.utility.NameComparator;
+import org.eclipse.osee.orcs.utility.SortOrder;
+
+/**
+ * @author Andrew M. Finkbeiner
+ * @author Ryan Schmitt
+ */
+public class LexicographicalSorter implements Sorter {
+
+ private final NameComparator comparator;
+ private final IRelationSorterId id;
+
+ public LexicographicalSorter(SortOrder sortOrder) {
+ this.comparator = new NameComparator(sortOrder);
+ if (sortOrder.isAscending()) {
+ id = RelationOrderBaseTypes.LEXICOGRAPHICAL_ASC;
+ } else {
+ id = RelationOrderBaseTypes.LEXICOGRAPHICAL_DESC;
+ }
+ }
+
+ @Override
+ public IRelationSorterId getId() {
+ return id;
+ }
+
+ @Override
+ public void sort(List<? extends Identifiable> relatives, List<String> relativeSequence) {
+ Collections.sort(relatives, comparator);
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/Sorter.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/Sorter.java
new file mode 100644
index 0000000000..68ba31999a
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/Sorter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.Identifiable;
+
+/**
+ * @author Andrew M. Finkbeiner
+ */
+public interface Sorter {
+
+ IRelationSorterId getId();
+
+ void sort(List<? extends Identifiable> relatives, List<String> relativeSequence);
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProvider.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProvider.java
new file mode 100644
index 0000000000..edd5b8f44f
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/SorterProvider.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.IRelationType;
+import org.eclipse.osee.framework.core.data.Named;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.util.Conditions;
+import org.eclipse.osee.orcs.data.RelationTypes;
+import org.eclipse.osee.orcs.utility.SortOrder;
+
+/**
+ * @author Andrew M. Finkbeiner
+ * @author Ryan Schmitt
+ */
+public class SorterProvider {
+
+ private final Map<IRelationSorterId, Sorter> orderMap = new HashMap<IRelationSorterId, Sorter>();
+ private final List<IRelationSorterId> ids = new ArrayList<IRelationSorterId>();
+
+ private final RelationTypes typeCache;
+
+ public SorterProvider(RelationTypes typeCache) {
+ this.typeCache = typeCache;
+
+ registerOrderType(new LexicographicalSorter(SortOrder.ASCENDING));
+ registerOrderType(new LexicographicalSorter(SortOrder.DESCENDING));
+ registerOrderType(new UnorderedSorter());
+ registerOrderType(new UserDefinedSorter());
+
+ Collection<Sorter> sorters = orderMap.values();
+ for (Sorter sorter : sorters) {
+ ids.add(sorter.getId());
+ }
+ Collections.sort(ids, new CaseInsensitiveNameComparator());
+ }
+
+ private void registerOrderType(Sorter order) {
+ orderMap.put(order.getId(), order);
+ }
+
+ public IRelationSorterId getDefaultSorterId(IRelationType relationType) throws OseeCoreException {
+ Conditions.checkNotNull(relationType, "type");
+ String orderTypeGuid = typeCache.getDefaultOrderTypeGuid(relationType);
+ Conditions.checkNotNullOrEmpty(orderTypeGuid, "defaultOrderTypeGuid", "Invalid default order type uuid for [%s]",
+ relationType);
+ return RelationOrderBaseTypes.getFromGuid(orderTypeGuid);
+ }
+
+ public List<IRelationSorterId> getSorterIds() {
+ return ids;
+ }
+
+ public boolean exists(IRelationSorterId sorterId) throws OseeCoreException {
+ Conditions.checkNotNull(sorterId, "sorterId");
+ return orderMap.containsKey(sorterId);
+ }
+
+ public Sorter getSorter(IRelationSorterId sorterId) throws OseeCoreException {
+ Conditions.checkNotNull(sorterId, "sorterId");
+ Sorter sorter = orderMap.get(sorterId);
+ Conditions.checkNotNull(sorter, "sorter", "Unable to locate sorter with sorterId %s", sorterId);
+ return sorter;
+ }
+
+ private static final class CaseInsensitiveNameComparator implements Comparator<Named> {
+ @Override
+ public int compare(Named o1, Named o2) {
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UnorderedSorter.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UnorderedSorter.java
new file mode 100644
index 0000000000..9a383c5a72
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UnorderedSorter.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.Identifiable;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+
+/**
+ * @author Andrew M. Finkbeiner
+ */
+public class UnorderedSorter implements Sorter {
+
+ @Override
+ public IRelationSorterId getId() {
+ return RelationOrderBaseTypes.UNORDERED;
+ }
+
+ @Override
+ public void sort(List<? extends Identifiable> relatives, List<String> relativeSequence) {
+ // do nothing
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedComparator.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedComparator.java
new file mode 100644
index 0000000000..6cd64f383b
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedComparator.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.osee.framework.core.data.Identifiable;
+
+/**
+ * @author Andrew M. Finkbeiner
+ */
+public class UserDefinedComparator implements Comparator<Identifiable> {
+
+ private final Map<String, Integer> value;
+
+ public UserDefinedComparator(List<String> guidOrder) {
+ value = new HashMap<String, Integer>(guidOrder.size());
+ for (int i = 0; i < guidOrder.size(); i++) {
+ value.put(guidOrder.get(i), i);
+ }
+ }
+
+ @Override
+ public int compare(Identifiable object1, Identifiable object2) {
+ Integer val1 = getIndex(object1);
+ Integer val2 = getIndex(object2);
+ if (val1 == null) {
+ val1 = Integer.MAX_VALUE - 1;
+ }
+ if (val2 == null) {
+ val2 = Integer.MAX_VALUE;
+ }
+ return val1 - val2;
+ }
+
+ private Integer getIndex(Identifiable object) {
+ Integer toReturn = null;
+ if (object != null) {
+ toReturn = value.get(object.getGuid());
+ }
+ return toReturn;
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedSorter.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedSorter.java
new file mode 100644
index 0000000000..576ad5b5c2
--- /dev/null
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/relation/sorter/UserDefinedSorter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.core.internal.relation.sorter;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.osee.framework.core.data.IRelationSorterId;
+import org.eclipse.osee.framework.core.data.Identifiable;
+import org.eclipse.osee.framework.core.enums.RelationOrderBaseTypes;
+
+/**
+ * @author Andrew M. Finkbeiner
+ */
+public class UserDefinedSorter implements Sorter {
+
+ @Override
+ public IRelationSorterId getId() {
+ return RelationOrderBaseTypes.USER_DEFINED;
+ }
+
+ @Override
+ public void sort(List<? extends Identifiable> relatives, List<String> relativeSequence) {
+ if (!relatives.isEmpty()) {
+ Collections.sort(relatives, new UserDefinedComparator(relativeSequence));
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/utility/NameComparator.java b/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/utility/NameComparator.java
index faa35a60fe..e0bf31809b 100644
--- a/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/utility/NameComparator.java
+++ b/plugins/org.eclipse.osee.orcs/src/org/eclipse/osee/orcs/utility/NameComparator.java
@@ -20,7 +20,7 @@ public class NameComparator implements Comparator<Named> {
private static final Pattern numberPattern = Pattern.compile("[+-]?\\d+");
private final Matcher numberMatcher = numberPattern.matcher("");
- private SortOrder orderType = SortOrder.ASCENDING;
+ private final SortOrder orderType;
public NameComparator(SortOrder orderType) {
this.orderType = orderType;
@@ -36,16 +36,12 @@ public class NameComparator implements Comparator<Named> {
String name1 = getName(o1);
String name2 = getName(o2);
- numberMatcher.reset(name1);
- if (numberMatcher.matches()) {
- numberMatcher.reset(name2);
- if (numberMatcher.matches()) {
- if ((name1.length() < NUMBER_STRING_LIMIT) && (name2.length() < NUMBER_STRING_LIMIT)) {
- if (orderType.isAscending()) {
- return Long.valueOf(name1).compareTo(Long.valueOf(name2));
- } else {
- return Long.valueOf(name2).compareTo(Long.valueOf(name1));
- }
+ if (areNumbers(name1, name2)) {
+ if ((name1.length() < NUMBER_STRING_LIMIT) && (name2.length() < NUMBER_STRING_LIMIT)) {
+ if (orderType.isAscending()) {
+ return Long.valueOf(name1).compareTo(Long.valueOf(name2));
+ } else {
+ return Long.valueOf(name2).compareTo(Long.valueOf(name1));
}
}
}
@@ -55,4 +51,18 @@ public class NameComparator implements Comparator<Named> {
return name2.compareTo(name1);
}
}
+
+ private boolean areNumbers(String o1, String o2) {
+ boolean result = false;
+ if (o1 != null && o2 != null) {
+ numberMatcher.reset(o1);
+ if (numberMatcher.matches()) {
+ numberMatcher.reset(o2);
+ if (numberMatcher.matches()) {
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
} \ No newline at end of file

Back to the top