package fi.vtt.simantics.procore.internal; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.simantics.db.ChangeSet; import org.simantics.db.ChangeSetIdentifier; import org.simantics.db.Metadata; import org.simantics.db.ReadGraph; import org.simantics.db.Session; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InternalException; import org.simantics.db.service.ManagementSupport; import org.simantics.db.service.XSupport; public class ManagementSupportImpl implements ManagementSupport { final private SessionImplSocket session; ManagementSupportImpl(SessionImplSocket session) { this.session = session; } @Override public Collection fetchChangeSets(final ReadGraph graph, final long min, final long max) throws DatabaseException { if (min < 1 || min > max) throw new IllegalArgumentException("Illegal range: min=" + min + " max=" + max); return graph.sync(new UniqueRead>() { @Override public Collection perform(ReadGraph graph) throws DatabaseException { int size = (int)(max - min + 1); ClientChangesImpl csi = new ClientChangesImpl(session); SynchronizeContext context = new SynchronizeContext(session, csi, size, true); boolean failed = session.graphSession.getChangeSets(min, max, context); if (failed) throw new InternalException("Trouble with server execution."); final boolean undo = false; if (!context.isOk(undo)) // this is a blocking operation throw new InternalException("Trouble with server reply."); return context.getChangeSets(); } }); } @Override public Collection getChangeSetIdentifiers(long from, long to) throws DatabaseException { return session.graphSession.getChangeSets(from, to, session.state.getHeadRevisionId()); } @Override @Deprecated public Collection getChangeSets(long from, long to) throws DatabaseException { return session.graphSession.getChangeSets(from, to, session.state.getHeadRevisionId()); } @Override public Collection getMetadata(ReadGraph graph, long from, long to, Class dataClass) throws DatabaseException { return this.getMetadata(from, to, dataClass); } @SuppressWarnings("unchecked") @Override public Collection getMetadata(long from, long to, Class dataClass) throws DatabaseException { ArrayList results = new ArrayList(); try { Method m = dataClass.getMethod("deserialise", Session.class, byte[].class); Collection css = getChangeSets(from, to); for(ChangeSetIdentifier cs : css) { Map md = cs.getMetadata(); if (null != md) { byte[] result = md.get(dataClass.getName()); if (null != result) { try { Object value = m.invoke(null, session, result); results.add((T)value); } catch (SecurityException e) { Logger.defaultLogError(e); } catch (IllegalArgumentException e) { Logger.defaultLogError(e); } catch (IllegalAccessException e) { Logger.defaultLogError(e); } catch (InvocationTargetException e) { Logger.defaultLogError(e.getCause()); } } } } } catch (SecurityException e) { Logger.defaultLogError(e); } catch (NoSuchMethodException e) { Logger.defaultLogError(e); } catch (IllegalArgumentException e) { Logger.defaultLogError(e); } return results; } @Override public void dumpRevision(long lastChangeSetId) throws DatabaseException { XSupport xs = session.getService(XSupport.class); String s = xs.execute("dumpRevision " + lastChangeSetId); long outChangeSetId = Long.parseLong(s); if (lastChangeSetId > 0 && outChangeSetId != lastChangeSetId) throw new DatabaseException("Failed to dump revision=" + lastChangeSetId + ":\n" + s); } @Override public void dumpChangeSets(long lastChangeSetId) throws DatabaseException { XSupport xs = session.getService(XSupport.class); String s = xs.execute("dumpChangeSets " + lastChangeSetId); long outChangeSetId = Long.parseLong(s); if (lastChangeSetId > 0 && outChangeSetId != lastChangeSetId) throw new DatabaseException("Failed to dump revision=" + lastChangeSetId + ":\n" + s); } @Override public long getHeadRevisionId() throws DatabaseException { return session.state.getHeadRevisionId(); // Better to use this to match getChangeSets implementation above. // or not return session.graphSession.getLastChangeSetId(); } @Override public long getFirstRevisionId() throws DatabaseException { return session.graphSession.dbSession.getDatabase().serverGetTailChangeSetId(); } @Override public void subscribe(ChangeSetListener changeSetListener) { session.graphSession.addChangeSetListener(changeSetListener); } @Override public void cancel(ChangeSetListener changeSetlistener) { session.graphSession.removeChangeSetListener(changeSetlistener); } }