Package thegame.io

Source Code of thegame.io.ReadAndSaveSettings

package thegame.io;

import java.awt.datatransfer.DataFlavor;
import java.io.*;
import java.net.URL;
import java.text.DateFormat;
import java.util.*;
import net.sf.jiga.xtended.JXAException;
import net.sf.jiga.xtended.kernel.BitStack;
import net.sf.jiga.xtended.kernel.DebugMap;
import net.sf.jiga.xtended.kernel.Debugger;
import net.sf.jiga.xtended.kernel.JXAenvUtils;
import net.sf.jiga.xtended.kernel.Level;
import net.sf.jiga.xtended.kernel.ThreadWorks;
import thegame.FieldGui;
import thegame.ReadAndSaveSettingsListener;

/**
VM system arg -J-Dthegame.debug.rass=true enables debug output at startup (file read/write operations)
*/

public class ReadAndSaveSettings<DATA extends Serializable> implements Debugger {

    /**VM system arg -J-Dthegame.debug.rass=true enables debug output at startup (file read/write operations)*/
    public static Level DBUG_RASS = DebugMap._getInstance().newDebugLevel(ReadAndSaveSettings.class);
    static {
        if(JXAenvUtils._getSysBoolean("thegame.debug.rass"))
            DebugMap._getInstance().setDebugLevelEnabled(true, DBUG_RASS);
    }
    /**
     *
     */
    public final static String[] _MIME_EXTS = new String[]{"MCO", "mco"};
    /**
     *
     */
    public final DataFlavor DATAFLAVOR;
    private File dataFile;
    DATA data;
    Set listeners = Collections.synchronizedSet(new HashSet());

    /**
     * creates a IO pipeline for GameProperties. No data will be loaded until {@linkplain #loadData()}
     * is invoked.
     *
     * @param dataFile the path of the saved game properties
     */
    public ReadAndSaveSettings(File dataFile, DATA data) {
        this.DATAFLAVOR = new DataFlavor(data.getClass(), data.getClass().getSimpleName());
        this.dataFile = dataFile;
        assert data != null : "must specify a default instance of the data to save/load";
        this.data = data;
    }

    /**
     * creates a IO pipeline for GameProperties.
     *
     * @throws IOException if the loading of props failed in any way
     * @param dataFile the path to store data (a file will be created and the
     * InputStream is copied into it)
     * @param input a resource-stream input of the Serialized DATA to use as
     * default data
     */
    public ReadAndSaveSettings(File dataFile, DATA data, URL input) {
        this(dataFile, data);
        if (input == null) {
            notify(new JXAException(JXAException.LEVEL.APP, "null input"), new Date(), saving | done);
        } else {
            try {
                BufferedInputStream bis = new BufferedInputStream(input.openStream());
                RandomAccessFile raf = new RandomAccessFile(this.dataFile, "rw");
                raf.setLength(bis.available());
                byte[] r = new byte[512];
                int rBLen = 0;
                while ((rBLen = bis.read(r)) != -1) {
                    raf.write(r, 0, rBLen);
                }
                bis.close();
                raf.close();
                notify(null, new Date(), saving | done);
            } catch (IOException ex) {
                if (isDebugEnabled()) {
                    ex.printStackTrace();
                }
                notify(ex, new Date(), saving | done);
            }
        }
    }

    public void deleteFile() {
        dataFile.delete();
        notify(null, null, done | delete);
    }
    private static BitStack _stateBits = new BitStack();
    private final static int ERROR = _stateBits._newBitRange();
    private final static int SAVED = _stateBits._newBitRange();
    private final static int DELETED = _stateBits._newBitRange();
    private final static int LOADED = _stateBits._newBitRange();
    private final static int NOTFOUND = _stateBits._newBitRange();
    private final static int SAVING = _stateBits._newBitRange();
    private final static int LOADING = _stateBits._newBitRange();
    private int state = 0;
    private ReadAndSaveSettingsListener stateHandler = new ReadAndSaveSettingsListener<DATA>() {

        public void dataSaved(DATA data, String date) {
            state = SAVED;
        }

        public void dataDeleted() {
            state = DELETED;
        }

        public void dataLoaded(DATA data, String date) {
            state = LOADED;
        }

        public void dataNotFound() {
            state = NOTFOUND;
        }

        public void dataError(Object e) {
            state = ERROR;
        }

        public void dataSaving(String m) {
            state = SAVING;
        }

        public void dataLoading(String m) {
            state = LOADING;
        }
    };

