Skip to content

Commit

Permalink
Don't reference classes directly in WebSocketVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
graemerocher committed Sep 21, 2018
1 parent 5f9ace5 commit fa90632
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ class TypeElementVisitorStart implements ASTTransformation {
for (ServiceDefinition<TypeElementVisitor> definition: serviceLoader) {
if (definition.isPresent()) {
TypeElementVisitor visitor = definition.load()
LoadedVisitor newLoadedVisitor = new LoadedVisitor(visitor, visitorContext)
loadedVisitors.put(definition.getName(), newLoadedVisitor)
try {
LoadedVisitor newLoadedVisitor = new LoadedVisitor(visitor, visitorContext)
loadedVisitors.put(definition.getName(), newLoadedVisitor)
} catch (TypeNotPresentException e) {
// skip, all classes not on classpath
} catch (NoClassDefFoundError e) {
// skip, all classes not on classpath
} catch (ClassNotFoundException e) {
// skip, all classes not on classpath
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
for (ServiceDefinition<TypeElementVisitor> definition : serviceLoader) {
if (definition.isPresent()) {
TypeElementVisitor visitor = definition.load();
loadedVisitors.put(definition.getName(), new LoadedVisitor(
visitor,
visitorContext,
genericUtils,
processingEnv
));
try {
loadedVisitors.put(definition.getName(), new LoadedVisitor(
visitor,
visitorContext,
genericUtils,
processingEnv
));
} catch (TypeNotPresentException | NoClassDefFoundError e) {
// skip, dependent classes not classpath
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import io.micronaut.core.util.ArrayUtils;
import io.micronaut.http.uri.UriMatchTemplate;
import io.micronaut.inject.visitor.*;
import io.micronaut.websocket.CloseReason;
import io.micronaut.websocket.WebSocketSession;
import io.micronaut.websocket.annotation.*;

import java.util.*;
Expand All @@ -34,41 +32,49 @@
*/
public class WebSocketVisitor implements TypeElementVisitor<WebSocketComponent, WebSocketMapping> {

private static final String WEB_SOCKET_COMPONENT = "io.micronaut.websocket.annotation.WebSocketComponent";
private static final String WEB_SOCKET_SESSION = "io.micronaut.websocket.WebSocketSession";
private static final String CLOSE_REASON = "io.micronaut.websocket.CloseReason";
private static final String ON_OPEN = "io.micronaut.websocket.annotation.OnOpen";
private static final String ON_CLOSE = "io.micronaut.websocket.annotation.OnClose";
private static final String ON_MESSAGE = "io.micronaut.websocket.annotation.OnMessage";
private static final String ON_ERROR = "io.micronaut.websocket.annotation.OnError";

private Map<String, UriMatchTemplate> uriCache = new HashMap<>(3);

@Override
public void visitMethod(MethodElement element, VisitorContext context) {
String uri = element.getValue(WebSocketComponent.class, String.class).orElse(WebSocketComponent.DEFAULT_URI);
String uri = element.getValue(WEB_SOCKET_COMPONENT, String.class).orElse("/ws");
UriMatchTemplate template = uriCache.computeIfAbsent(uri, UriMatchTemplate::of);
List<String> variables = template.getVariableNames();
ParameterElement[] parameters = element.getParameters();
if (ArrayUtils.isNotEmpty(parameters)) {

if (element.isAnnotationPresent(OnOpen.class)) {
if (element.hasAnnotation(ON_OPEN)) {
for (ParameterElement parameter : parameters) {
if (isInvalidParameter(variables, parameter, WebSocketSession.class)) {
if (isInvalidParameter(variables, parameter, WEB_SOCKET_SESSION)) {
context.fail("Parameter to @OnOpen must either be a URI variable, a WebSocketSession or annotated with an HTTP binding annotation (such as @Header)", parameter);
break;
}
}
} else if (element.isAnnotationPresent(OnClose.class)) {
} else if (element.hasAnnotation(ON_CLOSE)) {
for (ParameterElement parameter : parameters) {
if (isInvalidParameter(variables, parameter, WebSocketSession.class, CloseReason.class)) {
if (isInvalidParameter(variables, parameter, WEB_SOCKET_SESSION, CLOSE_REASON)) {
context.fail("Parameter to @OnClose must either be a URI variable, a CloseReason, a WebSocketSession or annotated with an HTTP binding annotation (such as @Header)", parameter);
break;
}
}
} else if (element.isAnnotationPresent(OnError.class)) {
} else if (element.hasAnnotation(ON_ERROR)) {
for (ParameterElement parameter : parameters) {
if (isInvalidParameter(variables, parameter, WebSocketSession.class, Throwable.class)) {
if (isInvalidParameter(variables, parameter, WEB_SOCKET_SESSION, Throwable.class.getName())) {
context.fail("Parameter to @OnError must either be a URI variable, a Throwable, a WebSocketSession or annotated with an HTTP binding annotation (such as @Header)", parameter);
break;
}
}
} else if (element.isAnnotationPresent(OnMessage.class)) {
} else if (element.hasAnnotation(ON_MESSAGE)) {
List<ParameterElement> bodyParameters = new ArrayList<>(3);
for (ParameterElement parameter : parameters) {
if (isInvalidParameter(variables, parameter, WebSocketSession.class)) {
if (isInvalidParameter(variables, parameter, WEB_SOCKET_SESSION)) {
// potential body parameter
bodyParameters.add(parameter);
}
Expand All @@ -82,7 +88,7 @@ public void visitMethod(MethodElement element, VisitorContext context) {

}

private boolean isInvalidParameter(List<String> variables, ParameterElement parameter, Class... validTypes) {
private boolean isInvalidParameter(List<String> variables, ParameterElement parameter, String... validTypes) {
String parameterName = parameter.getName();
ClassElement parameterType = parameter.getType();

Expand Down

0 comments on commit fa90632

Please sign in to comment.