001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.commons.collections.list;
018    
019    import java.util.Collection;
020    import java.util.List;
021    import java.util.ListIterator;
022    
023    import org.apache.commons.collections.Transformer;
024    import org.apache.commons.collections.collection.TransformedCollection;
025    import org.apache.commons.collections.iterators.AbstractListIteratorDecorator;
026    
027    /**
028     * Decorates another <code>List</code> to transform objects that are added.
029     * <p>
030     * The add and set methods are affected by this class.
031     * Thus objects must be removed or searched for using their transformed form.
032     * For example, if the transformation converts Strings to Integers, you must
033     * use the Integer form to remove objects.
034     * <p>
035     * This class is Serializable from Commons Collections 3.1.
036     *
037     * @since Commons Collections 3.0
038     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
039     * 
040     * @author Stephen Colebourne
041     */
042    public class TransformedList extends TransformedCollection implements List {
043    
044        /** Serialization version */
045        private static final long serialVersionUID = 1077193035000013141L;
046    
047        /**
048         * Factory method to create a transforming list.
049         * <p>
050         * If there are any elements already in the list being decorated, they
051         * are NOT transformed.
052         * 
053         * @param list  the list to decorate, must not be null
054         * @param transformer  the transformer to use for conversion, must not be null
055         * @throws IllegalArgumentException if list or transformer is null
056         */
057        public static List decorate(List list, Transformer transformer) {
058            return new TransformedList(list, transformer);
059        }
060        
061        //-----------------------------------------------------------------------
062        /**
063         * Constructor that wraps (not copies).
064         * <p>
065         * If there are any elements already in the list being decorated, they
066         * are NOT transformed.
067         * 
068         * @param list  the list to decorate, must not be null
069         * @param transformer  the transformer to use for conversion, must not be null
070         * @throws IllegalArgumentException if list or transformer is null
071         */
072        protected TransformedList(List list, Transformer transformer) {
073            super(list, transformer);
074        }
075    
076        /**
077         * Gets the decorated list.
078         * 
079         * @return the decorated list
080         */
081        protected List getList() {
082            return (List) collection;
083        }
084    
085        //-----------------------------------------------------------------------
086        public Object get(int index) {
087            return getList().get(index);
088        }
089    
090        public int indexOf(Object object) {
091            return getList().indexOf(object);
092        }
093    
094        public int lastIndexOf(Object object) {
095            return getList().lastIndexOf(object);
096        }
097    
098        public Object remove(int index) {
099            return getList().remove(index);
100        }
101    
102        //-----------------------------------------------------------------------
103        public void add(int index, Object object) {
104            object = transform(object);
105            getList().add(index, object);
106        }
107    
108        public boolean addAll(int index, Collection coll) {
109            coll = transform(coll);
110            return getList().addAll(index, coll);
111        }
112    
113        public ListIterator listIterator() {
114            return listIterator(0);
115        }
116    
117        public ListIterator listIterator(int i) {
118            return new TransformedListIterator(getList().listIterator(i));
119        }
120    
121        public Object set(int index, Object object) {
122            object = transform(object);
123            return getList().set(index, object);
124        }
125    
126        public List subList(int fromIndex, int toIndex) {
127            List sub = getList().subList(fromIndex, toIndex);
128            return new TransformedList(sub, transformer);
129        }
130    
131        /**
132         * Inner class Iterator for the TransformedList
133         */
134        protected class TransformedListIterator extends AbstractListIteratorDecorator {
135            
136            protected TransformedListIterator(ListIterator iterator) {
137                super(iterator);
138            }
139            
140            public void add(Object object) {
141                object = transform(object);
142                iterator.add(object);
143            }
144            
145            public void set(Object object) {
146                object = transform(object);
147                iterator.set(object);
148            }
149        }
150    
151    }