pcgen.util.TestHelper.java Source code

Java tutorial

Introduction

Here is the source code for pcgen.util.TestHelper.java

Source

/**
 * Copyright 2005 (c) Andrew Wilson <nuance@sourceforge.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
 *
 * Current Version: $Revision$
 */

package pcgen.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

import pcgen.base.lang.UnreachableError;
import pcgen.cdom.base.CDOMObject;
import pcgen.cdom.enumeration.ListKey;
import pcgen.cdom.enumeration.ObjectKey;
import pcgen.cdom.enumeration.SkillArmorCheck;
import pcgen.cdom.enumeration.StringKey;
import pcgen.cdom.enumeration.Type;
import pcgen.cdom.reference.CDOMDirectSingleRef;
import pcgen.core.Ability;
import pcgen.core.AbilityCategory;
import pcgen.core.Campaign;
import pcgen.core.ChronicleEntry;
import pcgen.core.Domain;
import pcgen.core.Equipment;
import pcgen.core.GameMode;
import pcgen.core.Globals;
import pcgen.core.Kit;
import pcgen.core.PCClass;
import pcgen.core.PCStat;
import pcgen.core.PCTemplate;
import pcgen.core.PlayerCharacter;
import pcgen.core.Race;
import pcgen.core.SettingsHandler;
import pcgen.core.SizeAdjustment;
import pcgen.core.Skill;
import pcgen.core.SystemCollections;
import pcgen.core.WeaponProf;
import pcgen.core.bonus.Bonus;
import pcgen.core.bonus.BonusObj;
import pcgen.core.spell.Spell;
import pcgen.persistence.CampaignFileLoader;
import pcgen.persistence.GameModeFileLoader;
import pcgen.persistence.PersistenceLayerException;
import pcgen.persistence.lst.AbilityLoader;
import pcgen.persistence.lst.CampaignSourceEntry;
import pcgen.persistence.lst.GenericLoader;
import pcgen.persistence.lst.LstObjectFileLoader;
import pcgen.persistence.lst.PCClassLoader;
import pcgen.rules.context.LoadContext;
import pcgen.system.ConfigurationSettings;
import pcgen.system.Main;
import pcgen.system.PCGenTask;
import pcgen.system.PropertyContextFactory;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import plugin.lsttokens.testsupport.BuildUtilities;

/**
 * Helps Junit tests
 */
@SuppressWarnings("nls")
public class TestHelper {
    private static boolean loaded = false;
    private static LstObjectFileLoader<Equipment> eqLoader = new GenericLoader<>(Equipment.class);
    private static LstObjectFileLoader<Ability> abLoader = new AbilityLoader();
    private static CampaignSourceEntry source = null;

    /**
     * Make some size adjustments
     */
    public static void makeSizeAdjustments() {
        final String sizes = "Fine|Diminutive|Tiny|Small|Medium|Large|Huge|Gargantuan|Colossal";
        final StringTokenizer aTok = new StringTokenizer(sizes, "|");
        GameMode gamemode = SystemCollections.getGameModeNamed("3.5");
        if (gamemode == null) {
            gamemode = new GameMode("3.5");
            SystemCollections.addToGameModeList(gamemode);
            GameModeFileLoader.addDefaultTabInfo(gamemode);
        }
        SettingsHandler.setGame("3.5");
        int count = 0;
        while (aTok.hasMoreTokens()) {
            SizeAdjustment sa = BuildUtilities.createSize(aTok.nextToken(), count++);
            Globals.getContext().getReferenceContext().importObject(sa);
        }
        Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(SizeAdjustment.class, "M")
                .put(ObjectKey.IS_DEFAULT_SIZE, true);
    }

    /**
     * Make some equipment
     * @param input Equipment source line to be parsed
     * @return true if OK
     */
    public static boolean makeEquipment(final String input) {
        loadPlugins();
        try {
            final CampaignSourceEntry source = createSource(TestHelper.class);
            eqLoader.parseLine(Globals.getContext(), null, input, source);
            return true;
        } catch (Exception e) {
            // TODO Deal with Exception?
        }
        return false;
    }

