ca.wumbo.wdl.parser.events.Event.java Source code

Java tutorial

Introduction

Here is the source code for ca.wumbo.wdl.parser.events.Event.java

Source

/*
 * WDLStats
 * Copyright (C) 2015  Chris K
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package ca.wumbo.wdl.parser.events;

import static com.google.common.base.Preconditions.*;

import java.util.Map;
import java.util.Optional;

import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.collect.BiMap;

import ca.wumbo.wdl.parser.CorruptStatFileException;
import ca.wumbo.wdl.parser.Player;
import ca.wumbo.wdl.parser.enums.EventType;

/**
 * The stat event data. It is parsed in the constructor and is immutable.
 * 
 * @author Chris
 */
public abstract class Event {

    /**
     * The activator player.
     */
    protected Player activator;

    /**
     * The player (if any) who was the target.
     */
    protected Optional<Player> target;

    /**
     * This gametic event.
     */
    protected int gametic;

    /**
     * The gametic that is normalized to start from zero.
     */
    protected int normalizedGametic;

    /**
     * The activator's X location.
     */
    protected int activatorX;

    /**
     * The activator's Y location.
     */
    protected int activatorY;

    /**
     * The activator's Z location.
     */
    protected int activatorZ;

    /**
     * The target's X location.
     */
    protected int targetX;

    /**
     * The target's Y location.
     */
    protected int targetY;

    /**
     * The target's Z location.
     */
    protected int targetZ;

    /**
     * The first varying argument.
     */
    protected int arg0;

    /**
     * The second varying argument.
     */
    protected int arg1;

    /**
     * The third varying argument.
     */
    protected int arg2;

    /**
     * Creates an event from a line of text.
     * 
     * @param tokens
     *       The tokens.
     * 
     * @param playerMap
     *       The map of players to look up a player.
     * 
     * @throws CorruptStatFileException
     *       If the line cannot properly be parsed.
     * 
     * @throws NullPointerException
     *       If the argument is null.
     */
    public Event(String[] tokens, Map<String, Player> playerMap) {
        checkNotNull(tokens);
        checkNotNull(playerMap);
        if (tokens.length != 13)
            throw new CorruptStatFileException("Invalid number of tokens for Event.");

        // Tokens[1] is the activator player name.
        if (playerMap.containsKey(tokens[1])) {
            activator = playerMap.get(tokens[1]);
            if (activator == null) {
                // Due to a bug in the logs, the target is the activator in enviro damage.
                if (isEnviroClassEvent()) {
                    throw new IllegalStateException(
                            "Player map contained a null key when looking for activator: " + tokens[1]);
                }
            }
        }

        // Tokens[2] is the target player name (may be empty).
        if (!playerMap.containsKey(tokens[2])) {
            target = Optional.empty();
        } else {
            target = Optional.of(playerMap.get(tokens[2]));
            if (!target.isPresent())
                throw new IllegalStateException(
                        "Player map contained a null key when looking for target: " + tokens[1]);
        }

        // If its an enviromental damage, set the activator as the player.
        if (activator == null && isEnviroClassEvent()) {
            activator = playerMap.get(tokens[2]);
            if (activator == null)
                throw new CorruptStatFileException(
                        "Environmental evemt did not have a target to copy from for an empty activator.");
        }

        // If the activator is still null, then we have a problem.
        if (activator == null)
            throw new CorruptStatFileException(
                    "Unable to get player for activator." + tokens[0] + " ... " + tokens[1] + " | " + tokens[2]);

        try {
            gametic = Integer.parseInt(tokens[3]);
            activatorX = Integer.parseInt(tokens[4]);
            activatorY = Integer.parseInt(tokens[5]);
            activatorZ = Integer.parseInt(tokens[6]);
            targetX = Integer.parseInt(tokens[7]);
            targetY = Integer.parseInt(tokens[8]);
            targetZ = Integer.parseInt(tokens[9]);
            arg0 = Integer.parseInt(tokens[10]);
            arg1 = Integer.parseInt(tokens[11]);
            arg2 = Integer.parseInt(tokens[12]);
        } catch (NumberFormatException e) {
            throw new CorruptStatFileException("Error parsing token value from event tokens.");
        }

        if (gametic <= 0) {
            throw new CorruptStatFileException("Corrupt data: negative gametic.");
        }
    }

    /**
     * Checks if this is an environmental damage class or not.
     * 
     * @return
     *       True if it is, false if not.
     */
    protected boolean isEnviroClassEvent() {
        EventType et = getEventType();
        switch (et) {
        case ENVIROKILL:
        case ENVIROCARRIERKILL:
        case ENVIRODAMAGE:
        case ENVIRODAMAGEUNUSED:
            return true;
        default:
            break;
        }
        return false;
    }

    /**
     * Gets the event type.
     * 
     * @return
     *       The event type.
     */
    public abstract EventType getEventType();

    /**
     * Gets the activator player.
     * 
     * @return
     *       The activator player.
     */
    public Player getActivator() {
        return activator;
    }

    /**
     * Gets the target, if any. The target may not be present in some event
     * cases (ex: environmental damage).
     * 
     * @return
     *       The target player, if any.
     */
    public Optional<Player> getTarget() {
        return target;
    }

    /**
     * Gets the gametic for this event.
     * 
     * @return
     *       The gametic.
     */
    public int getGametic() {
        return gametic;
    }

    /**
     * Gets the activator's X.
     * 
     * @return
     *       The activator's X.
     */
    public int getActivatorX() {
        return activatorX;
    }

