Imlement TypeMap and the Editor strukture for it.

This commit is contained in:
ulumulu1510 2015-12-19 01:33:16 +01:00 committed by Olof Larsson
parent 18bc7dc9db
commit f2d922e049
9 changed files with 509 additions and 3 deletions

View File

@ -0,0 +1,28 @@
package com.massivecraft.massivecore.command.editor;
import com.massivecraft.massivecore.command.type.Type;
import java.util.Map;
public class CommandEditMap<O, V extends Map<?, ?>> extends CommandEditAbstract<O, V>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CommandEditMap(EditSettings<O> settings, Property<O, V> property, Type<?> mapValueType)
{
// Super
super(settings, property, null);
// Children
this.addChild(new CommandEditShow<O, V>(settings, property));
this.addChild(new CommandEditCreate<O, V>(settings, property));
this.addChild(new CommandEditDelete<O, V>(settings, property));
this.addChild(new CommandEditMapPut<O, V>(settings, property, mapValueType));
this.addChild(new CommandEditMapRemove<O, V>(settings, property, mapValueType));
this.addChild(new CommandEditMapClear<O, V>(settings, property, mapValueType));
}
}

View File

@ -0,0 +1,112 @@
package com.massivecraft.massivecore.command.editor;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.command.requirement.RequirementEditorPropertyCreated;
import com.massivecraft.massivecore.command.type.Type;
import java.util.Map;
public abstract class CommandEditMapAbstract<O, V extends Map<?, ?>> extends CommandEditAbstract<O, V>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CommandEditMapAbstract(EditSettings<O> settings, Property<O, V> property, Type<?> mapValueType)
{
// Super
super(settings, property, true);
this.setMapValueType(mapValueType);
// Aliases
String alias = this.createCommandAlias();
this.setAliases(alias);
// Desc
this.setDesc(alias + " " + this.getPropertyName());
// Requirements
this.addRequirements(RequirementEditorPropertyCreated.get(true));
}
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
Type<?> mapValueType = null;
public void setMapValueType(Type<?> mapValueType) { this.mapValueType = mapValueType; }
// -------------------------------------------- //
// SHORTCUTS > PROPERTY > TYPE
// -------------------------------------------- //
// Only to be used with map type properties.
public Type<Object> getMapKeyType()
{
return this.getProperty().getValueType().getInnerType();
}
@SuppressWarnings("unchecked")
public Type<Object> getMapValueType()
{
return (Type<Object>) mapValueType;
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings("unchecked")
@Override
public void perform() throws MassiveException
{
// Create
Map<Object, Object> after = this.getShallowCopy();
// Alter
try
{
after = this.alter(after);
}
catch (MassiveException e)
{
throw e;
}
catch (Exception e)
{
throw new MassiveException().addMsg("<b>%s", e.getMessage());
}
// Apply
this.attemptSet((V) after);
}
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract Map<Object, Object> alter(Map<Object, Object> map) throws MassiveException;
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public Map<Object, Object> getShallowCopy()
{
// Create
V ret = this.getProperty().getRaw(this.getObject());
if (ret == null) return null;
// Fill
Map<Object, Object> copy = (Map<Object, Object>) this.getProperty().getValueType().createNewInstance();
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) ret).entrySet())
{
copy.put(entry.getKey(), entry.getValue());
}
// Return
return copy;
}
}

View File

@ -0,0 +1,34 @@
package com.massivecraft.massivecore.command.editor;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.command.type.Type;
import java.util.Map;
public class CommandEditMapClear<O, V extends Map<?,?>> extends CommandEditMapAbstract<O, V>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CommandEditMapClear(EditSettings<O> settings, Property<O, V> property, Type<?> mapValueType)
{
// Super
super(settings, property, mapValueType);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Map<Object, Object> alter(Map<Object, Object> map) throws MassiveException
{
// Alter
map.clear();
// Return
return map;
}
}

View File

@ -0,0 +1,42 @@
package com.massivecraft.massivecore.command.editor;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.command.type.Type;
import java.util.Map;
public class CommandEditMapPut<O, V extends Map<?,?>> extends CommandEditMapAbstract<O, V>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CommandEditMapPut(EditSettings<O> settings, Property<O, V> property, Type<?> mapValueType)
{
// Super
super(settings, property, mapValueType);
// Parameters
this.addParameter(this.getMapKeyType(), this.getMapKeyType().getTypeName());
this.addParameter(this.getMapValueType(), this.getMapValueType().getTypeName());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Map<Object, Object> alter(Map<Object, Object> map) throws MassiveException
{
// Args
Object key = this.readArg();
Object value = this.readArg();
// Alter
map.put(key, value);
// Return
return map;
}
}

