001    package net.sourceforge.retroweaver.runtime.java.lang;
002    
003    import java.lang.reflect.Method;
004    import java.util.Collection;
005    import java.util.Iterator;
006    
007    /**
008     * Replacements for methods added to java.lang.Iterable in Java 1.5, used
009     * for targets of the "foreach" statement.
010     */
011    public final class Iterable_ {
012    
013            private Iterable_() {
014                    // private constructor
015            }
016    
017            /**
018             * Returns an iterator for <code>iterable</code>.
019             * 
020             * @param iterable  the object to get the Iterator from
021             * @return an Iterator.
022             * @throws UnsupportedOperationException if an iterator method can not be found.
023             * @throws NullPointerException if <code>iterable</code> is null.
024             */
025            public static Iterator iterator(final Object iterable) {
026                    if (iterable == null) {
027                            throw new NullPointerException(); // NOPMD by xlv
028                    }
029    
030                    if (iterable instanceof Collection) {
031                            // core jdk classes implementing Iterable: they are not weaved but,
032                            // at least in 1.5, they all implement Collection and as its iterator
033                            // method exits in pre 1.5 jdks, a valid Iterator can be returned.
034                            return ((Collection) iterable).iterator();
035                    }
036    
037                    if (iterable instanceof net.sourceforge.retroweaver.runtime.java.lang.Iterable) {
038                            // weaved classes inheriting from Iterable
039                            return ((net.sourceforge.retroweaver.runtime.java.lang.Iterable) iterable).iterator();
040                    }
041    
042                    // for future jdk Iterable classes not inheriting from Collection
043                    // use reflection to try to get the iterator if it was present pre 1.5
044                    try {
045                            final Method method = iterable.getClass().getMethod("iterator", (Class[]) null);
046                            if (method != null) {
047                                    return (Iterator) method.invoke(iterable, (Object[]) null);
048                            }
049                    } catch (Exception ignored) { // NOPMD by xlv
050                    }
051    
052                    throw new UnsupportedOperationException("iterator call on " + iterable.getClass());
053            }
054    
055    }