Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / spi / JDBCResourcesStorage.java @ 44871

History | View | Annotate | Download (13.7 KB)

1 44297 jjdelcerro
package org.gvsig.fmap.dal.store.jdbc2.spi;
2
3
import java.io.ByteArrayInputStream;
4
import java.io.ByteArrayOutputStream;
5 44750 jjdelcerro
import java.io.File;
6
import java.io.FileInputStream;
7
import java.io.FileNotFoundException;
8
import java.io.FileOutputStream;
9 44297 jjdelcerro
import java.io.IOException;
10
import java.io.InputStream;
11
import java.io.OutputStream;
12
import java.net.URL;
13 44750 jjdelcerro
import java.security.MessageDigest;
14 44297 jjdelcerro
import java.util.ArrayList;
15
import java.util.List;
16 44750 jjdelcerro
import org.apache.commons.codec.digest.DigestUtils;
17
import org.apache.commons.io.FileUtils;
18 44297 jjdelcerro
import org.apache.commons.io.IOUtils;
19
import org.apache.commons.lang3.StringUtils;
20 44750 jjdelcerro
import org.apache.commons.lang3.tuple.ImmutablePair;
21
import org.apache.commons.lang3.tuple.Pair;
22 44297 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
23
import org.gvsig.expressionevaluator.ExpressionUtils;
24
import org.gvsig.fmap.dal.DALLocator;
25
import org.gvsig.fmap.dal.DataManager;
26 44304 jjdelcerro
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_RESOURCES_NAME;
27
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_RESOURCES_RESOURCE;
28
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_RESOURCES_NAME;
29 44297 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureStore;
32
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
33 44750 jjdelcerro
import org.gvsig.tools.ToolsLocator;
34 44297 jjdelcerro
import org.gvsig.tools.dispose.DisposeUtils;
35 44750 jjdelcerro
import org.gvsig.tools.folders.FoldersManager;
36 44297 jjdelcerro
import org.gvsig.tools.resourcesstorage.AbstractResourcesStorage;
37
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40
41
/**
42
 *
43
 * @author jjdelcerro
44
 */
