/* * MigrationLoader.java * Copyright 2013 (C) James Dempsey <jdempsey@users.equipforge.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 October 13, 2003, 11:50 AM */ package pcgen.persistence.lst; import java.net.URI; import java.util.Map; import java.util.StringTokenizer; import org.apache.commons.lang3.StringUtils; import pcgen.base.lang.UnreachableError; import pcgen.core.SystemCollections; import pcgen.core.system.MigrationRule; import pcgen.core.system.MigrationRule.ObjectType; import pcgen.core.utils.CoreUtility; import pcgen.persistence.PersistenceLayerException; import pcgen.persistence.SystemLoader; import pcgen.rules.context.LoadContext; import pcgen.util.Logging; /** * MigrationLoader is a LstFileLoader that processes the migration.lst file * * * @author James Dempsey <jdempsey@users.sourceforge.net> */ public class MigrationLoader extends LstLineFileLoader { private String invalidKeyPattern = ".*[,|\\||\\\\|:|;|%|\\*|=|\\[|\\]].*"; private String invalidSourceKeyPattern = ".*[\\||\\\\|;|%|\\*|=|\\[|\\]].*"; /* (non-Javadoc) * @see pcgen.persistence.lst.LstLineFileLoader#parseLine(pcgen.rules.context.LoadContext, java.lang.String, java.net.URI) */ @Override public void parseLine(LoadContext context, String lstLine, URI sourceURI) throws PersistenceLayerException { final StringTokenizer colToken = new StringTokenizer(lstLine, SystemLoader.TAB_DELIM); String firstToken = colToken.nextToken().trim(); final MigrationRule migrationRule = parseFirstToken(firstToken, lstLine, sourceURI); if (migrationRule == null) { return; } Map<String, LstToken> tokenMap = TokenStore.inst().getTokenMap(MigrationLstToken.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 } MigrationLstToken token = (MigrationLstToken) tokenMap.get(key); if (token != null) { final String value = colString.substring(idxColon + 1); LstUtils.deprecationCheck(token, migrationRule.getOldKey(), sourceURI, value); if (!token.parse(migrationRule, value, getGameMode())) { Logging.errorPrint("Error parsing migration rule " + migrationRule.getOldKey() + ':' + sourceURI + ':' + colString + "\""); return; } } else { Logging.errorPrint("Unknown token " + key + " in migration rule '" + lstLine + "' in " + sourceURI.toString()); return; } } // Check for mandatory tokens and interrelationship rules boolean errorFound = false; if (migrationRule.getMaxVer() == null) { Logging.errorPrint("Missing required token MAXVER in migration rule '" + lstLine + "' in " + sourceURI.toString()); errorFound = true; } if (migrationRule.getNewKey() == null) { Logging.errorPrint("Missing required token NEWKEY in migration rule '" + lstLine + "' in " + sourceURI.toString()); errorFound = true; } if (migrationRule.getMinVer() == null && migrationRule.getMinDevVer() != null) { Logging .errorPrint("MINVER is required when MINDEVVER is used. Migration rule was '" + lstLine + "' in " + sourceURI.toString()); errorFound = true; } if (migrationRule.getMaxVer() != null && migrationRule.getMaxDevVer() != null && CoreUtility.compareVersions(migrationRule.getMaxVer(), migrationRule.getMaxDevVer()) >= 0) { Logging .errorPrint("MAXVER must be before MAXDEVVER. Migration rule was '" + lstLine + "' in " + sourceURI.toString()); errorFound = true; } if (migrationRule.getMinVer() != null && migrationRule.getMinDevVer() != null && CoreUtility.compareVersions(migrationRule.getMinVer(), migrationRule.getMinDevVer()) >= 0) { Logging .errorPrint("MINVER must be before MINDEVVER. Migration rule was '" + lstLine + "' in " + sourceURI.toString()); errorFound = true; } if (errorFound) { // Abandon this rule. return; } SystemCollections.addToMigrationRulesList(migrationRule, gameMode); } /** * Parse the leading token and value to produce a starting MigrationRule object. * * @param firstToken The first token and value. * @param lstLine The full line it came form, for error reporting purposes only. * @param sourceURI The source path, for error reporting purposes only. * @return A new MigrationRule, or null if the token could nto be parsed. */ MigrationRule parseFirstToken(String firstToken, String lstLine, URI sourceURI) { final int idxColon = firstToken.indexOf(':'); if (idxColon <= 0 || idxColon == firstToken.length()-1) { // Missing colon or missing key or value Logging.errorPrint("Illegal migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } String objTypeKey = ""; try { objTypeKey = firstToken.substring(0, idxColon); } catch (StringIndexOutOfBoundsException e) { throw new UnreachableError(e); } MigrationRule.ObjectType objType; try { objType = ObjectType.valueOf(objTypeKey); } catch (IllegalArgumentException e) { Logging.errorPrint("Unknown object type for migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } String key = ""; try { key = firstToken.substring(idxColon+1); } catch (StringIndexOutOfBoundsException e) { throw new UnreachableError(e); } MigrationRule rule; if (objType.isCategorized()) { if (key.endsWith("|")) { // Extra | Logging.errorPrint("Invalid category|key of '" + firstToken + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } String[] keyParts = key.split("\\|"); if (keyParts.length < 2) { // No | so missing a category Logging.errorPrint("Missing category in '" + firstToken + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } if (keyParts.length > 2) { // Extra | Logging.errorPrint("Invalid category|key of '" + firstToken + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } if (StringUtils.isBlank(keyParts[0]) || keyParts[0].matches(invalidKeyPattern)) { Logging.errorPrint("Invalid category of '" + keyParts[0] + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } if (StringUtils.isBlank(keyParts[1]) || keyParts[1].matches(invalidKeyPattern)) { Logging.errorPrint("Invalid key of '" + keyParts[1] + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } rule = new MigrationRule(objType, keyParts[0], keyParts[1]); } else { String invalidKeyPat = objType == ObjectType.SOURCE ? invalidSourceKeyPattern : invalidKeyPattern; if (StringUtils.isBlank(key) || key.matches(invalidKeyPat)) { Logging.errorPrint("Invalid key of '" + key + "' of migration rule '" + lstLine + "' in " + sourceURI.toString()); return null; } rule = new MigrationRule(objType, key); } return rule; } }