From 2c9785af14ecbfdc48cf72af452ef8f9dea232ae Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 14 Apr 2017 18:15:40 +0200 Subject: [PATCH] messing preparations for MemberShareService, e.g. DefaultEnumPersistentObjectMapper and mapping in MemberShareVO --- .../de/hsadmin/bo/customer/ShareAction.java | 2 +- .../service/customer/MemberShareVO.java | 11 +++ .../service/customer/MemberShareVOTest.java | 35 ++++++++-- .../hsadmin/common/util/ReflectionUtil.java | 8 +++ .../hsadmin/module/impl/AbstractProperty.java | 2 +- .../DefaultEnumPersistentObjectMapper.java | 33 +++++++++ .../ReferredStringPersistentObjectMapper.java | 5 +- ...DefaultEnumPersistentObjectMapperTest.java | 69 +++++++++++++++++++ .../java/de/hsadmin/test/CauseMatcher.java | 28 ++++++++ 9 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 framework/src/main/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapper.java create mode 100644 framework/src/test/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapperTest.java create mode 100644 framework/src/test/java/de/hsadmin/test/CauseMatcher.java diff --git a/cust-services/src/main/java/de/hsadmin/bo/customer/ShareAction.java b/cust-services/src/main/java/de/hsadmin/bo/customer/ShareAction.java index 29cd342..63a75e8 100644 --- a/cust-services/src/main/java/de/hsadmin/bo/customer/ShareAction.java +++ b/cust-services/src/main/java/de/hsadmin/bo/customer/ShareAction.java @@ -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 { diff --git a/cust-services/src/main/java/de/hsadmin/service/customer/MemberShareVO.java b/cust-services/src/main/java/de/hsadmin/service/customer/MemberShareVO.java index 8e772a8..d26abfb 100644 --- a/cust-services/src/main/java/de/hsadmin/service/customer/MemberShareVO.java +++ b/cust-services/src/main/java/de/hsadmin/service/customer/MemberShareVO.java @@ -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 + "]"; + } } diff --git a/cust-services/src/test/java/de/hsadmin/service/customer/MemberShareVOTest.java b/cust-services/src/test/java/de/hsadmin/service/customer/MemberShareVOTest.java index af6b3bd..360f8b6 100644 --- a/cust-services/src/test/java/de/hsadmin/service/customer/MemberShareVOTest.java +++ b/cust-services/src/test/java/de/hsadmin/service/customer/MemberShareVOTest.java @@ -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); diff --git a/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java b/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java index ecc4617..9144bc5 100644 --- a/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java +++ b/framework/src/main/java/de/hsadmin/common/util/ReflectionUtil.java @@ -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); + } + } + } diff --git a/framework/src/main/java/de/hsadmin/module/impl/AbstractProperty.java b/framework/src/main/java/de/hsadmin/module/impl/AbstractProperty.java index d8d582a..d88ce10 100644 --- a/framework/src/main/java/de/hsadmin/module/impl/AbstractProperty.java +++ b/framework/src/main/java/de/hsadmin/module/impl/AbstractProperty.java @@ -23,7 +23,7 @@ public abstract class AbstractProperty implements Property { private PersistentObjectMapper persistentObjectMapper; private ParameterMapMapper parameterMapMapper; - protected boolean undefinedValue; + protected boolean undefinedValue; public AbstractProperty( final ValueObject owner, diff --git a/framework/src/main/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapper.java b/framework/src/main/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapper.java new file mode 100644 index 0000000..20ce420 --- /dev/null +++ b/framework/src/main/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapper.java @@ -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 { + + @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); + } +} \ No newline at end of file diff --git a/framework/src/main/java/de/hsadmin/module/property/mapping/ReferredStringPersistentObjectMapper.java b/framework/src/main/java/de/hsadmin/module/property/mapping/ReferredStringPersistentObjectMapper.java index 8c21869..ef0e3b9 100644 --- a/framework/src/main/java/de/hsadmin/module/property/mapping/ReferredStringPersistentObjectMapper.java +++ b/framework/src/main/java/de/hsadmin/module/property/mapping/ReferredStringPersistentObjectMapper.java @@ -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"); } } diff --git a/framework/src/test/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapperTest.java b/framework/src/test/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapperTest.java new file mode 100644 index 0000000..0e4190e --- /dev/null +++ b/framework/src/test/java/de/hsadmin/module/property/mapping/DefaultEnumPersistentObjectMapperTest.java @@ -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; + } +} + + + + diff --git a/framework/src/test/java/de/hsadmin/test/CauseMatcher.java b/framework/src/test/java/de/hsadmin/test/CauseMatcher.java new file mode 100644 index 0000000..68adea5 --- /dev/null +++ b/framework/src/test/java/de/hsadmin/test/CauseMatcher.java @@ -0,0 +1,28 @@ +package de.hsadmin.test; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +public class CauseMatcher extends TypeSafeMatcher { + + private final Class expectedExceptionTpe; + private final String expectedMessage; + + public CauseMatcher(Class 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); + } +} \ No newline at end of file