messing preparations for MemberShareService, e.g. DefaultEnumPersistentObjectMapper and mapping in MemberShareVO

This commit is contained in:
Michael Hoennig 2017-04-14 18:15:40 +02:00
parent 93b7e8b8c5
commit 2c9785af14
9 changed files with 184 additions and 9 deletions

View File

@ -1,6 +1,6 @@
package de.hsadmin.bo.customer;
/** Transaktionstpy für Geschäftsanteile {@link MemberShare}.
/** Transaktionstyp für Geschaeftsanteile {@link MemberShare}.
*/
public enum ShareAction {

View File

@ -10,6 +10,8 @@ import de.hsadmin.module.property.ReadWritePolicy;
import de.hsadmin.module.property.Required;
import de.hsadmin.module.property.Search;
import de.hsadmin.module.property.SearchPolicy;
import de.hsadmin.module.property.mapping.DefaultEnumParameterMapMapper;
import de.hsadmin.module.property.mapping.DefaultEnumPersistentObjectMapper;
import de.hsadmin.module.property.mapping.DefaultStringParameterMapMapper;
import de.hsadmin.module.property.mapping.Mapping;
import de.hsadmin.module.property.mapping.ReferredStringPersistentObjectMapper;
@ -24,6 +26,9 @@ public class MemberShareVO extends AbstractVO implements ValueObject {
@Search(SearchPolicy.EQUALS)
private String customer;
@Mapping(boMapping=DefaultEnumPersistentObjectMapper.class,
rpcMapping=DefaultEnumParameterMapMapper.class,
boMappingPath="customer.name")
@ReadWrite(ReadWritePolicy.WRITEONCE)
@Required(true)
@Search(SearchPolicy.EQUALS)
@ -87,4 +92,10 @@ public class MemberShareVO extends AbstractVO implements ValueObject {
public void setComment(String comment) {
this.comment = comment;
}
@Override
public String toString() {
return "MemberShareVO [customer=" + customer + ", action=" + action + ", date=" + date + ", quantity="
+ quantity + ", comment=" + comment + "]";
}
}

View File

@ -3,6 +3,8 @@ package de.hsadmin.service.customer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.h2.command.ddl.CreateAggregate;
import static junitparams.JUnitParamsRunner.$;
import org.joda.time.LocalDate;
@ -37,12 +39,27 @@ public class MemberShareVOTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
// --- tests ---
// --- special tests ---
@Test
public void toStringTest() throws TechnicalException, UserException {
MemberShareVO vo = givenInitializedMemberShareVOForCustomer(INITIAL_CUSTOMER);
// ACHTUNG:
// Wenn die toString() Implementierung geaendert wurde,
// koennten auch andere Tests fehlschlagen.
// Wenn Felder aus dem toString() herausgenommen werden,
// koennten sogar andere Tests stillschweigend wirkungslos werden!
assertEquals("MemberShareVO [customer=initCust, action=SUBSCRIPTION, date=Thu Dec 26 00:00:00 CET 1996, quantity=4, comment=initial comment]", vo.toString());
}
// --- generic tests ---
@Test
@Parameters(method = "properties")
public void propertyIsRequired(final String propertyName) throws UserException, TechnicalException {
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVO();
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVOForCustomer(INITIAL_CUSTOMER);
initializedMemberShareVO.get(propertyName).setValue(null);
assertInitialPropertyValueIsNull(initializedMemberShareVO, propertyName);
assertPrototypeIsNotCreateable(initializedMemberShareVO, "MSG_REQUIRED_FIELD: " + propertyName);
@ -61,7 +78,7 @@ public class MemberShareVOTest {
@Test
@Parameters(method = "propertiesWithInitialValues")
public void propertyIsCreatable(final String propertyName, final Object initialValue) throws UserException, TechnicalException {
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVO();
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVOForCustomer(INITIAL_CUSTOMER);
assertInitialPropertyValue(initializedMemberShareVO, propertyName, initialValue);
assertPrototypeIsCreateable(initializedMemberShareVO);
}
@ -79,7 +96,7 @@ public class MemberShareVOTest {
@Test
@Parameters(method = "propertiesWithChangedValues")
public void propertyIsNotUpdateable(final String propertyName, final Object changedValue) throws UserException, TechnicalException {
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVO();
MemberShareVO initializedMemberShareVO = givenInitializedMemberShareVOForCustomer(INITIAL_CUSTOMER);
assertChangedPropertyValue(initializedMemberShareVO, propertyName, changedValue);
assertPrototypeIsNotUpdateable(initializedMemberShareVO, "MSG_NO_FIELD_WRITEACCESS: " + propertyName);
}
@ -96,9 +113,15 @@ public class MemberShareVOTest {
// === test fixture ===
private MemberShareVO givenInitializedMemberShareVO() throws TechnicalException, UserException {
public static MemberShareVO givenEmptyMemberShareVOForCustomer(String customerName) throws TechnicalException, UserException {
MemberShareVO memberShareVO = new MemberShareVO();
memberShareVO.setCustomer(INITIAL_CUSTOMER);
memberShareVO.setCustomer(customerName);
return memberShareVO;
}
public static MemberShareVO givenInitializedMemberShareVOForCustomer(String customerName) throws TechnicalException, UserException {
MemberShareVO memberShareVO = new MemberShareVO();
memberShareVO.setCustomer(customerName);
memberShareVO.setAction(INITIAL_ACTION);
memberShareVO.setDate( INITIAL_DATE.toDate() );
memberShareVO.setQuantity(INITIAL_QUANTITY);

View File

@ -92,4 +92,12 @@ public class ReflectionUtil {
return EqualsBuilder.reflectionEquals(o1, 2, excludesFieldNames);
}
public static Class<?> getFieldType(Object persistentObject, String propertyName) throws TechnicalException {
try {
return persistentObject.getClass().getDeclaredField(propertyName).getType();
} catch (NoSuchFieldException | SecurityException e) {
throw new TechnicalException(e);
}
}
}

View File

@ -23,7 +23,7 @@ public abstract class AbstractProperty<T> implements Property<T> {
private PersistentObjectMapper<T> persistentObjectMapper;
private ParameterMapMapper<T> parameterMapMapper;
protected boolean undefinedValue;
protected boolean undefinedValue;
public AbstractProperty(
final ValueObject owner,

View File

@ -0,0 +1,33 @@
package de.hsadmin.module.property.mapping;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
import de.hsadmin.common.util.ReflectionUtil;
public class DefaultEnumPersistentObjectMapper implements PersistentObjectMapper<String> {
@Override
public String readValueFromPersistentObject(Object persistentObject, String propertyName)
throws TechnicalException, UserException {
final Object object = ReflectionUtil.invokeGetter(persistentObject, propertyName);
if (object instanceof String) {
return (String) object;
} else {
if (object instanceof Enum) {
return object.toString();
} else {
return null;
}
}
}
@Override
public void writeValueToPersistentObject(Object persistentObject, String propertyName, String value)
throws TechnicalException, UserException {
Class<?> propertyClass = ReflectionUtil.getFieldType(persistentObject, propertyName);
@SuppressWarnings("unchecked")
Enum<?> enumValue = Enum.valueOf(propertyClass.asSubclass(Enum.class), value);
ReflectionUtil.invokeSetter(persistentObject, propertyName, enumValue);
}
}

View File

@ -31,7 +31,10 @@ public class ReferredStringPersistentObjectMapper implements PersistentObjectMap
@Override
public void writeValueToPersistentObject(final Object persistentObject,
final String propertyName, final String value) throws TechnicalException {
throw new TechnicalException("writeValueToPersistentObject not implemented");
// FIXME MHOENNIG->PHORMANS: Statt dieser Exception müsste man evtl. nur sicherstellen,
// dass der Service das Feld belegt hat, oder?
// Verstehe ur nicht, wie das jemals funktioniert haben konnte.
// throw new TechnicalException("writeValueToPersistentObject not implemented");
}
}

View File

@ -0,0 +1,69 @@
package de.hsadmin.module.property.mapping;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
public class DefaultEnumPersistentObjectMapperTest {
private DefaultEnumPersistentObjectMapper mapper = new DefaultEnumPersistentObjectMapper();
@Test
public void readValueFromPersistentObjectHavingEnum() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(SomeEnum.V1);
assertEquals( "V1", mapper.readValueFromPersistentObject(persistentObject, "someEnumProp"));
}
@Test
public void readValueFromPersistentObjectHavingString() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(SomeEnum.V2);
assertEquals( "V2", mapper.readValueFromPersistentObject(persistentObject, "someStringProp"));
}
@Test
public void writeValueToPersistentObject() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(SomeEnum.V3);
mapper.writeValueToPersistentObject(persistentObject, "someEnumProp", "V3");
assertEquals(SomeEnum.V3, persistentObject.getSomeEnumProp());
}
public static class SomeBO {
private SomeEnum someEnumProp;
private String someStringProp;
public SomeBO(SomeEnum someProp) {
this.someEnumProp = someProp;
this.someStringProp = someProp.name();
}
public SomeEnum getSomeEnumProp() {
return someEnumProp;
}
public void setSomeEnumProp(SomeEnum someProp) {
this.someEnumProp = someProp;
}
public String getSomeStringProp() {
return someStringProp;
}
public void setSomeStringProp(String someStringProp) {
this.someStringProp = someStringProp;
}
}
public static enum SomeEnum {
V1, V2, V3;
}
}

View File

@ -0,0 +1,28 @@
package de.hsadmin.test;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class CauseMatcher extends TypeSafeMatcher<Throwable> {
private final Class<? extends Throwable> expectedExceptionTpe;
private final String expectedMessage;
public CauseMatcher(Class<? extends Throwable> expectedExceptionTpe, String expectedMessage) {
this.expectedExceptionTpe = expectedExceptionTpe;
this.expectedMessage = expectedMessage;
}
@Override
protected boolean matchesSafely(final Throwable item) {
return item.getClass().isAssignableFrom(expectedExceptionTpe)
&& item.getMessage().contains(expectedMessage);
}
@Override
public void describeTo(final Description description) {
description
.appendText("expects exception of type ").appendValue(expectedExceptionTpe)
.appendText(" and with message ").appendValue(expectedMessage);
}
}