Package com.forgeessentials.permissions.persistence

Source Code of com.forgeessentials.permissions.persistence.FlatfileProvider$SortedPermisssionProperties

package com.forgeessentials.permissions.persistence;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TreeSet;
import java.util.UUID;

import org.apache.commons.io.FileUtils;

import com.forgeessentials.api.permissions.AreaZone;
import com.forgeessentials.api.permissions.FEPermissions;
import com.forgeessentials.api.permissions.ServerZone;
import com.forgeessentials.api.permissions.WorldZone;
import com.forgeessentials.api.permissions.Zone;
import com.forgeessentials.api.permissions.Zone.PermissionList;
import com.forgeessentials.permissions.core.ZonePersistenceProvider;
import com.forgeessentials.util.OutputHandler;
import com.forgeessentials.util.UserIdent;
import com.forgeessentials.util.selections.AreaBase;
import com.forgeessentials.util.selections.Point;

public class FlatfileProvider extends ZonePersistenceProvider {

    public static final String PERMISSION_FILE_EXT = ".txt";

    private File basePath;

    public static final FileFilter permissionFilter = new FileFilters.Extension(PERMISSION_FILE_EXT);

    public static final FileFilter directoryFilter = new FileFilters.Directory();

    public static class SortedPermisssionProperties extends Properties {
        private static final long serialVersionUID = 1L;

        @Override
        public synchronized Enumeration<Object> keys()
        {
            TreeSet<Object> keys = new TreeSet<Object>(Zone.permissionComparator);
            keys.addAll(super.keySet());
            return Collections.enumeration(keys);
        }
    }

    public static final String COMMENT_INFO = "\nDO NOT MODIFY OR REMOVE fe.internal PERMISSIONS UNLESS YOU KNOW WHAT YOU DO!"
            + "\nAfter you modified permissions in this file, remember to directly run \"/feperm reload\", or the changes get overwritten next time permissions are saved by the server.";

    // ------------------------------------------------------------

    public FlatfileProvider(File basePath)
    {
        this.basePath = basePath;
    }

    // ------------------------------------------------------------
    // -- Saving
    // ------------------------------------------------------------

    @Override
    public void save(ServerZone serverZone)
    {
        File path = basePath;

        try
        {
            // TODO: Replace this by a system that only deletes invalid files
            FileUtils.moveDirectory(path, new File(path.getParentFile(), path.getName() + "_backup"));
            if (path.exists())
                FileUtils.cleanDirectory(path);
        }
        catch (IOException e)
        {
        }
       
        writeUserGroupPermissions(serverZone);

        saveServerZone(path, serverZone);
        saveZonePermissions(path, serverZone);

        for (WorldZone worldZone : serverZone.getWorldZones().values())
        {
            File worldPath = new File(path, worldZone.getName());
            saveWorldZone(worldPath, worldZone);
            saveZonePermissions(worldPath, worldZone);
            for (AreaZone areaZone : worldZone.getAreaZones())
            {
                File areaPath = new File(worldPath, areaZone.getName());
                saveAreaZone(areaPath, areaZone);
                saveZonePermissions(areaPath, areaZone);
            }
        }
    }

