summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnowleo <schneeleo@gmail.com>2011-12-06 10:37:17 +0100
committersnowleo <schneeleo@gmail.com>2011-12-06 10:37:17 +0100
commitf3b278eac291f88ca359d7c25e24c920ee4ac494 (patch)
tree97ffaa7e47ffd83c88cfd6bef1427e5d243abccf
parent6fe8e603af14fc9275060317c842c15ba327e971 (diff)
downloadEssentials-f3b278eac291f88ca359d7c25e24c920ee4ac494.tar
Essentials-f3b278eac291f88ca359d7c25e24c920ee4ac494.tar.gz
Essentials-f3b278eac291f88ca359d7c25e24c920ee4ac494.tar.lz
Essentials-f3b278eac291f88ca359d7c25e24c920ee4ac494.tar.xz
Essentials-f3b278eac291f88ca359d7c25e24c920ee4ac494.zip
More work done on config code
-rw-r--r--Essentials/src/com/earth2me/essentials/UserMap.java9
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java55
-rw-r--r--Essentials/src/com/earth2me/essentials/user/Ban.java (renamed from Essentials/src/com/earth2me/essentials/userdata/Ban.java)2
-rw-r--r--Essentials/src/com/earth2me/essentials/user/IOfflinePlayer.java15
-rw-r--r--Essentials/src/com/earth2me/essentials/user/IOfflineUser.java7
-rw-r--r--Essentials/src/com/earth2me/essentials/user/IUserData.java13
-rw-r--r--Essentials/src/com/earth2me/essentials/user/Inventory.java (renamed from Essentials/src/com/earth2me/essentials/userdata/Inventory.java)2
-rw-r--r--Essentials/src/com/earth2me/essentials/user/User.java111
-rw-r--r--Essentials/src/com/earth2me/essentials/user/UserBase.java115
-rw-r--r--Essentials/src/com/earth2me/essentials/user/UserData.java (renamed from Essentials/src/com/earth2me/essentials/userdata/UserData.java)2
-rw-r--r--Essentials/src/com/earth2me/essentials/user/UserMap.java128
-rw-r--r--Essentials/src/com/earth2me/essentials/userdata/User.java65
-rw-r--r--Essentials/test/com/earth2me/essentials/StorageTest.java10
13 files changed, 459 insertions, 75 deletions
diff --git a/Essentials/src/com/earth2me/essentials/UserMap.java b/Essentials/src/com/earth2me/essentials/UserMap.java
index b41298ed2..467c2693b 100644
--- a/Essentials/src/com/earth2me/essentials/UserMap.java
+++ b/Essentials/src/com/earth2me/essentials/UserMap.java
@@ -85,8 +85,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf
return new User(player, ess);
}
}
- final File userFolder = new File(ess.getDataFolder(), "userdata");
- final File userFile = new File(userFolder, Util.sanitizeFileName(name) + ".yml");
+ final File userFile = getUserFile(name);
if (userFile.exists())
{
keys.add(name.toLowerCase(Locale.ENGLISH));
@@ -116,4 +115,10 @@ public class UserMap extends CacheLoader<String, User> implements IConf
{
return keys.size();
}
+
+ public File getUserFile(final String name)
+ {
+ final File userFolder = new File(ess.getDataFolder(), "userdata");
+ return new File(userFolder, Util.sanitizeFileName(name) + ".yml");
+ }
}
diff --git a/Essentials/src/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java b/Essentials/src/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java
new file mode 100644
index 000000000..697ef7730
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java
@@ -0,0 +1,55 @@
+package com.earth2me.essentials.storage;
+
+import com.earth2me.essentials.IEssentials;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.bukkit.Bukkit;
+
+
+public abstract class AbstractDelayedYamlFileWriter implements Runnable
+{
+ private final transient File file;
+
+ public AbstractDelayedYamlFileWriter(IEssentials ess, File file)
+ {
+ this.file = file;
+ ess.scheduleAsyncDelayedTask(this);
+ }
+
+ public abstract StorageObject getObject();
+
+ @Override
+ public void run()
+ {
+ PrintWriter pw = null;
+ try
+ {
+ final StorageObject object = getObject();
+ final File folder = file.getParentFile();
+ if (!folder.exists())
+ {
+ folder.mkdirs();
+ }
+ pw = new PrintWriter(file);
+ new YamlStorageWriter(pw).save(object);
+ }
+ catch (FileNotFoundException ex)
+ {
+ Bukkit.getLogger().log(Level.SEVERE, file.toString(), ex);
+ }
+ finally
+ {
+ onFinish();
+ if (pw != null)
+ {
+ pw.close();
+ }
+ }
+
+ }
+
+ public abstract void onFinish();
+}
diff --git a/Essentials/src/com/earth2me/essentials/userdata/Ban.java b/Essentials/src/com/earth2me/essentials/user/Ban.java
index 6e86780cf..ba1c22333 100644
--- a/Essentials/src/com/earth2me/essentials/userdata/Ban.java
+++ b/Essentials/src/com/earth2me/essentials/user/Ban.java
@@ -1,4 +1,4 @@
-package com.earth2me.essentials.userdata;
+package com.earth2me.essentials.user;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
diff --git a/Essentials/src/com/earth2me/essentials/user/IOfflinePlayer.java b/Essentials/src/com/earth2me/essentials/user/IOfflinePlayer.java
new file mode 100644
index 000000000..4cdee715b
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/IOfflinePlayer.java
@@ -0,0 +1,15 @@
+package com.earth2me.essentials.user;
+
+import org.bukkit.Location;
+
+
+public interface IOfflinePlayer
+{
+ String getName();
+
+ String getDisplayName();
+
+ Location getBedSpawnLocation();
+
+ void setBanned(boolean bln);
+} \ No newline at end of file
diff --git a/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java b/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java
new file mode 100644
index 000000000..4ff54b37b
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java
@@ -0,0 +1,7 @@
+package com.earth2me.essentials.user;
+
+
+public interface IOfflineUser extends IUserData, IOfflinePlayer
+{
+
+}
diff --git a/Essentials/src/com/earth2me/essentials/user/IUserData.java b/Essentials/src/com/earth2me/essentials/user/IUserData.java
new file mode 100644
index 000000000..dcaeaf1a7
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/IUserData.java
@@ -0,0 +1,13 @@
+package com.earth2me.essentials.user;
+
+
+public interface IUserData
+{
+ UserData getData();
+
+ void aquireReadLock();
+
+ void aquireWriteLock();
+
+ void close();
+}
diff --git a/Essentials/src/com/earth2me/essentials/userdata/Inventory.java b/Essentials/src/com/earth2me/essentials/user/Inventory.java
index 91a19e2d1..0812f54a0 100644
--- a/Essentials/src/com/earth2me/essentials/userdata/Inventory.java
+++ b/Essentials/src/com/earth2me/essentials/user/Inventory.java
@@ -1,4 +1,4 @@
-package com.earth2me.essentials.userdata;
+package com.earth2me.essentials.user;
import com.earth2me.essentials.storage.MapKeyType;
import com.earth2me.essentials.storage.MapValueType;
diff --git a/Essentials/src/com/earth2me/essentials/user/User.java b/Essentials/src/com/earth2me/essentials/user/User.java
new file mode 100644
index 000000000..6ad35bfae
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/User.java
@@ -0,0 +1,111 @@
+package com.earth2me.essentials.user;
+
+import com.earth2me.essentials.IEssentials;
+import com.earth2me.essentials.storage.AbstractDelayedYamlFileWriter;
+import com.earth2me.essentials.storage.StorageObject;
+import com.earth2me.essentials.storage.YamlStorageReader;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import lombok.Cleanup;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+// this is a prototype for locking userdata
+public class User extends UserBase implements IOfflineUser
+{
+ private transient UserData data = new UserData();
+ private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+
+ public User(final Player base, final IEssentials ess)
+ {
+ super(base, ess);
+ }
+
+ public User(final OfflinePlayer offlinePlayer, final IEssentials ess)
+ {
+ super(offlinePlayer, ess);
+ }
+
+ public void loadUserData()
+ {
+ data = new YamlStorageReader(null).load(UserData.class);
+ }
+
+ @Override
+ public UserData getData()
+ {
+ return data;
+ }
+
+ @Override
+ public void aquireReadLock()
+ {
+ rwl.readLock().lock();
+ }
+
+ @Override
+ public void aquireWriteLock()
+ {
+ while (rwl.getReadHoldCount() > 0)
+ {
+ rwl.readLock().unlock();
+ }
+ rwl.writeLock().lock();
+ rwl.readLock().lock();
+ }
+
+ @Override
+ public void close()
+ {
+ if (rwl.isWriteLockedByCurrentThread())
+ {
+ rwl.writeLock().unlock();
+ scheduleSaving();
+ }
+ while (rwl.getReadHoldCount() > 0)
+ {
+ rwl.readLock().unlock();
+ }
+ }
+
+ public void example()
+ {
+ // Cleanup will call close at the end of the function
+ @Cleanup
+ final User user = this;
+
+ // read lock allows to read data from the user
+ user.aquireReadLock();
+ final double money = user.getData().getMoney();
+
+ // write lock allows only one thread to modify the data
+ user.aquireWriteLock();
+ user.getData().setMoney(10 + money);
+ }
+
+ private void scheduleSaving()
+ {
+ new UserDataWriter();
+ }
+
+
+ private class UserDataWriter extends AbstractDelayedYamlFileWriter
+ {
+ public UserDataWriter()
+ {
+ super(ess, ess.getUserMap().getUserFile(User.this.getName()));
+ }
+
+ @Override
+ public StorageObject getObject()
+ {
+ aquireReadLock();
+ return getData();
+ }
+
+ @Override
+ public void onFinish()
+ {
+ close();
+ }
+ }
+}
diff --git a/Essentials/src/com/earth2me/essentials/user/UserBase.java b/Essentials/src/com/earth2me/essentials/user/UserBase.java
new file mode 100644
index 000000000..cc071817e
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/UserBase.java
@@ -0,0 +1,115 @@
+package com.earth2me.essentials.user;
+
+import com.earth2me.essentials.IEssentials;
+import com.earth2me.essentials.craftbukkit.OfflineBedLocation;
+import lombok.Delegate;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.permissions.Permissible;
+import org.bukkit.permissions.ServerOperator;
+import org.bukkit.OfflinePlayer;
+
+
+public class UserBase implements Player, IOfflinePlayer
+{
+
+ @Delegate(types =
+ {
+ Player.class, Entity.class, CommandSender.class, ServerOperator.class,
+ HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
+ Permissible.class
+ },excludes=IOfflinePlayer.class)
+ protected Player base;
+ protected transient OfflinePlayer offlinePlayer;
+ protected final transient IEssentials ess;
+
+ public UserBase(final Player base, final IEssentials ess)
+ {
+ this.base = base;
+ this.ess = ess;
+ }
+
+ public UserBase(final OfflinePlayer offlinePlayer, final IEssentials ess)
+ {
+ this.offlinePlayer = offlinePlayer;
+ this.ess = ess;
+ }
+
+ public final Player getBase()
+ {
+ return base;
+ }
+
+ public final Player setBase(final Player base)
+ {
+ return this.base = base;
+ }
+
+ public void update(final Player base)
+ {
+ setBase(base);
+ }
+
+ public void update(final OfflinePlayer offlinePlayer)
+ {
+ this.offlinePlayer = offlinePlayer;
+ }
+
+ public void dispose()
+ {
+ this.offlinePlayer = Bukkit.getOfflinePlayer(base.getName());
+ this.base = null;
+ }
+
+ public boolean isOnlineUser() {
+ return base != null;
+ }
+
+ @Override
+ public String getName()
+ {
+ if (isOnlineUser()) {
+ return base.getName();
+ } else {
+ return offlinePlayer.getName();
+ }
+ }
+
+ @Override
+ public String getDisplayName()
+ {
+ if (isOnlineUser()) {
+ return base.getDisplayName();
+ } else {
+ return offlinePlayer.getName();
+ }
+ }
+
+ @Override
+ public Location getBedSpawnLocation()
+ {
+ if (isOnlineUser()) {
+ return base.getBedSpawnLocation();
+ } else {
+ return OfflineBedLocation.getBedLocation(base.getName(), ess);
+ }
+ }
+
+ @Override
+ public void setBanned(boolean bln)
+ {
+ if (isOnlineUser()) {
+ base.setBanned(bln);
+ } else {
+ offlinePlayer.setBanned(bln);
+ }
+ }
+
+
+}
diff --git a/Essentials/src/com/earth2me/essentials/userdata/UserData.java b/Essentials/src/com/earth2me/essentials/user/UserData.java
index fe537cae8..4586d0627 100644
--- a/Essentials/src/com/earth2me/essentials/userdata/UserData.java
+++ b/Essentials/src/com/earth2me/essentials/user/UserData.java
@@ -1,4 +1,4 @@
-package com.earth2me.essentials.userdata;
+package com.earth2me.essentials.user;
import com.earth2me.essentials.storage.ListType;
import com.earth2me.essentials.storage.MapKeyType;
diff --git a/Essentials/src/com/earth2me/essentials/user/UserMap.java b/Essentials/src/com/earth2me/essentials/user/UserMap.java
new file mode 100644
index 000000000..821ee4c8f
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/user/UserMap.java
@@ -0,0 +1,128 @@
+package com.earth2me.essentials.user;
+
+import com.earth2me.essentials.IConf;
+import com.earth2me.essentials.IEssentials;
+import com.earth2me.essentials.Util;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.util.concurrent.UncheckedExecutionException;
+import java.io.File;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.ExecutionException;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+
+public class UserMap extends CacheLoader<String, User> implements IConf
+{
+ private final transient IEssentials ess;
+ private final transient Cache<String, User> users = CacheBuilder.newBuilder().softValues().build(this);
+ private final transient ConcurrentSkipListSet<String> keys = new ConcurrentSkipListSet<String>();
+
+ public UserMap(final IEssentials ess)
+ {
+ super();
+ this.ess = ess;
+ loadAllUsersAsync(ess);
+ }
+
+ private void loadAllUsersAsync(final IEssentials ess)
+ {
+ ess.scheduleAsyncDelayedTask(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ final File userdir = new File(ess.getDataFolder(), "userdata");
+ if (!userdir.exists())
+ {
+ return;
+ }
+ keys.clear();
+ users.invalidateAll();
+ for (String string : userdir.list())
+ {
+ if (!string.endsWith(".yml"))
+ {
+ continue;
+ }
+ final String name = string.substring(0, string.length() - 4);
+ keys.add(name.toLowerCase(Locale.ENGLISH));
+ }
+ }
+ });
+ }
+
+ public boolean userExists(final String name)
+ {
+ return keys.contains(name.toLowerCase(Locale.ENGLISH));
+ }
+
+ public User getUser(final String name)
+ {
+ try
+ {
+ return users.get(name.toLowerCase(Locale.ENGLISH));
+ }
+ catch (ExecutionException ex)
+ {
+ return null;
+ }
+ catch (UncheckedExecutionException ex)
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public User load(final String name) throws Exception
+ {
+ for (Player player : ess.getServer().getOnlinePlayers())
+ {
+ if (player.getName().equalsIgnoreCase(name))
+ {
+ keys.add(name.toLowerCase(Locale.ENGLISH));
+ return new User(player, ess);
+ }
+ }
+ final File userFile = getUserFile(name);
+ if (userFile.exists())
+ {
+ keys.add(name.toLowerCase(Locale.ENGLISH));
+ return new User(Bukkit.getOfflinePlayer(name), ess);
+ }
+ throw new Exception("User not found!");
+ }
+
+ @Override
+ public void reloadConfig()
+ {
+ loadAllUsersAsync(ess);
+ }
+
+ public void removeUser(final String name)
+ {
+ keys.remove(name.toLowerCase(Locale.ENGLISH));
+ users.invalidate(name.toLowerCase(Locale.ENGLISH));
+ }
+
+ public Set<String> getAllUniqueUsers()
+ {
+ return Collections.unmodifiableSet(keys);
+ }
+
+ public int getUniqueUsers()
+ {
+ return keys.size();
+ }
+
+ public File getUserFile(final String name)
+ {
+ final File userFolder = new File(ess.getDataFolder(), "userdata");
+ return new File(userFolder, Util.sanitizeFileName(name) + ".yml");
+ }
+}
diff --git a/Essentials/src/com/earth2me/essentials/userdata/User.java b/Essentials/src/com/earth2me/essentials/userdata/User.java
deleted file mode 100644
index 232e0b95e..000000000
--- a/Essentials/src/com/earth2me/essentials/userdata/User.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.earth2me.essentials.userdata;
-
-import com.earth2me.essentials.storage.YamlStorageReader;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import lombok.Cleanup;
-
-// this is a prototype for locking userdata
-public class User
-{
- UserData data = new UserData();
- ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
-
- public void loadUserData()
- {
- data = new YamlStorageReader(null).load(UserData.class);
- }
-
- public void aquireReadLock()
- {
- rwl.readLock().lock();
- }
-
- public void aquireWriteLock()
- {
- while (rwl.getReadHoldCount() > 0)
- {
- rwl.readLock().unlock();
- }
- rwl.writeLock().lock();
- rwl.readLock().lock();
- }
-
- public void close()
- {
- if (rwl.isWriteLockedByCurrentThread())
- {
- scheduleSaving();
- rwl.writeLock().unlock();
- }
- while (rwl.getReadHoldCount() > 0)
- {
- rwl.readLock().unlock();
- }
- }
-
- public void example()
- {
- // Cleanup will call close at the end of the function
- @Cleanup
- final User user = this;
-
- // read lock allows to read data from the user
- user.aquireReadLock();
- double i = user.data.getMoney();
-
- // write lock allows only one thread to modify the data
- user.aquireWriteLock();
- user.data.setMoney(10 + user.data.getMoney());
- }
-
- private void scheduleSaving()
- {
- System.out.println("Schedule saving...");
- }
-}
diff --git a/Essentials/test/com/earth2me/essentials/StorageTest.java b/Essentials/test/com/earth2me/essentials/StorageTest.java
index e6850ce91..d57d88542 100644
--- a/Essentials/test/com/earth2me/essentials/StorageTest.java
+++ b/Essentials/test/com/earth2me/essentials/StorageTest.java
@@ -80,11 +80,11 @@ public class StorageTest extends TestCase
ext.start();
final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
final Reader reader = new InputStreamReader(bais);
- final com.earth2me.essentials.userdata.UserData userdata = new YamlStorageReader(reader).load(com.earth2me.essentials.userdata.UserData.class);
+ final com.earth2me.essentials.user.UserData userdata = new YamlStorageReader(reader).load(com.earth2me.essentials.user.UserData.class);
ext.mark("load empty user");
final ByteArrayInputStream bais3 = new ByteArrayInputStream(new byte[0]);
final Reader reader3 = new InputStreamReader(bais3);
- final com.earth2me.essentials.userdata.UserData userdata3 = new YamlStorageReader(reader3).load(com.earth2me.essentials.userdata.UserData.class);
+ final com.earth2me.essentials.user.UserData userdata3 = new YamlStorageReader(reader3).load(com.earth2me.essentials.user.UserData.class);
ext.mark("load empty user (class cached)");
for (int j = 0; j < 10000; j++)
@@ -107,16 +107,16 @@ public class StorageTest extends TestCase
ext.mark("debug output");
final ByteArrayInputStream bais2 = new ByteArrayInputStream(written);
final Reader reader2 = new InputStreamReader(bais2);
- final com.earth2me.essentials.userdata.UserData userdata2 = new YamlStorageReader(reader2).load(com.earth2me.essentials.userdata.UserData.class);
+ final com.earth2me.essentials.user.UserData userdata2 = new YamlStorageReader(reader2).load(com.earth2me.essentials.user.UserData.class);
ext.mark("reload file");
final ByteArrayInputStream bais4 = new ByteArrayInputStream(written);
final Reader reader4 = new InputStreamReader(bais4);
- final com.earth2me.essentials.userdata.UserData userdata4 = new YamlStorageReader(reader4).load(com.earth2me.essentials.userdata.UserData.class);
+ final com.earth2me.essentials.user.UserData userdata4 = new YamlStorageReader(reader4).load(com.earth2me.essentials.user.UserData.class);
ext.mark("reload file (cached)");
System.out.println(userdata.toString());
System.out.println(userdata2.toString());
System.out.println(ext.end());
- com.earth2me.essentials.userdata.User test = new com.earth2me.essentials.userdata.User();
+ com.earth2me.essentials.user.User test = new com.earth2me.essentials.user.User(null, ess);
test.example();
}