diff --git a/src/main/java/com/opengroupe/cloud/saas/domain/Comment.java b/src/main/java/com/opengroupe/cloud/saas/domain/Comment.java index fa28923..aa53170 100644 --- a/src/main/java/com/opengroupe/cloud/saas/domain/Comment.java +++ b/src/main/java/com/opengroupe/cloud/saas/domain/Comment.java @@ -1,8 +1,5 @@ package com.opengroupe.cloud.saas.domain; -import groovy.transform.ToString; - -@ToString public class Comment { private final Long id; diff --git a/src/main/java/com/opengroupe/cloud/saas/rest/CommentController.java b/src/main/java/com/opengroupe/cloud/saas/rest/CommentController.java index be035c0..f527ba8 100644 --- a/src/main/java/com/opengroupe/cloud/saas/rest/CommentController.java +++ b/src/main/java/com/opengroupe/cloud/saas/rest/CommentController.java @@ -1,8 +1,8 @@ package com.opengroupe.cloud.saas.rest; -import java.util.ArrayList; import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -10,12 +10,14 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.opengroupe.cloud.saas.domain.Comment; +import com.opengroupe.cloud.saas.service.CommentService; @RestController public class CommentController { - private List comments = new ArrayList(); - + @Autowired + private CommentService service; + @RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; @@ -23,7 +25,7 @@ public class CommentController { @RequestMapping(value="/api/comments", method=RequestMethod.GET) public @ResponseBody List comments() { - return comments; + return service.getAll(); } @RequestMapping(value="/api/comments", method=RequestMethod.POST) @@ -31,7 +33,8 @@ public class CommentController { @RequestParam(value="id", required=true) Long id, @RequestParam(value="author", required=true) String author, @RequestParam(value="text", required=true) String text) { - comments.add(new Comment(id, author, text)); - return comments; + service.add(new Comment(id, author, text)); + return service.getAll(); } + } diff --git a/src/main/java/com/opengroupe/cloud/saas/service/CommentService.java b/src/main/java/com/opengroupe/cloud/saas/service/CommentService.java new file mode 100644 index 0000000..08b25eb --- /dev/null +++ b/src/main/java/com/opengroupe/cloud/saas/service/CommentService.java @@ -0,0 +1,31 @@ +package com.opengroupe.cloud.saas.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.springframework.stereotype.Component; + +import com.opengroupe.cloud.saas.domain.Comment; + +@Component +public class CommentService { + + private List comments = new ArrayList(); + + @PostConstruct + void init() { + comments.addAll(Arrays.asList(new Comment(1L, "Pete Hunt", "This is one comment"), + new Comment(2L, "Jordan Walke", "This is *another* comment"))); + } + + public void add(Comment comment) { + comments.add(comment); + } + + public List getAll() { + return comments; + } +} diff --git a/src/main/java/com/opengroupe/cloud/saas/util/React.java b/src/main/java/com/opengroupe/cloud/saas/util/React.java new file mode 100644 index 0000000..dc29e00 --- /dev/null +++ b/src/main/java/com/opengroupe/cloud/saas/util/React.java @@ -0,0 +1,50 @@ +package com.opengroupe.cloud.saas.util; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.List; + +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import com.opengroupe.cloud.saas.domain.Comment; + +import jdk.nashorn.api.scripting.NashornScriptEngine; + +public class React { + + private ThreadLocal engineHolder = new ThreadLocal() { + @Override + protected NashornScriptEngine initialValue() { + NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn"); + try { + nashornScriptEngine.eval(read("static/js/nashorn-polyfill.js")); + nashornScriptEngine.eval(read("META-INF/resources/webjars/react/0.14.7/react.min.js")); + nashornScriptEngine.eval(read("META-INF/resources/webjars/marked/0.3.2/marked.js")); +// nashornScriptEngine.eval(read("classpath:static/js/react-bootstrap.js")); +// nashornScriptEngine.eval(read("classpath:static/js/comments.js")); + nashornScriptEngine.eval(read("static/js/app.js")); + nashornScriptEngine.eval(read("static/js/app.render.js")); + } catch (ScriptException e) { + throw new RuntimeException(e); + } + return nashornScriptEngine; + } + }; + + public String renderCommentBox(List comments) { + try { + Object html = engineHolder.get().invokeFunction("renderServer", comments); + return String.valueOf(html); + } + catch (Exception e) { + throw new IllegalStateException("failed to render react component", e); + } + } + + private Reader read(String path) { + InputStream in = getClass().getClassLoader().getResourceAsStream(path); + return new InputStreamReader(in); + } +} \ No newline at end of file diff --git a/src/main/java/com/opengroupe/cloud/saas/web/ViewController.java b/src/main/java/com/opengroupe/cloud/saas/web/ViewController.java index 8a65cd3..d9b88bc 100644 --- a/src/main/java/com/opengroupe/cloud/saas/web/ViewController.java +++ b/src/main/java/com/opengroupe/cloud/saas/web/ViewController.java @@ -1,13 +1,31 @@ package com.opengroupe.cloud.saas.web; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.opengroupe.cloud.saas.domain.Comment; +import com.opengroupe.cloud.saas.service.CommentService; +import com.opengroupe.cloud.saas.util.React; + @Controller public class ViewController { + @Autowired + private CommentService service; + + + @Autowired + private ObjectMapper objectMapper; + + private React react = new React(); + @RequestMapping("/greeting") public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); @@ -15,7 +33,12 @@ public class ViewController { } @RequestMapping("/index") - public String index(Model model) { + public String index(Model model) throws JsonProcessingException { + List comments = service.getAll(); + String commentBox = react.renderCommentBox(comments); + String data = objectMapper.writeValueAsString(comments); + model.addAttribute("markup", commentBox); + model.addAttribute("data", data); return "index"; } } diff --git a/src/main/resources/static/js/app.jsx b/src/main/resources/static/js/app.jsx index f4dc3da..2702ac4 100644 --- a/src/main/resources/static/js/app.jsx +++ b/src/main/resources/static/js/app.jsx @@ -59,7 +59,7 @@ var CommentForm = React.createClass({ }); var CommentBox = React.createClass({ getInitialState: function() { - return {data: []}; + return {data: this.props.data || []}; }, loadCommentsFromServer: function() { $.ajax({ diff --git a/src/main/resources/static/js/app.render.jsx b/src/main/resources/static/js/app.render.jsx index 9709ace..a9cb5e8 100644 --- a/src/main/resources/static/js/app.render.jsx +++ b/src/main/resources/static/js/app.render.jsx @@ -1,4 +1,14 @@ -ReactDOM.render( - , - document.getElementById('content') -); \ No newline at end of file +var renderClient = function (comments) { + var data = comments || []; + ReactDOM.render( + , + document.getElementById('content') + ); +}; + +var renderServer = function (comments) { + var data = Java.from(comments); + return React.renderToString( + + ); +}; \ No newline at end of file diff --git a/src/main/resources/static/js/nashorn-polyfill.js b/src/main/resources/static/js/nashorn-polyfill.js new file mode 100644 index 0000000..e95fea7 --- /dev/null +++ b/src/main/resources/static/js/nashorn-polyfill.js @@ -0,0 +1,6 @@ +var global = this; + +var console = {}; +console.debug = print; +console.warn = print; +console.log = print; \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 9abf25c..deb88d8 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -11,7 +11,7 @@
-
+
@@ -20,6 +20,9 @@ - + \ No newline at end of file