summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java141
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/IStorageObjectHolder.java17
-rw-r--r--Essentials/src/com/earth2me/essentials/user/IOfflineUser.java4
-rw-r--r--Essentials/src/com/earth2me/essentials/user/IUserData.java13
-rw-r--r--Essentials/src/com/earth2me/essentials/user/User.java170
-rw-r--r--Essentials/src/com/earth2me/essentials/user/UserBase.java19
-rw-r--r--EssentialsSpawn/src/com/earth2me/essentials/spawn/SpawnStorage.java111
7 files changed, 315 insertions, 160 deletions
diff --git a/Essentials/src/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java b/Essentials/src/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java
new file mode 100644
index 000000000..bf3301e41
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java
@@ -0,0 +1,141 @@
+package com.earth2me.essentials.storage;
+
+import com.earth2me.essentials.IConf;
+import com.earth2me.essentials.IEssentials;
+import java.io.File;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import org.bukkit.Bukkit;
+
+
+public abstract class AsyncStorageObjectHolder<T extends StorageObject> implements IConf, IStorageObjectHolder<T>
+{
+ private transient T data;
+ private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ private final transient Class<T> clazz;
+ protected final transient IEssentials ess;
+
+ public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz)
+ {
+ this.ess = ess;
+ this.clazz = clazz;
+ try
+ {
+ this.data = clazz.newInstance();
+ }
+ catch (Exception ex)
+ {
+ Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+
+ public T getData()
+ {
+ return data;
+ }
+
+ public void acquireReadLock()
+ {
+ rwl.readLock().lock();
+ }
+
+ public void acquireWriteLock()
+ {
+ while (rwl.getReadHoldCount() > 0)
+ {
+ rwl.readLock().unlock();
+ }
+ rwl.writeLock().lock();
+ rwl.readLock().lock();
+ }
+
+ public void close()
+ {
+ unlock();
+ }
+
+ public void unlock()
+ {
+ if (rwl.isWriteLockedByCurrentThread())
+ {
+ rwl.writeLock().unlock();
+ new StorageObjectDataWriter();
+ }
+ while (rwl.getReadHoldCount() > 0)
+ {
+ rwl.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void reloadConfig()
+ {
+ new StorageObjectDataReader();
+ }
+
+ public abstract File getStorageFile();
+
+
+ private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter
+ {
+ public StorageObjectDataWriter()
+ {
+ super(ess, getStorageFile());
+ }
+
+ @Override
+ public StorageObject getObject()
+ {
+ acquireReadLock();
+ return getData();
+ }
+
+ @Override
+ public void onFinish()
+ {
+ unlock();
+ }
+ }
+
+
+ private class StorageObjectDataReader extends AbstractDelayedYamlFileReader<T>
+ {
+ public StorageObjectDataReader()
+ {
+ super(ess, getStorageFile(), clazz);
+ }
+
+ @Override
+ public void onStart()
+ {
+ rwl.writeLock().lock();
+ }
+
+ @Override
+ public void onSuccess(final T object)
+ {
+ if (object != null)
+ {
+ data = object;
+ }
+ rwl.writeLock().unlock();
+ }
+
+ @Override
+ public void onException()
+ {
+ if (data == null)
+ {
+ try
+ {
+ data = clazz.newInstance();
+ }
+ catch (Exception ex)
+ {
+ Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+ rwl.writeLock().unlock();
+ }
+ }
+}
diff --git a/Essentials/src/com/earth2me/essentials/storage/IStorageObjectHolder.java b/Essentials/src/com/earth2me/essentials/storage/IStorageObjectHolder.java
new file mode 100644
index 000000000..f48e54002
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/IStorageObjectHolder.java
@@ -0,0 +1,17 @@
+package com.earth2me.essentials.storage;
+
+import com.earth2me.essentials.user.UserData;
+
+
+public interface IStorageObjectHolder<T extends StorageObject>
+{
+ T getData();
+
+ void acquireReadLock();
+
+ void acquireWriteLock();
+
+ void close();
+
+ void unlock();
+}
diff --git a/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java b/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java
index 4ff54b37b..d6266df49 100644
--- a/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java
+++ b/Essentials/src/com/earth2me/essentials/user/IOfflineUser.java
@@ -1,7 +1,9 @@
package com.earth2me.essentials.user;
+import com.earth2me.essentials.storage.IStorageObjectHolder;
-public interface IOfflineUser extends IUserData, IOfflinePlayer
+
+public interface IOfflineUser extends IStorageObjectHolder<UserData>, IOfflinePlayer
{
}
diff --git a/Essentials/src/com/earth2me/essentials/user/IUserData.java b/Essentials/src/com/earth2me/essentials/user/IUserData.java
deleted file mode 100644
index dcaeaf1a7..000000000
--- a/Essentials/src/com/earth2me/essentials/user/IUserData.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.earth2me.essentials.user;
-
-
-public interface IUserData
-{
- UserData getData();
-
- void aquireReadLock();
-
- void aquireWriteLock();
-
- void close();
-}
diff --git a/Essentials/src/com/earth2me/essentials/user/User.java b/Essentials/src/com/earth2me/essentials/user/User.java
index 55740134f..89e664252 100644
--- a/Essentials/src/com/earth2me/essentials/user/User.java
+++ b/Essentials/src/com/earth2me/essentials/user/User.java
@@ -1,19 +1,16 @@
package com.earth2me.essentials.user;
import com.earth2me.essentials.IEssentials;
-import com.earth2me.essentials.storage.AbstractDelayedYamlFileWriter;
-import com.earth2me.essentials.storage.StorageObject;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import com.earth2me.essentials.IUser;
+import com.earth2me.essentials.commands.IEssentialsCommand;
import lombok.Cleanup;
+import org.bukkit.Location;
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 class User extends UserBase implements IUser
+{
public User(final Player base, final IEssentials ess)
{
super(base, ess);
@@ -24,81 +21,158 @@ public class User extends UserBase implements IOfflineUser
super(offlinePlayer, ess);
}
+ 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.acquireReadLock();
+ final double money = user.getData().getMoney();
+
+ // write lock allows only one thread to modify the data
+ user.acquireWriteLock();
+ user.getData().setMoney(10 + money);
+ }
+
+ @Override
+ public long getLastTeleportTimestamp()
+ {
+ acquireReadLock();
+ try
+ {
+ return getData().getTimestamps().get("lastteleport");
+ }
+ finally
+ {
+ unlock();
+ }
+ }
+
+ @Override
+ public boolean isAuthorized(String node)
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
@Override
- public UserData getData()
+ public boolean isAuthorized(IEssentialsCommand cmd)
{
- return data;
+ throw new UnsupportedOperationException("Not supported yet.");
}
@Override
- public void aquireReadLock()
+ public boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix)
{
- rwl.readLock().lock();
+ throw new UnsupportedOperationException("Not supported yet.");
}
@Override
- public void aquireWriteLock()
+ public void setLastTeleportTimestamp(long time)
{
- while (rwl.getReadHoldCount() > 0)
+ acquireWriteLock();
+ try
{
- rwl.readLock().unlock();
+ getData().getTimestamps().put("lastteleport", time);
+ }
+ finally
+ {
+ unlock();
}
- rwl.writeLock().lock();
- rwl.readLock().lock();
}
@Override
- public void close()
+ public Location getLastLocation()
{
- if (rwl.isWriteLockedByCurrentThread())
+ acquireReadLock();
+ try
{
- rwl.writeLock().unlock();
- scheduleSaving();
+ return getData().getLastLocation();
}
- while (rwl.getReadHoldCount() > 0)
+ finally
{
- rwl.readLock().unlock();
+ unlock();
}
}
- public void example()
+ @Override
+ public double getMoney()
{
- // 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);
+ acquireReadLock();
+ try
+ {
+ return getData().getMoney();
+ }
+ finally
+ {
+ unlock();
+ }
}
- private void scheduleSaving()
+ @Override
+ public void takeMoney(double value)
{
- new UserDataWriter();
+ acquireWriteLock();
+ try
+ {
+ getData().setMoney(getData().getMoney() - value);
+ }
+ finally
+ {
+ unlock();
+ }
}
- private class UserDataWriter extends AbstractDelayedYamlFileWriter
+ @Override
+ public void giveMoney(double value)
{
- public UserDataWriter()
+ acquireWriteLock();
+ try
{
- super(ess, ess.getUserMap().getUserFile(User.this.getName()));
+ getData().setMoney(getData().getMoney() + value);
}
-
- @Override
- public StorageObject getObject()
+ finally
{
- aquireReadLock();
- return getData();
+ unlock();
}
+ }
+
+ @Override
+ public String getGroup()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
- @Override
- public void onFinish()
+ @Override
+ public void setLastLocation()
+ {
+ acquireWriteLock();
+ try
{
- close();
+ getData().setLastLocation(base.getLocation());
}
+ finally
+ {
+ unlock();
+ }
+ }
+
+ @Override
+ public Location getHome(String name) throws Exception
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Location getHome(Location loc) throws Exception
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isHidden()
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
}
}
diff --git a/Essentials/src/com/earth2me/essentials/user/UserBase.java b/Essentials/src/com/earth2me/essentials/user/UserBase.java
index cc071817e..c215ebee9 100644
--- a/Essentials/src/com/earth2me/essentials/user/UserBase.java
+++ b/Essentials/src/com/earth2me/essentials/user/UserBase.java
@@ -2,6 +2,8 @@ package com.earth2me.essentials.user;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.craftbukkit.OfflineBedLocation;
+import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
+import java.io.File;
import lombok.Delegate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -16,7 +18,7 @@ import org.bukkit.permissions.ServerOperator;
import org.bukkit.OfflinePlayer;
-public class UserBase implements Player, IOfflinePlayer
+public class UserBase extends AsyncStorageObjectHolder<UserData> implements Player, IOfflineUser
{
@Delegate(types =
@@ -27,18 +29,19 @@ public class UserBase implements Player, IOfflinePlayer
},excludes=IOfflinePlayer.class)
protected Player base;
protected transient OfflinePlayer offlinePlayer;
- protected final transient IEssentials ess;
public UserBase(final Player base, final IEssentials ess)
{
+ super(ess, UserData.class);
this.base = base;
- this.ess = ess;
+ reloadConfig();
}
public UserBase(final OfflinePlayer offlinePlayer, final IEssentials ess)
{
+ super(ess, UserData.class);
this.offlinePlayer = offlinePlayer;
- this.ess = ess;
+ reloadConfig();
}
public final Player getBase()
@@ -110,6 +113,10 @@ public class UserBase implements Player, IOfflinePlayer
offlinePlayer.setBanned(bln);
}
}
-
-
+
+ @Override
+ public File getStorageFile()
+ {
+ return ess.getUserMap().getUserFile(getName());
+ }
}
diff --git a/EssentialsSpawn/src/com/earth2me/essentials/spawn/SpawnStorage.java b/EssentialsSpawn/src/com/earth2me/essentials/spawn/SpawnStorage.java
index 02fb26c9b..088ee9052 100644
--- a/EssentialsSpawn/src/com/earth2me/essentials/spawn/SpawnStorage.java
+++ b/EssentialsSpawn/src/com/earth2me/essentials/spawn/SpawnStorage.java
@@ -1,57 +1,46 @@
package com.earth2me.essentials.spawn;
-import com.earth2me.essentials.IConf;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.IEssentialsModule;
import com.earth2me.essentials.settings.Spawns;
-import com.earth2me.essentials.storage.AbstractDelayedYamlFileReader;
-import com.earth2me.essentials.storage.AbstractDelayedYamlFileWriter;
-import com.earth2me.essentials.storage.ObjectLoadException;
-import com.earth2me.essentials.storage.StorageObject;
+import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
import java.io.File;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
-public class SpawnStorage implements IConf, IEssentialsModule
+public class SpawnStorage extends AsyncStorageObjectHolder<Spawns> implements IEssentialsModule
{
- private transient Spawns spawns;
- private final transient IEssentials ess;
- private final transient File spawnfile;
- private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
-
public SpawnStorage(final IEssentials ess)
{
- this.ess = ess;
- spawnfile = new File(ess.getDataFolder(), "spawn.yml");
- new SpawnReader();
+ super(ess, Spawns.class);
+ reloadConfig();
+ }
+
+ @Override
+ public File getStorageFile()
+ {
+ return new File(ess.getDataFolder(), "spawn.yml");
}
public void setSpawn(final Location loc, final String group)
{
- rwl.writeLock().lock();
+ acquireWriteLock();
try
{
- if (spawns == null)
+ if (getData().getSpawns() == null)
{
- spawns = new Spawns();
+ getData().setSpawns(new HashMap<String, Location>());
}
- if (spawns.getSpawns() == null)
- {
- spawns.setSpawns(new HashMap<String, Location>());
- }
- spawns.getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
+ getData().getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
}
finally
{
- rwl.writeLock().unlock();
+ unlock();
}
- new SpawnWriter();
if ("default".equalsIgnoreCase(group))
{
@@ -61,14 +50,14 @@ public class SpawnStorage implements IConf, IEssentialsModule
public Location getSpawn(final String group)
{
- rwl.readLock().lock();
+ acquireReadLock();
try
{
- if (spawns == null || spawns.getSpawns() == null || group == null)
+ if (getData().getSpawns() == null || group == null)
{
return getWorldSpawn();
}
- final Map<String, Location> spawnMap = spawns.getSpawns();
+ final Map<String, Location> spawnMap = getData().getSpawns();
String groupName = group.toLowerCase(Locale.ENGLISH);
if (!spawnMap.containsKey(groupName))
{
@@ -82,7 +71,7 @@ public class SpawnStorage implements IConf, IEssentialsModule
}
finally
{
- rwl.readLock().unlock();
+ unlock();
}
}
@@ -98,66 +87,4 @@ public class SpawnStorage implements IConf, IEssentialsModule
}
return ess.getServer().getWorlds().get(0).getSpawnLocation();
}
-
- @Override
- public void reloadConfig()
- {
- new SpawnReader();
- }
-
-
- private class SpawnWriter extends AbstractDelayedYamlFileWriter
- {
- public SpawnWriter()
- {
- super(ess, spawnfile);
- }
-
- @Override
- public StorageObject getObject()
- {
- rwl.readLock().lock();
- return spawns;
- }
-
- @Override
- public void onFinish()
- {
- rwl.readLock().unlock();
- }
- }
-
-
- private class SpawnReader extends AbstractDelayedYamlFileReader<Spawns>
- {
- public SpawnReader()
- {
- super(ess, spawnfile, Spawns.class);
- }
-
- @Override
- public void onStart()
- {
- rwl.writeLock().lock();
- }
-
- @Override
- public void onSuccess(final Spawns object)
- {
- if (object != null)
- {
- spawns = object;
- }
- rwl.writeLock().unlock();
- }
-
- @Override
- public void onException()
- {
- if (spawns == null) {
- spawns = new Spawns();
- }
- rwl.writeLock().unlock();
- }
- }
}