/* * IOHandler.java * Copyright 2002 (C) Thomas Behr <ravenlock@gmx.de> * * 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 March 11, 2002, 8:30 PM */ package pcgen.io; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import pcgen.core.GameMode; import pcgen.core.PlayerCharacter; import pcgen.facade.core.CampaignFacade; import pcgen.system.PCGenSettings; import pcgen.util.Logging; /** * {@code IOHandler}<br> * Abstract IO handler class<br> * An IO handler is responsible for reading and/or writing * PlayerCharacters in a specific format from/to a stream * * @author Thomas Behr 11-03-02 */ public abstract class IOHandler { /** * Fills the contents of the given graph from a file. * * <br>author: Thomas Behr 11-03-02 * * @param aPC the PlayerCharacter to store the read data * @param path the name of the input file, i.e. the file to be read */ public final void read(PlayerCharacter aPC, String path) { internalRead(aPC, path, true); } /** * Reads a player character from a character (PCG) file suitable for * preview. * * @param aPC a player character * * @param path a character (PCG) file path */ public final void readForPreview(final PlayerCharacter aPC, final String path) { internalRead(aPC, path, false); } private void internalRead(final PlayerCharacter aPC, final String path, final boolean validate) { InputStream in = null; try { in = new FileInputStream(path); read(aPC, in, validate); } catch (IOException ex) { Logging.errorPrint("Exception in IOHandler::read when reading", ex); } finally { if (in != null) { try { in.close(); } catch (IOException e) { Logging.errorPrint("Exception in IOHandler::read", e); } catch (NullPointerException e) { Logging.errorPrint( "Could not create file inputStream IOHandler::read", e); } } } } ///////////////////////////////////////////////////////////////////////////// ////////////////////////////// Convenience ////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// /** * Writes the contents of the PlayerCharacter to a file. * * <br>author: Thomas Behr 11-03-02 * * @param aPC the PlayerCharacter to write * @param filename the name of the output file * @throws IOException * @throws NullPointerException */ public final void write(PlayerCharacter aPC, String filename) throws IOException, NullPointerException { write(aPC, null, null, filename); } /** * Writes the contents of the PlayerCharacter to a file. * * <br>author: Thomas Behr 11-03-02 * * @param aPC the PlayerCharacter to write * @param filename the name of the output file * @throws IOException * @throws NullPointerException */ public final void write(PlayerCharacter aPC, GameMode mode, List<CampaignFacade> campaigns, String filename) throws IOException, NullPointerException { OutputStream out = null; try { File outFile = new File(filename); createBackupForFile(outFile); out = new FileOutputStream(filename); write(aPC, mode, campaigns, out); } catch (IOException ex) { Logging .errorPrint("Exception in IOHandler::write when writing", ex); throw ex; } finally { if (out != null) { try { out.flush(); out.close(); } catch (IOException e) { Logging.errorPrint("Exception in IOHandler::write", e); throw e; } catch (NullPointerException e) { Logging .errorPrint( "Could not create FileOutputStream in IOHandler::write", e); throw e; } } } } /** * Create a backup of the specified file, but only if backups are enabled, * the file exists and the file is not empty. * * @param outFile The file to be backed up. */ public void createBackupForFile(File outFile) { final String BAK_PREFIX = ".bak"; //$NON-NLS-1$ // Make a backup of the old file, if it exists and isn't empty if (PCGenSettings.getCreatePcgBackup() && outFile.exists() && outFile.length() > 0) { String file = outFile.getName(); String backupPcgPath = PCGenSettings.getBackupPcgDir(); if (backupPcgPath == null || backupPcgPath.isEmpty()) { backupPcgPath = outFile.getParent(); } File bakFile = new File(backupPcgPath, file + BAK_PREFIX); if (bakFile.exists() && outFile.exists() && outFile.length() > 0) { bakFile.delete(); } outFile.renameTo(bakFile); } } /** * Reads the contents of the given PlayerCharacter from a stream * * <br>author: Thomas Behr 11-03-02 * * @param aPC the PlayerCharacter to store the read data * @param in the stream to be read from * @param validate */ protected abstract void read(PlayerCharacter aPC, InputStream in, final boolean validate); ///////////////////////////////////////////////////////////////////////////// ////////////////////////////// Abstract ///////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// /** * Writes the contents of the given PlayerCharacter to a stream * * <br>author: Thomas Behr 11-03-02 * * @param aPC the PlayerCharacter to write * @param out the stream to be written to */ protected abstract void write(PlayerCharacter aPC, GameMode mode, List<CampaignFacade> campaigns, OutputStream out); }