org.getspout.spout.player.SimpleFileManager.java Source code

Java tutorial

Introduction

Here is the source code for org.getspout.spout.player.SimpleFileManager.java

Source

/*
 * This file is part of SpoutPlugin.
 *
 * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
 * SpoutPlugin is licensed under the GNU Lesser General Public License.
 *
 * SpoutPlugin 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 3 of the License, or
 * (at your option) any later version.
 *
 * SpoutPlugin 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 program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.getspout.spout.player;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.bukkit.plugin.Plugin;
import org.getspout.spout.Spout;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.io.CRCStore;
import org.getspout.spoutapi.io.CRCStore.URLCheck;
import org.getspout.spoutapi.io.CRCStoreRunnable;
import org.getspout.spoutapi.io.FileUtil;
import org.getspout.spoutapi.packet.PacketCacheDeleteFile;
import org.getspout.spoutapi.packet.PacketPreCacheCompleted;
import org.getspout.spoutapi.packet.PacketPreCacheFile;
import org.getspout.spoutapi.player.FileManager;
import org.getspout.spoutapi.player.SpoutPlayer;

public class SimpleFileManager implements FileManager {
    private Map<Plugin, List<File>> preLoginCache = new HashMap<Plugin, List<File>>();
    private Map<Plugin, List<String>> preLoginUrlCache = new HashMap<Plugin, List<String>>();
    private Map<Plugin, List<String>> cachedFiles = new HashMap<Plugin, List<String>>();
    private static final String[] validExtensions = { "txt", "yml", "xml", "png", "jpg", "ogg", "midi", "wav",
            "zip", "mp3" };

    public void onPlayerJoin(final SpoutPlayer player) {
        if (player.isSpoutCraftEnabled()) {
            Iterator<Entry<Plugin, List<File>>> i = preLoginCache.entrySet().iterator();
            while (i.hasNext()) {
                Entry<Plugin, List<File>> next = i.next();
                for (File file : next.getValue()) {
                    long crc = -1;
                    try {
                        byte[] data = new byte[FileUtils.readFileToByteArray(file).length];
                        crc = FileUtil.getCRC(file, data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if (crc != -1) {
                        player.sendPacket(new PacketPreCacheFile(next.getKey().getDescription().getName(),
                                file.getPath(), crc, false));
                    }
                }
            }
            LinkedList<Thread> urlThreads = new LinkedList<Thread>();
            Iterator<Entry<Plugin, List<String>>> j = preLoginUrlCache.entrySet().iterator();
            while (j.hasNext()) {
                final Entry<Plugin, List<String>> next = j.next();
                for (final String url : next.getValue()) {
                    URLCheck urlCheck = new URLCheck(url, new byte[4096], new CRCStoreRunnable() {
                        Long CRC;

                        public void setCRC(Long CRC) {
                            this.CRC = CRC;
                        }

                        public void run() {
                            player.sendPacket(new PacketPreCacheFile(next.getKey().getDescription().getName(), url,
                                    CRC, true));
                        }
                    });
                    urlCheck.setName(url);
                    urlCheck.start();
                    urlThreads.add(urlCheck);
                }
            }
            new URLCheckJoin(urlThreads, player).start();
        }
    }

    private class URLCheckJoin extends Thread {
        private final List<Thread> threads;
        private final SpoutPlayer player;

        public URLCheckJoin(List<Thread> threads, SpoutPlayer player) {
            this.threads = threads;
            this.player = player;
        }

        public void run() {
            while (!threads.isEmpty()) {
                Iterator<Thread> i = threads.iterator();
                while (i.hasNext()) {
                    Thread t = i.next();
                    try {
                        t.join();
                        i.remove();
                    } catch (InterruptedException ie) {
                    }
                }
            }
            player.sendPacket(new PacketPreCacheCompleted());
        }
    }

    @Override
    public List<String> getCache(Plugin plugin) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        List<String> cache = cachedFiles.get(plugin);
        if (cache == null) {
            cache = new ArrayList<String>(1);
        }
        if (preLoginCache.containsKey(plugin)) {
            for (File f : preLoginCache.get(plugin)) {
                cache.add(f.toString());
            }
        }
        if (preLoginUrlCache.containsKey(plugin)) {
            for (String s : preLoginUrlCache.get(plugin)) {
                cache.add(s);
            }
        }
        return cache;
    }

    @Override
    public boolean addToPreLoginCache(Plugin plugin, File file) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (file == null) {
            throw new NullPointerException("File may not be null");
        }
        if (canCache(file)) {
            List<File> cache = preLoginCache.get(plugin);
            if (cache == null) {
                cache = new ArrayList<File>();
            }
            cache.add(file);
            preLoginCache.put(plugin, cache);
            return true;
        }
        return false;
    }

    @Override
    public boolean addToPreLoginCache(Plugin plugin, String fileUrl) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (fileUrl == null) {
            throw new NullPointerException("The file url may not be null");
        }
        if (canCache(fileUrl)) {
            List<String> cache = preLoginUrlCache.get(plugin);
            if (cache == null) {
                cache = new ArrayList<String>();
            }
            cache.add(fileUrl);
            preLoginUrlCache.put(plugin, cache);
            return true;
        }
        return false;
    }

    @Override
    public boolean addToPreLoginCache(Plugin plugin, Collection<File> files) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (files == null) {
            throw new NullPointerException("The file collection may not be null");
        }
        for (File file : files) {
            if (file == null || !file.exists() || file.isDirectory()) {
                throw new IllegalArgumentException("Invalid Files! Files must not be null and must exist!");
            }
            if (!canCache(file)) {
                return false;
            }
        }
        List<File> cache = preLoginCache.get(plugin);
        if (cache == null) {
            cache = new ArrayList<File>();
        }
        cache.addAll(files);
        preLoginCache.put(plugin, cache);
        return true;
    }

    @Override
    public boolean addToPreLoginCache(Plugin plugin, List<String> fileUrls) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (fileUrls == null) {
            throw new NullPointerException("The url list may not be null");
        }
        for (String file : fileUrls) {
            if (!canCache(file)) {
                return false;
            }
        }
        List<String> cache = preLoginUrlCache.get(plugin);
        if (cache == null) {
            cache = new ArrayList<String>();
        }
        cache.addAll(fileUrls);
        preLoginUrlCache.put(plugin, cache);
        return true;
    }

    @Override
    public boolean addToPreLoginCache(Plugin plugin, InputStream input, String fileName) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (input == null) {
            throw new NullPointerException("Inputstream may not be null");
        }
        if (fileName == null) {
            throw new NullPointerException("Filename may not be null");
        }
        if (canCache(fileName)) {
            File result = addToTempDirectory(input, fileName);
            if (result != null) {
                addToPreLoginCache(plugin, result);
            }
        }
        return false;
    }

    @Override
    public boolean addToCache(Plugin plugin, File file) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (file == null || !file.exists() || file.isDirectory()) {
            throw new IllegalArgumentException("Invalid File! Files must not be null and must exist!");
        }
        if (addToPreLoginCache(plugin, file)) {
            String fileName = FileUtil.getFileName(file.getPath());
            long crc = -1;
            try {
                byte[] data = new byte[FileUtils.readFileToByteArray(file).length];
                crc = FileUtil.getCRC(file, data);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (crc != -1) {
                for (SpoutPlayer player : SpoutManager.getOnlinePlayers()) {
                    if (player.isSpoutCraftEnabled()) {
                        player.sendPacket(new PacketPreCacheFile(plugin.getDescription().getName(), file.getPath(),
                                crc, false));
                    }
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean addToCache(final Plugin plugin, final String fileUrl) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }

        // Only cache valid URL
        if (!isValidUrl(fileUrl)) {
            return false;
        }

        if (addToPreLoginCache(plugin, fileUrl)) {
            URLCheck urlCheck = new URLCheck(fileUrl, new byte[4096], new CRCStoreRunnable() {
                Long CRC;

                public void setCRC(Long CRC) {
                    this.CRC = CRC;
                }

                public void run() {
                    for (SpoutPlayer player : SpoutManager.getOnlinePlayers()) {
                        if (player.isSpoutCraftEnabled()) {
                            player.sendPacket(
                                    new PacketPreCacheFile(plugin.getDescription().getName(), fileUrl, CRC, true));
                        }
                    }
                }
            });
            urlCheck.start();
        }
        return false;
    }

    @Override
    public boolean addToCache(Plugin plugin, Collection<File> files) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        boolean success = true;
        for (File file : files) {
            if (!addToCache(plugin, file)) {
                success = false;
            }
        }
        return success;
    }

    @Override
    public boolean addToCache(Plugin plugin, List<String> fileUrls) {
        boolean success = true;
        for (String file : fileUrls) {
            if (!addToCache(plugin, file)) {
                success = false;
            }
        }
        return success;
    }

    @Override
    public boolean addToCache(Plugin plugin, InputStream input, String fileName) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        if (canCache(fileName)) {
            File result = addToTempDirectory(input, fileName);
            if (result != null) {
                addToCache(plugin, result);
            }
        }
        return false;
    }

    @Override
    public void removeFromCache(Plugin plugin, String file) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        List<File> cache = preLoginCache.get(plugin);
        if (cache != null) {
            Iterator<File> i = cache.iterator();
            while (i.hasNext()) {
                File next = i.next();
                String fileName = FileUtil.getFileName(next.getPath());
                if (fileName.equals(file)) {
                    i.remove();
                }
            }
        }
        List<String> urlCache = preLoginUrlCache.get(plugin);
        if (urlCache != null) {
            Iterator<String> i = urlCache.iterator();
            while (i.hasNext()) {
                String next = i.next();
                String fileName = FileUtil.getFileName(next);
                if (fileName.equals(file)) {
                    i.remove();
                }
            }
        }
        for (SpoutPlayer player : SpoutManager.getOnlinePlayers()) {
            if (player.isSpoutCraftEnabled()) {
                player.sendPacket(new PacketCacheDeleteFile(plugin.getDescription().getName(), file));
            }
        }
    }

    @Override
    public void removeFromCache(Plugin plugin, List<String> files) {
        if (plugin == null) {
            throw new NullPointerException("Plugin may not be null");
        }
        for (String file : files) {
            removeFromCache(plugin, file);
        }
    }

    @Override
    public boolean canCache(File file) {
        String filename = FileUtil.getFileName(file.getPath());
        return FilenameUtils.isExtension(filename, validExtensions);
    }

    @Override
    public boolean canCache(String fileUrl) {
        String filename = FileUtil.getFileName(fileUrl);
        return FilenameUtils.isExtension(filename, validExtensions);
    }

    private static File getTempDirectory() {
        File dir = new File(Spout.getInstance().getDataFolder(), "temp");
        if (!dir.exists()) {
            dir.mkdir();
        }
        return dir;
    }

    private static File addToTempDirectory(InputStream input, String fileName) {
        BufferedOutputStream output = null;
        try {
            File temp = new File(getTempDirectory(), fileName);
            output = new BufferedOutputStream(new FileOutputStream(temp));
            IOUtils.copy(input, output);
            return temp;
        } catch (IOException e) {
            return null;
        } finally {
            try {
                if (output != null) {
                    output.close();
                }
            } catch (IOException ignore) {
            }
            try {
                if (input != null) {
                    input.close();
                }
            } catch (IOException ignore) {
            }
        }
    }

    public static void clearTempDirectory() {
        try {
            FileUtils.deleteDirectory(getTempDirectory());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean isValidUrl(String url) {
        try {
            URL checkURL = new URL(url);
            return true;
        } catch (MalformedURLException e) {
            return false;
        }
    }

    public List<File> getPluginPreLoginCache(Plugin plugin) {
        if (!preLoginCache.containsKey(plugin)) {
            return null;
        }
        return preLoginCache.get(plugin);
    }

    public List<String> getPluginPreLoginUrlCache(Plugin plugin) {
        if (!preLoginUrlCache.containsKey(plugin)) {
            return null;
        }
        return preLoginUrlCache.get(plugin);
    }
}