Rearrange code
This commit is contained in:
@@ -25,6 +25,93 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
*/
|
||||
public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
|
||||
/** Caches the precomputed attribute accessors of a given class. */
|
||||
private static final ConcurrentMap<Class<?>, MethodWrapper[]> METHOD_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
/* Constants used to determine which methods are accessors */
|
||||
private static final Set<Class<?>> CONSIDERED_RETURN_TYPES
|
||||
= new HashSet<>(Arrays.<Class<?>>asList(Integer.TYPE, Boolean.TYPE, Double.TYPE, String.class, Long.TYPE, Character.TYPE, Float.TYPE));
|
||||
private static final Set<String> FILTERED_OUT_NAMES
|
||||
= new HashSet<>(Arrays.asList("toString", "getClass", "getXPathNodeName", "getTypeNameNode", "hashCode", "getImportedNameNode", "getScope"));
|
||||
|
||||
/* Iteration variables */
|
||||
private Attribute currObj;
|
||||
private MethodWrapper[] methodWrappers;
|
||||
private int position;
|
||||
private Node node;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new iterator that enumerates the attributes of the given node.
|
||||
*/
|
||||
public AttributeAxisIterator(Node contextNode) {
|
||||
this.node = contextNode;
|
||||
if (!METHOD_CACHE.containsKey(contextNode.getClass())) {
|
||||
Method[] preFilter = contextNode.getClass().getMethods();
|
||||
List<MethodWrapper> postFilter = new ArrayList<>();
|
||||
for (Method element : preFilter) {
|
||||
if (isAttributeAccessor(element)) {
|
||||
postFilter.add(new MethodWrapper(element));
|
||||
}
|
||||
}
|
||||
METHOD_CACHE.putIfAbsent(contextNode.getClass(), postFilter.toArray(new MethodWrapper[0]));
|
||||
}
|
||||
this.methodWrappers = METHOD_CACHE.get(contextNode.getClass());
|
||||
|
||||
this.position = 0;
|
||||
this.currObj = getNextAttribute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the given method is an attribute accessor,
|
||||
* in which case a corresponding Attribute will be added to
|
||||
* the iterator.
|
||||
*
|
||||
* @param method The method to test
|
||||
*/
|
||||
protected boolean isAttributeAccessor(Method method) {
|
||||
String methodName = method.getName();
|
||||
|
||||
return CONSIDERED_RETURN_TYPES.contains(method.getReturnType())
|
||||
&& method.getParameterTypes().length == 0
|
||||
&& !methodName.startsWith("jjt")
|
||||
&& !FILTERED_OUT_NAMES.contains(methodName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Attribute next() {
|
||||
if (!hasNext()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
Attribute ret = currObj;
|
||||
currObj = getNextAttribute();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currObj != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
private Attribute getNextAttribute() {
|
||||
if (methodWrappers == null || position == methodWrappers.length) {
|
||||
return null;
|
||||
}
|
||||
MethodWrapper m = methodWrappers[position++];
|
||||
return new Attribute(node, m.name, m.method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Associates an attribute accessor with the XPath-accessible
|
||||
* name of the attribute. This is used to avoid recomputing
|
||||
@@ -65,89 +152,4 @@ public class AttributeAxisIterator implements Iterator<Attribute> {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
private Attribute currObj;
|
||||
private MethodWrapper[] methodWrappers;
|
||||
private int position;
|
||||
private Node node;
|
||||
|
||||
private static final ConcurrentMap<Class<?>, MethodWrapper[]> METHOD_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new iterator that enumerates the attributes of the given node.
|
||||
*/
|
||||
public AttributeAxisIterator(Node contextNode) {
|
||||
this.node = contextNode;
|
||||
if (!METHOD_CACHE.containsKey(contextNode.getClass())) {
|
||||
Method[] preFilter = contextNode.getClass().getMethods();
|
||||
List<MethodWrapper> postFilter = new ArrayList<>();
|
||||
for (Method element : preFilter) {
|
||||
if (isAttributeAccessor(element)) {
|
||||
postFilter.add(new MethodWrapper(element));
|
||||
}
|
||||
}
|
||||
METHOD_CACHE.putIfAbsent(contextNode.getClass(), postFilter.toArray(new MethodWrapper[0]));
|
||||
}
|
||||
this.methodWrappers = METHOD_CACHE.get(contextNode.getClass());
|
||||
|
||||
this.position = 0;
|
||||
this.currObj = getNextAttribute();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Attribute next() {
|
||||
if (!hasNext()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
Attribute ret = currObj;
|
||||
currObj = getNextAttribute();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currObj != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
private Attribute getNextAttribute() {
|
||||
if (methodWrappers == null || position == methodWrappers.length) {
|
||||
return null;
|
||||
}
|
||||
MethodWrapper m = methodWrappers[position++];
|
||||
return new Attribute(node, m.name, m.method);
|
||||
}
|
||||
|
||||
|
||||
private static final Set<Class<?>> CONSIDERED_RETURN_TYPES
|
||||
= new HashSet<>(Arrays.<Class<?>>asList(Integer.TYPE, Boolean.TYPE, Double.TYPE, String.class, Long.TYPE, Character.TYPE, Float.TYPE));
|
||||
|
||||
private static final Set<String> FILTERED_OUT_NAMES
|
||||
= new HashSet<>(Arrays.asList("toString", "getClass", "getXPathNodeName", "getTypeNameNode", "hashCode", "getImportedNameNode", "getScope"));
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the given method is an attribute accessor,
|
||||
* in which case a corresponding Attribute will be added to
|
||||
* the iterator.
|
||||
*
|
||||
* @param method The method to test
|
||||
*/
|
||||
protected boolean isAttributeAccessor(Method method) {
|
||||
String methodName = method.getName();
|
||||
|
||||
return CONSIDERED_RETURN_TYPES.contains(method.getReturnType())
|
||||
&& method.getParameterTypes().length == 0
|
||||
&& !methodName.startsWith("jjt")
|
||||
&& !FILTERED_OUT_NAMES.contains(methodName);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user