Skip to content

Commit

Permalink
Simplified and refactored page event handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmihajlovski committed Aug 8, 2015
1 parent 15af6a5 commit 3f57964
Show file tree
Hide file tree
Showing 15 changed files with 268 additions and 126 deletions.
39 changes: 39 additions & 0 deletions rapidoid-annotations/src/main/java/org/rapidoid/annotation/On.java
@@ -0,0 +1,39 @@
package org.rapidoid.annotation;

/*
* #%L
* rapidoid-annotations
* %%
* 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 static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target({ METHOD })
@Retention(RUNTIME)
@Authors("Nikolche Mihajlovski")
@Since("4.1.0")
public @interface On {

String event();

String page() default "";

}
62 changes: 31 additions & 31 deletions rapidoid-app/src/main/java/org/rapidoid/app/AppHandler.java
Expand Up @@ -31,6 +31,8 @@
import org.rapidoid.dispatch.PojoDispatchException;
import org.rapidoid.dispatch.PojoDispatcher;
import org.rapidoid.dispatch.PojoHandlerNotFoundException;
import org.rapidoid.dispatch.PojoRequest;
import org.rapidoid.dispatch.impl.DispatchReqKind;
import org.rapidoid.http.Handler;
import org.rapidoid.http.HttpExchange;
import org.rapidoid.http.HttpExchangeImpl;
Expand All @@ -46,6 +48,7 @@
import org.rapidoid.util.UTILS;
import org.rapidoid.webapp.AppCtx;
import org.rapidoid.webapp.WebApp;
import org.rapidoid.webapp.WebEventReq;
import org.rapidoid.webapp.WebReq;

@Authors("Nikolche Mihajlovski")
Expand Down Expand Up @@ -84,7 +87,6 @@ public Object handle(final HttpExchange x) throws Exception {
}

return result;

}

public Object processReq(HttpExchange x) {
Expand Down Expand Up @@ -134,31 +136,37 @@ public Object dispatch(HttpExchangeImpl x) {
String inputId = e.getKey();
Object value = e.getValue();

x.locals().put(inputId, UTILS.serializable(value + ":"));
x.locals().put(inputId, UTILS.serializable(value));
}

DispatchResult dispatchResult = doDispatch(x, dispatcher);
U.must(dispatchResult != null && !dispatchResult.isService());
DispatchResult dispatchResult = doDispatch(dispatcher, new WebReq(x));
U.must(dispatchResult != null && dispatchResult.getKind() == DispatchReqKind.PAGE);

// in case of binding or validation errors
if (x.hasErrors()) {
x.json();
return U.map("!errors", x.errors());
}

// call the command handler
DispatchResult dr = on(x, dispatcher, event, args);
if (dr == null) {
x.json();
Log.warn("No event handler was found!", "event", event, "page", x.path());
return U.map();
}
}
}

// FIXME: call the command handler

// dispatch REST services or views (as POJO methods)

DispatchResult dispatchResult = doDispatch(x, dispatcher);
DispatchResult dispatchResult = doDispatch(dispatcher, new WebReq(x));

Object result = null;
if (dispatchResult != null) {
result = dispatchResult.getResult();

if (dispatchResult.isService()) {
if (dispatchResult.getKind() == DispatchReqKind.SERVICE) {
return result;
}
}
Expand All @@ -181,19 +189,15 @@ public Object dispatch(HttpExchangeImpl x) {
throw x.notFound();
}

private DispatchResult doDispatch(HttpExchange x, PojoDispatcher dispatcher) {
DispatchResult dispatchResult = null;

if (dispatcher != null) {
try {
dispatchResult = dispatcher.dispatch(new WebReq(x));
} catch (PojoHandlerNotFoundException e) {
// / just ignore, will try to dispatch a page next...
} catch (PojoDispatchException e) {
throw U.rte("Dispatch error!", e);
}
private DispatchResult doDispatch(PojoDispatcher dispatcher, PojoRequest req) {
try {
return dispatcher.dispatch(req);
} catch (PojoHandlerNotFoundException e) {
// / just ignore, will try to dispatch a page next...
return null;
} catch (PojoDispatchException e) {
throw U.rte("Dispatch error!", e);
}
return dispatchResult;
}

public boolean serveDynamicPage(HttpExchangeImpl x, Object result, boolean hasEvent) {
Expand Down Expand Up @@ -357,16 +361,12 @@ protected Object genericScreen() {
return null;
}

// public void on(String cmd, Object[] args) {
// try {
// Pages.callCmdHandler(x, screen, new Cmd(cmd, false, args));
// } catch (Exception e) {
// Throwable cause = UTILS.rootCause(e);
// if (cause instanceof HttpSuccessException || cause instanceof HttpNotFoundException) {
// Pages.store(x, screen);
// }
// throw U.rte(e);
// }
// }
public DispatchResult on(HttpExchange x, PojoDispatcher dispatcher, String event, Object[] args) {

Map<String, Object> state = U.cast(x.locals());
WebEventReq req = new WebEventReq(x.path(), event.toUpperCase(), args, state);

return doDispatch(dispatcher, req);
}

}
Expand Up @@ -22,31 +22,32 @@

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.dispatch.impl.DispatchReqKind;

@Authors("Nikolche Mihajlovski")
@Since("4.1.0")
public class DispatchResult {

private final Object result;

private final boolean service;
private final DispatchReqKind kind;

public DispatchResult(Object result, boolean service) {
public DispatchResult(Object result, DispatchReqKind kind) {
this.result = result;
this.service = service;
this.kind = kind;
}

public Object getResult() {
return result;
}

public boolean isService() {
return service;
public DispatchReqKind getKind() {
return kind;
}

@Override
public String toString() {
return "DispatchResult [result=" + result + ", service=" + service + "]";
return "DispatchResult [result=" + result + ", kind=" + kind + "]";
}

}
Expand Up @@ -33,6 +33,8 @@ public interface PojoRequest {

String path();

boolean isEvent();

Object param(String name);

Map<String, Object> params();
Expand Down
Expand Up @@ -31,27 +31,26 @@ public class DispatchReq {

final String path;

final boolean service;
final DispatchReqKind kind;

public DispatchReq(String command, String path, boolean service) {
super();
public DispatchReq(String command, String path, DispatchReqKind kind) {
this.command = command;
this.path = path;
this.service = service;
this.kind = kind;
}

@Override
public String toString() {
return "DispatchReq [command=" + command + ", path=" + path + ", service=" + service + "]";
return "DispatchReq [command=" + command + ", path=" + path + ", kind=" + kind + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((command == null) ? 0 : command.hashCode());
result = prime * result + ((kind == null) ? 0 : kind.hashCode());
result = prime * result + ((path == null) ? 0 : path.hashCode());
result = prime * result + (service ? 1231 : 1237);
return result;
}

Expand All @@ -69,13 +68,13 @@ public boolean equals(Object obj) {
return false;
} else if (!command.equals(other.command))
return false;
if (kind != other.kind)
return false;
if (path == null) {
if (other.path != null)
return false;
} else if (!path.equals(other.path))
return false;
if (service != other.service)
return false;
return true;
}

Expand Down
@@ -0,0 +1,30 @@
package org.rapidoid.dispatch.impl;

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;

/*
* #%L
* rapidoid-dispatch
* %%
* 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%
*/