45
@SuppressWarnings("UseSpecificCatch")
46
public class JDBCResourcesStorage extends AbstractResourcesStorage {
47
48
    private static final Logger LOGGER = LoggerFactory.getLogger(JDBCResourcesStorage.class);
49
50
    private static class DataBaseResource implements Resource {
51
52
        private class ResourceInputStream extends InputStream {
53
54
            @Override
55
            public int read() throws IOException {
56
                return in.read();
57
            }
58
59
            @Override
60
            public void close() throws IOException {
61
                DataBaseResource.this.close();
62
            }
63
        }
64
65
        private class ResourceOutputStream extends OutputStream {
66
67
            @Override
68
            public void write(int b) throws IOException {
69
                out.write(b);
70
            }
71
72
            @Override
73
            public void flush() throws IOException {
74
                out.flush();
75
            }
76
77
            @Override
78
            public void close() throws IOException {
79
                DataBaseResource.this.close();
80
            }
81
        }
82
83
        private final JDBCStoreParameters storeParameters;
84
        private final String tableName;
85
        private final String name;
86
87 44750 jjdelcerro
        private InputStream in;
88 44297 jjdelcerro
        private ByteArrayOutputStream out;
89
90
        public DataBaseResource(JDBCStoreParameters storeParameters, String tableName, String name) {
91
            this.storeParameters = storeParameters;
92
            this.tableName = tableName;
93
            this.name = name;
94
        }
95
96 44750 jjdelcerro
        @Override
97 44698 jjdelcerro
        public String getName() {
98
          return name;
99
        }
100
101 44297 jjdelcerro
        @Override
102
        public boolean isReadOnly() {
103
            return false;
104
        }
105
        @Override
106
        public URL getURL() {
107
            try {
108
                String url = this.storeParameters.getUrl();
109
                return new URL(url + "&tableName=" + this.tableName + "&resourceName=" + this.name);
110
            } catch (Throwable ex) {
111
                return null;
112
            }
113
        }
114
115
        @Override
116
        public boolean exists() {
117
            FeatureStore store = null;
118
            try {
119 44750 jjdelcerro
                FoldersManager fm = ToolsLocator.getFoldersManager();
120
                Pair<String, String> key = this.getCacheID();
121
                File f = fm.getTemporaryFile("resources-storage","jdbc", key.getLeft(), key.getRight());
122
                if( f.exists() ) {
123
                  return true;
124
                }
125 44297 jjdelcerro
                DataManager dataManager = DALLocator.getDataManager();
126
                store = (FeatureStore) dataManager.openStore(
127
                        this.storeParameters.getDataStoreName(),
128
                        this.storeParameters
129
                );
130
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
131
                String filter = builder.eq(
132 44304 jjdelcerro
                        builder.column(FIELD_RESOURCES_NAME),
133 44346 jjdelcerro
                        builder.constant(this.tableName+"."+this.name)
134 44297 jjdelcerro
                ).toString();
135
                Feature feature = store.findFirst(filter);
136
                return feature!=null;
137
            } catch (Throwable ex) {
138
                LOGGER.warn("Can't access to the resoure '" + this.getURL() + "'.", ex);
139
            } finally {
140
                DisposeUtils.disposeQuietly(store);
141
            }
142
            return false;
143
        }
144
145 44750 jjdelcerro
        private Pair<String,String> getCacheID() {
146
          byte[] data = this.storeParameters.toByteArray();
147
          ImmutablePair<String, String> r = new ImmutablePair<>(
148
                  DigestUtils.md5Hex(data),
149
                  this.tableName+"."+this.name
150
          );
151
          return r;
152
        }
153
154
        private InputStream getInputStreamFromCache() {
155
          FoldersManager fm = ToolsLocator.getFoldersManager();
156
          Pair<String, String> key = this.getCacheID();
157
          File f = fm.getTemporaryFile("resources-storage","jdbc", key.getLeft(), key.getRight());
158
          if( !f.exists() ) {
159
            InputStream is = null;
160
            FileOutputStream os = null;
161
            try {
162
              is = this.getInputStream();
163
              FileUtils.forceMkdir(f.getParentFile());
164
              os = new FileOutputStream(f);
165
              IOUtils.copy(is, os);
166
167
              File f2 = fm.getTemporaryFile("resources-storage","jdbc", key.getLeft(), "parameters");
168
              byte[] data = this.storeParameters.toByteArray();
169
              os = new FileOutputStream(f2);
170
              IOUtils.write(data, os);
171
            } catch (IOException ex) {
172
              return null;
173
            } finally {
174
              IOUtils.closeQuietly(is);
175
              IOUtils.closeQuietly(os);
176 44297 jjdelcerro
            }
177 44750 jjdelcerro
          }
178
          InputStream is = null;
179
          try {
180
            is = new FileInputStream(f);
181
          } catch (FileNotFoundException ex) {
182
          }
183
          return is;
184
        }
185
186
        private InputStream getInputStream() throws IOException {
187 44297 jjdelcerro
            FeatureStore store = null;
188
            try {
189
                DataManager dataManager = DALLocator.getDataManager();
190
                store = (FeatureStore) dataManager.openStore(
191
                        this.storeParameters.getDataStoreName(),
192
                        this.storeParameters
193
                );
194
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
195
                String filter = builder.eq(
196 44304 jjdelcerro
                        builder.column(FIELD_RESOURCES_NAME),
197 44346 jjdelcerro
                        builder.constant(this.tableName+"."+this.name)
198 44297 jjdelcerro
                ).toString();
199
                Feature feature = store.findFirst(filter);
200
                if (feature == null) {
201
                    return null;
202
                }
203 44304 jjdelcerro
                byte[] resource = feature.getByteArray(FIELD_RESOURCES_RESOURCE);
204 44750 jjdelcerro
                InputStream is = new ByteArrayInputStream(resource);
205
                return is;
206 44297 jjdelcerro
            } catch (Throwable ex) {
207
                LOGGER.warn("Can't access to the resoure '" + this.getURL() + "'.", ex);
208
            } finally {
209
                DisposeUtils.disposeQuietly(store);
210
            }
211
            return null;
212
        }
213
214
        @Override
215 44750 jjdelcerro
        public InputStream asInputStream() throws IOException {
216
            if (this.in != null || this.out != null) {
217
                throw new IllegalStateException("Resource is already open (" + this.getURL() + ")");
218
            }
219
            InputStream is = this.getInputStreamFromCache();
220
            if( is==null ) {
221
              is = this.getInputStream();
222
            }
223
            this.in = is;
224
            return new ResourceInputStream();
225
        }
226
227
        @Override
228 44297 jjdelcerro
        public OutputStream asOutputStream() throws IOException {
229
            if (this.in != null || this.out != null) {
230
                throw new IllegalStateException("Resource is already open (" + this.getURL() + ").");
231
            }
232
            this.out = new ByteArrayOutputStream();
233
            return new ResourceOutputStream();
234
        }
235
236
        @Override
237
        public void close() {
238
            if (this.in != null) {
239
                IOUtils.closeQuietly(this.in);
240
                this.in = null;
241
            }
242
            if (this.out != null) {
243
                FeatureStore store = null;
244
                try {
245
                    DataManager dataManager = DALLocator.getDataManager();
246
                    store = (FeatureStore) dataManager.openStore(
247
                            this.storeParameters.getDataStoreName(),
248
                            this.storeParameters
249
                    );
250
                    store.edit();
251
                    ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
252
                    String filter = builder.eq(
253 44304 jjdelcerro
                            builder.column(FIELD_RESOURCES_NAME),
254 44346 jjdelcerro
                            builder.constant(this.tableName+"."+this.name)
255 44297 jjdelcerro
                    ).toString();
256
                    Feature feature = store.findFirst(filter);
257
                    EditableFeature efeature;
258
                    if (feature == null) {
259
                        efeature = store.createNewFeature();
260 44346 jjdelcerro
                        efeature.set(FIELD_RESOURCES_NAME, this.tableName+"."+this.name);
261 44304 jjdelcerro
                        efeature.set(FIELD_RESOURCES_RESOURCE, this.out.toByteArray());
262 44297 jjdelcerro
                        store.insert(efeature);
263
                    } else {
264
                        efeature = feature.getEditable();
265 44304 jjdelcerro
                        efeature.set(FIELD_RESOURCES_RESOURCE, this.out.toByteArray());
266 44297 jjdelcerro
                        store.update(efeature);
267
                    }
268
                    store.finishEditing();
269
270
                } catch (Throwable ex) {
271
                    LOGGER.warn("Can't write the resoure '" + this.getURL() + "'.", ex);
272
                } finally {
273
                    DisposeUtils.disposeQuietly(store);
274
                }
275
            }
276
        }
277
    }
278
279 44346 jjdelcerro
    private final ResourcesStorage alternativeStorge;
280 44297 jjdelcerro
    private final JDBCStoreParameters resourcesStoreParameters;
281
    private final String tableName;
282
283 44346 jjdelcerro
    public JDBCResourcesStorage(ResourcesStorage alternativeStorge, JDBCStoreParameters resourcesStoreParameters, String tableName) {
284
        this.alternativeStorge = alternativeStorge;
285 44304 jjdelcerro
        if( StringUtils.equals(TABLE_RESOURCES_NAME, tableName) ) {
286 44297 jjdelcerro
            // No podemos buscar recursos de la tabla de recursos, ya que si no
287
            // al abrise la tabla de recursos entraria en bucle.
288
            this.resourcesStoreParameters = null;
289
        } else {
290
            this.resourcesStoreParameters = resourcesStoreParameters;
291
        }
292
        this.tableName = tableName;
293
    }
294
295
    @Override
296
    public boolean isEmpty() {
297
        return this.resourcesStoreParameters == null;
298
    }
299
300
    @Override
301
    public Resource getResource(String name) {
302 44346 jjdelcerro
        if( this.alternativeStorge!=null ) {
303
            Resource r = this.alternativeStorge.getResource(name);
304
            if( r.exists() ) {
305
                return r;
306
            }
307
        }
308 44297 jjdelcerro
        if (this.resourcesStoreParameters == null) {
309
            return null;
310
        }
311
        return new DataBaseResource(
312
                this.resourcesStoreParameters,
313
                this.tableName,
314
                name
315
        );
316
    }
317
318
    @Override
319
    public List<Resource> getResources(String name) {
320
        if (this.resourcesStoreParameters == null) {
321
            return null;
322
        }
323 44346 jjdelcerro
        if( this.alternativeStorge!=null ) {
324
            List<Resource> r = this.alternativeStorge.getResources(name);
325
            if( r!=null && !r.isEmpty() ) {
326
                return r;
327
            }
328
        }
329 44297 jjdelcerro
        FeatureStore store = null;
330
        try {
331
            DataManager dataManager = DALLocator.getDataManager();
332
            store = (FeatureStore) dataManager.openStore(
333
                    this.resourcesStoreParameters.getDataStoreName(),
334
                    this.resourcesStoreParameters
335
            );
336
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
337
            List<ResourcesStorage.Resource> ress = new ArrayList<>();
338
            int n = 0;
339
            while (true) {
340
                String multiresourceName;
341
                if (n == 0) {
342
                    multiresourceName = name;
343
                } else {
344 44346 jjdelcerro
                    multiresourceName = String.valueOf(n) + "." + name ;
345 44297 jjdelcerro
                }
346
                String filter = builder.eq(
347 44304 jjdelcerro
                        builder.column(FIELD_RESOURCES_NAME),
348 44346 jjdelcerro
                        builder.constant(this.tableName+"."+multiresourceName)
349 44297 jjdelcerro
                ).toString();
350
                Feature feature = store.findFirst(filter);
351
                if( feature==null ) {
352
                    break;
353
                }
354
                ress.add(new DataBaseResource(
355
                        this.resourcesStoreParameters,
356
                        this.tableName,
357
                        multiresourceName
358
                    )
359
                );
360
                n++;
361
            }
362
            if (ress.isEmpty()) {
363
                return null;
364
            }
365
            return ress;
366
        } catch (Throwable ex) {
367
            LOGGER.warn("Can't get resources for '" + this.resourcesStoreParameters.getUrl()+"&resourceName="+name + "'.", ex);
368
            return null;
369
370
        } finally {
371
            DisposeUtils.disposeQuietly(store);
372
        }
373
374
    }
375
376
}