    /**
     * Create a new CampaignSourceEntry for the class.
     * @param cls The class the try is for.
     * @return The CampaignSourceEntry.
     */
    public static CampaignSourceEntry createSource(Class cls) {
        final CampaignSourceEntry source;
        try {
            source = new CampaignSourceEntry(new Campaign(), new URI("file:/" + cls.getName() + ".java"));
        } catch (URISyntaxException e) {
            throw new UnreachableError(e);
        }
        return source;
    }

    /**
     * Load the plugins
     */
    public static void loadPlugins() {
        if (!loaded) {
            pcgen.system.Main.createLoadPluginTask().execute();
            loaded = true;
        }
    }

    /**
     * Get the field related to a name
     * @param aClass The class to search for the field
     * @param fieldName the field to search for
     * @return the field related to a name in the class
     */
    public static Object findField(final Class<?> aClass, final String fieldName) {
        try {
            Class<?> clazz = aClass;
            while (true) {
                for (final Field f : Arrays.asList(clazz.getDeclaredFields())) {
                    if (f.getName().equals(fieldName)) {
                        f.setAccessible(true);
                        return f;
                    }
                }
                if (!"Object".equals(clazz.getName())) {
                    clazz = clazz.getSuperclass();
                } else {
                    break;
                }
            }

        } catch (SecurityException e) {
            System.out.println(e);
        }
        return null;
    }

    /**
     * Set the important info about a Skill
     * @param name The skill name
     * @param type The type info ("." separated)
     * @param stat The key stat
     * @param untrained Can this be used untrained
     * @param armorCheck should an armor check penalty be applied
     */
    public static Skill makeSkill(final String name, final String type, final PCStat stat, final boolean untrained,
            final SkillArmorCheck armorCheck) {
        final Skill aSkill = new Skill();
        aSkill.setName(name);
        aSkill.put(StringKey.KEY_NAME, ("KEY_" + name));
        addType(aSkill, type);
        CDOMDirectSingleRef<PCStat> statRef = CDOMDirectSingleRef.getRef(stat);
        aSkill.put(ObjectKey.KEY_STAT, statRef);
        aSkill.put(ObjectKey.USE_UNTRAINED, untrained);
        aSkill.put(ObjectKey.ARMOR_CHECK, armorCheck);
        Globals.getContext().getReferenceContext().importObject(aSkill);
        return aSkill;
    }

    /**
     * Set the important info about a Skill
     * @param name The skill name
     * @param cat the category of this Ability
     * @param type The type info ("." separated)
     * @return The ability (which has also been added to global storage
     */
    public static Ability makeAbility(final String name, final String cat, final String type) {
        AbilityCategory useCat = Globals.getContext().getReferenceContext()
                .constructNowIfNecessary(AbilityCategory.class, cat);
        final Ability anAbility = new Ability();
        anAbility.setName(name);
        anAbility.put(StringKey.KEY_NAME, ("KEY_" + name));
        anAbility.setCDOMCategory(useCat);
        addType(anAbility, type);
        Globals.getContext().getReferenceContext().importObject(anAbility);
        return anAbility;
    }

    /**
     * Set the important info about a Skill
     * @param name The skill name
     * @param cat the category of this Ability
     * @param type The type info ("." separated)
     * @return The ability (which has also been added to global storage
     */
    public static Ability makeAbility(final String name, final AbilityCategory cat, final String type) {
        final Ability anAbility = new Ability();
        anAbility.setName(name);
        anAbility.put(StringKey.KEY_NAME, ("KEY_" + name));
        anAbility.setCDOMCategory(cat);
        addType(anAbility, type);
        Globals.getContext().getReferenceContext().importObject(anAbility);
        return anAbility;
    }

    /**
     * Make an ability
      *
     * @param input the Ability source string to parse and create the ability from
     * @return true if OK
     */
    public static boolean makeAbilityFromString(final String input) {
        loadPlugins();

        try {
            if (null == source) {
                try {
                    source = new CampaignSourceEntry(new Campaign(),
                            new URI("file:/" + TestHelper.class.getName() + ".java"));
                } catch (URISyntaxException e) {
                    throw new UnreachableError(e);
                }
            }

            abLoader.parseLine(Globals.getContext(), null, input, source);
            return true;
        } catch (Exception e) {
            Logging.errorPrint(e.getLocalizedMessage());
        }
        return false;
    }

