001/*
002 *  Copyright 2012 Chris Pheby
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.jadira.scanner.core.helper;
017
018import java.io.File;
019import java.io.FileInputStream;
020import java.io.FileNotFoundException;
021import java.io.IOException;
022import java.io.InputStream;
023import java.net.URISyntaxException;
024import java.net.URL;
025import java.util.WeakHashMap;
026
027import org.jadira.scanner.core.exception.FileAccessException;
028
029import de.schlichtherle.io.ArchiveDetector;
030import de.schlichtherle.io.ArchiveException;
031
032public final class FileUtils {
033
034    private static final WeakHashMap<String, de.schlichtherle.io.File> FILE_CACHE = new WeakHashMap<String, de.schlichtherle.io.File>();
035        
036        private FileUtils() {
037        }
038
039        public static File getFileForPathName(String pathName, File parentFile) throws FileAccessException {
040
041                final String directoryPathName;
042                if (!pathName.contains("/")) {
043                        directoryPathName = pathName.replace('.', de.schlichtherle.io.File.separatorChar);
044                } else {
045                        directoryPathName = pathName.replace('/', de.schlichtherle.io.File.separatorChar);
046                }
047
048                String filePath = parentFile.getPath() + de.schlichtherle.io.File.separatorChar + directoryPathName;
049                de.schlichtherle.io.File cachedFile = FILE_CACHE.get(filePath);
050                if (cachedFile != null) {
051                        return cachedFile;
052                }
053
054                de.schlichtherle.io.File resolvedFile = new de.schlichtherle.io.File(filePath, ArchiveDetector.ALL);
055                if (resolvedFile.exists()) {
056                        FILE_CACHE.put(filePath, resolvedFile);
057                        return resolvedFile;
058                } else {
059                        return null;
060                }
061        }
062        
063        public static File getFileForPathName(String pathName, URL url) throws FileAccessException {
064
065                File parentFile = getFileFromURL(url);
066
067                return getFileForPathName(pathName, parentFile);
068        }
069
070        public static File getFileFromURL(URL url) throws FileAccessException {
071
072                String pathString = url.toString();
073                if (pathString.endsWith("!/")) {
074                        pathString = pathString.substring(4);
075                        pathString = pathString.substring(0, pathString.length() - 2);
076                }
077
078                File retVal;
079
080                try {
081                        if (pathString.endsWith("/")) {
082                                retVal = new File(url.toURI());
083                        } else {
084                                retVal = new de.schlichtherle.io.File(new File(url.toURI()), ArchiveDetector.ALL);
085                        }
086                } catch (URISyntaxException e) {
087                        throw new FileAccessException("Could not derive file from URL: " + url, e);
088                }
089
090                return retVal;
091        }
092
093    public static <T> T doWithFile(File file, FileInputStreamOperation<T> callback) {
094        
095        InputStream fiStream = null;
096                
097                try {
098                        if (file instanceof de.schlichtherle.io.File) {
099                                fiStream = new de.schlichtherle.io.FileInputStream(file);
100                        } else {
101                                fiStream = new FileInputStream(file);
102                        }
103                        return callback.execute(file.getPath(), fiStream);
104                } catch (FileNotFoundException e) {
105                        throw new FileAccessException("Could not find referenced file: " + file.getPath(), e);
106                } finally {
107                        
108                        try {
109                                if (fiStream != null) {
110                                        fiStream.close();
111                                        
112                                }
113                        } catch (IOException e) {
114                        } finally {
115                        
116                                if (file instanceof de.schlichtherle.io.File) {
117                                        try {
118                                            de.schlichtherle.io.File.umount(); //TVFS.umount((de.schlichtherle.io.File)file);
119                                        } catch (ArchiveException e) { // FsSyncException e) {
120                                        }
121                                }
122                        }
123                }
124    }
125}