You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2021/06/11 09:35:37 UTC

[sling-whiteboard] branch master updated: Echo command added

This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new bf776f0  Echo command added
bf776f0 is described below

commit bf776f022cffda10392681cc7f673d7adb25b46d
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Jun 11 11:35:20 2021 +0200

    Echo command added
---
 remote-content-api/sample-graphql-api/README.md    | 27 ++++++-
 .../samples/graphql/CommandDataFetcher.java        | 82 ++++++++++++++++------
 .../{ObjectScalar.java => CommandResult.java}      | 29 ++++----
 .../graphql/{ObjectScalar.java => JsonScalar.java} |  6 +-
 .../main/resources/schemas/default/N.GQLschema.jsp |  6 +-
 5 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/remote-content-api/sample-graphql-api/README.md b/remote-content-api/sample-graphql-api/README.md
index 7adc603..2281c5a 100644
--- a/remote-content-api/sample-graphql-api/README.md
+++ b/remote-content-api/sample-graphql-api/README.md
@@ -143,7 +143,7 @@ This prototype is evolving, some of these examples might be out of date. See the
     mutation {
     command(
       lang:"repoinit",
-      script:"""
+      input:"""
         # comments work here
         create path /open-for-all/ok
       """)
@@ -154,6 +154,31 @@ This prototype is evolving, some of these examples might be out of date. See the
     }
     }
 
+    # commands support free-form JSON data as input
+    mutation {
+      command(lang: "echo", input: 
+        {structuredJSONdata: 
+          {
+            isSupported: true, 
+            for: "things like this", 
+            as: {json: "data"}
+          }
+        }
+      	) {
+        success
+        output
+        help
+      }
+    }
+
+    mutation {
+      command(lang: "echo", input: "Just a string") {
+        success
+        output
+        help
+      }
+    }
+
     {
       documents(query: "//open-for-all/*") {
         edges {
diff --git a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandDataFetcher.java b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandDataFetcher.java
index 1bf7bec..112e9b6 100644
--- a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandDataFetcher.java
+++ b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandDataFetcher.java
@@ -22,6 +22,8 @@ package org.apache.sling.remotecontent.samples.graphql;
 import java.io.StringReader;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
 
 import javax.jcr.Session;
 
@@ -37,38 +39,74 @@ import org.osgi.service.component.annotations.Reference;
 @Component(service = SlingDataFetcher.class, property = {"name=samples/command"})
 public class CommandDataFetcher implements SlingDataFetcher<Object> {
 
+    public static final String ARG_INPUT = "input";
+    public static final String ARG_LANG = "lang";
+
     @Reference
     private RepoInitParser parser;
 
     @Reference
     private JcrRepoInitOpsProcessor processor;
 
-    private static final String LANG_REPOINIT = "repoinit";
+    // TODO turn these into services and provide a GraphQL query to list them
+    abstract static  class CommandLanguage {
+        public final String name;
+        public final String help;
 
-    @Override
-    public @Nullable Object get(@NotNull SlingDataFetcherEnvironment e) throws Exception {
-        final String lang = e.getArgument("lang", LANG_REPOINIT);
-        if(!LANG_REPOINIT.equals(lang)) {
-            throw new RuntimeException("For now, the only supported language is " + LANG_REPOINIT);
+        protected CommandLanguage(String name, String help) {
+            this.name = name;
+            this.help = help;
         }
-        final String script = e.getArgument("script");
-        final Map<String, Object> result = new HashMap<>();
 
-        try {
-            final Session s = e.getCurrentResource().getResourceResolver().adaptTo(Session.class);
-            processor.apply(s, parser.parse(new StringReader(script)));
-            s.save();
-            result.put("success", true);
-            result.put("output", "repoinit script successfully executed");
-        } catch(Exception ex) {
-            result.put("success", false);
-            result.put("output", ex.toString());
-        }
+        abstract CommandResult execute(@NotNull SlingDataFetcherEnvironment e);
+    }
+    private static final Map<String, CommandLanguage> languages = new HashMap<>();
+
+    private void addLanguage(CommandLanguage language) {
+        languages.put(language.name, language);
+    }
+
+    public CommandDataFetcher() {
+        addLanguage(new CommandLanguage(
+            "repoinit", 
+            "See https://sling.apache.org/documentation/bundles/repository-initialization.html for information about the repoinit language") {
+                public CommandResult execute(@NotNull SlingDataFetcherEnvironment e) {
+                    final Map<String, Object> result = new HashMap<>();
+                    final String script = e.getArgument(ARG_INPUT, "");
+                    String output;
+                    boolean success;
+                    try {
+                        final Session s = e.getCurrentResource().getResourceResolver().adaptTo(Session.class);
+                        processor.apply(s, parser.parse(new StringReader(script)));
+                        s.save();
+                        success = true;
+                        output = "repoinit script successfully executed";
+                    } catch(Exception ex) {
+                        success = false;
+                        output = ex.toString();
+                    }
+                    return new CommandResult(success, output, help);
+            
+                }
+            });
+            addLanguage(new CommandLanguage(
+                "echo", 
+                "Echoes its input") {
+                    public CommandResult execute(@NotNull SlingDataFetcherEnvironment e) {
+                        final Object input = e.getArgument(ARG_INPUT, "");
+                        return new CommandResult(input != null, input, help);
+                    }
+                });
+    }
 
-        result.put("help", "See https://sling.apache.org/documentation/bundles/repository-initialization.html for information about the repoinit language");
-        
-        
-        return result;
+    @Override
+    public @Nullable Object get(@NotNull SlingDataFetcherEnvironment e) throws Exception {
+        final String lang = e.getArgument(ARG_LANG, null);
+        final CommandLanguage language = languages.get(lang);
+        if(language == null) {
+            throw new RuntimeException(String.format("Unsupported language '%s' (provided by %s argument)", lang, ARG_LANG));
+        }
+        return language.execute(e);
     }
     
 }
diff --git a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandResult.java
similarity index 55%
copy from remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java
copy to remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandResult.java
index 638e311..8524ee9 100644
--- a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java
+++ b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/CommandResult.java
@@ -19,23 +19,26 @@
 
 package org.apache.sling.remotecontent.samples.graphql;
 
-import org.apache.sling.graphql.api.ScalarConversionException;
-import org.apache.sling.graphql.api.SlingScalarConverter;
-import org.jetbrains.annotations.Nullable;
-import org.osgi.service.component.annotations.Component;
+public class CommandResult {
+    private final boolean success;
+    private final Object output;
+    private final String help;
 
-/** Passthrough Scalar, used to output unpredictable JSON structures */
-@Component(service = SlingScalarConverter.class, property = { "name=Object" })
-public class ObjectScalar implements SlingScalarConverter<Object, Object> {
+    CommandResult(boolean successful, Object output, String help) {
+        this.success = successful;
+        this.output = output;
+        this.help = help;
+    }
 
-    @Override
-    public @Nullable Object parseValue(@Nullable Object input) throws ScalarConversionException {
-        return input;
+    public boolean getSuccess() {
+        return success;
     }
 
-    @Override
-    public @Nullable Object serialize(@Nullable Object value) throws ScalarConversionException {
-        return value;
+    public Object getOutput() {
+        return output;
     }
 
+    public String getHelp() {
+        return help;
+    }
 }
\ No newline at end of file
diff --git a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/JsonScalar.java
similarity index 90%
rename from remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java
rename to remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/JsonScalar.java
index 638e311..1bcc434 100644
--- a/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/ObjectScalar.java
+++ b/remote-content-api/sample-graphql-api/src/main/java/org/apache/sling/remotecontent/samples/graphql/JsonScalar.java
@@ -24,9 +24,9 @@ import org.apache.sling.graphql.api.SlingScalarConverter;
 import org.jetbrains.annotations.Nullable;
 import org.osgi.service.component.annotations.Component;
 
-/** Passthrough Scalar, used to output unpredictable JSON structures */
-@Component(service = SlingScalarConverter.class, property = { "name=Object" })
-public class ObjectScalar implements SlingScalarConverter<Object, Object> {
+/** Passthrough Scalar, used to handle unpredictable JSON structures */
+@Component(service = SlingScalarConverter.class, property = { "name=JSON" })
+public class JsonScalar implements SlingScalarConverter<Object, Object> {
 
     @Override
     public @Nullable Object parseValue(@Nullable Object input) throws ScalarConversionException {
diff --git a/remote-content-api/sample-graphql-api/src/main/resources/schemas/default/N.GQLschema.jsp b/remote-content-api/sample-graphql-api/src/main/resources/schemas/default/N.GQLschema.jsp
index cfe2fcc..9bdf71c 100644
--- a/remote-content-api/sample-graphql-api/src/main/resources/schemas/default/N.GQLschema.jsp
+++ b/remote-content-api/sample-graphql-api/src/main/resources/schemas/default/N.GQLschema.jsp
@@ -26,7 +26,7 @@ create a "text passthrough" script engine for such things.
 """
 Some fields use this Scalar to provide unstructured or semi-structured data
 """
-scalar Object
+scalar JSON
 
 type Query {
   """ 
@@ -108,7 +108,7 @@ such as Resource Type values help make such structures self-descriptive.
 type UnstructuredContent {
   name : String!
   source : String!
-  content : Object
+  content : JSON
 }
 
 """
@@ -146,7 +146,7 @@ type Mutation {
   'lang' is the command language - TODO provide a query that lists languages with their help text
   'script' is the script to execute, in the language indicated by 'lang'
   """  
-  command(lang: String, script: String) : CommandResult @fetcher(name:"samples/command")
+  command(lang: String, input: JSON) : CommandResult @fetcher(name:"samples/command")
 }
 
 """