View Javadoc

1   /*
2    * Copyright 2006-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.osgi.service.importer.support.internal.collection;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.ListIterator;
22  import java.util.NoSuchElementException;
23  import java.util.RandomAccess;
24  
25  /**
26   * Subclass offering a List extension for a DynamicCollection. This allows not
27   * just forward, but also backwards iteration through the
28   * <code>ListIterator</list>.
29   * 
30   * @author Costin Leau
31   *
32   */
33  public class DynamicList extends DynamicCollection implements List, RandomAccess {
34  
35  	/**
36  	 * List iterator.
37  	 * 
38  	 * @author Costin Leau
39  	 * 
40  	 */
41  	private class DynamicListIterator extends DynamicIterator implements ListIterator {
42  
43  		private DynamicListIterator(int index) {
44  			super.cursor = index;
45  		}
46  
47  		public void add(Object o) {
48  			removalAllowed = false;
49  			synchronized (storage) {
50  				synchronized (lock) {
51  					DynamicList.this.add(cursor, o);
52  				}
53  			}
54  		}
55  
56  		private boolean unsafeHasPrevious() {
57  			return (cursor - 1 >= 0);
58  		}
59  
60  		public boolean hasPrevious() {
61  			synchronized (lock) {
62  				return unsafeHasPrevious();
63  			}
64  		}
65  
66  		public int nextIndex() {
67  			synchronized (lock) {
68  				return cursor;
69  			}
70  		}
71  
72  		public Object previous() {
73  			removalAllowed = true;
74  			synchronized (storage) {
75  				synchronized (lock) {
76  					if (unsafeHasPrevious()) {
77  						return storage.get(--cursor);
78  					}
79  				}
80  			}
81  
82  			throw new NoSuchElementException();
83  		}
84  
85  		public int previousIndex() {
86  			synchronized (lock) {
87  				return (cursor - 1);
88  			}
89  		}
90  
91  		public void set(Object o) {
92  			if (!removalAllowed)
93  				throw new IllegalStateException();
94  			synchronized (storage) {
95  				synchronized (lock) {
96  					storage.set(cursor - 1, o);
97  				}
98  			}
99  		}
100 	}
101 
102 
103 	public DynamicList() {
104 		super();
105 	}
106 
107 	public DynamicList(Collection c) {
108 		super(c);
109 	}
110 
111 	public DynamicList(int size) {
112 		super(size);
113 	}
114 
115 	public void add(int index, Object o) {
116 		super.add(index, o);
117 	}
118 
119 	public boolean addAll(int index, Collection c) {
120 		synchronized (storage) {
121 			return storage.addAll(index, c);
122 		}
123 	}
124 
125 	public Object get(int index) {
126 		synchronized (storage) {
127 			return storage.get(index);
128 		}
129 	}
130 
131 	public int indexOf(Object o) {
132 		synchronized (storage) {
133 			return storage.indexOf(o);
134 		}
135 	}
136 
137 	public int lastIndexOf(Object o) {
138 		synchronized (storage) {
139 			return storage.lastIndexOf(o);
140 		}
141 	}
142 
143 	public ListIterator listIterator() {
144 		ListIterator iter = new DynamicListIterator(0);
145 
146 		synchronized (iterators) {
147 			iterators.put(iter, null);
148 		}
149 
150 		return iter;
151 	}
152 
153 	public ListIterator listIterator(int index) {
154 		return new DynamicListIterator(index);
155 	}
156 
157 	public Object remove(int index) {
158 		return super.remove(index);
159 	}
160 
161 	public Object set(int index, Object o) {
162 		synchronized (storage) {
163 			return storage.set(index, o);
164 		}
165 	}
166 
167 	// TODO: test behavior to see if the returned list properly behaves under
168 	// dynamic circumstances
169 	public List subList(int fromIndex, int toIndex) {
170 		synchronized (storage) {
171 			return storage.subList(fromIndex, toIndex);
172 		}
173 	}
174 
175 }