blob: 224337155cbfe4683482545491117495c9374475 [file] [log] [blame]
/*
* 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.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.SDOType;
import org.eclipse.persistence.sdo.ValueStore;
import org.eclipse.persistence.sdo.helper.SDOClassLoader;
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 org.eclipse.persistence.platform.xml.XMLComparer;
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, (Double) aPropertyValue);
} else if (aType.equals(SDO_FLOAT)) {
assertEquals(0, (Float) 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 originalSettingsList = aSequence.getSettings();
List 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;
}
}