001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.felix.framework.util;
020    
021    import java.util.Enumeration;
022    import java.util.NoSuchElementException;
023    
024    public class CompoundEnumeration implements Enumeration
025    {
026        private Enumeration[] m_enums = null;
027        private int index = 0;
028    
029        public CompoundEnumeration(Enumeration[] enums)
030        {
031            m_enums = enums;
032        }
033    
034        public boolean hasMoreElements()
035        {
036            // if the current enum is null that means this enum is finished
037            if (currentEnumeration() == null)
038            {
039                // No next enum
040                return false;
041            }
042            // If the current enum has more elements, lets go
043            return currentEnumeration().hasMoreElements();
044        }
045    
046        private Enumeration findNextEnumeration(boolean moveCursor)
047        {
048            return findNextEnumeration(index, moveCursor);
049        }
050    
051        private Enumeration findNextEnumeration(int cursor, boolean moveCursor)
052        {
053            // next place in the array
054            int next = cursor + 1;
055            // If the cursor is still in the array
056            if (next < m_enums.length)
057            {
058    
059                // If there is something in that place
060                // AND the enum is not empty
061                if (m_enums[next] != null &&
062                    m_enums[next].hasMoreElements())
063                {
064                    // OK
065                    if (moveCursor)
066                    {
067                        index = next;
068                    }
069                    return m_enums[next];
070                }
071                // Try next element
072                return findNextEnumeration(next, moveCursor);
073            }
074            // No more elements available
075            return null;
076        }
077    
078        public Object nextElement()
079        {
080            // ask for the next element of the current enum.
081            if (currentEnumeration() != null)
082            {
083                return currentEnumeration().nextElement();
084            }
085    
086            // no more elements in this Enum
087            // We must throw a NoSuchElementException
088            throw new NoSuchElementException("No more elements");
089        }
090    
091        private Enumeration currentEnumeration()
092        {
093            if (m_enums != null)
094            {
095                if (index < m_enums.length)
096                {
097                    Enumeration e = m_enums[index];
098                    if (e == null || !e.hasMoreElements())
099                    {
100                        // the current enum is null or empty
101                        // we probably want to switch to the next one
102                        e = findNextEnumeration(true);
103                    }
104                    return e;
105                }
106            }
107            return null;
108        }
109    }