@Authors("Nikolche Mihajlovski")
@Since("4.1.0")
public enum DispatchReqKind {
SERVICE, PAGE, EVENT;
}
Expand Up @@ -73,7 +73,8 @@ private void init(Map<String, Class<?>> components) {

for (DispatchReq action : actions) {
mappings.put(action, new DispatchTarget(component, method));
Log.info("Registered web handler", "request", action, "method", method);
Log.info("Registered web handler", "kind", action.kind, "command", action.command, "path",
action.path, "method", method);
}
}
}
Expand All @@ -97,28 +98,44 @@ protected DispatchResult process(PojoRequest req, String command, String path, S
// normalize the path
path = UTILS.path(path);

// try a service
DispatchTarget target = mappings.get(new DispatchReq(command, path, true));
boolean service = target != null;
if (req.isEvent()) {
// find the event handler
DispatchTarget target = mappings.get(new DispatchReq(command, path, DispatchReqKind.EVENT));

if (!service) {
// try a view (GUI)
target = mappings.get(new DispatchReq(command, path, false));
}
if (target != null) {
return call(req, parts, paramsFrom, target, DispatchReqKind.EVENT);
}

} else {

// try a service
DispatchTarget target = mappings.get(new DispatchReq(command, path, DispatchReqKind.SERVICE));
boolean isService = target != null;

if (target != null) {
Object componentInstance = Cls.newInstance(target.clazz);
if (target.method != null) {
Object callResult = doDispatch(req, target.method, componentInstance, parts, paramsFrom);
return new DispatchResult(callResult, service);
} else {
throw notFound();
if (!isService) {
// try a web page
target = mappings.get(new DispatchReq(command, path, DispatchReqKind.PAGE));
}

if (target != null) {
return call(req, parts, paramsFrom, target, isService ? DispatchReqKind.SERVICE : DispatchReqKind.PAGE);
}
}

throw notFound();
}

private DispatchResult call(PojoRequest req, String[] parts, int paramsFrom, DispatchTarget target,
DispatchReqKind kind) throws PojoHandlerNotFoundException, PojoDispatchException {
Object componentInstance = Cls.newInstance(target.clazz);
if (target.method != null) {
Object callResult = doDispatch(req, target.method, componentInstance, parts, paramsFrom);
return new DispatchResult(callResult, kind);
} else {
throw notFound();
}
}

private Object doDispatch(PojoRequest request, Method method, Object component, String[] parts, int paramsFrom)
throws PojoHandlerNotFoundException, PojoDispatchException {

Expand Down Expand Up @@ -312,7 +329,7 @@ private Map<String, Object> mapArg(PojoRequest request, String[] parts, int para

protected List<DispatchReq> getMethodActions(String componentPath, Method method) {
String path = UTILS.path(componentPath, method.getName());
return U.list(new DispatchReq("", path, true));
return U.list(new DispatchReq("", path, DispatchReqKind.SERVICE));
}

private boolean shouldExpose(Method method) {
Expand Down
Expand Up @@ -30,11 +30,13 @@
@Since("2.0.0")
public class PojoRequestImpl implements PojoRequest {

private final boolean event;
private final String command;
private final String path;
private final Map<String, Object> params;

public PojoRequestImpl(String command, String path, Map<String, Object> params) {
public PojoRequestImpl(boolean event, String command, String path, Map<String, Object> params) {
this.event = event;
this.command = command;
this.path = path;
this.params = params;
Expand Down Expand Up @@ -62,7 +64,13 @@ public Object param(String name) {

@Override
public String toString() {
return "PojoRequestImpl [command=" + command + ", path=" + path + ", params=" + params + "]";
return "PojoRequestImpl [event=" + event + ", command=" + command + ", path=" + path + ", params=" + params
+ "]";
}

@Override
public boolean isEvent() {
return event;
}

}

0 comments on commit 3f57964

Please sign in to comment.