View File

@ -0,0 +1,40 @@
package com.massivecraft.massivecore.command.editor;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.command.type.Type;
import java.util.Map;
public class CommandEditMapRemove<O, V extends Map<?,?>> extends CommandEditMapAbstract<O, V>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CommandEditMapRemove(EditSettings<O> settings, Property<O, V> property, Type<?> mapValueType)
{
// Super
super(settings, property, mapValueType);
// Parameters
this.addParameter(this.getMapKeyType(), this.getMapKeyType().getTypeName(), true);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Map<Object, Object> alter(Map<Object, Object> map) throws MassiveException
{
// Args
Object key = this.readArg();
// Alter
map.remove(key);
// Return
return map;
}
}

View File

@ -4,7 +4,7 @@ import java.util.Collection;
import com.massivecraft.massivecore.MassiveException; import com.massivecraft.massivecore.MassiveException;
public class CommandEditShow<O, V extends Collection<?>> extends CommandEditAbstract<O, V> public class CommandEditShow<O, V> extends CommandEditAbstract<O, V>
{ {
// -------------------------------------------- // // -------------------------------------------- //
// CONSTRUCT // CONSTRUCT

View File

@ -64,12 +64,12 @@ public abstract class TypeAbstract<T> implements Type<T>
public <I extends Type<X>, X extends Object> List<I> getInnerTypes() { return (List<I>) this.innerTypes; } public <I extends Type<X>, X extends Object> List<I> getInnerTypes() { return (List<I>) this.innerTypes; }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <I> Type<I> getInnerType(int index) { return (Type<I>) this.getInnerTypes().get(index); } public <I> Type<I> getInnerType(int index) { return (Type<I>) this.getInnerTypes().get(index); }
public <I> Type<I> getInnerType() { return this.getInnerType(0); }; public <I> Type<I> getInnerType() { return this.getInnerType(0); }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public void setInnerTypes(Collection<Type<?>> innerTypes) { this.innerTypes = new MassiveList(innerTypes); } public void setInnerTypes(Collection<Type<?>> innerTypes) { this.innerTypes = new MassiveList(innerTypes); }
public void setInnerTypes(Type<?>... innerTypes) { this.setInnerTypes(Arrays.asList(innerTypes)); }; public void setInnerTypes(Type<?>... innerTypes) { this.setInnerTypes(Arrays.asList(innerTypes)); };
public void setInnerType(Type<?> innerType) { this.setInnerTypes(innerType); }; public void setInnerType(Type<?> innerType) { this.setInnerTypes(innerType); }
// -------------------------------------------- // // -------------------------------------------- //
// WRITE VISUAL COLOR // WRITE VISUAL COLOR

View File

@ -0,0 +1,35 @@
package com.massivecraft.massivecore.command.type.collection;
import java.util.HashMap;
import java.util.Map;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.command.type.Type;
public class TypeMap<K,V> extends TypeMapAbstract<Map<K, V>, K, V>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
public static <K,V> TypeMap<K,V> get(Type<K> keyType, Type<V> valueType)
{
return new TypeMap<K,V>(keyType, valueType);
}
public TypeMap(Type<K> keyType, Type<V> valueType)
{
super(keyType, valueType);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public HashMap<K,V> createNewInstance()
{
return new MassiveMap<K,V>();
}
}

View File

@ -0,0 +1,215 @@
package com.massivecraft.massivecore.command.type.collection;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.command.editor.CommandEditAbstract;
import com.massivecraft.massivecore.command.editor.CommandEditMap;
import com.massivecraft.massivecore.command.editor.EditSettings;
import com.massivecraft.massivecore.command.editor.Property;
import com.massivecraft.massivecore.command.type.Type;
import com.massivecraft.massivecore.command.type.TypeAbstract;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.command.CommandSender;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public abstract class TypeMapAbstract<C extends Map<K, V>, K, V> extends TypeAbstract<C>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private Type<V> mapValueType = null;
public void setMapValueType(Type<V> mapValueType) { this.mapValueType = mapValueType; }
public Type<V> getMapValueType() { return mapValueType; }
public void setMapKeyType(Type<K> mapKeyType) { this.setInnerType(mapKeyType); }
public Type<K> getMapKeyType() { return this.getInnerType(); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public TypeMapAbstract(Type<K> mapKeyType, Type<V> mapValueType)
{
this.setMapKeyType(mapKeyType);
this.setMapValueType(mapValueType);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getTypeName()
{
return "Map: " + this.getMapKeyType().getTypeName() + " -> " + this.getMapValueType().getTypeName();
}
@Override
public String getVisualInner(C value, CommandSender sender)
{
// Empty
if (value.isEmpty()) return EMPTY;
List<String> parts = new MassiveList<String>();
for (Entry<K,V> entry : value.entrySet())
{
K entryKey = entry.getKey();
String visualKey = this.getMapKeyType().getVisual(entryKey, sender);
V entryValue = entry.getValue();
String visualValue = this.getMapValueType().getVisual(entryValue, sender);
String part = Txt.parse("<key>%s: <value>%s", visualKey, visualValue);
parts.add(part);
}
return Txt.implode(parts, "\n");
}
@Override
public String getNameInner(C value)
{
// Empty
if (value.isEmpty()) return EMPTY;
// Create
StringBuilder builder = new StringBuilder();
boolean first = true;
// Fill
for (Entry<K,V> entry : value.entrySet())
{
if ( ! first) builder.append(", ");
// Append key
K entryKey = entry.getKey();
builder.append(this.getInnerType().getName(entryKey));
// Add Colon & Space
builder.append(':');
builder.append(' ');
// Append value
V entryValue = entry.getValue();
builder.append(this.getMapValueType().getName(entryValue));
first = false;
}
// Return
return builder.toString();
}
@Override
public String getIdInner(C value)
{
// Empty
if (value.isEmpty()) return EMPTY;
// Create
StringBuilder builder = new StringBuilder();
boolean first = true;
// Fill
for (Entry<K,V> entry : value.entrySet())
{
if ( ! first) builder.append(", ");
// Append key
K entryKey = entry.getKey();
builder.append(this.getInnerType().getId(entryKey));
// Add Colon & Space
builder.append(':');
builder.append(' ');
// Append value
V entryValue = entry.getValue();
builder.append(this.getMapValueType().getId(entryValue));
first = false;
}
// Return
return builder.toString();
}
@Override
public C read(String arg, CommandSender sender) throws MassiveException
{
// Create
C ret = this.createNewInstance();
// Prepare
List<String> args = new MassiveList<>(Txt.PATTERN_WHITESPACE.split(arg));
if (args.size() % 2 != 0)
{
throw new MassiveException().setMsg("<b>There must be an even amount of arguments for a map.");
}
// Fill
for (Iterator<String> it = args.iterator(); it.hasNext(); )
{
// Get Key
String keyString = it.next();
K key = this.getMapKeyType().read(keyString, sender);
// Get Value
String valueString = it.next();
V value = this.getMapValueType().read(valueString, sender);
ret.put(key, value);
}
// Return
return ret;
}
@Override
public Collection<String> getTabList(CommandSender sender, String arg)
{
// Because we accept multiple arguments pairs of the same type.
// The passed arg might be more than one. We only want the latest.
List<String> args = TypeCollection.getArgs(arg);
String lastArg = args.isEmpty() ? null : args.get(args.size() - 1);
// Type
Type<?> type = args.size() % 2 == 1 ? this.getMapKeyType() : this.getMapValueType();
// Return
return type.getTabList(sender, lastArg);
}
@Override
public List<String> getTabListFiltered(CommandSender sender, String arg)
{
// Because we accept multiple arguments pairs of the same type.
// The passed arg might be more than one. We only want the latest.
List<String> args = TypeCollection.getArgs(arg);
String lastArg = args.isEmpty() ? null : args.get(args.size() - 1);
// Type
Type<?> type = args.size() % 2 == 1 ? this.getMapKeyType() : this.getMapValueType();
// Return
return type.getTabListFiltered(sender, lastArg);
}
@Override
public boolean allowSpaceAfterTab()
{
return this.getMapKeyType().allowSpaceAfterTab() && this.getMapValueType().allowSpaceAfterTab();
}
@Override
public <O> CommandEditAbstract<O, C> createEditCommand(EditSettings<O> settings, Property<O, C> property)
{
return new CommandEditMap<O, C>(settings, property, this.getMapValueType());
}
}