Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / resource / spi / AbstractResource.java @ 40596

History | View | Annotate | Download (8.68 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.resource.spi;
25

    
26
import java.lang.ref.WeakReference;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30

    
31
import org.gvsig.fmap.dal.exception.CopyParametersException;
32
import org.gvsig.fmap.dal.exception.InitializeException;
33
import org.gvsig.fmap.dal.resource.Resource;
34
import org.gvsig.fmap.dal.resource.ResourceAction;
35
import org.gvsig.fmap.dal.resource.ResourceNotification;
36
import org.gvsig.fmap.dal.resource.ResourceParameters;
37
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
38
import org.gvsig.fmap.dal.resource.exception.PrepareResourceException;
39
import org.gvsig.fmap.dal.resource.exception.ResourceException;
40
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
41
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
42
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
43
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyDisposeException;
44
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
45
import org.gvsig.fmap.dal.resource.impl.DefaultResourceNotification;
46
import org.gvsig.tools.observer.Observer;
47
import org.gvsig.tools.observer.WeakReferencingObservable;
48
import org.gvsig.tools.observer.impl.BaseWeakReferencingObservable;
49
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
50

    
51
/**
52
 * <p>
53
 * Base implementation for Resource
54
 * </p>
55
 * 
56
 * <p>
57
 * This implementation not define the {@link Resource#begin()} and
58
 * {@link Resource#end()}
59
 * </p>
60
 * 
61
 * @author jmvivo
62
 * 
63
 */
64
public abstract class AbstractResource implements ResourceProvider,
65
                WeakReferencingObservable {
66

    
67
        private DelegateWeakReferencingObservable delegateObservable;
68

    
69
        private List consumers;
70

    
71
        private long lastTimeOpen;
72
        private long lastTimeUsed;
73

    
74
        private ResourceParameters parameters;
75
        private ResourceParameters preparedParameters;
76

    
77
        private Object data;
78

    
79
        private int openCount;
80

    
81
        /**
82
         * Number of times an execute is being simultaneously performed with this
83
         * resource.
84
         */
85
        private int executeCount = 0;
86

    
87
        protected final Object lock;
88

    
89
        protected AbstractResource(ResourceParameters parameters)
90
                        throws InitializeException {
91
                consumers = new ArrayList();
92
                lastTimeOpen = System.currentTimeMillis();
93
                lastTimeUsed = lastTimeOpen;
94

    
95
                openCount = 0;
96

    
97
                preparedParameters = null;
98
                delegateObservable = new DelegateWeakReferencingObservable(this);
99
                lock = new Object();
100
                try {
101
                        this.parameters = (ResourceParameters) parameters.getCopy();
102
                } catch (CopyParametersException e) {
103
                        throw new InitializeException(e);
104
                }
105

    
106
        }
107

    
108
        protected final void updateLastTimeUsed() {
109
                lastTimeUsed = System.currentTimeMillis();
110
        }
111

    
112
        protected final void updateLastTimeOpen() {
113
                lastTimeOpen = System.currentTimeMillis();
114
                lastTimeUsed = lastTimeOpen;
115
        }
116

    
117
        public final long getLastTimeOpen() {
118
                return lastTimeOpen;
119
        }
120

    
121
        public final long getLastTimeUsed() {
122
                return lastTimeUsed;
123
        }
124

    
125
        public final ResourceParameters getParameters() {
126
                if (preparedParameters != null) {
127
                        return preparedParameters;
128
                }
129
                return this.parameters;
130
        }
131

    
132
        public void prepare(ResourceParameters params)
133
                        throws PrepareResourceException {
134
                ResourceNotification notification =
135
                                new DefaultResourceNotification(this,
136
                                                ResourceNotification.PREPARE, params);
137
                this.delegateObservable.notifyObservers(notification);
138
        }
139

    
140
        public void prepare() throws PrepareResourceException {
141
                if (preparedParameters == null) {
142
                        try {
143
                                ResourceParameters params =
144
                                                (ResourceParameters) parameters.getCopy();
145
                                prepare(params);
146
                                preparedParameters = params;
147
                        } catch (CopyParametersException e) {
148
                                throw new PrepareResourceException(this, e);
149
                        }
150
                }
151

    
152
        }
153

    
154
        public void notifyOpen() throws ResourceNotifyOpenException {
155
                this.notifyObserver(ResourceNotification.OPEN);
156
                updateLastTimeOpen();
157
                openCount++;
158
        }
159

    
160
        public void notifyClose() throws ResourceNotifyCloseException {
161
                if (openCount <= 0) {
162
                        throw new IllegalStateException();
163
                }
164
                this.notifyObserver(ResourceNotification.CLOSE);
165
                openCount--;
166
        }
167

    
168
        public void notifyChanges() throws ResourceNotifyChangesException {
169
                this.notifyObserver(ResourceNotification.CHANGED);
170

    
171
                Iterator it = consumers.iterator();
172
                while (it.hasNext()) {
173
                        ResourceConsumer consumer =
174
                                        (ResourceConsumer) ((WeakReference) it.next()).get();
175
                        if (consumer != null) {
176
                                consumer.resourceChanged(this);
177
                        } else {
178
                                it.remove();
179
                        }
180
                }
181
        }
182

    
183
        public boolean isOpen() {
184
                return this.openCount > 0;
185
        }
186

    
187
        public int openCount() {
188
                return this.openCount;
189
        }
190

    
191
        public void addObserver(Observer o) {
192
                this.delegateObservable.addObserver(o);
193
        }
194

    
195
        public void deleteObserver(Observer o) {
196
                this.delegateObservable.deleteObserver(o);
197
        }
198

    
199
        public void deleteObservers() {
200
                this.delegateObservable.deleteObservers();
201

    
202
        }
203

    
204
        public final void addObservers(BaseWeakReferencingObservable observers) {
205
                this.delegateObservable.addObservers(observers);
206
        }
207

    
208
        public final void addConsumer(ResourceConsumer consumer) {
209
                this.updateConsumersList();
210
                consumers.add(new WeakReference(consumer));
211
        }
212

    
213
        public final void removeConsumer(ResourceConsumer consumer) {
214
                ResourceConsumer cur;
215
                Iterator it = consumers.iterator();
216
                while (it.hasNext()) {
217
                        cur = (ResourceConsumer) ((WeakReference) it.next()).get();
218
                        if (cur == null || (cur == consumer)) {
219
                                it.remove();
220
                        }
221
                }
222
        }
223

    
224
        public int getConsumersCount() {
225
                this.updateConsumersList();
226
                return consumers.size();
227
        }
228

    
229
        private synchronized void updateConsumersList() {
230
                Iterator it = consumers.iterator();
231
                WeakReference ref;
232
                while (it.hasNext()) {
233
                        ref = (WeakReference) it.next();
234
                        if (ref.get() == null) {
235
                                it.remove();
236
                        }
237
                }
238
        }
239

    
240
        public void closeRequest() throws ResourceException {
241
                if (inUse()) {
242
                        return;
243
                }
244
                if (consumers != null) {
245
                        for (int i = 0; i < consumers.size(); i++) {
246

    
247
                        }
248
                }
249
                if (consumers != null) {
250
                        Iterator it = consumers.iterator();
251
                        while (it.hasNext()) {
252
                                ResourceConsumer consumer =
253
                                                (ResourceConsumer) ((WeakReference) it.next()).get();
254
                                if (consumer != null) {
255
                                        consumer.closeResourceRequested(this);
256
                                } else {
257
                                        it.remove();
258
                                }
259
                        }
260
                }
261
        }
262

    
263
        public void setData(Object data) {
264
                this.data = data;
265
        }
266

    
267
        public Object getData() {
268
                return this.data;
269
        }
270

    
271
        protected void notifyObserver(String type) {
272
                if (delegateObservable != null) {
273
                        this.delegateObservable.notifyObservers(new DefaultResourceNotification(
274
                                        this, type));
275
                }
276
        }
277

    
278
        public void notifyDispose() throws ResourceNotifyDisposeException {
279
                this.notifyObserver(ResourceNotification.DISPOSE);
280

    
281
                if (consumers != null) {
282
                        consumers.clear();
283
                }
284

    
285
                lastTimeOpen = 0l;
286
                lastTimeUsed = 0l;
287

    
288
                data = null;
289

    
290
                if (delegateObservable != null) {
291
                        delegateObservable.deleteObservers();
292
                }
293
        }
294

    
295
        public final boolean inUse() {
296
                return executeCount > 0;
297
        }
298

    
299
        public Object execute(ResourceAction action)
300
                        throws ResourceExecuteException {
301
                Object value = null;
302
                synchronized (lock) {
303
                        executeBegins();
304
                        try {
305
                                value = performExecution(action);
306
                        } catch (Exception e) {
307
                                throw new ResourceExecuteException(this, e);
308
                        } finally {
309
                                executeEnds();
310
                        }
311
                }
312
                return value;
313
        }
314

    
315
        protected Object performExecution(ResourceAction action) throws Exception {
316
                return action.run();
317
        }
318

    
319
        protected final void executeBegins() {
320
                executeCount++;
321
        }
322

    
323
        protected final void executeEnds() {
324
                updateLastTimeUsed();
325
                executeCount--;
326
        }
327

    
328
        /**
329
         * Returns the name of the {@link Resource}.
330
         * 
331
         * @throws AccessResourceException
332
         *             if there is an error while accessing the resource
333
         */
334
        public abstract String getName() throws AccessResourceException;
335

    
336
        /**
337
         * Returns the real resource represented by this object.
338
         * 
339
         * @throws AccessResourceException
340
         *             if there is an error while accessing the resource
341
         */
342
        public abstract Object get() throws AccessResourceException;
343

    
344
}