]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/lru/ClusterUpdateOperation.java
NPE fix for Acorn cluster stream undo handling
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / lru / ClusterUpdateOperation.java
1 package org.simantics.acorn.lru;
2
3 import org.simantics.acorn.ClusterManager;
4 import org.simantics.acorn.cluster.ClusterImpl;
5 import org.simantics.acorn.exception.AcornAccessVerificationException;
6 import org.simantics.acorn.exception.IllegalAcornStateException;
7 import org.simantics.acorn.internal.ClusterUpdateProcessor;
8 import org.simantics.db.service.Bytes;
9 import org.simantics.db.service.ClusterUID;
10
11 final public class ClusterUpdateOperation {
12         
13         final public ClusterUID uid;
14         final protected ClusterManager manager;
15         final protected ClusterInfo info;
16
17         public byte[] data;
18         
19         public ClusterStreamChunk chunk;
20         public ClusterChangeSet ccs;
21         boolean finished = false;
22
23         public ClusterUpdateOperation(ClusterManager manager, byte[] data) throws IllegalAcornStateException, AcornAccessVerificationException {
24                 
25                 long cuid1 = Bytes.readLE8(data, 8);
26                 long cuid2 = Bytes.readLE8(data, 16);
27
28                 this.manager = manager;
29                 this.uid = ClusterUID.make(cuid1, cuid2);
30                 this.data = data;
31                 this.info = manager.clusterLRU.getOrCreate(uid, true);
32         }
33         
34         public void finish() {
35                 finished = true;
36         }
37         
38         public void scheduled(String ccsInfoId) throws AcornAccessVerificationException, IllegalAcornStateException {
39                 ccs = new ClusterChangeSet(ccsInfoId, uid);
40                 chunk = ccs.getChunk(manager);
41                 manager.addIntoCurrentChangeSet(ccsInfoId);
42         }
43         
44         public void run() throws AcornAccessVerificationException, IllegalAcornStateException {
45                 ClusterUpdateOperation op = null;
46                 byte[] data = null;
47                 chunk.acquireMutex();
48                 try {
49                         chunk.makeResident();
50                         op = chunk.operations.get(ccs.chunkOffset);
51                         data = op.data;
52                 } finally {
53                         chunk.releaseMutex();
54                 }
55                 op.runWithData(data);
56         }
57         
58         public void runWithData(byte[] data) throws IllegalAcornStateException, AcornAccessVerificationException {
59                 try {
60                         ClusterUpdateProcessor processor = new ClusterUpdateProcessor(manager, manager.support, data, this);
61                         ClusterImpl cluster = info.getForUpdate();
62                         cluster = processor.process(cluster);
63                         manager.update(uid, cluster);
64                 } catch (IllegalAcornStateException | AcornAccessVerificationException e) {
65                     throw e;
66                 } catch (Throwable t) {
67                         throw new IllegalAcornStateException(t);
68                 }
69         }
70         
71         @Override
72         public String toString() {
73             StringBuilder sb = new StringBuilder();
74             sb.append("ClusterUpdateOperation [uid=").append(uid).append("] [info=").append(info).append("] [ccs=").append(ccs).append("] [chunk=").append("]");
75             return sb.toString();
76         }
77 }