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

History | View | Annotate | Download (10.5 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.IOException;
6
import java.io.InputStream;
7
import java.io.OutputStream;
8
import java.net.URL;
9
import java.util.ArrayList;
10
import java.util.List;
11
import org.apache.commons.io.IOUtils;
12
import org.apache.commons.lang3.StringUtils;
13
import org.gvsig.expressionevaluator.ExpressionBuilder;
14
import org.gvsig.expressionevaluator.ExpressionUtils;
15
import org.gvsig.fmap.dal.DALLocator;
16
import org.gvsig.fmap.dal.DataManager;
17
import static org.gvsig.fmap.dal.DataManager.RESOURCES_FIELD_NAME;
18
import static org.gvsig.fmap.dal.DataManager.RESOURCES_FIELD_RESOURCE;
19
import static org.gvsig.fmap.dal.DataManager.RESOURCES_TABLE_NAME;
20
import org.gvsig.fmap.dal.feature.EditableFeature;
21
import org.gvsig.fmap.dal.feature.Feature;
22
import org.gvsig.fmap.dal.feature.FeatureStore;
23
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
24
import org.gvsig.tools.dispose.DisposeUtils;
25
import org.gvsig.tools.resourcesstorage.AbstractResourcesStorage;
26
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29

    
30
/**
31
 *
32
 * @author jjdelcerro
33
 */
34
@SuppressWarnings("UseSpecificCatch")
35
public class JDBCResourcesStorage extends AbstractResourcesStorage {
36

    
37
    private static final Logger LOGGER = LoggerFactory.getLogger(JDBCResourcesStorage.class);
38

    
39
    private static class DataBaseResource implements Resource {
40

    
41
        private class ResourceInputStream extends InputStream {
42

    
43
            @Override
44
            public int read() throws IOException {
45
                return in.read();
46
            }
47

    
48
            @Override
49
            public void close() throws IOException {
50
                DataBaseResource.this.close();
51
            }
52
        }
53

    
54
        private class ResourceOutputStream extends OutputStream {
55

    
56
            @Override
57
            public void write(int b) throws IOException {
58
                out.write(b);
59
            }
60

    
61
            @Override
62
            public void flush() throws IOException {
63
                out.flush();
64
            }
65

    
66
            @Override
67
            public void close() throws IOException {
68
                DataBaseResource.this.close();
69
            }
70
        }
71

    
72
        private final JDBCStoreParameters storeParameters;
73
        private final String tableName;
74
        private final String name;
75

    
76
        private ByteArrayInputStream in;
77
        private ByteArrayOutputStream out;
78

    
79
        public DataBaseResource(JDBCStoreParameters storeParameters, String tableName, String name) {
80
            this.storeParameters = storeParameters;
81
            this.tableName = tableName;
82
            this.name = name;
83
        }
84

    
85
        @Override
86
        public boolean isReadOnly() {
87
            return false;
88
        }
89
        @Override
90
        public URL getURL() {
91
            try {
92
                String url = this.storeParameters.getUrl();
93
                return new URL(url + "&tableName=" + this.tableName + "&resourceName=" + this.name);
94
            } catch (Throwable ex) {
95
                return null;
96
            }
97
        }
98

    
99
        @Override
100
        public boolean exists() {
101
            FeatureStore store = null;
102
            try {
103
                DataManager dataManager = DALLocator.getDataManager();
104
                store = (FeatureStore) dataManager.openStore(
105
                        this.storeParameters.getDataStoreName(),
106
                        this.storeParameters
107
                );
108
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
109
                String filter = builder.eq(
110
                        builder.column(RESOURCES_FIELD_NAME),
111
                        builder.constant(this.tableName+"/"+this.name)
112
                ).toString();
113
                Feature feature = store.findFirst(filter);
114
                return feature!=null;
115
            } catch (Throwable ex) {
116
                LOGGER.warn("Can't access to the resoure '" + this.getURL() + "'.", ex);
117
            } finally {
118
                DisposeUtils.disposeQuietly(store);
119
            }
120
            return false;
121
        }
122

    
123
        @Override
124
        public InputStream asInputStream() throws IOException {
125
            if (this.in != null || this.out != null) {
126
                throw new IllegalStateException("Resource is already open (" + this.getURL() + ")");
127
            }
128
            FeatureStore store = null;
129
            try {
130
                DataManager dataManager = DALLocator.getDataManager();
131
                store = (FeatureStore) dataManager.openStore(
132
                        this.storeParameters.getDataStoreName(),
133
                        this.storeParameters
134
                );
135
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
136
                String filter = builder.eq(
137
                        builder.column(RESOURCES_FIELD_NAME),
138
                        builder.constant(this.tableName+"/"+this.name)
139
                ).toString();
140
                Feature feature = store.findFirst(filter);
141
                if (feature == null) {
142
                    return null;
143
                }
144
                byte[] resource = feature.getByteArray(RESOURCES_FIELD_RESOURCE);
145
                this.in = new ByteArrayInputStream(resource);
146
                return new ResourceInputStream();
147
            } catch (Throwable ex) {
148
                LOGGER.warn("Can't access to the resoure '" + this.getURL() + "'.", ex);
149
            } finally {
150
                DisposeUtils.disposeQuietly(store);
151
            }
152
            return null;
153
        }
154

    
155
        @Override
156
        public OutputStream asOutputStream() throws IOException {
157
            if (this.in != null || this.out != null) {
158
                throw new IllegalStateException("Resource is already open (" + this.getURL() + ").");
159
            }
160
            this.out = new ByteArrayOutputStream();
161
            return new ResourceOutputStream();
162
        }
163

    
164
        @Override
165
        public void close() {
166
            if (this.in != null) {
167
                IOUtils.closeQuietly(this.in);
168
                this.in = null;
169
            }
170
            if (this.out != null) {
171
                FeatureStore store = null;
172
                try {
173
                    DataManager dataManager = DALLocator.getDataManager();
174
                    store = (FeatureStore) dataManager.openStore(
175
                            this.storeParameters.getDataStoreName(),
176
                            this.storeParameters
177
                    );
178
                    store.edit();
179
                    ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
180
                    String filter = builder.eq(
181
                            builder.column(RESOURCES_FIELD_NAME),
182
                            builder.constant(this.tableName+"/"+this.name)
183
                    ).toString();
184
                    Feature feature = store.findFirst(filter);
185
                    EditableFeature efeature;
186
                    if (feature == null) {
187
                        efeature = store.createNewFeature();
188
                        efeature.set(RESOURCES_FIELD_NAME, this.tableName+"/"+this.name);
189
                        efeature.set(RESOURCES_FIELD_RESOURCE, this.out.toByteArray());
190
                        store.insert(efeature);
191
                    } else {
192
                        efeature = feature.getEditable();
193
                        efeature.set(RESOURCES_FIELD_RESOURCE, this.out.toByteArray());
194
                        store.update(efeature);
195
                    }
196
                    store.finishEditing();
197

    
198
                } catch (Throwable ex) {
199
                    LOGGER.warn("Can't write the resoure '" + this.getURL() + "'.", ex);
200
                } finally {
201
                    DisposeUtils.disposeQuietly(store);
202
                }
203
            }
204
        }
205
    }
206

    
207
    private final JDBCStoreParameters resourcesStoreParameters;
208
    private final String tableName;
209

    
210
    public JDBCResourcesStorage(JDBCStoreParameters resourcesStoreParameters, String tableName) {
211
        if( StringUtils.equals(RESOURCES_TABLE_NAME, tableName) ) {
212
            // No podemos buscar recursos de la tabla de recursos, ya que si no
213
            // al abrise la tabla de recursos entraria en bucle.
214
            this.resourcesStoreParameters = null;
215
        } else {
216
            this.resourcesStoreParameters = resourcesStoreParameters;
217
        }
218
        this.tableName = tableName;
219
    }
220

    
221
    @Override
222
    public boolean isEmpty() {
223
        return this.resourcesStoreParameters == null;
224
    }
225

    
226
    @Override
227
    public Resource getResource(String name) {
228
        if (this.resourcesStoreParameters == null) {
229
            return null;
230
        }
231
        return new DataBaseResource(
232
                this.resourcesStoreParameters, 
233
                this.tableName, 
234
                name
235
        );
236
    }
237

    
238
    @Override
239
    public List<Resource> getResources(String name) {
240
        if (this.resourcesStoreParameters == null) {
241
            return null;
242
        }
243
        FeatureStore store = null;
244
        try {
245
            DataManager dataManager = DALLocator.getDataManager();
246
            store = (FeatureStore) dataManager.openStore(
247
                    this.resourcesStoreParameters.getDataStoreName(),
248
                    this.resourcesStoreParameters
249
            );
250
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
251
            List<ResourcesStorage.Resource> ress = new ArrayList<>();
252
            int n = 0;
253
            while (true) {
254
                String multiresourceName;
255
                if (n == 0) {
256
                    multiresourceName = name;
257
                } else {
258
                    multiresourceName = String.valueOf(n) + "." + name;
259
                }
260
                String filter = builder.eq(
261
                        builder.column(RESOURCES_FIELD_NAME),
262
                        builder.constant(multiresourceName)
263
                ).toString();
264
                Feature feature = store.findFirst(filter);
265
                if( feature==null ) {
266
                    break;
267
                }
268
                ress.add(new DataBaseResource(
269
                        this.resourcesStoreParameters, 
270
                        this.tableName,
271
                        multiresourceName
272
                    )
273
                );
274
                n++;
275
            }
276
            if (ress.isEmpty()) {
277
                return null;
278
            }
279
            return ress;
280
        } catch (Throwable ex) {
281
            LOGGER.warn("Can't get resources for '" + this.resourcesStoreParameters.getUrl()+"&resourceName="+name + "'.", ex);
282
            return null;
283
            
284
        } finally {
285
            DisposeUtils.disposeQuietly(store);
286
        }
287

    
288
    }
289

    
290
}