Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_data / src / org / gvsig / fmap / data / spi / AbstractResource.java @ 23871

History | View | Annotate | Download (8.22 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
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 2
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
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2008 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.data.spi;
32

    
33
import java.lang.ref.WeakReference;
34
import java.util.ArrayList;
35
import java.util.Date;
36
import java.util.List;
37

    
38
import org.gvsig.fmap.data.DataParameters;
39
import org.gvsig.fmap.data.DataStore;
40
import org.gvsig.fmap.data.Resource;
41
import org.gvsig.fmap.data.ResourceNotification;
42
import org.gvsig.fmap.data.exceptions.CloseException;
43
import org.gvsig.fmap.data.exceptions.DataException;
44
import org.gvsig.fmap.data.exceptions.OpenException;
45
import org.gvsig.fmap.data.exceptions.PrepareResourceException;
46
import org.gvsig.fmap.data.exceptions.ResourceChangedException;
47
import org.gvsig.fmap.data.exceptions.ResourceConsumerNotFoundException;
48
import org.gvsig.fmap.data.exceptions.UnreferenceResourceException;
49
import org.gvsig.fmap.data.impl.DefaultResourceNotification;
50
import org.gvsig.tools.observer.DefaultObservable;
51
import org.gvsig.tools.observer.Observable;
52
import org.gvsig.tools.observer.Observer;
53

    
54
/**
55
 * @author jmvivo
56
 *
57
 */
58
public abstract class AbstractResource implements Observable, Resource {
59

    
60
        private List references = new ArrayList();
61
        private DefaultObservable observable = new DefaultObservable();
62

    
63
        protected Date lastTimeOpen = new Date();
64
        protected Date lastTimeUsed = new Date();
65

    
66
        protected DataParameters params = null;
67

    
68
        protected AbstractResource(DataParameters params) {
69
                this.params = params;
70
        }
71

    
72
        /* (non-Javadoc)
73
         * @see org.gvsig.fmap.data.Resource#getParameters()
74
         */
75
        public DataParameters getParameters() throws DataException {
76
                return this.params.getCopy();
77
        }
78

    
79
        /* (non-Javadoc)
80
         * @see org.gvsig.fmap.data.Resource#description()
81
         */
82
        public abstract String getDescription();
83

    
84
        /* (non-Javadoc)
85
         * @see org.gvsig.fmap.data.Resource#getName()
86
         */
87
        public abstract String getName();
88

    
89
        protected abstract String generateKey();
90
        /* (non-Javadoc)
91
         * @see org.gvsig.fmap.data.Resource#getKey()
92
         */
93
        public final String getKey(){
94
                if (this.key == null){
95
                        this.key = this.generateKey();
96
                }
97
                return this.key;
98

    
99
        }
100

    
101
        protected abstract void doChanged();
102

    
103
        private String key=null;
104
        private boolean opened;
105

    
106
        public final void changed(DataStore store) {
107
                doChanged();
108
                observable.notifyObservers(
109
                                this,
110
                                new DefaultResourceNotification(this,ResourceNotification.CHANGED,store));
111
        }
112

    
113
        public final void changed() {
114

    
115
                observable.notifyObservers(
116
                                this,
117
                                new DefaultResourceNotification(this,ResourceNotification.CHANGED));
118
        }
119

    
120
        /* (non-Javadoc)
121
         * @see org.gvsig.fmap.data.Resource#close()
122
         */
123
        public synchronized final void close() throws CloseException{
124
                if (!this.isOpen()) {
125
                        return;
126
                }
127
                observable.notifyObservers(
128
                                this,
129
                                new DefaultResourceNotification(this,ResourceNotification.BEGIN_CLOSE));
130
                doClose();
131
                observable.notifyObservers(
132
                                this,
133
                                new DefaultResourceNotification(this,ResourceNotification.CLOSED));
134

    
135
        }
136

    
137
        public final void dispose() throws DataException {
138
                observable.notifyObservers(
139
                                this,
140
                                new DefaultResourceNotification(this,ResourceNotification.BEGIN_DISPOSE));
141
                doDispose();
142
                observable.deleteObservers();
143
                this.references.clear();
144
        }
145

    
146
        protected abstract void doDispose() throws DataException;
147

    
148
        /* (non-Javadoc)
149
         * @see org.gvsig.fmap.data.Resource#getLastTimeOpen()
150
         */
151
        public Date getLastTimeOpen() {
152
                return new Date(this.lastTimeOpen.getTime());
153
        }
154

    
155
        /* (non-Javadoc)
156
         * @see org.gvsig.fmap.data.Resource#getLastTimeUsed()
157
         */
158
        public Date getLastTimeUsed() {
159
                return new Date(this.lastTimeOpen.getTime());
160
        }
161

    
162
        public void incref(Object consumer) {
163
                this.updateLastTimeUsed();
164
                if (consumer != null) {
165
                        this.references.add(new WeakReference(consumer));
166
                } else {
167
                        this.references.add(null);
168
                }
169
                //                this.referenceCount++;
170
        }
171

    
172
        protected synchronized final void open() throws OpenException,
173
                        ResourceChangedException {
174
                this.updateLastTimeUsed();
175
                if (this.isOpen()){
176
                        return;
177
                }
178
                observable.notifyObservers(
179
                                this,
180
                                new DefaultResourceNotification(this,ResourceNotification.BEGIN_OPEN));
181

    
182
                if (doOpen()) {
183
                        this.updateLastTimeOpen();
184
                }
185
                observable.notifyObservers(
186
                                this,
187
                                new DefaultResourceNotification(this,ResourceNotification.OPENED));
188

    
189
        }
190

    
191
        protected void updateLastTimeUsed() {
192
                if (this.lastTimeUsed == null) {
193
                        this.lastTimeUsed = new Date();
194
                }
195
                this.lastTimeUsed.setTime(System.currentTimeMillis());
196
        }
197

    
198
        protected void updateLastTimeOpen(){
199
                if (this.lastTimeOpen == null){
200
                        this.lastTimeOpen = new Date();
201
                }
202
                this.lastTimeOpen.setTime(System.currentTimeMillis());
203
        }
204

    
205
        protected abstract boolean doOpen() throws OpenException,
206
                        ResourceChangedException;
207

    
208
        /**
209
         *
210
         * @param consumer
211
         * @return ref count after operation
212
         */
213
        public void unref(Object consumer) throws DataException {
214
                if (this.references.size() < 1) {
215
                        throw new UnreferenceResourceException(this.getKey());
216
                }
217
                this.updateLastTimeUsed();
218

    
219
                this.updateReferences();
220

    
221
                int index = -1;
222
                int i;
223
                WeakReference ref;
224
                for (i=0;i<this.references.size();i++){
225
                        ref = (WeakReference) this.references.get(i);
226
                        if (ref != null) {
227
                                if (ref.get().equals(consumer)) {
228
                                        index = i;
229
                                        break;
230
                                }
231

    
232
                        } else if (consumer == null) {
233
                                index = i;
234
                                break;
235
                        }
236
                }
237
                if (index < 0) {
238
                        throw new ResourceConsumerNotFoundException(this, consumer);
239
                }
240
                this.references.remove(index);
241

    
242

    
243
                if (this.references.size() == 0) {
244
                        this.close();
245
                }
246
        }
247

    
248
        public final int getRefencesCount(){
249
                this.updateReferences();
250
                return this.references.size();
251
        }
252

    
253

    
254
        /* (non-Javadoc)
255
         * @see org.gvsig.util.observer.Observable#addObserver(org.gvsig.tools.observer.Observer)
256
         */
257
        public void addObserver(Observer o) {
258
                this.observable.addObserver(o);
259

    
260
        }
261

    
262
        /* (non-Javadoc)
263
         * @see org.gvsig.util.observer.Observable#deleteObserver(org.gvsig.tools.observer.Observer)
264
         */
265
        public void deleteObserver(Observer o) {
266
                this.observable.deleteObserver(o);
267
        }
268

    
269
        /* (non-Javadoc)
270
         * @see org.gvsig.util.observer.Observable#deleteObservers()
271
         */
272
        public void deleteObservers() {
273
                this.deleteObservers();
274

    
275
        }
276

    
277
        public void addObservers(DefaultObservable ob){
278
                this.observable.addObservers(ob);
279
        }
280

    
281
        /**
282
         *
283
         */
284
        public void prepare() throws DataException {
285
                try{
286
                        observable.notifyObservers(
287
                                        this,
288
                                        new DefaultResourceNotification(this,ResourceNotification.PREPARE));
289
                } catch (Exception e){
290
                        throw new PrepareResourceException(this, e);
291
                }
292
                this.updateLastTimeUsed();
293
        }
294

    
295
        protected synchronized void checkOpen() throws OpenException,
296
                        ResourceChangedException {
297
                this.updateLastTimeUsed();
298
                if (!this.isOpen()){
299
                        this.open();
300
                } else {
301
                        this.checkChanged();
302
                }
303
        }
304

    
305
        protected abstract void checkChanged() throws ResourceChangedException;
306

    
307
        /* (non-Javadoc)
308
         * @see org.gvsig.fmap.data.Resource#isOpen()
309
         */
310
        public boolean isOpen() {
311
                return this.opened;
312
        }
313

    
314
        protected void setOpened() {
315
                this.updateLastTimeUsed();
316
                this.opened=true;
317
        }
318

    
319
        protected boolean doClose() throws CloseException {
320
                if (!this.isOpen()) {
321
                        return false;
322
                }
323
                this.opened= false;
324
                return true;
325
        }
326

    
327
        public synchronized void updateReferences() {
328
                List deadRefs = new ArrayList();
329
                WeakReference ref;
330
                int i;
331
                for (i = 0; i < this.references.size(); i++) {
332
                        ref = (WeakReference) this.references.get(i);
333
                        if (ref == null) {
334
                                continue;
335
                        }
336
                        if (ref.get() == null) {
337
                                deadRefs.add(new Integer(i));
338
                        }
339

    
340
                }
341
                for (i = deadRefs.size(); i > 0; i--) {
342
                        this.references.remove(((Integer) deadRefs.get(i - 1)).intValue());
343
                }
344
        }
345
}
346