From 0e943e47e672163c8bcc2c5469aad055cd8508a2 Mon Sep 17 00:00:00 2001 From: "nikolce.mihajlovski" Date: Thu, 23 Jul 2015 19:40:59 +0200 Subject: [PATCH] Refactored the context management and redesigned multi-web-app components. --- pom.xml | 1 - .../src/main/java/org/rapidoid/app/Apps.java | 27 ++--- .../main/java/org/rapidoid/app/UsersTool.java | 2 +- .../rapidoid/app/builtin/AppPageGeneric.java | 4 +- .../builtin/DebugUserInfoScreenBuiltIn.java | 2 +- .../app/builtin/ListEntityScreenGeneric.java | 2 +- .../app/builtin/ViewEntityScreenGeneric.java | 2 +- rapidoid-appctx/pom.xml | 33 ------ .../java/org/rapidoid/demo/http/HttpDemo.java | 5 +- .../main/java/org/rapidoid/docs/Examples.java | 18 ++-- rapidoid-html/pom.xml | 6 -- rapidoid-http/pom.xml | 9 +- .../appctx}/AppClasspathEntitiesPlugin.java | 4 +- .../java/org/rapidoid/appctx}/AppCtx.java | 4 +- .../java/org/rapidoid/appctx}/AppMode.java | 4 +- .../java/org/rapidoid/appctx/Application.java | 52 +++++++++ .../org/rapidoid/appctx}/Applications.java | 18 +++- .../org/rapidoid/appctx}/RootApplication.java | 10 +- .../main/java/org/rapidoid/appctx}/Scan.java | 4 +- .../main/java/org/rapidoid/appctx/WebApp.java | 47 ++++++-- .../java/org/rapidoid/http/HTMLSnippets.java | 10 +- .../src/main/java/org/rapidoid/http/HTTP.java | 10 +- .../java/org/rapidoid/http/HTTPServer.java | 16 --- .../org/rapidoid/http/HTTPServerImpl.java | 61 +---------- .../java/org/rapidoid/http/HttpBuiltins.java | 7 +- .../org/rapidoid/http/HttpExchangeImpl.java | 28 ++--- .../org/rapidoid/http/HttpInterception.java | 2 +- .../java/org/rapidoid/http/HttpProtocol.java | 31 +++--- .../java/org/rapidoid/http/HttpRouter.java | 101 +++++++++++++----- .../main/java/org/rapidoid/http/Router.java | 18 +++- .../rapidoid/http/HttpServerHeadersTest.java | 18 ++-- .../rapidoid/http/HttpServerSubAppTest.java | 68 ++++++++++++ .../org/rapidoid/http/HttpTestCommons.java | 32 ++++-- .../src/main/java/org/rapidoid/main/Main.java | 2 +- .../main/java/org/rapidoid/main/Rapidoid.java | 4 +- rapidoid-net/pom.xml | 2 +- .../java/org/rapidoid/NetTestCommons.java | 4 +- rapidoid-oauth/pom.xml | 5 + .../main/java/org/rapidoid/oauth/OAuth.java | 16 +-- .../java/org/rapidoid/oauth/OAuthDemo.java | 5 +- .../org/rapidoid/pages/PagesTestCommons.java | 2 +- .../main/java/org/rapidoid/quick/Quick.java | 14 +-- .../java/org/rapidoid/quick/QuickJPA.java | 2 +- rapidoid-test-appctx-helper/pom.xml | 2 +- .../org/rapidoid/test/ContextAwareTest.java | 28 +++-- .../java/org/rapidoid/widget/FormWidget.java | 2 +- .../org/rapidoidx/db/impl/DbSchemaImpl.java | 2 +- .../org/rapidoidx/demo/http/HttpDemo.java | 55 ---------- .../org/rapidoidx/demo/taskplanner/Main.java | 6 +- .../demo/taskplanner/gui/MyTasksScreen.java | 2 +- .../rapidoidx/http/HttpPipeliningTest.java | 2 +- rapidoid-x-inmem/pom.xml | 2 +- .../main/java/org/rapidoidx/inmem/InMem.java | 4 +- .../java/org/rapidoidx/websocket/Demo.java | 6 +- 54 files changed, 463 insertions(+), 360 deletions(-) delete mode 100644 rapidoid-appctx/pom.xml rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/AppClasspathEntitiesPlugin.java (98%) rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/AppCtx.java (96%) rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/AppMode.java (94%) create mode 100644 rapidoid-http/src/main/java/org/rapidoid/appctx/Application.java rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/Applications.java (84%) rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/RootApplication.java (84%) rename {rapidoid-appctx/src/main/java/org/rapidoid/apps => rapidoid-http/src/main/java/org/rapidoid/appctx}/Scan.java (98%) rename rapidoid-appctx/src/main/java/org/rapidoid/apps/Application.java => rapidoid-http/src/main/java/org/rapidoid/appctx/WebApp.java (62%) create mode 100644 rapidoid-http/src/test/java/org/rapidoid/http/HttpServerSubAppTest.java delete mode 100644 rapidoid-x-demo/src/main/java/org/rapidoidx/demo/http/HttpDemo.java diff --git a/pom.xml b/pom.xml index 28c8c37806..95537f8189 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,6 @@ rapidoid-test-appctx-helper rapidoid-buffer rapidoid-net - rapidoid-appctx rapidoid-http-api rapidoid-http rapidoid-measure diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/Apps.java b/rapidoid-app/src/main/java/org/rapidoid/app/Apps.java index a025f35517..1902c29fb8 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/Apps.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/Apps.java @@ -31,7 +31,8 @@ import org.rapidoid.annotation.Since; import org.rapidoid.annotation.Transaction; import org.rapidoid.aop.AOP; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Scan; import org.rapidoid.beany.Beany; import org.rapidoid.cls.Cls; import org.rapidoid.config.Conf; @@ -60,20 +61,12 @@ public class Apps { private static AppClasses APP_CLASSES; - public static void main(String[] args) { - run((Object[]) args); + public static void run(Application app, Object... args) { + bootstrap(app, args); + serve(app, args); } - public static void run(String[] args) { - run((Object[]) args); - } - - public static void run(Object... args) { - bootstrap(args); - serve(args); - } - - public static void bootstrap(Object... args) { + public static void bootstrap(Application app, Object... args) { Set config = U.set(); for (Object arg : args) { @@ -89,13 +82,13 @@ public static void bootstrap(Object... args) { Lifecycle.onStart(args); } - public static HTTPServer serve(Object... args) { + public static HTTPServer serve(Application app, Object... args) { HTTPServer server = HTTP.server().build(); - OAuth.register(server); - HttpBuiltins.register(server); + OAuth.register(app); + HttpBuiltins.register(app); - server.serve(new AppHandler()); + app.getRouter().serve(new AppHandler()); return server.start(); } diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/UsersTool.java b/rapidoid-app/src/main/java/org/rapidoid/app/UsersTool.java index f3a55c56f0..73dc52c368 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/UsersTool.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/UsersTool.java @@ -22,7 +22,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.ctx.UserInfo; import org.rapidoid.plugins.users.Users; diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/AppPageGeneric.java b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/AppPageGeneric.java index 2f47cb7fcf..38ae46d10e 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/AppPageGeneric.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/AppPageGeneric.java @@ -36,8 +36,8 @@ import org.rapidoid.app.AppScreens; import org.rapidoid.app.Apps; import org.rapidoid.app.Scaffolding; -import org.rapidoid.apps.AppCtx; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.AppCtx; +import org.rapidoid.appctx.Scan; import org.rapidoid.beany.Beany; import org.rapidoid.cls.Cls; import org.rapidoid.config.Conf; diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/DebugUserInfoScreenBuiltIn.java b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/DebugUserInfoScreenBuiltIn.java index 52b655e2dd..5e92083917 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/DebugUserInfoScreenBuiltIn.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/DebugUserInfoScreenBuiltIn.java @@ -23,7 +23,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; import org.rapidoid.app.GUI; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.html.Tag; import org.rapidoid.security.Secure; import org.rapidoid.security.annotation.DevMode; diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ListEntityScreenGeneric.java b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ListEntityScreenGeneric.java index 4a9fa9c897..a36dae1cee 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ListEntityScreenGeneric.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ListEntityScreenGeneric.java @@ -23,7 +23,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Session; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.cls.Cls; import org.rapidoid.html.Tag; import org.rapidoid.plugins.entities.Entities; diff --git a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ViewEntityScreenGeneric.java b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ViewEntityScreenGeneric.java index df09d531e4..01c3a91621 100644 --- a/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ViewEntityScreenGeneric.java +++ b/rapidoid-app/src/main/java/org/rapidoid/app/builtin/ViewEntityScreenGeneric.java @@ -22,7 +22,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.cls.Cls; import org.rapidoid.html.Tag; import org.rapidoid.plugins.db.DB; diff --git a/rapidoid-appctx/pom.xml b/rapidoid-appctx/pom.xml deleted file mode 100644 index f69393decc..0000000000 --- a/rapidoid-appctx/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - 4.0.0 - - - org.rapidoid - rapidoid - 4.1.0-SNAPSHOT - - - rapidoid-appctx - jar - Rapidoid App Ctx - - - - org.rapidoid - rapidoid-security - ${project.version} - - - org.rapidoid - rapidoid-plugins - ${project.version} - - - org.rapidoid - rapidoid-test-commons - ${project.version} - test - - - - \ No newline at end of file diff --git a/rapidoid-demo/src/main/java/org/rapidoid/demo/http/HttpDemo.java b/rapidoid-demo/src/main/java/org/rapidoid/demo/http/HttpDemo.java index 4e641cf23d..30180e597c 100644 --- a/rapidoid-demo/src/main/java/org/rapidoid/demo/http/HttpDemo.java +++ b/rapidoid-demo/src/main/java/org/rapidoid/demo/http/HttpDemo.java @@ -24,6 +24,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.config.Conf; import org.rapidoid.http.HTTP; import org.rapidoid.http.HTTPServer; @@ -36,12 +38,13 @@ public class HttpDemo { public static void main(String[] args) { Conf.args(args); + Application app = Applications.openRootContext(); final AtomicLong n = new AtomicLong(); HTTPServer server = HTTP.server().build(); - server.get("/hi", new Handler() { + app.getRouter().get("/hi", new Handler() { @Override public Object handle(HttpExchange x) { return "[" + n.incrementAndGet() + "] Hi: " + x.uri(); diff --git a/rapidoid-docs/src/main/java/org/rapidoid/docs/Examples.java b/rapidoid-docs/src/main/java/org/rapidoid/docs/Examples.java index bfbc37e5be..b5ab4134b0 100644 --- a/rapidoid-docs/src/main/java/org/rapidoid/docs/Examples.java +++ b/rapidoid-docs/src/main/java/org/rapidoid/docs/Examples.java @@ -31,9 +31,11 @@ import org.rapidoid.annotation.Since; import org.rapidoid.app.AppHandler; import org.rapidoid.app.Apps; -import org.rapidoid.apps.AppMode; -import org.rapidoid.apps.Application; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.AppMode; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; +import org.rapidoid.appctx.Scan; +import org.rapidoid.appctx.WebApp; import org.rapidoid.cls.Cls; import org.rapidoid.config.Conf; import org.rapidoid.ctx.Classes; @@ -65,10 +67,12 @@ public static void main(String[] args) { String path = "../../rapidoid.github.io/"; U.must(new File(path).exists()); + Application app = Applications.openRootContext(); + HTTPServer server = HTTP.server().build(); - OAuth.register(server); - HttpBuiltins.register(server); - server.serve(new AppHandler()); + OAuth.register(app); + HttpBuiltins.register(app); + app.getRouter().serve(new AppHandler()); server.start(); // FIXME For each example a server is created internally, trying to bind @@ -184,7 +188,7 @@ private static String cleanSnippet(String s) { public static void generate(HTTPServer server, String path, String id, List> classes) { Classes appClasses = Classes.from(classes); - Application app = new Application(id, "app", null, null, U.set("/"), AppMode.DEVELOPMENT, appClasses); + Application app = new WebApp(id, "app", null, null, U.set("/"), AppMode.DEVELOPMENT, null, appClasses); Ctxs.ctx().setApp(app); Class appCls = appClasses.get("Main"); diff --git a/rapidoid-html/pom.xml b/rapidoid-html/pom.xml index 3babfcb26b..b57d4307af 100644 --- a/rapidoid-html/pom.xml +++ b/rapidoid-html/pom.xml @@ -32,12 +32,6 @@ commons-lang3 3.3.2 - - org.rapidoid - rapidoid-test-appctx-helper - ${project.version} - test - \ No newline at end of file diff --git a/rapidoid-http/pom.xml b/rapidoid-http/pom.xml index c58e92db8e..eb1b6c69c1 100644 --- a/rapidoid-http/pom.xml +++ b/rapidoid-http/pom.xml @@ -29,12 +29,17 @@ org.rapidoid - rapidoid-appctx + rapidoid-security ${project.version} org.rapidoid - rapidoid-test-appctx-helper + rapidoid-plugins + ${project.version} + + + org.rapidoid + rapidoid-test-commons ${project.version} test diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppClasspathEntitiesPlugin.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppClasspathEntitiesPlugin.java similarity index 98% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/AppClasspathEntitiesPlugin.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/AppClasspathEntitiesPlugin.java index 7394b9f32a..625e38dd06 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppClasspathEntitiesPlugin.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppClasspathEntitiesPlugin.java @@ -1,4 +1,4 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import java.lang.reflect.Proxy; import java.util.Map; @@ -15,7 +15,7 @@ /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppCtx.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppCtx.java similarity index 96% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/AppCtx.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/AppCtx.java index ffdc52b4e1..779f11389b 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppCtx.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppCtx.java @@ -1,4 +1,4 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; @@ -8,7 +8,7 @@ /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppMode.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppMode.java similarity index 94% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/AppMode.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/AppMode.java index 2b0d4627a5..f365947d01 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/AppMode.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/AppMode.java @@ -1,11 +1,11 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% diff --git a/rapidoid-http/src/main/java/org/rapidoid/appctx/Application.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/Application.java new file mode 100644 index 0000000000..e96c181f81 --- /dev/null +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/Application.java @@ -0,0 +1,52 @@ +package org.rapidoid.appctx; + +/* + * #%L + * rapidoid-http + * %% + * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors + * %% + * 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. + * #L% + */ + +import java.util.Set; + +import org.rapidoid.annotation.Authors; +import org.rapidoid.annotation.Since; +import org.rapidoid.ctx.Classes; +import org.rapidoid.http.Router; + +@Authors("Nikolche Mihajlovski") +@Since("4.1.0") +public interface Application { + + String getId(); + + String getTitle(); + + Set getOwners(); + + Set getHostnames(); + + Set getUriContexts(); + + AppMode getMode(); + + Router getRouter(); + + Classes getClasses(); + + boolean dev(); + +} diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Applications.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/Applications.java similarity index 84% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/Applications.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/Applications.java index 6cc151aefa..6ec66a8f40 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Applications.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/Applications.java @@ -1,14 +1,16 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import java.util.Map; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.ctx.Ctxs; +import org.rapidoid.plugins.Plugins; import org.rapidoid.util.U; /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% @@ -71,4 +73,16 @@ public static RootApplication root() { return new RootApplication(); } + public static Application openRootContext() { + Application app = Applications.root(); + Applications.main().setDefaultApp(app); + + Ctxs.open(); + Ctxs.ctx().setApp(app); + + Plugins.register(new AppClasspathEntitiesPlugin()); + + return app; + } + } diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/RootApplication.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/RootApplication.java similarity index 84% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/RootApplication.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/RootApplication.java index 5cfb392acd..985ebe15ff 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/RootApplication.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/RootApplication.java @@ -1,4 +1,4 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import java.util.Collections; @@ -10,7 +10,7 @@ /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% @@ -30,12 +30,12 @@ @Authors("Nikolche Mihajlovski") @Since("4.1.0") -public class RootApplication extends Application { +public class RootApplication extends WebApp { @SuppressWarnings("unchecked") public RootApplication() { - super("root", "App", Collections.EMPTY_SET, Collections.EMPTY_SET, U.set("/"), AppMode.DEVELOPMENT, Classes - .from(ClasspathUtil.getAllClasses())); + super("root", "App", Collections.EMPTY_SET, Collections.EMPTY_SET, U.set("/"), AppMode.DEVELOPMENT, null, + Classes.from(ClasspathUtil.getAllClasses())); } } diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Scan.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/Scan.java similarity index 98% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/Scan.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/Scan.java index 14ea44083b..88b7f06ff0 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Scan.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/Scan.java @@ -1,4 +1,4 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; import java.lang.annotation.Annotation; import java.util.List; @@ -18,7 +18,7 @@ /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% diff --git a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Application.java b/rapidoid-http/src/main/java/org/rapidoid/appctx/WebApp.java similarity index 62% rename from rapidoid-appctx/src/main/java/org/rapidoid/apps/Application.java rename to rapidoid-http/src/main/java/org/rapidoid/appctx/WebApp.java index f065e862d7..001689cc83 100644 --- a/rapidoid-appctx/src/main/java/org/rapidoid/apps/Application.java +++ b/rapidoid-http/src/main/java/org/rapidoid/appctx/WebApp.java @@ -1,14 +1,18 @@ -package org.rapidoid.apps; +package org.rapidoid.appctx; +import java.util.Collections; import java.util.Set; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; import org.rapidoid.ctx.Classes; +import org.rapidoid.http.HttpRouter; +import org.rapidoid.http.Router; +import org.rapidoid.util.U; /* * #%L - * rapidoid-appctx + * rapidoid-http * %% * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors * %% @@ -28,7 +32,7 @@ @Authors("Nikolche Mihajlovski") @Since("4.1.0") -public class Application { +public class WebApp implements Application { private final String id; @@ -42,43 +46,59 @@ public class Application { private final AppMode mode; + private final Router router; + private final Classes classes; - public Application(String id, String title, Set owners, Set hostnames, Set uriContexts, - AppMode mode, Classes classes) { + @SuppressWarnings("unchecked") + public WebApp(String id, String title, Set owners, Set hostnames, Set uriContexts, + AppMode mode, Router router, Classes classes) { this.id = id; - this.title = title; - this.owners = owners; - this.hostnames = hostnames; - this.uriContexts = uriContexts; - this.mode = mode; - this.classes = classes; + this.router = U.or(router, new HttpRouter()); + this.title = U.or(title, "App"); + this.owners = U.or(owners, Collections.EMPTY_SET); + this.hostnames = U.or(hostnames, Collections.EMPTY_SET); + this.uriContexts = U.or(uriContexts, Collections.EMPTY_SET); + this.mode = U.or(mode, AppMode.DEVELOPMENT); + this.classes = U.or(classes, new Classes()); } + @Override public String getId() { return id; } + @Override public String getTitle() { return title; } + @Override public Set getOwners() { return owners; } + @Override public Set getHostnames() { return hostnames; } + @Override public Set getUriContexts() { return uriContexts; } + @Override public AppMode getMode() { return mode; } + @Override + public Router getRouter() { + return router; + } + + @Override public Classes getClasses() { return classes; } @@ -89,4 +109,9 @@ public String toString() { + ", uriPaths=" + uriContexts + ", mode=" + mode + ", classes #" + classes.size() + "]"; } + @Override + public boolean dev() { + return mode == AppMode.DEVELOPMENT; + } + } diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HTMLSnippets.java b/rapidoid-http/src/main/java/org/rapidoid/http/HTMLSnippets.java index 0e16374746..4f65783ede 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HTMLSnippets.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HTMLSnippets.java @@ -26,6 +26,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; import org.rapidoid.io.CachedResource; +import org.rapidoid.util.U; import org.rapidoid.util.UTILS; @Authors("Nikolche Mihajlovski") @@ -42,15 +43,18 @@ public class HTMLSnippets { } public static HttpExchange writePage(HttpExchange x, String title, String content) { - String html = UTILS.fillIn(PAGE_HTML.getContent(), "title", title); + String templ = PAGE_HTML.getContent(); + U.must(templ != null, "Cannot find page resource!"); + String html = UTILS.fillIn(templ, "title", title); html = UTILS.fillIn(html, "content", content); x.write(html); return x; } public static HttpExchange writeFullPage(HttpExchange x, String title, String content) { - String html = FULL_PAGE_HTML.getContent().replaceAll("\\{\\{title\\}\\}", title) - .replaceAll("\\{\\{content\\}\\}", content); + String templ = FULL_PAGE_HTML.getContent(); + U.must(templ != null, "Cannot find full page resource!"); + String html = templ.replaceAll("\\{\\{title\\}\\}", title).replaceAll("\\{\\{content\\}\\}", content); x.write(html); return x; } diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HTTP.java b/rapidoid-http/src/main/java/org/rapidoid/http/HTTP.java index 842b307272..cb624854b4 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HTTP.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HTTP.java @@ -22,6 +22,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.wire.Wire; @Authors("Nikolche Mihajlovski") @@ -33,11 +35,15 @@ public static HTTPServerBuilder server() { } public static HTTPServer serve(String response) { - return HTTP.server().build().serve(response).start(); + Application app = Applications.openRootContext(); + app.getRouter().serve(response); + return HTTP.server().build().start(); } public static HTTPServer serve(Handler handler) { - return HTTP.server().build().serve(handler).start(); + Application app = Applications.openRootContext(); + app.getRouter().serve(handler); + return HTTP.server().build().start(); } } diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServer.java b/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServer.java index 078cfb57dc..8e58a29dd8 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServer.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServer.java @@ -29,22 +29,6 @@ @Since("2.0.0") public interface HTTPServer extends TCPServer { - HTTPServer route(String cmd, String url, Handler handler); - - HTTPServer route(String cmd, String url, String response); - - HTTPServer serve(String response); - - HTTPServer serve(Handler handler); - - HTTPServer get(String url, Handler handler); - - HTTPServer post(String url, Handler handler); - - HTTPServer put(String url, Handler handler); - - HTTPServer delete(String url, Handler handler); - HTTPServer start(); HTTPServer shutdown(); diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServerImpl.java b/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServerImpl.java index c46c97f8f9..b49878c082 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServerImpl.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HTTPServerImpl.java @@ -35,69 +35,10 @@ public class HTTPServerImpl extends RapidoidServerLoop implements HTTPServer { private final SessionStore session = new InMemorySessionStore(); public HTTPServerImpl() { - super(new HttpProtocol(new HttpRouter()), HttpExchangeImpl.class, null); + super(new HttpProtocol(), HttpExchangeImpl.class, null); ((HttpProtocol) protocol).setSessionStore(session); } - @Override - public HTTPServer route(String cmd, String url, Handler handler) { - router().route(cmd, url, handler); - return this; - } - - @Override - public HTTPServer route(String cmd, String url, String response) { - router().route(cmd, url, contentHandler(response)); - return this; - } - - @Override - public HTTPServer serve(Handler handler) { - router().generic(handler); - return this; - } - - @Override - public HTTPServer serve(String response) { - return serve(contentHandler(response)); - } - - private Router router() { - return ((HttpProtocol) protocol).getRouter(); - } - - @Override - public HTTPServer get(String url, Handler handler) { - return route("GET", url, handler); - } - - @Override - public HTTPServer post(String url, Handler handler) { - return route("POST", url, handler); - } - - @Override - public HTTPServer put(String url, Handler handler) { - return route("PUT", url, handler); - } - - @Override - public HTTPServer delete(String url, Handler handler) { - return route("DELETE", url, handler); - } - - private static Handler contentHandler(String response) { - final byte[] bytes = response.getBytes(); - - return new Handler() { - @Override - public Object handle(HttpExchange x) { - x.html(); - return bytes; - } - }; - } - @Override public HTTPServer start() { super.start(); diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HttpBuiltins.java b/rapidoid-http/src/main/java/org/rapidoid/http/HttpBuiltins.java index 2433285344..360668c248 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HttpBuiltins.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HttpBuiltins.java @@ -2,6 +2,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; import org.rapidoid.config.Conf; import org.rapidoid.ctx.Ctxs; import org.rapidoid.ctx.UserInfo; @@ -32,9 +33,9 @@ @Since("2.0.0") public class HttpBuiltins { - public static void register(HTTPServer server) { - if (Conf.dev() && RapidoidConf.debuglogin()) { - server.get("/_debugLogin", new Handler() { + public static void register(Application app) { + if (app.dev() && RapidoidConf.debuglogin()) { + app.getRouter().get("/_debugLogin", new Handler() { @Override public Object handle(HttpExchange x) { x.accessDeniedIf(!Conf.dev()); diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HttpExchangeImpl.java b/rapidoid-http/src/main/java/org/rapidoid/http/HttpExchangeImpl.java index 5ed30def7c..bfe5cd156a 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HttpExchangeImpl.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HttpExchangeImpl.java @@ -28,7 +28,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.config.Conf; import org.rapidoid.ctx.Ctxs; import org.rapidoid.ctx.UserInfo; @@ -97,10 +97,10 @@ public class HttpExchangeImpl extends DefaultExchange implemen private boolean responseHasContentType; private int responseStartingPos; + private String path = null; private String uriContext = "/"; private HttpResponses responses; - private Router router; private Map data; private Map errors; @@ -182,6 +182,9 @@ public synchronized void reset() { files.reset(); data = null; + path = null; + uriContext = "/"; + parsedParams = false; parsedHeaders = false; parsedBody = false; @@ -190,7 +193,6 @@ public synchronized void reset() { classLoader = null; sessionStore = null; - router = null; session = null; cookiepack = null; @@ -361,7 +363,11 @@ public synchronized String uri() { @Override public synchronized String path() { - return path_().get(); + if (path == null) { + path = path_().get(); + } + + return path; } @Override @@ -838,11 +844,6 @@ public synchronized int responseCode() { return this.responseCode; } - @Override - public synchronized void run() { - router.dispatch(this); - } - @Override public synchronized HttpExchange exchange() { return this; @@ -921,10 +922,9 @@ public synchronized HttpExchange addToPageStack() { return this; } - public synchronized void init(HttpResponses responses, SessionStore sessionStore, Router router) { + public synchronized void init(HttpResponses responses, SessionStore sessionStore) { this.responses = responses; this.sessionStore = sessionStore; - this.router = router; synchronized (Conf.class) { if (Conf.option("mode", null) == null) { @@ -1265,7 +1265,11 @@ public synchronized String uriContext() { } public synchronized HttpExchangeImpl setUriContext(String uriContext) { - U.must(uri().startsWith(uriContext)); + String uriPath = path(); + U.must(uriPath.startsWith(uriContext)); + + this.path = U.triml(uriPath, uriContext); + this.rPath.strip(uriContext.length(), 0); this.uriContext = uriContext; return this; diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HttpInterception.java b/rapidoid-http/src/main/java/org/rapidoid/http/HttpInterception.java index 54b122f953..80a1115bfb 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HttpInterception.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HttpInterception.java @@ -25,7 +25,7 @@ @Authors("Nikolche Mihajlovski") @Since("2.0.0") -public interface HttpInterception extends Runnable { +public interface HttpInterception { HttpExchange exchange(); diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HttpProtocol.java b/rapidoid-http/src/main/java/org/rapidoid/http/HttpProtocol.java index f7dc7116a0..21daca9d71 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HttpProtocol.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HttpProtocol.java @@ -22,8 +22,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.Application; -import org.rapidoid.apps.Applications; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.bytes.BytesUtil; import org.rapidoid.ctx.Ctxs; import org.rapidoid.http.session.SessionStore; @@ -43,8 +43,6 @@ public class HttpProtocol extends ExchangeProtocol { private final HttpParser parser = Wire.singleton(HttpParser.class); - private final Router router; - private final HttpResponses responses; private final HttpUpgrades upgrades = new HttpUpgrades(); @@ -53,9 +51,8 @@ public class HttpProtocol extends ExchangeProtocol { private HTTPInterceptor interceptor; - public HttpProtocol(Router router) { + public HttpProtocol() { super(HttpExchangeImpl.class, true); - this.router = router; this.responses = new HttpResponses(true, true); } @@ -63,7 +60,6 @@ public HttpProtocol(Router router) { protected void process(Channel ctx, HttpExchangeImpl x) { U.notNull(responses, "responses"); U.notNull(sessionStore, "sessionStore"); - U.notNull(router, "router"); if (ctx.isInitial()) { return; @@ -71,8 +67,8 @@ protected void process(Channel ctx, HttpExchangeImpl x) { Usage.touchLastAppUsedOn(); - parser.parse(x.input(), x.isGet, x.isKeepAlive, x.rBody, x.rVerb, x.rUri, x.rPath, x.rQuery, x.rProtocol, x.headers, - x.helper()); + parser.parse(x.input(), x.isGet, x.isKeepAlive, x.rBody, x.rVerb, x.rUri, x.rPath, x.rQuery, x.rProtocol, + x.headers, x.helper()); if (upgradable()) { String upgrade = x.header("Upgrade", null); @@ -83,7 +79,7 @@ protected void process(Channel ctx, HttpExchangeImpl x) { } // FIXME separate responses from session store and router, per app - x.init(responses, sessionStore, router); + x.init(responses, sessionStore); String err = validateRequest(x); if (err != null) { @@ -139,8 +135,11 @@ private void processRequest(HttpExchangeImpl x) { Ctxs.ctx().setApp(app); Ctxs.ctx().setUser(x.user()); + Router router = app.getRouter(); + U.notNull(router, "application router"); + try { - executeRequest(x); + executeRequest(router, x); } finally { Ctxs.ctx().setUser(null); @@ -149,7 +148,7 @@ private void processRequest(HttpExchangeImpl x) { } private Application getApp(HttpExchangeImpl x) { - String uriContext = x.pathSegment(0); + String uriContext = "/" + x.pathSegment(0); Application app = Applications.main().get(x.host(), uriContext); U.must(app != null, "The application must be provided!"); @@ -161,12 +160,12 @@ private Application getApp(HttpExchangeImpl x) { return app; } - private void executeRequest(HttpExchangeImpl x) { + private void executeRequest(Router router, HttpExchangeImpl x) { try { if (interceptor != null) { interceptor.intercept(x); } else { - x.run(); + router.dispatch(x); } } catch (Throwable e) { handleError(x, e); @@ -217,10 +216,6 @@ public static void processResponse(HttpExchange xch, Object res) { } } - public Router getRouter() { - return router; - } - public void setSessionStore(SessionStore sessionStore) { this.sessionStore = sessionStore; } diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/HttpRouter.java b/rapidoid-http/src/main/java/org/rapidoid/http/HttpRouter.java index 9994a80146..88c6f34558 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/HttpRouter.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/HttpRouter.java @@ -54,31 +54,6 @@ public void generic(Handler handler) { this.genericHandler = handler; } - @Override - public void route(String action, String url, Handler handler) { - // verbs are case-sensitive, forcing uppercase convention - if (!action.matches("[A-Z_][A-Z0-9_]*")) { - throw new IllegalArgumentException( - "Only uppercase letters, digits and underscore are allowed! Invalid action: " + action); - } - - if (!url.matches("[a-zA-Z0-9_/\\.\\-\\~]*")) { - throw new IllegalArgumentException("Invalid url: " + url); - } - - if (url.endsWith("/")) { - url = url.substring(0, url.length() - 1); - } - - if (!url.startsWith("/")) { - url = "/" + url; - } - - Log.info("Registering handler", "action", action, "url", url); - - addRoute(action, url, handler); - } - private void addRoute(String action, String path, Handler handler) { assert action.length() >= 1; assert path.length() >= 1; @@ -160,4 +135,80 @@ private void handle(Handler handler, HttpExchangeImpl x) { HttpProtocol.processResponse(x, res); } + @Override + public HttpRouter route(String action, String url, Handler handler) { + // verbs are case-sensitive, forcing uppercase convention + if (!action.matches("[A-Z_][A-Z0-9_]*")) { + throw new IllegalArgumentException( + "Only uppercase letters, digits and underscore are allowed! Invalid action: " + action); + } + + if (!url.matches("[a-zA-Z0-9_/\\.\\-\\~]*")) { + throw new IllegalArgumentException("Invalid url: " + url); + } + + if (url.endsWith("/")) { + url = url.substring(0, url.length() - 1); + } + + if (!url.startsWith("/")) { + url = "/" + url; + } + + Log.info("Registering handler", "action", action, "url", url); + + addRoute(action, url, handler); + + return this; + } + + @Override + public HttpRouter route(String cmd, String url, String response) { + route(cmd, url, contentHandler(response)); + return this; + } + + @Override + public HttpRouter serve(Handler handler) { + generic(handler); + return this; + } + + @Override + public HttpRouter serve(String response) { + return serve(contentHandler(response)); + } + + @Override + public HttpRouter get(String url, Handler handler) { + return route("GET", url, handler); + } + + @Override + public HttpRouter post(String url, Handler handler) { + return route("POST", url, handler); + } + + @Override + public HttpRouter put(String url, Handler handler) { + return route("PUT", url, handler); + } + + @Override + public HttpRouter delete(String url, Handler handler) { + return route("DELETE", url, handler); + } + + private static Handler contentHandler(String response) { + final byte[] bytes = response.getBytes(); + + return new Handler() { + @Override + public Object handle(HttpExchange x) { + x.html(); + return bytes; + } + }; + } + } diff --git a/rapidoid-http/src/main/java/org/rapidoid/http/Router.java b/rapidoid-http/src/main/java/org/rapidoid/http/Router.java index 92517217ff..1d3d36c9ea 100644 --- a/rapidoid-http/src/main/java/org/rapidoid/http/Router.java +++ b/rapidoid-http/src/main/java/org/rapidoid/http/Router.java @@ -27,9 +27,23 @@ @Since("2.0.0") public interface Router { - void generic(Handler handler); + Router route(String cmd, String url, Handler handler); + + Router route(String cmd, String url, String response); + + Router serve(String response); + + Router serve(Handler handler); + + Router get(String url, Handler handler); - void route(String action, String path, Handler handler); + Router post(String url, Handler handler); + + Router put(String url, Handler handler); + + Router delete(String url, Handler handler); + + void generic(Handler handler); void dispatch(HttpExchangeImpl x); diff --git a/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerHeadersTest.java b/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerHeadersTest.java index 7a469869d9..1cd42ceca5 100644 --- a/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerHeadersTest.java +++ b/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerHeadersTest.java @@ -39,21 +39,21 @@ public void shouldHandleHttpRequests() throws IOException, URISyntaxException { server(); - server.get("/file", new Handler() { + router.get("/file", new Handler() { @Override public Object handle(HttpExchange x) { return x.download(x.subpath().substring(1) + ".txt").write("ab").write("cde"); } }); - server.get("/bin", new Handler() { + router.get("/bin", new Handler() { @Override public Object handle(HttpExchange x) { return x.binary().write("bin"); } }); - server.get("/session", new Handler() { + router.get("/session", new Handler() { @Override public Object handle(HttpExchange x) { if (x.cookie("ses", null) == null) { @@ -65,35 +65,35 @@ public Object handle(HttpExchange x) { } }); - server.get("/async", new Handler() { + router.get("/async", new Handler() { @Override public Object handle(HttpExchange x) { return x.async().write("now").done(); } }); - server.get("/testfile1", new Handler() { + router.get("/testfile1", new Handler() { @Override public Object handle(HttpExchange x) { return IO.file("test1.txt"); } }); - server.get("/rabbit.jpg", new Handler() { + router.get("/rabbit.jpg", new Handler() { @Override public Object handle(HttpExchange x) { return x.sendFile(IO.file("rabbit.jpg")); } }); - server.get("/ab", new Handler() { + router.get("/ab", new Handler() { @Override public Object handle(HttpExchange x) { return x.sendFile(IO.file("ab.html")); } }); - server.serve(new Handler() { + router.serve(new Handler() { @Override public Object handle(HttpExchange x) { return x.setCookie("asd", "f").html().write("abc"); @@ -123,7 +123,7 @@ public void shouldRenderRabbit() throws Exception { // :) server(); - server.get("/rabbit.jpg", new Handler() { + router.get("/rabbit.jpg", new Handler() { @Override public Object handle(HttpExchange x) { return x.sendFile(IO.file("rabbit.jpg")); diff --git a/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerSubAppTest.java b/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerSubAppTest.java new file mode 100644 index 0000000000..aee07149e3 --- /dev/null +++ b/rapidoid-http/src/test/java/org/rapidoid/http/HttpServerSubAppTest.java @@ -0,0 +1,68 @@ +package org.rapidoid.http; + +/* + * #%L + * rapidoid-http + * %% + * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors + * %% + * 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. + * #L% + */ + +import java.io.IOException; +import java.net.URISyntaxException; + +import org.junit.Test; +import org.rapidoid.annotation.Authors; +import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; +import org.rapidoid.appctx.WebApp; +import org.rapidoid.util.U; + +@Authors("Nikolche Mihajlovski") +@Since("4.1.0") +public class HttpServerSubAppTest extends HttpTestCommons { + + @Test + public void shouldHandleSubAppRequests() throws IOException, URISyntaxException { + + Application myapp = new WebApp("myapp", "My App", null, null, U.set("my"), null, null, null); + Applications.main().register(myapp); + + server = HTTP.server().build(); + + router.get("/ab", new Handler() { + @Override + public Object handle(HttpExchange x) { + return U.join(":", "special", x.uri(), x.uriContext(), x.path(), x.subpath()); + } + }); + + router.serve(new Handler() { + @Override + public Object handle(HttpExchange x) { + return U.join(":", "generic", x.uri(), x.uriContext(), x.path(), x.subpath()); + } + }); + + start(); + + eq(get("/"), "generic:/:/::"); + eq(get("/ab"), "special:/ab:/:/ab:"); + + shutdown(); + } + +} diff --git a/rapidoid-http/src/test/java/org/rapidoid/http/HttpTestCommons.java b/rapidoid-http/src/test/java/org/rapidoid/http/HttpTestCommons.java index bab401e164..62600660c3 100644 --- a/rapidoid-http/src/test/java/org/rapidoid/http/HttpTestCommons.java +++ b/rapidoid-http/src/test/java/org/rapidoid/http/HttpTestCommons.java @@ -38,24 +38,44 @@ import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.buffer.Buf; import org.rapidoid.crypto.Crypto; +import org.rapidoid.ctx.Ctxs; import org.rapidoid.data.KeyValueRanges; import org.rapidoid.data.Range; import org.rapidoid.io.IO; -import org.rapidoid.test.ContextAwareTest; +import org.rapidoid.test.TestCommons; import org.rapidoid.util.U; import org.rapidoid.util.UTILS; @Authors("Nikolche Mihajlovski") @Since("2.0.0") -public abstract class HttpTestCommons extends ContextAwareTest { +public abstract class HttpTestCommons extends TestCommons { + + protected Application app; protected HTTPServer server; + protected Router router; + + @Before + public void openContext() { + app = Applications.openRootContext(); + router = app.getRouter(); + } + + @After + public void closeContext() { + Ctxs.close(); + } + protected String localhost(String url) { return "http://localhost:8080" + url; } @@ -67,7 +87,7 @@ protected void server() { protected void defaultServerSetup() { server(); - server.get("/echo", new Handler() { + router.get("/echo", new Handler() { @Override public Object handle(HttpExchange h) throws Exception { @@ -76,14 +96,14 @@ public Object handle(HttpExchange h) throws Exception { } }); - server.get("/hello", new Handler() { + router.get("/hello", new Handler() { @Override public Object handle(HttpExchange x) { return "Hello"; } }); - server.post("/upload", new Handler() { + router.post("/upload", new Handler() { @SuppressWarnings("unchecked") @Override public Object handle(HttpExchange x) { @@ -93,7 +113,7 @@ public Object handle(HttpExchange x) { } }); - server.serve(new Handler() { + router.serve(new Handler() { @Override public Object handle(HttpExchange x) { return U.join(":", x.verb(), x.path(), x.subpath(), x.query()); diff --git a/rapidoid-main/src/main/java/org/rapidoid/main/Main.java b/rapidoid-main/src/main/java/org/rapidoid/main/Main.java index 44dda1a7e2..66d79c3938 100644 --- a/rapidoid-main/src/main/java/org/rapidoid/main/Main.java +++ b/rapidoid-main/src/main/java/org/rapidoid/main/Main.java @@ -26,7 +26,7 @@ import org.rapidoid.annotation.App; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.Scan; import org.rapidoid.cls.Cls; @Authors("Nikolche Mihajlovski") diff --git a/rapidoid-main/src/main/java/org/rapidoid/main/Rapidoid.java b/rapidoid-main/src/main/java/org/rapidoid/main/Rapidoid.java index 419ea037d6..f654817c39 100644 --- a/rapidoid-main/src/main/java/org/rapidoid/main/Rapidoid.java +++ b/rapidoid-main/src/main/java/org/rapidoid/main/Rapidoid.java @@ -22,8 +22,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.Application; -import org.rapidoid.apps.Applications; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.log.Log; import org.rapidoid.quick.Quick; import org.rapidoid.util.U; diff --git a/rapidoid-net/pom.xml b/rapidoid-net/pom.xml index c2b2c06e32..28c20baca3 100644 --- a/rapidoid-net/pom.xml +++ b/rapidoid-net/pom.xml @@ -34,7 +34,7 @@ org.rapidoid - rapidoid-test-appctx-helper + rapidoid-test-commons ${project.version} test diff --git a/rapidoid-net/src/test/java/org/rapidoid/NetTestCommons.java b/rapidoid-net/src/test/java/org/rapidoid/NetTestCommons.java index a35636f4ed..b86cfd3a0b 100644 --- a/rapidoid-net/src/test/java/org/rapidoid/NetTestCommons.java +++ b/rapidoid-net/src/test/java/org/rapidoid/NetTestCommons.java @@ -26,12 +26,12 @@ import org.rapidoid.net.Protocol; import org.rapidoid.net.Serve; import org.rapidoid.net.TCPServer; -import org.rapidoid.test.ContextAwareTest; +import org.rapidoid.test.TestCommons; import org.rapidoid.util.U; @Authors("Nikolche Mihajlovski") @Since("2.0.0") -public abstract class NetTestCommons extends ContextAwareTest { +public abstract class NetTestCommons extends TestCommons { protected void server(Protocol protocol, Runnable client) { TCPServer server = Serve.listen(protocol); diff --git a/rapidoid-oauth/pom.xml b/rapidoid-oauth/pom.xml index d601690884..886c366167 100644 --- a/rapidoid-oauth/pom.xml +++ b/rapidoid-oauth/pom.xml @@ -17,6 +17,11 @@ rapidoid-http ${project.version} + + org.rapidoid + rapidoid-html + ${project.version} + org.apache.oltu.oauth2 org.apache.oltu.oauth2.client diff --git a/rapidoid-oauth/src/main/java/org/rapidoid/oauth/OAuth.java b/rapidoid-oauth/src/main/java/org/rapidoid/oauth/OAuth.java index fff9ad8d36..022fa14a26 100644 --- a/rapidoid-oauth/src/main/java/org/rapidoid/oauth/OAuth.java +++ b/rapidoid-oauth/src/main/java/org/rapidoid/oauth/OAuth.java @@ -24,9 +24,9 @@ import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; import org.rapidoid.config.Conf; import org.rapidoid.http.HTMLSnippets; -import org.rapidoid.http.HTTPServer; import org.rapidoid.http.Handler; import org.rapidoid.http.HttpExchange; import org.rapidoid.util.U; @@ -39,11 +39,11 @@ public class OAuth { private static OAuthStateCheck STATE_CHECK; - public static void register(HTTPServer server, OAuthProvider... providers) { - register(server, null, new DefaultOAuthStateCheck(), providers); + public static void register(Application app, OAuthProvider... providers) { + register(app, null, new DefaultOAuthStateCheck(), providers); } - public static void register(HTTPServer server, String oauthDomain, OAuthStateCheck stateCheck, + public static void register(Application app, String oauthDomain, OAuthStateCheck stateCheck, OAuthProvider... providers) { if (Conf.oauth() == null) { @@ -70,16 +70,16 @@ public static void register(HTTPServer server, String oauthDomain, OAuthStateChe String clientId = Conf.option(name + ".clientId", "NO-CLIENT-ID"); String clientSecret = Conf.option(name + ".clientSecret", "NO-CLIENT-SECRET"); - server.get(loginPath, new OAuthLoginHandler(provider, oauthDomain)); - server.get(callbackPath, new OAuthTokenHandler(provider, oauthDomain, stateCheck, clientId, clientSecret, - callbackPath)); + app.getRouter().get(loginPath, new OAuthLoginHandler(provider, oauthDomain)); + app.getRouter().get(callbackPath, + new OAuthTokenHandler(provider, oauthDomain, stateCheck, clientId, clientSecret, callbackPath)); loginHtml.append(U.format(LOGIN_BTN, name, provider.getName())); } loginHtml.append(""); - server.get("/_oauthLogin", new Handler() { + app.getRouter().get("/_oauthLogin", new Handler() { @Override public Object handle(HttpExchange x) throws Exception { return HTMLSnippets.writePage(x, "Login with OAuth provider", loginHtml.toString()); diff --git a/rapidoid-oauth/src/test/java/org/rapidoid/oauth/OAuthDemo.java b/rapidoid-oauth/src/test/java/org/rapidoid/oauth/OAuthDemo.java index ccacbdc69e..931f63ff70 100644 --- a/rapidoid-oauth/src/test/java/org/rapidoid/oauth/OAuthDemo.java +++ b/rapidoid-oauth/src/test/java/org/rapidoid/oauth/OAuthDemo.java @@ -22,6 +22,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.http.HTTP; import org.rapidoid.http.HTTPServer; import org.rapidoid.log.Log; @@ -32,9 +34,10 @@ public class OAuthDemo { public static void main(String[] args) { + Application app = Applications.openRootContext(); Log.setLogLevel(LogLevel.DEBUG); HTTPServer server = HTTP.server().build(); - OAuth.register(server); + OAuth.register(app); server.start(); } diff --git a/rapidoid-pages/src/test/java/org/rapidoid/pages/PagesTestCommons.java b/rapidoid-pages/src/test/java/org/rapidoid/pages/PagesTestCommons.java index 062417498c..21b9b7f243 100644 --- a/rapidoid-pages/src/test/java/org/rapidoid/pages/PagesTestCommons.java +++ b/rapidoid-pages/src/test/java/org/rapidoid/pages/PagesTestCommons.java @@ -121,7 +121,7 @@ protected static HttpExchange setupMockExchange() { x.setConnection(conn); InMemorySessionStore sessions = new InMemorySessionStore(); - x.init(new HttpResponses(false, false), sessions, null); + x.init(new HttpResponses(false, false), sessions); Ctxs.ctx().setExchange(x); return x; diff --git a/rapidoid-quick/src/main/java/org/rapidoid/quick/Quick.java b/rapidoid-quick/src/main/java/org/rapidoid/quick/Quick.java index ef834cec01..dfe7558bb1 100644 --- a/rapidoid-quick/src/main/java/org/rapidoid/quick/Quick.java +++ b/rapidoid-quick/src/main/java/org/rapidoid/quick/Quick.java @@ -32,9 +32,9 @@ import org.rapidoid.aop.AOP; import org.rapidoid.app.Apps; import org.rapidoid.app.TransactionInterceptor; -import org.rapidoid.apps.AppClasspathEntitiesPlugin; -import org.rapidoid.apps.Application; -import org.rapidoid.apps.Applications; +import org.rapidoid.appctx.AppClasspathEntitiesPlugin; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.ctx.Ctxs; import org.rapidoid.job.Jobs; import org.rapidoid.log.Log; @@ -51,11 +51,11 @@ public static void run(Application app, Object[] args) { serve(app, args); } - public static void serve(Application app, Object[] args) { - Apps.serve(args); + public static void serve(Application app, Object... args) { + Apps.serve(app, args); } - public static void bootstrap(Application app, final Object[] args) { + public static void bootstrap(Application app, final Object... args) { Applications.main().setDefaultApp(app); Ctxs.open(); @@ -65,7 +65,7 @@ public static void bootstrap(Application app, final Object[] args) { List appArgs = U. list(db); appArgs.addAll(U.list(args)); - Apps.bootstrap(U.array(appArgs)); + Apps.bootstrap(app, U.array(appArgs)); Applications.main().register(app); diff --git a/rapidoid-quick/src/main/java/org/rapidoid/quick/QuickJPA.java b/rapidoid-quick/src/main/java/org/rapidoid/quick/QuickJPA.java index bdf250af46..9726dfa4d2 100644 --- a/rapidoid-quick/src/main/java/org/rapidoid/quick/QuickJPA.java +++ b/rapidoid-quick/src/main/java/org/rapidoid/quick/QuickJPA.java @@ -33,7 +33,7 @@ import org.hibernate.jpa.internal.EntityManagerFactoryImpl; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.Scan; import org.rapidoid.config.Conf; import org.rapidoid.ctx.PersisterProvider; import org.rapidoid.io.IO; diff --git a/rapidoid-test-appctx-helper/pom.xml b/rapidoid-test-appctx-helper/pom.xml index 5c1404ecc2..6c7b85e9c9 100644 --- a/rapidoid-test-appctx-helper/pom.xml +++ b/rapidoid-test-appctx-helper/pom.xml @@ -14,7 +14,7 @@ org.rapidoid - rapidoid-appctx + rapidoid-http ${project.version} diff --git a/rapidoid-test-appctx-helper/src/main/java/org/rapidoid/test/ContextAwareTest.java b/rapidoid-test-appctx-helper/src/main/java/org/rapidoid/test/ContextAwareTest.java index 215083f926..7b9981145d 100644 --- a/rapidoid-test-appctx-helper/src/main/java/org/rapidoid/test/ContextAwareTest.java +++ b/rapidoid-test-appctx-helper/src/main/java/org/rapidoid/test/ContextAwareTest.java @@ -22,27 +22,25 @@ import org.junit.After; import org.junit.Before; -import org.rapidoid.apps.AppClasspathEntitiesPlugin; -import org.rapidoid.apps.Applications; -import org.rapidoid.apps.RootApplication; +import org.rapidoid.annotation.Authors; +import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.ctx.Ctxs; -import org.rapidoid.plugins.Plugins; +import org.rapidoid.http.Router; -/** - * @author Nikolche Mihajlovski - * @since 2.0.0 - */ +@Authors("Nikolche Mihajlovski") +@Since("4.1.0") public abstract class ContextAwareTest extends TestCommons { - @Before - public void openContext() { - RootApplication app = Applications.root(); - Applications.main().setDefaultApp(app); + protected Application app; - Ctxs.open(); - Ctxs.ctx().setApp(app); + protected Router router; - Plugins.register(new AppClasspathEntitiesPlugin()); + @Before + public void openContext() { + app = Applications.openRootContext(); + router = app.getRouter(); } @After diff --git a/rapidoid-widget/src/main/java/org/rapidoid/widget/FormWidget.java b/rapidoid-widget/src/main/java/org/rapidoid/widget/FormWidget.java index 4caf717618..4b93862298 100644 --- a/rapidoid-widget/src/main/java/org/rapidoid/widget/FormWidget.java +++ b/rapidoid-widget/src/main/java/org/rapidoid/widget/FormWidget.java @@ -25,7 +25,7 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.cls.Cls; import org.rapidoid.html.FieldType; import org.rapidoid.html.FormLayout; diff --git a/rapidoid-x-db-impl/src/main/java/org/rapidoidx/db/impl/DbSchemaImpl.java b/rapidoid-x-db-impl/src/main/java/org/rapidoidx/db/impl/DbSchemaImpl.java index 81f404c978..c8e61aef55 100644 --- a/rapidoid-x-db-impl/src/main/java/org/rapidoidx/db/impl/DbSchemaImpl.java +++ b/rapidoid-x-db-impl/src/main/java/org/rapidoidx/db/impl/DbSchemaImpl.java @@ -8,7 +8,7 @@ import org.rapidoid.annotation.DbEntity; import org.rapidoid.annotation.Scaffold; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.Scan; import org.rapidoid.beany.Beany; import org.rapidoid.cls.Cls; import org.rapidoid.entity.IEntity; diff --git a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/http/HttpDemo.java b/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/http/HttpDemo.java deleted file mode 100644 index ceaaa98fb1..0000000000 --- a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/http/HttpDemo.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.rapidoidx.demo.http; - -/* - * #%L - * rapidoid-x-demo - * %% - * Copyright (C) 2014 - 2015 Nikolche Mihajlovski and contributors - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * #L% - */ - -import java.util.concurrent.atomic.AtomicLong; - -import org.rapidoid.annotation.Authors; -import org.rapidoid.annotation.Since; -import org.rapidoid.config.Conf; -import org.rapidoid.http.HTTP; -import org.rapidoid.http.HTTPServer; -import org.rapidoid.http.Handler; -import org.rapidoid.http.HttpExchange; - -@Authors("Nikolche Mihajlovski") -@Since("3.0.0") -public class HttpDemo { - - public static void main(String[] args) { - Conf.args(args); - - final AtomicLong n = new AtomicLong(); - - HTTPServer server = HTTP.server().build(); - - server.get("/hi", new Handler() { - @Override - public Object handle(HttpExchange x) { - return "[" + n.incrementAndGet() + "] Hi: " + x.uri(); - } - }); - - server.start(); - } - -} diff --git a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/Main.java b/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/Main.java index a3304f8904..94fbdc6f5d 100644 --- a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/Main.java +++ b/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/Main.java @@ -24,6 +24,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; import org.rapidoid.app.Apps; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoidx.db.XDB; @Authors("Nikolche Mihajlovski") @@ -31,7 +33,9 @@ public class Main { public static void main(String[] args) { - Apps.run("oauth-no-state"); + Application app = Applications.openRootContext(); + Apps.run(app, "oauth-no-state"); + XDB.clear(); for (int i = 0; i < 100; i++) { XDB.init("task title=?, description=?, rating=?", "abc" + i, "Some description of the task " + i, i * 10); diff --git a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/gui/MyTasksScreen.java b/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/gui/MyTasksScreen.java index 17ff0c4b93..b454d135a8 100644 --- a/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/gui/MyTasksScreen.java +++ b/rapidoid-x-demo/src/main/java/org/rapidoidx/demo/taskplanner/gui/MyTasksScreen.java @@ -27,7 +27,7 @@ import org.rapidoid.annotation.Order; import org.rapidoid.annotation.Since; import org.rapidoid.app.GUI; -import org.rapidoid.apps.AppCtx; +import org.rapidoid.appctx.AppCtx; import org.rapidoid.beany.Beany; import org.rapidoid.html.Tag; import org.rapidoid.lambda.Predicate; diff --git a/rapidoid-x-http-client/src/test/java/org/rapidoidx/http/HttpPipeliningTest.java b/rapidoid-x-http-client/src/test/java/org/rapidoidx/http/HttpPipeliningTest.java index c904c400ec..bb8ffb5f6f 100644 --- a/rapidoid-x-http-client/src/test/java/org/rapidoidx/http/HttpPipeliningTest.java +++ b/rapidoid-x-http-client/src/test/java/org/rapidoidx/http/HttpPipeliningTest.java @@ -55,7 +55,7 @@ public void testHttpServerPipelining() { HTTPServer server = HTTP.server().build(); - server.get("/hello", new Handler() { + router.get("/hello", new Handler() { @Override public Object handle(HttpExchange x) { return "Hello"; diff --git a/rapidoid-x-inmem/pom.xml b/rapidoid-x-inmem/pom.xml index e0263202f8..2701f14d6f 100644 --- a/rapidoid-x-inmem/pom.xml +++ b/rapidoid-x-inmem/pom.xml @@ -14,7 +14,7 @@ org.rapidoid - rapidoid-appctx + rapidoid-http ${project.version} diff --git a/rapidoid-x-inmem/src/main/java/org/rapidoidx/inmem/InMem.java b/rapidoid-x-inmem/src/main/java/org/rapidoidx/inmem/InMem.java index 42d13bbcce..fcee10fc16 100644 --- a/rapidoid-x-inmem/src/main/java/org/rapidoidx/inmem/InMem.java +++ b/rapidoid-x-inmem/src/main/java/org/rapidoidx/inmem/InMem.java @@ -51,8 +51,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Rel; import org.rapidoid.annotation.Since; -import org.rapidoid.apps.AppCtx; -import org.rapidoid.apps.Scan; +import org.rapidoid.appctx.AppCtx; +import org.rapidoid.appctx.Scan; import org.rapidoid.beany.Beany; import org.rapidoid.beany.Prop; import org.rapidoid.beany.PropertyFilter; diff --git a/rapidoid-x-websocket/src/test/java/org/rapidoidx/websocket/Demo.java b/rapidoid-x-websocket/src/test/java/org/rapidoidx/websocket/Demo.java index 4edc26aa83..a93581bad0 100644 --- a/rapidoid-x-websocket/src/test/java/org/rapidoidx/websocket/Demo.java +++ b/rapidoid-x-websocket/src/test/java/org/rapidoidx/websocket/Demo.java @@ -23,6 +23,8 @@ import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; +import org.rapidoid.appctx.Application; +import org.rapidoid.appctx.Applications; import org.rapidoid.config.Conf; import org.rapidoid.http.HTTPServer; import org.rapidoid.http.Handler; @@ -37,6 +39,8 @@ public static void main(String[] args) { Conf.args(args); Log.args("debug"); + Application app = Applications.openRootContext(); + HTTPServer server = WebSocket.serve(new WSHandler() { @Override public Object handle(WSExchange x) throws Exception { @@ -46,7 +50,7 @@ public Object handle(WSExchange x) throws Exception { } }); - server.serve(new Handler() { + app.getRouter().serve(new Handler() { @Override public Object handle(HttpExchange x) { return "Hi: " + x.uri();