Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* 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.
*/
package br.com.caelum.vraptor.http.route;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Predicates.instanceOf;
import static com.google.common.base.Predicates.or;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Arrays.asList;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javassist.Modifier;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import net.vidageek.mirror.dsl.Mirror;
import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Options;
import br.com.caelum.vraptor.Patch;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.controller.BeanClass;
import br.com.caelum.vraptor.controller.HttpMethod;
import br.com.caelum.vraptor.util.StringUtils;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
/**
* The default parser routes creator uses the path annotation to create rules.
* Note that methods are only registered to be public accessible if the type is
* annotated with @Controller.
*
* If you want to override the convention for default URI, you can create a
* class like:
*
* public class MyRoutesParser extends PathAnnotationRoutesParser { //delegate
* constructor protected String extractControllerNameFrom(Class<?> type) {
* return //your convention here }
*
* protected String defaultUriFor(String controllerName, String methodName) {
* return //your convention here } }
*
* @author Guilherme Silveira
* @author Lucas Cavalcanti
*/
@ApplicationScoped
public class PathAnnotationRoutesParser implements RoutesParser {
private final Router router;
/**
* @deprecated CDI eyes only
*/
protected PathAnnotationRoutesParser() {
this(null);
}
@Inject
public PathAnnotationRoutesParser(Router router) {
this.router = router;
}
@Override
public List rulesFor(BeanClass controller) {
Class> baseType = controller.getType();
return registerRulesFor(baseType);
}
protected List registerRulesFor(Class> baseType) {
EnumSet typeMethods = getHttpMethods(baseType);
List routes = new ArrayList<>();
for (Method javaMethod : baseType.getMethods()) {
if (isEligible(javaMethod)) {
String[] uris = getURIsFor(javaMethod, baseType);
for (String uri : uris) {
RouteBuilder rule = router.builderFor(uri);
EnumSet methods = getHttpMethods(javaMethod);
rule.with(methods.isEmpty() ? typeMethods : methods);
if(javaMethod.isAnnotationPresent(Path.class)){
rule.withPriority(javaMethod.getAnnotation(Path.class).priority());
}
if (getUris(javaMethod).length > 0) {
rule.withPriority(Path.DEFAULT);
}
rule.is(baseType, javaMethod);
routes.add(rule.build());
}
}
}
return routes;
}
private EnumSet getHttpMethods(AnnotatedElement annotated) {
EnumSet methods = EnumSet.noneOf(HttpMethod.class);
for (HttpMethod method : HttpMethod.values()) {
if (annotated.isAnnotationPresent(method.getAnnotation())) {
methods.add(method);
}
}
return methods;
}
protected boolean isEligible(Method javaMethod) {
return Modifier.isPublic(javaMethod.getModifiers())
&& !Modifier.isStatic(javaMethod.getModifiers())
&& !javaMethod.isBridge()
&& !javaMethod.getDeclaringClass().equals(Object.class);
}
protected String[] getURIsFor(Method javaMethod, Class> type) {
if (javaMethod.isAnnotationPresent(Path.class)) {
String[] uris = javaMethod.getAnnotation(Path.class).value();
checkArgument(uris.length > 0, "You must specify at least one path on @Path at %s", javaMethod);
checkArgument(getUris(javaMethod).length == 0,
"You should specify paths either in @Path(\"/path\") or @Get(\"/path\") (or @Post, @Put, @Delete), not both at %s", javaMethod);
fixURIs(type, uris);
return uris;
}
String[] uris = getUris(javaMethod);
if(uris.length > 0){
fixURIs(type, uris);
return uris;
}
return new String[] { defaultUriFor(extractControllerNameFrom(type), javaMethod.getName()) };
}
protected String[] getUris(Method javaMethod){
Annotation method = FluentIterable.from(asList(javaMethod.getAnnotations()))
.filter(instanceOfMethodAnnotation())
.first().orNull();
if (method == null) {
return new String[0];
}
return (String[]) new Mirror().on(method).invoke().method("value").withoutArgs();
}
protected void fixURIs(Class> type, String[] uris) {
String prefix = extractPrefix(type);
for (int i = 0; i < uris.length; i++) {
if (isNullOrEmpty(prefix)) {
uris[i] = fixLeadingSlash(uris[i]);
} else if (isNullOrEmpty(uris[i])) {
uris[i] = prefix;
} else {
uris[i] = removeTrailingSlash(prefix) + fixLeadingSlash(uris[i]);
}
}
}
protected String removeTrailingSlash(String prefix) {
return prefix.replaceFirst("/$", "");
}
protected String extractPrefix(Class> type) {
if (type.isAnnotationPresent(Path.class)) {
String[] uris = type.getAnnotation(Path.class).value();
checkArgument(uris.length == 1, "You must specify exactly one path on @Path at %s", type);
return fixLeadingSlash(uris[0]);
} else {
return "";
}
}
private String fixLeadingSlash(String uri) {
if (!uri.startsWith("/")) {
return "/" + uri;
}
return uri;
}
/**
* You can override this method for use a different convention for your
* controller name, given a type
*/
protected String extractControllerNameFrom(Class> type) {
String prefix = extractPrefix(type);
if (isNullOrEmpty(prefix)) {
String baseName = StringUtils.lowercaseFirst(type.getSimpleName());
if (baseName.endsWith("Controller")) {
return "/" + baseName.substring(0, baseName.lastIndexOf("Controller"));
}
return "/" + baseName;
} else {
return prefix;
}
}
/**
* You can override this method for use a different convention for your
* default URI, given a controller name and a method name
*/
protected String defaultUriFor(String controllerName, String methodName) {
return controllerName + "/" + methodName;
}
private Predicate instanceOfMethodAnnotation() {
return or(instanceOf(Get.class), instanceOf(Post.class), instanceOf(Put.class), instanceOf(Delete.class), instanceOf(Options.class), instanceOf(Patch.class));
}
}