01: // Copyright 2004, 2005, 2006 The Apache Software Foundation
02: //
03: // Licensed under the Apache License, Version 2.0 (the "License");
04: // you may not use this file except in compliance with the License.
05: // You may obtain a copy of the License at
06: //
07: // http://www.apache.org/licenses/LICENSE-2.0
08: //
09: // Unless required by applicable law or agreed to in writing, software
10: // distributed under the License is distributed on an "AS IS" BASIS,
11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12: // See the License for the specific language governing permissions and
13: // limitations under the License.
14:
15: package org.apache.tapestry.ioc.services;
16:
17: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
18: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
19:
20: import java.lang.reflect.Method;
21: import java.util.List;
22: import java.util.Map;
23: import java.util.NoSuchElementException;
24:
25: /**
26: * Utility used to iterate over the publically visible methods of a class or interface. The
27: * MethodIterator understands some complications that can occur when a class inherits the same
28: * method from multiple interfaces and with slightly different signatures (due to the fact that
29: * declared thrown exceptions can vary slightly for the "same" method).
30: *
31: * @see org.apache.tapestry.ioc.services.MethodSignature#isOverridingSignatureOf(MethodSignature)
32: */
33: public class MethodIterator {
34: private boolean _toString;
35:
36: private int _index = 0;
37:
38: private final int _count;
39:
40: private final List<MethodSignature> _signatures;
41:
42: public MethodIterator(Class subjectClass) {
43: Method[] methods = subjectClass.getMethods();
44:
45: Map<String, MethodSignature> map = newMap();
46:
47: for (int i = 0; i < methods.length; i++)
48: processMethod(methods[i], map);
49:
50: _signatures = newList(map.values());
51: _count = _signatures.size();
52: }
53:
54: private void processMethod(Method m,
55: Map<String, MethodSignature> map) {
56: _toString |= ClassFabUtils.isToString(m);
57:
58: MethodSignature sig = new MethodSignature(m);
59: String uid = sig.getUniqueId();
60:
61: MethodSignature existing = map.get(uid);
62:
63: if (existing == null || sig.isOverridingSignatureOf(existing))
64: map.put(uid, sig);
65: }
66:
67: public boolean hasNext() {
68: return _index < _count;
69: }
70:
71: /**
72: * Returns the next method (as a {@link MethodSignature}, returning null when all are
73: * exhausted. Each method signature is returned exactly once (even if the same method signature
74: * is defined in multiple inherited classes or interfaces). The order in which method signatures
75: * are returned is not specified.
76: *
77: * @throws NoSuchElementException
78: * if there are no more signatures
79: */
80: public MethodSignature next() {
81: if (_index >= _count)
82: throw new NoSuchElementException();
83:
84: return _signatures.get(_index++);
85: }
86:
87: /**
88: * Returns true if the method <code>public String toString()</code> is part of the interface.
89: * This will be known immediately after iterator contruction (it is not necessary to iterate the
90: * methods first).
91: */
92: public boolean getToString() {
93: return _toString;
94: }
95: }
|