]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterUpdateProcessorBase.java
NPE fix for Acorn cluster stream undo handling
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / internal / ClusterUpdateProcessorBase.java
index cd8130d9c51357902b2cea7ef3a2f9be2117f2a8..507db172126963611a7bdba7da7f4009957afd0b 100644 (file)
@@ -12,9 +12,15 @@ import org.simantics.acorn.internal.ClusterStream.StmEnum;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.service.Bytes;
 import org.simantics.db.service.ClusterUID;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import fi.vtt.simantics.procore.internal.ClusterChange2;
 
 abstract public class ClusterUpdateProcessorBase {
-       
+
+       private static final Logger LOGGER = LoggerFactory.getLogger(ClusterUpdateProcessorBase.class);
+
        public final static boolean DEBUG = false;
 
        final protected ClusterManager manager;
@@ -24,9 +30,9 @@ abstract public class ClusterUpdateProcessorBase {
        final private ClusterUID uid;
        final private int clusterKey;
        final public int version;
-       
-       final Map<ClusterUID, Integer> clusterKeyCache = new HashMap<ClusterUID, Integer>();
-       
+
+       final Map<ClusterUID, Integer> clusterKeyCache = new HashMap<>();
+
        public int getResourceKey(ClusterUID uid, int index) throws IllegalAcornStateException {
                Integer match = clusterKeyCache.get(uid);
                if(match != null) return match+index;
@@ -40,7 +46,7 @@ abstract public class ClusterUpdateProcessorBase {
                this.manager = client;
                this.bytes = operations;
                this.len = Bytes.readLE4(bytes, 0)+4; // whatta?
-               version = Bytes.readLE4(bytes, 4);
+               this.version = Bytes.readLE4(bytes, 4);
                long cuid1 = Bytes.readLE8(bytes, 8);
                long cuid2 = Bytes.readLE8(bytes, 16);
                uid = ClusterUID.make(cuid1, cuid2);
@@ -66,24 +72,21 @@ abstract public class ClusterUpdateProcessorBase {
                try {
                        create();
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       LOGGER.error("resource create failed", e);
                }
-               
        }
-       
+
        private void processDelete() {
-               
                int ri = Bytes.readLE2(bytes, pos);
                pos += 2;
-               
+
                if(DEBUG) System.err.println("DEBUG: Delete " + ri);
-               
+
                try {
                        delete(ri);
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       LOGGER.error("resource {} value delete failed", ri, e);
                }
-               
        }
 
        private void processModify(int op) {
@@ -110,7 +113,8 @@ abstract public class ClusterUpdateProcessorBase {
                try {
                        modify(clusterKey + ri, offset, size, bytes, pos);
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       LOGGER.error("resource value modify(clusterKey: {}, ri: {}, offset: {}, size: {}, pos: {}) failed",
+                                       clusterKey, ri, offset, size, pos, e);
                }
 
                pos += size;
@@ -134,7 +138,8 @@ abstract public class ClusterUpdateProcessorBase {
                try {
                        set(clusterKey+r, valueBuffer, length);
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       LOGGER.error("resource value set(clusterKey: {}, r: {}, length: {}) failed",
+                                       clusterKey, r, length, e);
                }
                
        }
@@ -160,7 +165,8 @@ abstract public class ClusterUpdateProcessorBase {
                try {
                        set(clusterKey+r, valueBuffer, length);
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       LOGGER.error("resource value setShort(clusterKey: {}, r: {}, length: {}) failed",
+                                       clusterKey, r, length, e);
                }
                
        }
@@ -288,7 +294,8 @@ abstract public class ClusterUpdateProcessorBase {
                        try {
                                claim(clusterKey+ri, predicateKey, objectKey, puid, ouid);
                        } catch (DatabaseException e) {
-                               e.printStackTrace();
+                               LOGGER.error("statement add(clusterKey: {}, ri: {}, predicateKey: {}, objectKey: {}, puid: {}, ouid: {}) failed",
+                                               clusterKey, ri, predicateKey, objectKey, puid.toString(), ouid.toString(), e);
                        }
                        
                } else {
@@ -301,7 +308,8 @@ abstract public class ClusterUpdateProcessorBase {
                        try {
                                deny(clusterKey+ri, predicateKey, objectKey, puid, ouid);
                        } catch (DatabaseException e) {
-                               e.printStackTrace();
+                               LOGGER.error("statement deny(clusterKey: {}, ri: {}, predicateKey: {}, objectKey: {}, puid: {}, ouid: {}) failed",
+                                               clusterKey, ri, predicateKey, objectKey, puid.toString(), ouid.toString(), e);
                        }
                        
                }
@@ -309,6 +317,14 @@ abstract public class ClusterUpdateProcessorBase {
        }
 
        public void process() throws IllegalAcornStateException {
+               if (version == ClusterChange.VERSION) {
+                       process1();
+               } else if (version == ClusterChange2.VERSION) {
+                       process2();
+               }
+       }
+
+       private void process1() throws IllegalAcornStateException {
                
                foreignPos = 0;
 
@@ -463,14 +479,50 @@ abstract public class ClusterUpdateProcessorBase {
                }
                
        }
-       
-       
+
+       private void process2() throws IllegalAcornStateException {
+
+               while(pos < len) {
+
+                       int op = bytes[pos++]&0xff;
+
+                       switch(op) {
+
+                       case ClusterChange2.SET_IMMUTABLE_OPERATION:
+                               processSetImmutable(op);
+                               break;
+                       case ClusterChange2.UNDO_VALUE_OPERATION:
+                               processUndoValue(op);
+                               break;
+                       case ClusterChange2.SET_DELETED_OPERATION:
+                               // TODO: implement?
+                               break;
+                       default:
+                               throw new IllegalAcornStateException("Can not process operation " + op + " for cluster " + uid);
+
+                       }
+               }
+
+       }
+
+       private void processSetImmutable(int op) {
+               int value = bytes[pos++]&0xff;
+               setImmutable(value > 0);
+       }
+
+       private void processUndoValue(int op) {
+               Bytes.readLE4(bytes, pos);
+               pos+=4;
+       }
+
        abstract void create() throws DatabaseException;
        abstract void delete(int resourceIndex) throws DatabaseException;
        abstract void modify(int resourceKey, long offset, int size, byte[] bytes, int pos) throws DatabaseException;
        abstract void set(int resourceKey, byte[] bytes, int length) throws DatabaseException;
-       
+
        abstract void claim(int resourceKey, int predicateKey, int objectKey, ClusterUID puid, ClusterUID ouid) throws DatabaseException;
        abstract void deny(int resourceKey, int predicateKey, int objectKey, ClusterUID puid, ClusterUID ouid) throws DatabaseException;
-       
+
+       abstract void setImmutable(boolean value);
+
 }