    public static void saveServerZone(File path, ServerZone serverZone)
    {
        // Store zone information
        try
        {
            path.mkdirs();

            Properties p = new Properties();

            p.setProperty("id", Integer.toString(serverZone.getId()));
            p.setProperty("maxZoneId", Integer.toString(serverZone.getMaxZoneID()));

            p.storeToXML(new BufferedOutputStream(new FileOutputStream(new File(path, "server.xml"))), "Data of server");
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static void saveWorldZone(File path, WorldZone worldZone)
    {
        try
        {
            path.mkdirs();

            Properties p = new Properties();

            p.setProperty("id", Integer.toString(worldZone.getId()));
            p.setProperty("dimId", Integer.toString(worldZone.getDimensionID()));

            p.storeToXML(new BufferedOutputStream(new FileOutputStream(new File(path, "world.xml"))), "Data of world " + worldZone.getName());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static void saveAreaZone(File path, AreaZone areaZone)
    {
        try
        {
            path.mkdirs();

            Properties p = new Properties();

            p.setProperty("id", Integer.toString(areaZone.getId()));
            p.setProperty("name", areaZone.getName());
            p.setProperty("x1", Integer.toString(areaZone.getArea().getLowPoint().getX()));
            p.setProperty("y1", Integer.toString(areaZone.getArea().getLowPoint().getY()));
            p.setProperty("z1", Integer.toString(areaZone.getArea().getLowPoint().getZ()));
            p.setProperty("x2", Integer.toString(areaZone.getArea().getHighPoint().getX()));
            p.setProperty("y2", Integer.toString(areaZone.getArea().getHighPoint().getY()));
            p.setProperty("z2", Integer.toString(areaZone.getArea().getHighPoint().getZ()));

            p.storeToXML(new BufferedOutputStream(new FileOutputStream(new File(path, "area.xml"))), "Data of area " + areaZone.getName());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static void saveZonePermissions(File path, Zone zone)
    {
        File playersPath = new File(path, "players");
        File groupsPath = new File(path, "groups");
        for (Entry<UserIdent, PermissionList> entry : zone.getPlayerPermissions().entrySet())
        {
            // Get filename and info
            String username = entry.getKey().getUsername() == null ? entry.getKey().getUuid().toString() : entry.getKey().getUsername();
            UUID uuid = entry.getKey().getUuid();
            String userIdentification = username == null ? uuid.toString() : username;
            String comment = "Permissions for user " + (username != null ? username : "<unknown-username>") + " with UUID "
                    + (uuid != null ? uuid.toString() : "<unknown-uuid>") + COMMENT_INFO;
            userIdentification = userIdentification.replaceAll("[^a-zA-Z0-9\\.\\-]", "_");

            // Save permissions
            Properties p = permissionListToProperties(entry.getValue());
            if (entry.getKey().getUsername() != null)
                p.setProperty(FEPermissions.PLAYER_NAME, entry.getKey().getUsername());
            if (entry.getKey().getUuid() != null)
                p.setProperty(FEPermissions.PLAYER_UUID, entry.getKey().getUuid().toString());
            saveProperties(p, playersPath, userIdentification + PERMISSION_FILE_EXT, comment);
        }
        for (Entry<String, PermissionList> entry : zone.getGroupPermissions().entrySet())
        {
            // Get filename and info
            String comment = "Permissions for group " + entry.getKey() + COMMENT_INFO;

            // Save permissions
            Properties p = permissionListToProperties(entry.getValue());
            saveProperties(p, groupsPath, entry.getKey() + PERMISSION_FILE_EXT, comment);
        }
    }

    public static Properties permissionListToProperties(PermissionList list)
    {
        Properties p = new SortedPermisssionProperties();
        for (Entry<String, String> permission : list.entrySet())
            p.setProperty(permission.getKey(), permission.getValue() != null ? permission.getValue() : "");
        return p;
    }

    public static void saveProperties(Properties properties, File path, String filename, String comment)
    {
        try
        {
            path.mkdirs();
            properties.store(new BufferedOutputStream(new FileOutputStream(new File(path, filename))), comment);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    // ------------------------------------------------------------

    // ------------------------------------------------------------
    // -- Loading
    // ------------------------------------------------------------

    @Override
    public ServerZone load()
    {
        File path = basePath;
        try
        {
            // Create ServerZone and load permissions
            ServerZone serverZone = new ServerZone();
            loadZonePermissions(path, serverZone);

            readUserGroupPermissions(serverZone);

            int maxId = 2;

            File[] worldDirs = path.listFiles(directoryFilter);
            if (worldDirs == null)
            {
                OutputHandler.felog.severe("Error loading permissions: invalid path");
                return null;
            }
            for (File worldPath : worldDirs)
            {
                try
                {
                    File worldFile = new File(worldPath, "world.xml");
                    if (!worldFile.exists())
                        continue;
                    Properties worldProperties = new Properties();
                    worldProperties.loadFromXML(new BufferedInputStream(new FileInputStream(worldFile)));

                    // Read world data
                    int worldId = Integer.parseInt(worldProperties.getProperty("id"));
                    maxId = Math.max(maxId, worldId);

                    int dimensionID = Integer.parseInt(worldProperties.getProperty("dimId"));

                    // Create WorldZone and load permissions
                    WorldZone worldZone = new WorldZone(serverZone, dimensionID, worldId);
                    loadZonePermissions(worldPath, worldZone);

                    for (File areaPath : worldPath.listFiles(directoryFilter))
                    {
                        try
                        {
                            File areaFile = new File(areaPath, "area.xml");
                            if (!areaFile.exists())
                                continue;
                            Properties areaProperties = new Properties();
                            areaProperties.loadFromXML(new BufferedInputStream(new FileInputStream(areaFile)));

                            // Read area data
                            int areaId = Integer.parseInt(areaProperties.getProperty("id"));
                            maxId = Math.max(maxId, areaId);

                            String name = areaProperties.getProperty("name");
                            int x1 = Integer.parseInt(areaProperties.getProperty("x1"));
                            int y1 = Integer.parseInt(areaProperties.getProperty("y1"));
                            int z1 = Integer.parseInt(areaProperties.getProperty("z1"));
                            int x2 = Integer.parseInt(areaProperties.getProperty("x2"));
                            int y2 = Integer.parseInt(areaProperties.getProperty("y2"));
                            int z2 = Integer.parseInt(areaProperties.getProperty("z2"));
                            if (name == null)
                                throw new IllegalArgumentException();

                            // Create AreaZone and load permissions
                            AreaZone areaZone = new AreaZone(worldZone, name, new AreaBase(new Point(x1, y1, z1), new Point(x2, y2, z2)), areaId);
                            loadZonePermissions(areaPath, areaZone);
                        }
                        catch (IllegalArgumentException | IOException e)
                        {
                            OutputHandler.felog.severe("Error reading area " + worldPath.getName() + "/" + areaPath.getName());
                        }
                    }
                }
                catch (NumberFormatException | IOException e)
                {
                    OutputHandler.felog.severe("Error reading world " + worldPath.getName());
                }
            }

            File serverFile = new File(path, "server.xml");
            if (serverFile.exists())
            {
                try
                {
                    Properties serverProperties = new Properties();
                    serverProperties.loadFromXML(new BufferedInputStream(new FileInputStream(serverFile)));
                    serverZone.setMaxZoneId(Integer.parseInt(serverProperties.getProperty("maxZoneId")));
                }
                catch (IllegalArgumentException | IOException e)
                {
                    OutputHandler.felog.severe("Error reading server data " + serverFile.getName());
                    serverZone.setMaxZoneId(maxId);
                }
            }
            else
            {
                serverZone.setMaxZoneId(maxId);
            }

            return serverZone;
        }
        catch (Exception e)
        {
            OutputHandler.felog.severe("Error loading permissions");
            e.printStackTrace();
            return null;
        }
    }

    public static void loadZonePermissions(File path, Zone zone)
    {
        File playersPath = new File(path, "players");
        File groupsPath = new File(path, "groups");

        if (playersPath.exists())
        {
            for (File file : playersPath.listFiles(permissionFilter))
            {
                try
                {
                    Properties p = new Properties();
                    p.load(new BufferedInputStream(new FileInputStream(file)));

                    // Get player
                    String username = p.getProperty(FEPermissions.PLAYER_NAME);
                    String uuid = p.getProperty(FEPermissions.PLAYER_UUID);
                    p.remove(FEPermissions.PLAYER_NAME);
                    p.remove(FEPermissions.PLAYER_UUID);
                    if (username == null && uuid == null)
                    {
                        OutputHandler.felog.severe("User identification missing in " + path.getAbsolutePath());
                        continue;
                    }
                    UserIdent ident = new UserIdent(uuid, username);

                    // Load permissions
                    PermissionList permissions = zone.getOrCreatePlayerPermissions(ident);
                    for (Entry permission : p.entrySet())
                    {
                        permissions.put((String) permission.getKey(), (String) permission.getValue());
                    }
                }
                catch (IllegalArgumentException | IOException e)
                {
                    OutputHandler.felog.severe("Error reading permissions from " + path.getAbsolutePath());
                }
            }

        }

        if (groupsPath.exists())
        {
            for (File file : groupsPath.listFiles(permissionFilter))
            {
                try
                {
                    Properties p = new Properties();
                    p.load(new BufferedInputStream(new FileInputStream(file)));

                    // Get group
                    String groupName = file.getName().substring(0, file.getName().length() - PERMISSION_FILE_EXT.length());

                    // Load permissions
                    PermissionList permissions = zone.getOrCreateGroupPermissions(groupName);
                    for (Entry permission : p.entrySet())
                    {
                        permissions.put((String) permission.getKey(), (String) permission.getValue());
                    }
                }
                catch (IllegalArgumentException | IOException e)
                {
                    OutputHandler.felog.severe("Error reading permissions from " + path.getAbsolutePath());
                }
            }

        }
    }

}
TOP

Related Classes of com.forgeessentials.permissions.persistence.FlatfileProvider$SortedPermisssionProperties

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.