    /**
     * returns true if and only if the last activity had errors and clears the
     * error bits.
     *
     * @return true if and only if the last activity had errors
     *
     */
    public boolean checkError() {
        int ret = state;
        state = 0;
        return (ret & (ERROR | NOTFOUND)) != 0;
    }

    public void saveData() {
        Date now = new Date();
        ObjectOutputStream oos = null;
        FileOutputStream fos = null;
        RandomAccessFile raf = null;
        Exception error = null;
        notify(error, now, saving);
        try {
            raf = new RandomAccessFile(dataFile, "rw");
            raf.setLength(0);
            oos = new ObjectOutputStream(fos = new FileOutputStream(raf.getFD()));
            oos.writeObject(data);
            oos.writeObject(now);
            fos.close();
            raf.close();
        } catch (Exception e) {
            if (isDebugEnabled()) {
                e.printStackTrace();
            }
            error = e;
        } finally {
            notify(error, now, done | saving);
        }
    }

    public DATA loadData() {
        Exception error = null;
        ObjectInputStream ois = null;
        FileInputStream fis = null;
        RandomAccessFile raf = null;
        Date date = null;
        notify(error, date, loading);
        try {
            raf = new RandomAccessFile(dataFile, "r");
            ois = new ObjectInputStream(fis = new FileInputStream(raf.getFD()));
            data = (DATA) ois.readObject();
            date = (Date) ois.readObject();
            if (data == null && date == null) {
                error = new FileNotFoundException("no data could be read");
            }
            ois.close();
            fis.close();
            raf.close();
        } catch (Exception e) {
            if (isDebugEnabled()) {
                e.printStackTrace();
            }
            error = e;
        } finally {
            notify(error, date, done | loading);
            return data;
        }
    }
    final static int done = 1;
    final static int loading = 2;
    final static int saving = 4;
    final static int delete = 8;

    private void _notify(ReadAndSaveSettingsListener l, final Exception error, final Date date, final int status) {
        switch (status) {
            case loading:
                l.dataLoading("loading file...");
                break;
            case saving:
                l.dataSaving("saving file...");
                break;
            default:
                if (error == null) {
                    if ((status & done) != 0) {
                        String dateFormat = date == null ? "" : DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(date);
                        if ((status & loading) != 0) {
                            l.dataLoaded(data, dateFormat);
                        }
                        if ((status & saving) != 0) {
                            l.dataSaved(data, dateFormat);
                        }
                        if ((status & delete) != 0) {
                            l.dataDeleted();
                        }
                    }
                } else if (error instanceof FileNotFoundException) {
                    l.dataNotFound();
                } else {
                    l.dataError(error);
                }
                break;
        }
    }

    private void notify(final Exception error, final Date date, final int status) {
        _notify(stateHandler, error, date, status);
        Runnable r = new Runnable() {

            public void run() {
                synchronized (listeners) {
                    for (Iterator<ReadAndSaveSettingsListener> i = listeners.iterator(); i.hasNext();) {
                        _notify(i.next(), error, date, status);
                    }
                }
            }
        };
        if (ThreadWorks.Swing.isEventDispatchThread()) {
            r.run();
        } else {
            ThreadWorks.Swing.invokeLater(r);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }

    public void addListener(ReadAndSaveSettingsListener listener) {
        listeners.add(listener);
    }

    public void removeListener(ReadAndSaveSettingsListener listener) {
        listeners.remove(listener);
    }

    /**
     * VM system arg -J-Dthegame.debug.rass=true enables debug output at startup (file read/write operations)*/
    public boolean isDebugEnabled() {
        return DebugMap._getInstance().isDebuggerEnabled(ReadAndSaveSettings.class);
    }

    public void setDebugEnabled(boolean b) {
        DebugMap._getInstance().setDebuggerEnabled(b, ReadAndSaveSettings.class);
    }
}
TOP

Related Classes of thegame.io.ReadAndSaveSettings

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.