Internal entities
This commit is contained in:
parent
fe81648eb7
commit
5c416c3a1d
@ -3,6 +3,7 @@ package com.massivecraft.massivecore;
|
|||||||
import com.massivecraft.massivecore.adapter.AdapterBackstringSet;
|
import com.massivecraft.massivecore.adapter.AdapterBackstringSet;
|
||||||
import com.massivecraft.massivecore.adapter.AdapterBannerPatterns;
|
import com.massivecraft.massivecore.adapter.AdapterBannerPatterns;
|
||||||
import com.massivecraft.massivecore.adapter.AdapterEntry;
|
import com.massivecraft.massivecore.adapter.AdapterEntry;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterEntityInternalMap;
|
||||||
import com.massivecraft.massivecore.adapter.AdapterInventory;
|
import com.massivecraft.massivecore.adapter.AdapterInventory;
|
||||||
import com.massivecraft.massivecore.adapter.AdapterItemStack;
|
import com.massivecraft.massivecore.adapter.AdapterItemStack;
|
||||||
import com.massivecraft.massivecore.adapter.AdapterJsonElement;
|
import com.massivecraft.massivecore.adapter.AdapterJsonElement;
|
||||||
@ -38,6 +39,7 @@ import com.massivecraft.massivecore.nms.NmsItemStackCreate17R4P;
|
|||||||
import com.massivecraft.massivecore.ps.PS;
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
import com.massivecraft.massivecore.ps.PSAdapter;
|
import com.massivecraft.massivecore.ps.PSAdapter;
|
||||||
import com.massivecraft.massivecore.store.Coll;
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
import com.massivecraft.massivecore.store.ModificationPollerLocal;
|
import com.massivecraft.massivecore.store.ModificationPollerLocal;
|
||||||
import com.massivecraft.massivecore.store.ModificationPollerRemote;
|
import com.massivecraft.massivecore.store.ModificationPollerRemote;
|
||||||
import com.massivecraft.massivecore.util.BoardUtil;
|
import com.massivecraft.massivecore.util.BoardUtil;
|
||||||
@ -165,6 +167,9 @@ public class MassiveCore extends MassivePlugin
|
|||||||
ret.registerTypeAdapter(Inventory.class, AdapterInventory.get());
|
ret.registerTypeAdapter(Inventory.class, AdapterInventory.get());
|
||||||
ret.registerTypeAdapter(PlayerInventory.class, AdapterPlayerInventory.get());
|
ret.registerTypeAdapter(PlayerInventory.class, AdapterPlayerInventory.get());
|
||||||
|
|
||||||
|
// Storage
|
||||||
|
ret.registerTypeAdapter(EntityInternalMap.class, AdapterEntityInternalMap.get());
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternal;
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
|
import com.massivecraft.massivecore.xlib.gson.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class AdapterEntityInternalMap implements JsonDeserializer<EntityInternalMap<?>>, JsonSerializer<EntityInternalMap<?>>
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterEntityInternalMap i = new AdapterEntityInternalMap();
|
||||||
|
public static AdapterEntityInternalMap get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(EntityInternalMap<?> src, Type type, JsonSerializationContext context)
|
||||||
|
{
|
||||||
|
// NULL
|
||||||
|
if (src == null) return JsonNull.INSTANCE;
|
||||||
|
|
||||||
|
// Get value
|
||||||
|
Map<String, ?> contents = src.getIdToEntity();
|
||||||
|
|
||||||
|
// Create ret
|
||||||
|
JsonElement ret = context.serialize(contents);
|
||||||
|
|
||||||
|
// Return Ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityInternalMap<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException
|
||||||
|
{
|
||||||
|
// NULL
|
||||||
|
if (json == null) return null;
|
||||||
|
if (json instanceof JsonNull) return null;
|
||||||
|
|
||||||
|
// Get type
|
||||||
|
Class<? extends EntityInternal> entityType = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||||
|
|
||||||
|
// Create ret
|
||||||
|
EntityInternalMap ret = new EntityInternalMap<>(entityType);
|
||||||
|
|
||||||
|
// Fill ret
|
||||||
|
JsonObject jsonObject = (JsonObject) json;
|
||||||
|
for (Entry<String, JsonElement> entry : jsonObject.entrySet())
|
||||||
|
{
|
||||||
|
String id = entry.getKey();
|
||||||
|
JsonElement value = entry.getValue();
|
||||||
|
|
||||||
|
EntityInternal obj = context.deserialize(value, entityType);
|
||||||
|
|
||||||
|
ret.getIdToEntityRaw().put(id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,12 +3,9 @@ package com.massivecraft.massivecore.store;
|
|||||||
import com.massivecraft.massivecore.MassiveCore;
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
import com.massivecraft.massivecore.MassiveCoreMConf;
|
import com.massivecraft.massivecore.MassiveCoreMConf;
|
||||||
import com.massivecraft.massivecore.MassivePlugin;
|
import com.massivecraft.massivecore.MassivePlugin;
|
||||||
import com.massivecraft.massivecore.Named;
|
|
||||||
import com.massivecraft.massivecore.collections.MassiveList;
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
import com.massivecraft.massivecore.comparator.ComparatorNaturalOrder;
|
import com.massivecraft.massivecore.comparator.ComparatorNaturalOrder;
|
||||||
import com.massivecraft.massivecore.mixin.MixinModification;
|
import com.massivecraft.massivecore.mixin.MixinModification;
|
||||||
import com.massivecraft.massivecore.predicate.Predicate;
|
|
||||||
import com.massivecraft.massivecore.predicate.PredicateEqualsIgnoreCase;
|
|
||||||
import com.massivecraft.massivecore.store.migrator.MigratorUtil;
|
import com.massivecraft.massivecore.store.migrator.MigratorUtil;
|
||||||
import com.massivecraft.massivecore.util.ReflectionUtil;
|
import com.massivecraft.massivecore.util.ReflectionUtil;
|
||||||
import com.massivecraft.massivecore.util.Txt;
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
@ -131,249 +128,20 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
// Loaded
|
// Loaded
|
||||||
protected Map<String, E> id2entity;
|
protected Map<String, E> idToEntity;
|
||||||
|
|
||||||
@Override
|
@Override public Map<String, E> getIdToEntityRaw() { return this.idToEntity; }
|
||||||
public String fixId(Object oid)
|
|
||||||
{
|
|
||||||
if (oid == null) return null;
|
|
||||||
|
|
||||||
String ret = null;
|
|
||||||
if (oid instanceof String) ret = (String) oid;
|
|
||||||
else if (oid.getClass() == this.getEntityClass()) ret = ((Entity<?>) oid).getId();
|
|
||||||
if (ret == null) return null;
|
|
||||||
|
|
||||||
return this.isLowercasing() ? ret.toLowerCase() : ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Map<String, E> getId2entity() { return Collections.unmodifiableMap(this.id2entity); }
|
|
||||||
@Override
|
|
||||||
public E getFixed(String id, boolean creative)
|
|
||||||
{
|
|
||||||
return this.getFixed(id, creative, true);
|
|
||||||
}
|
|
||||||
protected E getFixed(String id, boolean creative, boolean noteModification)
|
|
||||||
{
|
|
||||||
if (id == null) return null;
|
|
||||||
E ret = this.id2entity.get(id);
|
|
||||||
if (ret != null) return ret;
|
|
||||||
if ( ! creative) return null;
|
|
||||||
return this.create(id, noteModification);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Collection<String> getIds() { return Collections.unmodifiableCollection(this.id2entity.keySet()); }
|
|
||||||
@Override public Collection<String> getIdsRemote() { return this.getDb().getIds(this); }
|
@Override public Collection<String> getIdsRemote() { return this.getDb().getIds(this); }
|
||||||
@Override
|
|
||||||
public boolean containsIdFixed(String id)
|
|
||||||
{
|
|
||||||
if (id == null) return false;
|
|
||||||
return this.id2entity.containsKey(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsEntity(Object entity)
|
|
||||||
{
|
|
||||||
return this.id2entity.containsValue(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Collection<E> getAll()
|
|
||||||
{
|
|
||||||
return Collections.unmodifiableCollection(this.id2entity.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// BEHAVIOR
|
// BEHAVIOR
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
protected boolean creative;
|
|
||||||
@Override public boolean isCreative() { return this.creative; }
|
|
||||||
@Override public void setCreative(boolean creative) { this.creative = creative; }
|
|
||||||
|
|
||||||
// "Lowercasing" means that the ids are always converted to lower case when fixed.
|
|
||||||
// This is highly recommended for sender colls.
|
|
||||||
// The senderIds are case insensitive by nature and some times you simply can't know the correct casing.
|
|
||||||
protected boolean lowercasing;
|
|
||||||
@Override public boolean isLowercasing() { return this.lowercasing; }
|
|
||||||
@Override public void setLowercasing(boolean lowercasing) { this.lowercasing = lowercasing; }
|
|
||||||
|
|
||||||
// Should that instance be saved or not?
|
|
||||||
// If it is default it should not be saved.
|
|
||||||
@Override
|
|
||||||
public boolean isDefault(E entity)
|
|
||||||
{
|
|
||||||
return entity.isDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
// What entity version do we want?
|
// What entity version do we want?
|
||||||
protected final int entityTargetVersion;
|
protected final int entityTargetVersion;
|
||||||
@Override public int getEntityTargetVersion() { return this.entityTargetVersion; }
|
@Override public int getEntityTargetVersion() { return this.entityTargetVersion; }
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// COPY AND CREATE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void copy(E efrom, E eto)
|
|
||||||
{
|
|
||||||
if (efrom == null) throw new NullPointerException("efrom");
|
|
||||||
if (eto == null) throw new NullPointerException("eto");
|
|
||||||
|
|
||||||
eto.load(efrom);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This simply creates and returns a new instance
|
|
||||||
// It does not detach/attach or anything. Just creates a new instance.
|
|
||||||
@Override
|
|
||||||
public E createNewInstance()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return this.getEntityClass().newInstance();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new instance with the requested id
|
|
||||||
@Override
|
|
||||||
public synchronized E create(Object oid)
|
|
||||||
{
|
|
||||||
return this.create(oid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized E create(Object oid, boolean noteModification)
|
|
||||||
{
|
|
||||||
E entity = this.createNewInstance();
|
|
||||||
if (this.attach(entity, oid, noteModification) == null) return null;
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// ATTACH AND DETACH
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String attach(E entity, Object oid)
|
|
||||||
{
|
|
||||||
return this.attach(entity, oid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized String attach(E entity, Object oid, boolean noteModification)
|
|
||||||
{
|
|
||||||
// Check entity
|
|
||||||
if (entity == null) return null;
|
|
||||||
if (entity.attached()) return entity.getId();
|
|
||||||
|
|
||||||
String id;
|
|
||||||
// Check/Fix id
|
|
||||||
if (oid == null)
|
|
||||||
{
|
|
||||||
id = MStore.createId();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = this.fixId(oid);
|
|
||||||
if (id == null) return null;
|
|
||||||
if (this.id2entity.containsKey(id)) return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRE
|
|
||||||
this.preAttach(entity, id);
|
|
||||||
|
|
||||||
// Add entity reference info
|
|
||||||
entity.setColl(this);
|
|
||||||
entity.setId(id);
|
|
||||||
|
|
||||||
// Attach
|
|
||||||
this.id2entity.put(id, entity);
|
|
||||||
|
|
||||||
// Identify Modification
|
|
||||||
if (noteModification)
|
|
||||||
{
|
|
||||||
this.identifiedModifications.put(id, Modification.LOCAL_ATTACH);
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST
|
|
||||||
this.postAttach(entity, id);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E detachEntity(E entity)
|
|
||||||
{
|
|
||||||
if (entity == null) throw new NullPointerException("entity");
|
|
||||||
|
|
||||||
String id = entity.getId();
|
|
||||||
if (id == null)
|
|
||||||
{
|
|
||||||
// It seems the entity is already detached.
|
|
||||||
// In such case just silently return it.
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.detachFixed(entity, id);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E detachIdFixed(String id)
|
|
||||||
{
|
|
||||||
if (id == null) throw new NullPointerException("id");
|
|
||||||
|
|
||||||
E e = this.get(id, false);
|
|
||||||
if (e == null) return null;
|
|
||||||
|
|
||||||
this.detachFixed(e, id);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void detachFixed(E entity, String id)
|
|
||||||
{
|
|
||||||
if (entity == null) throw new NullPointerException("entity");
|
|
||||||
if (id == null) throw new NullPointerException("id");
|
|
||||||
|
|
||||||
// PRE
|
|
||||||
this.preDetach(entity, id);
|
|
||||||
|
|
||||||
// Remove @ local
|
|
||||||
this.removeAtLocalFixed(id);
|
|
||||||
|
|
||||||
// Identify Modification
|
|
||||||
this.identifiedModifications.put(id, Modification.LOCAL_DETACH);
|
|
||||||
|
|
||||||
// POST
|
|
||||||
this.postDetach(entity, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preAttach(E entity, String id)
|
|
||||||
{
|
|
||||||
entity.preAttach(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postAttach(E entity, String id)
|
|
||||||
{
|
|
||||||
entity.postAttach(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preDetach(E entity, String id)
|
|
||||||
{
|
|
||||||
entity.preDetach(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postDetach(E entity, String id)
|
|
||||||
{
|
|
||||||
entity.postDetach(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// IDENTIFIED MODIFICATIONS
|
// IDENTIFIED MODIFICATIONS
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
@ -438,12 +206,12 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
|
|
||||||
this.removeIdentifiedModificationFixed(id);
|
this.removeIdentifiedModificationFixed(id);
|
||||||
|
|
||||||
E entity = this.id2entity.remove(id);
|
E entity = this.idToEntity.remove(id);
|
||||||
if (entity == null) return null;
|
if (entity == null) return null;
|
||||||
entity.clearSyncLogFields();
|
entity.clearSyncLogFields();
|
||||||
|
|
||||||
// Remove entity reference info
|
// Remove entity reference info
|
||||||
entity.setColl(null);
|
entity.setContainer(null);
|
||||||
entity.setId(null);
|
entity.setId(null);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
@ -467,7 +235,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
|
|
||||||
this.removeIdentifiedModificationFixed(id);
|
this.removeIdentifiedModificationFixed(id);
|
||||||
|
|
||||||
E entity = this.id2entity.get(id);
|
E entity = this.idToEntity.get(id);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
entity.clearSyncLogFields();
|
entity.clearSyncLogFields();
|
||||||
|
|
||||||
@ -623,7 +391,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
// }
|
// }
|
||||||
if (current != null && current.hasTopPriority()) return current;
|
if (current != null && current.hasTopPriority()) return current;
|
||||||
|
|
||||||
E localEntity = this.id2entity.get(id);
|
E localEntity = this.idToEntity.get(id);
|
||||||
if (remoteMtime == null && remote)
|
if (remoteMtime == null && remote)
|
||||||
{
|
{
|
||||||
// TODO: This is slow
|
// TODO: This is slow
|
||||||
@ -713,7 +481,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
Modification actualModification = this.examineIdFixed(id, remoteMtime, true, true);
|
Modification actualModification = this.examineIdFixed(id, remoteMtime, true, true);
|
||||||
if (MassiveCoreMConf.get().warnOnLocalAlter && modification == Modification.UNKNOWN_LOG && actualModification.isModified())
|
if (MassiveCoreMConf.get().warnOnLocalAlter && modification == Modification.UNKNOWN_LOG && actualModification.isModified())
|
||||||
{
|
{
|
||||||
E entity = this.id2entity.get(id);
|
E entity = this.idToEntity.get(id);
|
||||||
if (entity != null)
|
if (entity != null)
|
||||||
{
|
{
|
||||||
this.logModification(entity, actualModification);
|
this.logModification(entity, actualModification);
|
||||||
@ -831,10 +599,10 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
Map<String, Long> id2RemoteMtime = this.getDb().getId2mtime(this);
|
Map<String, Long> id2RemoteMtime = this.getDb().getId2mtime(this);
|
||||||
|
|
||||||
// Java 8
|
// Java 8
|
||||||
//this.id2entity.keySet().forEach(id -> id2RemoteMtime.putIfAbsent(id, 0));
|
//this.idToEntity.keySet().forEach(id -> id2RemoteMtime.putIfAbsent(id, 0));
|
||||||
|
|
||||||
// Java 8 >
|
// Java 8 >
|
||||||
for (String id : this.id2entity.keySet())
|
for (String id : this.idToEntity.keySet())
|
||||||
{
|
{
|
||||||
if (id2RemoteMtime.containsKey(id)) continue;
|
if (id2RemoteMtime.containsKey(id)) continue;
|
||||||
id2RemoteMtime.put(id, 0L);
|
id2RemoteMtime.put(id, 0L);
|
||||||
@ -859,7 +627,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
@Override
|
@Override
|
||||||
public void identifyLocalModifications(Modification veto)
|
public void identifyLocalModifications(Modification veto)
|
||||||
{
|
{
|
||||||
for (String id : id2entity.keySet())
|
for (String id : idToEntity.keySet())
|
||||||
{
|
{
|
||||||
this.identifyLocalModificationFixed(id, veto);
|
this.identifyLocalModificationFixed(id, veto);
|
||||||
}
|
}
|
||||||
@ -883,10 +651,10 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
//Note: We must also check local ids, in case of remote detach.
|
//Note: We must also check local ids, in case of remote detach.
|
||||||
|
|
||||||
// Java 8
|
// Java 8
|
||||||
//this.id2entity.keySet().forEach(id -> id2RemoteMtime.putIfAbsent(id, 0));
|
//this.idToEntity.keySet().forEach(id -> id2RemoteMtime.putIfAbsent(id, 0));
|
||||||
|
|
||||||
// Java 8 >
|
// Java 8 >
|
||||||
for (String id : this.id2entity.keySet())
|
for (String id : this.idToEntity.keySet())
|
||||||
{
|
{
|
||||||
if (id2RemoteMtime.containsKey(id)) continue;
|
if (id2RemoteMtime.containsKey(id)) continue;
|
||||||
id2RemoteMtime.put(id, 0L);
|
id2RemoteMtime.put(id, 0L);
|
||||||
@ -996,7 +764,7 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
this.collDriverObject = db.createCollDriverObject(this);
|
this.collDriverObject = db.createCollDriverObject(this);
|
||||||
|
|
||||||
// Collections
|
// Collections
|
||||||
this.id2entity = new ConcurrentHashMap<>();
|
this.idToEntity = new ConcurrentHashMap<>();
|
||||||
this.identifiedModifications = new ConcurrentHashMap<>();
|
this.identifiedModifications = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
// Migration
|
// Migration
|
||||||
@ -1075,6 +843,12 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
return MStore.getDb();
|
return MStore.getDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coll<E> getColl()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// ACTIVE
|
// ACTIVE
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
@ -1085,6 +859,8 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
return name2instance.containsKey(this.getName());
|
return name2instance.containsKey(this.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public boolean isLive() { return this.isActive(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setActive(boolean active)
|
public void setActive(boolean active)
|
||||||
{
|
{
|
||||||
@ -1141,31 +917,4 @@ public class Coll<E extends Entity<E>> extends CollAbstract<E>
|
|||||||
this.setActive(plugin != null);
|
this.setActive(plugin != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// NAME UTILITIES
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
public E getByName(String name)
|
|
||||||
{
|
|
||||||
if (name == null) throw new NullPointerException("name");
|
|
||||||
|
|
||||||
Predicate<String> predicate = PredicateEqualsIgnoreCase.get(name);
|
|
||||||
for (E entity : this.getAll())
|
|
||||||
{
|
|
||||||
if (entity == null) continue;
|
|
||||||
|
|
||||||
if ( ! (entity instanceof Named)) continue;
|
|
||||||
Named named = (Named)entity;
|
|
||||||
|
|
||||||
if (predicate.apply(named.getName())) return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNameTaken(String str)
|
|
||||||
{
|
|
||||||
return this.getByName(str) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
package com.massivecraft.massivecore.store;
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
import com.massivecraft.massivecore.predicate.Predicate;
|
|
||||||
import com.massivecraft.massivecore.util.MUtil;
|
|
||||||
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
|
||||||
public abstract class CollAbstract<E extends Entity<E>> implements CollInterface<E>
|
public abstract class CollAbstract<E extends Entity<E>> extends EntityContainerAbstract<E> implements CollInterface<E>
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// WHAT DO WE HANDLE?
|
// WHAT DO WE HANDLE?
|
||||||
@ -22,140 +17,6 @@ public abstract class CollAbstract<E extends Entity<E>> implements CollInterface
|
|||||||
return this.getId();
|
return this.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// SUPPORTING SYSTEM
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// This is all placed in the implementation.
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// STORAGE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String fixIdOrThrow(Object oid) throws IllegalArgumentException
|
|
||||||
{
|
|
||||||
String ret = this.fixId(oid);
|
|
||||||
if (ret == null) throw new IllegalArgumentException(String.valueOf(oid) + " is not a valid id.");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E get(Object oid)
|
|
||||||
{
|
|
||||||
return this.getFixed(this.fixId(oid));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E get(Object oid, boolean creative)
|
|
||||||
{
|
|
||||||
return this.getFixed(this.fixId(oid), creative);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E getFixed(String id)
|
|
||||||
{
|
|
||||||
return this.getFixed(id, this.isCreative());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsId(Object oid)
|
|
||||||
{
|
|
||||||
return this.containsIdFixed(this.fixId(oid));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), where, orderby, limit, offset); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(oids), where, orderby, limit); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(oids), where, orderby); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), where, limit, offset); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit) { return MUtil.transform(this.getAll(oids), where, limit); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), limit, offset); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(oids), limit); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where) { return MUtil.transform(this.getAll(oids), where); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(oids), orderby); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), limit, offset); }
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids, Integer limit) { return MUtil.transform(this.getAll(oids), limit); }
|
|
||||||
|
|
||||||
@Override public List<E> getAll(Iterable<?> oids)
|
|
||||||
{
|
|
||||||
// Return Create
|
|
||||||
List<E> ret = new ArrayList<>();
|
|
||||||
|
|
||||||
// Return Fill
|
|
||||||
for (Object oid : oids)
|
|
||||||
{
|
|
||||||
E e = this.get(oid);
|
|
||||||
if (e == null) continue;
|
|
||||||
ret.add(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return Return
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), where, orderby, limit, offset); }
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(), where, orderby, limit); }
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(), where, orderby); }
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), where, limit, offset); }
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where, Integer limit) { return MUtil.transform(this.getAll(), where, limit); }
|
|
||||||
@Override public List<E> getAll(Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), limit, offset); }
|
|
||||||
@Override public List<E> getAll(Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(), limit); }
|
|
||||||
@Override public List<E> getAll(Predicate<? super E> where) { return MUtil.transform(this.getAll(), where); }
|
|
||||||
@Override public List<E> getAll(Comparator<? super E> orderby) { return MUtil.transform(this.getAll(), orderby); }
|
|
||||||
@Override public List<E> getAll(Integer limit, Integer offset) { return MUtil.transform(this.getAll(), limit, offset); }
|
|
||||||
@Override public List<E> getAll(Integer limit) { return MUtil.transform(this.getAll(), limit); }
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// BEHAVIOR
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// This is all placed in the implementation.
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// COPY AND CREATE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
// Create new instance with automatic id
|
|
||||||
@Override
|
|
||||||
public E create()
|
|
||||||
{
|
|
||||||
return this.create(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// ATTACH AND DETACH
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String attach(E entity)
|
|
||||||
{
|
|
||||||
return this.attach(entity, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E detachId(Object oid)
|
|
||||||
{
|
|
||||||
if (oid == null) throw new NullPointerException("oid");
|
|
||||||
return this.detachIdFixed(this.fixIdOrThrow(oid));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// IDENTIFIED MODIFICATIONS
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putIdentifiedModification(Object oid, Modification modification)
|
|
||||||
{
|
|
||||||
if (oid == null) throw new NullPointerException("oid");
|
|
||||||
this.putIdentifiedModificationFixed(this.fixIdOrThrow(oid), modification);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeIdentifiedModification(Object oid)
|
|
||||||
{
|
|
||||||
if (oid == null) throw new NullPointerException("oid");
|
|
||||||
this.removeIdentifiedModificationFixed(this.fixIdOrThrow(oid));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// SYNC LOG
|
// SYNC LOG
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
@ -242,14 +103,4 @@ public abstract class CollAbstract<E extends Entity<E>> implements CollInterface
|
|||||||
return this.syncIdFixed(id, modification, null);
|
return this.syncIdFixed(id, modification, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// SYNC RUNNABLES / SCHEDULING
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// This is all in the implementation
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// CONSTRUCT
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// This is all in the implementation;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,13 @@ import com.massivecraft.massivecore.Active;
|
|||||||
import com.massivecraft.massivecore.Identified;
|
import com.massivecraft.massivecore.Identified;
|
||||||
import com.massivecraft.massivecore.MassivePlugin;
|
import com.massivecraft.massivecore.MassivePlugin;
|
||||||
import com.massivecraft.massivecore.Named;
|
import com.massivecraft.massivecore.Named;
|
||||||
import com.massivecraft.massivecore.predicate.Predicate;
|
|
||||||
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public interface CollInterface<E extends Entity<E>> extends Named, Active, Identified
|
public interface CollInterface<E extends Entity<E>> extends Named, Active, Identified, EntityContainer<E>
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// WHAT DO WE HANDLE?
|
// WHAT DO WE HANDLE?
|
||||||
@ -42,117 +39,18 @@ public interface CollInterface<E extends Entity<E>> extends Named, Active, Ident
|
|||||||
// STORAGE
|
// STORAGE
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
String fixId(Object oid);
|
|
||||||
String fixIdOrThrow(Object oid) throws IllegalArgumentException;
|
|
||||||
|
|
||||||
Map<String, E> getId2entity();
|
|
||||||
E get(Object oid);
|
|
||||||
E get(Object oid, boolean creative);
|
|
||||||
E getFixed(String id);
|
|
||||||
E getFixed(String id, boolean creative);
|
|
||||||
Collection<String> getIds();
|
|
||||||
Collection<String> getIdsRemote();
|
Collection<String> getIdsRemote();
|
||||||
boolean containsId(Object oid);
|
|
||||||
boolean containsIdFixed(String id);
|
|
||||||
|
|
||||||
boolean containsEntity(Object entity);
|
|
||||||
|
|
||||||
Collection<E> getAll();
|
|
||||||
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit);
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby);
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit);
|
|
||||||
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit);
|
|
||||||
List<E> getAll(Iterable<?> oids, Predicate<? super E> where);
|
|
||||||
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby);
|
|
||||||
List<E> getAll(Iterable<?> oids, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Iterable<?> oids, Integer limit);
|
|
||||||
List<E> getAll(Iterable<?> oids);
|
|
||||||
|
|
||||||
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit);
|
|
||||||
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby);
|
|
||||||
List<E> getAll(Predicate<? super E> where, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Predicate<? super E> where, Integer limit);
|
|
||||||
List<E> getAll(Comparator<? super E> orderby, Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Comparator<? super E> orderby, Integer limit);
|
|
||||||
List<E> getAll(Predicate<? super E> where);
|
|
||||||
List<E> getAll(Comparator<? super E> orderby);
|
|
||||||
List<E> getAll(Integer limit, Integer offset);
|
|
||||||
List<E> getAll(Integer limit);
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// BEHAVIOR
|
// BEHAVIOR
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
boolean isCreative();
|
|
||||||
void setCreative(boolean creative);
|
|
||||||
|
|
||||||
boolean isLowercasing();
|
|
||||||
void setLowercasing(boolean lowercasing);
|
|
||||||
|
|
||||||
// A default entity will not be saved.
|
|
||||||
// This is often used together with creative collections to save disc space.
|
|
||||||
boolean isDefault(E entity);
|
|
||||||
|
|
||||||
int getEntityTargetVersion();
|
int getEntityTargetVersion();
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// COPY AND CREATE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
void copy(E fromo, E too);
|
|
||||||
|
|
||||||
// This simply creates and returns a new instance
|
|
||||||
// It does not detach/attach or anything. Just creates a new instance.
|
|
||||||
E createNewInstance();
|
|
||||||
|
|
||||||
// Create new instance with automatic id
|
|
||||||
E create();
|
|
||||||
// Create new instance with the requested id
|
|
||||||
E create(Object oid);
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// ATTACH AND DETACH
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
String attach(E entity);
|
|
||||||
String attach(E entity, Object oid);
|
|
||||||
|
|
||||||
E detachEntity(E entity);
|
|
||||||
E detachId(Object oid);
|
|
||||||
E detachIdFixed(String id);
|
|
||||||
|
|
||||||
void preAttach(E entity, String id);
|
|
||||||
void postAttach(E entity, String id);
|
|
||||||
|
|
||||||
void preDetach(E entity, String id);
|
|
||||||
void postDetach(E entity, String id);
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// IDENTIFIED MODIFICATIONS
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
void putIdentifiedModification(Object oid, Modification modification);
|
|
||||||
void putIdentifiedModificationFixed(String id, Modification modification);
|
|
||||||
|
|
||||||
void removeIdentifiedModification(Object oid);
|
|
||||||
void removeIdentifiedModificationFixed(String id);
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// SYNC LOG
|
// SYNC LOG
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
/*
|
|
||||||
public Map<L, Long> lastMtime();
|
|
||||||
public Map<L, Object> lastRaw();
|
|
||||||
public Set<L> lastDefault();
|
|
||||||
public void clearSynclog(Object oid);
|
|
||||||
*/
|
|
||||||
|
|
||||||
Map<String, Long> getSyncMap(boolean in);
|
Map<String, Long> getSyncMap(boolean in);
|
||||||
long getSyncCountFixed(String name, boolean in);
|
long getSyncCountFixed(String name, boolean in);
|
||||||
void addSyncCountFixed(String name, boolean in);
|
void addSyncCountFixed(String name, boolean in);
|
||||||
@ -162,13 +60,11 @@ public interface CollInterface<E extends Entity<E>> extends Named, Active, Ident
|
|||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
// oid
|
// oid
|
||||||
E removeAtLocal(Object oid);
|
|
||||||
void removeAtRemote(Object oid);
|
void removeAtRemote(Object oid);
|
||||||
void saveToRemote(Object oid);
|
void saveToRemote(Object oid);
|
||||||
void loadFromRemote(Object oid, Entry<JsonObject, Long> remoteEntry);
|
void loadFromRemote(Object oid, Entry<JsonObject, Long> remoteEntry);
|
||||||
|
|
||||||
// Fixed id
|
// Fixed id
|
||||||
E removeAtLocalFixed(String id);
|
|
||||||
void removeAtRemoteFixed(String id);
|
void removeAtRemoteFixed(String id);
|
||||||
void saveToRemoteFixed(String id);
|
void saveToRemoteFixed(String id);
|
||||||
void loadFromRemoteFixed(String id, Entry<JsonObject, Long> remoteEntry);
|
void loadFromRemoteFixed(String id, Entry<JsonObject, Long> remoteEntry);
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
package com.massivecraft.massivecore.store;
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
import com.massivecraft.massivecore.Identified;
|
|
||||||
import com.massivecraft.massivecore.MassiveCore;
|
|
||||||
import com.massivecraft.massivecore.store.accessor.Accessor;
|
|
||||||
import com.massivecraft.massivecore.xlib.gson.Gson;
|
|
||||||
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
import com.massivecraft.massivecore.xlib.gson.JsonObject;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usage of this class is highly optional. You may persist anything. If you are
|
* Usage of this class is highly optional. You may persist anything. If you are
|
||||||
* creating the class to be persisted yourself, it might be handy to extend this
|
* creating the class to be persisted yourself, it might be handy to extend this
|
||||||
@ -16,23 +10,17 @@ import java.util.Objects;
|
|||||||
|
|
||||||
// Self referencing generic.
|
// Self referencing generic.
|
||||||
// http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206
|
// http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206
|
||||||
public class Entity<E extends Entity<E>> implements Identified
|
public class Entity<E extends Entity<E>> extends EntityInternal<E>
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// FIELDS
|
// FIELDS
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
protected transient Coll<E> coll;
|
public Coll<?> getColl() { return (Coll<?>) this.getContainer(); }
|
||||||
protected void setColl(Coll<E> val) { this.coll = val; }
|
|
||||||
public Coll<E> getColl() { return this.coll; }
|
|
||||||
|
|
||||||
protected transient String id;
|
|
||||||
protected void setId(String id) { this.id = id; }
|
|
||||||
@Override public String getId() { return this.id; }
|
|
||||||
|
|
||||||
public String getUniverse()
|
public String getUniverse()
|
||||||
{
|
{
|
||||||
Coll<E> coll = this.getColl();
|
Coll<?> coll = this.getColl();
|
||||||
if (coll == null) return null;
|
if (coll == null) return null;
|
||||||
|
|
||||||
return coll.getUniverse();
|
return coll.getUniverse();
|
||||||
@ -62,79 +50,25 @@ public class Entity<E extends Entity<E>> implements Identified
|
|||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public String attach(Coll<E> coll)
|
public String attach(EntityContainer<E> container)
|
||||||
{
|
{
|
||||||
return coll.attach((E) this);
|
if (!(container instanceof Coll)) throw new IllegalArgumentException(container.getClass().getName() + " is not a Coll.");
|
||||||
|
return container.attach((E) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public E detach()
|
public E detach()
|
||||||
{
|
{
|
||||||
Coll<E> coll = this.getColl();
|
EntityContainer<E> coll = this.getContainer();
|
||||||
if (coll == null) return (E)this;
|
if (coll == null) return (E)this;
|
||||||
|
|
||||||
return coll.detachEntity((E) this);
|
return coll.detachEntity((E) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean attached()
|
|
||||||
{
|
|
||||||
return this.getColl() != null && this.getId() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean detached()
|
|
||||||
{
|
|
||||||
return ! this.attached();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void preAttach(String id)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postAttach(String id)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void preDetach(String id)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postDetach(String id)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// SYNC AND IO ACTIONS
|
// SYNC AND IO ACTIONS
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
public boolean isLive()
|
|
||||||
{
|
|
||||||
String id = this.getId();
|
|
||||||
if (id == null) return false;
|
|
||||||
|
|
||||||
Coll<E> coll = this.getColl();
|
|
||||||
if (coll == null) return false;
|
|
||||||
|
|
||||||
if ( ! coll.isActive()) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changed()
|
|
||||||
{
|
|
||||||
if ( ! this.isLive()) return;
|
|
||||||
|
|
||||||
//System.out.println(this.getColl().getName() + ": " +this.getId() + " was modified locally");
|
|
||||||
|
|
||||||
// UNKNOWN is very unimportant really.
|
|
||||||
// LOCAL_ATTACH is for example much more important and should not be replaced.
|
|
||||||
this.getColl().putIdentifiedModificationFixed(this.getId(), Modification.UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Modification sync()
|
public Modification sync()
|
||||||
{
|
{
|
||||||
if (!this.isLive()) return Modification.UNKNOWN;
|
if (!this.isLive()) return Modification.UNKNOWN;
|
||||||
@ -155,61 +89,4 @@ public class Entity<E extends Entity<E>> implements Identified
|
|||||||
this.getColl().loadFromRemoteFixed(id, null);
|
this.getColl().loadFromRemoteFixed(id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// DERPINGTON
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public E load(E that)
|
|
||||||
{
|
|
||||||
Accessor.get(this.getClass()).copy(that, this);
|
|
||||||
return (E) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefault()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// CONVENIENCE: DATABASE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
// GENERIC
|
|
||||||
public <T> T convertGet(T value, T standard)
|
|
||||||
{
|
|
||||||
return value != null ? value : standard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T convertSet(T value, T standard)
|
|
||||||
{
|
|
||||||
this.changed();
|
|
||||||
return Objects.equals(value, standard) ? null : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BOOLEAN
|
|
||||||
public boolean convertGet(Boolean value)
|
|
||||||
{
|
|
||||||
return convertGet(value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean convertSet(Boolean value)
|
|
||||||
{
|
|
||||||
return convertSet(value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// STANDARDS
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
Gson gson = MassiveCore.gson;
|
|
||||||
Coll<E> coll = this.getColl();
|
|
||||||
if (coll != null) gson = coll.getGson();
|
|
||||||
|
|
||||||
return this.getClass().getSimpleName()+gson.toJson(this, this.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
149
src/com/massivecraft/massivecore/store/EntityContainer.java
Normal file
149
src/com/massivecraft/massivecore/store/EntityContainer.java
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.predicate.Predicate;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
// Most base EntityContainer
|
||||||
|
public interface EntityContainer<E>
|
||||||
|
{
|
||||||
|
String attach(E entity);
|
||||||
|
String attach(E entity, Object oid);
|
||||||
|
|
||||||
|
E detachEntity(E entity);
|
||||||
|
E detachId(Object oid);
|
||||||
|
E detachIdFixed(String id);
|
||||||
|
|
||||||
|
boolean isLive();
|
||||||
|
|
||||||
|
Coll<?> getColl();
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// WHAT DO WE HANDLE?
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
Class<E> getEntityClass();
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STORAGE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
String fixId(Object oid);
|
||||||
|
String fixIdOrThrow(Object oid) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
Map<String, E> getIdToEntityRaw();
|
||||||
|
Map<String, E> getIdToEntity();
|
||||||
|
E get(Object oid);
|
||||||
|
E get(Object oid, boolean creative);
|
||||||
|
E getFixed(String id);
|
||||||
|
E getFixed(String id, boolean creative);
|
||||||
|
Collection<String> getIds();
|
||||||
|
boolean containsId(Object oid);
|
||||||
|
boolean containsIdFixed(String id);
|
||||||
|
|
||||||
|
boolean containsEntity(Object entity);
|
||||||
|
|
||||||
|
Collection<E> getAll();
|
||||||
|
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit);
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby);
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit);
|
||||||
|
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit);
|
||||||
|
List<E> getAll(Iterable<?> oids, Predicate<? super E> where);
|
||||||
|
List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby);
|
||||||
|
List<E> getAll(Iterable<?> oids, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Iterable<?> oids, Integer limit);
|
||||||
|
List<E> getAll(Iterable<?> oids);
|
||||||
|
|
||||||
|
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit);
|
||||||
|
List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby);
|
||||||
|
List<E> getAll(Predicate<? super E> where, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Predicate<? super E> where, Integer limit);
|
||||||
|
List<E> getAll(Comparator<? super E> orderby, Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Comparator<? super E> orderby, Integer limit);
|
||||||
|
List<E> getAll(Predicate<? super E> where);
|
||||||
|
List<E> getAll(Comparator<? super E> orderby);
|
||||||
|
List<E> getAll(Integer limit, Integer offset);
|
||||||
|
List<E> getAll(Integer limit);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// BEHAVIOR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
boolean isCreative();
|
||||||
|
void setCreative(boolean creative);
|
||||||
|
|
||||||
|
boolean isLowercasing();
|
||||||
|
void setLowercasing(boolean lowercasing);
|
||||||
|
|
||||||
|
// A default entity will not be saved.
|
||||||
|
// This is often used together with creative collections to save disc space.
|
||||||
|
boolean isDefault(E entity);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// COPY AND CREATE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
void copy(E fromo, E too);
|
||||||
|
|
||||||
|
// This simply creates and returns a new instance
|
||||||
|
// It does not detach/attach or anything. Just creates a new instance.
|
||||||
|
E createNewInstance();
|
||||||
|
|
||||||
|
// Create new instance with automatic id
|
||||||
|
E create();
|
||||||
|
// Create new instance with the requested id
|
||||||
|
E create(Object oid);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ATTACH AND DETACH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
/*String attach(E entity);
|
||||||
|
String attach(E entity, Object oid);
|
||||||
|
|
||||||
|
E detachEntity(E entity);
|
||||||
|
E detachId(Object oid);
|
||||||
|
E detachIdFixed(String id);*/
|
||||||
|
|
||||||
|
void preAttach(E entity, String id);
|
||||||
|
void postAttach(E entity, String id);
|
||||||
|
|
||||||
|
void preDetach(E entity, String id);
|
||||||
|
void postDetach(E entity, String id);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IDENTIFIED MODIFICATIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
void putIdentifiedModification(Object oid, Modification modification);
|
||||||
|
void putIdentifiedModificationFixed(String id, Modification modification);
|
||||||
|
|
||||||
|
void removeIdentifiedModification(Object oid);
|
||||||
|
void removeIdentifiedModificationFixed(String id);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SYNC LOWLEVEL IO ACTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// oid
|
||||||
|
E removeAtLocal(Object oid);
|
||||||
|
|
||||||
|
// fixed
|
||||||
|
E removeAtLocalFixed(String id);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// NAME UTILITIES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
E getByName(String name);
|
||||||
|
boolean isNameTaken(String str);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,416 @@
|
|||||||
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.Named;
|
||||||
|
import com.massivecraft.massivecore.predicate.Predicate;
|
||||||
|
import com.massivecraft.massivecore.predicate.PredicateEqualsIgnoreCase;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
// Calls fixId when necessary
|
||||||
|
public abstract class EntityContainerAbstract<E extends EntityInternal<E>> implements EntityContainer<E>
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STORAGE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override public Map<String, E> getIdToEntity() { return Collections.unmodifiableMap(this.getIdToEntityRaw()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fixId(Object oid)
|
||||||
|
{
|
||||||
|
if (oid == null) return null;
|
||||||
|
|
||||||
|
String ret = null;
|
||||||
|
if (oid instanceof String) ret = (String) oid;
|
||||||
|
else if (oid.getClass() == this.getEntityClass()) ret = ((Entity<?>) oid).getId();
|
||||||
|
if (ret == null) return null;
|
||||||
|
|
||||||
|
return this.isLowercasing() ? ret.toLowerCase() : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fixIdOrThrow(Object oid) throws IllegalArgumentException
|
||||||
|
{
|
||||||
|
String ret = this.fixId(oid);
|
||||||
|
if (ret == null) throw new IllegalArgumentException(String.valueOf(oid) + " is not a valid id.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E get(Object oid)
|
||||||
|
{
|
||||||
|
return this.getFixed(this.fixId(oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E get(Object oid, boolean creative)
|
||||||
|
{
|
||||||
|
return this.getFixed(this.fixId(oid), creative);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getFixed(String id)
|
||||||
|
{
|
||||||
|
return this.getFixed(id, this.isCreative());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getFixed(String id, boolean creative)
|
||||||
|
{
|
||||||
|
return this.getFixed(id, creative, true);
|
||||||
|
}
|
||||||
|
protected E getFixed(String id, boolean creative, boolean noteModification)
|
||||||
|
{
|
||||||
|
if (id == null) return null;
|
||||||
|
E ret = this.getIdToEntity().get(id);
|
||||||
|
if (ret != null) return ret;
|
||||||
|
if ( ! creative) return null;
|
||||||
|
return this.create(id, noteModification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Collection<String> getIds() { return this.getIdToEntity().keySet(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsId(Object oid)
|
||||||
|
{
|
||||||
|
return this.containsIdFixed(this.fixId(oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsIdFixed(String id)
|
||||||
|
{
|
||||||
|
if (id == null) return false;
|
||||||
|
return this.getIdToEntity().containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsEntity(Object entity)
|
||||||
|
{
|
||||||
|
return this.getIdToEntity().containsValue(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Collection<E> getAll()
|
||||||
|
{
|
||||||
|
return this.getIdToEntity().values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), where, orderby, limit, offset); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(oids), where, orderby, limit); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(oids), where, orderby); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), where, limit, offset); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where, Integer limit) { return MUtil.transform(this.getAll(oids), where, limit); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), limit, offset); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(oids), limit); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Predicate<? super E> where) { return MUtil.transform(this.getAll(oids), where); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(oids), orderby); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Integer limit, Integer offset) { return MUtil.transform(this.getAll(oids), limit, offset); }
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids, Integer limit) { return MUtil.transform(this.getAll(oids), limit); }
|
||||||
|
|
||||||
|
@Override public List<E> getAll(Iterable<?> oids)
|
||||||
|
{
|
||||||
|
// Return Create
|
||||||
|
List<E> ret = new ArrayList<>();
|
||||||
|
|
||||||
|
// Return Fill
|
||||||
|
for (Object oid : oids)
|
||||||
|
{
|
||||||
|
E e = this.get(oid);
|
||||||
|
if (e == null) continue;
|
||||||
|
ret.add(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return Return
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), where, orderby, limit, offset); }
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(), where, orderby, limit); }
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where, Comparator<? super E> orderby) { return MUtil.transform(this.getAll(), where, orderby); }
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), where, limit, offset); }
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where, Integer limit) { return MUtil.transform(this.getAll(), where, limit); }
|
||||||
|
@Override public List<E> getAll(Comparator<? super E> orderby, Integer limit, Integer offset) { return MUtil.transform(this.getAll(), limit, offset); }
|
||||||
|
@Override public List<E> getAll(Comparator<? super E> orderby, Integer limit) { return MUtil.transform(this.getAll(), limit); }
|
||||||
|
@Override public List<E> getAll(Predicate<? super E> where) { return MUtil.transform(this.getAll(), where); }
|
||||||
|
@Override public List<E> getAll(Comparator<? super E> orderby) { return MUtil.transform(this.getAll(), orderby); }
|
||||||
|
@Override public List<E> getAll(Integer limit, Integer offset) { return MUtil.transform(this.getAll(), limit, offset); }
|
||||||
|
@Override public List<E> getAll(Integer limit) { return MUtil.transform(this.getAll(), limit); }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// BEHAVIOR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected boolean creative;
|
||||||
|
@Override public boolean isCreative() { return this.creative; }
|
||||||
|
@Override public void setCreative(boolean creative) { this.creative = creative; }
|
||||||
|
|
||||||
|
// "Lowercasing" means that the ids are always converted to lower case when fixed.
|
||||||
|
// This is highly recommended for sender colls.
|
||||||
|
// The senderIds are case insensitive by nature and some times you simply can't know the correct casing.
|
||||||
|
protected boolean lowercasing;
|
||||||
|
@Override public boolean isLowercasing() { return this.lowercasing; }
|
||||||
|
@Override public void setLowercasing(boolean lowercasing) { this.lowercasing = lowercasing; }
|
||||||
|
|
||||||
|
// Should that instance be saved or not?
|
||||||
|
// If it is default it should not be saved.
|
||||||
|
@Override
|
||||||
|
public boolean isDefault(E entity)
|
||||||
|
{
|
||||||
|
return entity.isDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// COPY AND CREATE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// Create new instance with automatic id
|
||||||
|
@Override
|
||||||
|
public E create()
|
||||||
|
{
|
||||||
|
return this.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// COPY AND CREATE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copy(E efrom, E eto)
|
||||||
|
{
|
||||||
|
if (efrom == null) throw new NullPointerException("efrom");
|
||||||
|
if (eto == null) throw new NullPointerException("eto");
|
||||||
|
|
||||||
|
eto.load(efrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This simply creates and returns a new instance
|
||||||
|
// It does not detach/attach or anything. Just creates a new instance.
|
||||||
|
@Override
|
||||||
|
public E createNewInstance()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return this.getEntityClass().newInstance();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new instance with the requested id
|
||||||
|
@Override
|
||||||
|
public synchronized E create(Object oid)
|
||||||
|
{
|
||||||
|
return this.create(oid, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized E create(Object oid, boolean noteModification)
|
||||||
|
{
|
||||||
|
E entity = this.createNewInstance();
|
||||||
|
if (this.attach(entity, oid, noteModification) == null) return null;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ATTACH AND DETACH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String attach(E entity)
|
||||||
|
{
|
||||||
|
return this.attach(entity, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String attach(E entity, Object oid)
|
||||||
|
{
|
||||||
|
return this.attach(entity, oid, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized String attach(E entity, Object oid, boolean noteModification)
|
||||||
|
{
|
||||||
|
// Check entity
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (entity.attached()) return entity.getId();
|
||||||
|
|
||||||
|
String id;
|
||||||
|
// Check/Fix id
|
||||||
|
if (oid == null)
|
||||||
|
{
|
||||||
|
id = MStore.createId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = this.fixId(oid);
|
||||||
|
if (id == null) return null;
|
||||||
|
if (this.getIdToEntity().containsKey(id)) return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRE
|
||||||
|
this.preAttach(entity, id);
|
||||||
|
|
||||||
|
// Add entity reference info
|
||||||
|
entity.setContainer(this);
|
||||||
|
entity.setId(id);
|
||||||
|
|
||||||
|
// Attach
|
||||||
|
this.getIdToEntityRaw().put(id, entity);
|
||||||
|
|
||||||
|
// Identify Modification
|
||||||
|
if (noteModification)
|
||||||
|
{
|
||||||
|
this.putIdentifiedModificationFixed(id, Modification.LOCAL_ATTACH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST
|
||||||
|
this.postAttach(entity, id);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E detachId(Object oid)
|
||||||
|
{
|
||||||
|
if (oid == null) throw new NullPointerException("oid");
|
||||||
|
return this.detachIdFixed(this.fixIdOrThrow(oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E detachEntity(E entity)
|
||||||
|
{
|
||||||
|
if (entity == null) throw new NullPointerException("entity");
|
||||||
|
|
||||||
|
String id = entity.getId();
|
||||||
|
if (id == null)
|
||||||
|
{
|
||||||
|
// It seems the entity is already detached.
|
||||||
|
// In such case just silently return it.
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.detachFixed(entity, id);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E detachIdFixed(String id)
|
||||||
|
{
|
||||||
|
if (id == null) throw new NullPointerException("id");
|
||||||
|
|
||||||
|
E e = this.get(id, false);
|
||||||
|
if (e == null) return null;
|
||||||
|
|
||||||
|
this.detachFixed(e, id);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void detachFixed(E entity, String id)
|
||||||
|
{
|
||||||
|
if (entity == null) throw new NullPointerException("entity");
|
||||||
|
if (id == null) throw new NullPointerException("id");
|
||||||
|
|
||||||
|
// PRE
|
||||||
|
this.preDetach(entity, id);
|
||||||
|
|
||||||
|
// Remove @ local
|
||||||
|
this.removeAtLocalFixed(id);
|
||||||
|
|
||||||
|
// Identify Modification
|
||||||
|
this.putIdentifiedModificationFixed(id, Modification.LOCAL_DETACH);
|
||||||
|
|
||||||
|
// POST
|
||||||
|
this.postDetach(entity, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preAttach(E entity, String id)
|
||||||
|
{
|
||||||
|
entity.preAttach(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postAttach(E entity, String id)
|
||||||
|
{
|
||||||
|
entity.postAttach(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preDetach(E entity, String id)
|
||||||
|
{
|
||||||
|
entity.preDetach(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postDetach(E entity, String id)
|
||||||
|
{
|
||||||
|
entity.postDetach(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IDENTIFIED MODIFICATIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putIdentifiedModification(Object oid, Modification modification)
|
||||||
|
{
|
||||||
|
if (oid == null) throw new NullPointerException("oid");
|
||||||
|
this.putIdentifiedModificationFixed(this.fixIdOrThrow(oid), modification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeIdentifiedModification(Object oid)
|
||||||
|
{
|
||||||
|
if (oid == null) throw new NullPointerException("oid");
|
||||||
|
this.removeIdentifiedModificationFixed(this.fixIdOrThrow(oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SYNC LOWLEVEL IO ACTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeAtLocal(Object oid)
|
||||||
|
{
|
||||||
|
if (oid == null) throw new NullPointerException("oid");
|
||||||
|
return this.removeAtLocalFixed(this.fixIdOrThrow(oid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// NAME UTILITIES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getByName(String name)
|
||||||
|
{
|
||||||
|
if (name == null) throw new NullPointerException("name");
|
||||||
|
|
||||||
|
Predicate<String> predicate = PredicateEqualsIgnoreCase.get(name);
|
||||||
|
for (E entity : this.getAll())
|
||||||
|
{
|
||||||
|
if (entity == null) continue;
|
||||||
|
|
||||||
|
if ( ! (entity instanceof Named)) continue;
|
||||||
|
Named named = (Named)entity;
|
||||||
|
|
||||||
|
if (predicate.apply(named.getName())) return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNameTaken(String str)
|
||||||
|
{
|
||||||
|
return this.getByName(str) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
159
src/com/massivecraft/massivecore/store/EntityInternal.java
Normal file
159
src/com/massivecraft/massivecore/store/EntityInternal.java
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.store.accessor.Accessor;
|
||||||
|
import com.massivecraft.massivecore.xlib.gson.Gson;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class EntityInternal<E extends EntityInternal<E>>
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected transient WeakReference<EntityContainer<E>> container = new WeakReference<>(null);
|
||||||
|
protected void setContainer(EntityContainer<E> container)
|
||||||
|
{
|
||||||
|
this.container = new WeakReference<>(container);
|
||||||
|
}
|
||||||
|
public EntityContainer<E> getContainer()
|
||||||
|
{
|
||||||
|
return this.container.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coll<?> getColl()
|
||||||
|
{
|
||||||
|
return this.getContainer().getColl();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected transient String id;
|
||||||
|
protected void setId(String id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public String getId()
|
||||||
|
{
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ATTACH AND DETACH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public boolean attached()
|
||||||
|
{
|
||||||
|
return this.getContainer() != null && this.getId() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean detached()
|
||||||
|
{
|
||||||
|
return !this.attached();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preAttach(String id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postAttach(String id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preDetach(String id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postDetach(String id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SYNC AND IO ACTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public boolean isLive()
|
||||||
|
{
|
||||||
|
String id = this.getId();
|
||||||
|
if (id == null) return false;
|
||||||
|
|
||||||
|
EntityContainer<E> container = this.getContainer();
|
||||||
|
if (container == null) return false;
|
||||||
|
|
||||||
|
if (!container.isLive()) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changed()
|
||||||
|
{
|
||||||
|
if (!this.isLive()) return;
|
||||||
|
|
||||||
|
//System.out.println(this.getColl().getName() + ": " +this.getId() + " was modified locally");
|
||||||
|
|
||||||
|
this.getContainer().putIdentifiedModificationFixed(this.getId(), Modification.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DERPINGTON
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public E load(E that)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(that, "that");
|
||||||
|
Accessor.get(this.getClass()).copy(that, this);
|
||||||
|
return (E) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefault()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONVENIENCE: DATABASE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// GENERIC
|
||||||
|
public <T> T convertGet(T value, T standard)
|
||||||
|
{
|
||||||
|
return value != null ? value : standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T convertSet(T value, T standard)
|
||||||
|
{
|
||||||
|
this.changed();
|
||||||
|
return Objects.equals(value, standard) ? null : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOOLEAN
|
||||||
|
public boolean convertGet(Boolean value)
|
||||||
|
{
|
||||||
|
return convertGet(value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean convertSet(Boolean value)
|
||||||
|
{
|
||||||
|
return convertSet(value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STANDARDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
Gson gson = MassiveCore.gson;
|
||||||
|
Coll<?> coll = this.getColl();
|
||||||
|
if (coll != null) gson = coll.getGson();
|
||||||
|
|
||||||
|
return this.getClass().getSimpleName() + gson.toJson(this, this.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
228
src/com/massivecraft/massivecore/store/EntityInternalMap.java
Normal file
228
src/com/massivecraft/massivecore/store/EntityInternalMap.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package com.massivecraft.massivecore.store;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class EntityInternalMap<E extends EntityInternal<E>> extends EntityContainerAbstract<E>
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private EntityInternalMap()
|
||||||
|
{
|
||||||
|
this.entityClass = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityInternalMap(Class<E> entityClass)
|
||||||
|
{
|
||||||
|
this.entityClass = entityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityInternalMap(EntityInternal<?> entity, Class<E> entityClass)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(entity, "entity");
|
||||||
|
Objects.requireNonNull(entityClass, "entityClass");
|
||||||
|
|
||||||
|
this.setEntity(entity);
|
||||||
|
this.entityClass = entityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// REFERENCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected transient WeakReference<EntityInternal<?>> entity = new WeakReference<>(null);
|
||||||
|
protected void setEntity(EntityInternal<?> entity) { this.entity = new WeakReference<EntityInternal<?>>(entity); }
|
||||||
|
public EntityInternal<?> getEntity() { return this.entity.get(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLive()
|
||||||
|
{
|
||||||
|
EntityInternal<?> entity = this.getEntity();
|
||||||
|
if (entity == null) return false;
|
||||||
|
|
||||||
|
if (!entity.isLive()) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// WHAT DO WE HANDLE?
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected final transient Class<E> entityClass;
|
||||||
|
@Override public Class<E> getEntityClass() { return this.entityClass; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STORAGE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, E> id2Entity = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override public Map<String, E> getIdToEntityRaw() { return this.id2Entity; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// REFERENCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coll<?> getColl()
|
||||||
|
{
|
||||||
|
return this.getEntity().getContainer().getColl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LOAD
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public EntityInternalMap<E> load(EntityInternalMap<E> that)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(that, "that");
|
||||||
|
|
||||||
|
// Loop over all the entities in that
|
||||||
|
for (Entry<String, E> entry : that.id2Entity.entrySet())
|
||||||
|
{
|
||||||
|
String id = entry.getKey();
|
||||||
|
E entity = entry.getValue();
|
||||||
|
|
||||||
|
E current = this.id2Entity.get(id);
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
// Load if present
|
||||||
|
current.load(entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// attach if not present
|
||||||
|
this.attach(entity, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean entities of those that are not in that
|
||||||
|
if (this.id2Entity.size() != that.id2Entity.size())
|
||||||
|
{
|
||||||
|
// Avoid CME
|
||||||
|
Set<Entry<String, E>> removals = new MassiveSet<>();
|
||||||
|
|
||||||
|
// Loop over all current entries ...
|
||||||
|
for (Iterator<Entry<String, E>> it = this.id2Entity.entrySet().iterator(); it.hasNext(); )
|
||||||
|
{
|
||||||
|
Entry<String, E> entry = it.next();
|
||||||
|
String id = entry.getKey();
|
||||||
|
|
||||||
|
// ... if it is not present in those ...
|
||||||
|
if (that.id2Entity.containsKey(id)) continue;
|
||||||
|
|
||||||
|
// ... remove.
|
||||||
|
removals.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove
|
||||||
|
for (Entry<String, E> removal : removals)
|
||||||
|
{
|
||||||
|
this.detachFixed(removal.getValue(), removal.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IDENTIFIED MODIFICATIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected Map<String, Modification> identifiedModifications;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void putIdentifiedModificationFixed(String id, Modification modification)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(id, "id");
|
||||||
|
this.changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void removeIdentifiedModificationFixed(String id)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(id, "id");
|
||||||
|
this.changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changed()
|
||||||
|
{
|
||||||
|
if (!this.isLive()) return;
|
||||||
|
|
||||||
|
//System.out.println(this.getColl().getName() + ": " +this.getId() + " was modified locally");
|
||||||
|
|
||||||
|
this.getEntity().changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SYNC LOWLEVEL IO ACTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized E removeAtLocalFixed(String id)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(id, "id");
|
||||||
|
|
||||||
|
this.removeIdentifiedModificationFixed(id);
|
||||||
|
|
||||||
|
E entity = this.getIdToEntity().remove(id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
|
||||||
|
// Remove entity reference info
|
||||||
|
entity.setContainer(null);
|
||||||
|
entity.setId(null);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// MAP DELEGATION
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Set<Entry<String, E>> entrySet()
|
||||||
|
{
|
||||||
|
return this.getIdToEntityRaw().entrySet();
|
||||||
|
}
|
||||||
|
public Set<String> keySet()
|
||||||
|
{
|
||||||
|
return this.getIdToEntity().keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(String id)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(id, "id");
|
||||||
|
return this.getIdToEntityRaw().containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public E remove(String id)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(id, "id");
|
||||||
|
return this.getIdToEntityRaw().remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return this.getIdToEntityRaw().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return this.getIdToEntityRaw().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
this.getIdToEntityRaw().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.massivecraft.massivecore.store.accessor;
|
package com.massivecraft.massivecore.store.accessor;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -72,11 +74,23 @@ public class Accessor
|
|||||||
{
|
{
|
||||||
String fieldName = entry.getKey();
|
String fieldName = entry.getKey();
|
||||||
Field field = entry.getValue();
|
Field field = entry.getValue();
|
||||||
FieldAccessor fieldAccessor = new FieldAccessor(field);
|
FieldAccessor fieldAccessor = createFieldAccessor(field);
|
||||||
this.setFieldAccessor(fieldName, fieldAccessor);
|
this.setFieldAccessor(fieldName, fieldAccessor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FieldAccessor createFieldAccessor(Field field)
|
||||||
|
{
|
||||||
|
if (EntityInternalMap.class.isAssignableFrom(field.getType()))
|
||||||
|
{
|
||||||
|
return new FieldAccessorInternalEntityMap(field);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new FieldAccessorSimple(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// GET & SET & COPY
|
// GET & SET & COPY
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -1,54 +1,8 @@
|
|||||||
package com.massivecraft.massivecore.store.accessor;
|
package com.massivecraft.massivecore.store.accessor;
|
||||||
|
|
||||||
import com.massivecraft.massivecore.util.ReflectionUtil;
|
public interface FieldAccessor
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class FieldAccessor
|
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
public Object get(Object entity);
|
||||||
// FIELDS
|
public void set(Object entity, Object val);
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
private final Field field;
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// CONSTRUCT
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
public FieldAccessor(Field field)
|
|
||||||
{
|
|
||||||
ReflectionUtil.makeAccessible(field);
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// CORE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
|
|
||||||
public Object get(Object entity)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return this.field.get(entity);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(Object entity, Object val)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.field.set(entity, val);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.massivecraft.massivecore.store.accessor;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class FieldAccessorInternalEntityMap extends FieldAccessorSimple
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public FieldAccessorInternalEntityMap(Field field)
|
||||||
|
{
|
||||||
|
super(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CORE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void set(Object entity, Object val)
|
||||||
|
{
|
||||||
|
EntityInternalMap entityMap = (EntityInternalMap) this.get(entity);
|
||||||
|
EntityInternalMap that = (EntityInternalMap) val;
|
||||||
|
|
||||||
|
entityMap.load(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.massivecraft.massivecore.store.accessor;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.ReflectionUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class FieldAccessorSimple implements FieldAccessor
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final Field field;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public FieldAccessorSimple(Field field)
|
||||||
|
{
|
||||||
|
ReflectionUtil.makeAccessible(field);
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CORE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Object get(Object entity)
|
||||||
|
{
|
||||||
|
if (!field.getDeclaringClass().isAssignableFrom(entity.getClass())) throw new IllegalArgumentException(field.getDeclaringClass() + " : " + entity.getClass());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return this.field.get(entity);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Object entity, Object val)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.field.set(entity, val);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user