BigDecimalProperty + DefaultBigDecimal*Mapper

This commit is contained in:
Michael Hoennig 2017-04-16 14:09:28 +02:00
parent 7894bc88aa
commit 1b44709320
8 changed files with 384 additions and 2 deletions

View File

@ -4,6 +4,10 @@ public class TechnicalException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public TechnicalException(String message, Exception e) {
super(message, e);
}
public TechnicalException(Exception e) { public TechnicalException(Exception e) {
super(e); super(e);
} }

View File

@ -43,7 +43,7 @@ public class ReflectionUtil {
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, anObject.getClass()); final PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, anObject.getClass());
return propertyDescriptor.getReadMethod().invoke(anObject); return propertyDescriptor.getReadMethod().invoke(anObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) {
throw new TechnicalException(e); throw new TechnicalException("cannot get value from " + anObject + "." + propertyName, e);
} }
} }
@ -52,7 +52,7 @@ public class ReflectionUtil {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, anObject.getClass()); PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, anObject.getClass());
propertyDescriptor.getWriteMethod().invoke(anObject, value); propertyDescriptor.getWriteMethod().invoke(anObject, value);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) {
throw new TechnicalException(e); throw new TechnicalException("cannot set " + value + " to " + anObject + "." + propertyName, e);
} }
} }

View File

@ -0,0 +1,33 @@
package de.hsadmin.module.property;
import java.math.BigDecimal;
import de.hsadmin.module.ValueObject;
import de.hsadmin.module.impl.AbstractProperty;
import de.hsadmin.module.property.mapping.DefaultBigDecimalParameterMapMapper;
import de.hsadmin.module.property.mapping.DefaultBigDecimalPersistentObjectMapper;
import de.hsadmin.module.property.mapping.ParameterMapMapper;
import de.hsadmin.module.property.mapping.PersistentObjectMapper;
public class BigDecimalProperty extends AbstractProperty<BigDecimal> implements Property<BigDecimal> {
private static final PersistentObjectMapper<BigDecimal> defaultPersistentObjectMapper;
private static final ParameterMapMapper<BigDecimal> defaultParameterMapMapper;
static {
defaultPersistentObjectMapper = new DefaultBigDecimalPersistentObjectMapper();
defaultParameterMapMapper = new DefaultBigDecimalParameterMapMapper();
}
public BigDecimalProperty(final ValueObject ownerVO, final String propertyName, final ReadWritePolicy readWritePolicy, final SearchPolicy searchPolicy, final boolean required) {
super(ownerVO, propertyName, readWritePolicy, searchPolicy, required);
setPersistentObjectMapper(defaultPersistentObjectMapper);
setParameterMapMapper(defaultParameterMapMapper);
}
@Override
public Class<?> getValueType() {
return BigDecimal.class;
}
}

View File

@ -0,0 +1,38 @@
package de.hsadmin.module.property.mapping;
import java.math.BigDecimal;
import java.util.Map;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
public class DefaultBigDecimalParameterMapMapper implements ParameterMapMapper<BigDecimal> {
@Override
public void writeValueToParameterMap(final Map<String, Object> rpcParameter,
final String propertyName, final BigDecimal value)
throws TechnicalException, UserException {
if (value != null) {
rpcParameter.put(propertyName, value.toString());
}
}
@Override
public BigDecimal readValueFromParameterMap(final Map<String, Object> rpcParameter,
final String propertyName, final Class<?> propertyClass) throws TechnicalException, UserException {
final Object object = rpcParameter.get(propertyName);
if (object instanceof BigDecimal) {
return (BigDecimal) object;
}
if (object instanceof String) {
try {
BigDecimal value = new BigDecimal((String) object);
return value;
} catch (NumberFormatException exc) {
throw new TechnicalException("invalid decimal number '" + object + "'", exc);
}
}
return null;
}
}

View File

@ -0,0 +1,32 @@
package de.hsadmin.module.property.mapping;
import java.math.BigDecimal;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.util.ReflectionUtil;
public class DefaultBigDecimalPersistentObjectMapper implements PersistentObjectMapper<BigDecimal> {
@Override
public void writeValueToPersistentObject(final Object persistentObject, final String propertyName, final BigDecimal value) throws TechnicalException {
ReflectionUtil.invokeSetter(persistentObject, propertyName, value);
}
@Override
public BigDecimal readValueFromPersistentObject(final Object persistentObject, final String propertyName) throws TechnicalException {
final Object object = ReflectionUtil.invokeGetter(persistentObject, propertyName);
if (object instanceof BigDecimal) {
return (BigDecimal) object;
} else {
if (object instanceof String) {
try {
return new BigDecimal((String)object);
} catch ( NumberFormatException exc ) {
throw new TechnicalException(exc);
}
} else {
return null;
}
}
}
}

