Bug 574779: [RService] Adapt to enhanced ToolCommandHandler

  - Add implementation for ToolCommandData with RJ data
  - Add notice to CHANGES

Change-Id: Ie0620bf52522cd3c21db3a9e865ce4e79c1ffd79
diff --git a/CHANGES.md b/CHANGES.md
index 912e93f..558c592 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,19 @@
 # Notable Changes in StatET RJ
 
 
+## RJ 4.5.0 ~ StatET 4.5.0
+
+  * The data access for tool command handler is enhanced. Implementations of handlers need to be
+    adapted.
+    
+    `ToolCommandHandler` uses `ToolCommandData` instead of a map for the data exchange providing
+    access to the raw data (RJObject for RJ) and more flexible, dynamic data conversion to Java
+    types. `ToolCommandHandlerUtils` is removed since the functionality is integrated in the new
+    tool command data class.
+    
+    (Bug 574779)
+
+
 ## RJ 4.4.0 ~ StatET 4.4.0
 
 ### RServi Pool
diff --git a/core/org.eclipse.statet.rj.client/src/org/eclipse/statet/rj/server/client/AbstractRJComClient.java b/core/org.eclipse.statet.rj.client/src/org/eclipse/statet/rj/server/client/AbstractRJComClient.java
index 6ab84f3..f084be6 100644
--- a/core/org.eclipse.statet.rj.client/src/org/eclipse/statet/rj/server/client/AbstractRJComClient.java
+++ b/core/org.eclipse.statet.rj.client/src/org/eclipse/statet/rj/server/client/AbstractRJComClient.java
@@ -455,7 +455,7 @@
 		final ExtClientCmdItem item= new ExtClientCmdItem(io);
 		try {
 			final RList answer= handleUICallback(item.getDataText(), item.getDataArgs(),
-					this.progressMonitor);
+					item.waitForClient(), this.progressMonitor );
 			item.setAnswer(answer);
 		}
 		catch (final IOException e) {
@@ -477,6 +477,7 @@
 	}
 	
 	protected RList handleUICallback(final String commandId, final RList args,
+			final boolean acceptsAnswer,
 			final ProgressMonitor m) throws Exception {
 		throw new StatusException(new WarningStatus(RJ_CLIENT_ID,
 				String.format("Unhandled RJ UI command '%1$s'.", commandId) ));
diff --git a/core/org.eclipse.statet.rj.services.core/META-INF/MANIFEST.MF b/core/org.eclipse.statet.rj.services.core/META-INF/MANIFEST.MF
index 3d4ac5b..48e92a5 100644
--- a/core/org.eclipse.statet.rj.services.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.statet.rj.services.core/META-INF/MANIFEST.MF
@@ -23,4 +23,5 @@
  org.eclipse.statet.rj.services;version="4.5.0",
  org.eclipse.statet.rj.services.util;version="4.5.0",
  org.eclipse.statet.rj.services.util.dataaccess;version="4.5.0",
- org.eclipse.statet.rj.ts.core;version="4.5.0"
+ org.eclipse.statet.rj.ts.core;version="4.5.0",
+ org.eclipse.statet.rj.ts.core.util;version="4.5.0"
diff --git a/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/AbstractRToolCommandHandler.java b/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/AbstractRToolCommandHandler.java
index 2c61dd3..5c9eb6e 100644
--- a/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/AbstractRToolCommandHandler.java
+++ b/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/AbstractRToolCommandHandler.java
@@ -14,12 +14,11 @@
 
 package org.eclipse.statet.rj.ts.core;
 
-import java.util.Map;
-
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 import org.eclipse.statet.jcommons.status.ProgressMonitor;
 import org.eclipse.statet.jcommons.status.Status;
 import org.eclipse.statet.jcommons.status.StatusException;
+import org.eclipse.statet.jcommons.ts.core.ToolCommandData;
 import org.eclipse.statet.jcommons.ts.core.ToolCommandHandler;
 import org.eclipse.statet.jcommons.ts.core.ToolService;
 
@@ -32,12 +31,12 @@
 	
 	
 	@Override
-	public Status execute(final String id, final ToolService service, final Map<String, Object> data,
+	public Status execute(final String id, final ToolService service, final ToolCommandData data,
 			final ProgressMonitor m) throws StatusException {
-		return execute(id, (RToolService) service, data, m);
+		return execute(id, (RToolService)service, data, m);
 	}
 	
-	protected abstract Status execute(final String id, final RToolService r, final Map<String, Object> data,
+	protected abstract Status execute(final String id, final RToolService r, final ToolCommandData data,
 			final ProgressMonitor m) throws StatusException;
 	
 }
diff --git a/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/util/RjToolCommandData.java b/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/util/RjToolCommandData.java
new file mode 100644
index 0000000..9bad284
--- /dev/null
+++ b/core/org.eclipse.statet.rj.services.core/srcToolService/org/eclipse/statet/rj/ts/core/util/RjToolCommandData.java
@@ -0,0 +1,72 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ # 
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ # 
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ # 
+ # Contributors:
+ #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.rj.ts.core.util;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+import org.eclipse.statet.jcommons.ts.core.BasicToolCommandData;
+
+import org.eclipse.statet.rj.data.RDataJConverter;
+import org.eclipse.statet.rj.data.RList;
+import org.eclipse.statet.rj.data.RObject;
+import org.eclipse.statet.rj.data.RObjectFactory;
+
+
+@NonNullByDefault
+public class RjToolCommandData extends BasicToolCommandData {
+	
+	
+	private final RList rjData;
+	
+	private final RDataJConverter rjConverter;
+	
+	
+	public RjToolCommandData(final RList rjData) {
+		this.rjData= rjData;
+		this.rjConverter= new RDataJConverter();
+		this.rjConverter.setKeepArray1(true);
+	}
+	
+	
+	@Override
+	public @Nullable Object getRawData(final String key) {
+		return this.rjData.get(key);
+	}
+	
+	
+	@Override
+	@SuppressWarnings("unchecked")
+	public <TValue> @Nullable TValue convert(@Nullable Object data, final Class<TValue> type) {
+		if (data instanceof RObject) {
+			if (RObject.class.isAssignableFrom(type)) {
+				return null;
+			}
+			data= this.rjConverter.toJava((RObject)data);
+			if (data == null || type.isInstance(data)) {
+				return (TValue)data;
+			}
+		}
+		
+		return super.convert(data, type);
+	}
+	
+	
+	protected RList getRJReturnData(final RObjectFactory rObjectFactory) {
+		final var returnData= getReturnData();
+		this.rjConverter.setRObjectFactory(rObjectFactory);
+		return (RList)this.rjConverter.toRJ(returnData);
+	}
+	
+}