Reflection Util improvements. A bug fix. Dirt code from messing around.
This commit is contained in:
parent
1e73cfb7db
commit
053a54190a
@ -308,6 +308,13 @@ public class MassiveCore extends MassivePlugin
|
|||||||
// Delete Files (at once and additionally after all plugins loaded)
|
// Delete Files (at once and additionally after all plugins loaded)
|
||||||
MassiveCoreTaskDeleteFiles.get().run();
|
MassiveCoreTaskDeleteFiles.get().run();
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, MassiveCoreTaskDeleteFiles.get());
|
Bukkit.getScheduler().scheduleSyncDelayedTask(this, MassiveCoreTaskDeleteFiles.get());
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
//PickerTest.get().action();
|
||||||
|
//this.activate(
|
||||||
|
// PickerTest.class
|
||||||
|
//);
|
||||||
|
//PickerTest.get().action();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,8 +81,7 @@ public abstract class WriterAbstract<OA, OB, CA, CB, FA, FB, D> extends Engine
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Class<WriterAbstract<?, ?, ?, ?, ?, ?, ?>> writerClassInner = (Class<WriterAbstract<?, ?, ?, ?, ?, ?, ?>>) writerClass;
|
WriterAbstract<?, ?, ?, ?, ?, ?, ?> writer = ReflectionUtil.getSingletonInstance(writerClass);
|
||||||
WriterAbstract<?, ?, ?, ?, ?, ?, ?> writer = ReflectionUtil.getSingletonInstance(writerClassInner);
|
|
||||||
|
|
||||||
if ( ! writer.isActive()) writer.setActive(this.getActivePlugin());
|
if ( ! writer.isActive()) writer.setActive(this.getActivePlugin());
|
||||||
|
|
||||||
|
158
src/com/massivecraft/massivecore/picker/Picker.java
Normal file
158
src/com/massivecraft/massivecore/picker/Picker.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package com.massivecraft.massivecore.picker;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.Engine;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.util.ReflectionUtil;
|
||||||
|
|
||||||
|
// TODO: Rename to Mixin... because that's what we are trying to replace.
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class Picker extends Engine
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DEFAULT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// The default class contains the static fields.
|
||||||
|
// It should never be abstract and should always be compatible.
|
||||||
|
// A default class instance is set as the default value. This avoids null.
|
||||||
|
// It is detected by the required static field d.
|
||||||
|
|
||||||
|
private final Class<?> defaultClass = ReflectionUtil.getSuperclassDeclaringField(this.getClass(), true, "d");
|
||||||
|
public Class<?> getDefaultClass() { return this.defaultClass; }
|
||||||
|
|
||||||
|
public Picker getDefault() { return ReflectionUtil.getField(this.getDefaultClass(), "d", null); }
|
||||||
|
public boolean isDefault() { return this == this.getDefault(); }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Access the active static instance using instance methods.
|
||||||
|
// This looks a bit strange but will save us a lot of repetitive source code down the road.
|
||||||
|
// These are not meant to be used for selection or activation.
|
||||||
|
// The standard active interface methods are used for that.
|
||||||
|
|
||||||
|
public Picker getInstance() { return ReflectionUtil.getField(this.getDefaultClass(), "i", null); }
|
||||||
|
public void setInstance(Picker i) { ReflectionUtil.setField(this.getDefaultClass(), "i", null, i); }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// This is the base name.
|
||||||
|
// It should describe the function supplied.
|
||||||
|
// It should be set in the base class constructor.
|
||||||
|
private String baseName = this.getDefaultClass().getClass().getSimpleName();
|
||||||
|
public String getBaseName() { return this.baseName; }
|
||||||
|
public void setBaseName(String baseName) { this.baseName = baseName; }
|
||||||
|
|
||||||
|
// This is the instance specific name.
|
||||||
|
// It should describe the circumstances for compatibility.
|
||||||
|
// It could for example contain a version number.
|
||||||
|
private String name = this.getClass().getSimpleName();
|
||||||
|
public String getName() { return this.name; }
|
||||||
|
public void setName(String name) { this.name = name; }
|
||||||
|
|
||||||
|
// This is the list of alternatives to choose from.
|
||||||
|
// The first compatible alternative will be chosen for activation.
|
||||||
|
// The list should thus start with the most provoking and detailed alternative.
|
||||||
|
// If the list is empty we simply offer ourselves.
|
||||||
|
private List<Class<?>> alternatives = new MassiveList<>();
|
||||||
|
public List<Class<?>> getAlternatives() { return this.alternatives; }
|
||||||
|
public <T extends Picker> T setAlternatives(List<Class<?>> alternatives) { this.alternatives = alternatives; return (T) this; }
|
||||||
|
public <T extends Picker> T setAlternatives(Class<?>... alternatives) { return this.setAlternatives(Arrays.asList(alternatives)); }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Picker()
|
||||||
|
{
|
||||||
|
// Provoke!
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.provoke();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
throw ReflectionUtil.asRuntimeException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// PROVOKE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Provoke your exceptions and errors here.
|
||||||
|
// If a throwable is thrown here the instance is not compatible with the circumstances.
|
||||||
|
|
||||||
|
public Object provoke() throws Throwable
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// We need to modify the active logic sightly.
|
||||||
|
//
|
||||||
|
// We make use of the standard engine isActive.
|
||||||
|
// That one looks at the engine registry and does not care about the instance.
|
||||||
|
// That behavior tends to work out well for us in this case.
|
||||||
|
//
|
||||||
|
// The reason for this is that the default will be set as the instance from the start.
|
||||||
|
// That does however not mean that it's active.
|
||||||
|
// It means it will be used to set the active which may or may not be itself.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActive(boolean active)
|
||||||
|
{
|
||||||
|
// NoChange
|
||||||
|
if (this.isActive() == active) return;
|
||||||
|
|
||||||
|
// Before
|
||||||
|
Picker before = this.getInstance();
|
||||||
|
|
||||||
|
// After
|
||||||
|
Picker after;
|
||||||
|
if (active)
|
||||||
|
{
|
||||||
|
// This
|
||||||
|
after = this;
|
||||||
|
|
||||||
|
// Alternatives
|
||||||
|
for (Class<?> alternative : this.getAlternatives())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Picker alternativeInstance = ReflectionUtil.getSingletonInstance(alternative);
|
||||||
|
after = alternativeInstance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
// Not Compatible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default
|
||||||
|
after = this.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deactivate Before
|
||||||
|
if (before != this) before.setActive(false);
|
||||||
|
|
||||||
|
// Set Instance
|
||||||
|
this.setInstance(after);
|
||||||
|
|
||||||
|
// Activate After
|
||||||
|
if (after != this) after.setActive(true);
|
||||||
|
|
||||||
|
// Super
|
||||||
|
if (after == this) super.setActive(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
49
src/com/massivecraft/massivecore/picker/PickerTest.java
Normal file
49
src/com/massivecraft/massivecore/picker/PickerTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.massivecraft.massivecore.picker;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
public class PickerTest extends Picker
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DEFAULT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final PickerTest d = new PickerTest().setAlternatives(
|
||||||
|
PickerTestImpossible.class,
|
||||||
|
PickerTestPossible.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final PickerTest i = d;
|
||||||
|
public static PickerTest get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public PickerTest()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// METHODS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void action()
|
||||||
|
{
|
||||||
|
String msg = this.getMsg();
|
||||||
|
String message = Txt.parse(msg);
|
||||||
|
MassiveCore.get().log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg()
|
||||||
|
{
|
||||||
|
return "<silver>Default...";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.massivecraft.massivecore.picker;
|
||||||
|
|
||||||
|
public class PickerTestImpossible extends PickerTest
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final PickerTestImpossible i = new PickerTestImpossible();
|
||||||
|
public static PickerTestImpossible get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// PROVOKE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object provoke() throws Throwable
|
||||||
|
{
|
||||||
|
throw new RuntimeException("so provokative!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// METHODS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMsg()
|
||||||
|
{
|
||||||
|
return "<rose>Impossible and Unexpected";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.massivecraft.massivecore.picker;
|
||||||
|
|
||||||
|
public class PickerTestPossible extends PickerTest
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final PickerTestPossible i = new PickerTestPossible();
|
||||||
|
public static PickerTestPossible get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// METHODS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMsg()
|
||||||
|
{
|
||||||
|
return "<lime>Possible and Expected";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -89,7 +89,7 @@ public class ReflectionUtil
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Method ret = clazz.getMethod(name, parameterTypes);
|
Method ret = clazz.getDeclaredMethod(name, parameterTypes);
|
||||||
makeAccessible(ret);
|
makeAccessible(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ public class ReflectionUtil
|
|||||||
// SINGLETON INSTANCE
|
// SINGLETON INSTANCE
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
public static <T> T getSingletonInstance(Class<T> clazz)
|
public static <T> T getSingletonInstance(Class<?> clazz)
|
||||||
{
|
{
|
||||||
Method get = getMethod(clazz, "get");
|
Method get = getMethod(clazz, "get");
|
||||||
T ret = invokeMethod(get, null);
|
T ret = invokeMethod(get, null);
|
||||||
@ -369,16 +369,16 @@ public class ReflectionUtil
|
|||||||
// AS RUNTIME EXCEPTION
|
// AS RUNTIME EXCEPTION
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
public static RuntimeException asRuntimeException(Throwable e)
|
public static RuntimeException asRuntimeException(Throwable t)
|
||||||
{
|
{
|
||||||
// Runtime
|
// Runtime
|
||||||
if (e instanceof RuntimeException) return (RuntimeException) e;
|
if (t instanceof RuntimeException) return (RuntimeException) t;
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
if (e instanceof InvocationTargetException) return asRuntimeException(((InvocationTargetException)e).getCause());
|
if (t instanceof InvocationTargetException) return asRuntimeException(((InvocationTargetException)t).getCause());
|
||||||
|
|
||||||
// Rest
|
// Rest
|
||||||
return new IllegalStateException(e.getClass().getSimpleName() + ": " + e.getMessage());
|
return new IllegalStateException(t.getClass().getSimpleName() + ": " + t.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user