com.aionemu.gameserver.dataholders.DataLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.aionemu.gameserver.dataholders.DataLoader.java

Source

/**
 * This file is part of Aion-Lightning <aion-lightning.org>.
 *
 *  Aion-Lightning 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.
 *
 *  Aion-Lightning 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 Aion-Lightning.
 *  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionemu.gameserver.dataholders;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;

/**
 * This class is responsible for loading data from static .txt files.<br>
 * It's used as base class of {@link NpcData} and {@link SpawnData}.<br>
 * <br>
 * <font color="red">NOTICE: </font> This class is used temporarily and later
 * will be removed and npc and spawn data will be loaded with xml loader.<br>
 * <br>
 * <font color="red"><b>Do not use this class for anything else than
 * <tt>NpcData</tt> or <tt>SpawnData</tt></b></font>
 *
 * @author Luno
 */
abstract class DataLoader {

    /**
     * The logger used for <tt>DataLoader</tt> and its subclasses
     */
    protected Logger log = LoggerFactory.getLogger(getClass().getName());
    /**
     * Relative path to directory containing .txt files with static data
     */
    private static final String PATH = "./data/static_data/";
    /**
     * File containing data to load ( may be file or directory )
     */
    private File dataFile;

    /**
     * Constructor that is supposed to be called from subclass.
     *
     * @param file file or directory in the static data directory, containing
     *             data that will be loaded
     */
    DataLoader(String file) {
        this.dataFile = new File(PATH + file);
    }

    /**
     * This method is supposed to be called from subclass to initialize data
     * loading process.<br>
     * <br>
     * This method is using file given in the constructor to load the data and
     * there are two possibilities:
     * <ul>
     * <li>Given file is file is in deed the <b>file</b> then it's forwarded to
     * {@link #loadFile(File)} method</li>
     * <li>Given file is a <b>directory</b>, then this method is obtaining list
     * of all visible .txt files in this directory and subdirectiores ( except
     * hidden ones and those named "new" ) and call {@link #loadFile(File)} for
     * each of these files.
     * </ul>
     */
    @SuppressWarnings("deprecation")
    protected void loadData() {
        if (dataFile.isDirectory()) {
            Collection<?> files = FileUtils
                    .listFiles(dataFile,
                            FileFilterUtils
                                    .andFileFilter(
                                            FileFilterUtils.andFileFilter(
                                                    FileFilterUtils
                                                            .notFileFilter(FileFilterUtils.nameFileFilter("new")),
                                                    FileFilterUtils.suffixFileFilter(".txt")),
                                            HiddenFileFilter.VISIBLE),
                            HiddenFileFilter.VISIBLE);

            for (Object file1 : files) {
                File f = (File) file1;
                loadFile(f);
            }
        } else {
            loadFile(dataFile);
        }
    }

    /**
     * This method is loading data from particular .txt file.
     *
     * @param file a file which the data is loaded from.<br>
     *             The method is loading the file row by row, omitting those started with
     *             "#" sign.<br>
     *             Every read row is then forwarded to {@link #parse(String)} method, which
     *             should be overriden in subclcass.
     */
    private void loadFile(File file) {
        LineIterator it = null;
        try {
            it = FileUtils.lineIterator(file);
            while (it.hasNext()) {
                String line = it.nextLine();
                if (line.isEmpty() || line.startsWith("#")) {
                    continue;
                }
                parse(line);
            }
        } catch (IOException e) {
            log.error("Error while loading " + getClass().getSimpleName() + ", file: " + file.getPath(), e);
        } finally {
            LineIterator.closeQuietly(it);
        }
    }

    /**
     * This method must be overriden in every subclass and is responsible for
     * parsing given <tt>dataEntry</tt> String which represents one row from
     * data file.
     *
     * @param dataEntry A String containing data about a data entry, that is to
     *                  be parsed by this method.
     */
    protected abstract void parse(String dataEntry);

    /**
     * Saves data to the file. Used only by {@link SpawnData}.
     *
     * @return true if the data was successfully saved, false - if some error
     * occurred.
     */
    public boolean saveData() {
        String desc = PATH + getSaveFile();

        log.info("Saving " + desc);

        FileWriter fr = null;
        try {
            fr = new FileWriter(desc);

            saveEntries(fr);

            fr.flush();

            return true;
        } catch (Exception e) {
            log.error("Error while saving " + desc, e);
            return false;
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (Exception e) {
                    log.error("Error while closing save data file", e);
                }
            }
        }
    }

    /**
     * Name of the file which is used to store data in.<br>
     * This method must be overriden in sublass if we want to be able to store
     * its data. It's used only in {@link SpawnData} and should not be used
     * anywhere else.
     *
     * @return name of the file
     */
    protected abstract String getSaveFile();

    /**
     * This method must be overriden in subclass which we want to be able to
     * save data. It's responsibility is basicly to put data into given
     * FileWriter instance.
     *
     * @param fileWriter
     * @throws Exception
     */
    protected void saveEntries(FileWriter fileWriter) throws Exception {
        // TODO Auto-generated method stub
    }
}