GeoWebCache

root/trunk/geowebcache/src/main/java/org/geowebcache/storage/blobstore/file/FileBlobStore.java

Revision 893, 12.4 kB (checked in by arneke, 6 weeks ago)

Adding discontinuous tile range and renaming TileRangeObject? to TileRange?

Line 
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
6 *
7 *  This program is distributed in the hope that it will be useful,
8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *  GNU General Public License for more details.
11 *
12 *  You should have received a copy of the GNU Lesser General Public License
13 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
14 *
15 * @author Arne Kepp / The Open Planning Project 2009
16 *
17 */
18package org.geowebcache.storage.blobstore.file;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.FileNotFoundException;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26
27import org.apache.commons.logging.Log;
28import org.apache.commons.logging.LogFactory;
29import org.geowebcache.mime.MimeException;
30import org.geowebcache.mime.MimeType;
31import org.geowebcache.storage.BlobStore;
32import org.geowebcache.storage.DefaultStorageFinder;
33import org.geowebcache.storage.StorageException;
34import org.geowebcache.storage.TileObject;
35import org.geowebcache.storage.TileRange;
36import org.geowebcache.storage.WFSObject;
37import org.geowebcache.util.ServletUtils;
38
39/**
40 * See BlobStore interface description for details
41 *
42 */
43public class FileBlobStore implements BlobStore {
44    private static Log log = LogFactory.getLog(org.geowebcache.storage.blobstore.file.FileBlobStore.class);
45   
46    public static final int BUFFER_SIZE = 32768;
47   
48    private final String path;
49   
50   
51    public FileBlobStore(DefaultStorageFinder defStoreFinder) throws StorageException {
52        path = defStoreFinder.getDefaultPath();
53    }
54   
55    public FileBlobStore(String rootPath) throws StorageException {
56        path = rootPath;
57        File fh = new File(path);
58       
59        if(! fh.exists() || ! fh.isDirectory() || !  fh.canWrite()) {
60            throw new StorageException(path + " is not writable directory.");
61        }
62    }
63   
64    public boolean delete(String layerName) throws StorageException {
65        int count = 0;
66
67        String prefix = path + File.separator 
68            + FilePathGenerator.filteredLayerName(layerName);
69
70        File layerPath = new File(prefix);
71
72        if (!layerPath.exists() || !layerPath.canWrite()) {
73            log.info(layerPath + " does not exist or is not writable");
74            return false;
75        }
76        File[] srsZoomDirs = layerPath.listFiles();
77
78        for (File srsZoom : srsZoomDirs) {
79            File[] intermediates = srsZoom.listFiles();
80
81            for (File imd : intermediates) {
82                File[] tiles = imd.listFiles();
83
84                for (File tile : tiles) {
85                    tile.delete();
86                    count++;
87                }
88
89                String[] chk = imd.list();
90                if (chk == null || chk.length == 0) {
91                    imd.delete();
92                    count++;
93                }
94            }
95
96            String[] chk = srsZoom.list();
97            if (chk == null || chk.length == 0) {
98                srsZoom.delete();
99                count++;
100            }
101
102        }
103
104        if(layerPath.exists()) {
105            layerPath.delete();
106        }
107       
108       
109        log.info("Truncated " + count + " tiles from " + layerPath);
110        return true;
111    }
112   
113    public boolean delete(TileObject stObj) throws StorageException {
114        File fh = getFileHandleTile(stObj, false);
115        if (!fh.exists())
116            return false;
117
118        //System.out.println("Deleting " + fh.getAbsolutePath());
119       
120        if (!fh.delete()) {
121            throw new StorageException("Unable to delete "
122                    + fh.getAbsolutePath());
123        }
124       
125        File parentDir = new File(fh.getParent());
126       
127        // TODO This could potentially be very slow
128        if(parentDir.isDirectory() && parentDir.canWrite() && parentDir.list().length == 0) {
129            parentDir.delete();
130        }
131
132        return true;
133    }
134
135   
136    public boolean delete(WFSObject stObj) throws StorageException {
137        if(stObj.getQueryBlobSize() != -1) {
138            File fh = getFileHandleWFS(stObj, true, false);
139
140            if (fh.exists() && !fh.delete()) {
141                throw new StorageException("Unable to delete "
142                        + fh.getAbsolutePath());
143            }
144        }
145       
146        File fh = getFileHandleWFS(stObj, false, false);
147        if (!fh.exists())
148            return false;
149
150        if (!fh.delete()) {
151            throw new StorageException("Unable to delete "
152                    + fh.getAbsolutePath());
153        }
154
155        return true;
156    }
157   
158    public boolean delete(TileRange trObj) throws StorageException {
159        int count = 0;
160
161        String prefix = path + File.separator 
162            + FilePathGenerator.filteredLayerName(trObj.layerName);
163
164        File layerPath = new File(prefix);
165
166        if (!layerPath.exists() || !layerPath.canWrite()) {
167            throw new StorageException(prefix
168                    + " does not exist or is not writable.");
169        }
170        FilePathFilter fpf = new FilePathFilter(trObj);
171
172        File[] srsZoomDirs = layerPath.listFiles(fpf);
173
174        for (File srsZoom : srsZoomDirs) {
175            File[] intermediates = srsZoom.listFiles(fpf);
176
177            for (File imd : intermediates) {
178                File[] tiles = imd.listFiles(fpf);
179
180                for (File tile : tiles) {
181                    tile.delete();
182                    count++;
183                }
184
185                String[] chk = imd.list();
186                if (chk == null || chk.length == 0) {
187                    imd.delete();
188                    count++;
189                }
190            }
191
192            String[] chk = srsZoom.list();
193            if (chk == null || chk.length == 0) {
194                srsZoom.delete();
195                count++;
196            }
197
198        }
199
200        log.info("Truncated " + count + " tiles");
201
202        return true;
203    }
204
205    public byte[] get(TileObject stObj) throws StorageException {
206        File fh = getFileHandleTile(stObj, false);
207        return readFile(fh);
208    }
209
210    public long get(WFSObject stObj) throws StorageException {
211        // Should we check and compare the blobs?
212        File fh = getFileHandleWFS(stObj, false, false);
213        //return readFile(fh);
214       
215        stObj.setInputStream(getFileInputStream(fh));
216       
217        return fh.length();
218    }
219   
220    public void put(TileObject stObj) throws StorageException {
221        File fh = getFileHandleTile(stObj, true);
222        writeFile(fh,stObj.getBlob());
223    }
224   
225    public void put(WFSObject stObj) throws StorageException {
226        if(stObj.getQueryBlobSize() != -1) {
227            File queryfh = getFileHandleWFS(stObj,true, true);
228            writeFile(queryfh, stObj.getQueryBlob());
229        }
230       
231        File responsefh = getFileHandleWFS(stObj, false, true);
232        writeFile(responsefh,stObj.getInputStream());
233       
234        InputStream is = getFileInputStream(responsefh);
235
236        stObj.setInputStream(is);
237    }
238   
239    private File getFileHandleTile(TileObject stObj, boolean create) {
240        String[] paths = null;
241        try {
242            paths = FilePathGenerator.tilePath(
243                    path, stObj.getLayerName(),
244                    stObj.getXYZ(), stObj.getGridSetId(), 
245                    MimeType.createFromFormat(stObj.getBlobFormat()), 
246                    stObj.getParametersId());
247        } catch (MimeException me) {
248            log.error(me.getMessage());
249        }
250
251        if (create) {
252            File parent = new File(paths[0]);
253            parent.mkdirs();
254        }
255
256        return new File(paths[0] + File.separator + paths[1]);
257    }
258   
259    private File getFileHandleWFS(WFSObject stObj, boolean query, boolean create) {
260        String parentPath;
261       
262        if(query) {
263            parentPath = path +File.separator+ "wfs" + File.separator + "query";
264        } else {
265            parentPath = path +File.separator+ "wfs" + File.separator + "response";
266        }
267       
268        if(create) {
269            File dir = new File(parentPath);
270            dir.mkdirs();
271        }
272       
273        return new File(parentPath + File.separator + stObj.getId());
274    }
275   
276   
277    private byte[] readFile(File fh) throws StorageException {
278        byte[] blob = null;
279
280        FileInputStream fis;
281        try {
282            fis = new FileInputStream(fh);
283        } catch (FileNotFoundException e) {
284            return null;
285        }
286
287        try {
288            blob = ServletUtils.readStream(fis, BUFFER_SIZE, BUFFER_SIZE);
289        } catch (IOException ioe) {
290            throw new StorageException(ioe.getMessage() + " for "
291                    + fh.getAbsolutePath());
292        } finally {
293            try {
294                fis.close();
295            } catch (IOException ioe) {
296                throw new StorageException(ioe.getMessage() + " for "
297                        + fh.getAbsolutePath());
298            }
299        }
300       
301        return blob;
302    }
303   
304    private InputStream getFileInputStream(File fh) throws StorageException {
305        FileInputStream fis = null;
306        try {
307            fis = new FileInputStream(fh);
308        } catch (FileNotFoundException e) {
309            return null;
310        }
311       
312        return fis;
313    }
314   
315    private void writeFile(File fh, byte[] blob) throws StorageException {
316        // Open the output stream
317        FileOutputStream fos;
318        try {
319            fos = new FileOutputStream(fh);
320        } catch (FileNotFoundException ioe) {
321            throw new StorageException(ioe.getMessage() + " for "
322                    + fh.getAbsolutePath());
323        }
324
325        // Write the stream
326        try {
327            fos.write(blob);
328        } catch (IOException ioe) {
329            throw new StorageException(ioe.getMessage() + " for "
330                    + fh.getAbsolutePath());
331        } finally {
332            try {
333                fos.close();
334            } catch (IOException ioe) {
335                throw new StorageException(ioe.getMessage() + " for "
336                        + fh.getAbsolutePath());
337            }
338        }
339    }
340   
341    private int writeFile(File fh, InputStream is) throws StorageException {
342        // Open the output stream
343        FileOutputStream fos;
344        try {
345            fos = new FileOutputStream(fh);
346        } catch (FileNotFoundException ioe) {
347            throw new StorageException(ioe.getMessage() + " for "
348                    + fh.getAbsolutePath());
349        }
350
351        byte[] buffer = new byte[2048];
352        int read = 0;
353        int total = 0;
354        try {
355            while(read != -1) {
356                 read = is.read(buffer);
357                 if(read != -1) {
358                     fos.write(buffer, 0, read);
359                     total += read;
360                 }
361            }
362        } catch (IOException ioe) {
363            throw new StorageException(ioe.getMessage() + " for "
364                    + fh.getAbsolutePath());
365        } finally {
366            try {
367                fos.close();
368                is.close();
369            } catch (IOException ioe) {
370                throw new StorageException(ioe.getMessage() + " for "
371                        + fh.getAbsolutePath());
372            }
373        }
374        return read;
375    }
376       
377    public void clear() throws StorageException {
378        throw new StorageException("Not implemented yet!");
379    }
380
381    /**
382     * Destroy method for Spring
383     */
384    public void destroy() {
385       // Do nothing
386    }
387
388//    public boolean isReady() {
389//        File fh = new File(path + File.separator + "version");
390//        if(fh.isFile() && fh.canRead()) {
391//            try {
392//                FileInputStream fis = new FileInputStream(fh);
393//                byte[] ret = ServletUtils.readStream(fis, 10, 10);
394//               
395//                int ver = Integer.parseInt(new String(ret));
396//               
397//                if(ver == 120) {
398//                    return true;
399//                }
400//            } catch (FileNotFoundException e) {
401//                e.printStackTrace();
402//            } catch (IOException e) {
403//                e.printStackTrace();
404//            }
405//            return true;
406//        }
407//        log.error("Could not find " + fh.getAbsolutePath() + ", upgrade required.");
408//        return false;
409//    }
410}
Note: See TracBrowser for help on using the browser.