001: package org.acm.seguin.pmd.jaxen;
002:
003: import net.sourceforge.jrefactory.ast.Node;
004:
005: import java.lang.reflect.InvocationTargetException;
006: import java.lang.reflect.Method;
007: import java.util.Iterator;
008:
009: /**
010: * Description of the Class
011: *
012: *@author mikea
013: *@created September 19, 2003
014: */
015: public class AttributeAxisIterator implements Iterator {
016:
017: private final static Object[] EMPTY_OBJ_ARRAY = new Object[0];
018: private Object currObj;
019: private Method[] methods;
020: private int position;
021: private Node node;
022:
023: /**
024: * Constructor for the AttributeAxisIterator object
025: *
026: *@param contextNode Description of the Parameter
027: */
028: public AttributeAxisIterator(Node contextNode) {
029: this .node = contextNode;
030: this .methods = contextNode.getClass().getMethods();
031: // FIXME? MRA this is a hack to get these attributes in the right order
032: java.util.List methodsList = new java.util.ArrayList(
033: java.util.Arrays.asList(this .methods));
034: java.util.List newMA = new java.util.ArrayList();
035: for (Iterator i = methodsList.iterator(); i.hasNext();) {
036: Method method = (Method) i.next();
037: String name = method.getName();
038: Class returnType = method.getReturnType();
039: if ((method.getParameterTypes().length == 0)
040: && (Void.TYPE != returnType)) {
041: if (name.equals("getBeginLine")) {
042: i.remove();
043: newMA.add(method);
044: }
045: }
046: }
047:
048: for (Iterator i = methodsList.iterator(); i.hasNext();) {
049: Method method = (Method) i.next();
050: String name = method.getName();
051: Class returnType = method.getReturnType();
052: if ((method.getParameterTypes().length == 0)
053: && (Void.TYPE != returnType)) {
054: if (name.equals("getBeginColumn")) {
055: i.remove();
056: newMA.add(method);
057: }
058: }
059: }
060: for (Iterator i = methodsList.iterator(); i.hasNext();) {
061: Method method = (Method) i.next();
062: String name = method.getName();
063: Class returnType = method.getReturnType();
064: if ((method.getParameterTypes().length == 0)
065: && (Void.TYPE != returnType)) {
066: if (name.equals("getEndLine")) {
067: i.remove();
068: newMA.add(method);
069: }
070: }
071: }
072: for (Iterator i = methodsList.iterator(); i.hasNext();) {
073: Method method = (Method) i.next();
074: String name = method.getName();
075: Class returnType = method.getReturnType();
076: if ((method.getParameterTypes().length == 0)
077: && (Void.TYPE != returnType)) {
078: if (name.equals("getEndColumn")) {
079: i.remove();
080: newMA.add(method);
081: }
082: }
083: }
084: newMA.addAll(methodsList);
085: this .methods = (Method[]) newMA.toArray(this .methods);
086: this .position = 0;
087: this .currObj = getNextAttribute();
088: }
089:
090: /**
091: * Description of the Method
092: *
093: *@return Description of the Return Value
094: */
095: public Object next() {
096: if (currObj == null) {
097: throw new IndexOutOfBoundsException();
098: }
099: Object ret = currObj;
100: currObj = getNextAttribute();
101: return ret;
102: }
103:
104: /**
105: * Description of the Method
106: *
107: *@return Description of the Return Value
108: */
109: public boolean hasNext() {
110: return currObj != null;
111: }
112:
113: /**
114: * Description of the Method
115: */
116: public void remove() {
117: throw new UnsupportedOperationException();
118: }
119:
120: /**
121: * Gets the nextAttribute attribute of the AttributeAxisIterator object
122: *
123: *@return The nextAttribute value
124: */
125: private Attribute getNextAttribute() {
126: while (position < methods.length) {
127: Method method = methods[position];
128: try {
129: if (isAttribute(method)) {
130: Class returnType = method.getReturnType();
131: if (Boolean.TYPE == returnType
132: || String.class == returnType
133: || Integer.TYPE == returnType) {
134: Attribute attribute = getAttribute(node, method);
135: if (attribute != null) {
136: return attribute;
137: }
138: }
139: }
140: } catch (IllegalAccessException e) {
141: e.printStackTrace();
142: } catch (InvocationTargetException e) {
143: e.printStackTrace();
144: } finally {
145: position++;
146: }
147: }
148: return null;
149: }
150:
151: /**
152: * Gets the attribute attribute of the AttributeAxisIterator object
153: *
154: *@param node Description of the Parameter
155: *@param method Description of the Parameter
156: *@return The attribute value
157: *@exception IllegalAccessException Description of the Exception
158: *@exception InvocationTargetException Description of the Exception
159: */
160: protected Attribute getAttribute(Node node, Method method)
161: throws IllegalAccessException, InvocationTargetException {
162: String name = method.getName();
163: name = truncateMethodName(name);
164: Object value = method.invoke(node, EMPTY_OBJ_ARRAY);
165: if (value != null) {
166: if (value instanceof String) {
167: return new Attribute(node, name, (String) value);
168: } else {
169: return new Attribute(node, name, String.valueOf(value));
170: }
171: } else {
172: return null;
173: }
174: }
175:
176: /**
177: * Description of the Method
178: *
179: *@param name Description of the Parameter
180: *@return Description of the Return Value
181: */
182: protected String truncateMethodName(String name) {
183: String truncatedName = null;
184: if (name.startsWith("is")) {
185: truncatedName = name.substring("is".length());
186: } else if (name.startsWith("uses")) {
187: truncatedName = name.substring("uses".length());
188: } else if (name.startsWith("has")) {
189: truncatedName = name.substring("has".length());
190: } else if (name.startsWith("get")) {
191: truncatedName = name.substring("get".length());
192: } else {
193: truncatedName = name;
194: }
195: return truncatedName;
196: }
197:
198: /**
199: * Gets the attribute attribute of the AttributeAxisIterator object
200: *
201: *@param method Description of the Parameter
202: *@return The attribute value
203: */
204: protected boolean isAttribute(Method method) {
205: String name = method.getName();
206: Class returnType = method.getReturnType();
207: return (method.getParameterTypes().length == 0)
208: && (Void.TYPE != returnType) && !name.startsWith("jjt")
209: && !name.equals("toString") && !name.equals("getScope")
210: && !name.equals("getClass")
211: && !name.equals("getFinallyBlock")
212: && !name.equals("getCatchBlocks")
213: && !name.equals("getTypeNameNode")
214: && !name.equals("getImportedNameNode")
215: && !name.equals("hashCode")
216: // && !name.equals("getImage")// FIXME? MRA
217: && !name.equals("hasAnyChildren") // MRA This attribute should not be visible to XPath
218: && !name.equals("isRequired") // MRA This attribute should not be visible to XPath
219: && !name.equals("getName"); // MRA This attribute should not be visible to XPath
220: }
221: }
|