diff --git a/play-framework/student-api/.gitignore b/play-framework/student-api/.gitignore
new file mode 100644
index 0000000000..eb372fc719
--- /dev/null
+++ b/play-framework/student-api/.gitignore
@@ -0,0 +1,8 @@
+logs
+target
+/.idea
+/.idea_modules
+/.classpath
+/.project
+/.settings
+/RUNNING_PID
diff --git a/play-framework/student-api/LICENSE b/play-framework/student-api/LICENSE
new file mode 100644
index 0000000000..4baedcb95f
--- /dev/null
+++ b/play-framework/student-api/LICENSE
@@ -0,0 +1,8 @@
+This software is licensed under the Apache 2 license, quoted below.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project 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.
\ No newline at end of file
diff --git a/play-framework/student-api/README b/play-framework/student-api/README
new file mode 100644
index 0000000000..f21d092edf
--- /dev/null
+++ b/play-framework/student-api/README
@@ -0,0 +1,49 @@
+This is your new Play application
+=================================
+
+This file will be packaged with your application when using `activator dist`.
+
+There are several demonstration files available in this template.
+
+Controllers
+===========
+
+- HomeController.java:
+
+ Shows how to handle simple HTTP requests.
+
+- AsyncController.java:
+
+ Shows how to do asynchronous programming when handling a request.
+
+- CountController.java:
+
+ Shows how to inject a component into a controller and use the component when
+ handling requests.
+
+Components
+==========
+
+- Module.java:
+
+ Shows how to use Guice to bind all the components needed by your application.
+
+- Counter.java:
+
+ An example of a component that contains state, in this case a simple counter.
+
+- ApplicationTimer.java:
+
+ An example of a component that starts when the application starts and stops
+ when the application stops.
+
+Filters
+=======
+
+- Filters.java:
+
+ Creates the list of HTTP filters used by your application.
+
+- ExampleFilter.java
+
+ A simple filter that adds a header to every response.
\ No newline at end of file
diff --git a/play-framework/student-api/app/Filters.java b/play-framework/student-api/app/Filters.java
new file mode 100644
index 0000000000..255de8ca93
--- /dev/null
+++ b/play-framework/student-api/app/Filters.java
@@ -0,0 +1,46 @@
+import javax.inject.*;
+import play.*;
+import play.mvc.EssentialFilter;
+import play.http.HttpFilters;
+import play.mvc.*;
+
+import filters.ExampleFilter;
+
+/**
+ * This class configures filters that run on every request. This
+ * class is queried by Play to get a list of filters.
+ *
+ * Play will automatically use filters from any class called
+ * Filters that is placed the root package. You can load filters
+ * from a different class by adding a `play.http.filters` setting to
+ * the application.conf configuration file.
+ */
+@Singleton
+public class Filters implements HttpFilters {
+
+ private final Environment env;
+ private final EssentialFilter exampleFilter;
+
+ /**
+ * @param env Basic environment settings for the current application.
+ * @param exampleFilter A demonstration filter that adds a header to
+ */
+ @Inject
+ public Filters(Environment env, ExampleFilter exampleFilter) {
+ this.env = env;
+ this.exampleFilter = exampleFilter;
+ }
+
+ @Override
+ public EssentialFilter[] filters() {
+ // Use the example filter if we're running development mode. If
+ // we're running in production or test mode then don't use any
+ // filters at all.
+ if (env.mode().equals(Mode.DEV)) {
+ return new EssentialFilter[] { exampleFilter };
+ } else {
+ return new EssentialFilter[] {};
+ }
+ }
+
+}
diff --git a/play-framework/student-api/app/Module.java b/play-framework/student-api/app/Module.java
new file mode 100644
index 0000000000..6e7d1766ef
--- /dev/null
+++ b/play-framework/student-api/app/Module.java
@@ -0,0 +1,31 @@
+import com.google.inject.AbstractModule;
+import java.time.Clock;
+
+import services.ApplicationTimer;
+import services.AtomicCounter;
+import services.Counter;
+
+/**
+ * This class is a Guice module that tells Guice how to bind several
+ * different types. This Guice module is created when the Play
+ * application starts.
+ *
+ * Play will automatically use any class called `Module` that is in
+ * the root package. You can create modules in other locations by
+ * adding `play.modules.enabled` settings to the `application.conf`
+ * configuration file.
+ */
+public class Module extends AbstractModule {
+
+ @Override
+ public void configure() {
+ // Use the system clock as the default implementation of Clock
+ bind(Clock.class).toInstance(Clock.systemDefaultZone());
+ // Ask Guice to create an instance of ApplicationTimer when the
+ // application starts.
+ bind(ApplicationTimer.class).asEagerSingleton();
+ // Set AtomicCounter as the implementation for Counter.
+ bind(Counter.class).to(AtomicCounter.class);
+ }
+
+}
diff --git a/play-framework/student-api/app/controllers/AsyncController.java b/play-framework/student-api/app/controllers/AsyncController.java
new file mode 100644
index 0000000000..33cd112837
--- /dev/null
+++ b/play-framework/student-api/app/controllers/AsyncController.java
@@ -0,0 +1,60 @@
+package controllers;
+
+import akka.actor.ActorSystem;
+import javax.inject.*;
+import play.*;
+import play.mvc.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.TimeUnit;
+import scala.concurrent.duration.Duration;
+import scala.concurrent.ExecutionContextExecutor;
+
+/**
+ * This controller contains an action that demonstrates how to write
+ * simple asynchronous code in a controller. It uses a timer to
+ * asynchronously delay sending a response for 1 second.
+ *
+ * @param actorSystem We need the {@link ActorSystem}'s
+ * {@link Scheduler} to run code after a delay.
+ * @param exec We need a Java {@link Executor} to apply the result
+ * of the {@link CompletableFuture} and a Scala
+ * {@link ExecutionContext} so we can use the Akka {@link Scheduler}.
+ * An {@link ExecutionContextExecutor} implements both interfaces.
+ */
+@Singleton
+public class AsyncController extends Controller {
+
+ private final ActorSystem actorSystem;
+ private final ExecutionContextExecutor exec;
+
+ @Inject
+ public AsyncController(ActorSystem actorSystem, ExecutionContextExecutor exec) {
+ this.actorSystem = actorSystem;
+ this.exec = exec;
+ }
+
+ /**
+ * An action that returns a plain text message after a delay
+ * of 1 second.
+ *
+ * The configuration in the routes file means that this method
+ * will be called when the application receives a GET request with
+ * a path of /message.
+ */
+ public CompletionStage message() {
+ return getFutureMessage(1, TimeUnit.SECONDS).thenApplyAsync(Results::ok, exec);
+ }
+
+ private CompletionStage getFutureMessage(long time, TimeUnit timeUnit) {
+ CompletableFuture future = new CompletableFuture<>();
+ actorSystem.scheduler().scheduleOnce(
+ Duration.create(time, timeUnit),
+ () -> future.complete("Hi!"),
+ exec
+ );
+ return future;
+ }
+
+}
diff --git a/play-framework/student-api/app/controllers/CountController.java b/play-framework/student-api/app/controllers/CountController.java
new file mode 100644
index 0000000000..02fcb15f8e
--- /dev/null
+++ b/play-framework/student-api/app/controllers/CountController.java
@@ -0,0 +1,35 @@
+package controllers;
+
+import javax.inject.*;
+import play.*;
+import play.mvc.*;
+
+import services.Counter;
+
+/**
+ * This controller demonstrates how to use dependency injection to
+ * bind a component into a controller class. The class contains an
+ * action that shows an incrementing count to users. The {@link Counter}
+ * object is injected by the Guice dependency injection system.
+ */
+@Singleton
+public class CountController extends Controller {
+
+ private final Counter counter;
+
+ @Inject
+ public CountController(Counter counter) {
+ this.counter = counter;
+ }
+
+ /**
+ * An action that responds with the {@link Counter}'s current
+ * count. The result is plain text. This action is mapped to
+ * GET requests with a path of /count
+ * requests by an entry in the routes config file.
+ */
+ public Result count() {
+ return ok(Integer.toString(counter.nextCount()));
+ }
+
+}
diff --git a/play-framework/student-api/app/controllers/HomeController.java b/play-framework/student-api/app/controllers/HomeController.java
new file mode 100644
index 0000000000..6a79856eb4
--- /dev/null
+++ b/play-framework/student-api/app/controllers/HomeController.java
@@ -0,0 +1,23 @@
+package controllers;
+
+import play.mvc.*;
+
+import views.html.*;
+
+/**
+ * This controller contains an action to handle HTTP requests
+ * to the application's home page.
+ */
+public class HomeController extends Controller {
+
+ /**
+ * An action that renders an HTML page with a welcome message.
+ * The configuration in the routes file means that
+ * this method will be called when the application receives a
+ * GET request with a path of /.
+ */
+ public Result index() {
+ return ok(index.render("Your new application is ready."));
+ }
+
+}
diff --git a/play-framework/student-api/app/controllers/StudentController.java b/play-framework/student-api/app/controllers/StudentController.java
new file mode 100644
index 0000000000..0adedfa432
--- /dev/null
+++ b/play-framework/student-api/app/controllers/StudentController.java
@@ -0,0 +1,56 @@
+package controllers;
+import models.*;
+import util.*;
+import play.mvc.*;
+import play.libs.Json;
+import play.libs.Json.*;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.List;
+
+public class StudentController extends Controller {
+ public Result create() {
+ JsonNode json = request().body().asJson();
+ if(json == null)
+ return badRequest(Util.createResponse("Expecting Json data",false));
+ Student student=StudentStore.getInstance().addStudent((Student)Json.fromJson(json,Student.class));
+ JsonNode jsonObject=Json.toJson(student);
+ return created(Util.createResponse(jsonObject,true));
+ }
+ public Result update() {
+ JsonNode json = request().body().asJson();
+ if(json == null)
+ return badRequest(Util.createResponse("Expecting Json data",false));
+ Student student=StudentStore.getInstance().updateStudent((Student)Json.fromJson(json,Student.class));
+ if(student==null){
+ return notFound(Util.createResponse("Student not found",false));
+ }
+
+ JsonNode jsonObject=Json.toJson(student);
+ return ok(Util.createResponse(jsonObject,true));
+ }
+ public Result retrieve(int id) {
+ Student student=StudentStore.getInstance().getStudent(id);
+ if(student==null){
+ return notFound(Util.createResponse("Student with id:"+id+" not found",false));
+ }
+ JsonNode jsonObjects=Json.toJson(student);
+ return ok(Util.createResponse(jsonObjects,true));
+ }
+ public Result listStudents() {
+ List result=StudentStore.getInstance().getAllStudents();
+ ObjectMapper mapper = new ObjectMapper();
+
+ JsonNode jsonData=mapper.convertValue(result, JsonNode.class);
+ return ok(Util.createResponse(jsonData,true));
+
+ }
+ public Result delete(int id) {
+ boolean status=StudentStore.getInstance().deleteStudent(id);
+ if(!status){
+ return notFound(Util.createResponse("Student with id:"+id+" not found",false));
+ }
+ return ok(Util.createResponse("Student with id:"+id+" deleted",true));
+ }
+
+}
diff --git a/play-framework/student-api/app/filters/ExampleFilter.java b/play-framework/student-api/app/filters/ExampleFilter.java
new file mode 100644
index 0000000000..67a6a36cc3
--- /dev/null
+++ b/play-framework/student-api/app/filters/ExampleFilter.java
@@ -0,0 +1,45 @@
+package filters;
+
+import akka.stream.Materializer;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.function.Function;
+import javax.inject.*;
+import play.mvc.*;
+import play.mvc.Http.RequestHeader;
+
+
+/**
+ * This is a simple filter that adds a header to all requests. It's
+ * added to the application's list of filters by the
+ * {@link Filters} class.
+ */
+@Singleton
+public class ExampleFilter extends Filter {
+
+ private final Executor exec;
+
+ /**
+ * @param mat This object is needed to handle streaming of requests
+ * and responses.
+ * @param exec This class is needed to execute code asynchronously.
+ * It is used below by the thenAsyncApply method.
+ */
+ @Inject
+ public ExampleFilter(Materializer mat, Executor exec) {
+ super(mat);
+ this.exec = exec;
+ }
+
+ @Override
+ public CompletionStage apply(
+ Function> next,
+ RequestHeader requestHeader) {
+
+ return next.apply(requestHeader).thenApplyAsync(
+ result -> result.withHeader("X-ExampleFilter", "foo"),
+ exec
+ );
+ }
+
+}
diff --git a/play-framework/student-api/app/models/Student.java b/play-framework/student-api/app/models/Student.java
new file mode 100644
index 0000000000..dc539767bd
--- /dev/null
+++ b/play-framework/student-api/app/models/Student.java
@@ -0,0 +1,47 @@
+package models;
+public class Student {
+ private String firstName;
+ private String lastName;
+ private int age;
+ private int id;
+ public Student(){}
+ public Student(String firstName, String lastName, int age) {
+ super();
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.age = age;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+}
diff --git a/play-framework/student-api/app/models/StudentStore.java b/play-framework/student-api/app/models/StudentStore.java
new file mode 100644
index 0000000000..3290e141cd
--- /dev/null
+++ b/play-framework/student-api/app/models/StudentStore.java
@@ -0,0 +1,52 @@
+package models;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class StudentStore {
+ private static StudentStore instance;
+ private Map students = new HashMap<>();
+
+ public static StudentStore getInstance() {
+ if (instance == null)
+ instance = new StudentStore();
+ return instance;
+ }
+
+ public Student addStudent(Student student) {
+ int id = students.size() + 1;
+ student.setId(id);
+ students.put(id, student);
+ return student;
+ }
+
+ public Student getStudent(int id) {
+ if (students.containsKey(id))
+ return students.get(id);
+ return null;
+ }
+
+ public List getAllStudents() {
+ return new ArrayList(students.values());
+ }
+
+ public Student updateStudent(Student student) {
+ int id=student.getId();
+ if (students.containsKey(id)) {
+ student.setId(id);
+ students.put(id, student);
+ return student;
+ }
+ return null;
+ }
+
+ public boolean deleteStudent(int id) {
+
+ if (!students.containsKey(id))
+ return false;
+ students.remove(id);
+ return true;
+
+ }
+}
\ No newline at end of file
diff --git a/play-framework/student-api/app/services/ApplicationTimer.java b/play-framework/student-api/app/services/ApplicationTimer.java
new file mode 100644
index 0000000000..a951562b1d
--- /dev/null
+++ b/play-framework/student-api/app/services/ApplicationTimer.java
@@ -0,0 +1,50 @@
+package services;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.util.concurrent.CompletableFuture;
+import javax.inject.*;
+import play.Logger;
+import play.inject.ApplicationLifecycle;
+
+/**
+ * This class demonstrates how to run code when the
+ * application starts and stops. It starts a timer when the
+ * application starts. When the application stops it prints out how
+ * long the application was running for.
+ *
+ * This class is registered for Guice dependency injection in the
+ * {@link Module} class. We want the class to start when the application
+ * starts, so it is registered as an "eager singleton". See the code
+ * in the {@link Module} class to see how this happens.
+ *
+ * This class needs to run code when the server stops. It uses the
+ * application's {@link ApplicationLifecycle} to register a stop hook.
+ */
+@Singleton
+public class ApplicationTimer {
+
+ private final Clock clock;
+ private final ApplicationLifecycle appLifecycle;
+ private final Instant start;
+
+ @Inject
+ public ApplicationTimer(Clock clock, ApplicationLifecycle appLifecycle) {
+ this.clock = clock;
+ this.appLifecycle = appLifecycle;
+ // This code is called when the application starts.
+ start = clock.instant();
+ Logger.info("ApplicationTimer demo: Starting application at " + start);
+
+ // When the application starts, register a stop hook with the
+ // ApplicationLifecycle object. The code inside the stop hook will
+ // be run when the application stops.
+ appLifecycle.addStopHook(() -> {
+ Instant stop = clock.instant();
+ Long runningTime = stop.getEpochSecond() - start.getEpochSecond();
+ Logger.info("ApplicationTimer demo: Stopping application at " + clock.instant() + " after " + runningTime + "s.");
+ return CompletableFuture.completedFuture(null);
+ });
+ }
+
+}
diff --git a/play-framework/student-api/app/services/AtomicCounter.java b/play-framework/student-api/app/services/AtomicCounter.java
new file mode 100644
index 0000000000..41f741cbf7
--- /dev/null
+++ b/play-framework/student-api/app/services/AtomicCounter.java
@@ -0,0 +1,26 @@
+package services;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.inject.*;
+
+/**
+ * This class is a concrete implementation of the {@link Counter} trait.
+ * It is configured for Guice dependency injection in the {@link Module}
+ * class.
+ *
+ * This class has a {@link Singleton} annotation because we need to make
+ * sure we only use one counter per application. Without this
+ * annotation we would get a new instance every time a {@link Counter} is
+ * injected.
+ */
+@Singleton
+public class AtomicCounter implements Counter {
+
+ private final AtomicInteger atomicCounter = new AtomicInteger();
+
+ @Override
+ public int nextCount() {
+ return atomicCounter.getAndIncrement();
+ }
+
+}
diff --git a/play-framework/student-api/app/services/Counter.java b/play-framework/student-api/app/services/Counter.java
new file mode 100644
index 0000000000..dadad8b09d
--- /dev/null
+++ b/play-framework/student-api/app/services/Counter.java
@@ -0,0 +1,13 @@
+package services;
+
+/**
+ * This interface demonstrates how to create a component that is injected
+ * into a controller. The interface represents a counter that returns a
+ * incremented number each time it is called.
+ *
+ * The {@link Modules} class binds this interface to the
+ * {@link AtomicCounter} implementation.
+ */
+public interface Counter {
+ int nextCount();
+}
diff --git a/play-framework/student-api/app/util/Util.java b/play-framework/student-api/app/util/Util.java
new file mode 100644
index 0000000000..3718b50677
--- /dev/null
+++ b/play-framework/student-api/app/util/Util.java
@@ -0,0 +1,17 @@
+package util;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import play.libs.Json;
+import play.libs.Json.*;
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class Util{
+ public static ObjectNode createResponse(Object response,boolean ok){
+ ObjectNode result = Json.newObject();
+ result.put("isSuccessfull", ok);
+ if(response instanceof String)
+ result.put("body",(String)response);
+ else result.put("body",(JsonNode)response);
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/play-framework/student-api/app/views/index.scala.html b/play-framework/student-api/app/views/index.scala.html
new file mode 100644
index 0000000000..4539f5a10b
--- /dev/null
+++ b/play-framework/student-api/app/views/index.scala.html
@@ -0,0 +1,20 @@
+@*
+ * This template takes a single argument, a String containing a
+ * message to display.
+ *@
+@(message: String)
+
+@*
+ * Call the `main` template with two arguments. The first
+ * argument is a `String` with the title of the page, the second
+ * argument is an `Html` object containing the body of the page.
+ *@
+@main("Welcome to Play") {
+
+ @*
+ * Get an `Html` object by calling the built-in Play welcome
+ * template and passing a `String` message.
+ *@
+ @play20.welcome(message, style = "Java")
+
+}
diff --git a/play-framework/student-api/app/views/main.scala.html b/play-framework/student-api/app/views/main.scala.html
new file mode 100644
index 0000000000..9414f4be6e
--- /dev/null
+++ b/play-framework/student-api/app/views/main.scala.html
@@ -0,0 +1,23 @@
+@*
+ * This template is called from the `index` template. This template
+ * handles the rendering of the page header and body tags. It takes
+ * two arguments, a `String` for the title of the page and an `Html`
+ * object to insert into the body of the page.
+ *@
+@(title: String)(content: Html)
+
+
+
+
+ @* Here's where we render the page title `String`. *@
+ @title
+
+
+
+
+
+ @* And here's where we render the `Html` object containing
+ * the page content. *@
+ @content
+
+
diff --git a/play-framework/student-api/bin/activator b/play-framework/student-api/bin/activator
new file mode 100644
index 0000000000..a8b11d482f
--- /dev/null
+++ b/play-framework/student-api/bin/activator
@@ -0,0 +1,397 @@
+#!/usr/bin/env bash
+
+### ------------------------------- ###
+### Helper methods for BASH scripts ###
+### ------------------------------- ###
+
+realpath () {
+(
+ TARGET_FILE="$1"
+ FIX_CYGPATH="$2"
+
+ cd "$(dirname "$TARGET_FILE")"
+ TARGET_FILE=$(basename "$TARGET_FILE")
+
+ COUNT=0
+ while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ]
+ do
+ TARGET_FILE=$(readlink "$TARGET_FILE")
+ cd "$(dirname "$TARGET_FILE")"
+ TARGET_FILE=$(basename "$TARGET_FILE")
+ COUNT=$(($COUNT + 1))
+ done
+
+ # make sure we grab the actual windows path, instead of cygwin's path.
+ if [[ "x$FIX_CYGPATH" != "x" ]]; then
+ echo "$(cygwinpath "$(pwd -P)/$TARGET_FILE")"
+ else
+ echo "$(pwd -P)/$TARGET_FILE"
+ fi
+)
+}
+
+
+# Uses uname to detect if we're in the odd cygwin environment.
+is_cygwin() {
+ local os=$(uname -s)
+ case "$os" in
+ CYGWIN*) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
+# TODO - Use nicer bash-isms here.
+CYGWIN_FLAG=$(if is_cygwin; then echo true; else echo false; fi)
+
+
+# This can fix cygwin style /cygdrive paths so we get the
+# windows style paths.
+cygwinpath() {
+ local file="$1"
+ if [[ "$CYGWIN_FLAG" == "true" ]]; then
+ echo $(cygpath -w $file)
+ else
+ echo $file
+ fi
+}
+
+# Make something URI friendly
+make_url() {
+ url="$1"
+ local nospaces=${url// /%20}
+ if is_cygwin; then
+ echo "/${nospaces//\\//}"
+ else
+ echo "$nospaces"
+ fi
+}
+
+declare -a residual_args
+declare -a java_args
+declare -a scalac_args
+declare -a sbt_commands
+declare java_cmd=java
+declare java_version
+declare -r real_script_path="$(realpath "$0")"
+declare -r sbt_home="$(realpath "$(dirname "$(dirname "$real_script_path")")")"
+declare -r sbt_bin_dir="$(dirname "$real_script_path")"
+declare -r app_version="1.3.10"
+
+declare -r script_name=activator
+declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" )
+userhome="$HOME"
+if is_cygwin; then
+ # cygwin sets home to something f-d up, set to real windows homedir
+ userhome="$USERPROFILE"
+fi
+declare -r activator_user_home_dir="${userhome}/.activator"
+declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt"
+declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt"
+
+echoerr () {
+ echo 1>&2 "$@"
+}
+vlog () {
+ [[ $verbose || $debug ]] && echoerr "$@"
+}
+dlog () {
+ [[ $debug ]] && echoerr "$@"
+}
+
+jar_file () {
+ echo "$(cygwinpath "${sbt_home}/libexec/activator-launch-${app_version}.jar")"
+}
+
+acquire_sbt_jar () {
+ sbt_jar="$(jar_file)"
+
+ if [[ ! -f "$sbt_jar" ]]; then
+ echoerr "Could not find launcher jar: $sbt_jar"
+ exit 2
+ fi
+}
+
+execRunner () {
+ # print the arguments one to a line, quoting any containing spaces
+ [[ $verbose || $debug ]] && echo "# Executing command line:" && {
+ for arg; do
+ if printf "%s\n" "$arg" | grep -q ' '; then
+ printf "\"%s\"\n" "$arg"
+ else
+ printf "%s\n" "$arg"
+ fi
+ done
+ echo ""
+ }
+
+ # THis used to be exec, but we loose the ability to re-hook stty then
+ # for cygwin... Maybe we should flag the feature here...
+ "$@"
+}
+
+addJava () {
+ dlog "[addJava] arg = '$1'"
+ java_args=( "${java_args[@]}" "$1" )
+}
+addSbt () {
+ dlog "[addSbt] arg = '$1'"
+ sbt_commands=( "${sbt_commands[@]}" "$1" )
+}
+addResidual () {
+ dlog "[residual] arg = '$1'"
+ residual_args=( "${residual_args[@]}" "$1" )
+}
+addDebugger () {
+ addJava "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$1"
+}
+
+get_mem_opts () {
+ # if we detect any of these settings in ${JAVA_OPTS} we need to NOT output our settings.
+ # The reason is the Xms/Xmx, if they don't line up, cause errors.
+ if [[ "${JAVA_OPTS}" == *-Xmx* ]] || [[ "${JAVA_OPTS}" == *-Xms* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxPermSize* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxMetaspaceSize* ]] || [[ "${JAVA_OPTS}" == *-XX:ReservedCodeCacheSize* ]]; then
+ echo ""
+ else
+ # a ham-fisted attempt to move some memory settings in concert
+ # so they need not be messed around with individually.
+ local mem=${1:-1024}
+ local codecache=$(( $mem / 8 ))
+ (( $codecache > 128 )) || codecache=128
+ (( $codecache < 512 )) || codecache=512
+ local class_metadata_size=$(( $codecache * 2 ))
+ local class_metadata_opt=$([[ "$java_version" < "1.8" ]] && echo "MaxPermSize" || echo "MaxMetaspaceSize")
+
+ echo "-Xms${mem}m -Xmx${mem}m -XX:ReservedCodeCacheSize=${codecache}m -XX:${class_metadata_opt}=${class_metadata_size}m"
+ fi
+}
+
+require_arg () {
+ local type="$1"
+ local opt="$2"
+ local arg="$3"
+ if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then
+ echo "$opt requires <$type> argument"
+ exit 1
+ fi
+}
+
+is_function_defined() {
+ declare -f "$1" > /dev/null
+}
+
+# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter
+detect_terminal_for_ui() {
+ [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && {
+ addResidual "ui"
+ }
+ # SPECIAL TEST FOR MAC
+ [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && {
+ echo "Detected MAC OSX launched script...."
+ echo "Swapping to UI"
+ addResidual "ui"
+ }
+}
+
+process_args () {
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -h|-help) usage; exit 1 ;;
+ -v|-verbose) verbose=1 && shift ;;
+ -d|-debug) debug=1 && shift ;;
+
+ -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;;
+ -mem) require_arg integer "$1" "$2" && sbt_mem="$2" && shift 2 ;;
+ -jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;;
+ -batch) exec &1 | awk -F '"' '/version/ {print $2}')
+ vlog "[process_args] java_version = '$java_version'"
+}
+
+# Detect that we have java installed.
+checkJava() {
+ local required_version="$1"
+ # Now check to see if it's a good enough version
+ if [[ "$java_version" == "" ]]; then
+ echo
+ echo No java installations was detected.
+ echo Please go to http://www.java.com/getjava/ and download
+ echo
+ exit 1
+ elif [[ ! "$java_version" > "$required_version" ]]; then
+ echo
+ echo The java installation you have is not up to date
+ echo $script_name requires at least version $required_version+, you have
+ echo version $java_version
+ echo
+ echo Please go to http://www.java.com/getjava/ and download
+ echo a valid Java Runtime and install before running $script_name.
+ echo
+ exit 1
+ fi
+}
+
+
+run() {
+ # no jar? download it.
+ [[ -f "$sbt_jar" ]] || acquire_sbt_jar "$sbt_version" || {
+ # still no jar? uh-oh.
+ echo "Download failed. Obtain the sbt-launch.jar manually and place it at $sbt_jar"
+ exit 1
+ }
+
+ # process the combined args, then reset "$@" to the residuals
+ process_args "$@"
+ detect_terminal_for_ui
+ set -- "${residual_args[@]}"
+ argumentCount=$#
+
+ # TODO - java check should be configurable...
+ checkJava "1.6"
+
+ #If we're in cygwin, we should use the windows config, and terminal hacks
+ if [[ "$CYGWIN_FLAG" == "true" ]]; then
+ stty -icanon min 1 -echo > /dev/null 2>&1
+ addJava "-Djline.terminal=jline.UnixTerminal"
+ addJava "-Dsbt.cygwin=true"
+ fi
+
+ # run sbt
+ execRunner "$java_cmd" \
+ "-Dactivator.home=$(make_url "$sbt_home")" \
+ ${SBT_OPTS:-$default_sbt_opts} \
+ $(get_mem_opts $sbt_mem) \
+ ${JAVA_OPTS} \
+ ${java_args[@]} \
+ -jar "$sbt_jar" \
+ "${sbt_commands[@]}" \
+ "${residual_args[@]}"
+
+ exit_code=$?
+
+ # Clean up the terminal from cygwin hacks.
+ if [[ "$CYGWIN_FLAG" == "true" ]]; then
+ stty icanon echo > /dev/null 2>&1
+ fi
+ exit $exit_code
+}
+
+
+declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy"
+declare -r sbt_opts_file=".sbtopts"
+declare -r etc_sbt_opts_file="${sbt_home}/conf/sbtopts"
+declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt"
+
+usage() {
+ cat < path to global settings/plugins directory (default: ~/.sbt)
+ -sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series)
+ -ivy path to local Ivy repository (default: ~/.ivy2)
+ -mem set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem))
+ -no-share use all local caches; no sharing
+ -no-global uses global caches, but does not use global ~/.sbt directory.
+ -jvm-debug Turn on JVM debugging, open at the given port.
+ -batch Disable interactive mode
+
+ # sbt version (default: from project/build.properties if present, else latest release)
+ -sbt-version use the specified version of sbt
+ -sbt-jar use the specified jar as the sbt launcher
+ -sbt-rc use an RC version of sbt
+ -sbt-snapshot use a snapshot version of sbt
+
+ # java version (default: java from PATH, currently $(java -version 2>&1 | grep version))
+ -java-home alternate JAVA_HOME
+
+ # jvm options and output control
+ JAVA_OPTS environment variable, if unset uses "$java_opts"
+ SBT_OPTS environment variable, if unset uses "$default_sbt_opts"
+ ACTIVATOR_OPTS Environment variable, if unset uses ""
+ .sbtopts if this file exists in the current directory, it is
+ prepended to the runner args
+ /etc/sbt/sbtopts if this file exists, it is prepended to the runner args
+ -Dkey=val pass -Dkey=val directly to the java runtime
+ -J-X pass option -X directly to the java runtime
+ (-J is stripped)
+ -S-X add -X to sbt's scalacOptions (-S is stripped)
+
+In the case of duplicated or conflicting options, the order above
+shows precedence: JAVA_OPTS lowest, command line options highest.
+EOM
+}
+
+
+
+process_my_args () {
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;;
+ -no-share) addJava "$noshare_opts" && shift ;;
+ -no-global) addJava "-Dsbt.global.base=$(pwd)/project/.sbtboot" && shift ;;
+ -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;;
+ -sbt-dir) require_arg path "$1" "$2" && addJava "-Dsbt.global.base=$2" && shift 2 ;;
+ -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;;
+ -batch) exec ^&1') do (
+ if %%~j==java set JAVAINSTALLED=1
+ if %%~j==openjdk set JAVAINSTALLED=1
+)
+
+rem Detect the same thing about javac
+if "%_JAVACCMD%"=="" (
+ if not "%JAVA_HOME%"=="" (
+ if exist "%JAVA_HOME%\bin\javac.exe" set "_JAVACCMD=%JAVA_HOME%\bin\javac.exe"
+ )
+)
+if "%_JAVACCMD%"=="" set _JAVACCMD=javac
+for /F %%j in ('"%_JAVACCMD%" -version 2^>^&1') do (
+ if %%~j==javac set JAVACINSTALLED=1
+)
+
+rem BAT has no logical or, so we do it OLD SCHOOL! Oppan Redmond Style
+set JAVAOK=true
+if not defined JAVAINSTALLED set JAVAOK=false
+if not defined JAVACINSTALLED set JAVAOK=false
+
+if "%JAVAOK%"=="false" (
+ echo.
+ echo A Java JDK is not installed or can't be found.
+ if not "%JAVA_HOME%"=="" (
+ echo JAVA_HOME = "%JAVA_HOME%"
+ )
+ echo.
+ echo Please go to
+ echo http://www.oracle.com/technetwork/java/javase/downloads/index.html
+ echo and download a valid Java JDK and install before running Activator.
+ echo.
+ echo If you think this message is in error, please check
+ echo your environment variables to see if "java.exe" and "javac.exe" are
+ echo available via JAVA_HOME or PATH.
+ echo.
+ if defined DOUBLECLICKED pause
+ exit /B 1
+)
+
+rem Check what Java version is being used to determine what memory options to use
+for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do (
+ set JAVA_VERSION=%%g
+)
+
+rem Strips away the " characters
+set JAVA_VERSION=%JAVA_VERSION:"=%
+
+rem TODO Check if there are existing mem settings in JAVA_OPTS/CFG_OPTS and use those instead of the below
+for /f "delims=. tokens=1-3" %%v in ("%JAVA_VERSION%") do (
+ set MAJOR=%%v
+ set MINOR=%%w
+ set BUILD=%%x
+
+ set META_SIZE=-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M
+ if "!MINOR!" LSS "8" (
+ set META_SIZE=-XX:PermSize=64M -XX:MaxPermSize=256M
+ )
+
+ set MEM_OPTS=!META_SIZE!
+ )
+
+rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config.
+set _JAVA_OPTS=%JAVA_OPTS%
+if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS%
+
+set DEBUG_OPTS=
+
+rem Loop through the arguments, building remaining args in args variable
+set args=
+:argsloop
+if not "%~1"=="" (
+ rem Checks if the argument contains "-D" and if true, adds argument 1 with 2 and puts an equal sign between them.
+ rem This is done since batch considers "=" to be a delimiter so we need to circumvent this behavior with a small hack.
+ set arg1=%~1
+ if "!arg1:~0,2!"=="-D" (
+ set "args=%args% "%~1"="%~2""
+ shift
+ shift
+ goto argsloop
+ )
+
+ if "%~1"=="-jvm-debug" (
+ if not "%~2"=="" (
+ rem This piece of magic somehow checks that an argument is a number
+ for /F "delims=0123456789" %%i in ("%~2") do (
+ set var="%%i"
+ )
+ if defined var (
+ rem Not a number, assume no argument given and default to 9999
+ set JPDA_PORT=9999
+ ) else (
+ rem Port was given, shift arguments
+ set JPDA_PORT=%~2
+ shift
+ )
+ ) else (
+ set JPDA_PORT=9999
+ )
+ shift
+
+ set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=!JPDA_PORT!
+ goto argsloop
+ )
+ rem else
+ set "args=%args% "%~1""
+ shift
+ goto argsloop
+)
+
+:run
+
+if "!args!"=="" (
+ if defined DOUBLECLICKED (
+ set CMDS="ui"
+ ) else set CMDS=!args!
+) else set CMDS=!args!
+
+rem We add a / in front, so we get file:///C: instead of file://C:
+rem Java considers the later a UNC path.
+rem We also attempt a solid effort at making it URI friendly.
+rem We don't even bother with UNC paths.
+set JAVA_FRIENDLY_HOME_1=/!ACTIVATOR_HOME:\=/!
+set JAVA_FRIENDLY_HOME=/!JAVA_FRIENDLY_HOME_1: =%%20!
+
+rem Checks if the command contains spaces to know if it should be wrapped in quotes or not
+set NON_SPACED_CMD=%_JAVACMD: =%
+if "%_JAVACMD%"=="%NON_SPACED_CMD%" %_JAVACMD% %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS%
+if NOT "%_JAVACMD%"=="%NON_SPACED_CMD%" "%_JAVACMD%" %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS%
+
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+
+@endlocal
+
+exit /B %ERROR_CODE%
diff --git a/play-framework/student-api/build.sbt b/play-framework/student-api/build.sbt
new file mode 100644
index 0000000000..0f5ea736f6
--- /dev/null
+++ b/play-framework/student-api/build.sbt
@@ -0,0 +1,13 @@
+name := """student-api"""
+
+version := "1.0-SNAPSHOT"
+
+lazy val root = (project in file(".")).enablePlugins(PlayJava)
+
+scalaVersion := "2.11.7"
+
+libraryDependencies ++= Seq(
+ javaJdbc,
+ cache,
+ javaWs
+)
diff --git a/play-framework/student-api/conf/application.conf b/play-framework/student-api/conf/application.conf
new file mode 100644
index 0000000000..489d3f9b3e
--- /dev/null
+++ b/play-framework/student-api/conf/application.conf
@@ -0,0 +1,353 @@
+# This is the main configuration file for the application.
+# https://www.playframework.com/documentation/latest/ConfigFile
+# ~~~~~
+# Play uses HOCON as its configuration file format. HOCON has a number
+# of advantages over other config formats, but there are two things that
+# can be used when modifying settings.
+#
+# You can include other configuration files in this main application.conf file:
+#include "extra-config.conf"
+#
+# You can declare variables and substitute for them:
+#mykey = ${some.value}
+#
+# And if an environment variable exists when there is no other subsitution, then
+# HOCON will fall back to substituting environment variable:
+#mykey = ${JAVA_HOME}
+
+## Akka
+# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
+# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
+# ~~~~~
+# Play uses Akka internally and exposes Akka Streams and actors in Websockets and
+# other streaming HTTP responses.
+akka {
+ # "akka.log-config-on-start" is extraordinarly useful because it log the complete
+ # configuration at INFO level, including defaults and overrides, so it s worth
+ # putting at the very top.
+ #
+ # Put the following in your conf/logback.xml file:
+ #
+ #
+ #
+ # And then uncomment this line to debug the configuration.
+ #
+ #log-config-on-start = true
+}
+
+## Secret key
+# http://www.playframework.com/documentation/latest/ApplicationSecret
+# ~~~~~
+# The secret key is used to sign Play's session cookie.
+# This must be changed for production, but we don't recommend you change it in this file.
+play.crypto.secret = "changeme"
+
+## Modules
+# https://www.playframework.com/documentation/latest/Modules
+# ~~~~~
+# Control which modules are loaded when Play starts. Note that modules are
+# the replacement for "GlobalSettings", which are deprecated in 2.5.x.
+# Please see https://www.playframework.com/documentation/latest/GlobalSettings
+# for more information.
+#
+# You can also extend Play functionality by using one of the publically available
+# Play modules: https://playframework.com/documentation/latest/ModuleDirectory
+play.modules {
+ # By default, Play will load any class called Module that is defined
+ # in the root package (the "app" directory), or you can define them
+ # explicitly below.
+ # If there are any built-in modules that you want to disable, you can list them here.
+ #enabled += my.application.Module
+
+ # If there are any built-in modules that you want to disable, you can list them here.
+ #disabled += ""
+}
+
+## IDE
+# https://www.playframework.com/documentation/latest/IDE
+# ~~~~~
+# Depending on your IDE, you can add a hyperlink for errors that will jump you
+# directly to the code location in the IDE in dev mode. The following line makes
+# use of the IntelliJ IDEA REST interface:
+#play.editor="http://localhost:63342/api/file/?file=%s&line=%s"
+
+## Internationalisation
+# https://www.playframework.com/documentation/latest/JavaI18N
+# https://www.playframework.com/documentation/latest/ScalaI18N
+# ~~~~~
+# Play comes with its own i18n settings, which allow the user's preferred language
+# to map through to internal messages, or allow the language to be stored in a cookie.
+play.i18n {
+ # The application languages
+ langs = [ "en" ]
+
+ # Whether the language cookie should be secure or not
+ #langCookieSecure = true
+
+ # Whether the HTTP only attribute of the cookie should be set to true
+ #langCookieHttpOnly = true
+}
+
+## Play HTTP settings
+# ~~~~~
+play.http {
+ ## Router
+ # https://www.playframework.com/documentation/latest/JavaRouting
+ # https://www.playframework.com/documentation/latest/ScalaRouting
+ # ~~~~~
+ # Define the Router object to use for this application.
+ # This router will be looked up first when the application is starting up,
+ # so make sure this is the entry point.
+ # Furthermore, it's assumed your route file is named properly.
+ # So for an application router like `my.application.Router`,
+ # you may need to define a router file `conf/my.application.routes`.
+ # Default to Routes in the root package (aka "apps" folder) (and conf/routes)
+ #router = my.application.Router
+
+ ## Action Creator
+ # https://www.playframework.com/documentation/latest/JavaActionCreator
+ # ~~~~~
+ #actionCreator = null
+
+ ## ErrorHandler
+ # https://www.playframework.com/documentation/latest/JavaRouting
+ # https://www.playframework.com/documentation/latest/ScalaRouting
+ # ~~~~~
+ # If null, will attempt to load a class called ErrorHandler in the root package,
+ #errorHandler = null
+
+ ## Filters
+ # https://www.playframework.com/documentation/latest/ScalaHttpFilters
+ # https://www.playframework.com/documentation/latest/JavaHttpFilters
+ # ~~~~~
+ # Filters run code on every request. They can be used to perform
+ # common logic for all your actions, e.g. adding common headers.
+ # Defaults to "Filters" in the root package (aka "apps" folder)
+ # Alternatively you can explicitly register a class here.
+ #filters = my.application.Filters
+
+ ## Session & Flash
+ # https://www.playframework.com/documentation/latest/JavaSessionFlash
+ # https://www.playframework.com/documentation/latest/ScalaSessionFlash
+ # ~~~~~
+ session {
+ # Sets the cookie to be sent only over HTTPS.
+ #secure = true
+
+ # Sets the cookie to be accessed only by the server.
+ #httpOnly = true
+
+ # Sets the max-age field of the cookie to 5 minutes.
+ # NOTE: this only sets when the browser will discard the cookie. Play will consider any
+ # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout,
+ # you need to put a timestamp in the session and check it at regular intervals to possibly expire it.
+ #maxAge = 300
+
+ # Sets the domain on the session cookie.
+ #domain = "example.com"
+ }
+
+ flash {
+ # Sets the cookie to be sent only over HTTPS.
+ #secure = true
+
+ # Sets the cookie to be accessed only by the server.
+ #httpOnly = true
+ }
+}
+
+## Netty Provider
+# https://www.playframework.com/documentation/latest/SettingsNetty
+# ~~~~~
+play.server.netty {
+ # Whether the Netty wire should be logged
+ #log.wire = true
+
+ # If you run Play on Linux, you can use Netty's native socket transport
+ # for higher performance with less garbage.
+ #transport = "native"
+}
+
+## WS (HTTP Client)
+# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS
+# ~~~~~
+# The HTTP client primarily used for REST APIs. The default client can be
+# configured directly, but you can also create different client instances
+# with customized settings. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += ws // or javaWs if using java
+#
+play.ws {
+ # Sets HTTP requests not to follow 302 requests
+ #followRedirects = false
+
+ # Sets the maximum number of open HTTP connections for the client.
+ #ahc.maxConnectionsTotal = 50
+
+ ## WS SSL
+ # https://www.playframework.com/documentation/latest/WsSSL
+ # ~~~~~
+ ssl {
+ # Configuring HTTPS with Play WS does not require programming. You can
+ # set up both trustManager and keyManager for mutual authentication, and
+ # turn on JSSE debugging in development with a reload.
+ #debug.handshake = true
+ #trustManager = {
+ # stores = [
+ # { type = "JKS", path = "exampletrust.jks" }
+ # ]
+ #}
+ }
+}
+
+## Cache
+# https://www.playframework.com/documentation/latest/JavaCache
+# https://www.playframework.com/documentation/latest/ScalaCache
+# ~~~~~
+# Play comes with an integrated cache API that can reduce the operational
+# overhead of repeated requests. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += cache
+#
+play.cache {
+ # If you want to bind several caches, you can bind the individually
+ #bindCaches = ["db-cache", "user-cache", "session-cache"]
+}
+
+## Filters
+# https://www.playframework.com/documentation/latest/Filters
+# ~~~~~
+# There are a number of built-in filters that can be enabled and configured
+# to give Play greater security. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += filters
+#
+play.filters {
+ ## CORS filter configuration
+ # https://www.playframework.com/documentation/latest/CorsFilter
+ # ~~~~~
+ # CORS is a protocol that allows web applications to make requests from the browser
+ # across different domains.
+ # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has
+ # dependencies on CORS settings.
+ cors {
+ # Filter paths by a whitelist of path prefixes
+ #pathPrefixes = ["/some/path", ...]
+
+ # The allowed origins. If null, all origins are allowed.
+ #allowedOrigins = ["http://www.example.com"]
+
+ # The allowed HTTP methods. If null, all methods are allowed
+ #allowedHttpMethods = ["GET", "POST"]
+ }
+
+ ## CSRF Filter
+ # https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter
+ # https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter
+ # ~~~~~
+ # Play supports multiple methods for verifying that a request is not a CSRF request.
+ # The primary mechanism is a CSRF token. This token gets placed either in the query string
+ # or body of every form submitted, and also gets placed in the users session.
+ # Play then verifies that both tokens are present and match.
+ csrf {
+ # Sets the cookie to be sent only over HTTPS
+ #cookie.secure = true
+
+ # Defaults to CSRFErrorHandler in the root package.
+ #errorHandler = MyCSRFErrorHandler
+ }
+
+ ## Security headers filter configuration
+ # https://www.playframework.com/documentation/latest/SecurityHeaders
+ # ~~~~~
+ # Defines security headers that prevent XSS attacks.
+ # If enabled, then all options are set to the below configuration by default:
+ headers {
+ # The X-Frame-Options header. If null, the header is not set.
+ #frameOptions = "DENY"
+
+ # The X-XSS-Protection header. If null, the header is not set.
+ #xssProtection = "1; mode=block"
+
+ # The X-Content-Type-Options header. If null, the header is not set.
+ #contentTypeOptions = "nosniff"
+
+ # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
+ #permittedCrossDomainPolicies = "master-only"
+
+ # The Content-Security-Policy header. If null, the header is not set.
+ #contentSecurityPolicy = "default-src 'self'"
+ }
+
+ ## Allowed hosts filter configuration
+ # https://www.playframework.com/documentation/latest/AllowedHostsFilter
+ # ~~~~~
+ # Play provides a filter that lets you configure which hosts can access your application.
+ # This is useful to prevent cache poisoning attacks.
+ hosts {
+ # Allow requests to example.com, its subdomains, and localhost:9000.
+ #allowed = [".example.com", "localhost:9000"]
+ }
+}
+
+## Evolutions
+# https://www.playframework.com/documentation/latest/Evolutions
+# ~~~~~
+# Evolutions allows database scripts to be automatically run on startup in dev mode
+# for database migrations. You must enable this by adding to build.sbt:
+#
+# libraryDependencies += evolutions
+#
+play.evolutions {
+ # You can disable evolutions for a specific datasource if necessary
+ #db.default.enabled = false
+}
+
+## Database Connection Pool
+# https://www.playframework.com/documentation/latest/SettingsJDBC
+# ~~~~~
+# Play doesn't require a JDBC database to run, but you can easily enable one.
+#
+# libraryDependencies += jdbc
+#
+play.db {
+ # The combination of these two settings results in "db.default" as the
+ # default JDBC pool:
+ #config = "db"
+ #default = "default"
+
+ # Play uses HikariCP as the default connection pool. You can override
+ # settings by changing the prototype:
+ prototype {
+ # Sets a fixed JDBC connection pool size of 50
+ #hikaricp.minimumIdle = 50
+ #hikaricp.maximumPoolSize = 50
+ }
+}
+
+## JDBC Datasource
+# https://www.playframework.com/documentation/latest/JavaDatabase
+# https://www.playframework.com/documentation/latest/ScalaDatabase
+# ~~~~~
+# Once JDBC datasource is set up, you can work with several different
+# database options:
+#
+# Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick
+# JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA
+# EBean: https://playframework.com/documentation/latest/JavaEbean
+# Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm
+#
+db {
+ # You can declare as many datasources as you want.
+ # By convention, the default datasource is named `default`
+
+ # https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database
+ #default.driver = org.h2.Driver
+ #default.url = "jdbc:h2:mem:play"
+ #default.username = sa
+ #default.password = ""
+
+ # You can turn on SQL logging for any datasource
+ # https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements
+ #default.logSql=true
+}
diff --git a/play-framework/student-api/conf/logback.xml b/play-framework/student-api/conf/logback.xml
new file mode 100644
index 0000000000..86ec12c0af
--- /dev/null
+++ b/play-framework/student-api/conf/logback.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ ${application.home:-.}/logs/application.log
+
+ %date [%level] from %logger in %thread - %message%n%xException
+
+
+
+
+
+ %coloredLevel %logger{15} - %message%n%xException{10}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/play-framework/student-api/conf/routes b/play-framework/student-api/conf/routes
new file mode 100644
index 0000000000..ab55792683
--- /dev/null
+++ b/play-framework/student-api/conf/routes
@@ -0,0 +1,12 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+
+GET / controllers.StudentController.listStudents()
+POST /:id controllers.StudentController.retrieve(id:Int)
+POST / controllers.StudentController.create()
+PUT / controllers.StudentController.update()
+DELETE /:id controllers.StudentController.delete(id:Int)
+
+# Map static resources from the /public folder to the /assets URL path
+GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
diff --git a/play-framework/student-api/libexec/activator-launch-1.3.10.jar b/play-framework/student-api/libexec/activator-launch-1.3.10.jar
new file mode 100644
index 0000000000..69050e7dec
Binary files /dev/null and b/play-framework/student-api/libexec/activator-launch-1.3.10.jar differ
diff --git a/play-framework/student-api/project/build.properties b/play-framework/student-api/project/build.properties
new file mode 100644
index 0000000000..6d9fa6badb
--- /dev/null
+++ b/play-framework/student-api/project/build.properties
@@ -0,0 +1,4 @@
+#Activator-generated Properties
+#Wed Sep 07 12:29:40 EAT 2016
+template.uuid=c373963b-f5ad-433b-8e74-178e7ae25b1c
+sbt.version=0.13.11
diff --git a/play-framework/student-api/project/plugins.sbt b/play-framework/student-api/project/plugins.sbt
new file mode 100644
index 0000000000..51c5b2a35a
--- /dev/null
+++ b/play-framework/student-api/project/plugins.sbt
@@ -0,0 +1,21 @@
+// The Play plugin
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.6")
+
+// Web plugins
+addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")
+addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0")
+addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.3")
+addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.7")
+addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0")
+addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0")
+addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.2")
+
+// Play enhancer - this automatically generates getters/setters for public fields
+// and rewrites accessors of these fields to use the getters/setters. Remove this
+// plugin if you prefer not to have this feature, or disable on a per project
+// basis using disablePlugins(PlayEnhancer) in your build.sbt
+addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0")
+
+// Play Ebean support, to enable, uncomment this line, and enable in your build.sbt using
+// enablePlugins(PlayEbean).
+// addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "1.0.0")
diff --git a/play-framework/student-api/public/images/favicon.png b/play-framework/student-api/public/images/favicon.png
new file mode 100644
index 0000000000..c7d92d2ae4
Binary files /dev/null and b/play-framework/student-api/public/images/favicon.png differ
diff --git a/play-framework/student-api/public/javascripts/hello.js b/play-framework/student-api/public/javascripts/hello.js
new file mode 100644
index 0000000000..02ee13c7ca
--- /dev/null
+++ b/play-framework/student-api/public/javascripts/hello.js
@@ -0,0 +1,3 @@
+if (window.console) {
+ console.log("Welcome to your Play application's JavaScript!");
+}
diff --git a/play-framework/student-api/public/stylesheets/main.css b/play-framework/student-api/public/stylesheets/main.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/play-framework/student-api/test/ApplicationTest.java b/play-framework/student-api/test/ApplicationTest.java
new file mode 100644
index 0000000000..3d7c4875aa
--- /dev/null
+++ b/play-framework/student-api/test/ApplicationTest.java
@@ -0,0 +1,45 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.*;
+
+import play.mvc.*;
+import play.test.*;
+import play.data.DynamicForm;
+import play.data.validation.ValidationError;
+import play.data.validation.Constraints.RequiredValidator;
+import play.i18n.Lang;
+import play.libs.F;
+import play.libs.F.*;
+import play.twirl.api.Content;
+
+import static play.test.Helpers.*;
+import static org.junit.Assert.*;
+
+
+/**
+ *
+ * Simple (JUnit) tests that can call all parts of a play app.
+ * If you are interested in mocking a whole application, see the wiki for more details.
+ *
+ */
+public class ApplicationTest {
+
+ @Test
+ public void simpleCheck() {
+ int a = 1 + 1;
+ assertEquals(2, a);
+ }
+
+ @Test
+ public void renderTemplate() {
+ Content html = views.html.index.render("Your new application is ready.");
+ assertEquals("text/html", html.contentType());
+ assertTrue(html.body().contains("Your new application is ready."));
+ }
+
+
+}
diff --git a/play-framework/student-api/test/IntegrationTest.java b/play-framework/student-api/test/IntegrationTest.java
new file mode 100644
index 0000000000..c53c71e124
--- /dev/null
+++ b/play-framework/student-api/test/IntegrationTest.java
@@ -0,0 +1,25 @@
+import org.junit.*;
+
+import play.mvc.*;
+import play.test.*;
+
+import static play.test.Helpers.*;
+import static org.junit.Assert.*;
+
+import static org.fluentlenium.core.filter.FilterConstructor.*;
+
+public class IntegrationTest {
+
+ /**
+ * add your integration test here
+ * in this example we just check if the welcome page is being shown
+ */
+ @Test
+ public void test() {
+ running(testServer(3333, fakeApplication(inMemoryDatabase())), HTMLUNIT, browser -> {
+ browser.goTo("http://localhost:3333");
+ assertTrue(browser.pageSource().contains("Your new application is ready."));
+ });
+ }
+
+}