    /**
     * Gets the activator's Y.
     * 
     * @return
     *       The activator's Y.
     */
    public int getActivatorY() {
        return activatorY;
    }

    /**
     * Gets the activator's Z.
     * 
     * @return
     *       The activator's Z.
     */
    public int getActivatorZ() {
        return activatorZ;
    }

    /**
     * Gets the target's X.
     * 
     * @return
     *       The target's X.
     */
    public int getTargetX() {
        return targetX;
    }

    /**
     * Gets the target's Y.
     * 
     * @return
     *       The target's Y.
     */
    public int getTargetY() {
        return targetY;
    }

    /**
     * Gets the target's Z.
     * 
     * @return
     *       The target's Z.
     */
    public int getTargetZ() {
        return targetZ;
    }

    /**
     * Gets the argument value.
     * 
     * @return
     *       The argument value.
     */
    public int getArg0() {
        return arg0;
    }

    /**
     * Gets the argument value.
     * 
     * @return
     *       The argument value.
     */
    public int getArg1() {
        return arg1;
    }

    /**
     * Gets the argument value.
     * 
     * @return
     *       The argument value.
     */
    public int getArg2() {
        return arg2;
    }

    /**
     * Gets the numerical value of the event type.
     * 
     * @return
     *       The numerical value of the event type.
     */
    public int getEventTypeNumber() {
        return getEventType().ordinal();
    }

    /**
     * Uses the 'base' gametic for the round start.
     * 
     * @param baseGametic
     *       The gametic that the round starts at.
     * 
     * @throws IllegalArgumentException
     *       If the gametic is negative or greater than the current gametic.
     */
    public void createNormalizedGametic(int baseGametic) {
        checkArgument(baseGametic >= 0);
        checkArgument(baseGametic <= gametic);
        normalizedGametic = gametic - baseGametic;
    }

    /**
     * Gets the normalized gametic (which starts from 0 based on the round
     * start). This must have been set with the method createNormalizedGametic
     * or else it will return 0.
     * 
     * @return
     *       The normalized gametic.
     */
    public int getNormalizedGametic() {
        return normalizedGametic;
    }

    /**
     * Gets the insertion query statement for this event.
     * 
     * @param database
     *       The database this belongs to. This should not be empty.
     * 
     * @param table
     *       The table for this event.
     * 
     * @param nameToPlayerIdMap
     *       The name to player ID map.
     * @param eventLogId 
     * 
     * @return
     *       A query statement that can be issued to the database.
     * 
     * @throws NullPointerException
     *       If any argument is null.
     * 
     * @throws IllegalArgumentException
     *       If any string or table has zero characters/elements, or the log id
     *       is negative.
     * 
     * @throws RuntimeException
     *       If neither an activator nor target ID can be found (both parts
     *       of the query for the ID's would be 'NULL').
     */
    public String getSqlInsertionQuery(String database, String table, BiMap<String, Integer> nameToPlayerIdMap,
            int eventLogId) {
        checkNotNull(database);
        checkNotNull(table);
        checkNotNull(nameToPlayerIdMap);
        checkArgument(database.length() > 0);
        checkArgument(table.length() > 0);
        checkArgument(nameToPlayerIdMap.size() > 0);
        checkArgument(eventLogId >= 0);

        String tblArgs = "fk_event_log_id, type, nfk_activator_player_id, nfk_target_player_id, "
                + "gametic, activator_x, activator_y, activator_z, "
                + "target_x, target_y, target_z, arg0, arg1, arg2";
        String valueArgs = "%d, %d, %s, %s, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d";
        String activatorIdOrNullSqlStr = activator != null && nameToPlayerIdMap.containsKey(activator.getName())
                ? Integer.toString(nameToPlayerIdMap.get(activator.getName()))
                : "NULL";
        String targetIdOrNullSqlStr = target.isPresent() && nameToPlayerIdMap.containsKey(target.get().getName())
                ? Integer.toString(nameToPlayerIdMap.get(target.get().getName()))
                : "NULL";

        // If both are null, something is critically wrong.
        if (activatorIdOrNullSqlStr.equals("NULL") && targetIdOrNullSqlStr.equals("NULL")) {
            throw new RuntimeException(
                    "Both activator and target are 'NULL', malformed event or corrupt name to ID map.");
        }

        return String.format("INSERT INTO `%s`.`%s`(%s) VALUES(" + valueArgs + ")", database, table, tblArgs,
                eventLogId, getEventTypeNumber(), activatorIdOrNullSqlStr, targetIdOrNullSqlStr, getGametic(),
                getActivatorX(), getActivatorY(), getActivatorZ(), getTargetX(), getTargetY(), getTargetZ(),
                getArg0(), getArg1(), getArg2());
    }

    /**
     * Creates a helper that allows inheriting classes to extend this and
     * return the values appended.
     * 
     * @return
     *       A starting of the helper object.
     */
    public ToStringHelper eventToStringHelper() {
        return MoreObjects.toStringHelper(this).add("type", getEventType()).add("name", activator.getName())
                .add("target", target.toString()).add("gametic", gametic).add("activatorX", activatorX)
                .add("activatorY", activatorY).add("activatorZ", activatorZ).add("targetX", targetX)
                .add("targetY", targetY).add("targetZ", targetZ).add("arg0", arg0).add("arg1", arg1)
                .add("arg2", arg2);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return eventToStringHelper().toString();
    }
}