/* * RPGeneration - A role playing utility generate interesting things * Copyright (C) 2002 Devon Jones * * 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 * * VariableHashMap.java * * Created on November 1, 2002, 1:15 PM */ package pcgen.core.doomsdaybook; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * {@code VariableHashMap} is a collection of variables (key/value * pairs) and DataElements optimised for quick lookup and updating. Note * there are three structures here, the principle map of variables, a * secondary map of DataElement objects and a list of Operation objects. * * * @author devon */ public class VariableHashMap extends HashMap<String, String> { private List<Operation> initialize = new ArrayList<>(); private Map<String, DataElement> dataElements; /** Creates a new instance of VariableHashMap */ public VariableHashMap() { this.dataElements = new HashMap<>(); } /** * Create a new instance of VariableHashMap using a pre generated * map of DataElement objects. NB: The passed in map will be * retained by the new VariableHashMap. * @param dataElements */ public VariableHashMap(HashMap<String, DataElement> dataElements) { this.dataElements = dataElements; } /** * Retrieve the data element for the given key. If no entry is * present for the key an exception will be thrown. * * @param key The key of the element to be retrieved. * @return The data element. * @throws Exception When no entry exists for the supplied key. */ public DataElement getDataElement(String key) throws Exception { DataElement de = dataElements.get(key); if (de == null) { throw new Exception("Data Set " + key + " Does Not Exist"); } return de; } /** * Retrieve the variable value for the given key. If no entry is * present for the key an exception will be thrown. * * @param key The key of the variable to be retrieved. * @return The value fo the variable. * @throws variableException When no entry exists for the supplied key. */ public String getVal(String key) throws variableException { String value = get(key); if (value == null) { throw new variableException("Variable " + key + " does not exist, cannot get value"); } return value; } /** * Set the value for an existing variable. If no entry is * present for the key, an exception will be thrown. * * @param key The key of the variable to be set. * @param value The new value for the variable * @throws variableException When no entry exists for the supplied key. */ public void setVar(String key, String value) throws variableException { if (get(key) == null) { throw new variableException("Variable " + key + " does not exist, cannot set value"); } put(key, value); } /** * Add a new DataElement to the map of DataElement objects. * The dataElement's Id will be used as the key for the map. * * @param dataElement The DataElement object to be added. */ public void addDataElement(DataElement dataElement) { String key = dataElement.getId(); dataElement.trimToSize(); dataElements.put(key, dataElement); } /** * Add an Operation to the initialize list * * @param op The Operation to be added. */ public void addInitialOperations(Operation op) { initialize.add(op); } /** * Add an amount to an existing variable. If no entry is * present for the key, an exception will be thrown. * * @param key The key of the variable to be updated. * @param add The amount to add to the variable. * @return The new value of the variable. * @throws variableException When no entry exists for the supplied key. */ public String addVar(String key, int add) throws variableException { String value = get(key); if (value == null) { throw new variableException("Variable " + key + " does not exist, cannot add to value"); } int val; if ("".equals(value)) { val = 0; } else { val = Integer.parseInt(get(key)); } return put(key, Integer.toString(val + add)); } /** * Divide the value of an existing variable by an amount. If no entry is * present for the key, an exception will be thrown. NB: Integer divison * is used. * * @param key The key of the variable to be updated. * @param divide The amount to divide the variable's value by. * @return The new value of the variable. * @throws variableException When no entry exists for the supplied key. */ public String divideVar(String key, int divide) throws variableException { String value = get(key); if (value == null) { throw new variableException("Variable " + key + " does not exist, cannot divide by value"); } int val; if ("".equals(value)) { val = 0; } else { val = Integer.parseInt(get(key)); } return put(key, Integer.toString(val / divide)); } /** * Perform the supplied Operations in sequence. * * @param ops The Operations to be performed. * @throws variableException When no entry exists for an Operation's key. */ public void doOperation(List<Operation> ops) throws variableException { for (Operation op : ops) { doOperation(op); } } /** * Perform the Operation. The Operation defines, the action, the variable * to be affected and the value to be used in the operation. If no entry is * present for the key expected by the Operation, an exception will be * thrown. * * @param op The Operation to be performed. * @throws variableException When no entry exists for the Operation's key. */ public void doOperation(Operation op) throws variableException { String type = op.getType(); String key = op.getKey(); String value = op.getValue(); if (type.equals("Set")) { value = parse(value); setVar(key, value); } else if (type.equals("Add")) { int val = Integer.parseInt(parse(value)); addVar(key, val); } else if (type.equals("Subtract")) { int val = Integer.parseInt(parse(value)); subtractVar(key, val); } else if (type.equals("Multiply")) { int val = Integer.parseInt(parse(value)); multiplyVar(key, val); } else if (type.equals("Divide")) { int val = Integer.parseInt(parse(value)); divideVar(key, val); } } /** * Perform the initialization Operations in sequence. * * @throws variableException When no entry exists for an Operation's key. */ public void initialize() throws variableException { doOperation(initialize); } /** * Multiply the value of an existing variable by an amount. If no entry is * present for the key, an exception will be thrown. NB: Integer divison * is used. * * @param key The key of the variable to be updated. * @param multiply The amount to multiply the variable's value by. * @return The new value of the variable. * @throws variableException When no entry exists for the supplied key. */ public String multiplyVar(String key, int multiply) throws variableException { String value = get(key); if (value == null) { throw new variableException("Variable " + key + " does not exist, cannot multiply by value"); } int val; if ("".equals(value)) { val = 0; } else { val = Integer.parseInt(get(key)); } return put(key, Integer.toString(val * multiply)); } /** * Parse a value substituting the first variable referred to as * ${varname} with the variable's value. * * @param val The value to be parsed * @return The parsed value. */ public String parse(String val) { String retString = val; if (val.matches("\\$\\{.*?\\}.*")) { String var = val.substring(val.indexOf("${") + 2, val.indexOf("}")); String value = get(var); if (value == null) { value = ""; } retString = val.replaceFirst("\\$\\{.*?\\}", value); } return retString; } /** * Subtract an amount to an existing variable. If no entry is * present for the key, an exception will be thrown. * * @param key The key of the variable to be updated. * @param subtract The amount to subtract from the variable. * @return The new value of the variable. * @throws variableException When no entry exists for the supplied key. */ public String subtractVar(String key, int subtract) throws variableException { String value = get(key); if (value == null) { throw new variableException("Variable " + key + " does not exist, cannot subtract from value"); } int val; if ("".equals(value)) { val = 0; } else { val = Integer.parseInt(get(key)); } return put(key, Integer.toString(val - subtract)); } }