net.rptools.maptool.client.functions.LookupTableFunction.java Source code

Java tutorial

Introduction

Here is the source code for net.rptools.maptool.client.functions.LookupTableFunction.java

Source

/*
 * This software copyright by various authors including the RPTools.net
 * development team, and licensed under the LGPL Version 3 or, at your option,
 * any later version.
 *
 * Portions of this software were originally covered under the Apache Software
 * License, Version 1.1 or Version 2.0.
 *
 * See the file LICENSE elsewhere in this distribution for license details.
 */

package net.rptools.maptool.client.functions;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import net.rptools.lib.MD5Key;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.language.I18N;
import net.rptools.maptool.model.LookupTable;
import net.rptools.maptool.model.LookupTable.LookupEntry;
import net.rptools.parser.Parser;
import net.rptools.parser.ParserException;
import net.rptools.parser.function.AbstractFunction;
import net.sf.json.JSONArray;

public class LookupTableFunction extends AbstractFunction {

    public LookupTableFunction() {
        super(0, 5, "tbl", "table", "tblImage", "tableImage", "getTableNames", "getTableRoll", "setTableRoll",
                "clearTable", "addTableEntry", "deleteTableEntry", "createTable", "deleteTable", "getTableVisible",
                "setTableVisible", "getTableAccess", "setTableAccess", "getTableImage", "setTableImage",
                "copyTable", "setTableEntry");
    }

    /** The singleton instance. */
    private final static LookupTableFunction instance = new LookupTableFunction();

    /**
     * Gets the instance of TableLookup.
     * @return the TableLookup.
     */
    public static LookupTableFunction getInstance() {
        return instance;
    }

