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 / FileMultiResource.java @ 44276

History | View | Annotate | Download (5.26 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.IOUtils;
22
import org.apache.commons.lang3.StringUtils;
23
import org.gvsig.fmap.dal.AbstractDataResource;
24
import org.gvsig.tools.util.ResourcesStorage.Resource;
25
import org.slf4j.LoggerFactory;
26

    
27
/**
28
 *
29
 * @author jjdelcerro
30
 */
31
@SuppressWarnings("UseSpecificCatch")
32
public class FileMultiResource
33
        extends AbstractDataResource
34
        implements Resource {
35

    
36
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FileMultiResource.class);
37

    
38
    private final File zipFile;
39
    private final String tableName;
40
    private final String resourceName;
41
    private ZipFile zip;
42
    private InputStream in;
43
    private ByteArrayOutputStream out;
44

    
45
    public FileMultiResource(File zipFile, String tableName, String resourceName) {
46
        this.zipFile = new File(zipFile.getAbsolutePath() + ".gvres");
47
        this.tableName = tableName;
48
        this.resourceName = resourceName;
49
        this.zip = null;
50
        this.in = null;
51
        this.out = null;
52
        if( StringUtils.isBlank(this.tableName) ) {
53
            LOGGER.warn("The table name is empty (URL="+this.getURL()+").");
54
        }
55
        if( StringUtils.isBlank(this.resourceName) ) {
56
            LOGGER.warn("The resource name is empty (URL="+this.getURL()+").");
57
        }
58
    }
59

    
60
    @Override
61
    public URL getURL() {
62
        try {
63
            return new URL("jar:" + this.zipFile.toURI().toString() + "!/" + this.tableName + "." + this.resourceName);
64
        } catch (Exception ex) {
65
            return null;
66
        }
67
    }
68

    
69
    @Override
70
    public boolean exists() {
71
        try {
72
            if (!this.zipFile.exists()) {
73
                return false;
74
            }
75
            ZipFile z = new ZipFile(zipFile);
76
            try {
77
                ZipEntry entry = z.getEntry(this.tableName + "." + this.resourceName);
78
                if (entry == null) {
79
                    return false;
80
                }
81
                return true;
82
            } finally {
83
                IOUtils.closeQuietly(z);
84
            }
85
        } catch (Exception ex) {
86
            LOGGER.warn("Can't access to the resource (" + Objects.toString(this.getURL()) + ").", ex);
87
            return false;
88
        }
89
    }
90

    
91
    @Override
92
    public InputStream asInputStream() throws IOException {
93
        if (!this.zipFile.exists()) {
94
            return null;
95
        }
96
        if (this.in != null || this.out != null) {
97
            throw new IllegalStateException("Resource is already open (" + this.zipFile.toString() + "!" + this.tableName + ")");
98
        }
99
        try {
100
            if( this.zip == null ) {
101
                this.zip = new ZipFile(zipFile);
102
            }
103
            ZipEntry entry = this.zip.getEntry(this.tableName + "." + this.resourceName);
104
            if (entry == null) {
105
                return null;
106
            }
107
            this.in = this.zip.getInputStream(entry);
108
            return this.in;
109
        } catch (Exception ex) {
110
            LOGGER.warn("Can't create input stream (" + Objects.toString(this.getURL()) + ").", ex);
111
            return null;
112
        }
113
    }
114

    
115
    @Override
116
    public OutputStream asOutputStream() throws IOException {
117
        if (this.in != null || this.out != null) {
118
            throw new IllegalStateException("Resource is already open (" + Objects.toString(this.getURL()) + ").");
119
        }
120
        this.out = new ByteArrayOutputStream();
121
        return this.out;
122
    }
123

    
124
    @Override
125
    public void close() {
126
        if (this.in != null) {
127
            IOUtils.closeQuietly(this.in);
128
            this.in = null;
129
        }
130
        if (this.out != null) {
131
            ByteArrayInputStream contents = new ByteArrayInputStream(this.out.toByteArray());
132
            try {
133
                this.updateZipEntry(zipFile, this.tableName + "." + this.resourceName, contents);
134
            } catch (Exception ex) {
135
                LOGGER.warn("Can't write resource (" + Objects.toString(this.getURL()) + ").", ex);
136
            } finally {
137
                IOUtils.closeQuietly(contents);
138
                IOUtils.closeQuietly(this.out);
139
                this.out = null;
140
            }
141
        }
142
        if (this.zip != null) {
143
            IOUtils.closeQuietly(this.zip);
144
            this.zip = null;
145
        }
146
    }
147

    
148
    private void updateZipEntry(File zip, String entryName, InputStream entryContents) throws URISyntaxException, IOException {
149
        FileSystem zipfs = null;
150
        try {
151
            URI zipfsuri = new URI("jar:" + zip.toURI().toString());
152
            zipfs = FileSystems.newFileSystem(zipfsuri, Collections.singletonMap("create", "true"));
153
            Path entryPath = zipfs.getPath(entryName);
154
            Files.copy(entryContents, entryPath, StandardCopyOption.REPLACE_EXISTING);
155
        } finally {
156
            IOUtils.closeQuietly(zipfs);
157
        }
158
    }
159
}