mirror of
https://github.com/apache/struts.git
synced 2026-08-06 15:17:00 +00:00
WW-4166 Improves way of discovering tag's attributes
This commit is contained in:
@@ -25,6 +25,8 @@ import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.AnnotationUtils;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsException;
|
||||
@@ -43,9 +45,12 @@ import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* Base class to extend for UI components.
|
||||
@@ -55,8 +60,15 @@ import java.util.Stack;
|
||||
*/
|
||||
public class Component {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Component.class);
|
||||
|
||||
public static final String COMPONENT_STACK = "__component_stack";
|
||||
|
||||
/**
|
||||
* Caches information about common tag's attributes to reduce scanning for annotation @StrutsTagAttribute
|
||||
*/
|
||||
protected static ConcurrentMap<Class<?>, Collection<String>> standardAttributesMap = new ConcurrentHashMap<Class<?>, Collection<String>>();
|
||||
|
||||
protected ValueStack stack;
|
||||
protected Map parameters;
|
||||
protected ActionMapper actionMapper;
|
||||
@@ -502,13 +514,24 @@ public class Component {
|
||||
* @return true if attribute with the same name was already defined
|
||||
*/
|
||||
public boolean isValidTagAttribute(String attrName) {
|
||||
Collection<Method> annotatedMethods = AnnotationUtils.getAnnotatedMethods(getClass(), StrutsTagAttribute.class);
|
||||
for (Method annotatedMethod : annotatedMethods) {
|
||||
if (annotatedMethod.getName().contains(StringUtils.capitalize(attrName))) {
|
||||
return true;
|
||||
return getStandardAttributes().contains(attrName);
|
||||
}
|
||||
|
||||
/**
|
||||
* If needed caches all methods annotated by given annotation to avoid further scans
|
||||
*/
|
||||
protected Collection<String> getStandardAttributes() {
|
||||
Class clz = getClass();
|
||||
Collection<String> standardAttributes = standardAttributesMap.get(clz);
|
||||
if (standardAttributes == null) {
|
||||
Collection<Method> methods = AnnotationUtils.getAnnotatedMethods(clz, StrutsTagAttribute.class);
|
||||
standardAttributes = new HashSet<String>(methods.size());
|
||||
for(Method m : methods) {
|
||||
standardAttributes.add(StringUtils.uncapitalize(m.getName().substring(3)));
|
||||
}
|
||||
standardAttributesMap.putIfAbsent(clz, standardAttributes);
|
||||
}
|
||||
return false;
|
||||
return standardAttributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -517,9 +517,6 @@ public abstract class UIBean extends Component {
|
||||
protected String uiThemeExpansionToken;
|
||||
protected TemplateEngineManager templateEngineManager;
|
||||
|
||||
// dynamic attributes support for tags used with FreeMarker templates
|
||||
protected static ConcurrentMap<Class, Set<String>> standardAttributesMap = new ConcurrentHashMap<Class, Set<String>>();
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
|
||||
public void setDefaultTemplateDir(String dir) {
|
||||
this.defaultTemplateDir = dir;
|
||||
@@ -1271,40 +1268,16 @@ public abstract class UIBean extends Component {
|
||||
/**
|
||||
* supports dynamic attributes for freemarker ui tags
|
||||
* @see https://issues.apache.org/jira/browse/WW-3174
|
||||
* @see https://issues.apache.org/jira/browse/WW-4166
|
||||
*/
|
||||
public void copyParams(Map params) {
|
||||
super.copyParams(params);
|
||||
Set<String> standardAttributes = getStandardAttributes();
|
||||
public void copyParams(Map params) {
|
||||
super.copyParams(params);
|
||||
for (Object o : params.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) o;
|
||||
String key = (String) entry.getKey();
|
||||
if (!key.equals("dynamicAttributes") && !standardAttributes.contains(key)){
|
||||
if(!isValidTagAttribute(key) && !key.equals("dynamicAttributes"))
|
||||
dynamicAttributes.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<String> getStandardAttributes() {
|
||||
Class clz = getClass();
|
||||
Set<String> standardAttributes = standardAttributesMap.get(clz);
|
||||
if (standardAttributes == null) {
|
||||
standardAttributes = new HashSet<String>();
|
||||
while (clz != null) {
|
||||
for (Field f : clz.getDeclaredFields()) {
|
||||
if (Modifier.isProtected(f.getModifiers())
|
||||
&& (f.getType().equals(String.class) || clz.equals(ListUIBean.class)
|
||||
&& f.getName().equals("list")))
|
||||
standardAttributes.add(f.getName());
|
||||
}
|
||||
if (clz.equals(UIBean.class)) {
|
||||
break;
|
||||
} else {
|
||||
clz = clz.getSuperclass();
|
||||
}
|
||||
}
|
||||
standardAttributesMap.putIfAbsent(clz, standardAttributes);
|
||||
}
|
||||
return standardAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user