    @Override
    public Object childEvaluate(Parser parser, String function, List<Object> params) throws ParserException {

        if ("getTableNames".equalsIgnoreCase(function)) {

            checkNumberOfParameters("getTableNames", params, 0, 1);
            String delim = ",";
            if (params.size() > 0) {
                delim = params.get(0).toString();
            }
            if ("json".equalsIgnoreCase(delim))
                return JSONArray.fromObject(getTableList(MapTool.getPlayer().isGM()));

            return StringUtils.join(getTableList(MapTool.getPlayer().isGM()), delim);

        } else if ("getTableVisible".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("getTableVisible", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            return lookupTable.getVisible() ? "1" : "0";

        } else if ("setTableVisible".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("setTableVisible", params, 2, 2);
            String name = params.get(0).toString();
            String visible = params.get(1).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.setVisible(AbstractTokenAccessorFunction.getBooleanValue(visible));
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return lookupTable.getVisible() ? "1" : "0";

        } else if ("getTableAccess".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("getTableAccess", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            return lookupTable.getAllowLookup() ? "1" : "0";

        } else if ("setTableAccess".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("setTableAccess", params, 2, 2);
            String name = params.get(0).toString();
            String access = params.get(1).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.setAllowLookup(AbstractTokenAccessorFunction.getBooleanValue(access));
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return lookupTable.getAllowLookup() ? "1" : "0";

        } else if ("getTableRoll".equalsIgnoreCase(function)) {

            checkNumberOfParameters("getTableRoll", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            return lookupTable.getRoll();

        } else if ("setTableRoll".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("setTableRoll", params, 2, 2);
            String name = params.get(0).toString();
            String roll = params.get(1).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.setRoll(roll);
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return lookupTable.getRoll();

        } else if ("clearTable".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("clearTable", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.clearEntries();
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return "";

        } else if ("addTableEntry".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("addTableEntry", params, 4, 5);
            String name = params.get(0).toString();
            String min = params.get(1).toString();
            String max = params.get(2).toString();
            String value = params.get(3).toString();
            MD5Key asset = null;
            if (params.size() > 4) {
                asset = new MD5Key(params.get(4).toString());
            }
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.addEntry(Integer.valueOf(min), Integer.valueOf(max), value, asset);
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return "";

        } else if ("deleteTableEntry".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("deleteTableEntry", params, 2, 2);
            String name = params.get(0).toString();
            String roll = params.get(1).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            LookupEntry entry = lookupTable.getLookup(roll);
            if (entry != null) {
                List<LookupEntry> oldlist = new ArrayList<LookupEntry>(lookupTable.getEntryList());
                lookupTable.clearEntries();
                for (LookupEntry e : oldlist)
                    if (e != entry)
                        lookupTable.addEntry(e.getMin(), e.getMax(), e.getValue(), e.getImageId());
            }
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return "";

        } else if ("createTable".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("createTable", params, 3, 4);
            String name = params.get(0).toString();
            String visible = params.get(1).toString();
            String lookups = params.get(2).toString();
            MD5Key asset = null;
            if (params.size() > 3) {
                asset = new MD5Key(params.get(3).toString());
            }
            LookupTable lookupTable = new LookupTable();
            lookupTable.setName(name);
            lookupTable.setVisible(AbstractTokenAccessorFunction.getBooleanValue(visible));
            lookupTable.setAllowLookup(AbstractTokenAccessorFunction.getBooleanValue(lookups));
            if (asset != null)
                lookupTable.setTableImage(asset);
            MapTool.getCampaign().getLookupTableMap().put(name, lookupTable);
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return "";

        } else if ("deleteTable".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("deleteTable", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            if (lookupTable != null) {
                MapTool.getCampaign().getLookupTableMap().remove(name);
                MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            }
            return "";

        } else if ("getTableImage".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("getTableImage", params, 1, 1);
            String name = params.get(0).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            return lookupTable.getTableImage();

        } else if ("setTableImage".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("setTableImage", params, 2, 2);
            String name = params.get(0).toString();
            MD5Key asset = new MD5Key(params.get(1).toString());
            LookupTable lookupTable = getMaptoolTable(name, function);
            lookupTable.setTableImage(asset);
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return "";

        } else if ("copyTable".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("copyTable", params, 2, 2);
            String oldName = params.get(0).toString();
            String newName = params.get(1).toString();
            LookupTable oldTable = getMaptoolTable(oldName, function);
            if (oldTable != null) {
                LookupTable newTable = new LookupTable(oldTable);
                newTable.setName(newName);
                MapTool.getCampaign().getLookupTableMap().put(newName, newTable);
                MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            }
            return "";

        } else if ("setTableEntry".equalsIgnoreCase(function)) {

            checkTrusted(function);
            checkNumberOfParameters("setTableEntry", params, 3, 3);
            String name = params.get(0).toString();
            String roll = params.get(1).toString();
            String result = params.get(2).toString();
            LookupTable lookupTable = getMaptoolTable(name, function);
            LookupEntry entry = lookupTable.getLookup(roll);
            if (entry == null)
                return 0; // no entry was found
            int rollInt = Integer.valueOf(roll);
            if (rollInt < entry.getMin() || rollInt > entry.getMax())
                return 0; // entry was found but doesn't match
            List<LookupEntry> oldlist = new ArrayList<LookupEntry>(lookupTable.getEntryList());
            lookupTable.clearEntries();
            for (LookupEntry e : oldlist)
                if (e != entry)
                    lookupTable.addEntry(e.getMin(), e.getMax(), e.getValue(), e.getImageId());
                else
                    lookupTable.addEntry(e.getMin(), e.getMax(), result, e.getImageId());
            MapTool.serverCommand().updateCampaign(MapTool.getCampaign().getCampaignProperties());
            return 1;

        } else {
            checkNumberOfParameters(function, params, 1, 3);
            String name = params.get(0).toString();

            String roll = null;
            if (params.size() > 1) {
                roll = params.get(1).toString().length() == 0 ? null : params.get(1).toString();
            }

            LookupTable lookupTable = MapTool.getCampaign().getLookupTableMap().get(name);
            if (!MapTool.getPlayer().isGM() && !lookupTable.getAllowLookup()) {
                if (lookupTable.getVisible()) {
                    throw new ParserException(function + "(): " + I18N.getText("msg.error.tableUnknown") + name);
                } else {
                    throw new ParserException(
                            function + "(): " + I18N.getText("msg.error.tableAccessProhibited") + ": " + name);
                }
            }
            if (lookupTable == null) {
                throw new ParserException(
                        I18N.getText("macro.function.LookupTableFunctions.unknownTable", function, name));
            }

            LookupEntry result = lookupTable.getLookup(roll);

            if (function.equals("table") || function.equals("tbl")) {
                String val = result.getValue();
                try {
                    BigDecimal bival = new BigDecimal(val);
                    return bival;
                } catch (NumberFormatException nfe) {
                    return val;
                }
            } else { // We want the image URI

                if (result.getImageId() == null) {
                    throw new ParserException(
                            I18N.getText("macro.function.LookupTableFunctions.noImage", function, name));
                }

                BigDecimal size = null;
                if (params.size() > 2) {
                    if (params.get(2) instanceof BigDecimal) {
                        size = (BigDecimal) params.get(2);
                    } else {
                        throw new ParserException(
                                I18N.getText("macro.function.LookupTableFunctions.invalidSize", function));
                    }
                }

                StringBuilder assetId = new StringBuilder("asset://");
                assetId.append(result.getImageId().toString());
                if (size != null) {
                    int i = Math.max(size.intValue(), 1); // Constrain to a minimum of 1
                    assetId.append("-");
                    assetId.append(i);
                }
                return assetId.toString();
            }
        }
    }

    /**
     * Checks that the number of objects in the list <code>parameters</code>
     * is within given bounds (inclusive). Throws a <code>ParserException</code>
     * if the check fails.
     *
     * @param   functionName   this is used in the exception message
     * @param   parameters      a list of parameters
     * @param   min            the minimum amount of parameters (inclusive)
     * @param   max            the maximum amount of parameters (inclusive)
     * @throws   ParserException   if there were more or less parameters than allowed
     */
    private void checkNumberOfParameters(String functionName, List<Object> parameters, int min, int max)
            throws ParserException {
        int numberOfParameters = parameters.size();
        if (numberOfParameters < min) {
            throw new ParserException(
                    I18N.getText("macro.function.general.notEnoughParam", functionName, min, numberOfParameters));
        } else if (numberOfParameters > max) {
            throw new ParserException(
                    I18N.getText("macro.function.general.tooManyParam", functionName, max, numberOfParameters));
        }
    }

    /**
     * Checks whether or not the function is trusted
     * 
     * @param functionName     Name of the macro function
     * @throws ParserException Returns trust error message and function name 
     */
    private void checkTrusted(String functionName) throws ParserException {
        if (!MapTool.getParser().isMacroTrusted()) {
            throw new ParserException(I18N.getText("macro.function.general.noPerm", functionName));
        }
    }

    /***
     * If GM return all tables
     * Otherwise only return visible tables
     * 
     * @param isGm boolean Does the calling function has GM privileges
     * @return a list of table names
     */
    private List<String> getTableList(boolean isGm) {
        List<String> tables = new ArrayList<String>();
        if (isGm)
            tables.addAll(MapTool.getCampaign().getLookupTableMap().keySet());
        else
            for (LookupTable lt : MapTool.getCampaign().getLookupTableMap().values()) {
                if (lt.getVisible())
                    tables.add(lt.getName());
            }
        return tables;
    }

    /**
     * Function to return a maptool table.
     * 
     * @param tableName         String containing the name of the desired table
     * @param functionName      String containing the name of the calling function,
     *                          used by the error message.
     * @return LookupTable      The desired maptool table object
     * @throws ParserException   if there were more or less parameters than allowed
     */
    private LookupTable getMaptoolTable(String tableName, String functionName) throws ParserException {

        LookupTable lookupTable = MapTool.getCampaign().getLookupTableMap().get(tableName);
        if (!MapTool.getPlayer().isGM() && !lookupTable.getAllowLookup()) {
            if (lookupTable.getVisible()) {
                throw new ParserException(
                        functionName + "(): " + I18N.getText("msg.error.tableUnknown") + tableName);
            } else {
                throw new ParserException(
                        functionName + "(): " + I18N.getText("msg.error.tableAccessProhibited") + ": " + tableName);
            }
        }
        if (lookupTable == null) {
            throw new ParserException(
                    I18N.getText("macro.function.LookupTableFunctions.unknownTable", functionName, tableName));
        }
        return lookupTable;
    }

}