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.impl;
016    
017    import java.util.AbstractList;
018    import java.util.List;
019    
020    /**
021     * Implements a {@link java.util.List} as a proxy to an actual list of
022     * elements, provided by an extension point. The proxy is unmodifiable
023     * and will work with the extension point to generate the real list
024     * of elements in a just-in-time manner.
025     *
026     * @author Howard Lewis Ship
027     */
028    public final class ElementsInnerProxyList extends AbstractList
029    {
030        private List _inner;
031        private ConfigurationPointImpl _point;
032        private ElementsProxyList _outer;
033    
034        ElementsInnerProxyList(ConfigurationPointImpl point, ElementsProxyList outer)
035        {
036            _point = point;
037            _outer = outer;
038    
039            _outer.setInner(this);
040        }
041    
042        private synchronized List inner()
043        {
044            if (_inner == null)
045            {
046                _inner = _point.constructElements();
047    
048                // Replace ourselves in the outer proxy with the actual list.
049                _outer.setInner(_inner);
050            }
051    
052            return _inner;
053        }
054    
055        public Object get(int index)
056        {
057            return inner().get(index);
058        }
059    
060        public int size()
061        {
062            return inner().size();
063        }
064    
065        public boolean equals(Object o)
066        {
067            if (this == o)
068                return true;
069    
070            if (o == null)
071                return false;
072    
073            return inner().equals(o);
074        }
075    
076        public int hashCode()
077        {
078            return inner().hashCode();
079        }
080    
081        public synchronized String toString()
082        {
083            if (_inner != null)
084                return _inner.toString();
085    
086            return "<Element List Proxy for " + _point.getExtensionPointId() + ">";
087        }
088    
089    }