package org.concord.otrunk.test2; import java.net.URL; import java.util.Random; import java.util.logging.Logger; import org.concord.framework.otrunk.OTID; import org.concord.framework.otrunk.OTObject; import org.concord.framework.otrunk.OTObjectService; import org.concord.framework.otrunk.OTResourceList; import org.concord.framework.otrunk.OTUser; import org.concord.otrunk.OTObjectServiceImpl; import org.concord.otrunk.OTrunkImpl; import org.concord.otrunk.datamodel.OTDatabase; import org.concord.otrunk.datamodel.OTTransientMapID; import org.concord.otrunk.overlay.CompositeDatabase; import org.concord.otrunk.overlay.OTOverlay; import org.concord.otrunk.overlay.OverlayImpl; import org.concord.otrunk.test.OTBasicTestObject; import org.concord.otrunk.test.OTPrimitivesTestObject; import org.concord.otrunk.test.OTResourceListTestObject; import org.concord.otrunk.view.OTConfig; import org.concord.otrunk.view.OTViewerHelper; import org.concord.otrunk.xml.XMLDatabase; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class OverlayDatabasePruningTest { private static final Logger logger = Logger.getLogger(OverlayDatabasePruningTest.class.getCanonicalName()); private static URL authoredContent = OverlayObjectCopyTest.class.getResource("/overlay-pruning-authored.otml"); private static URL learnerContent = OverlayObjectCopyTest.class.getResource("/overlay-pruning-learner.otml"); private static OTViewerHelper viewerHelper; private static OTDatabase mainDb; private static OTDatabase learnerDb; private static OTrunkImpl otrunk; private static OTObjectServiceImpl overlayObjService; private static OTDatabase overlayDb; private static OverlayImpl overlayImpl; private static OTOverlay overlay; @BeforeClass public static void setup() throws Exception { initOtrunk(); initOverlay(); } @Test public void databasePruning() throws Exception { // load in the first argument as an otml file // assume the root object is a folder, and then // get the first child of the folder and // copy it and store the copy as the second // object in the folder // GET THE OBJECT logger.fine("Getting object"); OTBasicTestObject root = (OTBasicTestObject) viewerHelper.getRootObject(); OTUser user = otrunk.getUsers().get(0); root = (OTBasicTestObject) otrunk.getUserRuntimeObject(root, user); Assert.assertTrue(root.getGlobalId() instanceof OTTransientMapID); // edit the child objects OTResourceListTestObject resourceListObject = root.getOTObjectService().createObject(OTResourceListTestObject.class); root.setReference(resourceListObject); OTResourceList resourceList = resourceListObject.getResourceList(); for (int i = 0; i < 4; i++) { OTPrimitivesTestObject testObj = root.getOTObjectService().createObject(OTPrimitivesTestObject.class); testObj.setString("primary: " + i); resourceList.add(testObj); } copyIntoOverlay(root); // VERIFY THAT NON-DELTA-OBJECTS HAS 5 OBJECTS // there should be one OTResourceListTestObject and 4 OTPrimitivesTestObject OTResourceList nonDeltas = overlay.getNonDeltaObjects(); Assert.assertTrue("There should be 1 non-delta object. There were: " + nonDeltas.size(), nonDeltas.size() == 1); checkCounts(nonDeltas, 1, 0, 0); // edit the child objects resourceList.remove(new Random().nextInt(resourceList.size())); resourceList.remove(new Random().nextInt(resourceList.size())); for (int i = 0; i < 4; i++) { OTPrimitivesTestObject testObj = root.getOTObjectService().createObject(OTPrimitivesTestObject.class); testObj.setString("secondary: " + i); resourceList.add(testObj); } // copy the objects copyIntoOverlay(root); // PRUNE THE OVERLAY logger.fine("Pruning overlay"); overlayImpl.pruneNonDeltaObjects(); // TODO VERIFY THAT NON-DELTA-OBJECTS HAS P OBJECTS nonDeltas = overlay.getNonDeltaObjects(); Assert.assertTrue("There should be 1 non-delta object. There were: " + nonDeltas.size(), nonDeltas.size() == 1); checkCounts(nonDeltas, 1, 0, 0); } private void copyIntoOverlay(OTBasicTestObject root) throws Exception { // get the overlay version of the object OTID id = root.getGlobalId().getMappedId(); OTBasicTestObject overlayVersion = (OTBasicTestObject) overlayObjService.getOTObject(id); // COPY THE OBJECT logger.fine("Copying objects:\n"); logger.fine("Student root: " + root.getGlobalId().getMappedId().toString()); logger.fine("Overlay root: " + overlayVersion.getGlobalId().getMappedId().toString()); ((OTObjectServiceImpl)root.getOTObjectService()).copyInto(root, overlayVersion, -1, true); OTResourceListTestObject overlayResourceList = (OTResourceListTestObject) overlayVersion.getReference(); logger.fine("Overlay resource list id: " + overlayResourceList.getGlobalId().getMappedId()); for (Object obj : overlayResourceList.getResourceList()) { logger.fine("Resource child: " + ((OTObject)obj).getGlobalId().getMappedId()); } } private void checkCounts(OTResourceList nonDeltas, int expectedResourceLists, int expectedPrimitives, int expectedOther) throws Exception { int resourceLists = 0; int primitives = 0; int other = 0; for (Object obj : nonDeltas) { if (obj instanceof OTID) { obj = overlay.getOTObjectService().getOTObject((OTID) obj); } if (obj instanceof OTResourceListTestObject) { resourceLists++; } else if (obj instanceof OTPrimitivesTestObject) { primitives++; } else { other++; } } Assert.assertTrue("Should be " + expectedResourceLists + " resource list non-delta. Were: " + resourceLists, expectedResourceLists == resourceLists); Assert.assertTrue("Should be " + expectedPrimitives + " primitive non-delta. Were: " + primitives, expectedPrimitives == primitives); Assert.assertTrue("Should be " + expectedOther + " other non-delta. Were: " + other, expectedOther == other); } private static void initOtrunk() throws Exception { logger.fine("loading otrunk"); System.setProperty(OTConfig.SINGLE_USER_PROP, "true"); viewerHelper = new OTViewerHelper(); mainDb = viewerHelper.loadOTDatabase(authoredContent); learnerDb = viewerHelper.loadOTDatabase(learnerContent); viewerHelper.loadOTrunk(mainDb, null); viewerHelper.loadUserData(learnerDb, null); otrunk = (OTrunkImpl) viewerHelper.getOtrunk(); } private static void initOverlay() throws Exception { logger.fine("creating default overlay"); overlayDb = new XMLDatabase(); OTObjectService tempObjService = otrunk.createObjectService(overlayDb); overlay = tempObjService.createObject(OTOverlay.class); overlayDb.setRoot(overlay.getGlobalId()); initOverlayObjService(overlay); } private static void initOverlayObjService(OTOverlay overlay) throws Exception { logger.fine("setting up overlay object service"); overlayImpl = new OverlayImpl(overlay); CompositeDatabase db = new CompositeDatabase(otrunk.getDataObjectFinder(), overlayImpl); overlayObjService = otrunk.createObjectService(db); } }