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 / spi / ZipResourcesStorage.java @ 44297

History | View | Annotate | Download (7.53 KB)

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

    
3
import java.io.ByteArrayInputStream;
4
import java.io.ByteArrayOutputStream;
5
import java.io.File;
6
import java.io.IOException;
7
import java.io.InputStream;
8
import java.io.OutputStream;
9
import java.net.URI;
10
import java.net.URISyntaxException;
11
import java.net.URL;
12
import java.nio.file.FileSystem;
13
import java.nio.file.FileSystems;
14
import java.nio.file.Files;
15
import java.nio.file.Path;
16
import java.nio.file.StandardCopyOption;
17
import java.util.Collections;
18
import java.util.Objects;
19
import java.util.zip.ZipEntry;
20
import java.util.zip.ZipFile;
21
import org.apache.commons.io.FilenameUtils;
22
import org.apache.commons.io.IOUtils;
23
import org.apache.commons.lang3.StringUtils;
24
import org.gvsig.fmap.dal.AbstractDataResource;
25
import org.gvsig.tools.resourcesstorage.AbstractResourcesStorage;
26
import org.gvsig.tools.resourcesstorage.ResourcesStorage.Resource;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29

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

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

    
39
    public class ZipFileResource
40
            extends AbstractDataResource
41
            implements Resource {
42

    
43
        private class ResourceInputStream extends InputStream {
44

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

    
50
            @Override
51
            public void close() throws IOException {
52
                ZipFileResource.this.close();
53
            }
54
        }
55

    
56
        private class ResourceOutputStream extends OutputStream {
57

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

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

    
68
            @Override
69
            public void close() throws IOException {
70
                ZipFileResource.this.close();
71
            }
72
        }
73

    
74
        private final File zipFile;
75
        private final String tableName;
76
        private final String resourceName;
77
        private ZipFile zip;
78
        private InputStream in;
79
        private ByteArrayOutputStream out;
80

    
81
        public ZipFileResource(File zipFile, String tableName, String resourceName) {
82
            this.zipFile = zipFile;
83
            this.tableName = tableName;
84
            this.resourceName = resourceName;
85
            this.zip = null;
86
            this.in = null;
87
            this.out = null;
88
            if (StringUtils.isBlank(this.tableName)) {
89
                LOGGER.warn("The table name is empty (URL=" + this.getURL() + ").");
90
            }
91
            if (StringUtils.isBlank(this.resourceName)) {
92
                LOGGER.warn("The resource name is empty (URL=" + this.getURL() + ").");
93
            }
94
        }
95

    
96
        @Override
97
        public boolean isReadOnly() {
98
            return false;
99
        }
100
        
101
        @Override
102
        public final URL getURL() {
103
            try {
104
                return new URL("jar:" + this.zipFile.toURI().toString() + "!/" + this.tableName + "." + this.resourceName);
105
            } catch (Exception ex) {
106
                return null;
107
            }
108
        }
109

    
110
        @Override
111
        public boolean exists() {
112
            try {
113
                if (!this.zipFile.exists()) {
114
                    return false;
115
                }
116
                ZipFile z = new ZipFile(zipFile);
117
                try {
118
                    ZipEntry entry = z.getEntry(this.tableName + "." + this.resourceName);
119
                    if (entry == null) {
120
                        return false;
121
                    }
122
                    return true;
123
                } finally {
124
                    IOUtils.closeQuietly(z);
125
                }
126
            } catch (Exception ex) {
127
                LOGGER.warn("Can't access to the resource (" + Objects.toString(this.getURL()) + ").", ex);
128
                return false;
129
            }
130
        }
131

    
132
        @Override
133
        public InputStream asInputStream() throws IOException {
134
            if (!this.zipFile.exists()) {
135
                return null;
136
            }
137
            if (this.in != null || this.out != null) {
138
                throw new IllegalStateException("Resource is already open (" + this.zipFile.toString() + "!" + this.tableName + ")");
139
            }
140
            try {
141
                if (this.zip == null) {
142
                    this.zip = new ZipFile(zipFile);
143
                }
144
                ZipEntry entry = this.zip.getEntry(this.tableName + "." + this.resourceName);
145
                if (entry == null) {
146
                    return null;
147
                }
148
                this.in = this.zip.getInputStream(entry);
149
                return new ResourceInputStream();
150
            } catch (Exception ex) {
151
                LOGGER.warn("Can't create input stream (" + Objects.toString(this.getURL()) + ").", ex);
152
                return null;
153
            }
154
        }
155

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

    
165
        @Override
166
        public void close() {
167
            if (this.in != null) {
168
                IOUtils.closeQuietly(this.in);
169
                this.in = null;
170
            }
171
            if (this.out != null) {
172
                ByteArrayInputStream contents = new ByteArrayInputStream(this.out.toByteArray());
173
                try {
174
                    this.updateZipEntry(zipFile, this.tableName + "." + this.resourceName, contents);
175
                } catch (Exception ex) {
176
                    LOGGER.warn("Can't write resource (" + Objects.toString(this.getURL()) + ").", ex);
177
                } finally {
178
                    IOUtils.closeQuietly(contents);
179
                    IOUtils.closeQuietly(this.out);
180
                    this.out = null;
181
                }
182
            }
183
            if (this.zip != null) {
184
                IOUtils.closeQuietly(this.zip);
185
                this.zip = null;
186
            }
187
        }
188

    
189
        private void updateZipEntry(File zip, String entryName, InputStream entryContents) throws URISyntaxException, IOException {
190
            FileSystem zipfs = null;
191
            try {
192
                URI zipfsuri = new URI("jar:" + zip.toURI().toString());
193
                zipfs = FileSystems.newFileSystem(zipfsuri, Collections.singletonMap("create", "true"));
194
                Path entryPath = zipfs.getPath(entryName);
195
                Files.copy(entryContents, entryPath, StandardCopyOption.REPLACE_EXISTING);
196
            } finally {
197
                IOUtils.closeQuietly(zipfs);
198
            }
199
        }
200
    }
201

    
202
    private final File zipFile;
203
    private final String tableName;
204
    
205
    public ZipResourcesStorage(String pathName, String tableName) {
206
        this.zipFile = new File(pathName + ".gvres");
207
        this.tableName = tableName;
208
    }
209
    
210
    public static boolean existsStorage(String pathName) {
211
        File theZipFile = new File(pathName + ".gvres");
212
        return theZipFile.exists();
213
    }
214

    
215
    @Override
216
    public Resource getResource(String resourceName) {
217
        ZipFileResource res = new ZipFileResource(
218
                this.zipFile,
219
                this.tableName,
220
                resourceName
221
        );
222
        return res;
223
    }
224

    
225
    @Override
226
    public boolean isEmpty() {
227
        return !this.zipFile.exists();
228
    }
229

    
230
}