    /**
     * Set the important info about a WeaponProf
     * @param name The weaponprof name
     * @param type The type info ("." separated)
     * @return The weapon prof (which has also been added to global storage
     */
    public static WeaponProf makeWeaponProf(final String name, final String type) {
        final WeaponProf aWpnProf = new WeaponProf();
        aWpnProf.setName(name);
        aWpnProf.put(StringKey.KEY_NAME, ("KEY_" + name));
        addType(aWpnProf, type);
        Globals.getContext().getReferenceContext().importObject(aWpnProf);
        return aWpnProf;
    }

    /**
     * Set the important info about a Race
     * @param name The race name
     * @return The race (which has also been added to global storage)
     */
    public static Race makeRace(final String name) {
        final Race aRace = new Race();
        aRace.setName(name);
        aRace.put(StringKey.KEY_NAME, ("KEY_" + name));

        LoadContext context = Globals.getContext();
        final BonusObj bon = Bonus.newBonus(context, "FEAT|POOL|1");
        aRace.addToListFor(ListKey.BONUS, bon);

        context.getReferenceContext().importObject(aRace);
        return aRace;
    }

    /**
     * Set the important info about a Class
     * @param name The race name
     * @return The race (which has also been added to global storage)
     */
    public static PCClass makeClass(final String name) {
        final PCClass aClass = new PCClass();
        aClass.setName(name);
        aClass.put(StringKey.KEY_NAME, ("KEY_" + name));

        Globals.getContext().getReferenceContext().importObject(aClass);
        return aClass;
    }

    /**
     * Set the important info about a Domain
     * @param name The domain name
     * @return The domain (which has also been added to global storage)
     */
    public static Domain makeDomain(final String name) {
        final Domain domain = new Domain();
        domain.setName(name);
        domain.put(StringKey.KEY_NAME, (name));

        Globals.getContext().getReferenceContext().importObject(domain);
        return domain;
    }

    /**
     * Set the important info about a Spell
     * @param name The spell name
     * @return The spell (which has also been added to global storage)
     */
    public static Spell makeSpell(final String name) {
        final Spell aSpell = new Spell();
        aSpell.setName(name);
        aSpell.put(StringKey.KEY_NAME, ("KEY_" + name));

        Globals.getContext().getReferenceContext().importObject(aSpell);
        return aSpell;
    }

    /**
     * Set the important info about a Kit. Note the key of the kit created will 
     * be the provided name with KEY_ added at the front. e.g. KEY_name
     * @param name The kit name
     * @return The kit (which has also been added to global storage)
     */
    public static Kit makeKit(final String name) {
        final Kit aKit = new Kit();
        aKit.setName(name);
        aKit.put(StringKey.KEY_NAME, ("KEY_" + name));

        Globals.getContext().getReferenceContext().importObject(aKit);
        return aKit;
    }

    /**
     * Set the important info about a Template
     * @param name The template name
     * @return The template (which has also been added to global storage)
     */
    public static PCTemplate makeTemplate(final String name) {
        final PCTemplate aTemplate = new PCTemplate();
        aTemplate.setName(name);
        aTemplate.put(StringKey.KEY_NAME, ("KEY_" + name));

        Globals.getContext().getReferenceContext().importObject(aTemplate);
        return aTemplate;
    }

    /**
      * Get the Ability Category of the Ability object passed in.  If it does
      * not exist in the game mode, a new object wil be created and added to
      * the game mode
      *
     * @param ability an ability in the AbilityCategory we want to retrieve
     * @return the AbilityCategory
     */
    public static AbilityCategory getAbilityCategory(final Ability ability) {
        return (AbilityCategory) ability.getCDOMCategory();
    }

    public static void addType(CDOMObject cdo, String string) {
        List<String> stringList = Arrays.asList(string.split("\\."));
        for (String s : stringList) {
            cdo.addToListFor(ListKey.TYPE, Type.getConstant(s));
        }
    }

