001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.hivemind.service; 016 017 import java.lang.reflect.Method; 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.List; 021 import java.util.Map; 022 import java.util.NoSuchElementException; 023 024 import org.apache.hivemind.util.Defense; 025 026 /** 027 * Utility used to iterate over the visible methods of a class. 028 * 029 * @author Howard Lewis Ship 030 */ 031 public class MethodIterator 032 { 033 private boolean _toString; 034 035 private int _index = 0; 036 037 /** @since 1.1 */ 038 private int _count; 039 040 /** @since 1.1 */ 041 private List _signatures; 042 043 public MethodIterator(Class subjectClass) 044 { 045 Defense.notNull(subjectClass, "subjectClass"); 046 047 Method[] methods = subjectClass.getMethods(); 048 049 Map map = new HashMap(); 050 051 for (int i = 0; i < methods.length; i++) 052 processMethod(methods[i], map); 053 054 _signatures = new ArrayList(map.values()); 055 _count = _signatures.size(); 056 } 057 058 /** @since 1.1 */ 059 private void processMethod(Method m, Map map) 060 { 061 _toString |= ClassFabUtils.isToString(m); 062 063 MethodSignature sig = new MethodSignature(m); 064 String uid = sig.getUniqueId(); 065 066 MethodSignature existing = (MethodSignature) map.get(uid); 067 068 if (existing == null || sig.isOverridingSignatureOf(existing)) 069 map.put(uid, sig); 070 } 071 072 public boolean hasNext() 073 { 074 return _index < _count; 075 } 076 077 /** 078 * Returns the next method (as a {@link MethodSignature}, returning null when all are 079 * exhausted. Each method signature is returned exactly once (even if the same method signature 080 * is defined in multiple inherited classes or interfaces). The order in which method signatures 081 * are returned is not specified. 082 * 083 * @throws NoSuchElementException 084 * if there are no more signatures 085 */ 086 public MethodSignature next() 087 { 088 if (_index >= _count) 089 throw new NoSuchElementException(); 090 091 return (MethodSignature) _signatures.get(_index++); 092 } 093 094 /** 095 * Returns true if the method <code>public String toString()</code> is part of the interface. 096 */ 097 public boolean getToString() 098 { 099 return _toString; 100 } 101 }