Mostly javadoc, and also some fixes there and there
This commit is contained in:
@@ -12,5 +12,9 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ConcreteWrapper {
|
||||
/**
|
||||
* The class representing a dummy implementation of the annotated wrapper interface.
|
||||
* @return the class representing a dummy implementation of the annotated wrapper interface.
|
||||
*/
|
||||
Class<? extends ReflectWrapper> value();
|
||||
}
|
||||
|
@@ -6,6 +6,11 @@ import java.util.function.Supplier;
|
||||
|
||||
import fr.pandacube.lib.util.MappedListView;
|
||||
|
||||
/**
|
||||
* A wrapper for a list of wrapped object. It is an extension of {@link MappedListView} that is used to transparently
|
||||
* wrap/unwrap the elements of the backend list.
|
||||
* @param <W> the type of the reflect wrapper for the elements of this list.
|
||||
*/
|
||||
public class ReflectListWrapper<W extends ReflectWrapperI> extends MappedListView<Object, W> implements ReflectWrapperTypedI<List<Object>> {
|
||||
|
||||
private final Class<W> expectedWrapperClass;
|
||||
@@ -14,11 +19,12 @@ public class ReflectListWrapper<W extends ReflectWrapperI> extends MappedListVie
|
||||
this(ArrayList::new, expectedWrapperClass);
|
||||
}
|
||||
|
||||
/* package */
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ReflectListWrapper(Supplier<List<?>> listCreator, Class<W> expectedWrapperClass) {
|
||||
/* package */ ReflectListWrapper(Supplier<List<?>> listCreator, Class<W> expectedWrapperClass) {
|
||||
this((List<Object>) (listCreator == null ? new ArrayList<>() : listCreator.get()), expectedWrapperClass);
|
||||
}
|
||||
|
||||
/* package */ ReflectListWrapper(List<Object> wrappedList, Class<W> expectedWrapperClass) {
|
||||
super(wrappedList, el -> ReflectWrapper.wrap(el, expectedWrapperClass), ReflectWrapper::unwrap);
|
||||
this.expectedWrapperClass = expectedWrapperClass;
|
||||
|
@@ -10,25 +10,79 @@ import java.util.Objects;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
/**
|
||||
* Superclass of all reflect wrapper objects.
|
||||
*/
|
||||
public abstract class ReflectWrapper implements ReflectWrapperI {
|
||||
|
||||
|
||||
private static final Map<Object, ReflectWrapperI> objectWrapperCache = new MapMaker().weakKeys().makeMap();
|
||||
|
||||
/**
|
||||
* Unwraps the object from the provided reflect wrapper.
|
||||
* @param wr the reflect wrapper from which to get the object.
|
||||
* @return the object from the provided reflect wrapper.
|
||||
*/
|
||||
public static Object unwrap(ReflectWrapperI wr) {
|
||||
return wr == null ? null : wr.__getRuntimeInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps the object from the provided reflect wrapper.
|
||||
* @param wr the reflect wrapper from which to get the object.
|
||||
* @param <T> the type of the wrapped object.
|
||||
* @return the object from the provided reflect wrapper.
|
||||
*/
|
||||
public static <T> T unwrap(ReflectWrapperTypedI<T> wr) {
|
||||
return wr == null ? null : wr.__getRuntimeInstance();
|
||||
}
|
||||
|
||||
public static <W extends ReflectWrapperI> W wrap(Object runtimeObj) {
|
||||
/**
|
||||
* Wraps the provided runtime object into a reflect wrapper.
|
||||
* If a wrapper instance is already known, it will return it instead of instanciating a new one.
|
||||
* It is better to call {@link #wrap(Object, Class)} if you know the type of wrapper needed.
|
||||
* @param runtimeObj the object to wrap.
|
||||
* @return the reflect wrapper wrapping the provided object.
|
||||
* @throws ClassCastException if the runtime class of the object is not handled by the expected wrapper class or its
|
||||
* subclasses.
|
||||
* @throws IllegalArgumentException if the runtime class of the object is not handled by any of the registered
|
||||
* wrapper classes.
|
||||
*/
|
||||
public static ReflectWrapperI wrap(Object runtimeObj) {
|
||||
return wrap(runtimeObj, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the provided runtime object (with has a known type) into a reflect wrapper.
|
||||
* If a wrapper instance is already known, it will return it instead of instanciating a new one.
|
||||
* It is better to call {@link #wrap(Object, Class)} if you know the type of wrapper needed.
|
||||
* @param runtimeObj the object to wrap.
|
||||
* @param expectedWrapperClass the reflect wrapper class expected to be returned.
|
||||
* @param <W> the type of the reflect wrapper.
|
||||
* @param <T> the type of the wrapped object.
|
||||
* @return the reflect wrapper wrapping the provided object.
|
||||
* @throws ClassCastException if the runtime class of the object is not handled by the expected wrapper class or its
|
||||
* subclasses.
|
||||
* @throws IllegalArgumentException if the runtime class of the object is not handled by any of the registered
|
||||
* wrapper classes.
|
||||
*/
|
||||
public static <T, W extends ReflectWrapperTypedI<T>> W wrapTyped(T runtimeObj, Class<W> expectedWrapperClass) {
|
||||
return wrap(runtimeObj, expectedWrapperClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the provided runtime object into a reflect wrapper.
|
||||
* If a wrapper instance is already known, it will return it instead of instanciating a new one.
|
||||
* It is better to call {@link #wrap(Object, Class)} if you know the type of wrapper needed.
|
||||
* @param runtimeObj the object to wrap.
|
||||
* @param expectedWrapperClass the reflect wrapper class expected to be returned.
|
||||
* @param <W> the type of the reflect wrapper.
|
||||
* @return the reflect wrapper wrapping the provided object.
|
||||
* @throws ClassCastException if the runtime class of the object is not handled by the expected wrapper class or its
|
||||
* subclasses.
|
||||
* @throws IllegalArgumentException if the runtime class of the object is not handled by any of the registered
|
||||
* wrapper classes.
|
||||
*/
|
||||
public static <W extends ReflectWrapperI> W wrap(Object runtimeObj, Class<W> expectedWrapperClass) {
|
||||
if (runtimeObj == null)
|
||||
return null;
|
||||
@@ -73,16 +127,36 @@ public abstract class ReflectWrapper implements ReflectWrapperI {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the provided runtime list into a reflect list wrapper.
|
||||
* @param runtimeList the list of runtime object to wrap.
|
||||
* @param expectedWrapperClass the wrapper class of the objects in this list.
|
||||
* @param <W> the type of reflect wrapper for the objects in this list.
|
||||
* @return a reflect list wrapper wrapping the provided list.
|
||||
*/
|
||||
public static <W extends ReflectWrapperI> ReflectListWrapper<W> wrapList(List<Object> runtimeList, Class<W> expectedWrapperClass) {
|
||||
return new ReflectListWrapper<>(runtimeList, expectedWrapperClass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected final Object reflectObject;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private final Object reflectObject;
|
||||
|
||||
/**
|
||||
* Instanciate this Reflect Wrapper with the provided object.
|
||||
* Any subclasses should not make their constructor public since the instanciation is managed by {@link #wrap(Object, Class) wrap(...)}.
|
||||
* @param obj the object to wrap. It must be an instance of the {@link #__getRuntimeClass() runtime class} of this
|
||||
* wrapper class.
|
||||
*/
|
||||
protected ReflectWrapper(Object obj) {
|
||||
Objects.requireNonNull(obj);
|
||||
if (!__getRuntimeClass().isInstance(obj)) {
|
||||
|
@@ -1,11 +1,22 @@
|
||||
package fr.pandacube.lib.reflect.wrapper;
|
||||
|
||||
/**
|
||||
* Interface implemented by all reflect wrapper objects.
|
||||
*/
|
||||
public interface ReflectWrapperI {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the class of the wrapped object.
|
||||
* @return the class of the wrapped object.
|
||||
*/
|
||||
default Class<?> __getRuntimeClass() {
|
||||
return WrapperRegistry.getRuntimeClassOfWrapperClass(getClass());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the wrapped object.
|
||||
* @return the wrapped object.
|
||||
*/
|
||||
Object __getRuntimeInstance();
|
||||
|
||||
|
||||
|
@@ -1,7 +1,17 @@
|
||||
package fr.pandacube.lib.reflect.wrapper;
|
||||
|
||||
/**
|
||||
* Superclass of all reflect wrapper objects which wrapped objet type is statically known.
|
||||
* @param <T> the type (or supertype) of the wrapped object.
|
||||
*/
|
||||
public abstract class ReflectWrapperTyped<T> extends ReflectWrapper implements ReflectWrapperTypedI<T> {
|
||||
|
||||
/**
|
||||
* Instanciate this Reflect Wrapper with the provided object.
|
||||
* Any subclasses should not make their constructor public since the instanciation is managed by {@link #wrap(Object, Class) wrap(...)}.
|
||||
* @param obj the object to wrap. It must be an instance of the {@link #__getRuntimeClass() runtime class} of this
|
||||
* wrapper class.
|
||||
*/
|
||||
protected ReflectWrapperTyped(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@@ -1,5 +1,9 @@
|
||||
package fr.pandacube.lib.reflect.wrapper;
|
||||
|
||||
/**
|
||||
* Interface implemented by all reflect wrapper objects which wrapped objet type is statically known.
|
||||
* @param <T> the type (or supertype) of the wrapped object.
|
||||
*/
|
||||
public interface ReflectWrapperTypedI<T> extends ReflectWrapperI {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user