net.tbnr.gearz.arena.ArenaManager.java Source code

Java tutorial

Introduction

Here is the source code for net.tbnr.gearz.arena.ArenaManager.java

Source

/*
 * Copyright (c) 2014.
 * CogzMC LLC USA
 * All Right reserved
 *
 * This software is the confidential and proprietary information of Cogz Development, LLC.
 * ("Confidential Information").
 * You shall not disclose such Confidential Information and shall use it only in accordance
 * with the terms of the license agreement you entered into with Cogz LLC.
 */

package net.tbnr.gearz.arena;

import com.mongodb.*;
import net.tbnr.gearz.Gearz;
import net.tbnr.gearz.GearzException;
import org.bson.types.ObjectId;
import org.bukkit.Bukkit;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Joey
 * Date: 9/5/13
 * Time: 11:26 PM
 * To change this template use File | Settings | File Templates.
 */
public final class ArenaManager {
    /**
     * Stores all the Arenas for this game
     */
    private List<Arena> arenas;
    /**
     * The collection where the arenas are stored.
     */
    private final DBCollection collection;

    /**
     * The arena class
     */
    private final Class<? extends Arena> arenaClass;

    /**
     * Creates an ArenaManager based off a game identifier
     *
     * @param gameId The game identifier
     */
    public ArenaManager(String gameId, Class<? extends Arena> arenaClass) throws GearzException {
        try {
            this.collection = Gearz.getInstance().getMongoDB().getCollection("arena_v2_" + gameId);
        } catch (NullPointerException ex) {
            Bukkit.shutdown();
            throw new GearzException("Cannot start ArenaManager! Not connected to Mongo!");
        }
        this.arenaClass = arenaClass;
        try {
            reloadArenas();
        } catch (GearzException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Loads the arenas into the List.
     */
    private void loadArenas() throws GearzException {
        DBCursor dbCursor = this.collection.find();
        if (dbCursor.size() == 0) {
            throw new GearzException("No arenas found!");
        }
        while (dbCursor.hasNext()) {
            DBObject next = dbCursor.next();
            Arena attempt;
            try {
                attempt = ArenaManager.arenaFromDBObject(this.arenaClass, next);
            } catch (GearzException e) {
                e.printStackTrace();
                continue;
            }
            this.arenas.add(attempt);
            Gearz.getInstance().getLogger()
                    .info("Loaded Arena - " + attempt.getName() + " by - " + attempt.getAuthors());
        }
    }

    /**
     * Clears the list, and loads the Arenas
     */
    private void reloadArenas() throws GearzException {
        this.arenas = new ArrayList<>();
        loadArenas();
    }

    /**
     * CRUD - C : Creates an arena in the database. Checks for existing data and falls back to CRUD - U
     *
     * @param arena The arena to check.
     * @throws GearzException This is when there is an exception parsing this arena.
     */
    public void addArena(Arena arena) throws GearzException {
        this.collection.insert(ArenaManager.objectFromArena(arena));
    }

    /**
     * CRUD - D : Deletes an entry from the database (removes the Arena from circulation)
     *
     * @param arena The arena to remove from the database.
     * @throws GearzException
     */
    public void removeArena(Arena arena) throws GearzException {
        this.collection.remove(new BasicDBObject("_id", new ObjectId(arena.getId())));
    }

    /**
     * CRUD - U : Updates a current arena using the ID from the Arena.
     *
     * @param arena The arena to update.
     * @throws GearzException
     */
    public void updateArena(Arena arena) throws GearzException {
        if (arena.getId() == null) {
            throw new GearzException("Cannot update a new arena!");
        }
        this.collection.save(ArenaManager.objectFromArena(arena));
    }

    /**
     * Gets all loaded arenas.
     *
     * @return The loaded arenas.
     */
    public List<Arena> getArenas() {
        return this.arenas;
    }

    /**
     * Converts an Arena object into a DB Object that can be reversed using the other method (which is not static)
     *
     * @param arena The arena to convert into a DBObject
     * @return The DBObject version of this Arena.
     */
    public static DBObject objectFromArena(Arena arena) {
        BasicDBObjectBuilder objectBuilder = new BasicDBObjectBuilder(); //Start building the database object for this arena
        for (Field field : arena.getClass().getFields()) { //Get all the fields ...
            if (!field.isAnnotationPresent(ArenaField.class)) {
                continue; //... that we can access, and are annotated by ArenaField ...
            }
            ArenaField annotation = field.getAnnotation(ArenaField.class); //Get the Annotation from the field as an object
            ArenaIterator iterator; //Setup an object to put the iterator in
            try {
                iterator = (ArenaIterator) field.get(arena); //Try to getSetting the arena iterator
            } catch (IllegalAccessException e) {
                continue; //Didn't work :o
            }
            BasicDBList list = new BasicDBList(); //Pour our list into the DB List object
            while (iterator.hasNext()) {
                Object next = iterator.next();
                ArenaFieldSerializer.SerializationDelegate<?> serializerFor = ArenaFieldSerializer
                        .getSerializerFor(next.getClass());
                if (serializerFor == null)
                    continue;
                list.add(serializerFor.getObjectFor(next)); //Add whatever "next" is now. Depending on code above, it could be a DBObject, or whatever the iterator has in store.
            }
            objectBuilder.append(annotation.key(), list); //Put that in the database
        }
        objectBuilder.append("name", arena.getName()); //Meta for a bit.
        objectBuilder.append("description", arena.getDescription());
        objectBuilder.append("worldId", arena.getWorldId());
        objectBuilder.append("last-updated", Calendar.getInstance().getTimeInMillis());
        objectBuilder.append("author", arena.getAuthors());
        if (arena.getId() != null) {
            objectBuilder.append("_id", new ObjectId(arena.getId())); //Good for replacing/updating
        }
        return objectBuilder.get(); //Finish the object off! :D
    }

    public void logVotes(Arena arena, Integer votes) {
        DBObject object = this.collection.findOne(new BasicDBObject("_id", new ObjectId(arena.getId())));
        Integer votes1 = getInt(object.get("votes"));
        if (votes1 == null) {
            votes1 = 0;
        }
        votes1 += votes;
        object.put("votes", votes1);
        this.collection.save(object);
    }

    /**
     * Loads an arena
     *
     * @param object The DBObject that represents the arena
     * @return The arena object, fully loaded.
     * @throws GearzException When something goes wrong
     */
    public static Arena arenaFromDBObject(Class<? extends Arena> arenaClass, DBObject object)
            throws GearzException {
        Arena arena;
        try {
            Constructor constructor = arenaClass.getConstructor(String.class, String.class, String.class,
                    String.class, String.class);
            if (constructor == null) {
                return null;
            }
            arena = (Arena) constructor.newInstance(object.get("name"), object.get("author"),
                    object.get("description"), object.get("worldId"), object.get("_id").toString());
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
        for (Field field : arenaClass.getFields()) {
            if (!(field.isAnnotationPresent(ArenaField.class)))
                continue;
            if (!ArenaIterator.class.isAssignableFrom(field.getType()))
                continue;
            ArenaField annotation = field.getAnnotation(ArenaField.class);
            if (!object.containsField(annotation.key()))
                continue;
            Object o = object.get(annotation.key());
            if (!(o instanceof BasicDBList))
                continue;
            BasicDBList list = (BasicDBList) o;
            List<Object> list2 = new ArrayList<>();
            ArenaFieldSerializer.SerializationDelegate serializer = null;
            for (Object lObject : list) {
                if (lObject instanceof DBObject) {
                    DBObject lObject1 = (DBObject) lObject;
                    if (serializer == null) {
                        serializer = ArenaFieldSerializer.getSerializerFor(lObject1);
                    } else if (!ArenaFieldSerializer.getSerializerFor(lObject1).equals(serializer)) {
                        continue; //In case we have a rogue strange value
                    }
                    list2.add(serializer.getObjectFor(lObject1));
                }
            }
            ArenaIterator iterator;
            if (serializer == null) {
                iterator = new PointIterator();
            } else //noinspection unchecked
            {
                iterator = serializer.getNewIterator(list2);
            }
            iterator.setLoop(annotation.loop()); //Checks the annotation for this new looping thing. :D
            try {
                field.set(arena, field.getType().cast(iterator));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return arena;
    }

    private static Integer getInt(Object o) {
        if (o instanceof Integer) {
            return (Integer) o;
        }
        if (o instanceof Double) {
            return ((Double) o).intValue();
        }
        if (o instanceof Float) {
            return ((Float) o).intValue();
        }
        return null;
    }

    public List<Arena> getRandomArenas(int count) {
        List<Arena> arenas = new ArrayList<>();
        while (arenas.size() < count) {
            Arena a = null;
            while (a == null || arenas.contains(a)) {
                a = getArenas().get(Gearz.getRandom().nextInt(getArenas().size()));
            }
            arenas.add(a);
            if (arenas.containsAll(getArenas())) {
                break;
            }
        }
        return arenas;
    }
}