/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package test.sdo21.tests.api; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Enclosed; import org.junit.runners.Suite; import test.sdo21.tests.TestData.StandardDynamicFactory; import test.sdo21.tests.TestData.StandardFactory; import test.sdo21.tests.TestData.StandardXSDFactory; import test.sdo21.tests.TestData.TestDataFactory; import commonj.sdo.DataObject; import commonj.sdo.Sequence; /** * Tests prevdention of containment cycles. Each test passes if the method call that * would result in a containment cycle throws an IllegalArgumentException and does * not allow the formation of containment cycle. There is a test case for * each of the various mechanisms through which a containment cycle may be created. */ public abstract class ContainmentCyclePreventionTest extends CTSConsistencyBase { public ContainmentCyclePreventionTest() { } public static class DynamicMetadata extends ContainmentCyclePreventionTest { public DynamicMetadata() { } public TestDataFactory createTestDataFactory() { return new StandardDynamicFactory(); } } public static class XSDMetadata extends ContainmentCyclePreventionTest { public XSDMetadata() { } public TestDataFactory createTestDataFactory() { return new StandardXSDFactory(); } } @Before public void setUp () throws Exception { super.setUp(); } @After public void tearDown() throws Exception { super.tearDown(); } /** * Attempt to create a 1-Member Containment Cycle using set____ on a single valued property * and verify the behavior of the method. * @throws Exception */ @Test public void oneMemberSingleValueSetDataObject() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); setSingleValueOneMember(dataObj1); } /** * Attempt to create an n-Member Containment Cycle using set____ on a single valued property * and verify the behavior of the method. * @throws Exception */ @Test public void nMemberSingleValueSetDataObject() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.API_TYPE); setSingleValueNMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create a 1-Member Containment Cycle using set____ on a multi valued property * and verify the behavior of the method. * @throws Exception */ @Test public void oneMemberMultiValueSetDataObject() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.API_TYPE); setMultiValueOneMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create an n-Member Containment Cycle using set____ on a multi valued property * and verify the behavior of the method. * @throws Exception */ @Test public void nMemberMultiValueSetDataObject() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.API_TYPE); setManyValueNMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create a 1-Member Containment Cycle by making updates to a List returned * from the DataObject and verify the behavior of the method. This is the static version * of this test case. * @throws Exception */ @Test public void oneMemberReturnedList() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); returnedListOneMember(dataObj1); } /** * Attempt to create an n-Member Containment Cycle by making updates to a List returned * from the DataObject and verify the behavior of the method. This is the static version * of this test case. * @throws Exception */ @Test public void nMemberReturnedList() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.API_TYPE); DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.API_TYPE); returnedListNMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create a 1-Member Containment Cycle using by using a Sequence to make updates * to the DataObject, affecting a single valued property, and verify the behavior of * the method. * @throws Exception */ @Test public void oneMemberSingleValueSequence() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE); sequenceSingleValueOneMember(dataObj1); } /** * Attempt to create an n-Member Containment Cycle using by using a Sequence to make updates * to the DataObject, affecting a single valued property, and verify the behavior of * the method. * @throws Exception */ @Test public void nMemberSingleValueSequence() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; sequenceSingleValueNMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create a 1-Member Containment Cycle using by using a Sequence to make updates * to the DataObject, affecting a multi valued property, and verify the behavior of * the method. * @throws Exception */ @Test public void oneMemberMultiValueSequence() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; sequenceMultiValueOneMember(dataObj1, dataObj2, dataObj3); } /** * Attempt to create an n-Member Containment Cycle using by using a Sequence to make updates * to the DataObject, affecting a multi valued property, and verify the behavior of * the method. * @throws Exception */ @Test public void nMemberMultiValueSequence() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj2 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; DataObject dataObj3 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE);; sequenceManyValueNMember(dataObj1, dataObj2, dataObj3); } /** * Returns true if input DataObject root is part of a containment cycle, * false otherwise. * @param root * @return */ private static boolean containmentCycleExists (DataObject root) { DataObject curr = root.getContainer(); while (curr != null) { if (curr == root) return true; curr = curr.getContainer(); } return false; } /** * Use setDataObject to create a one member containment cycle. * @param dataObj1 */ private void setSingleValueOneMember(DataObject dataObj1) { try { dataObj1.setDataObject("contain", dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Use setDataObject to create an N-member containment cycle. * @param dataObj1 * @param dataObj2 * @param dataobj3 */ private void setSingleValueNMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { dataObj1.setDataObject("contain", dataObj2); dataObj2.setDataObject("contain", dataObj3); try { dataObj3.setDataObject("contain", dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Use setList to create a one member containment cycle. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void setMultiValueOneMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { List addList = new ArrayList(); addList.add(dataObj2); addList.add(dataObj1); addList.add(dataObj3); try { dataObj1.setList("containMany", addList); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Use setList to create an N-member containment cycle. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void setManyValueNMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { List addList = new ArrayList(); dataObj1.setDataObject("contain", dataObj2); dataObj2.setDataObject("contain", dataObj3); addList.add(dataObj1); try { dataObj3.setList("containMany", addList); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create a 1-member containment cycle by making updates to a returned List. * @param dataObj1 */ private void returnedListOneMember(DataObject dataObj1) { List returnedList = dataObj1.getList("containMany"); try { returnedList.add(dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create an n-member containment cycle by making updates to a returned List. * @param dataObj1 * @param dataObj2 * @param dataobj3 */ private void returnedListNMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { dataObj1.setDataObject("contain", dataObj2); dataObj2.setDataObject("contain", dataObj3); List returnedList = dataObj3.getList("containMany"); try { returnedList.add(dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create a 1-member containment cycle by making updates to a Sequence. * The data member in this case is single valued. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void sequenceSingleValueOneMember(DataObject dataObj1) { assertTrue("DataObject is not Sequenced. Test case may not proceed.", dataObj1.getType().isSequenced()); Sequence sequence = dataObj1.getSequence(); try { sequence.add("contain", dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create an n-member containment cycle by making updates to a Sequence. * The data member in this case is single valued. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void sequenceSingleValueNMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { assertTrue("DataObject is not Sequenced. Test case may not proceed.", dataObj1.getType().isSequenced()); Sequence sequence1 = dataObj1.getSequence(); Sequence sequence2 = dataObj2.getSequence(); Sequence sequence3 = dataObj3.getSequence(); sequence1.add("contain", (Object) dataObj2); sequence2.add("contain", (Object) dataObj3); try { sequence3.add("contain", (Object) dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create a 1-member containment cycle by making updates to a Sequence. * The data member in this case is many valued. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void sequenceMultiValueOneMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { assertTrue("DataObject is not Sequenced. Test case may not proceed.", dataObj1.getType().isSequenced()); Sequence sequence = dataObj1.getSequence(); sequence.add("containMany", dataObj2); sequence.add("containMany", dataObj3); try { sequence.add("containMany", dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } /** * Create an n-member containment cycle by making updates to a Sequence. * The data member in this case is many valued. * @param dataObj1 * @param dataObj2 * @param dataObj3 */ private void sequenceManyValueNMember(DataObject dataObj1, DataObject dataObj2, DataObject dataObj3) { assertTrue("DataObject is not Sequenced. Test case may not proceed.", dataObj1.getType().isSequenced()); List addList = new ArrayList(); addList.add(dataObj2); dataObj1.setList("containMany", addList); addList.clear(); addList.add(dataObj3); dataObj2.setList("containMany", addList); Sequence sequence = dataObj3.getSequence(); try { sequence.add("containMany", dataObj1); if (containmentCycleExists(dataObj1)) fail("Attempting to create a containment cycle should result in an Exception."); else fail("Containment cycle was neither created nor prevented."); } catch (Exception e) { // do nothing - success } } }