com.wx3.galacdecks.datastore.GameDatastore.java Source code

Java tutorial

Introduction

Here is the source code for com.wx3.galacdecks.datastore.GameDatastore.java

Source

/**
 * The MIT License (MIT)
 * 
 * Copyright (c) 2015 Kevin Lin
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */
/**
 * 
 */
package com.wx3.galacdecks.datastore;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ImmutableMap;
import com.wx3.galacdecks.Bootstrap;
import com.wx3.galacdecks.ai.AiManager;
import com.wx3.galacdecks.ai.AiHint;
import com.wx3.galacdecks.game.EntityPrototype;
import com.wx3.galacdecks.game.EntityRule;
import com.wx3.galacdecks.game.GameInstance;
import com.wx3.galacdecks.game.GameState;
import com.wx3.galacdecks.game.GameSystem;
import com.wx3.galacdecks.game.PlayerShip;
import com.wx3.galacdecks.game.PlayerInstance;
import com.wx3.galacdecks.game.ValidatorScript;
import com.wx3.galacdecks.server.AuthenticationException;
import com.wx3.galacdecks.server.Authenticator;
import com.wx3.galacdecks.server.User;

/**
 * @author Kevin
 *
 */
public class GameDatastore implements Authenticator {

    final static Logger logger = LoggerFactory.getLogger(GameDatastore.class);

    private static SessionFactory sessionFactory;

    private Map<String, EntityPrototype> cardsById = new HashMap<String, EntityPrototype>();
    private Map<String, EntityRule> rulesById = new HashMap<String, EntityRule>();
    private Map<String, GameSystem> systemsById = new HashMap<>();
    private Map<String, PlayerShip> playerShips = new HashMap<>();

    public GameDatastore() {
        sessionFactory = createSessionFactory();
    }

    private SessionFactory createSessionFactory() {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
        serviceRegistryBuilder.applySettings(configuration.getProperties());
        ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
        return configuration.buildSessionFactory(serviceRegistry);
    }

    public void loadCache() {
        Collection<EntityPrototype> cards = loadPrototypes();
        for (EntityPrototype card : cards) {
            cardsById.put(card.getId(), card);
        }
        Collection<EntityRule> rules = loadRules();
        for (EntityRule rule : rules) {
            rulesById.put(rule.getId(), rule);
        }
        Collection<GameSystem> systems = loadSystems();
        for (GameSystem system : systems) {
            systemsById.put(system.id, system);
        }
        Collection<PlayerShip> ships = loadShips();
        for (PlayerShip ship : ships) {
            playerShips.put(ship.getId(), ship);
        }
    }