View File

@ -0,0 +1,150 @@
package de.hsadmin.module.property;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
import de.hsadmin.module.ValueObject;
import de.hsadmin.module.impl.AbstractVO;
import de.hsadmin.module.property.mapping.DefaultBigDecimalPersistentObjectMapper;
import de.hsadmin.module.property.mapping.DefaultStringParameterMapMapper;
import de.hsadmin.module.property.mapping.Mapping;
public class BigDecimalPropertyTest {
private final TestBO testBO = new TestBO();
private TestVO testVO;
private Property<BigDecimal> voPropertyFrontendConverted;
private Property<BigDecimal> voPropertyBackendConverted;
private Map<String, Object> rpcParameterMap = new HashMap<String, Object>();
@Before
@SuppressWarnings("unchecked")
public void init() throws TechnicalException, UserException {
testVO = new TestVO();
testVO.amountFrontendConverted = new BigDecimal("9876.43");
testVO.amountBackendConverted = new BigDecimal("1234.56");
testVO.initPropertyValues();
voPropertyFrontendConverted = (Property<BigDecimal>) testVO.get("amountFrontendConverted");
voPropertyBackendConverted = (Property<BigDecimal>) testVO.get("amountBackendConverted");
}
@Test
@Ignore("MHOENNIG: muss mit PHORMANNS geklaert werden, warum es diese PersistenceMapper ueberhaupt gibt, scheinen mir sinnlos ")
public void effectivePersistentObjectMapperIsDefaultBigDecimalPersistentObjectMapper() throws TechnicalException, UserException {
// VO -> BO
voPropertyBackendConverted.setValue(new BigDecimal("1234.56"));
// FIXME MHOENNIG->PHORMANNS:
// in writeValueToPersistentObject(...) haette ich die Konvertierung erwartet,
// aber auch beim DefaultDatePersistentObjectMapper ist gerade da keine Konvertierung,
// so nun zunäcsht auch analog beim DefaultBigDecimalPersistentObjectMapper.
voPropertyBackendConverted.copyValueToPersistentObject(testBO);
assertEquals("1234.56", testBO.amountBackendConverted);
// BO -> VO
testBO.amountBackendConverted = "1111.11";
voPropertyBackendConverted.copyValueFromPersistentObject(testBO);
assertEquals("1111.11", testVO.amountBackendConverted);
}
@Test
public void effectiveParameterMapMapperIsDefaultBigDecimalParameterMapMapper() throws TechnicalException, UserException {
// VO -> rpcParameterMap
voPropertyFrontendConverted.setValue(new BigDecimal("1234.56"));
voPropertyFrontendConverted.copyValueToParameterMap(rpcParameterMap);;
assertEquals("1234.56", rpcParameterMap.get("amountFrontendConverted"));
// rpcParameterMap -> VO
rpcParameterMap.put("amountFrontendConverted", "1111.11");
voPropertyFrontendConverted.copyValueFromParameterMap(rpcParameterMap);
assertEquals(new BigDecimal("1111.11"), testVO.amountFrontendConverted);
}
@Test
public void getValueTypeIsBigDecimal() {
assertSame(BigDecimal.class, voPropertyFrontendConverted.getValueType());
}
// === test fixture ===
public static class TestVO extends AbstractVO implements ValueObject {
@ReadWrite(ReadWritePolicy.READWRITE)
@Required(true)
@Search(SearchPolicy.COMPARE)
private BigDecimal amountFrontendConverted;
@Mapping(boMapping=DefaultBigDecimalPersistentObjectMapper.class,
rpcMapping=DefaultStringParameterMapMapper.class)
@ReadWrite(ReadWritePolicy.READWRITE)
@Required(true)
@Search(SearchPolicy.LIKE)
private BigDecimal amountBackendConverted;
public TestVO() throws TechnicalException {
super();
}
public BigDecimal getAmountFrontendConverted() {
return amountFrontendConverted;
}
public void setAmountFrontendConverted(BigDecimal amountFrontendConverted) {
this.amountFrontendConverted = amountFrontendConverted;
}
public BigDecimal getAmountBackendConverted() {
return amountBackendConverted;
}
public void setAmountBackendConverted(BigDecimal amountBackendConverted) {
this.amountBackendConverted = amountBackendConverted;
}
}
public static class TestBO {
@ReadWrite(ReadWritePolicy.READWRITE)
@Required(true)
@Search(SearchPolicy.COMPARE)
private BigDecimal amountFrontendConverted;
@ReadWrite(ReadWritePolicy.READWRITE)
@Required(true)
@Search(SearchPolicy.LIKE)
private String amountBackendConverted;
public BigDecimal getAmountFrontendConverted() {
return amountFrontendConverted;
}
public void setAmountFrontendConverted(BigDecimal amountFrontendConverted) {
this.amountFrontendConverted = amountFrontendConverted;
}
public String getAmountBackendConverted() {
return amountBackendConverted;
}
public void setAmountBackendConverted(String amountBackendConverted) {
this.amountBackendConverted = amountBackendConverted;
}
}
}

