/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.tests.api.write.request; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.TreeMap; import org.junit.Assert; import org.junit.Test; import org.simantics.databoard.Databoard; import org.simantics.databoard.annotations.Arguments; import org.simantics.databoard.annotations.Union; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.serialization.Serializer; import org.simantics.db.ChangeSetIdentifier; import org.simantics.db.Metadata; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.service.ManagementSupport; import org.simantics.db.testing.base.ExistingDatabaseTest; /** * @author Tuukka Lehtonen */ public class WriteMetadataTest extends ExistingDatabaseTest { boolean DEBUG = false; @Test public void test() throws Exception{ final Resource root = getSession().getRootLibrary(); Collection ids = getSession().getService(ManagementSupport.class).getChangeSetIdentifiers(Long.MIN_VALUE, Long.MAX_VALUE); if (DEBUG) for (ChangeSetIdentifier id : ids) { System.out.println("CSID: " + id.getId()); System.out.println(" METADATA: " + id.getMetadata()); } getSession().syncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Resource r = graph.newResource(); graph.claim(root, L0.InstanceOf, L0.Library); graph.claim(root, L0.ConsistsOf, r); TreeMap map = new TreeMap(); map.put(r, new StructuralChanges.Change[] { new StructuralChanges.ComponentAddition(r) }); StructuralChanges ch = new StructuralChanges(map); graph.addMetadata(ch); } }); int count = ids.size(); ids = getSession().getService(ManagementSupport.class).getChangeSetIdentifiers(Long.MIN_VALUE, Long.MAX_VALUE); Assert.assertTrue("Metadata not updated.", count < ids.size()); if (DEBUG) for (ChangeSetIdentifier id : ids) { System.out.println("CSID: " + id.getId()); System.out.println(" METADATA: " + id.getMetadata()); } if (DEBUG) { Thread.sleep(5000); ids = getSession().getService(ManagementSupport.class).getChangeSetIdentifiers(Long.MIN_VALUE, Long.MAX_VALUE); for (ChangeSetIdentifier id : ids) { System.out.println("CSID: " + id.getId()); System.out.println(" METADATA: " + id.getMetadata()); } } } } class StructuralChanges implements Metadata { public final @Arguments({Resource.class, Change[].class}) TreeMap modelChanges; public StructuralChanges(TreeMap modelChanges) { this.modelChanges = modelChanges; } public StructuralChanges(Map> _modelChanges) { this(new TreeMap()); for(Map.Entry> entry : _modelChanges.entrySet()) { ArrayList value = entry.getValue(); modelChanges.put(entry.getKey(), value.toArray(new Change[value.size()])); } } public static enum ChangeType { COMPONENT_ADDITION, COMPONENT_REMOVAL, COMPONENT_MODIFICATION, CONNECTION_CHANGE } @Union({ComponentAddition.class, ComponentRemoval.class, ComponentModification.class, ConnectionChange.class}) public static interface Change { ChangeType getType(); } public static class ComponentAddition implements Change { public final Resource component; public ComponentAddition(Resource component) { this.component = component; } @Override public ChangeType getType() { return ChangeType.COMPONENT_ADDITION; } } public static class ComponentRemoval implements Change { public final Resource component; public final Resource parent; public ComponentRemoval(Resource component, Resource parent) { this.component = component; this.parent = parent; } @Override public ChangeType getType() { return ChangeType.COMPONENT_REMOVAL; } } public static class ComponentModification implements Change { public final Resource component; public ComponentModification(Resource component) { this.component = component; } @Override public ChangeType getType() { return ChangeType.COMPONENT_MODIFICATION; } } public static class ConnectionChange implements Change { public final Resource connection; public ConnectionChange(Resource connection) { this.connection = connection; } @Override public ChangeType getType() { return ChangeType.CONNECTION_CHANGE; } } public Change[] get(Resource model) { return modelChanges.get(model); } @Override public byte[] serialise(Session session) { try { Databoard databoard = session.getService( Databoard.class ); Binding binding = databoard.getBinding( StructuralChanges.class ); Serializer serializer = databoard.getSerializer( binding ); return serializer.serialize(this); } catch (Exception e) { e.printStackTrace(); if (e instanceof RuntimeDatabaseException) throw (RuntimeDatabaseException)e; else throw new RuntimeDatabaseException("Serialization failed.", e); } } public static StructuralChanges deserialise(Session session, byte[] input) { try { Databoard databoard = session.getService( Databoard.class ); Binding binding = databoard.getBinding( StructuralChanges.class ); Serializer serializer = databoard.getSerializer( binding ); return (StructuralChanges) serializer.deserialize(input); } catch (Exception e) { e.printStackTrace(); if (e instanceof RuntimeDatabaseException) throw (RuntimeDatabaseException)e; else throw new RuntimeDatabaseException("Deserialization failed.", e); } } }