/* * LevelLoader.java * Copyright 2002 (C) James Dempsey * * 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 August 16, 2002, 10:00 PM * * Current Ver: $Revision$ * */ package pcgen.persistence.lst; import java.net.URI; import java.util.Map; import java.util.StringTokenizer; import pcgen.core.GameMode; import pcgen.core.LevelInfo; import pcgen.core.XPTable; import pcgen.persistence.SystemLoader; import pcgen.util.Logging; /** * {@code LevelLoader} loads up the level system file * by processing each line passed to it. * * @author James Dempsey <jdempsey@users.sourceforge.net> **/ public final class LevelLoader { /** Creates a new instance of LevelLoader */ private LevelLoader() { // Empty Constructor } /** * Parse the line from the level.lst file, populating the * levelInfo object with the info found. * * @param gameMode the game mode * @param inputLine The line to be parsed * @param lineNum The number of the line being parsed. */ public static String parseLine(GameMode gameMode, String inputLine, int lineNum, URI source, String xpTable) { if (gameMode == null) { return ""; } // Deal with the start of a new XPTable definition if (inputLine.startsWith("XPTABLE:")) { String value = inputLine.substring(8); if (value.indexOf("\t") >= 0) { value = value.substring(0, value.indexOf("\t")); } value = value.trim(); if (value.equals("")) { Logging.errorPrint("Error parsing level line \"" + inputLine + "\": empty XPTABLE value."); } else { value = value.intern(); gameMode.addXPTableName(value); return value; } } // Provide a default fallback table name for backwards compatibility if (xpTable.equals("")) { xpTable = "Default"; gameMode.addXPTableName(xpTable); } final LevelInfo levelInfo = new LevelInfo(); final StringTokenizer colToken = new StringTokenizer(inputLine, SystemLoader.TAB_DELIM); Map<String, LstToken> tokenMap = TokenStore.inst().getTokenMap(LevelLstToken.class); while (colToken.hasMoreTokens()) { final String colString = colToken.nextToken().trim(); final int idxColon = colString.indexOf(':'); String key = ""; try { key = colString.substring(0, idxColon); } catch (StringIndexOutOfBoundsException e) { // TODO Handle Exception } LevelLstToken token = (LevelLstToken) tokenMap.get(key); if (token != null) { final String value = colString.substring(idxColon + 1).intern(); LstUtils.deprecationCheck(token, levelInfo.getLevelString(), source, value); if (!token.parse(levelInfo, value)) { Logging.errorPrint("LevelLoader got invalid " + key + " value of '" + value + "' in '" + inputLine + "' at line " + lineNum + " of " + source + ". Token ignored."); } } else { Logging.errorPrint("LevelLoader got unexpected token of '" + colString + "' at line " + lineNum + ". Token ignored."); } } if (validateLevelInfo(gameMode, xpTable, levelInfo, inputLine, lineNum, source)) { gameMode.addLevelInfo(xpTable, levelInfo); } return xpTable; } private static boolean validateLevelInfo(GameMode gameMode, String xpTable, LevelInfo levelInfo, String inputLine, int lineNum, URI source) { String level = levelInfo.getLevelString(); if (level == null) { Logging.errorPrint("LevelLoader got empty level value in '" + inputLine + "' at line " + lineNum + " of " + source + ". Line ignored."); return false; } XPTable existingTable = gameMode.getLevelInfo(xpTable); if (existingTable == null) { // No data on this table held yet, so it has to be right return true; } // Not a number so just check for a duplicate if (existingTable.getLevelInfo(level) != null) { Logging.errorPrint("LevelLoader got duplicate level value of '" + level + "' in '" + inputLine + "' at line " + lineNum + " of " + source + ". Line ignored."); return false; } if (!isNumeric(level)) { // Not a number so must be good now return true; } if (!existingTable.validateSequence(level)) { Logging.errorPrint("LevelLoader got out of sequence level value of '" + level + "' in '" + inputLine + "' at line " + lineNum + " of " + source + ". Line ignored."); } return true; } private static boolean isNumeric(String level) { try { Integer.parseInt(level); return true; } catch (NumberFormatException e) { return false; } } }