X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Ffi%2Fvtt%2Fsimantics%2Fprocore%2Finternal%2FUndoRedoSupportImpl.java;h=0f8d9706c6814d089120f71996a5ebcd10fd3b62;hp=a50a6eb3e10b64aebaa66e3099b73adbf54890d1;hb=1dd02a0d0e604a82e67f04559e213db76c9ebac5;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java index a50a6eb3e..0f8d9706c 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java @@ -1,291 +1,293 @@ -package fi.vtt.simantics.procore.internal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; - -import org.simantics.db.Operation; -import org.simantics.db.Session; -import org.simantics.db.SessionVariables; -import org.simantics.db.UndoContext; -import org.simantics.db.WriteGraph; -import org.simantics.db.common.CommentMetadata; -import org.simantics.db.common.CommitMetadata; -import org.simantics.db.common.UndoMetadata; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.impl.graph.WriteGraphImpl; -import org.simantics.db.impl.query.QueryProcessor.SessionTask; -import org.simantics.db.service.ExternalOperation; -import org.simantics.db.service.ManagementSupport; -import org.simantics.db.service.UndoRedoSupport; -import org.simantics.scl.runtime.function.FunctionImpl1; -import org.simantics.utils.DataContainer; - -import fi.vtt.simantics.procore.internal.SessionImplSocket.TaskHelper; - -public class UndoRedoSupportImpl implements UndoRedoSupport { - final private boolean DEBUG = SessionImplSocket.DEBUG; - final private SessionImplSocket session; - final ManagementSupport managementSupport; - - UndoRedoSupportImpl(SessionImplSocket session) { - this.session = session; - this.managementSupport = session.getService(ManagementSupport.class); - } - - @Override - public Operation undo(final Collection ops) throws DatabaseException { - if (null == ops || ops.size() < 1) - throw new IllegalArgumentException("At least one operation must be defined."); - final Operation fop = (Operation)ops.toArray()[0]; - final DataContainer id = new DataContainer(0L); - final TaskHelper th = new TaskHelper("Undo"); - session.requestManager.scheduleWrite(new SessionTask(null, 0) { - @Override - public void run(int thread) { - session.flushCounter = 0; - session.clusterStream.reallyFlush(); - ClientChangesImpl cs = new ClientChangesImpl(session); - if (session.clientChanges == null) - session.clientChanges = cs; - WriteGraphImpl writer = WriteGraphImpl.create(session.getQueryProvider2(), session.writeSupport, null); - session.writeState = new WriteState(writer, th.writeTraits, th.sema, th.proc); - try { - SynchronizeContext context = new SynchronizeContext(session, cs, 1); - boolean potentialConflicts = session.graphSession.undo(ops, context); - if (potentialConflicts) - th.throw_("Server thinks that there might be potential conflicts with this undo operation."); - final boolean undo = true; - if (!context.isOk(undo)) // this is a blocking operation - th.throw_("Trouble with server reply."); - } catch (Throwable e) { - if (DEBUG) - e.printStackTrace(); - th.throwableSet(e); - th.sema.release(); - return; - } - try { - writer.markUndoPoint(); // Undo should form it's own operation. - // Add a comment to metadata. - CommentMetadata cm = writer.getMetadata(CommentMetadata.class); - UndoMetadata um = writer.getMetadata(UndoMetadata.class); - UndoMetadata pum = getComment4Undo(fop.getId()); - if (null != pum) { - writer.addMetadata(um.add(pum)); - um.setTypeAndRange(pum); - } - writer.addMetadata(um.add("Undo operation " + fop.getId() + ".")); - Operation ope = fop; - if (ops.size() > 1) { - writer.addMetadata(um.add("Undo " + ops.size() + " change sets.")); - writer.addMetadata(um.add("First change set was " + fop.getCSId() + ".")); - Operation lop = (Operation)ops.toArray()[ops.size()-1]; - writer.addMetadata(um.add("Last change set was " + lop.getCSId() + ".")); - ope = lop; - } - writer.addMetadata(cm.add(getComment(ope.getId()))); - if (null == pum || pum.getBeginCSId() == 0) { - um.setTypeAndRange(false, ope.getId(), ope.getCSId()); - writer.addMetadata(um); - } - session.getQueryProvider2().performDirtyUpdates(writer); - session.fireMetadataListeners(writer, cs); - session.getQueryProvider2().performScheduledUpdates(writer); - session.fireReactionsToSynchronize(cs); - session.fireSessionVariableChange(SessionVariables.QUEUED_WRITES); - session.printDiagnostics(); - long headChangeSetId = session.state.getHeadRevisionId(); - id.set(headChangeSetId+1); - } catch (Throwable e) { - if (DEBUG) - e.printStackTrace(); - Logger.defaultLogError(e); - th.throwableSet(e); - } - } - }); - session.acquire(th.sema, th.writeTraits); - th.throwableCheck(); - long headChangeSetId = session.state.getHeadRevisionId(); - if (id.get() == headChangeSetId+1) - return null; // Empty undo operation; - - final ArrayList externalRedos = new ArrayList(); - GraphSession.forExternals(ops, new FunctionImpl1() { - - @Override - public Boolean apply(final ExternalOperation op) { - externalRedos.add(new ExternalOperation() { - - @Override - public void undo() { - op.redo(); - } - - @Override - public void redo() { - op.undo(); - } - - @Override - public boolean isDisposed() { - return op.isDisposed(); - } - - }); - return true; - } - - }); - - return new OperationImpl(id.get(), id.get(), externalRedos); - - } - private CommentMetadata getComment(long id) { - Collection metadata; - try { - metadata = managementSupport.getMetadata(id, id, CommentMetadata.class); - if (metadata.size() > 0) - return metadata.iterator().next(); - } catch (Throwable t) { - Logger.defaultLogError(t); - } - return null; - } - private UndoMetadata getComment4Undo(long id) { - Collection metadata; - try { - metadata = managementSupport.getMetadata(id, id, UndoMetadata.class); - if (metadata.size() > 0) - return metadata.iterator().next(); - } catch (Throwable t) { - Logger.defaultLogError(t); - } - return null; - } - @Override - public void undo(Operation op) - throws DatabaseException { - Collection ops = new ArrayList(); - ops.add(op); - undo(ops); - } - - @Override - public Operation getCurrent() { - return session.state.getLastOperation(); - } - - @Override - public int undo(Session session, int count) - throws DatabaseException { - return undoAndReturnOperations(session, count).size(); - } - - @Override - public List undoAndReturnOperations(Session session, int count) - throws DatabaseException { - if ( count < 1) - return Collections.emptyList(); - if (!(session instanceof SessionImplDb)) - return Collections.emptyList(); - SessionImplDb s = (SessionImplDb)session; - return s.graphSession.undoContext.undo(this, count); - } - - @Override - public List redo(Session session, int count) - throws DatabaseException { - if ( count < 1) - return Collections.emptyList(); - if (!(session instanceof SessionImplDb)) - return Collections.emptyList(); - SessionImplDb s = (SessionImplDb)session; - return s.graphSession.undoContext.redo(this, count); - } - - @Override - public int undoTo(Session session, long changeSet) - throws DatabaseException { - if (!(session instanceof SessionImplDb) || changeSet < 1) - return 0; - SessionImplDb s = (SessionImplDb)session; - long head = s.graphSession.getLastChangeSetId(); - int SIZE = (int)(head - changeSet); - if (SIZE < 1) - return 0; - s.graphSession.undoContext.clear(); - Vector ops = new Vector(SIZE); - ops.setSize(SIZE); - long id = changeSet; - for (int i = 0; i metadata = ms.getMetadata(changeSet, head, CommitMetadata.class); - if (metadata.size() != SIZE) - return 0; - s.graphSession.undoContext.clear(); - long first = 0; - Iterator it = metadata.iterator(); - long csid = changeSet; - SIZE += csid; - for (; csid ops) throws DatabaseException { + if (null == ops || ops.size() < 1) + throw new IllegalArgumentException("At least one operation must be defined."); + final Operation fop = (Operation)ops.toArray()[0]; + final DataContainer id = new DataContainer(0L); + final TaskHelper th = new TaskHelper("Undo"); + session.requestManager.scheduleWrite(new SessionTask(null, 0) { + @Override + public void run(int thread) { + session.flushCounter = 0; + session.clusterStream.reallyFlush(); + ClientChangesImpl cs = new ClientChangesImpl(session); + if (session.clientChanges == null) + session.clientChanges = cs; + WriteGraphImpl writer = WriteGraphImpl.create(session.getQueryProvider2(), session.writeSupport, null); + session.writeState = new WriteState(writer, th.writeTraits, th.sema, th.proc); + try { + SynchronizeContext context = new SynchronizeContext(session, cs, 1); + boolean potentialConflicts = session.graphSession.undo(ops, context); + if (potentialConflicts) + th.throw_("Server thinks that there might be potential conflicts with this undo operation."); + final boolean undo = true; + if (!context.isOk(undo)) // this is a blocking operation + th.throw_("Trouble with server reply."); + } catch (Throwable e) { + if (DEBUG) + e.printStackTrace(); + th.throwableSet(e); + th.sema.release(); + return; + } + try { + writer.markUndoPoint(); // Undo should form it's own operation. + // Add a comment to metadata. + CommentMetadata cm = writer.getMetadata(CommentMetadata.class); + UndoMetadata um = writer.getMetadata(UndoMetadata.class); + UndoMetadata pum = getComment4Undo(fop.getId()); + if (null != pum) { + writer.addMetadata(um.add(pum)); + um.setTypeAndRange(pum); + } + writer.addMetadata(um.add("Undo operation " + fop.getId() + ".")); + Operation ope = fop; + if (ops.size() > 1) { + writer.addMetadata(um.add("Undo " + ops.size() + " change sets.")); + writer.addMetadata(um.add("First change set was " + fop.getCSId() + ".")); + Operation lop = (Operation)ops.toArray()[ops.size()-1]; + writer.addMetadata(um.add("Last change set was " + lop.getCSId() + ".")); + ope = lop; + } + writer.addMetadata(cm.add(getComment(ope.getId()))); + if (null == pum || pum.getBeginCSId() == 0) { + um.setTypeAndRange(false, ope.getId(), ope.getCSId()); + writer.addMetadata(um); + } + session.getQueryProvider2().performDirtyUpdates(writer); + session.fireMetadataListeners(writer, cs); + session.getQueryProvider2().performScheduledUpdates(writer); + session.fireReactionsToSynchronize(cs); + session.fireSessionVariableChange(SessionVariables.QUEUED_WRITES); + session.printDiagnostics(); + long headChangeSetId = session.state.getHeadRevisionId(); + id.set(headChangeSetId+1); + } catch (Throwable e) { + if (DEBUG) + e.printStackTrace(); + Logger.defaultLogError(e); + th.throwableSet(e); + } finally { + cs.dispose(); + } + } + }); + session.acquire(th.sema, th.writeTraits); + th.throwableCheck(); + long headChangeSetId = session.state.getHeadRevisionId(); + if (id.get() == headChangeSetId+1) + return null; // Empty undo operation; + + final ArrayList externalRedos = new ArrayList(); + GraphSession.forExternals(ops, new FunctionImpl1() { + + @Override + public Boolean apply(final ExternalOperation op) { + externalRedos.add(new ExternalOperation() { + + @Override + public void undo() { + op.redo(); + } + + @Override + public void redo() { + op.undo(); + } + + @Override + public boolean isDisposed() { + return op.isDisposed(); + } + + }); + return true; + } + + }); + + return new OperationImpl(id.get(), id.get(), externalRedos); + + } + private CommentMetadata getComment(long id) { + Collection metadata; + try { + metadata = managementSupport.getMetadata(id, id, CommentMetadata.class); + if (metadata.size() > 0) + return metadata.iterator().next(); + } catch (Throwable t) { + Logger.defaultLogError(t); + } + return null; + } + private UndoMetadata getComment4Undo(long id) { + Collection metadata; + try { + metadata = managementSupport.getMetadata(id, id, UndoMetadata.class); + if (metadata.size() > 0) + return metadata.iterator().next(); + } catch (Throwable t) { + Logger.defaultLogError(t); + } + return null; + } + @Override + public void undo(Operation op) + throws DatabaseException { + Collection ops = new ArrayList(); + ops.add(op); + undo(ops); + } + + @Override + public Operation getCurrent() { + return session.state.getLastOperation(); + } + + @Override + public int undo(Session session, int count) + throws DatabaseException { + return undoAndReturnOperations(session, count).size(); + } + + @Override + public List undoAndReturnOperations(Session session, int count) + throws DatabaseException { + if ( count < 1) + return Collections.emptyList(); + if (!(session instanceof SessionImplDb)) + return Collections.emptyList(); + SessionImplDb s = (SessionImplDb)session; + return s.graphSession.undoContext.undo(this, count); + } + + @Override + public List redo(Session session, int count) + throws DatabaseException { + if ( count < 1) + return Collections.emptyList(); + if (!(session instanceof SessionImplDb)) + return Collections.emptyList(); + SessionImplDb s = (SessionImplDb)session; + return s.graphSession.undoContext.redo(this, count); + } + + @Override + public int undoTo(Session session, long changeSet) + throws DatabaseException { + if (!(session instanceof SessionImplDb) || changeSet < 1) + return 0; + SessionImplDb s = (SessionImplDb)session; + long head = s.graphSession.getLastChangeSetId(); + int SIZE = (int)(head - changeSet); + if (SIZE < 1) + return 0; + s.graphSession.undoContext.clear(); + Vector ops = new Vector(SIZE); + ops.setSize(SIZE); + long id = changeSet; + for (int i = 0; i metadata = ms.getMetadata(changeSet, head, CommitMetadata.class); + if (metadata.size() != SIZE) + return 0; + s.graphSession.undoContext.clear(); + long first = 0; + Iterator it = metadata.iterator(); + long csid = changeSet; + SIZE += csid; + for (; csid