/* * 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.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; 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 test.sdo21.tests.util.CTSUtil; import commonj.sdo.DataObject; import commonj.sdo.Sequence; import commonj.sdo.helper.HelperContext; /** * Tests serialization of containment cycles. Each test passes if the serialization does * not generate output representing the containment cycle. There is a test case for * each of the various mechanisms through which a containment cycle may be created and serialized. * * Note also that Java serialization of a containment cycle should result in an IllegalStateException, * while XMLHelper and XMLStreamHelper serialization should successfully serialize the DataObject * absent the containment cycle. */ public abstract class ContainmentCycleSerializationTest extends CTSConsistencyBase { public ContainmentCycleSerializationTest() { } public static class DynamicMetadata extends ContainmentCycleSerializationTest { public DynamicMetadata() { } public TestDataFactory createTestDataFactory() { return new StandardDynamicFactory(); } } public static class XSDMetadata extends ContainmentCycleSerializationTest { 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 serialization. * @throws Exception */ @Test public void oneMemberSingleValueSetDataObject() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.API_TYPE); setSingleValueOneMember(dataObj1); attemptSerialization(dataObj1, getScope()); } /** * Attempt to create an n-Member Containment Cycle using set____ on a single valued property * and verify the behavior of serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * Attempt to create a 1-Member Containment Cycle using set____ on a multi valued property * and verify the behavior of serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * Attempt to create an n-Member Containment Cycle using set____ on a multi valued property * and verify the behavior of serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * Attempt to create a 1-Member Containment Cycle by making updates to a List returned * from the DataObject and verify the behavior of serialization. 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); attemptSerialization(dataObj1, getScope()); } /** * Attempt to create an n-Member Containment Cycle by making updates to a List returned * from the DataObject and verify the behavior of serialization. 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); attemptSerialization(dataObj1, getScope()); } /** * 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 * serialization. * @throws Exception */ @Test public void oneMemberSingleValueSequence() throws Exception { DataObject dataObj1 = factory.createTestData(getScope(), StandardFactory.SEQ_TYPE); sequenceSingleValueOneMember(dataObj1); attemptSerialization(dataObj1, getScope()); } /** * 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 * serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * 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 * serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * 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 * serialization. * @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); attemptSerialization(dataObj1, getScope()); } /** * Attempt to serialize the DataObject in via XML, XMLStreamHelper, * and Java serialization. * @param dataObj */ private void attemptSerialization(DataObject dataObj, HelperContext scope) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); assertTrue("Containment cycle was not established.", containmentCycleExists(dataObj)); try { CTSUtil.serializeDataObjectXML(dataObj, baos, scope); } catch (Exception e) { fail("XML serialization of a containment cycle resulted in a(n) " + e.getClass().getName() + "."); e.printStackTrace(); } assertTrue("Containment cycle was affected by XMLHelper serialization.", containmentCycleExists(dataObj)); try { CTSUtil.serializeDataObjectJava(getTestHelper(), dataObj, baos, scope); fail("Java serialization of a containment cycle should result in an IllegalStateException."); } catch (Exception e) { // Do nothing. An Exception is expected in this case. } assertTrue("Containment cycle was affected by Java serialization.", containmentCycleExists(dataObj)); // try { // ParamatizedTestUtil.serializeDataObjectStream(dataObj, baos, scope); // } catch (Exception e) { // fail("XMLStreamHelper serialization of a containment cycle resulted in a(n) " + e.getClass().getName() + "."); // e.printStackTrace(); // } // assertTrue("Containment cycle was affected by XMLStreamHelper serialization.", // containmentCycleExists(dataObj)); } /** * 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); } 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); } 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); } 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); } 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); } 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); } 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); } 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); } 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); } 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); } catch (Exception e) { // do nothing - success } } }