mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Merge pull request #206 from lukaszlenart/scan-deeper
WW-4912: scan package-info and class at the same time
This commit is contained in:
@@ -18,9 +18,12 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.util;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -129,7 +132,7 @@ public class AnnotationUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the annotation on the given class or the package of the class. This searchs up the
|
||||
* Returns the annotation on the given class or the package of the class. This searches up the
|
||||
* class hierarchy and the package hierarchy for the closest match.
|
||||
*
|
||||
* @param <T> class type
|
||||
@@ -154,4 +157,36 @@ public class AnnotationUtils {
|
||||
|
||||
return ann;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the annotation on the given class or the package of the class.
|
||||
* This searches up the class hierarchy and the package hierarchy.
|
||||
*
|
||||
* @param <T> class type
|
||||
* @param clazz The class to search for the annotation.
|
||||
* @param annotationClass The Class of the annotation.
|
||||
* @return List of the annotations or an empty list.
|
||||
*/
|
||||
public static <T extends Annotation> List<T> findAnnotations(Class<?> clazz, Class<T> annotationClass) {
|
||||
List<T> anns = new ArrayList<>();
|
||||
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
classes.add(clazz);
|
||||
|
||||
classes.addAll(ClassUtils.getAllSuperclasses(clazz));
|
||||
classes.addAll(ClassUtils.getAllInterfaces(clazz));
|
||||
for (Class<?> aClass : classes) {
|
||||
T ann = aClass.getAnnotation(annotationClass);
|
||||
if (ann != null) {
|
||||
anns.add(ann);
|
||||
}
|
||||
|
||||
ann = aClass.getPackage().getAnnotation(annotationClass);
|
||||
if (ann != null) {
|
||||
anns.add(ann);
|
||||
}
|
||||
}
|
||||
|
||||
return anns;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,19 @@
|
||||
package com.opensymphony.xwork2.util;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.Dummy2Class;
|
||||
import com.opensymphony.xwork2.util.annotation.Dummy3Class;
|
||||
import com.opensymphony.xwork2.util.annotation.DummyClass;
|
||||
import com.opensymphony.xwork2.util.annotation.DummyClassExt;
|
||||
import com.opensymphony.xwork2.util.annotation.MyAnnotation;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.MyAnnotation2;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Dan Oxlade, dan d0t oxlade at gmail d0t c0m
|
||||
*/
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
public class AnnotationUtilsTest extends TestCase {
|
||||
|
||||
public void testFindAnnotationOnClass() {
|
||||
@@ -41,4 +46,25 @@ public class AnnotationUtilsTest extends TestCase {
|
||||
assertEquals("package-test", ns.value());
|
||||
}
|
||||
|
||||
public void testFindAnnotationOnParents() {
|
||||
MyAnnotation2 ns = AnnotationUtils.findAnnotation(Dummy3Class.class, MyAnnotation2.class);
|
||||
assertNotNull(ns);
|
||||
assertEquals("abstract-abstract", ns.value());
|
||||
}
|
||||
|
||||
public void testFindAnnotationsOnAll() {
|
||||
List<MyAnnotation> annotations = AnnotationUtils.findAnnotations(DummyClassExt.class, MyAnnotation.class);
|
||||
|
||||
assertThat(annotations)
|
||||
.isNotNull()
|
||||
.isNotEmpty()
|
||||
.hasSize(5);
|
||||
|
||||
Set<String> values = new HashSet<>();
|
||||
for (MyAnnotation annotation : annotations) {
|
||||
values.add(annotation.value());
|
||||
}
|
||||
assertThat(values).contains("class-test", "package-test", "interface-test", "package2-test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 com.opensymphony.xwork2.util.annotation;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.pkg1.AbstractDummyAction;
|
||||
|
||||
public class Dummy3Class extends AbstractDummyAction{
|
||||
|
||||
}
|
||||
@@ -18,8 +18,10 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.util.annotation;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.pkg2.Package2DummyInterface;
|
||||
|
||||
@MyAnnotation("class-test")
|
||||
public class DummyClass {
|
||||
public class DummyClass implements Package2DummyInterface {
|
||||
|
||||
public DummyClass() {
|
||||
}
|
||||
|
||||
@@ -23,4 +23,6 @@ import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyAnnotation2 {
|
||||
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 com.opensymphony.xwork2.util.annotation.pkg1;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.MyAnnotation2;
|
||||
|
||||
@MyAnnotation2("abstract-abstract")
|
||||
public class AbstractAbstractDummyAction {
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 com.opensymphony.xwork2.util.annotation.pkg1;
|
||||
|
||||
public class AbstractDummyAction extends AbstractAbstractDummyAction {
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 com.opensymphony.xwork2.util.annotation.pkg2;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.MyAnnotation;
|
||||
|
||||
@MyAnnotation("interface-test")
|
||||
public interface Package2DummyInterface {
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
|
||||
@MyAnnotation("package2-test")
|
||||
package com.opensymphony.xwork2.util.annotation.pkg2;
|
||||
|
||||
import com.opensymphony.xwork2.util.annotation.MyAnnotation;
|
||||
+7
-8
@@ -749,13 +749,13 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
}
|
||||
|
||||
private Set<String> getAllowedMethods(Class<?> actionClass) {
|
||||
AllowedMethods annotation = AnnotationUtils.findAnnotation(actionClass, AllowedMethods.class);
|
||||
if (annotation == null) {
|
||||
List<AllowedMethods> annotations = AnnotationUtils.findAnnotations(actionClass, AllowedMethods.class);
|
||||
if (annotations == null || annotations.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
} else {
|
||||
Set<String> methods = new HashSet<>();
|
||||
for (String method : annotation.value()) {
|
||||
methods.add(method);
|
||||
for (AllowedMethods allowedMethods : annotations) {
|
||||
methods.addAll(Arrays.asList(allowedMethods.value()));
|
||||
}
|
||||
return methods;
|
||||
}
|
||||
@@ -924,7 +924,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
String actionMethod, Action annotation, Set<String> allowedMethods) {
|
||||
String className = actionClass.getName();
|
||||
if (annotation != null) {
|
||||
actionName = annotation.value() != null && annotation.value().equals(Action.DEFAULT_VALUE) ? actionName : annotation.value();
|
||||
actionName = annotation.value().equals(Action.DEFAULT_VALUE) ? actionName : annotation.value();
|
||||
actionName = StringUtils.contains(actionName, "/") && !slashesInActionNames ? StringUtils.substringAfterLast(actionName, "/") : actionName;
|
||||
if(!Action.DEFAULT_VALUE.equals(annotation.className())){
|
||||
className = annotation.className();
|
||||
@@ -960,7 +960,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
actionConfig.addParams(StringTools.createParameterMap(annotation.params()));
|
||||
|
||||
//add exception mappings from annotation
|
||||
if (annotation != null && annotation.exceptionMappings() != null)
|
||||
if (annotation != null)
|
||||
actionConfig.addExceptionMappings(buildExceptionMappings(annotation.exceptionMappings(), actionName));
|
||||
|
||||
//add exception mapping from class
|
||||
@@ -997,8 +997,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
exceptionMapping.result(), actionName);
|
||||
ExceptionMappingConfig.Builder builder = new ExceptionMappingConfig.Builder(null, exceptionMapping
|
||||
.exception(), exceptionMapping.result());
|
||||
if (exceptionMapping.params() != null)
|
||||
builder.addParams(StringTools.createParameterMap(exceptionMapping.params()));
|
||||
builder.addParams(StringTools.createParameterMap(exceptionMapping.params()));
|
||||
exceptionMappings.add(builder.build());
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -544,10 +544,14 @@ public class PackageBasedActionConfigBuilderTest extends TestCase {
|
||||
assertEquals("struts-default", pkgConfig.getParents().get(0).getName());
|
||||
|
||||
ActionConfig actionConfig = pkgConfig.getActionConfigs().get("class-level-allowed-methods");
|
||||
assertEquals(actionConfig.getAllowedMethods().size(), 5);
|
||||
assertEquals(7, actionConfig.getAllowedMethods().size());
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("execute"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("end"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("input"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("cancel"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("start"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("home"));
|
||||
assertTrue(actionConfig.getAllowedMethods().contains("browse"));
|
||||
|
||||
/* org.apache.struts2.convention.actions.allowedmethods.sub package level */
|
||||
pkgConfig = configuration.getPackageConfig("org.apache.struts2.convention.actions.allowedmethods.sub#struts-default#/allowedmethods/sub");
|
||||
|
||||
Reference in New Issue
Block a user