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.collection.SynchronizedCollection;
024
025 /**
026 * Decorates another <code>List</code> to synchronize its behaviour
027 * for a multi-threaded environment.
028 * <p>
029 * Methods are synchronized, then forwarded to the decorated list.
030 * <p>
031 * This class is Serializable from Commons Collections 3.1.
032 *
033 * @since Commons Collections 3.0
034 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
035 *
036 * @author Stephen Colebourne
037 */
038 public class SynchronizedList extends SynchronizedCollection implements List {
039
040 /** Serialization version */
041 private static final long serialVersionUID = -1403835447328619437L;
042
043 /**
044 * Factory method to create a synchronized list.
045 *
046 * @param list the list to decorate, must not be null
047 * @throws IllegalArgumentException if list is null
048 */
049 public static List decorate(List list) {
050 return new SynchronizedList(list);
051 }
052
053 //-----------------------------------------------------------------------
054 /**
055 * Constructor that wraps (not copies).
056 *
057 * @param list the list to decorate, must not be null
058 * @throws IllegalArgumentException if list is null
059 */
060 protected SynchronizedList(List list) {
061 super(list);
062 }
063
064 /**
065 * Constructor that wraps (not copies).
066 *
067 * @param list the list to decorate, must not be null
068 * @param lock the lock to use, must not be null
069 * @throws IllegalArgumentException if list is null
070 */
071 protected SynchronizedList(List list, Object lock) {
072 super(list, lock);
073 }
074
075 /**
076 * Gets the decorated list.
077 *
078 * @return the decorated list
079 */
080 protected List getList() {
081 return (List) collection;
082 }
083
084 //-----------------------------------------------------------------------
085 public void add(int index, Object object) {
086 synchronized (lock) {
087 getList().add(index, object);
088 }
089 }
090
091 public boolean addAll(int index, Collection coll) {
092 synchronized (lock) {
093 return getList().addAll(index, coll);
094 }
095 }
096
097 public Object get(int index) {
098 synchronized (lock) {
099 return getList().get(index);
100 }
101 }
102
103 public int indexOf(Object object) {
104 synchronized (lock) {
105 return getList().indexOf(object);
106 }
107 }
108
109 public int lastIndexOf(Object object) {
110 synchronized (lock) {
111 return getList().lastIndexOf(object);
112 }
113 }
114
115 /**
116 * Iterators must be manually synchronized.
117 * <pre>
118 * synchronized (coll) {
119 * ListIterator it = coll.listIterator();
120 * // do stuff with iterator
121 * }
122 *
123 * @return an iterator that must be manually synchronized on the collection
124 */
125 public ListIterator listIterator() {
126 return getList().listIterator();
127 }
128
129 /**
130 * Iterators must be manually synchronized.
131 * <pre>
132 * synchronized (coll) {
133 * ListIterator it = coll.listIterator(3);
134 * // do stuff with iterator
135 * }
136 *
137 * @return an iterator that must be manually synchronized on the collection
138 */
139 public ListIterator listIterator(int index) {
140 return getList().listIterator(index);
141 }
142
143 public Object remove(int index) {
144 synchronized (lock) {
145 return getList().remove(index);
146 }
147 }
148
149 public Object set(int index, Object object) {
150 synchronized (lock) {
151 return getList().set(index, object);
152 }
153 }
154
155 public List subList(int fromIndex, int toIndex) {
156 synchronized (lock) {
157 List list = getList().subList(fromIndex, toIndex);
158 // the lock is passed into the constructor here to ensure that the sublist is
159 // synchronized on the same lock as the parent list
160 return new SynchronizedList(list, lock);
161 }
162 }
163
164 }