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  package org.springframework.osgi.service.importer.support.internal.collection;
17  
18  import java.util.Collection;
19  import java.util.List;
20  import java.util.ListIterator;
21  import java.util.RandomAccess;
22  
23  import org.osgi.framework.BundleContext;
24  import org.osgi.framework.Filter;
25  import org.springframework.osgi.service.importer.support.internal.aop.ServiceProxyCreator;
26  
27  
28  /**
29   * OSGi service dynamic collection - allows iterating while the underlying
30   * storage is being shrunk/expanded. This collection is read-only - its content
31   * is being retrieved dynamically from the OSGi platform.
32   * 
33   * <p/> This collection and its iterators are thread-safe. That is, multiple
34   * threads can access the collection. However, since the collection is
35   * read-only, it cannot be modified by the client.
36   * 
37   * @author Costin Leau
38   * 
39   */
40  public class OsgiServiceList extends OsgiServiceCollection implements List, RandomAccess {
41  
42  	protected class OsgiServiceListIterator implements ListIterator {
43  
44  		// dynamic iterator
45  		private final ListIterator iter;
46  
47  		public OsgiServiceListIterator(int index) {
48  			iter = storage.listIterator(index);
49  		}
50  
51  		public Object next() {
52  			synchronized (serviceProxies) {
53  				mandatoryServiceCheck();
54  				Object proxy = iter.next();
55  				return (proxy == null ? tailDeadProxy : proxy);
56  			}
57  		}
58  
59  		public Object previous() {
60  			synchronized (serviceProxies) {
61  				mandatoryServiceCheck();
62  				Object proxy = iter.previous();
63  
64  				return (proxy == null ? headDeadProxy : proxy);
65  			}
66  		}
67  
68  		//
69  		// index operations
70  		//
71  		public boolean hasNext() {
72  			mandatoryServiceCheck();
73  			return iter.hasNext();
74  		}
75  
76  		public boolean hasPrevious() {
77  			mandatoryServiceCheck();
78  			return iter.hasPrevious();
79  		}
80  
81  		public int nextIndex() {
82  			mandatoryServiceCheck();
83  			return iter.nextIndex();
84  		}
85  
86  		public int previousIndex() {
87  			mandatoryServiceCheck();
88  			return iter.previousIndex();
89  		}
90  
91  		//
92  		// read-only operations
93  		//
94  		public void add(Object o) {
95  			throw new UnsupportedOperationException();
96  		}
97  
98  		public void remove() {
99  			throw new UnsupportedOperationException();
100 		}
101 
102 		public void set(Object o) {
103 			throw new UnsupportedOperationException();
104 		}
105 
106 	};
107 
108 	// dead proxy at the head of the collection
109 	protected volatile Object headDeadProxy;
110 
111 	/**
112 	 * cast the collection to a specialized collection
113 	 */
114 	protected List storage;
115 
116 	public OsgiServiceList(Filter filter, BundleContext context, ClassLoader classLoader,
117 			ServiceProxyCreator proxyCreator) {
118 		super(filter, context, classLoader, proxyCreator);
119 	}
120 
121 	protected DynamicCollection createInternalDynamicStorage() {
122 		storage = new DynamicList();
123 		return (DynamicList) storage;
124 	}
125 
126 	public Object get(int index) {
127 		mandatoryServiceCheck();
128 		return storage.get(index);
129 	}
130 
131 	/**
132 	 * Override to determine head proxies.
133 	 */
134 	protected void checkDeadProxies(Object proxy, int proxyCollectionPos) {
135 		// head of collection
136 		if (proxyCollectionPos == 0)
137 			headDeadProxy = proxy;
138 		super.checkDeadProxies(proxy, proxyCollectionPos);
139 	}
140 
141 	public int indexOf(Object o) {
142 		// FIXME: implement this
143 		throw new UnsupportedOperationException();
144 	}
145 
146 	public int lastIndexOf(Object o) {
147 		// FIXME: implement this
148 		throw new UnsupportedOperationException();
149 	}
150 
151 	public ListIterator listIterator() {
152 		return listIterator(0);
153 	}
154 
155 	public ListIterator listIterator(final int index) {
156 		return new OsgiServiceListIterator(index);
157 	}
158 
159 	public List subList(int fromIndex, int toIndex) {
160 		// FIXME: implement this
161 		// note: the trick here is to return a list which is backed up by this
162 		// one (i.e. read-only)
163 		throw new UnsupportedOperationException();
164 	}
165 
166 	//
167 	// WRITE operations forbidden
168 	//
169 	public Object remove(int index) {
170 		throw new UnsupportedOperationException();
171 	}
172 
173 	public Object set(int index, Object o) {
174 		throw new UnsupportedOperationException();
175 	}
176 
177 	public void add(int index, Object o) {
178 		throw new UnsupportedOperationException();
179 	}
180 
181 	public boolean addAll(int index, Collection c) {
182 		throw new UnsupportedOperationException();
183 	}
184 
185 }