View File

@ -0,0 +1,63 @@
package de.hsadmin.module.property.mapping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
public class DefaultBigDecimalParameterMapMapperTest {
private final Map<String, Object> rpcParameters = new HashMap<String, Object>();
private final DefaultBigDecimalParameterMapMapper defaultBigDecimalParameterMapMapper = new DefaultBigDecimalParameterMapMapper();
@Test
public void readValueFromParameterMapWithNumericString() throws TechnicalException, UserException{
rpcParameters.put("test", "1234.56");
assertEquals(new BigDecimal("1234.56"), defaultBigDecimalParameterMapMapper.readValueFromParameterMap(rpcParameters, "test", BigDecimal.class));
}
@Test(expected=TechnicalException.class)
public void readValueFromParameterMapWithNonNumericString() throws TechnicalException, UserException{
rpcParameters.put("test", "not a number");
defaultBigDecimalParameterMapMapper.readValueFromParameterMap(rpcParameters, "test", BigDecimal.class);
}
@Test(expected=TechnicalException.class)
public void readValueFromParameterMapWithNumericStringWithGarbage() throws TechnicalException, UserException{
rpcParameters.put("test", "1234x");
defaultBigDecimalParameterMapMapper.readValueFromParameterMap(rpcParameters, "test", BigDecimal.class);
}
@Test
public void readValueFromParameterMapWithBigDecimal() throws TechnicalException, UserException{
rpcParameters.put("test", new BigDecimal("1234.56"));
assertEquals(new BigDecimal("1234.56"), defaultBigDecimalParameterMapMapper.readValueFromParameterMap(rpcParameters, "test", BigDecimal.class));
}
@Test
public void readValueFromParameterMapWithBigOther() throws TechnicalException, UserException{
rpcParameters.put("test", new Date());
assertNull(defaultBigDecimalParameterMapMapper.readValueFromParameterMap(rpcParameters, "test", BigDecimal.class));
}
@Test
public void writeValueToParameterMap() throws TechnicalException, UserException{
defaultBigDecimalParameterMapMapper.writeValueToParameterMap(rpcParameters, "test", new BigDecimal("9876.64"));
assertEquals("9876.64", rpcParameters.get("test"));
}
@Test
public void writeNullValueToParameterMap() throws TechnicalException, UserException{
defaultBigDecimalParameterMapMapper.writeValueToParameterMap(rpcParameters, "test", null);
assertFalse(rpcParameters.containsKey("test"));
}
}

View File

@ -0,0 +1,62 @@
package de.hsadmin.module.property.mapping;
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import org.junit.Test;
import de.hsadmin.common.error.TechnicalException;
import de.hsadmin.common.error.UserException;
public class DefaultBigDecimalPersistentObjectMapperTest {
private DefaultBigDecimalPersistentObjectMapper mapper = new DefaultBigDecimalPersistentObjectMapper();
@Test
public void readValueFromPersistentObjectHavingEnum() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(new BigDecimal("1234.56"));
assertEquals( new BigDecimal("1234.56"), mapper.readValueFromPersistentObject(persistentObject, "someBigDecimalProp"));
}
@Test
public void readValueFromPersistentObjectHavingString() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(new BigDecimal("9876.54"));
assertEquals( new BigDecimal("9876.54"), mapper.readValueFromPersistentObject(persistentObject, "someStringProp"));
}
@Test
public void writeValueToPersistentObject() throws TechnicalException, UserException {
SomeBO persistentObject = new SomeBO(new BigDecimal(0));
mapper.writeValueToPersistentObject(persistentObject, "someBigDecimalProp", new BigDecimal("3333.44") );
assertEquals(new BigDecimal("3333.44"), persistentObject.getSomeBigDecimalProp());
}
public static class SomeBO {
private BigDecimal someBigDecimalProp;
private String someStringProp;
public SomeBO(BigDecimal someProp) {
this.someBigDecimalProp = someProp;
this.someStringProp = someProp.toString();
}
public BigDecimal getSomeBigDecimalProp() {
return someBigDecimalProp;
}
public void setSomeBigDecimalProp(BigDecimal someProp) {
this.someBigDecimalProp = someProp;
}
public String getSomeStringProp() {
return someStringProp;
}
public void setSomeStringProp(String someStringProp) {
this.someStringProp = someStringProp;
}
}
}