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

History | View | Annotate | Download (9.48 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
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

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

    
69
        private static Logger logger = LoggerFactory.getLogger(AbstractResource.class);
70

    
71
        private DelegateWeakReferencingObservable delegateObservable;
72

    
73
        private List consumers;
74

    
75
        private long lastTimeOpen;
76
        private long lastTimeUsed;
77

    
78
        private ResourceParameters parameters;
79
        private ResourceParameters preparedParameters;
80

    
81
        private Object data;
82

    
83
        private int openCount;
84

    
85
        /**
86
         * Number of times an execute is being simultaneously performed with this
87
         * resource.
88
         */
89
        private int executeCount = 0;
90

    
91
        protected final Object lock;
92

    
93
        protected Object multiResourcelock;
94

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

    
101
                openCount = 0;
102

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

    
113
        }
114

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

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

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

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

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

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

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

    
159
        }
160

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

    
167
        public void notifyClose() throws ResourceNotifyCloseException {
168
                if (openCount <= 0) {
169
                    try {
170
                        throw new IllegalStateException();
171
                    } catch(IllegalStateException ex) {
172
                        this.
173
                        logger.warn("notify close in a resource already closed ("+this.parameters.toString()+").", ex);
174
                    }
175
                    this.notifyObserver(ResourceNotification.CLOSE);
176
                } else {
177
                    this.notifyObserver(ResourceNotification.CLOSE);
178
                    openCount--;
179
                }
180
        }
181

    
182
        public void notifyChanges() throws ResourceNotifyChangesException {
183
                this.notifyObserver(ResourceNotification.CHANGED);
184

    
185
                Iterator it = consumers.iterator();
186
                while (it.hasNext()) {
187
                        ResourceConsumer consumer =
188
                                        (ResourceConsumer) ((WeakReference) it.next()).get();
189
                        if (consumer != null) {
190
                                consumer.resourceChanged(this);
191
                        } else {
192
                                it.remove();
193
                        }
194
                }
195
        }
196

    
197
        public boolean isOpen() {
198
                return this.openCount > 0;
199
        }
200

    
201
        public int openCount() {
202
                return this.openCount;
203
        }
204

    
205
        public void addObserver(Observer o) {
206
                this.delegateObservable.addObserver(o);
207
        }
208

    
209
        public void deleteObserver(Observer o) {
210
                this.delegateObservable.deleteObserver(o);
211
        }
212

    
213
        public void deleteObservers() {
214
                this.delegateObservable.deleteObservers();
215

    
216
        }
217

    
218
        public final void addObservers(BaseWeakReferencingObservable observers) {
219
                this.delegateObservable.addObservers(observers);
220
        }
221

    
222
        public final void addConsumer(ResourceConsumer consumer) {
223
                this.updateConsumersList();
224
                consumers.add(new WeakReference(consumer));
225
        }
226

    
227
        public final void removeConsumer(ResourceConsumer consumer) {
228
                ResourceConsumer cur;
229
                Iterator it = consumers.iterator();
230
                while (it.hasNext()) {
231
                        cur = (ResourceConsumer) ((WeakReference) it.next()).get();
232
                        if (cur == null || (cur == consumer)) {
233
                                it.remove();
234
                        }
235
                }
236

    
237
        }
238

    
239
        public int getConsumersCount() {
240
                this.updateConsumersList();
241
                return consumers.size();
242
        }
243

    
244
        public ResourceConsumer getConsumerAt(int i){
245
            this.updateConsumersList();
246
            if (consumers==null){
247
                return null;
248
            }else{
249
                return (ResourceConsumer)consumers.get(i);
250
            }
251
        }
252

    
253
        private synchronized void updateConsumersList() {
254
                Iterator it = consumers.iterator();
255
                WeakReference ref;
256
                while (it.hasNext()) {
257
                        ref = (WeakReference) it.next();
258
                        if (ref.get() == null) {
259
                                it.remove();
260
                        }
261
                }
262
        }
263

    
264
        public void closeRequest() throws ResourceException {
265
                if (inUse()) {
266
                        return;
267
                }
268

    
269
                if (consumers != null) {
270
                        Iterator it = consumers.iterator();
271
                        while (it.hasNext()) {
272
                                ResourceConsumer consumer =
273
                                                (ResourceConsumer) ((WeakReference) it.next()).get();
274
                                if (consumer != null) {
275
                                        consumer.closeResourceRequested(this);
276
                                } else {
277
                                        it.remove();
278
                                }
279
                        }
280
                }
281
        }
282

    
283
        public void setData(Object data) {
284
                this.data = data;
285
        }
286

    
287
        public Object getData() {
288
                return this.data;
289
        }
290

    
291
        protected void notifyObserver(String type) {
292
                if (delegateObservable != null) {
293
                        this.delegateObservable.notifyObservers(new DefaultResourceNotification(
294
                                        this, type));
295
                }
296
        }
297

    
298
        public void notifyDispose() throws ResourceNotifyDisposeException {
299
                this.notifyObserver(ResourceNotification.DISPOSE);
300

    
301
                if (consumers != null) {
302
                        consumers.clear();
303
                }
304

    
305
                lastTimeOpen = 0l;
306
                lastTimeUsed = 0l;
307

    
308
                data = null;
309

    
310
                if (delegateObservable != null) {
311
                        delegateObservable.deleteObservers();
312
                }
313
        }
314

    
315
        public final boolean inUse() {
316
                return executeCount > 0;
317
        }
318

    
319
        public Object execute(ResourceAction action)
320
                        throws ResourceExecuteException {
321
                Object value = null;
322
                synchronized (lock) {
323
                    synchronized (multiResourcelock) {
324
                            executeBegins();
325
                            try {
326
                                    value = performExecution(action);
327
                            } catch (Exception e) {
328
                                    throw new ResourceExecuteException(this, e);
329
                            } finally {
330
                                    executeEnds();
331
                            }
332
                    }
333
                }
334
                return value;
335
        }
336

    
337
        protected Object performExecution(ResourceAction action) throws Exception {
338
                return action.run();
339
        }
340

    
341
        protected final void executeBegins() {
342
                executeCount++;
343
        }
344

    
345
        protected final void executeEnds() {
346
                updateLastTimeUsed();
347
                executeCount--;
348
        }
349

    
350
        /**
351
         * Returns the name of the {@link Resource}.
352
         *
353
         * @throws AccessResourceException
354
         *             if there is an error while accessing the resource
355
         */
356
        public abstract String getName() throws AccessResourceException;
357

    
358
        /**
359
         * Returns the real resource represented by this object.
360
         *
361
         * @throws AccessResourceException
362
         *             if there is an error while accessing the resource
363
         */
364
        public abstract Object get() throws AccessResourceException;
365

    
366
}