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 @ 40559

History | View | Annotate | Download (8.76 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
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2009 IVER T.I   {{Task}}
27
 */
28

    
29
/**
30
 *
31
 */
32
package org.gvsig.fmap.dal.resource.spi;
33

    
34
import java.lang.ref.WeakReference;
35
import java.util.ArrayList;
36
import java.util.Iterator;
37
import java.util.List;
38

    
39
import org.gvsig.fmap.dal.exception.CopyParametersException;
40
import org.gvsig.fmap.dal.exception.InitializeException;
41
import org.gvsig.fmap.dal.resource.Resource;
42
import org.gvsig.fmap.dal.resource.ResourceAction;
43
import org.gvsig.fmap.dal.resource.ResourceNotification;
44
import org.gvsig.fmap.dal.resource.ResourceParameters;
45
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
46
import org.gvsig.fmap.dal.resource.exception.PrepareResourceException;
47
import org.gvsig.fmap.dal.resource.exception.ResourceException;
48
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
49
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
50
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
51
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyDisposeException;
52
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
53
import org.gvsig.fmap.dal.resource.impl.DefaultResourceNotification;
54
import org.gvsig.tools.observer.Observer;
55
import org.gvsig.tools.observer.WeakReferencingObservable;
56
import org.gvsig.tools.observer.impl.BaseWeakReferencingObservable;
57
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
58

    
59
/**
60
 * <p>
61
 * Base implementation for Resource
62
 * </p>
63
 * 
64
 * <p>
65
 * This implementation not define the {@link Resource#begin()} and
66
 * {@link Resource#end()}
67
 * </p>
68
 * 
69
 * @author jmvivo
70
 * 
71
 */
72
public abstract class AbstractResource implements ResourceProvider,
73
                WeakReferencingObservable {
74

    
75
        private DelegateWeakReferencingObservable delegateObservable;
76

    
77
        private List consumers;
78

    
79
        private long lastTimeOpen;
80
        private long lastTimeUsed;
81

    
82
        private ResourceParameters parameters;
83
        private ResourceParameters preparedParameters;
84

    
85
        private Object data;
86

    
87
        private int openCount;
88

    
89
        /**
90
         * Number of times an execute is being simultaneously performed with this
91
         * resource.
92
         */
93
        private int executeCount = 0;
94

    
95
        protected final Object lock;
96

    
97
        protected AbstractResource(ResourceParameters parameters)
98
                        throws InitializeException {
99
                consumers = new ArrayList();
100
                lastTimeOpen = System.currentTimeMillis();
101
                lastTimeUsed = lastTimeOpen;
102

    
103
                openCount = 0;
104

    
105
                preparedParameters = null;
106
                delegateObservable = new DelegateWeakReferencingObservable(this);
107
                lock = new Object();
108
                try {
109
                        this.parameters = (ResourceParameters) parameters.getCopy();
110
                } catch (CopyParametersException e) {
111
                        throw new InitializeException(e);
112
                }
113

    
114
        }
115

    
116
        protected final void updateLastTimeUsed() {
117
                lastTimeUsed = System.currentTimeMillis();
118
        }
119

    
120
        protected final void updateLastTimeOpen() {
121
                lastTimeOpen = System.currentTimeMillis();
122
                lastTimeUsed = lastTimeOpen;
123
        }
124

    
125
        public final long getLastTimeOpen() {
126
                return lastTimeOpen;
127
        }
128

    
129
        public final long getLastTimeUsed() {
130
                return lastTimeUsed;
131
        }
132

    
133
        public final ResourceParameters getParameters() {
134
                if (preparedParameters != null) {
135
                        return preparedParameters;
136
                }
137
                return this.parameters;
138
        }
139

    
140
        public void prepare(ResourceParameters params)
141
                        throws PrepareResourceException {
142
                ResourceNotification notification =
143
                                new DefaultResourceNotification(this,
144
                                                ResourceNotification.PREPARE, params);
145
                this.delegateObservable.notifyObservers(notification);
146
        }
147

    
148
        public void prepare() throws PrepareResourceException {
149
                if (preparedParameters == null) {
150
                        try {
151
                                ResourceParameters params =
152
                                                (ResourceParameters) parameters.getCopy();
153
                                prepare(params);
154
                                preparedParameters = params;
155
                        } catch (CopyParametersException e) {
156
                                throw new PrepareResourceException(this, e);
157
                        }
158
                }
159

    
160
        }
161

    
162
        public void notifyOpen() throws ResourceNotifyOpenException {
163
                this.notifyObserver(ResourceNotification.OPEN);
164
                updateLastTimeOpen();
165
                openCount++;
166
        }
167

    
168
        public void notifyClose() throws ResourceNotifyCloseException {
169
                if (openCount <= 0) {
170
                        throw new IllegalStateException();
171
                }
172
                this.notifyObserver(ResourceNotification.CLOSE);
173
                openCount--;
174
        }
175

    
176
        public void notifyChanges() throws ResourceNotifyChangesException {
177
                this.notifyObserver(ResourceNotification.CHANGED);
178

    
179
                Iterator it = consumers.iterator();
180
                while (it.hasNext()) {
181
                        ResourceConsumer consumer =
182
                                        (ResourceConsumer) ((WeakReference) it.next()).get();
183
                        if (consumer != null) {
184
                                consumer.resourceChanged(this);
185
                        } else {
186
                                it.remove();
187
                        }
188
                }
189
        }
190

    
191
        public boolean isOpen() {
192
                return this.openCount > 0;
193
        }
194

    
195
        public int openCount() {
196
                return this.openCount;
197
        }
198

    
199
        public void addObserver(Observer o) {
200
                this.delegateObservable.addObserver(o);
201
        }
202

    
203
        public void deleteObserver(Observer o) {
204
                this.delegateObservable.deleteObserver(o);
205
        }
206

    
207
        public void deleteObservers() {
208
                this.delegateObservable.deleteObservers();
209

    
210
        }
211

    
212
        public final void addObservers(BaseWeakReferencingObservable observers) {
213
                this.delegateObservable.addObservers(observers);
214
        }
215

    
216
        public final void addConsumer(ResourceConsumer consumer) {
217
                this.updateConsumersList();
218
                consumers.add(new WeakReference(consumer));
219
        }
220

    
221
        public final void removeConsumer(ResourceConsumer consumer) {
222
                ResourceConsumer cur;
223
                Iterator it = consumers.iterator();
224
                while (it.hasNext()) {
225
                        cur = (ResourceConsumer) ((WeakReference) it.next()).get();
226
                        if (cur == null || (cur == consumer)) {
227
                                it.remove();
228
                        }
229
                }
230
        }
231

    
232
        public int getConsumersCount() {
233
                this.updateConsumersList();
234
                return consumers.size();
235
        }
236

    
237
        private synchronized void updateConsumersList() {
238
                Iterator it = consumers.iterator();
239
                WeakReference ref;
240
                while (it.hasNext()) {
241
                        ref = (WeakReference) it.next();
242
                        if (ref.get() == null) {
243
                                it.remove();
244
                        }
245
                }
246
        }
247

    
248
        public void closeRequest() throws ResourceException {
249
                if (inUse()) {
250
                        return;
251
                }
252
                if (consumers != null) {
253
                        for (int i = 0; i < consumers.size(); i++) {
254

    
255
                        }
256
                }
257
                if (consumers != null) {
258
                        Iterator it = consumers.iterator();
259
                        while (it.hasNext()) {
260
                                ResourceConsumer consumer =
261
                                                (ResourceConsumer) ((WeakReference) it.next()).get();
262
                                if (consumer != null) {
263
                                        consumer.closeResourceRequested(this);
264
                                } else {
265
                                        it.remove();
266
                                }
267
                        }
268
                }
269
        }
270

    
271
        public void setData(Object data) {
272
                this.data = data;
273
        }
274

    
275
        public Object getData() {
276
                return this.data;
277
        }
278

    
279
        protected void notifyObserver(String type) {
280
                if (delegateObservable != null) {
281
                        this.delegateObservable.notifyObservers(new DefaultResourceNotification(
282
                                        this, type));
283
                }
284
        }
285

    
286
        public void notifyDispose() throws ResourceNotifyDisposeException {
287
                this.notifyObserver(ResourceNotification.DISPOSE);
288

    
289
                if (consumers != null) {
290
                        consumers.clear();
291
                }
292

    
293
                lastTimeOpen = 0l;
294
                lastTimeUsed = 0l;
295

    
296
                data = null;
297

    
298
                if (delegateObservable != null) {
299
                        delegateObservable.deleteObservers();
300
                }
301
        }
302

    
303
        public final boolean inUse() {
304
                return executeCount > 0;
305
        }
306

    
307
        public Object execute(ResourceAction action)
308
                        throws ResourceExecuteException {
309
                Object value = null;
310
                synchronized (lock) {
311
                        executeBegins();
312
                        try {
313
                                value = performExecution(action);
314
                        } catch (Exception e) {
315
                                throw new ResourceExecuteException(this, e);
316
                        } finally {
317
                                executeEnds();
318
                        }
319
                }
320
                return value;
321
        }
322

    
323
        protected Object performExecution(ResourceAction action) throws Exception {
324
                return action.run();
325
        }
326

    
327
        protected final void executeBegins() {
328
                executeCount++;
329
        }
330

    
331
        protected final void executeEnds() {
332
                updateLastTimeUsed();
333
                executeCount--;
334
        }
335

    
336
        /**
337
         * Returns the name of the {@link Resource}.
338
         * 
339
         * @throws AccessResourceException
340
         *             if there is an error while accessing the resource
341
         */
342
        public abstract String getName() throws AccessResourceException;
343

    
344
        /**
345
         * Returns the real resource represented by this object.
346
         * 
347
         * @throws AccessResourceException
348
         *             if there is an error while accessing the resource
349
         */
350
        public abstract Object get() throws AccessResourceException;
351

    
352
}