/* * LstFileLoader.java * Copyright 2003 (C) David Hibbs <sage_sam@users.sourceforge.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on September 22, 2003, 11:29 AM * * Current Ver: $Revision$ <br> */ package pcgen.persistence.lst; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import pcgen.cdom.base.Constants; import pcgen.core.SettingsHandler; import pcgen.core.utils.CoreUtility; import pcgen.core.utils.MessageType; import pcgen.core.utils.ShowMessageDelegate; import pcgen.persistence.PersistenceLayerException; import pcgen.util.Logging; /** * This class is a base class for LST file loaders. * * <p> * This class lays out a skeleton for LST file loading, setting * up shared features and functions for loading and parsing of files. * * <p> * This class extends the <tt>Observable</tt> class so interested observers * will be notified of the progress of loading files. * * <p> * Instances of LstFileLoader or its subclasses are not thread-safe, * so any thread should only acccess a single loader (or group of loaders) * at a time. */ public final class LstFileLoader { private LstFileLoader() { //Utility class } /** The String that represents the start of a line comment. */ public static final char LINE_COMMENT_CHAR = '#'; //$NON-NLS-1$ /** The String that separates individual objects */ public static final String LINE_SEPARATOR_REGEXP = "(\r\n?|\n)"; //$NON-NLS-1$ /** * This method reads the given URL and stores its contents in the provided * data buffer, returning a URL to the specified file for use in log/error * messages by its caller. * * @param uri String path of the URL to read -- MUST be a URL path, * not a file! * @return URL pointing to the actual file read, for use in debug/log * messages * @throws PersistenceLayerException */ public static StringBuilder readFromURI(URI uri) throws PersistenceLayerException { if (uri == null) { // We have a problem! throw new PersistenceLayerException( "LstFileLoader.readFromURI() received a null uri parameter!"); } URL url; try { url = uri.toURL(); } catch (MalformedURLException e) { throw new PersistenceLayerException( "LstFileLoader.readFromURI() could not convert parameter to a URL: " + e.getLocalizedMessage()); } InputStream inputStream = null; StringBuilder dataBuffer = null; try { //only load local urls, unless loading of URLs is allowed if (!CoreUtility.isNetURL(url) || SettingsHandler.isLoadURLs()) { // try to make a buffer of sufficient size in one go to save on GC int size = 2048; if ("file".equals(url.getProtocol())) { long fileSize = new File(url.getPath()).length(); if (fileSize > 0) { // this is an overestimate if the LST has wide // characters, but it's accurate for ASCII size = (int) fileSize; } } dataBuffer = new StringBuilder(size); // Get the URL and open the stream inputStream = url.openStream(); // Read from the stream final InputStreamReader ir = new InputStreamReader(inputStream, "UTF-8"); //$NON-NLS-1$ // Buffer the stream content final char[] b = new char[512]; int n; n = ir.read(b, 0, 1); /* * Take out the optional BOM: This is a pre-Java 1.6 workaround * for Sun B-U-G 4508058, see: * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 */ if (n == 1 && b[0] != '\uFEFF') { dataBuffer.append(b, 0, 1); } while ((n = ir.read(b)) > 0) { dataBuffer.append(b, 0, n); } } else { // Just to protect people from using web // sources without their knowledge, // we added a preference. ShowMessageDelegate .showMessageDialog( "Preferences are currently set to NOT allow\nloading of " + "sources from web links. \n" + url + " is a web link", Constants.APPLICATION_NAME, MessageType.ERROR); // aURL = null; //currently unnecessary reassignment } } catch (IOException ioe) { // Don't throw an exception here because a simple // file not found will prevent ANY other files from // being loaded/processed -- NOT what we want Logging.errorPrint("ERROR:" + url + "\n" + "Exception type:" + ioe.getClass().getName() + "\n" + "Message:" + ioe.getMessage()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e2) { Logging.errorPrint( "Can't close inputStream in LstSystemLoader.initFile", e2); } } } return dataBuffer == null ? new StringBuilder() : dataBuffer; } }