Skip to content

Commit

Permalink
IBean is not self typed anymore:
Browse files Browse the repository at this point in the history
- Enables full inheritance features
- Simplified generic stuff
  • Loading branch information
SimonDan committed Mar 15, 2020
1 parent 77543f6 commit 4ba7230
Show file tree
Hide file tree
Showing 65 changed files with 260 additions and 269 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ public Set<BeanReference> getDirectReferences()
}

@Override
public void addWeakReference(IBean<?> pBean, IField<?> pField)
public void addWeakReference(IBean pBean, IField<?> pField)
{
final IEncapsulatedBeanData encapsulatedData = requestEncapsulatedDataForField(pBean, pField);
weakReferencesMapping.computeIfAbsent(encapsulatedData, pKey -> new HashSet<>()).add(new BeanReference(pBean, pField));
}

@Override
public void removeReference(IBean<?> pBean, IField<?> pField)
public void removeReference(IBean pBean, IField<?> pField)
{
final IEncapsulatedBeanData encapsulatedData = requestEncapsulatedDataForField(pBean, pField);
boolean removed = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @author Simon Danner, 23.08.2016
*/
@RequiresEncapsulatedAccess
public class BeanContainer<BEAN extends IBean<BEAN>> implements IBeanContainer<BEAN>
public class BeanContainer<BEAN extends IBean> implements IBeanContainer<BEAN>
{
private final IEncapsulatedBeanContainerData<BEAN> encapsulatedData;

Expand Down
32 changes: 16 additions & 16 deletions ojcms-beans/src/main/java/de/adito/ojcms/beans/BeanCopies.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ private BeanCopies()
* @param pCustomCopies a collection of custom copy mechanisms for specific bean fields
* @return a copy of the bean
*/
static <BEAN extends IBean<BEAN>> BEAN doCreateCopy(BEAN pOriginal, ECopyMode pMode, CustomFieldCopy<?>... pCustomCopies)
static IBean doCreateCopy(IBean pOriginal, ECopyMode pMode, CustomFieldCopy<?>... pCustomCopies)
{
requestEncapsulatedData(pOriginal); //Check if the data core is present
//noinspection unchecked
final Class<BEAN> beanType = (Class<BEAN>) BeanReflector.requiresDeclaredBeanType(pOriginal.getClass());
final Class<? extends IBean> beanType = BeanReflector.requiresDeclaredBeanType(pOriginal.getClass());
final List<IField<?>> fieldOrder = pOriginal.streamFields().collect(Collectors.toList());
final BEAN copyInstance = _createBeanPerDefaultConstructorAndSetDataSource(beanType, fieldOrder)

final IBean copyInstance = _createBeanPerDefaultConstructorAndSetDataSource(beanType)
.orElse(_createBeanSneakyAndInjectEncapsulatedData(beanType, fieldOrder));

return _setValues(pOriginal, copyInstance, pMode, pCustomCopies);
}

Expand All @@ -67,26 +68,25 @@ static <BEAN extends IBean<BEAN>> BEAN doCreateCopy(BEAN pOriginal, ECopyMode pM
* @param pCustomCopies a collection of custom copy mechanisms for specific bean fields
* @return a copy of the bean
*/
static <BEAN extends IBean<BEAN>> BEAN doCreateCopy(BEAN pOriginal, ECopyMode pMode, UnaryOperator<BEAN> pCustomConstructorCall,
CustomFieldCopy<?>... pCustomCopies)
static <BEAN extends IBean> BEAN doCreateCopy(BEAN pOriginal, ECopyMode pMode, UnaryOperator<BEAN> pCustomConstructorCall,
CustomFieldCopy<?>... pCustomCopies)
{
requestEncapsulatedData(pOriginal); //Check if the data core is present
return _setValues(pOriginal, pCustomConstructorCall.apply(pOriginal), pMode, pCustomCopies);
//noinspection unchecked
return (BEAN) _setValues(pOriginal, pCustomConstructorCall.apply(pOriginal), pMode, pCustomCopies);
}

/**
* Tries to create the bean copy per default constructor call.
*
* @param pBeanType the bean type to copy
* @param <BEAN> the generic bean type
* @return an optional instance of the copied bean
*/
private static <BEAN extends IBean<BEAN>> Optional<BEAN> _createBeanPerDefaultConstructorAndSetDataSource(Class<BEAN> pBeanType,
List<IField<?>> pFieldOrder)
private static Optional<IBean> _createBeanPerDefaultConstructorAndSetDataSource(Class<? extends IBean> pBeanType)
{
try
{
final BEAN bean = pBeanType.getDeclaredConstructor().newInstance();
final IBean bean = pBeanType.getDeclaredConstructor().newInstance();
return Optional.of(bean);
}
catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException pE)
Expand All @@ -101,12 +101,11 @@ private static <BEAN extends IBean<BEAN>> Optional<BEAN> _createBeanPerDefaultCo
*
* @param pBeanType the type of the bean to create
* @param pFieldOrder the ordered fields of the bean
* @param <BEAN> the generic type of the bean
* @return the created bean instance
*/
private static <BEAN extends IBean<BEAN>> BEAN _createBeanSneakyAndInjectEncapsulatedData(Class<BEAN> pBeanType, List<IField<?>> pFieldOrder)
private static IBean _createBeanSneakyAndInjectEncapsulatedData(Class<? extends IBean> pBeanType, List<IField<?>> pFieldOrder)
{
final BEAN bean = COPY_CREATOR.newInstance(pBeanType);
final IBean bean = COPY_CREATOR.newInstance(pBeanType);
final IBeanDataSource dataSource = new MapBasedBeanDataSource(pFieldOrder);
final EncapsulatedBeanData encapsulatedData = new EncapsulatedBeanData(dataSource, pFieldOrder);
try
Expand All @@ -133,15 +132,15 @@ private static <BEAN extends IBean<BEAN>> BEAN _createBeanSneakyAndInjectEncapsu
* @param pCopy the copied bean
* @param pMode the copy mode
* @param pCustomCopies a collection of custom copy mechanisms for specific bean fields
* @param <BEAN> the type of the bean to set the values
* @return the copy of the bean
*/
private static <BEAN extends IBean<BEAN>> BEAN _setValues(BEAN pOriginal, BEAN pCopy, ECopyMode pMode, CustomFieldCopy<?>[] pCustomCopies)
private static IBean _setValues(IBean pOriginal, IBean pCopy, ECopyMode pMode, CustomFieldCopy<?>[] pCustomCopies)
{
final _BeanValueCopyCreator beanValueCopyCreator = new _BeanValueCopyCreator(pMode, pCustomCopies);
//noinspection unchecked,RedundantCast
requestEncapsulatedData(pOriginal).streamFields()
.forEach(pField -> pCopy.setValue((IField) pField, beanValueCopyCreator.copyFieldValue((IField) pField, pOriginal.getValue(pField))));

//If required set non bean values as well
if (pMode.shouldCopyAllFields())
{
Expand All @@ -160,6 +159,7 @@ private static <BEAN extends IBean<BEAN>> BEAN _setValues(BEAN pOriginal, BEAN p
}
});
}

return pCopy;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
public final class BeanCreationEvents
{
private static final Map<Class<? extends IBean>, PublishSubject<IBean<?>>> PUBLISHERS_BY_TYPE = new ConcurrentHashMap<>();
private static final Map<Class<? extends IBean>, PublishSubject<IBean>> PUBLISHERS_BY_TYPE = new ConcurrentHashMap<>();
private static final Map<Class<? extends Annotation>, PublishSubject<? extends BeanCreationEvent<?>>> PUBLISHERS_BY_ANNOTATION = new ConcurrentHashMap<>();

private BeanCreationEvents()
Expand All @@ -35,7 +35,7 @@ private BeanCreationEvents()
* @param pBeanType the bean's type to observe creations of
* @param <BEAN> the generic runtime type of the bean
*/
public static <BEAN extends IBean<BEAN>> Observable<BEAN> observeCreationByBeanType(Class<BEAN> pBeanType)
public static <BEAN extends IBean> Observable<BEAN> observeCreationByBeanType(Class<BEAN> pBeanType)
{
_getObservableAnnotation(pBeanType); //check, if annotation is present
//noinspection unchecked
Expand Down Expand Up @@ -64,7 +64,7 @@ public static <ANNOTATION extends Annotation> Observable<BeanCreationEvent<ANNOT
*
* @param pCreatedBean the newly created bean
*/
static void fireCreationIfAnnotationPresent(IBean<?> pCreatedBean)
static void fireCreationIfAnnotationPresent(IBean pCreatedBean)
{
if (_observersPresent() && hasObservableAnnotation(pCreatedBean.getClass()))
fireCreation(pCreatedBean);
Expand All @@ -75,7 +75,7 @@ static void fireCreationIfAnnotationPresent(IBean<?> pCreatedBean)
*
* @param pCreatedBean the created bean
*/
static void fireCreation(IBean<?> pCreatedBean)
static void fireCreation(IBean pCreatedBean)
{
if (!_observersPresent())
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@
import java.util.*;
import java.util.function.*;

import static de.adito.ojcms.beans.BeanFieldFactory.createField;

/**
* Utility to add bean fields.
*
* @param <BEAN> the runtime type of the bean the field is for
* @param <VALUE> the data type of the field to add
* @param <FIELD> the runtime type of the field to add/create
* @author Simon Danner, 25.12.2018
*/
public final class BeanFieldAdder<BEAN extends IBean<BEAN>, VALUE, FIELD extends IField<VALUE>>
public final class BeanFieldAdder<VALUE, FIELD extends IField<VALUE>>
{
private final ObjIntConsumer<FIELD> addFunction;
private final IntSupplier fieldCountSupplier;
private final Class<FIELD> beanFieldType;
private final String fieldName;
private final Collection<Annotation> annotations;
private Optional<BiPredicate<BEAN, VALUE>> activeCondition = Optional.empty();
private BiPredicate<? extends IBean, VALUE> activeCondition;
private Class<?> genericType;

/**
Expand Down Expand Up @@ -51,7 +52,7 @@ public final class BeanFieldAdder<BEAN extends IBean<BEAN>, VALUE, FIELD extends
* @param pGenericType the generic type of the field to add
* @return the bean field adder itself to enable a pipelining mechanism
*/
public BeanFieldAdder<BEAN, VALUE, FIELD> withGenericType(Class<?> pGenericType)
public BeanFieldAdder<VALUE, FIELD> withGenericType(Class<?> pGenericType)
{
genericType = pGenericType;
return this;
Expand All @@ -63,9 +64,9 @@ public BeanFieldAdder<BEAN, VALUE, FIELD> withGenericType(Class<?> pGenericType)
* @param pActiveCondition the condition to determine the active state of the field
* @return the bean field adder itself to enable a pipelining mechanism
*/
public BeanFieldAdder<BEAN, VALUE, FIELD> optionalField(BiPredicate<BEAN, VALUE> pActiveCondition)
public <BEAN extends IBean> BeanFieldAdder<VALUE, FIELD> optionalField(BiPredicate<BEAN, VALUE> pActiveCondition)
{
activeCondition = Optional.of(pActiveCondition);
activeCondition = pActiveCondition;
return this;
}

Expand All @@ -87,7 +88,7 @@ public FIELD addAtTheEnd()
*/
public FIELD addAtIndex(int pIndex)
{
final FIELD field = BeanFieldFactory.createField(beanFieldType, () -> genericType, fieldName, false, annotations, activeCondition);
final FIELD field = createField(beanFieldType, () -> genericType, fieldName, false, annotations, activeCondition);
addFunction.accept(field, pIndex);
return field;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import de.adito.ojcms.beans.exceptions.OJInternalException;
import de.adito.ojcms.beans.literals.IAdditionalMemberInfo;
import de.adito.ojcms.beans.literals.fields.IField;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;
Expand Down Expand Up @@ -37,9 +38,9 @@ private BeanFieldFactory()
* @param <FIELD> the generic field type
* @return the newly created field
*/
static <BEAN extends IBean<BEAN>, VALUE, FIELD extends IField<VALUE>> FIELD createField(Class<FIELD> pFieldType, String pName,
boolean pIsPrivate, Collection<Annotation> pAnnotations,
Optional<BiPredicate<BEAN, VALUE>> pActiveCondition)
static <VALUE, FIELD extends IField<VALUE>> FIELD createField(Class<FIELD> pFieldType, String pName, boolean pIsPrivate,
Collection<Annotation> pAnnotations,
@Nullable BiPredicate<? extends IBean, VALUE> pActiveCondition)
{
return createField(pFieldType, () -> null, pName, pIsPrivate, pAnnotations, pActiveCondition);
}
Expand All @@ -56,36 +57,38 @@ static <BEAN extends IBean<BEAN>, VALUE, FIELD extends IField<VALUE>> FIELD crea
* @param pIsPrivate determines if the field is declared privately
* @param pAnnotations the field's annotations
* @param pActiveCondition an optional condition for optional bean fields (determines the active state of the field)
* @param <BEAN> the generic type of the bean the field is for
* @param <VALUE> the data type of the field to create
* @param <FIELD> the generic field type
* @return the newly created field
*/
static <BEAN extends IBean<?>, VALUE, FIELD extends IField<VALUE>> FIELD createField(Class<FIELD> pFieldType,
Supplier<Class<?>> pGenericTypeSupplier,
String pName, boolean pIsPrivate,
Collection<Annotation> pAnnotations,
Optional<BiPredicate<BEAN, VALUE>> pActiveCondition)
static <VALUE, FIELD extends IField<VALUE>> FIELD createField(Class<FIELD> pFieldType, Supplier<Class<?>> pGenericTypeSupplier,
String pName, boolean pIsPrivate, Collection<Annotation> pAnnotations,
@Nullable BiPredicate<? extends IBean, VALUE> pActiveCondition)
{
try
{
final Optional<Class<?>> optionalGenericType = _getGenericType(pFieldType, pGenericTypeSupplier);
final boolean isOptional = pActiveCondition.isPresent();
final boolean isOptional = pActiveCondition != null;
//Constructor argument distinction between generic and non generic values (generic types provide their type additionally)
final Class[] constructorArgumentTypes = optionalGenericType
.map(pType -> new Class[]{Class.class, String.class, Collection.class, boolean.class, boolean.class})
.orElseGet(() -> new Class[]{String.class, Collection.class, boolean.class, boolean.class});

final Object[] constructorArguments = optionalGenericType
.map(pClass -> new Object[]{pClass, pName, pAnnotations, isOptional, pIsPrivate})
.orElseGet(() -> new Object[]{pName, pAnnotations, isOptional, pIsPrivate});

//Create the field by using the reflected constructor
final Constructor<FIELD> constructor = pFieldType.getDeclaredConstructor(constructorArgumentTypes);
if (!constructor.isAccessible())
constructor.setAccessible(true);

final FIELD field = constructor.newInstance(constructorArguments);

//Add the optional condition as field info to determine the state of the field later on
if (isOptional)
field.addAdditionalInformation(OPTIONAL_FIELD_INFO, pActiveCondition.get());
field.addAdditionalInformation(OPTIONAL_FIELD_INFO, pActiveCondition);

return field;
}
catch (NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException pE)
Expand Down
Loading

0 comments on commit 4ba7230

Please sign in to comment.