diff --git a/application/pom.xml b/application/pom.xml new file mode 100644 index 0000000..1a126b2 --- /dev/null +++ b/application/pom.xml @@ -0,0 +1,84 @@ + + 4.0.0 + + org.jeudego.pairgoth + engine-parent + 1.0-SNAPSHOT + + application + pom + + UTF-8 + ${project.build.directory}/servermanifest + + + + ${project.groupId} + webapp + ${project.version} + war + + + ${project.groupId} + bootstrap + ${project.version} + + + ${project.groupId} + container + ${project.version} + + + + pairgoth-engine + + + org.apache.maven.plugins + maven-dependency-plugin + + + use-server-manifest + prepare-package + + unpack + + + + + ${project.groupId} + bootstrap + ${project.version} + ${serverManifestDirectory} + META-INF/MANIFEST.MF + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + build-livewar + package + + single + + + false + + src/assembly/livewar.xml + + + ${serverManifestDirectory}/META-INF/MANIFEST.MF + + + + + + + + diff --git a/application/src/assembly/livewar.xml b/application/src/assembly/livewar.xml new file mode 100644 index 0000000..58f0085 --- /dev/null +++ b/application/src/assembly/livewar.xml @@ -0,0 +1,29 @@ + + live-war + / + + war + + + + /WEB-INF/jetty-server/ + true + false + + ${project.groupId}:container + + + + / + true + false + + ${project.groupId}:webapp + ${project.groupId}:bootstrap + + + + + diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml new file mode 100644 index 0000000..70ff372 --- /dev/null +++ b/bootstrap/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + org.jeudego.pairgoth + engine-parent + 1.0-SNAPSHOT + + bootstrap + jar + Simple Bootstrap for the Server UberJar (when packaged in a WAR) + + UTF-8 + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + jetty.bootstrap.JettyBootstrap + + + + + + + diff --git a/bootstrap/src/main/java/jetty/bootstrap/JettyBootstrap.java b/bootstrap/src/main/java/jetty/bootstrap/JettyBootstrap.java new file mode 100644 index 0000000..2f7d2d2 --- /dev/null +++ b/bootstrap/src/main/java/jetty/bootstrap/JettyBootstrap.java @@ -0,0 +1,55 @@ +// +// ======================================================================== +// Copyright (c) Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package jetty.bootstrap; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; + +public class JettyBootstrap +{ + public static void main(String[] args) + { + try + { + URL warLocation = JettyBootstrap.class.getProtectionDomain().getCodeSource().getLocation(); + if (warLocation == null) + { + throw new IOException("JettyBootstrap not discoverable"); + } + + LiveWarClassLoader clWar = new LiveWarClassLoader(warLocation); + System.err.println("Using ClassLoader: " + clWar); + Thread.currentThread().setContextClassLoader(clWar); + + File warFile = new File(warLocation.toURI()); + System.setProperty("org.eclipse.jetty.livewar.LOCATION",warFile.toPath().toRealPath().toString()); + + Class mainClass = Class.forName("org.jeudego.pairgoth.container.ServerMain",false,clWar); + Method mainMethod = mainClass.getMethod("main",args.getClass()); + mainMethod.invoke(mainClass,new Object[] { args }); + } + catch (Throwable t) + { + t.printStackTrace(System.err); + System.exit(-1); + } + } +} diff --git a/bootstrap/src/main/java/jetty/bootstrap/LiveWarClassLoader.java b/bootstrap/src/main/java/jetty/bootstrap/LiveWarClassLoader.java new file mode 100644 index 0000000..6499bc4 --- /dev/null +++ b/bootstrap/src/main/java/jetty/bootstrap/LiveWarClassLoader.java @@ -0,0 +1,171 @@ +// +// ======================================================================== +// Copyright (c) Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package jetty.bootstrap; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +public class LiveWarClassLoader extends ClassLoader implements Closeable +{ + private static final String ID = LiveWarClassLoader.class.getSimpleName(); + private static final boolean DEBUG = Boolean.getBoolean("jetty.bootstrap.debug"); + private static final String CLASSES_BASE = "WEB-INF/jetty-server/"; + private final URI warFileUri; + private JarFile warFile; + + public LiveWarClassLoader(URL warFileUrl) throws URISyntaxException, IOException + { + this.warFileUri = warFileUrl.toURI(); + this.warFile = new JarFile(new File(warFileUri)); + } + + public void close() throws IOException + { + warFile.close(); + } + + private void debug(String format, Object... args) + { + if (DEBUG) + { + System.err.printf('[' + ID + "] " + format + "%n",args); + } + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException + { + debug("findClass: %s",name); + String path = name.replace('.','/').concat(".class"); + ZipEntry entry = findEntry(path); + if (entry != null) + { + try + { + return loadClass(name,entry); + } + catch (IOException e) + { + throw new ClassNotFoundException(name,e); + } + } + else + { + throw new ClassNotFoundException(name); + } + } + + private ZipEntry findEntry(String name) + { + StringBuilder path = new StringBuilder(); + path.append(CLASSES_BASE); + if (name.charAt(0) == '/') + { + path.append(name.substring(1)); + } + else + { + path.append(name); + } + ZipEntry entry = warFile.getEntry(path.toString()); + debug("findEntry(%s) %s => %s",name,path,entry); + return entry; + } + + @Override + protected URL findResource(String name) + { + debug("findResource: %s",name); + ZipEntry entry = findEntry(name); + if (entry != null) + { + try + { + return URI.create("jar:" + this.warFileUri.toASCIIString() + "!/" + entry.getName()).toURL(); + } + catch (MalformedURLException e) + { + e.printStackTrace(System.err); + return null; + } + } + return null; + } + + @Override + protected Enumeration findResources(String name) throws IOException + { + debug("findResources: %s",name); + List urls = new ArrayList<>(); + URL self = findResource(name); + if (self != null) + { + urls.add(self); + } + + if (getParent() != null) + { + Enumeration parent = getParent().getResources(name); + while (parent.hasMoreElements()) + { + urls.add(parent.nextElement()); + } + } + + return Collections.enumeration(urls); + } + + private Class loadClass(String name, ZipEntry entry) throws IOException + { + try (InputStream in = warFile.getInputStream(entry); ByteArrayOutputStream out = new ByteArrayOutputStream()) + { + int len = 0; + int bufferSize = 4096; + byte[] buffer = new byte[bufferSize]; + while (true) + { + len = in.read(buffer,0,bufferSize); + if (len < 0) + break; + out.write(buffer,0,len); + } + byte[] classBytes = out.toByteArray(); + return defineClass(name,classBytes,0,classBytes.length); + } + } + + @Override + public String toString() + { + return String.format("%s[%s]",this.getClass().getName(),this.warFileUri); + } +} diff --git a/container/pom.xml b/container/pom.xml new file mode 100644 index 0000000..3bdf876 --- /dev/null +++ b/container/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + + org.jeudego.pairgoth + engine-parent + 1.0-SNAPSHOT + + container + jar + Creates a UberJar consisting of all classes needed to start Jetty + + UTF-8 + + + + org.eclipse.jetty + jetty-webapp + ${jetty.version} + + + org.eclipse.jetty + jetty-annotations + ${jetty.version} + + + org.eclipse.jetty.websocket + websocket-javax-server + ${jetty.version} + + + org.eclipse.jetty + jetty-slf4j-impl + ${jetty.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + rebuild-war + package + + shade + + + false + + + *:* + + + + + *:* + + META-INF/MANIFEST.MF + META-INF/VERSION.txt + + + + + + + + + + + + + diff --git a/container/src/main/java/org/jeudego/pairgoth/container/ServerMain.java b/container/src/main/java/org/jeudego/pairgoth/container/ServerMain.java new file mode 100644 index 0000000..4ff8536 --- /dev/null +++ b/container/src/main/java/org/jeudego/pairgoth/container/ServerMain.java @@ -0,0 +1,108 @@ +// +// ======================================================================== +// Copyright (c) Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.jeudego.pairgoth.container; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.resource.PathResource; +import org.eclipse.jetty.webapp.WebAppContext; + +public class ServerMain +{ + enum OperationalMode + { + DEV, + PROD + } + + private Path basePath; + + public static void main(String[] args) + { + try + { + new ServerMain().run(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + private void run() throws Throwable + { + Server server = new Server(8080); + + WebAppContext context = new WebAppContext(); + context.setContextPath("/"); + + switch (getOperationalMode()) + { + case PROD: + // Configure as WAR + context.setWar(basePath.toString()); + break; + case DEV: + // Configuring from Development Base + context.setBaseResource(new PathResource(basePath.resolve("src/main/webapp"))); + // Add webapp compiled classes & resources (copied into place from src/main/resources) + Path classesPath = basePath.resolve("target/webapp/WEB-INF/classes"); + context.setExtraClasspath(classesPath.toAbsolutePath().toString()); + server.setDumpAfterStart(true); + break; + default: + throw new FileNotFoundException("Unable to configure WebAppContext base resource undefined"); + } + + server.setHandler(context); + + server.start(); + server.join(); + } + + private OperationalMode getOperationalMode() throws IOException + { + // Property set by jetty.bootstrap.JettyBootstrap + String warLocation = System.getProperty("org.eclipse.jetty.livewar.LOCATION"); + if (warLocation != null) + { + Path warPath = new File(warLocation).toPath().toRealPath(); + if (Files.exists(warPath) && Files.isRegularFile(warPath)) + { + this.basePath = warPath; + return OperationalMode.PROD; + } + } + + // We are in development mode, likely building and testing from an IDE. + Path devPath = new File("../webapp").toPath().toRealPath(); + if (Files.exists(devPath) && Files.isDirectory(devPath)) + { + this.basePath = devPath; + return OperationalMode.DEV; + } + + return null; + } +} diff --git a/container/src/main/resources/jetty-logging.properties b/container/src/main/resources/jetty-logging.properties new file mode 100644 index 0000000..f82758f --- /dev/null +++ b/container/src/main/resources/jetty-logging.properties @@ -0,0 +1,8 @@ +org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +org.eclipse.jetty.LEVEL=INFO + +# Squelch noisy logging +org.eclipse.jetty.websocket.jsr356.JsrBasicRemote.LEVEL=WARN + +# org.eclipse.jetty.annotations.LEVEL=DEBUG +# org.eclipse.jetty.websocket.LEVEL=DEBUG diff --git a/pom.xml b/pom.xml index 6763352..c20849e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,474 +1,151 @@ - - 4.0.0 - org.jeudego - pairgoth - 1.0-SNAPSHOT + + 4.0.0 - war - ${project.groupId}:${project.artifactId} - PairGoth pairing system - TODO - - UTF-8 - UTF-8 - 4.13.2 - 1.7.36 - 3.1.0 - 1.8.21 - official - 10 - true - 5.7.1 - 10.0.12 - ${project.build.directory}/${project.build.finalName}/WEB-INF/jetty - 8080 - - - - pairgoth - - true - - - /var/lib/pairgoth/pairgoth.properties - - - - - package - src/main/kotlin - src/test/kotlin - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.1.0 - - - enforce-maven - - enforce - - - - - 3.6.3 - - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M7 - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.0.0-M7 - - - run-tests - integration-test - - integration-test - verify - - - - - - **/Test* - - false - - ${project.build.testOutputDirectory} - dev - - - - project.version - ${project.version} - - - project.dir - ${project.basedir} - - - build.dir - ${project.build.directory} - - - test.resources.dir - ${project.build.testOutputDirectory} - - - test.run.dir - ${project.build.directory}/run - - - test.result.dir - ${project.build.directory}/results - - - org.slf4j.simpleLogger.defaultLogLevel - debug - - - org.slf4j.simpleLogger.log.com.icegreen.greenmail.util.LineLoggingBuffer - info - - - - - - - - org.codehaus.mojo - properties-maven-plugin - 1.0.0 - - - initialize - - read-project-properties - - - - ${webapp.properties} - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.2 - - - - true - ./ - com.performance.easyedi.MainKt - - - - - - org.apache.maven.plugins - maven-resources-plugin - - 2.7 - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 10 - 10 - - - - org.apache.maven.plugins - maven-war-plugin - 3.2.2 - - true - - - ${basedir}/src/main/config - true - WEB-INF - - webapp.properties - web.xml - tools.xml - - - - ${basedir}/src/main/config/jetty - true - WEB-INF/jetty - - - - - - default-war - none - - - war-exploded - - - exploded - - - - - - org.codehaus.mojo - templating-maven-plugin - 1.0.0 - - - filter-src - - filter-test-sources - - - - - - org.eclipse.jetty - jetty-maven-plugin - ${jetty.version} - - 3 - - ${jetty.files}/jetty-http.xml,${jetty.files}/jetty-env.xml - 9966 - STOP - - - - start-jetty - pre-integration-test - - start - - - - stop-jetty - post-integration-test - - stop - - - - - - org.eclipse.jetty.http2 - http2-server - ${jetty.version} - - - - - - - - - org.jetbrains.kotlin - kotlin-test-junit5 - ${kotlin.version} - test - - - org.junit.jupiter - junit-jupiter-engine - 5.6.0 - test - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-reflect - ${kotlin.version} - - - org.jetbrains.kotlinx - kotlinx-datetime-jvm - 0.3.3 - - - - javax.servlet - javax.servlet-api - ${servlet.version} - provided - - - com.sun.mail - jakarta.mail - 1.6.5 - - - - org.pac4j - pac4j-oauth - ${pac4j.version} - - - - io.github.microutils - kotlin-logging-jvm - 2.1.23 - - - org.slf4j - slf4j-api - ${slf4j.version} - - - com.republicate - webapp-slf4j-logger - 1.6 - runtime - - - org.slf4j - jcl-over-slf4j - ${slf4j.version} - - - com.diogonunes - JColor - 5.0.1 - - - - com.republicate - simple-mailer - 1.6 - - - - com.republicate.kson - essential-kson-jvm - 2.3 - - - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpmime - 4.5.13 - - - commons-io - commons-io - 2.11.0 - - - commons-net - commons-net - 3.8.0 - - - - org.apache.poi - poi - 5.2.2 - - - org.apache.poi - poi-ooxml - 5.2.2 - - - - org.apache.pdfbox - pdfbox - 2.0.28 - - - - com.icegreen - greenmail - 1.6.12 - test - - - junit - junit - - - javax.activation - activation - - - com.sun.mail - javax.mail - - - - + org.jeudego.pairgoth + engine-parent + 1.0-SNAPSHOT + pom + + + UTF-8 + 11 + 11 + + 3.5.0 + 3.2.0 + 3.11.0 + 3.5.0 + 3.1.1 + 3.3.0 + 3.1.1 + 3.3.0 + 3.5.0 + 3.3.1 + 3.4.1 + 3.2.1 + 3.0.0 + 3.3.2 + 4.2 + + 4.0.4 + 1.1.2 + 10.0.15 + 2.0.0-alpha3 + + + + webapp + container + bootstrap + application + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + org.apache.maven.plugins + maven-clean-plugin + ${maven.clean.plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven.dependency.plugin.version} + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven.deploy.plugin.version} + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven.enforcer.plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven.install.plugin.version} + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + org.apache.maven.plugins + maven-resources-plugin + ${maven.resources.plugin.version} + + + org.apache.maven.plugins + maven-shade-plugin + ${maven.shade.plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + com.mycila + license-maven-plugin + ${license.plugin.version} + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-java + + enforce + + + + + [3.0.0,) + + + [11,) + [ERROR] OLD JDK [${java.version}] in use. This project requires JDK 11 or newer + + + + + + + + diff --git a/webapp/pom.xml b/webapp/pom.xml new file mode 100644 index 0000000..e22c852 --- /dev/null +++ b/webapp/pom.xml @@ -0,0 +1,204 @@ + + + 4.0.0 + + + org.jeudego.pairgoth + engine-parent + 1.0-SNAPSHOT + + webapp + + war + ${project.groupId}:${project.artifactId} + PairGoth pairing system + TODO + + 1.8.21 + official + 10 + true + 5.7.1 + + + package + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + + + + + org.jetbrains.kotlin + kotlin-test-junit5 + ${kotlin.version} + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + + + org.jetbrains.kotlinx + kotlinx-datetime-jvm + 0.3.3 + + + + jakarta.servlet + jakarta.servlet-api + ${servlet.api.version} + provided + + + com.sun.mail + jakarta.mail + 1.6.5 + + + + org.pac4j + pac4j-oauth + ${pac4j.version} + + + + io.github.microutils + kotlin-logging-jvm + 2.1.23 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + com.republicate + webapp-slf4j-logger + 1.6 + runtime + + + + com.diogonunes + JColor + 5.0.1 + + + + com.republicate + simple-mailer + 1.6 + + + + com.republicate.kson + essential-kson-jvm + 2.3 + + + + + + org.apache.pdfbox + pdfbox + 2.0.28 + + + + com.icegreen + greenmail + 1.6.12 + test + + + junit + junit + + + javax.activation + activation + + + com.sun.mail + javax.mail + + + + + diff --git a/src/main/config/jetty/jetty-env.xml b/webapp/src/main/config/jetty/jetty-env.xml similarity index 100% rename from src/main/config/jetty/jetty-env.xml rename to webapp/src/main/config/jetty/jetty-env.xml diff --git a/src/main/config/jetty/jetty-http.xml b/webapp/src/main/config/jetty/jetty-http.xml similarity index 100% rename from src/main/config/jetty/jetty-http.xml rename to webapp/src/main/config/jetty/jetty-http.xml diff --git a/src/main/config/jetty/jetty-https.xml b/webapp/src/main/config/jetty/jetty-https.xml similarity index 100% rename from src/main/config/jetty/jetty-https.xml rename to webapp/src/main/config/jetty/jetty-https.xml diff --git a/src/main/config/jetty/jetty-ssl-context.xml b/webapp/src/main/config/jetty/jetty-ssl-context.xml similarity index 100% rename from src/main/config/jetty/jetty-ssl-context.xml rename to webapp/src/main/config/jetty/jetty-ssl-context.xml diff --git a/src/main/config/jetty/jetty-ssl.xml b/webapp/src/main/config/jetty/jetty-ssl.xml similarity index 100% rename from src/main/config/jetty/jetty-ssl.xml rename to webapp/src/main/config/jetty/jetty-ssl.xml diff --git a/src/main/config/web.xml b/webapp/src/main/config/web.xml similarity index 100% rename from src/main/config/web.xml rename to webapp/src/main/config/web.xml diff --git a/src/main/config/webapp.properties b/webapp/src/main/config/webapp.properties similarity index 100% rename from src/main/config/webapp.properties rename to webapp/src/main/config/webapp.properties diff --git a/src/main/kotlin/org/jeudego/pairgoth/api/ApiHandler.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiHandler.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/api/ApiHandler.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiHandler.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/api/PlayerHandler.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/PlayerHandler.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/api/PlayerHandler.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/api/PlayerHandler.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Pairable.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairable.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Pairable.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairable.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Player.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Player.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Player.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Player.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Rules.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Rules.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Rules.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Rules.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Team.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Team.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Team.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Team.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/TimeSystem.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/TimeSystem.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/TimeSystem.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/TimeSystem.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/FacebookHelper.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/FacebookHelper.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/FacebookHelper.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/FacebookHelper.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/GoogleHelper.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/GoogleHelper.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/GoogleHelper.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/GoogleHelper.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/InstagramHelper.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/InstagramHelper.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/InstagramHelper.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/InstagramHelper.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/OauthHelperFactory.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OauthHelperFactory.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/OauthHelperFactory.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OauthHelperFactory.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/oauth/TwitterHelper.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/TwitterHelper.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/oauth/TwitterHelper.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/TwitterHelper.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/store/Store.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/util/Colorizer.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/util/Colorizer.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/util/Colorizer.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/util/Colorizer.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/util/JsonIO.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/util/JsonIO.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/util/JsonIO.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/util/JsonIO.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/web/ApiException.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/web/ApiException.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/web/ApiException.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/web/ApiException.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/web/ApiServlet.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/web/ApiServlet.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/web/ApiServlet.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/web/ApiServlet.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/web/Logging.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/web/Logging.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/web/Logging.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/web/Logging.kt diff --git a/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt similarity index 100% rename from src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt rename to webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt diff --git a/src/main/webapp/WEB-INF/jetty-web.xml b/webapp/src/main/webapp/WEB-INF/jetty-web.xml similarity index 100% rename from src/main/webapp/WEB-INF/jetty-web.xml rename to webapp/src/main/webapp/WEB-INF/jetty-web.xml diff --git a/src/main/webapp/WEB-INF/logger.properties b/webapp/src/main/webapp/WEB-INF/logger.properties similarity index 100% rename from src/main/webapp/WEB-INF/logger.properties rename to webapp/src/main/webapp/WEB-INF/logger.properties diff --git a/src/main/webapp/WEB-INF/web.xml b/webapp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from src/main/webapp/WEB-INF/web.xml rename to webapp/src/main/webapp/WEB-INF/web.xml diff --git a/src/main/webapp/WEB-INF/webapp.properties b/webapp/src/main/webapp/WEB-INF/webapp.properties similarity index 100% rename from src/main/webapp/WEB-INF/webapp.properties rename to webapp/src/main/webapp/WEB-INF/webapp.properties diff --git a/src/test/kotlin/.gitkeep b/webapp/src/test/kotlin/.gitkeep similarity index 100% rename from src/test/kotlin/.gitkeep rename to webapp/src/test/kotlin/.gitkeep