/******************************************************************************* * Copyright (c) 2010-2014 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation *******************************************************************************/ package org.eclipse.skalli.core.persistence; import static org.eclipse.skalli.testutil.StorageKey.keyOf; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.*; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import javax.xml.bind.DatatypeConverter; import org.apache.commons.lang.StringUtils; import org.easymock.EasyMock; import org.eclipse.skalli.commons.CollectionUtils; import org.eclipse.skalli.commons.UUIDListConverter; import org.eclipse.skalli.commons.XMLUtils; import org.eclipse.skalli.core.xstream.ExtensionsMapConverter; import org.eclipse.skalli.core.xstream.NoopConverter; import org.eclipse.skalli.model.EntityBase; import org.eclipse.skalli.services.extension.DataMigration; import org.eclipse.skalli.testutil.HashMapStorageService; import org.eclipse.skalli.testutil.StorageKey; import org.eclipse.skalli.testutil.TestExtensibleEntityBase; import org.eclipse.skalli.testutil.TestExtensibleEntityEntityService; import org.eclipse.skalli.testutil.TestExtension; import org.eclipse.skalli.testutil.TestExtension1; import org.eclipse.skalli.testutil.TestUUIDs; import org.junit.Test; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.thoughtworks.xstream.converters.Converter; @SuppressWarnings("nls") public class XStreamPersistenceTest { private static final int CURRENT_MODEL_VERSION = 43; private static final String ALIAS_EXT1 = "ext1"; private static final String ALIAS_EXT2 = "ext2"; private static final String TIME0 = "2002-12-05T05:22:11Z"; private static final String UPDATED_TIME0 = ">" + TIME0; private static final String TIME1 = "2011-02-25T14:33:48"; private static final String TIME2 = "2010-06-17T21:00:23Z"; private static final String USER0 = "hugo"; private static final String USER1 = "homer"; private static final String USER2 = "marge"; private static final String PERSIST_USER = "skalli"; private static final String ANY_XSD_TIME = "ANY_XSD_TIME"; private static final String VALUE1 = "string"; private static final String VALUE2 = "another_string"; private static final String MODIFIED_VALUE = "modified_string"; private static final String[] ALIASES = { ALIAS_EXT1, ALIAS_EXT2 }; private static final String[] VALUES = { VALUE1, VALUE2 }; private static final String[] LAST_MODIFIED = { TIME1, TIME2 }; private static final String[] LAST_MODIFIED_BY = { USER1, USER2 }; private static final String TEXT1 = "XStreamPersistenceTest greets the world!"; private static final String XML_WITH_VERSION = "<bla version=\"42\"><uuid>" + TestUUIDs.TEST_UUIDS[0] + "</uuid><hello>world</hello><blubb>noop</blubb></bla>"; private static final String XML_WITHOUT_VERSION = "<bla><uuid>" + TestUUIDs.TEST_UUIDS[0] + "</uuid><hello>world</hello><blubb>noop</blubb></bla>"; private static final String XML_WITH_EXTENSIONS = createXML(TIME0, USER0, ALIASES, VALUES, LAST_MODIFIED, LAST_MODIFIED_BY); // XStreamPersistence instance under test backed by a HashMap-based storage service private static class TestXStreamPersistence extends XStreamPersistence { public TestXStreamPersistence() { super(new HashMapStorageService()); } private static StorageKey getStorageKey(TestExtensibleEntityBase entity) { return keyOf(TestExtensibleEntityBase.class.getSimpleName(), entity.getUuid().toString()); } private byte[] getContentFromHashMap(TestExtensibleEntityBase entityKey) { return ((HashMapStorageService) storageService).asMap().get(getStorageKey(entityKey)); } private Document getDocumentFromHashMap(TestExtensibleEntityBase entityKey) throws Exception { return XMLUtils.documentFromString(new String(getContentFromHashMap(entityKey), "UTF-8")); } } @Test public void testSaveLoadCycle() throws Exception { TestExtensibleEntityBase entity = getExtensibleEntity(); TestExtensibleEntityEntityService entityService = new TestExtensibleEntityEntityService(CURRENT_MODEL_VERSION); TestExtension ext1 = entity.getExtension(TestExtension.class); ext1.setStr(TEXT1); ext1.setBool(false); Map<String, Class<?>> aliases = getAliases(); Set<Converter> converters = getConverters(); TestXStreamPersistence xp = new TestXStreamPersistence(); //saveEntity Calendar beforeSaveDate = Calendar.getInstance(); xp.saveEntity(entityService, entity, USER0, aliases, converters); Calendar afterSaveDate = Calendar.getInstance(); //test that entity is now in the HashMap available and lastModified is set. Document savedHashMapDoc = xp.getDocumentFromHashMap(entity); String lastModified = xp.getLastModifiedAttribute(savedHashMapDoc.getDocumentElement()); assertNotNull(lastModified); assertIsXsdDateTime(lastModified); Calendar lastModifiedDate = DatatypeConverter.parseDateTime(lastModified); assertTrue(beforeSaveDate.compareTo(lastModifiedDate) <= 0); assertTrue(lastModifiedDate.compareTo(afterSaveDate) <= 0); //test that lastModifiedDate is set for extensions as well SortedMap<String, Element> extensions = xp.getExtensionsByAlias(savedHashMapDoc, aliases); assertEquals(2, extensions.size()); String lastModifiedExt1 = xp.getLastModifiedAttribute(extensions.get(ALIAS_EXT1)); assertIsXsdDateTime(lastModifiedExt1); String lastModifiedExt2 = xp.getLastModifiedAttribute(extensions.get(ALIAS_EXT1)); assertIsXsdDateTime(lastModifiedExt2); //loadEntity again Set<ClassLoader> entityClassLoaders = getTestExtensibleEntityBaseClassLodades(); TestExtensibleEntityBase loadedEntity = xp.loadEntity(entityService, entity.getUuid().toString(), entityClassLoaders, null, aliases, converters); assertLoadedEntityIsExpectedOne(loadedEntity, USER0, USER0, USER0, lastModified, lastModifiedExt1, lastModifiedExt2, TEXT1, false); // and check that loadEntities can read it List<? extends TestExtensibleEntityBase> loadedEntities = xp.loadEntities(entityService, entityClassLoaders, null, aliases, converters); assertEquals(1, loadedEntities.size()); assertLoadedEntityIsExpectedOne(loadedEntities.get(0), USER0, USER0, USER0, lastModified, lastModifiedExt1, lastModifiedExt2, TEXT1, false); //change the entity and save again ext1 = entity.getExtension(TestExtension.class); ext1.setStr(TEXT1 + " is now updated"); xp.saveEntity(entityService, entity, USER1, aliases, converters); TestExtensibleEntityBase updatedEntity = xp.loadEntity(entityService, entity.getUuid().toString(), entityClassLoaders, null, aliases, converters); Document updatedHashMapDoc = xp.getDocumentFromHashMap(entity); lastModified = xp.getLastModifiedAttribute(updatedHashMapDoc.getDocumentElement()); SortedMap<String, Element> updatedExtensions = xp.getExtensionsByAlias(updatedHashMapDoc, aliases); lastModifiedExt1 = xp.getLastModifiedAttribute(updatedExtensions.get(ALIAS_EXT1)); assertLoadedEntityIsExpectedOne(updatedEntity, USER1, USER1, USER0, lastModified, lastModifiedExt1, lastModifiedExt2, TEXT1 + " is now updated", false); } @Test public void testPreProcessXML() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); DataMigration mockMigration = getMigrationMock(); EasyMock.replay(mockMigration); Document doc = XMLUtils.documentFromString(XML_WITH_VERSION); xp.preProcessXML(doc, Collections.singleton(mockMigration), null, CURRENT_MODEL_VERSION); String res = XMLUtils.documentToString(doc); // TODO: Insnt there something wrong here? // isn't the expect version CURRENT_XSTREAM_PERSISTENCE_VERSION instead of the one out of the XML_WITH_VERSION=42 String expected = "version=\"" + 42 + "\""; assertTrue(res.contains(expected)); EasyMock.verify(mockMigration); } @Test public void testPostProcessEntity() throws Exception { Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); Map<String, Class<?>> aliases = getAliases(); TestExtensibleEntityBase entity = getExtensibleEntity(); XStreamPersistence xp = new TestXStreamPersistence(); xp.postProcessEntity(doc, entity, aliases); assertEquals(TIME0, entity.getLastModified()); assertEquals(USER0, entity.getLastModifiedBy()); TestExtension ext1 = entity.getExtension(TestExtension.class); assertNotNull(ext1); assertEquals(TIME1, ext1.getLastModified()); assertEquals(USER1, ext1.getLastModifiedBy()); TestExtension ext2 = entity.getExtension(TestExtension1.class); assertNotNull(ext2); assertEquals(TIME2, ext2.getLastModified()); assertEquals(USER2, ext2.getLastModifiedBy()); } @Test public void testPostProcessXMLUnmodifiedDocument() throws Exception { Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, USER0, ALIASES, LAST_MODIFIED, LAST_MODIFIED_BY); // test initialization of missing lastModified and lastModifiedBy attributes doc = XMLUtils.documentFromString(createXML(null, null, ALIASES, VALUES, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(doc, doc, PERSIST_USER, ANY_XSD_TIME, PERSIST_USER, ALIASES, new String[] { ANY_XSD_TIME, ANY_XSD_TIME }, new String[] { PERSIST_USER, PERSIST_USER }); // test initialization of missing lastModified attributes doc = XMLUtils.documentFromString(createXML(TIME0, USER0, ALIASES, VALUES, new String[] { null, null }, LAST_MODIFIED_BY)); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, USER0, ALIASES, new String[] { ANY_XSD_TIME, ANY_XSD_TIME }, LAST_MODIFIED_BY); doc = XMLUtils.documentFromString(createXML(null, USER0, ALIASES, VALUES, new String[] { TIME1, null }, LAST_MODIFIED_BY)); assertPostProcessedXML(doc, doc, PERSIST_USER, ANY_XSD_TIME, USER0, ALIASES, new String[] { TIME1, ANY_XSD_TIME }, LAST_MODIFIED_BY); doc = XMLUtils.documentFromString(createXML(null, USER0, ALIASES, VALUES, new String[] { null, TIME2 }, LAST_MODIFIED_BY)); assertPostProcessedXML(doc, doc, PERSIST_USER, ANY_XSD_TIME, USER0, ALIASES, new String[] { ANY_XSD_TIME, TIME2 }, LAST_MODIFIED_BY); // test initialization of missing lastModifiedBy attributes doc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, VALUES, LAST_MODIFIED, new String[] { null, null })); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, PERSIST_USER, ALIASES, LAST_MODIFIED, new String[] { PERSIST_USER, PERSIST_USER }); doc = XMLUtils.documentFromString(createXML(TIME0, USER1, ALIASES, VALUES, LAST_MODIFIED, new String[] { null, null })); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, USER1, ALIASES, LAST_MODIFIED, new String[] { PERSIST_USER, PERSIST_USER }); doc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, VALUES, LAST_MODIFIED, new String[] { USER1, null })); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, PERSIST_USER, ALIASES, LAST_MODIFIED, new String[] { USER1, PERSIST_USER }); doc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, VALUES, LAST_MODIFIED, new String[] { null, USER1 })); assertPostProcessedXML(doc, doc, PERSIST_USER, TIME0, PERSIST_USER, ALIASES, LAST_MODIFIED, new String[] { PERSIST_USER, USER1 }); } @Test public void testPostProcessXMLModifiedExtension() throws Exception { Document oldDoc = XMLUtils.documentFromString(createXML(TIME0, USER0, ALIASES, new String[] { VALUE1, VALUE2 }, LAST_MODIFIED, LAST_MODIFIED_BY)); Document newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, TIME2 }, new String[] { PERSIST_USER, USER2 }); // test initialization of missing lastModified and lastModifiedBy attributes oldDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { VALUE1, VALUE2 }, new String[] { null, null }, new String[] { null, null })); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, ANY_XSD_TIME, PERSIST_USER, ALIASES, new String[] { ANY_XSD_TIME, ANY_XSD_TIME }, new String[] { PERSIST_USER, PERSIST_USER }); // test initialization of missing lastModified attributes oldDoc = XMLUtils.documentFromString(createXML(TIME0, USER0, ALIASES, new String[] { VALUE1, VALUE2 }, new String[] { null, null }, LAST_MODIFIED_BY)); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, ANY_XSD_TIME }, new String[] { PERSIST_USER, USER2 }); oldDoc = XMLUtils.documentFromString(createXML(null, USER0, ALIASES, new String[] { VALUE1, VALUE2 }, new String[] { TIME0, null }, LAST_MODIFIED_BY)); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, ANY_XSD_TIME }, new String[] { PERSIST_USER, USER2 }); oldDoc = XMLUtils.documentFromString(createXML(null, USER0, ALIASES, new String[] { VALUE1, VALUE2 }, new String[] { null, TIME0 }, LAST_MODIFIED_BY)); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, TIME0 }, new String[] { PERSIST_USER, USER2 }); // test initialization of missing lastModifiedBy attributes oldDoc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, new String[] { VALUE1, VALUE2 }, LAST_MODIFIED, new String[] { null, null })); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, TIME2 }, new String[] { PERSIST_USER, PERSIST_USER }); oldDoc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, new String[] { VALUE1, VALUE2 }, LAST_MODIFIED, new String[] { USER0, null })); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, TIME2 }, new String[] { PERSIST_USER, PERSIST_USER }); oldDoc = XMLUtils.documentFromString(createXML(TIME0, null, ALIASES, new String[] { VALUE1, VALUE2 }, LAST_MODIFIED, new String[] { null, USER0 })); newDoc = XMLUtils.documentFromString(createXML(null, null, ALIASES, new String[] { MODIFIED_VALUE, VALUE2 }, new String[] { null, null }, new String[] { null, null })); assertPostProcessedXML(newDoc, oldDoc, PERSIST_USER, UPDATED_TIME0, PERSIST_USER, ALIASES, new String[] { UPDATED_TIME0, TIME2 }, new String[] { PERSIST_USER, USER0 }); } @Test public void testGetExtensionsByAlias() throws Exception { Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); Map<String, Class<?>> aliases = getAliases(); XStreamPersistence xp = new TestXStreamPersistence(); SortedMap<String, Element> extensions = xp.getExtensionsByAlias(doc, aliases); assertEquals(2, extensions.size()); for (String alias : extensions.keySet()) { assertTrue(aliases.containsKey(alias)); assertEquals(alias, extensions.get(alias).getNodeName()); } //check that the content of ext1 is the expected one assertEquals("string", extensions.get("ext1").getFirstChild().getNodeName()); assertEquals("string", extensions.get("ext1").getFirstChild().getTextContent()); } @Test public void testGetExtensionsByClassName() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); Map<String, Class<?>> aliases = getAliases(); SortedMap<String, Element> extensions = xp.getExtensionsByClassName(doc, aliases); assertEquals(2, extensions.size()); for (String alias : aliases.keySet()) { String className = aliases.get(alias).getName(); assertTrue(extensions.containsKey(className)); assertEquals(alias, extensions.get(className).getNodeName()); } } @Test public void testGetExtensionsNoMatchingAliases() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); Map<String, Class<?>> notMatchingAliases = getNotMatchingAliases(); SortedMap<String, Element> extensions = xp.getExtensionsByAlias(doc, notMatchingAliases); assertNotNull(extensions); assertTrue(extensions.isEmpty()); extensions = xp.getExtensionsByClassName(doc, notMatchingAliases); assertNotNull(extensions); assertTrue(extensions.isEmpty()); } @Test public void testVersionAttribute() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); assertEquals(0, xp.getVersionAttribute(XMLUtils.documentFromString(XML_WITHOUT_VERSION))); assertEquals(42, xp.getVersionAttribute(XMLUtils.documentFromString(XML_WITH_VERSION))); } @Test public void testSetVersionAttribute() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITHOUT_VERSION); xp.setVersionAttribute(doc, CURRENT_MODEL_VERSION); assertEquals(CURRENT_MODEL_VERSION, xp.getVersionAttribute(doc)); } @Test public void testSetLastModifiedAttribute() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Element element = XMLUtils.documentFromString("<dummy></dummy>").getDocumentElement(); xp.setLastModifiedAttribute(element); Attr lastMod = element.getAttributeNode("lastModified"); assertIsXsdDateTime(lastMod.getTextContent()); } @Test public void testCallSetVersionAttributeTwice() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITHOUT_VERSION); xp.setVersionAttribute(doc, CURRENT_MODEL_VERSION); try { xp.setVersionAttribute(doc, CURRENT_MODEL_VERSION); } catch (RuntimeException e) { assertTrue(e.getMessage().contains("element already has a 'version' attribute")); } } @Test public void testLastModified() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITHOUT_VERSION); Element documentElement = doc.getDocumentElement(); xp.setLastModifiedAttribute(documentElement); assertIsXsdDateTime(xp.getLastModifiedAttribute(documentElement)); } @Test public void testLastModifiedBy() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITHOUT_VERSION); Element documentElement = doc.getDocumentElement(); xp.setLastModifiedByAttribute(documentElement, USER0); assertEquals(USER0, xp.getLastModifiedByAttribute(documentElement)); } @Test public void testNonIdenticalElements() throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Document doc = XMLUtils.documentFromString(XML_WITH_EXTENSIONS); Element documentElement = doc.getDocumentElement(); Map<String, Class<?>> aliases = getAliases(); SortedMap<String, Element> extensions = xp.getExtensionsByClassName(doc, aliases); assertTrue(extensions.size() > 0); for (Element element : extensions.values()) { assertFalse(XMLDiff.identical(documentElement, element)); } } @Test public void testIdenticalWithNullParams() throws Exception { Document doc = XMLUtils.documentFromString(XML_WITHOUT_VERSION); Element documentElement = doc.getDocumentElement(); assertTrue(XMLDiff.identical(null, null)); assertFalse(XMLDiff.identical(null, documentElement)); assertFalse(XMLDiff.identical(documentElement, null)); assertTrue(XMLDiff.identical(documentElement, documentElement)); } private void assertPostProcessedXML(Document newDoc, Document oldDoc, String userId, String expectedGlobalLastModified, String expectedGlobalLastModifiedBy, String[] expectedAliases, String[] expectedExtLastModified, String[] expectedExtLastModifiedBy) throws Exception { XStreamPersistence xp = new TestXStreamPersistence(); Map<String, Class<?>> aliases = getAliases(); xp.postProcessXML(newDoc, oldDoc, aliases, userId, CURRENT_MODEL_VERSION); Element documentElement = newDoc.getDocumentElement(); assertLastModifiedTime(expectedGlobalLastModified, xp.getLastModifiedAttribute(documentElement)); assertEquals(expectedGlobalLastModifiedBy, xp.getLastModifiedByAttribute(documentElement)); SortedMap<String, Element> extensions = xp.getExtensionsByAlias(newDoc, aliases); int i = 0; for (Element ext: extensions.values()) { assertEquals(expectedAliases[i], ext.getNodeName()); assertLastModifiedTime(expectedExtLastModified[i], xp.getLastModifiedAttribute(ext)); assertEquals(expectedExtLastModifiedBy[i], xp.getLastModifiedByAttribute(ext)); ++i; } assertEquals(CURRENT_MODEL_VERSION, xp.getVersionAttribute(newDoc)); } private void assertLastModifiedTime(String expected, String actual) { if (ANY_XSD_TIME.equals(expected)) { assertIsXsdDateTime(actual); } else if (expected.startsWith(">")) { assertIsXsdDateTime(actual); long actualMillis = DatatypeConverter.parseDateTime(actual).getTimeInMillis(); long expectedMillis = DatatypeConverter.parseDateTime(expected.substring(1)).getTimeInMillis(); assertTrue(actualMillis > expectedMillis); } else { assertEquals(actual, expected); } } private void assertIsXsdDateTime(String lexicalXSDDateTime) { assertTrue(StringUtils.isNotBlank(lexicalXSDDateTime)); DatatypeConverter.parseDateTime(lexicalXSDDateTime); } //checks that within a range of seconds the dateString matches the expectedDateString private void assertLastModifiedDate(String dateString, String expectedDateString) { assertThat(dateString, startsWith(expectedDateString.substring(0, "YYYY-MM-DDTHH:MM:SS".length()))); } private void assertLoadedEntityIsExpectedOne(TestExtensibleEntityBase loadedEntity, String user, String userExt1, String userExt2, String lastModified, String lastModifiedExt1, String lastModifiedExt2, String ext1Text, boolean ext1boolean) { assertNotNull(loadedEntity); assertLastModifiedDate(loadedEntity.getLastModified(), lastModified); assertEquals(user, loadedEntity.getLastModifiedBy()); TestExtension ext1 = ((TestExtensibleEntityBase) loadedEntity).getExtension(TestExtension.class); assertNotNull(ext1); assertLastModifiedDate(ext1.getLastModified(), lastModifiedExt1); assertEquals(ext1Text, ext1.getStr()); assertEquals(ext1boolean, ext1.isBool()); assertEquals(userExt1, ext1.getLastModifiedBy()); TestExtension1 ext2 = ((TestExtensibleEntityBase) loadedEntity).getExtension(TestExtension1.class); assertNotNull(ext2); assertLastModifiedDate(ext2.getLastModified(), lastModifiedExt2); } private Map<String, Class<?>> getAliases() { Map<String, Class<?>> aliases = new HashMap<String, Class<?>>(); aliases.put(ALIAS_EXT1, TestExtension.class); aliases.put(ALIAS_EXT2, TestExtension1.class); return aliases; } private <T extends EntityBase> Set<Converter> getConverters() { return CollectionUtils.asSet(new NoopConverter(), new UUIDListConverter(), new ExtensionsMapConverter()); } private Set<ClassLoader> getTestExtensibleEntityBaseClassLodades() { Set<ClassLoader> entityClassLoaders = new HashSet<ClassLoader>(); entityClassLoaders.add(TestExtensibleEntityBase.class.getClassLoader()); entityClassLoaders.add(TestExtension.class.getClassLoader()); entityClassLoaders.add(TestExtension1.class.getClassLoader()); return entityClassLoaders; } private Map<String, Class<?>> getNotMatchingAliases() { Map<String, Class<?>> aliases = new HashMap<String, Class<?>>(); aliases.put("notext1", TestExtension.class); aliases.put("notext2", TestExtension1.class); return aliases; } private TestExtensibleEntityBase getExtensibleEntity() { TestExtensibleEntityBase entity = new TestExtensibleEntityBase(TestUUIDs.TEST_UUIDS[0]); entity.addExtension(new TestExtension()); entity.addExtension(new TestExtension1()); return entity; } private DataMigration getMigrationMock() throws Exception { DataMigration mockMigration = EasyMock.createMock(DataMigration.class); EasyMock.reset(mockMigration); mockMigration.handlesType(EasyMock.isA(String.class)); EasyMock.expectLastCall().andReturn(true).anyTimes(); mockMigration.getFromVersion(); EasyMock.expectLastCall().andReturn(42).anyTimes(); mockMigration.migrate(EasyMock.isA(Document.class)); EasyMock.expectLastCall(); return mockMigration; } private static String createXML(String docLastModified, String docLastModifiedBy, String[] aliases, String[] values, String[] extLastModified, String[] extLastModifiedBy) { StringBuilder sb = new StringBuilder(); sb.append("<root"); appendModifiedAttributes(sb, docLastModified, docLastModifiedBy); sb.append(">"); if (aliases != null) { sb.append("<extensions>"); for (int i = 0; i < aliases.length; ++i) { sb.append("<").append(aliases[i]); appendModifiedAttributes(sb, extLastModified[i], extLastModifiedBy[i]); sb.append(">"); if (values[i] != null) { sb.append("<string>").append(values[i]).append("</string>"); } sb.append("</").append(aliases[i]).append(">"); } sb.append("</extensions>"); } sb.append("</root>"); return sb.toString(); } private static void appendModifiedAttributes(StringBuilder sb, String lastModified, String lastModifiedBy) { if (lastModified != null) { sb.append(" lastModified=\"").append(lastModified).append("\""); } if (lastModifiedBy != null) { sb.append(" modifiedBy=\"").append(lastModifiedBy).append("\""); } } }