Skip to content

Commit

Permalink
add support for ratpack
Browse files Browse the repository at this point in the history
  • Loading branch information
siordache committed Apr 3, 2017
1 parent 70e4bb0 commit bb1dd6a
Show file tree
Hide file tree
Showing 12 changed files with 501 additions and 87 deletions.
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ project('text-io') {
project('text-io-web') {
dependencies {
compile project(':text-io')
compile 'com.sparkjava:spark-core:2.5.4'
compile 'com.google.code.gson:gson:2.8.0'
compile 'org.apache.commons:commons-lang3:3.5'
compileOnly 'com.sparkjava:spark-core:2.5.4'
compileOnly 'io.ratpack:ratpack-core:1.4.5'
compileOnly 'io.ratpack:ratpack-session:1.4.5'
testCompile 'io.ratpack:ratpack-test:1.4.5'
}
}

Expand All @@ -280,6 +283,9 @@ project('text-io-demo') {
dependencies {
compile project(':text-io')
compile project(':text-io-web')
compile 'com.sparkjava:spark-core:2.5.4'
compile 'io.ratpack:ratpack-core:1.4.5'
compile 'io.ratpack:ratpack-session:1.4.5'
runtime ('ch.qos.logback:logback-classic:1.1.7')
}
artifacts {
Expand Down
16 changes: 14 additions & 2 deletions doc/user_guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,15 @@ your application via a browser. See details below.

The WebTextTerminal works only in conjunction with a web server supporting the
link:javadoc/org/beryx/textio/web/DataApi.html[DataApi]
(such as the link:javadoc/org/beryx/textio/web/SparkDataServer.html[SparkDataServer])
(such as the link:javadoc/org/beryx/textio/web/SparkDataServer.html[SparkDataServer]
or the link:javadoc/org/beryx/textio/web/RatpackDataServer.html[RatpackDataServer])
and a web page that contains code for accessing this API.
This is typically accomplished via link:{blob-root}/text-io-web/src/main/resources/public-html/textterm.js[textterm.js],
Typically, the web server is managed by an implementation of
link:javadoc/org/beryx/textio/web/TextIoApp.html[TextIoApp] (such as
link:javadoc/org/beryx/textio/web/SparkTextIoApp.html[SparkTextIoApp] or
link:javadoc/org/beryx/textio/web/RatpackTextIoApp.html[RatpackTextIoApp]),
while the web page makes use of the library
link:{blob-root}/text-io-web/src/main/resources/public-html/textterm.js[textterm.js],
as shown in the code snippet below.

[source, html]
Expand Down Expand Up @@ -273,3 +279,9 @@ link:javadoc/org/beryx/textio/TerminalProperties.html#put-java.lang.String-java.
Additionally, convenience methods are available for frequently used properties (for example:
link:javadoc/org/beryx/textio/TerminalProperties.html#setInputBold-boolean-[setInputBold(boolean bold)] or
link:javadoc/org/beryx/textio/TerminalProperties.html#setPromptColor-javafx.scene.paint.Color-[setPromptColor(Color color)]).


TIP: You can learn how to configure and use terminal properties by looking at the
link:{blob-root}/text-io-demo/src/main/java/org/beryx/textio/demo[source code]
and the link:{blob-root}/dist/xbin[configuration files]
of the https://github.com/beryx/text-io/releases/download/v{project-version}/textio-demo-{project-version}.zip[demo application].
63 changes: 44 additions & 19 deletions text-io-demo/src/main/java/org/beryx/textio/demo/TextIoDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import org.beryx.textio.swing.SwingTextTerminalProvider;
import org.beryx.textio.system.SystemTextTerminal;
import org.beryx.textio.system.SystemTextTerminalProvider;
import org.beryx.textio.web.RatpackTextIoApp;
import org.beryx.textio.web.SparkTextIoApp;
import org.beryx.textio.web.TextIoApp;
import org.beryx.textio.web.WebTextTerminal;
import spark.Service;

import java.util.Arrays;
import java.util.List;
Expand All @@ -36,8 +38,6 @@
* Demo application showing various TextTerminals.
*/
public class TextIoDemo {
private static int webServerPort = -1;

private static class NamedProvider implements TextTerminalProvider {
final String name;
final Supplier<TextTerminal> supplier;
Expand All @@ -59,25 +59,59 @@ public String toString() {
}

public static void main(String[] args) {
Consumer<TextIO> app = chooseApp();
TextTerminal sysTerminal = new SystemTextTerminal();
TextIO sysTextIO = new TextIO(sysTerminal);

Consumer<TextIO> app = chooseApp(sysTextIO);
TextIO textIO = chooseTextIO();

// Uncomment the line below to ignore user interrupts.
// textIO.getTextTerminal().registerUserInterruptHandler(term -> System.out.println("\n\t### User interrupt ignored."), false);

if(textIO.getTextTerminal() instanceof WebTextTerminal) {
WebTextTerminal webTextTerm = (WebTextTerminal)textIO.getTextTerminal();
WebTextIoExecutor webTextIoExecutor = new WebTextIoExecutor(webTextTerm).withPort(webServerPort);
webTextIoExecutor.execute(app);
TextIoApp textIoApp = createTextIoApp(sysTextIO, app, webTextTerm);
WebTextIoExecutor webTextIoExecutor = new WebTextIoExecutor();
configurePort(sysTextIO, webTextIoExecutor, 8080);
webTextIoExecutor.execute(textIoApp);
} else {
app.accept(textIO);
}
}

private static Consumer<TextIO> chooseApp() {
TextTerminal terminal = new SystemTextTerminal();
TextIO textIO = new TextIO(terminal);
private static TextIoApp createTextIoApp(TextIO textIO, Consumer<TextIO> app, WebTextTerminal webTextTerm) {
class Provider {
private final String name;
private final Supplier<TextIoApp> supplier;

private Provider(String name, Supplier<TextIoApp> supplier) {
this.name = name;
this.supplier = supplier;
}

@Override
public String toString() {
return name;
}
}
Provider textIoAppProvider = textIO.<Provider>newGenericInputReader(null)
.withNumberedPossibleValues(
new Provider("Ratpack", () -> new RatpackTextIoApp(app, webTextTerm)),
new Provider("Spark", () -> new SparkTextIoApp(app, webTextTerm))
)
.read("\nChoose the web framework to be used");

return textIoAppProvider.supplier.get();
}

private static void configurePort(TextIO textIO, WebTextIoExecutor webTextIoExecutor, int defaultPort) {
int port = textIO.newIntInputReader()
.withDefaultValue(defaultPort)
.read("Server port number");
webTextIoExecutor.withPort(port);
}

private static Consumer<TextIO> chooseApp(TextIO textIO) {
List<Consumer<TextIO>> apps = Arrays.asList(new UserDataCollector(), new ECommerce(), new Cuboid());

Consumer<TextIO> app = textIO.<Consumer<TextIO>>newGenericInputReader(null)
Expand All @@ -100,7 +134,7 @@ private static TextIO chooseTextIO() {
new ConsoleTextTerminalProvider(),
new JLineTextTerminalProvider(),
new SwingTextTerminalProvider(),
new NamedProvider("Web terminal", () -> createWebTextTerminal(textIO))
new NamedProvider("Web terminal", WebTextTerminal::new)
)
.read("\nChoose the terminal to be used for running the demo");

Expand All @@ -119,13 +153,4 @@ private static TextIO chooseTextIO() {
return new TextIO(chosenTerminal);
}
}

private static WebTextTerminal createWebTextTerminal(TextIO textIO) {
webServerPort = textIO.newIntInputReader()
.withDefaultValue(Service.SPARK_DEFAULT_PORT)
.read("Server port number");

// The returned WebTextTerminal is used as a template by the WebTextIoExecutor, which instantiates a new WebTextTerminal each time a client starts a new session.
return new WebTextTerminal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,42 @@
*/
package org.beryx.textio.demo;

import org.beryx.textio.TextIO;
import org.beryx.textio.web.SparkDataServer;
import org.beryx.textio.web.SparkTextIoApp;
import org.beryx.textio.web.WebTextTerminal;
import org.beryx.textio.web.TextIoApp;

import java.awt.*;
import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static spark.Spark.staticFiles;
import static spark.Spark.stop;

/**
* Allows executing code in a {@link org.beryx.textio.web.WebTextTerminal}.
* by configuring and initializing a {@link SparkDataServer}.
* Allows executing code in a {@link org.beryx.textio.web.WebTextTerminal}
* by configuring and initializing a {@link TextIoApp}.
*/
public class WebTextIoExecutor {
private final WebTextTerminal termTemplate;
private int port = -1;

public WebTextIoExecutor(WebTextTerminal termTemplate) {
this.termTemplate = termTemplate;
}
private Integer port;

public WebTextIoExecutor withPort(int port) {
this.port = port;
return this;
}

public void execute(Consumer<TextIO> textIoRunner) {
SparkTextIoApp app = new SparkTextIoApp(textIoRunner, termTemplate);
app.setMaxInactiveSeconds(600);
public void execute(TextIoApp app) {
Consumer<String> stopServer = sessionId -> Executors.newSingleThreadScheduledExecutor().schedule(() -> {
stop();
System.exit(0);
}, 2, TimeUnit.SECONDS);
app.setOnDispose(stopServer);
app.setOnAbort(stopServer);

SparkDataServer server = app.getServer();
if(port > 0) {
server.withPort(port);
}

staticFiles.location("/public-html");
server.init();
app.withOnDispose(stopServer)
.withOnAbort(stopServer)
.withPort(port)
.withMaxInactiveSeconds(600)
.withStaticFilesLocation("public-html")
.init();

String url = "http://localhost:" + server.getPort() + "/web-demo.html";
String url = "http://localhost:" + app.getPort() + "/web-demo.html";
boolean browserStarted = false;
if(Desktop.isDesktopSupported()) {
try {
Expand Down
3 changes: 3 additions & 0 deletions text-io-demo/src/main/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<logger name="org.beryx.textio" level="trace" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="ratpack" level="trace" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<logger name="org.beryx.textio.web.WebTextTerminal" level="info" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.beryx.textio.web;

import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Typically used as base class for {@link DataServer} implementations.
*/
public abstract class AbstractDataServer implements DataServer {
private static final Logger logger = LoggerFactory.getLogger(WebTextTerminal.class);
public static final String DEFAULT_PATH_FOR_GET_DATA = "textTerminalData";
public static final String DEFAULT_PATH_FOR_POST_INPUT = "textTerminalInput";

private String pathForGetData = DEFAULT_PATH_FOR_GET_DATA;
private String pathForPostInput = DEFAULT_PATH_FOR_POST_INPUT;

private final Gson gson = new Gson();

public AbstractDataServer withPathForGetData(String pathForGetData) {
this.pathForGetData = pathForGetData;
return this;
}
public String getPathForGetData() {
return pathForGetData;
}

public AbstractDataServer withPathForPostInput(String pathForPostInput) {
this.pathForPostInput = pathForPostInput;
return this;
}
public String getPathForPostInput() {
return pathForPostInput;
}

protected String handleGetData(DataApi dataApi) {
logger.trace("Retrieving terminal data...");
TextTerminalData data = dataApi.getTextTerminalData();
logger.trace("Retrieved terminal data: {}", data);
return gson.toJson(data);
}

protected String handlePostInput(DataApi dataApi, String input, boolean userInterrupt) {
if(userInterrupt) {
logger.trace("Posting user interrupted input...");
dataApi.postUserInterrupt(input);
} else {
logger.trace("Posting input...");
dataApi.postUserInput(input);
}
return "OK";
}

}
32 changes: 32 additions & 0 deletions text-io-web/src/main/java/org/beryx/textio/web/DataServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.beryx.textio.web;

/**
* The interface implementetd by a web server that allows clients to access the {@link DataApi}.
*/
public interface DataServer {
public static final String DEFAULT_PATH_FOR_GET_DATA = "/textTerminalData";
public static final String DEFAULT_PATH_FOR_POST_INPUT = "/textTerminalInput";

public DataServer withPathForGetData(String pathForGetData);
public DataServer withPathForPostInput(String pathForPostInput);

public DataServer withPort(int portNumber);
public int getPort();

public void init();
}
Loading

0 comments on commit bb1dd6a

Please sign in to comment.