    /**
     * Checks to see if this PC has the weapon proficiency key aKey
     * 
     * @param aKey
     * @return boolean
     */
    public static boolean hasWeaponProfKeyed(PlayerCharacter pc, final String aKey) {
        WeaponProf wp = Globals.getContext().getReferenceContext()
                .silentlyGetConstructedCDOMObject(WeaponProf.class, aKey);
        return wp != null && pc.hasWeaponProf(wp);
    }

    /**
     * Locate the data folder which contains the primary set of LST data. This 
     * defaults to the data folder under the current directory, but can be 
     * customised in the config.ini folder. 
     * @return The path of the data folder.
     */
    public static String findDataFolder() {
        // Set the pcc location to "data"
        String pccLoc = "data";
        try {
            // Read in options.ini and override the pcc location if it exists
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(new FileInputStream("config.ini"), "UTF-8"));
            while (br.ready()) {
                String line = br.readLine();
                if (line != null && line.startsWith("pccFilesPath=")) {
                    pccLoc = line.substring(13);
                    break;
                }
            }
            br.close();
        } catch (IOException e) {
            // Ignore, see method comment
        }
        return pccLoc;
    }

    /**
     * Write a settings/config file for use by unit tests.
     * @param configFileName The name of the new config file.
     * @param configFolder The folder in which other settings files will be saved.
     * @param pccLoc The location of the data folder.
     * @return The file that was created.
     * @throws IOException If the file cannot be written.
     */
    public static File createDummySettingsFile(String configFileName, String configFolder, String pccLoc)
            throws IOException {
        File configFile = new File(configFileName);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(configFile), "UTF-8"));
        bw.write("settingsPath=" + configFolder + "\r\n");
        if (pccLoc != null) {
            System.out.println("Using PCC Location of '" + pccLoc + "'.");
            bw.write("pccFilesPath=" + pccLoc + "\r\n");
        }
        bw.write("customPath=testsuite\\\\customdata\r\n");
        bw.close();

        return configFile;
    }

    public static void loadGameModes(String testConfigFile) {
        String configFolder = "testsuite";
        String pccLoc = TestHelper.findDataFolder();
        System.out.println("Got data folder of " + pccLoc);
        try {
            TestHelper.createDummySettingsFile(testConfigFile, configFolder, pccLoc);
        } catch (IOException e) {
            Logging.errorPrint("DataTest.loadGameModes failed", e);
        }

        PropertyContextFactory configFactory = new PropertyContextFactory(SystemUtils.USER_DIR);
        configFactory.registerAndLoadPropertyContext(ConfigurationSettings.getInstance(testConfigFile));
        Main.loadProperties(false);
        PCGenTask loadPluginTask = Main.createLoadPluginTask();
        loadPluginTask.execute();
        GameModeFileLoader gameModeFileLoader = new GameModeFileLoader();
        gameModeFileLoader.execute();
        CampaignFileLoader campaignFileLoader = new CampaignFileLoader();
        campaignFileLoader.execute();
    }

    public static ChronicleEntry buildChronicleEntry(boolean visible, String campaign, String date, String gm,
            String party, String adventure, int xp, String chronicle) {
        ChronicleEntry chronEntry = new ChronicleEntry();
        chronEntry.setOutputEntry(visible);
        chronEntry.setCampaign(campaign);
        chronEntry.setDate(date);
        chronEntry.setGmField(gm);
        chronEntry.setParty(party);
        chronEntry.setAdventure(adventure);
        chronEntry.setXpField(xp);
        chronEntry.setChronicle(chronicle);
        return chronEntry;
    }

    public static PCClass parsePCClassText(String classPCCText, CampaignSourceEntry source)
            throws PersistenceLayerException {
        PCClassLoader pcClassLoader = new PCClassLoader();
        PCClass reconstClass = null;
        StringTokenizer tok = new StringTokenizer(classPCCText, "\n");
        while (tok.hasMoreTokens()) {
            String line = tok.nextToken();
            if (!StringUtils.isBlank(line)) {
                System.out.println("Processing line:'" + line + "'.");
                reconstClass = pcClassLoader.parseLine(Globals.getContext(), reconstClass, line, source);
            }
        }
        return reconstClass;
    }
}