1515 */
1616package org .netbeans .modules .nbcode .java .notebook ;
1717
18+ import java .util .concurrent .CompletableFuture ;
19+ import java .util .concurrent .ExecutionException ;
1820import java .util .concurrent .atomic .AtomicReference ;
21+ import java .util .logging .Logger ;
1922import org .eclipse .lsp4j .ExecutionSummary ;
2023import org .eclipse .lsp4j .NotebookCell ;
2124import org .eclipse .lsp4j .NotebookCellKind ;
2225import org .eclipse .lsp4j .TextDocumentItem ;
26+ import org .netbeans .modules .java .lsp .server .notebook .CellStateResponse ;
27+ import org .netbeans .modules .java .lsp .server .notebook .NotebookCellStateParams ;
28+ import org .netbeans .modules .java .lsp .server .protocol .NbCodeLanguageClient ;
2329
2430/**
2531 *
@@ -29,13 +35,18 @@ public class CellState {
2935
3036 private final NotebookCellKind type ;
3137 private final String language ;
38+ private final String cellUri ;
39+ private final String notebookUri ;
3240 private final AtomicReference <Object > metadata ;
33- private final AtomicReference <VersionAwareCotent > content ;
41+ private final AtomicReference <VersionAwareContent > content ;
3442 private final AtomicReference <ExecutionSummary > executionSummary ;
43+ private static final Logger LOG = Logger .getLogger (CellState .class .getName ());
3544
36- CellState (NotebookCell notebookCell , TextDocumentItem details ) {
45+ CellState (NotebookCell notebookCell , TextDocumentItem details , String notebookUri ) {
3746 String normalizedText = NotebookUtils .normalizeLineEndings (details .getText ());
38- this .content = new AtomicReference <>(new VersionAwareCotent (normalizedText , details .getVersion ()));
47+ this .cellUri = details .getUri ();
48+ this .notebookUri = notebookUri ;
49+ this .content = new AtomicReference <>(new VersionAwareContent (normalizedText , details .getVersion ()));
3950 this .language = details .getLanguageId ();
4051 this .type = notebookCell .getKind ();
4152 this .metadata = new AtomicReference <>(notebookCell .getMetadata ());
@@ -62,19 +73,57 @@ public ExecutionSummary getExecutionSummary() {
6273 return executionSummary .get ();
6374 }
6475
65- public void setContent (String newContent , int newVersion ) {
76+ public String getCellUri () {
77+ return cellUri ;
78+ }
79+
80+ public String getNotebookUri () {
81+ return notebookUri ;
82+ }
83+
84+ public void setContent (String newContent , int newVersion ) throws InterruptedException , ExecutionException {
6685 String normalizedContent = NotebookUtils .normalizeLineEndings (newContent );
67- VersionAwareCotent currentContent = content .get ();
86+ VersionAwareContent currentContent = content .get ();
6887
6988 if (currentContent .getVersion () != newVersion - 1 ) {
70- throw new IllegalStateException ("Version mismatch: expected " + (newVersion - 1 ) + ", got " + currentContent .getVersion ());
89+ if (currentContent .getVersion () >= newVersion ) {
90+ LOG .warning ("Current version is higher or equal than the new version request received, so ignoring it." );
91+ return ;
92+ }
93+ CompletableFuture <CellStateResponse > response = requestLatestCellState ();
94+ if (response == null ) {
95+ throw new IllegalStateException ("Unable to send notebook cell state request to the client" );
96+ }
97+
98+ CellStateResponse newCellState = response .get ();
99+ int receivedVersion = newCellState .getVersion ();
100+
101+ if (receivedVersion > currentContent .getVersion ()) {
102+ VersionAwareContent newVersionContent = new VersionAwareContent (newCellState .getText (), receivedVersion );
103+ content .set (newVersionContent );
104+ } else {
105+ throw new IllegalStateException ("Version mismatch: Received version to be greater than current version, received version: " + (receivedVersion ) + ", current version: " + currentContent .getVersion ());
106+ }
107+ } else {
108+ VersionAwareContent newVersionContent = new VersionAwareContent (normalizedContent , newVersion );
109+
110+ if (!content .compareAndSet (currentContent , newVersionContent )) {
111+ throw new IllegalStateException ("Concurrent modification detected. Version expected: " + (newVersion - 1 ) + ", current: " + content .get ().getVersion ());
112+ }
71113 }
114+ }
72115
73- VersionAwareCotent newVersionContent = new VersionAwareCotent ( normalizedContent , newVersion );
74-
75- if (! content . compareAndSet ( currentContent , newVersionContent ) ) {
76- throw new IllegalStateException ("Concurrent modification detected. Version expected: " + ( newVersion - 1 ) + ", current: " + content . get (). getVersion () );
116+ public void requestContentAndSet () throws InterruptedException , ExecutionException {
117+ CompletableFuture < CellStateResponse > response = requestLatestCellState ();
118+ if (response == null ) {
119+ throw new IllegalStateException ("Unable to send notebook cell state request to the client" );
77120 }
121+ CellStateResponse newCellState = response .get ();
122+ if (newCellState .getVersion () <= 0 ) {
123+ throw new IllegalStateException ("Received incorrect version number: " + newCellState .getVersion ());
124+ }
125+ VersionAwareContent newVersionContent = new VersionAwareContent (newCellState .getText (), newCellState .getVersion ());
126+ content .set (newVersionContent );
78127 }
79128
80129 public void setExecutionSummary (ExecutionSummary executionSummary ) {
@@ -85,12 +134,27 @@ public void setMetadata(Object metadata) {
85134 this .metadata .set (metadata );
86135 }
87136
88- private class VersionAwareCotent {
137+ // protected methods for ease of unit testing
138+ protected CompletableFuture <CellStateResponse > requestLatestCellState () {
139+ NbCodeLanguageClient client = LanguageClientInstance .getInstance ().getClient ();
140+
141+ if (client == null ) {
142+ LOG .warning ("Client is null" );
143+ return null ;
144+ }
145+ return client .getNotebookCellState (new NotebookCellStateParams (notebookUri , cellUri ));
146+ }
147+
148+ protected VersionAwareContent getVersionAwareContent (){
149+ return this .content .get ();
150+ }
151+
152+ protected class VersionAwareContent {
89153
90154 private String content ;
91155 private int version ;
92156
93- public VersionAwareCotent (String content , int version ) {
157+ public VersionAwareContent (String content , int version ) {
94158 this .content = content ;
95159 this .version = version ;
96160 }
0 commit comments