/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.sdo;

import commonj.sdo.ChangeSummary;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.Sequence;
import commonj.sdo.helper.CopyHelper;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.EqualityHelper;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.helper.XMLHelper;
import commonj.sdo.helper.XSDHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.persistence.oxm.sequenced.Setting;
import org.eclipse.persistence.sdo.SDOChangeSummary;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOSequence;
import org.eclipse.persistence.sdo.SDOSetting;
import org.eclipse.persistence.sdo.ValueStore;
import org.eclipse.persistence.sdo.helper.SDODataHelper;
import org.eclipse.persistence.sdo.helper.SDOHelperContext;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.helper.SDOXSDHelper;
import commonj.sdo.Type;
import commonj.sdo.impl.HelperProvider;
import org.eclipse.persistence.Version;
import org.eclipse.persistence.logging.AbstractSessionLog;

import static org.eclipse.persistence.sdo.SDOConstants.*;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SDOTestCase extends junit.framework.TestCase {

    static {
        System.setProperty("user.timezone", "Canada/Eastern");
    }

    public boolean useLogging = false;
    public boolean ignoreCRLF = false;
    public boolean customContext = false;
    public boolean loggingLevelFinest = false;
    public HelperContext aHelperContext;
    public TypeHelper typeHelper;
    public XMLHelper xmlHelper;
    public XSDHelper xsdHelper;
    public EqualityHelper equalityHelper;
    public CopyHelper copyHelper;
    public DataFactory dataFactory;
    public SDODataHelper dataHelper;
    public DocumentBuilder parser;
    public String classgenCompilePath;
    public String tempFileDir;
    public SDOXMLComparer xmlComparer;

    protected static final String USER_DIR = System.getProperty("user.dir").replace('\\', '/');
    protected static final String FILE_PROTOCOL = USER_DIR.startsWith("/")? "file:" : "file:/";
    protected static final String HTTP_PROTOCOL = "http://";
    protected static final String NON_DEFAULT_JAVA_PACKAGE_DIR = "org/example";
    protected static final String NON_DEFAULT_JAVA_PACKAGE_NAME = "org.example";
    protected static final String NON_DEFAULT_URI = "http://www.example.org";

    public SDOTestCase(String name) {
        super(name);
        useLogging = Boolean.getBoolean("useLogging");
        ignoreCRLF = Boolean.getBoolean("ignoreCRLF");
        customContext = Boolean.getBoolean("customContext");
        loggingLevelFinest = Boolean.getBoolean("loggingLevelFinest");
        classgenCompilePath = System.getProperty("sdo.classgen.compile.path");
        tempFileDir = System.getProperty("tempFileDir");
        if(null == tempFileDir || tempFileDir.length() < 1) {
            tempFileDir = ".";
        }

        if (loggingLevelFinest && AbstractSessionLog.getLog().getLevel() != AbstractSessionLog.FINEST) {
            // override default INFO logging level for static logs
            AbstractSessionLog.getLog().setLevel(AbstractSessionLog.FINEST);
            AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, "{0} {1}", //
                    new Object[] {Version.getProduct(), Version.getVersionString()}, false);
        }

        // reverse the flags so that a false(from the flag not found) will not
        // default to a static context
    }

    @Override
    public void setUp() {
        xmlComparer = new SDOXMLComparer();
        if (customContext) {
            // default to instance of a HelperContext
            aHelperContext = new SDOHelperContext();
        } else {
            // default to static context (Global)
            aHelperContext = HelperProvider.getDefaultContext();
        }
        typeHelper = aHelperContext.getTypeHelper();
        xmlHelper = aHelperContext.getXMLHelper();
        xsdHelper = aHelperContext.getXSDHelper();
        equalityHelper = aHelperContext.getEqualityHelper();
        copyHelper = aHelperContext.getCopyHelper();
        dataFactory = aHelperContext.getDataFactory();
        // TODO: we should be using the DataHelper interface
        dataHelper = (SDODataHelper)aHelperContext.getDataHelper();

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(true);
        builderFactory.setIgnoringElementContentWhitespace(true);
        try {
            parser = builderFactory.newDocumentBuilder();
        } catch (Exception e) {
            fail("Could not create parser.");
            e.printStackTrace();
        }

        ((SDOTypeHelper) typeHelper).reset();
        ((SDOXMLHelper) xmlHelper).reset();
        ((SDOXSDHelper) xsdHelper).reset();
    }

    @Override
    public void tearDown() throws Exception {

        ((SDOTypeHelper) typeHelper).reset();
        ((SDOXMLHelper) xmlHelper).reset();
        ((SDOXSDHelper) xsdHelper).reset();

        typeHelper = null;
        xmlHelper = null;
        xsdHelper = null;
        equalityHelper = null;
        copyHelper = null;
        dataFactory = null;
        parser = null;
        aHelperContext = null;


    }

    public void assertXMLIdentical(Document control, Document test) {
        boolean isEqual = xmlComparer.isNodeEqual(control, test);
        String controlString = "";
        String testString = "";

        if (!isEqual) {
            org.eclipse.persistence.platform.xml.XMLTransformer t =
                org.eclipse.persistence.platform.xml.XMLPlatformFactory.getInstance().getXMLPlatform().newXMLTransformer();
            java.io.StringWriter controlWriter = new java.io.StringWriter();
            t.transform(control, controlWriter);

            t = org.eclipse.persistence.platform.xml.XMLPlatformFactory.getInstance().getXMLPlatform().newXMLTransformer();
            java.io.StringWriter testWriter = new java.io.StringWriter();
            t.transform(test, testWriter);

            controlString = controlWriter.toString();
            testString = testWriter.toString();
        }

        assertTrue("Documents are not equal.\nCONTROL:\n" + controlString + "\nTEST:\n" + testString, isEqual);
    }

    public void assertSchemaIdentical(Document control, Document test) {
        assertTrue("Node " + control + " is not equal to node " + test, xmlComparer.isSchemaEqual(control, test));
    }
    @Override
    public String getName() {
        String longClassName = getClass().getName();
        String shortClassName = longClassName.substring(longClassName.lastIndexOf(".") + 1, longClassName.length() - 1);
        return shortClassName + SDO_XPATH_NS_SEPARATOR_FRAGMENT + super.getName();
    }

    protected void log(String string) {
        if (useLogging) {
            System.out.println(string);
        }
    }

    protected void log(List items) {
        if (useLogging) {
            for (int i = 0; i < items.size(); i++) {
                log(items.get(i));
            }
        }
    }

    protected void log(Object object) {
        if (useLogging) {
            if (object instanceof Type) {
                log((Type) object);
            } else {
                System.out.println(object.toString());
            }
        }
    }

    protected void log(Type type) {
        if (useLogging) {
            System.out.println(type.getURI());
            System.out.println(type.getName());
        }
    }

    public String getSchema(String fileName) {
        String xsdSchema = EMPTY_STRING;
        FileInputStream is = null;
        try {
            is = new FileInputStream(fileName);
            return getSchema(is, fileName);
        } catch (Exception e) {
            log(getClass().toString() + ": Reading error for : " + fileName + " message: " + e.getClass() + " " + e.getMessage());
        } finally {
            try {
                if (null != is) {
                    is.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return xsdSchema;
    }

 public String getSchema(InputStream is, String fileName) {
        String xsdSchema = EMPTY_STRING;
        try {
            byte[] bytes = new byte[is.available()];
            is.read(bytes);
            xsdSchema = removeCopyrightFromString(new String(bytes));
            log(xsdSchema);
            return xsdSchema;
        } catch (Exception e) {
            log(getClass().toString() + ": Reading error for : " + fileName + " message: " + e.getClass() + " " + e.getMessage());
        } finally {
            try {
                if (null != is) {
                    is.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return xsdSchema;
    }

    /* Tree specific algorithms to aide in testing */
    /**
     * Return the depth of this dataObject from it's root
     *
     * @return int
     */
    public int depth(DataObject aChild) {
        if (null == aChild.getContainer()) {
            // base case
            return 0;
        } else {
            // recursive case
            return 1 + depth(aChild.getContainer());
        }
    }

    // diff function required

    /**
     * Return an ArrayList of all the DataObjects in the tree in a preOrder
     * fashion
     */
    public List<DataObject> preOrderTraversalDataObjectList(SDODataObject currentDO) {
        return preOrderTraversalDataObjectList(currentDO, new ArrayList<DataObject>(), false, true);
    }

    public List<DataObject> preOrderTraversalDataObjectList(DataObject currentDO) {
        return preOrderTraversalDataObjectList((SDODataObject) currentDO, new ArrayList<DataObject>(), false, true);
    }

    /**
     * Return an ArrayList of all the DataObjects (including unset ones) in the
     * tree in a preOrder fashion
     */
    public List<DataObject> preOrderTraversalDataObjectList(SDODataObject currentDO, boolean countNullObjects) {
        return preOrderTraversalDataObjectList(currentDO, new ArrayList<DataObject>(), countNullObjects, true);
    }

    private List<DataObject> preOrderTraversalDataObjectList(SDODataObject currentDO, ArrayList<DataObject> currentList, boolean countNullObjects, boolean recurse) {
        if (currentDO != null) {
            // add yourself
            currentList.add(currentDO);
            // check DO's recursively
            List instanceProperties = currentDO.getInstanceProperties();
            SDOProperty nextProperty = null;
            Object value = null;
            if (recurse) {
                for (int i = 0; i < instanceProperties.size(); i++) {
                    nextProperty = (SDOProperty) instanceProperties.get(i);
                    value = currentDO.get(nextProperty);
                    boolean recurseHopefullyNotToInfinityPlease = true;
                    if (!nextProperty.getType().isChangeSummaryType() && !nextProperty.getType().isDataType()) {
                        // don't traverse into opposite properties to avoid an
                        // infinite loop
                        if (null != nextProperty.getOpposite()) {
                            recurseHopefullyNotToInfinityPlease = false;
                        }

                        if (nextProperty.isMany()) {
                            // iterate list
                            Object manyItem;

                            // use of delete while using an iterator will
                            // generate a ConcurrentModificationException
                            for (int index = 0; index < ((List) value).size(); index++) {
                                manyItem = ((List) value).get(index);
                                if (manyItem != null && manyItem instanceof SDODataObject) {
                                    preOrderTraversalDataObjectList((SDODataObject) manyItem, currentList, countNullObjects, recurseHopefullyNotToInfinityPlease);
                                }
                            }
                        } else {
                            if (value != null) {
                                preOrderTraversalDataObjectList((SDODataObject) value, currentList, countNullObjects, recurseHopefullyNotToInfinityPlease);
                            }
                        }
                    }
                }
            }
        } else {
            if (countNullObjects) {
                currentList.add(currentDO);
            }
        }
        return currentList;
    }

    protected void assertCreated(DataObject dataObject, ChangeSummary changeSummary) {
        assertTrue(changeSummary.isCreated(dataObject));
        assertFalse(changeSummary.isModified(dataObject));
        assertFalse(changeSummary.isDeleted(dataObject));
        // if we are at the root then there is no parent to track
        if (null != dataObject.getContainer()) {
            // check that parent (if not the root) sequence has been saved in
            // originalSequences (if dataObject is not an attribute - which it
            // is not)
            if (dataObject.getContainer().getSequence() != null) {
                assertNotNull(changeSummary.getOldSequence(dataObject.getContainer()));
            } else {
                assertNull(changeSummary.getOldSequence(dataObject.getContainer()));
            }
        }
        assertEquals(0, changeSummary.getOldValues(dataObject).size());
    }

    protected void assertModified(DataObject dataObject, ChangeSummary changeSummary) {
        assertFalse(changeSummary.isCreated(dataObject));
        assertTrue(changeSummary.isModified(dataObject));
        assertFalse(changeSummary.isDeleted(dataObject));
    }

    protected void assertChildrenUnset(DataObject dataobject) {
        // verify all properties are unset and all many properties are size 0
        Iterator anIterator = dataobject.getType().getProperties().iterator();
        while (anIterator.hasNext()) {
            Property aProperty = (Property) anIterator.next();
            Object aPropertyValue = dataobject.get(aProperty);
            assertFalse(dataobject.isSet(aProperty));
            // all properties must be unset
            if (aProperty.isMany()) {
                assertSame(((List) aPropertyValue).size(), 0);
            } else {
                if(!aProperty.getType().isDataType()) {
                    assertEquals(aProperty.getDefault(),aPropertyValue);
                    // assertSame(aProperty.getDefault(), dataobject.get(aProperty));
                } else {
                    // JIRA-253: we return a wrapped numeric primitive when it has no default
                    Type aType = aProperty.getType();
                    if (aType.equals(SDO_BOOLEAN)) {
                        assertEquals(false, ((Boolean)aPropertyValue).booleanValue());
                    } else if (aType.equals(SDO_BYTE)) {
                        assertEquals(0, ((Byte)aPropertyValue).byteValue());
                    } else if (aType.equals(SDO_CHARACTER)) {
                        assertEquals(0, ((Character)aPropertyValue).charValue());
                    } else if (aType.equals(SDO_DOUBLE)) {
                        assertEquals(0, aPropertyValue);
                    } else if (aType.equals(SDO_FLOAT)) {
                        assertEquals(0, aPropertyValue);
                    } else if (aType.equals(SDO_INT)) {
                        assertEquals(0, ((Integer)aPropertyValue).intValue());
                    } else if (aType.equals(SDO_SHORT)) {
                        assertEquals(0, ((Short)aPropertyValue).shortValue());
                    } else if (aType.equals(SDO_LONG)) {
                        assertEquals(0, ((Long)aPropertyValue).longValue());
                    }
                }
            }
        }
    }

    protected void assertDeleted(DataObject dataobject, ChangeSummary changeSummary) {
        assertDeleted(dataobject, changeSummary, true, false, false);
    }

    protected void assertDeleted(DataObject dataobject, ChangeSummary changeSummary, boolean nullContainer) {
        assertDeleted(dataobject, changeSummary, nullContainer, false, false);
    }

    // for objects that were detached and then (re)set - their container and cs
    // will not be null but they will have oldSettings/deletedList items
    protected void assertDeleted(DataObject dataObject, ChangeSummary changeSummary, boolean nullContainer, boolean testLoadSave) {
        assertDeleted(dataObject, changeSummary, nullContainer, false, testLoadSave);
        assertChildrenUnset(dataObject);
    }

    protected void assertDeleted(DataObject dataObject, ChangeSummary changeSummary, boolean nullContainer, boolean isReAttached, boolean testLoadSave) {
        assertFalse(changeSummary.isCreated(dataObject));
        assertFalse(changeSummary.isModified(dataObject));
        if (!isReAttached) {
            assertTrue(changeSummary.isDeleted(dataObject));
            if (dataObject.getSequence() != null) {
                assertNotNull(changeSummary.getOldSequence(dataObject));
            } else {
                assertNull(changeSummary.getOldSequence(dataObject));
            }
        } else {
            assertFalse(changeSummary.isDeleted(dataObject));
        }

        int propertySize = dataObject.getType().getProperties().size();
        int oldValuesSize = changeSummary.getOldValues(dataObject).size();

        assertEquals(propertySize, oldValuesSize);

        // for objects that were detached and then (re)set - their container and
        // cs will not be null but they will have oldSettings/deletedList items
        if (nullContainer) {
            assertNull(dataObject.getContainer());
            // verify that the cs is not set on deleted/detached objects
            assertNull(dataObject.getChangeSummary());
        }

        assertChildrenUnset(dataObject);
    }

    // detached objects' properties are intact and not unset
    protected void assertDetached(DataObject dataobject, ChangeSummary changeSummary) {
        assertDetached(dataobject, changeSummary, true, false, false);
    }

    // we delete/detach and then (Re)set - deletedSet is cleared but oldSettings
    // remain (for now until we have smart undo code)
    protected void assertDetachedAndReset(DataObject dataobject, ChangeSummary changeSummary, boolean nullContainment) {
        assertDetached(dataobject, changeSummary, nullContainment, true, false);
    }

    protected void assertDetached(DataObject dataobject, ChangeSummary changeSummary, boolean nullContainment) {
        assertDetached(dataobject, changeSummary, nullContainment, false, false);
    }

    protected void assertDetached(DataObject dataobject, ChangeSummary changeSummary, boolean nullContainment, boolean isReAttached) {
        assertDetached(dataobject, changeSummary, nullContainment, isReAttached, false);
    }

    // isReAttached means that the property was detached and then (re)set - no
    // deletedSet entry but oldSettings remain
    protected void assertDetached(DataObject dataobject, ChangeSummary changeSummary, boolean nullContainment, boolean isReAttached, boolean testLoadSave) {
        assertFalse(changeSummary.isCreated(dataobject));
        assertFalse(changeSummary.isModified(dataobject));
        if (!isReAttached) {
            assertTrue(changeSummary.isDeleted(dataobject));
        } else {
            assertFalse(changeSummary.isDeleted(dataobject));
        }

        int propertySize = dataobject.getType().getProperties().size();
        int oldValuesSize = changeSummary.getOldValues(dataobject).size();

        assertEquals(propertySize, oldValuesSize);

        // for objects that were detached and then (re)set - their container and
        // cs will not be null but they will have oldSettings/deletedList items
        if (nullContainment) {
            assertNull(dataobject.getContainer());
            // verify that the cs is not set on deleted/detached objects
            assertNull(dataobject.getChangeSummary());
        }
    }

    protected void assertUnchanged(DataObject dataobject, ChangeSummary changeSummary) {
        assertFalse(changeSummary.isCreated(dataobject));
        assertFalse(changeSummary.isModified(dataobject));
        assertFalse(changeSummary.isDeleted(dataobject));

        assertEquals(0, changeSummary.getOldValues(dataobject).size());
    }

    // inOrderNodeList, preOrderNodeList, postOrderNodeList
    // function to monitor actual values inside the oldSetting HashMap
    protected void checkOldSettingsValues(String values, SDOChangeSummary aCS, List dataObjectList) {
        SDODataObject aDataObject = null;
        for (int i = 0; i < dataObjectList.size(); i++) {
            aDataObject = (SDODataObject) dataObjectList.get(i);
            assertEquals(Integer.parseInt(values.substring(i, i + 1)), aCS.getOldValues(aDataObject).size());
        }
    }

    protected void checkOldContainers(SDOChangeSummary aCS,//
    List dataObjectChildList, List dataObjectContainerList) {// we need
                                                                // generics here
        SDODataObject aChildDataObject = null;
        SDODataObject aContainerDataObject = null;
        for (int i = 0; i < dataObjectChildList.size(); i++) {
            aChildDataObject = (SDODataObject) dataObjectChildList.get(i);
            aContainerDataObject = (SDODataObject) dataObjectContainerList.get(i);
            assertEquals(aChildDataObject, aCS.getOldContainer(aContainerDataObject));
        }
    }

    /*
     * ChangeSummary specific functions for undoChanges
     */
    /**
     *
     */
    public void assertChangeSummaryStatusIfClearedIfCSIsAncestor(DataObject currentDO, boolean isCSonAncestor) {
        if (currentDO != null) {
            // check current DO
            if (isCSonAncestor) {
                assertNull(((SDODataObject) currentDO).getChangeSummary());
            } else {
                assertNotNull(((SDODataObject) currentDO).getChangeSummary());
            }
            // check DO's recursively
            List instanceProperties = currentDO.getInstanceProperties();
            for (int i = 0; i < instanceProperties.size(); i++) {
                SDOProperty nextProperty = (SDOProperty) instanceProperties.get(i);
                Object value = currentDO.get(nextProperty);

                if (!nextProperty.getType().isChangeSummaryType() && !nextProperty.getType().isDataType() && value != null) {
                    if (nextProperty.isMany()) {
                        // iterate list
                        Object manyItem;

                        // use of delete while using an iterator will generate a
                        // ConcurrentModificationException
                        for (int index = 0; index < ((List) value).size(); index++) {
                            manyItem = ((List) value).get(index);
                            if (manyItem != null) {
                                assertChangeSummaryStatusIfClearedIfCSIsAncestor((SDODataObject) manyItem, isCSonAncestor);
                            }
                        }
                    } else {
                        assertChangeSummaryStatusIfClearedIfCSIsAncestor((SDODataObject) value, isCSonAncestor);
                    }
                }
            }
        }
    }

    /**
     *
     */
    protected void assertUndoChangesEqualToOriginal(ChangeSummary aChangeSummary,//
    DataObject undoneDO, DataObject originalDO) {
        // get logging flag before
        boolean loggingStateBefore = aChangeSummary.isLogging();
        aChangeSummary.undoChanges();
        assertTrue(loggingStateBefore == aChangeSummary.isLogging());

        // verify that the model has been returned to its original base state
        assertTrue(equalityHelper.equal(undoneDO, originalDO));
        // the objects are deep copies of each other but not the actual same
        // purchase order
        assertFalse(undoneDO == originalDO);
        // verify that CS is cleared but logging is unchanged
        assertTrue(aChangeSummary.getChangedDataObjects().size() == 0);
        assertTrue(aChangeSummary.getOldValues(undoneDO).size() == 0);
        assertTrue(aChangeSummary.getOldValues(originalDO).size() == 0);
    }

    /**
     *
     */
    // test undo when logging is off (with previous changes)
    protected void assertValueStoresInitializedAfterLoggingOn(DataObject aRootObject) {
        // verify logging is on
        assertTrue(aRootObject.getChangeSummary().isLogging());
        // verify original VS is null and save a copy of current VS for object
        // identity testing after undo
        ValueStore aCurrentValueStore = ((SDODataObject) aRootObject)._getCurrentValueStore();
        assertNotNull(aCurrentValueStore);
        ValueStore anOriginalValueStore = (ValueStore) ((SDOChangeSummary) aRootObject.getChangeSummary()).getOriginalValueStores().get(aRootObject);
        assertNull(anOriginalValueStore);
    }

    /**
     *
     */
    protected void assertValueStoresCopiedAndSwappedAfterFirstModifyOperation(DataObject aRootObject, ValueStore aCurrentValueStoreAfterLoggingFirstOnParam) {
        // verify logging is on
        assertTrue(aRootObject.getChangeSummary().isLogging());
        assertNotNull(aCurrentValueStoreAfterLoggingFirstOnParam);
        ValueStore anOriginalValueStoreAfterOperation = (ValueStore) ((SDOChangeSummary) aRootObject.getChangeSummary()).getOriginalValueStores().get(aRootObject);
        ValueStore aCurrentValueStoreAfterOperation = ((SDODataObject) aRootObject)._getCurrentValueStore();
        assertNotNull(anOriginalValueStoreAfterOperation);
        assertNotNull(aCurrentValueStoreAfterOperation);
        assertTrue(anOriginalValueStoreAfterOperation == aCurrentValueStoreAfterLoggingFirstOnParam);
    }

    protected void assertSequencesCopiedAndSwappedAfterFirstModifyOperation(DataObject aRootObject, Sequence aCurrentSequenceAfterLoggingFirstOnParam) {
        // verify logging is on
        assertTrue(aRootObject.getChangeSummary().isLogging());
        assertNotNull(aCurrentSequenceAfterLoggingFirstOnParam);
        Sequence anOriginalSequenceAfterOperation = (Sequence) ((SDOChangeSummary) aRootObject.getChangeSummary()).getOriginalSequences().get(aRootObject);
        Sequence aCurrentSequenceAfterOperation = ((SDODataObject) aRootObject).getSequence();
        assertNotNull(anOriginalSequenceAfterOperation);
        assertNotNull(aCurrentSequenceAfterOperation);
        assertTrue(anOriginalSequenceAfterOperation == aCurrentSequenceAfterLoggingFirstOnParam);
    }

    /**
     *
     */
    protected void assertValueStoresReturnedToStartStateAfterUndoChanges(DataObject aRootObject, ValueStore aCurrentValueStoreAfterLoggingFirstOnParam) {
        // verify logging is on
        assertTrue(aRootObject.getChangeSummary().isLogging());
        ValueStore anOriginalValueStoreAfterUndo = (ValueStore) ((SDOChangeSummary) aRootObject.getChangeSummary()).getOriginalValueStores().get(aRootObject);
        ValueStore aCurrentValueStoreAfterUndo = ((SDODataObject) aRootObject)._getCurrentValueStore();
        assertNull(anOriginalValueStoreAfterUndo);
        assertNotNull(aCurrentValueStoreAfterUndo);
        // we return the original value store back to the current VS
        assertTrue(aCurrentValueStoreAfterUndo == aCurrentValueStoreAfterLoggingFirstOnParam);
    }

    /**
     *
     */
    protected void assertSequencesReturnedToStartStateAfterUndoChanges(DataObject aRootObject, Sequence aCurrentSequenceAfterLoggingFirstOnParam) {
        // verify logging is on
        assertTrue(aRootObject.getChangeSummary().isLogging());
        SDOSequence anOriginalSequenceAfterUndo = (SDOSequence) ((SDOChangeSummary) aRootObject.getChangeSummary()).getOriginalSequences().get(aRootObject);
        SDOSequence aCurrentSequenceAfterUndo = ((SDODataObject) aRootObject).getSequence();
        assertNull(anOriginalSequenceAfterUndo);
        assertNotNull(aCurrentSequenceAfterUndo);
        // we return the sequence back to the current VS
        assertEquals(aCurrentSequenceAfterUndo.size(), aCurrentSequenceAfterLoggingFirstOnParam.size());
        assertTrue(compareSequences(aCurrentSequenceAfterUndo, (SDOSequence) aCurrentSequenceAfterLoggingFirstOnParam, true));
    }

    /**
     * INTERNAL: Return whether the 2 sequences are equal. Element properties
     * and unstructured text will be compared - attributes are out of scope.
     * <p>
     * For shallow equal - only dataType=true objects are compared, DataObject
     * values are ignored but should be defaults. Note: A setting object should
     * handle its own isEqual() behavior
     *
     */
    public boolean compareSequences(SDOSequence aSequence, SDOSequence aSequenceCopy, boolean isDeep) {
        // corner case: isSequenced set to true after type definition had not
        // sequence
        if (null == aSequence && null == aSequenceCopy) {
            return true;
        }
        // both sequences must be null
        if (null == aSequence || null == aSequenceCopy) {
            return false;
        }
        // for shallow equal - match whether we skipped creating settings or set
        // value=null for shallow copies
        if (aSequence.size() != aSequenceCopy.size()) {
            return false;
        }

        // the settings inside the sequence must be new objects
        SDOSetting originalSetting = null;
        SDOSetting copySetting = null;
        List<? super Setting> originalSettingsList = aSequence.getSettings();
        List<? super Setting> copySettingsList = aSequenceCopy.getSettings();
        if (null == originalSettingsList || null == copySettingsList) {
            return false;
        }

        Property originalProperty = null;
        Property copyProperty = null;
        /**
         * For shallow equal when dataType is false we do not check this
         * setting, the value will be unset (default value) in the shallow copy.
         * orig v1=String v2=DataObject v3=String shallowcopy v1=String
         * v2=null(default) v3=String deepcopy v1=String v2=DataObject v3=String
         */
        for (int index = 0, size = aSequence.size(); index < size; index++) {
            originalSetting = (SDOSetting) originalSettingsList.get(index);
            copySetting = (SDOSetting) copySettingsList.get(index);

            originalProperty = originalSetting.getProperty();
            copyProperty = copySetting.getProperty();

            // we must handle null properties that represent unstructured text
            // both null = unstructured
            // one null = invalid state (return not equal)
            // both !null = valid state (check equality)
            if ((null == originalProperty && null != copyProperty) || (null != originalProperty && null == copyProperty)) {
                return false;
            }

            // the property field on the setting must point to the same property
            // instance as the original
            // handle both properties == null
            if (originalProperty != copyProperty) {
                return false;
            }

            Object originalValue = originalSetting.getValue();
            Object copyValue = copySetting.getValue();

            // for unstructuredText (null property) and simple dataTypes we
            // check equality directly
            if (null == originalProperty || originalProperty.getType().isDataType()) {
                // if one of the values is null return false
                if (((null == originalValue) && (null != copyValue)) || //
                ((null != originalValue) && (null == copyValue))) {
                    return false;
                }
                // if both values are null - they are equal
                // we can also use !.equals
                if ((null != originalValue) && !originalValue.equals(copyValue)) {
                    return false;
                }
            } else {
                // For complex types
                // we do not need to check deep equality on dataObjects twice
                // here, just check instances
                // because the dataObject compare will iterate all the
                // properties of each dataObject
                // only compare DataObjects when in a deep equal
                if (isDeep) {
                    if (null != originalValue && null != copyValue) {
                        // setting.isSet is ignored for sequences
                        // perform a deep equal on the single item
                        // the values may not match their types - return false
                        // instead of a CCE
                        if (originalValue instanceof DataObject && copyValue instanceof DataObject) {
                            if (!equalityHelper.equal((DataObject) originalValue, (DataObject) copyValue)) {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    } else {
                        // both values must be null to be equal
                        if ((null == originalValue && null != copyValue) || (null == copyValue && null != originalValue)) {
                            return false;
                        }
                    }
                } else {
                    /**
                     * For DataObjects in general anything that is deep equal is
                     * also shallow equal - but not the reverse. In the case of
                     * shallow equal on sequences. We can ignore the state of
                     * the 2 complex objects. UC1: if aSequenceCopy setting was
                     * from a shallowCopy then it will be unset. UC2: if
                     * aSequenceCopy setting was from a deepCopy or a reversed
                     * argument shallowCopy then it may be unset or set. We will
                     * not check for a default value on either sequence setting.
                     */
                }
            }
        }
        return true;
    }

    /**
     * Remove CR\LF=13\10 from source and target strings so that we can run the
     * suite on windows without assertEquals() failing. Use the system property
     * -DignoreCRLF=true
     *
     * @param removeCRLF
     *            void
     *
     */
    protected DataObject addProperty(DataObject parentType, String name, Type propType) {
        DataObject newProperty = parentType.createDataObject("property");
        SDOProperty prop = (SDOProperty) newProperty.getType().getProperty("name");
        newProperty.set(prop, name);
        prop = (SDOProperty) newProperty.getType().getProperty("type");
        newProperty.set(prop, propType);
        return newProperty;
    }

    /**
     *
     */
    protected DataObject addProperty(DataObject parentType, String name, Type propType, boolean isContainment) {
        DataObject newProperty = addProperty(parentType, name, propType);
        newProperty.setBoolean(CONTAINMENT, isContainment);
        return newProperty;
    }

    /**
     *
     */
    protected DataObject addProperty(DataObject parentType, String name, Type propType, boolean isContainment, boolean isMany) {
        DataObject newProperty = addProperty(parentType, name, propType, isContainment);
        newProperty.setBoolean(SDOXML_MANY, isMany);
        return newProperty;
    }

    protected DataObject addProperty(DataObject parentType, String name, Type propType, boolean isContainment, boolean isMany, boolean isElement) {
        DataObject newProperty = addProperty(parentType, name, propType, isContainment, isMany);
        if (isElement) {
            newProperty.set(XMLELEMENT_PROPERTY, true);

        }
        return newProperty;
    }

    protected DataObject addProperty(DataObject parentType, String name, DataObject propTypeDO, boolean isContainment, boolean isMany, boolean isElement) {
        DataObject newProperty = parentType.createDataObject("property");
        SDOProperty prop = (SDOProperty) newProperty.getType().getProperty("name");
        newProperty.set(prop, name);
        prop = (SDOProperty) newProperty.getType().getProperty("type");
        newProperty.set(prop, propTypeDO);

        newProperty.setBoolean(CONTAINMENT, isContainment);
        if (isElement) {
            newProperty.set(XMLELEMENT_PROPERTY, true);

        }
        return newProperty;
    }

    /**
     * Set the oc prop containing the idProp property - for unidirectional/bidirectional relationships
     */
    public void setIDPropForReferenceProperties(DataObject doType, Object idProp) {
        // get the global property referencing the idProp property
        doType.set(ID_PROPERTY, idProp);
    }

    /**
     * INTERNAL:
     * Get the reference ID open content Property if it exists for this Type.
     * @return id Property or null
     */
    public SDOProperty getIDProp(Type aType) {
           return (SDOProperty)aType.getProperty((String)aType.get(SDOConstants.ID_PROPERTY));
    }

    /**
     *
     */
    protected DataObject defineType(String uri, String name) {
        DataObject newType = aHelperContext.getDataFactory().create(SDO_URL, TYPE);
        newType.set("uri", uri);
        newType.set("name", name);
        return newType;
    }

    public HelperContext getHelperContext() {
        return aHelperContext;
    }

    public void setHelperContext(HelperContext helperContext) {
        aHelperContext = helperContext;
    }

    protected void assertEqualsBytes(byte[] controlBytes, byte[] bytes) {
        if (controlBytes.length != bytes.length) {
            fail("Expected:" + log(controlBytes) + " but was:" + log(bytes));
        }

        for (int i = 0; i < controlBytes.length; i++) {
            if (controlBytes[i] != bytes[i]) {
                fail("Expected:" + log(controlBytes) + " but was:" + log(bytes));
            }
        }
    }

    protected String log(byte[] bytes) {
        String s = new String();
        for (int i = 0; i < bytes.length; i++) {
            s += bytes[i];
        }
        return s;
    }

    protected Document getDocument(String fileName) {
        InputStream inputStream = null;
        try{
          inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
          return getDocument(inputStream);
          } catch (Exception e) {
            e.printStackTrace();
            fail("An error occurred loading the control document:" + fileName);
            return null;
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

    }

     protected Document getDocument(InputStream inputStream) {
        try {

            Document document = parser.parse(inputStream);
            inputStream.close();
            return document;
        } catch (Exception e) {
            e.printStackTrace();
            fail("An error occurred loading the control document:"); // + inputStream.);
            return null;
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    public void assertStringsEqual(String controlString, String generatedString) {
        String controlString2 = removeCRLFfromString(controlString);
        String generatedString2 = removeCRLFfromString(generatedString);
        // Allow Windows generated java code to pass comparison as well as Linux generated ones
//        if (ignoreCRLF) {
            assertEquals(controlString2, generatedString2);
//        } else {
//            assertEquals(controlString, generatedString);
//        }
    }

    protected void removeEmptyTextNodes(Node node) {
        NodeList nodeList = node.getChildNodes();
        Node childNode;
        for (int x = nodeList.getLength() - 1; x >= 0; x--) {
            childNode = nodeList.item(x);
            if (childNode.getNodeType() == Node.TEXT_NODE) {
                if (childNode.getNodeValue().trim().equals("")) {
                    node.removeChild(childNode);
                }
            } else if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                removeEmptyTextNodes(childNode);
            }
        }
    }

    public static void removeCopyrightNode(Node node) {
        NodeList nodeList = node.getChildNodes();
        Node childNode;
        for (int x = 0; x < nodeList.getLength(); x++) {
            childNode = nodeList.item(x);
            if (childNode.getNodeType() == Node.COMMENT_NODE) {
                if (childNode.getNodeValue().trim().contains("Copyright")) {
                    node.removeChild(childNode);
                    break;
                }
            }
        }
    }

    protected String removeWhiteSpaceFromString(String s) {
        String returnString = s.replaceAll(" ", "");
        returnString = returnString.replaceAll("\n", "");
        returnString = returnString.replaceAll("\t", "");
        returnString = returnString.replaceAll("\r", "");

        return returnString;
    }

    protected String removeCRLFfromString(String s) {
        String returnString = s.replaceAll("\n", "");
        returnString = returnString.replaceAll("\t", "");
        returnString = returnString.replaceAll("\r", "");
        return returnString;
    }

    public static String removeCopyrightFromString(String s) {
        return s.replaceAll("<!--.*Copyright.*?-->", "").replaceAll("(?s)/\\*.*Copyright.*?\\*/", "");
    }

    /**
     * Write to the output stream and return a success flag if no exceptions
     * thrown
     *
     * @return success flag
     */
    public boolean writeXML(DataObject anObject, String uri, String typename, OutputStream aStream) {
        boolean success = true;
        // verify save
        if (useLogging) {
            try {
                xmlHelper.save(anObject, uri, typename, aStream);
            } catch (Exception e) {
                System.out.println("Exception: " + e.getMessage());
                e.printStackTrace();
                success = false;
            }
        }
        return success;
    }

    public DataObject loadXML(String filename, boolean resetChangeSummary) {
        DataObject anObject = null;
        try {
            XMLDocument document = xmlHelper.load(new FileInputStream(filename));
            anObject = document.getRootObject();
            // leave the cs alone?
            if (resetChangeSummary) {
                ChangeSummary aCS = anObject.getChangeSummary();
                if (aCS != null) {
                    aCS.endLogging();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail("_Error: SDOTestSuite.loadXML(): An error occurred loading the xml file " + filename);
        }
        return anObject;
    }

     protected void emptyAndDeleteDirectory(File f) {
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (int i = 0; i < files.length; i++) {
                File next = files[i];
                if (next.isDirectory()) {
                    emptyAndDeleteDirectory(next);
                } else {
                    next.delete();
                }
            }
            f.delete();
        }
    }

     protected void deleteDirsOnExit(File f) {
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (int i = 0; i < files.length; i++) {
                File next = files[i];
                if (next.isDirectory()) {
                    deleteDirsOnExit(next);
                } else {
                    next.deleteOnExit();
                }
            }
            f.deleteOnExit();
        }
    }

    protected String getClassPathForCompile(){
        return classgenCompilePath;
    }

}
