/* * Copyright (C) 2014 Alec Dhuse * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package co.foldingmap; import java.awt.image.BufferedImage; import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import javax.imageio.ImageIO; import javax.swing.ImageIcon; /** * Helper class for getting jar resources. * * @author Alec */ public class ResourceHelper { private final ArrayList<String> filePaths; private static ResourceHelper resourceHelper; private static String webUserAgent; private ResourceHelper() { filePaths = new ArrayList<String>(); webUserAgent = "GoogleEarth/6.1.0.5001(Macintosh;Mac OS X (10.7.4);en;kml:2.2;client:Free;type:default)"; } /** * Adds file paths to search for resource files. * * @param newFilePath */ public static void addFilePath(String newFilePath) { boolean pathFound = false; if (newFilePath.endsWith(File.separator)) { for (String path: ResourceHelper.getInstance().filePaths) { if (path.equals(newFilePath)) { pathFound = true; break; } } //If the path does not exist add it to the paths list. if (!pathFound) ResourceHelper.getInstance().filePaths.add(newFilePath); } else { for (String path: ResourceHelper.getInstance().filePaths) { if (path.equals(newFilePath + File.separator)) { pathFound = true; break; } } //If the path does not exist add it to the paths list. if (!pathFound) ResourceHelper.getInstance().filePaths.add(newFilePath + File.separator); } } /** * Removes all stored resource paths in the ResourceHelper. */ public static void clearResourcePaths() { ResourceHelper.getInstance().filePaths.clear(); } /** * Downloads a file from an external resource over HTTP. * * @param fileAddress * @return */ public static File downloadFile(String fileAddress) { boolean binaryFile; BufferedReader br; BufferedWriter bw; File file; String currentLine, fileExtension, secondLine; URL urlAddress; URLConnection urlConnection; file = null; try { binaryFile = false; try { //Assume HTTP protocol urlAddress = new URL(fileAddress); urlConnection = urlAddress.openConnection(); //set user agent System.setProperty("http.agent", ""); urlConnection.setRequestProperty("User-Agent", webUserAgent); br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); } catch (Exception e) { //HTTP failed try local file urlAddress = null; File sourceFile = new File(fileAddress); int filePathIndex = 0; //If the file does not exist try to find it in the filePaths while (sourceFile.exists() == false) { if (filePathIndex < ResourceHelper.getInstance().filePaths.size()) { sourceFile = new File(ResourceHelper.getInstance().filePaths.get(filePathIndex) + fileAddress); filePathIndex++; } else { sourceFile = null; break; } } if (sourceFile != null) { br = new BufferedReader(new FileReader(sourceFile)); } else { Logger.log(Logger.ERR, "Could not find file: " + fileAddress); return null; } //TODO: Make this work for Binary files. } //read first line to try and discover the file type currentLine = br.readLine(); if (currentLine != null) { if (currentLine.startsWith("GIF")) { fileExtension = "gif"; binaryFile = true; } else if (currentLine.startsWith("PK")) { fileExtension = "kmz"; binaryFile = true; } else if (currentLine.startsWith("����JFIF")) { fileExtension = "jpg"; binaryFile = true; } else if (currentLine.startsWith("�PNG")) { fileExtension = "png"; binaryFile = true; } else if (currentLine.startsWith("<kml")) { fileExtension = "kml"; } else if (currentLine.startsWith("<?xml")) { secondLine = br.readLine(); if (secondLine.startsWith("<rss")) { fileExtension = "rss"; } else if (secondLine.startsWith("<feed")) { fileExtension = "rss"; } else if (secondLine.startsWith("<fmxml")) { fileExtension = "fmxml"; } else { fileExtension = "kml"; } currentLine += ("\n" + secondLine); } else if (currentLine.startsWith("{")) { fileExtension = "geojson"; } else if (currentLine.startsWith("var")) { fileExtension = "js"; } else { fileExtension = "tmp"; } file = File.createTempFile("tempFile", fileExtension); file.deleteOnExit(); if (binaryFile == false) { bw = new BufferedWriter(new FileWriter(file)); bw.write(currentLine + "\n"); while ((currentLine = br.readLine()) != null) { bw.write(currentLine + "\n"); } br.close(); bw.close(); } else { //Binary File br.close(); urlConnection = urlAddress.openConnection(); InputStream is = urlConnection.getInputStream(); byte[] buffer = new byte[urlConnection.getContentLength()]; OutputStream output = new FileOutputStream( file ); BufferedInputStream bis = new BufferedInputStream(is); int n; while ((n = bis.read(buffer)) != -1) { if (n > 0) output.write(buffer, 0, n); } output.close(); } } } catch (Exception e) { System.err.println("Error in ResourceHelper.downloadFile(String) - " + e); } return file; } /** * Downloads a text file over HTTP and returns its contents as a String. * * @param fileAddress * @return */ public static String downloadString(String fileAddress) { BufferedReader br; StringBuilder content; URL urlAddress; URLConnection urlConnection; content = new StringBuilder(); try { urlAddress = new URL(fileAddress); urlConnection = urlAddress.openConnection(); // //set user agent // System.setProperty("http.agent", ""); // urlConnection.setRequestProperty("User-Agent", webUserAgent); br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); while (br.ready()) content.append(br.readLine()); br.close(); } catch (Exception e) { System.err.println("Error in ResourceHelper.downloadString(String) - " + e); } return content.toString(); } /** * Returns a buffered image version of a given image file; * * @param fileName * @return */ public BufferedImage getBufferedImage(String fileName) { BufferedImage bi = null; String filePath, prefix; URL url; try { if (fileName.length() > 7) { prefix = fileName.substring(0, 7); } else { prefix = ""; } if (prefix.equalsIgnoreCase("http://")) { url = new URL(fileName); bi = ImageIO.read(url); } else if (prefix.toLowerCase().startsWith("file:/")) { bi = ImageIO.read(new File(fileName.substring(5))); } else if (fileName.contains(File.separator)) { bi = ImageIO.read(new File(fileName)); } else { filePath = "resources/" + fileName; url = getClass().getResource(filePath); if (url == null) url = getURL(fileName); if (url == null) { //If no file is found check alternative resource paths for (String path: ResourceHelper.getInstance().filePaths) { filePath = path + fileName; url = getURL(filePath); if (url != null) { bi = ImageIO.read(url); break; } } } else { bi = ImageIO.read(url); } } if (bi != null) { return bi; } else { throw new FileNotFoundException(fileName); } } catch (Exception e) { Logger.log(Logger.ERR, "Error in ResourceHelper.getBufferedImage(String) - " + e); return new BufferedImage(16, 16, BufferedImage.TYPE_4BYTE_ABGR) ; } } /** * Returns the instance of ResourceHelper. * * @return */ public static ResourceHelper getInstance() { if (resourceHelper == null) resourceHelper = new ResourceHelper(); return resourceHelper; } /** * Opens a text file and returns the contense as a string. * * @param file * @return The file's text. */ public static String getTextFromFile(File file) { StringBuffer sb = new StringBuffer(); try { FileReader fileReader = new FileReader(file); BufferedReader bf = new BufferedReader(fileReader); while (bf.ready()) sb.append(bf.readLine() + "\n"); } catch (Exception e) { Logger.log(Logger.ERR, "Error in ResourceHelper.getTextFromFile(File) - " + e); } return sb.toString(); } /** * Returns the URL for a given FileLocation * * @param fileLocation * @return */ public URL getURL(String fileLocation) { String filePath, prefix; URL url; url = null; try { if (fileLocation.length() > 7) { prefix = fileLocation.substring(0, 7); } else { prefix = ""; } if (prefix.equalsIgnoreCase("http://")) { url = new URL(fileLocation); } else if (fileLocation.contains(File.separator)) { url = new URL(fileLocation); } else { filePath = "resources" + File.separator + fileLocation; url = getClass().getResource(filePath); } } catch (Exception e) { Logger.log(Logger.ERR, "Error in ResourceHelper.getURL(String \"" + fileLocation + "\") - " + e); } return url; } /** * Gets an image from the jar's main resource folder. * * @param fileName * @return */ public ImageIcon getImage(String fileName) { ImageIcon image; String filePath, prefix; URL url; try { image = new ImageIcon(); if (fileName.length() > 7) { prefix = fileName.substring(0, 7); } else { prefix = ""; } if (prefix.equalsIgnoreCase("http://")) { url = new URL(fileName); image = new ImageIcon(url); } else if (fileName.contains(File.separator)) { image = new ImageIcon(fileName); } else { filePath = "resources/" + fileName; url = getClass().getResource(filePath); if (url == null) url = getURL(fileName); if (url == null) { //If no file is found check alternative resource paths for (String path: ResourceHelper.getInstance().filePaths) { filePath = path + fileName; url = getURL(filePath); if (url != null) { image = new ImageIcon(url); break; } } } else { image = new ImageIcon(url); } } return image; } catch (Exception e) { Logger.log(Logger.ERR, "Error in ResourceHelper.getImage(String \"" + fileName + "\") - " + e); return new ImageIcon(); } } /** * Returns a File with the given name from the jar's resource folder. * Returns null if the file does not exist. * * @param fileName * @return */ public File getFile(String fileName) { try { String filePath = "resources" + File.separator + fileName; URL url = getClass().getResource(filePath); File returnFile = new File(url.toString()); return returnFile; } catch (Exception e) { Logger.log(Logger.ERR, "File: " + fileName + " Not Found."); return null; } } }