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

History | View | Annotate | Download (13.7 KB)

1
package org.gvsig.fmap.dal.store.jdbc2.spi;
2

    
3
import java.io.ByteArrayInputStream;
4
import java.io.ByteArrayOutputStream;
5
import java.io.File;
6
import java.io.FileInputStream;
7
import java.io.FileNotFoundException;
8
import java.io.FileOutputStream;
9
import java.io.IOException;
10
import java.io.InputStream;
11
import java.io.OutputStream;
12
import java.net.URL;
13
import java.security.MessageDigest;
14
import java.util.ArrayList;
15
import java.util.List;
16
import org.apache.commons.codec.digest.DigestUtils;
17
import org.apache.commons.io.FileUtils;
18
import org.apache.commons.io.IOUtils;
19
import org.apache.commons.lang3.StringUtils;
20
import org.apache.commons.lang3.tuple.ImmutablePair;
21
import org.apache.commons.lang3.tuple.Pair;
22
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
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
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
import org.gvsig.tools.ToolsLocator;
34
import org.gvsig.tools.dispose.DisposeUtils;
35
import org.gvsig.tools.folders.FoldersManager;
36
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
        private InputStream in;
88
        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
        @Override
97
        public String getName() {
98
          return name;
99
        }
100
        
101
        @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
                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
                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
                        builder.column(FIELD_RESOURCES_NAME),
133
                        builder.constant(this.tableName+"."+this.name)
134
                ).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
        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
            }
177
          }
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
            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
                        builder.column(FIELD_RESOURCES_NAME),
197
                        builder.constant(this.tableName+"."+this.name)
198
                ).toString();
199
                Feature feature = store.findFirst(filter);
200
                if (feature == null) {
201
                    return null;
202
                }
203
                byte[] resource = feature.getByteArray(FIELD_RESOURCES_RESOURCE);
204
                InputStream is = new ByteArrayInputStream(resource);
205
                return is;
206
            } 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
        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
        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
                            builder.column(FIELD_RESOURCES_NAME),
254
                            builder.constant(this.tableName+"."+this.name)
255
                    ).toString();
256
                    Feature feature = store.findFirst(filter);
257
                    EditableFeature efeature;
258
                    if (feature == null) {
259
                        efeature = store.createNewFeature();
260
                        efeature.set(FIELD_RESOURCES_NAME, this.tableName+"."+this.name);
261
                        efeature.set(FIELD_RESOURCES_RESOURCE, this.out.toByteArray());
262
                        store.insert(efeature);
263
                    } else {
264
                        efeature = feature.getEditable();
265
                        efeature.set(FIELD_RESOURCES_RESOURCE, this.out.toByteArray());
266
                        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
    private final ResourcesStorage alternativeStorge;
280
    private final JDBCStoreParameters resourcesStoreParameters;
281
    private final String tableName;
282

    
283
    public JDBCResourcesStorage(ResourcesStorage alternativeStorge, JDBCStoreParameters resourcesStoreParameters, String tableName) {
284
        this.alternativeStorge = alternativeStorge;
285
        if( StringUtils.equals(TABLE_RESOURCES_NAME, tableName) ) {
286
            // 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
        if( this.alternativeStorge!=null ) {
303
            Resource r = this.alternativeStorge.getResource(name);
304
            if( r.exists() ) {
305
                return r;
306
            }
307
        }
308
        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
        if( this.alternativeStorge!=null ) {
324
            List<Resource> r = this.alternativeStorge.getResources(name);
325
            if( r!=null && !r.isEmpty() ) {
326
                return r;
327
            }
328
        }
329
        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
                    multiresourceName = String.valueOf(n) + "." + name ;
345
                }
346
                String filter = builder.eq(
347
                        builder.column(FIELD_RESOURCES_NAME),
348
                        builder.constant(this.tableName+"."+multiresourceName)
349
                ).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
}