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 015package org.apache.hivemind.service; 016 017import java.lang.reflect.Method; 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.NoSuchElementException; 023 024import 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 */ 031public 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}