    public void createUser(User user) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();
    }

    public User newUser(String username) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        User user = User.CreateUser(username);
        session.save(user);
        session.getTransaction().commit();
        return user;
    }

    public User getUser(String username) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        Criteria criteria = session.createCriteria(User.class);
        User user = (User) criteria.add(Restrictions.eq("username", username)).uniqueResult();
        session.getTransaction().commit();
        return user;
    }

    public void createPrototype(com.wx3.galacdecks.game.EntityPrototype prototype) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(prototype);
        session.getTransaction().commit();

        session = sessionFactory.openSession();
        session.beginTransaction();
        EntityPrototype loaded = (EntityPrototype) session.get(EntityPrototype.class, prototype.getId());
        session.getTransaction().commit();

        if (loaded.getAiHints().size() != prototype.getAiHints().size()) {
            logger.info("Houston, we have a problem.");
        }
    }

    public void createValidator(ValidatorScript validator) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(validator);
        session.getTransaction().commit();
    }

    public void createRule(EntityRule rule) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(rule);
        session.getTransaction().commit();
    }

    public void createAiHint(AiHint hint) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(hint);
        session.getTransaction().commit();
    }

    public void createSystem(GameSystem system) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(system);
        session.getTransaction().commit();
    }

    public void createPlayerShip(PlayerShip playerShip) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(playerShip);
        session.getTransaction().commit();
    }

    /**
     * Returns an unmodifiable view of the card lookup. The card lookup is shared by
     * all games so we don't want to accidentally modify it.
     * @return
     */
    public Map<String, EntityPrototype> getPrototypes() {
        return Collections.unmodifiableMap(cardsById);
    }

    public EntityPrototype getPrototype(String id) {
        if (!cardsById.containsKey(id)) {
            throw new RuntimeException("Could not find card named '" + id + "' in datastore cache.");
        }
        return cardsById.get(id);
    }

    public GameSystem getSystem(String id) {
        GameSystem system = systemsById.get(id);
        if (system == null)
            return null;
        system.setPrototypes(getPrototypes());
        system.setRules(getEntityRules());
        system.setPlayerShips(Collections.unmodifiableMap(playerShips));
        return system;
    }

    /**
     * Return an unmodifiable map of the rule lookup, so games can add rules to entities
     * dynamically.
     * 
     * @return
     */
    public Map<String, EntityRule> getEntityRules() {
        if (rulesById == null) {
            throw new RuntimeException("Rule cache not initialized");
        }
        return Collections.unmodifiableMap(rulesById);
    }

    public PlayerShip getShip(String id) {
        PlayerShip ship = null;
        if (playerShips.containsKey(id)) {
            ship = playerShips.get(id);
            ship.setStartingDeck(Bootstrap.GetDefaultDeck());
        }
        return ship;
    }

    public PlayerInstance authenticate(String authtoken) throws AuthenticationException {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        Criteria criteria = session.createCriteria(PlayerInstance.class);
        PlayerInstance player = (PlayerInstance) criteria.add(Restrictions.eq("authtoken", authtoken))
                .uniqueResult();
        session.getTransaction().commit();
        return player;
    }

    public void newGame(GameInstance game) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(game);
        session.getTransaction().commit();
    }

    public EntityPrototype loadPrototype(String id) {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        EntityPrototype proto = (EntityPrototype) session.get(EntityPrototype.class, id);
        session.getTransaction().commit();
        return proto;
    }

    private Collection<EntityPrototype> loadPrototypes() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // If we're using some kind of SQL database, there may be a behind-the-scenes
        // join creating multiple results, so we need the DISTINCT_ROOT_ENTITY transformer:
        @SuppressWarnings("unchecked")
        List<EntityPrototype> cardList = session.createCriteria(EntityPrototype.class)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
        session.getTransaction().commit();
        for (EntityPrototype card : cardList) {
            if (card.getAiHints().size() > 1) {
                logger.info("Many hints: " + card.getAiHints().size());
            }
        }
        return cardList;
    }

    private Collection<EntityRule> loadRules() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // If we're using some kind of SQL database, there may be a behind-the-scenes
        // join creating multiple results, so we need the DISTINCT_ROOT_ENTITY transformer:
        @SuppressWarnings("unchecked")
        List<EntityRule> ruleList = session.createCriteria(EntityRule.class)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
        session.getTransaction().commit();
        return ruleList;
    }

    private Collection<GameSystem> loadSystems() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // If we're using some kind of SQL database, there may be a behind-the-scenes
        // join creating multiple results, so we need the DISTINCT_ROOT_ENTITY transformer:
        @SuppressWarnings("unchecked")
        List<GameSystem> systemList = session.createCriteria(GameSystem.class)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
        session.getTransaction().commit();
        return systemList;
    }

    private Collection<PlayerShip> loadShips() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // If we're using some kind of SQL database, there may be a behind-the-scenes
        // join creating multiple results, so we need the DISTINCT_ROOT_ENTITY transformer:
        @SuppressWarnings("unchecked")
        List<PlayerShip> shipList = session.createCriteria(PlayerShip.class)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
        session.getTransaction().commit();
        return shipList;
    }

}