diff --git a/framework/src/main/java/de/hsadmin/module/impl/AbstractVO.java b/framework/src/main/java/de/hsadmin/module/impl/AbstractVO.java index 6326160..1d1f7ce 100644 --- a/framework/src/main/java/de/hsadmin/module/impl/AbstractVO.java +++ b/framework/src/main/java/de/hsadmin/module/impl/AbstractVO.java @@ -86,7 +86,7 @@ public abstract class AbstractVO implements ValueObject { } private boolean isPropertyField(final Field f) { - ReadWrite annotation = f.getAnnotation(ReadWrite.class); + final ReadWrite annotation = f.getAnnotation(ReadWrite.class); return annotation != null; } @@ -102,12 +102,15 @@ public abstract class AbstractVO implements ValueObject { final Class type = Class.forName("de.hsadmin.module.property." + simplePropertyClassName + "Property"); final Constructor constructor = type.getConstructor(ValueObject.class, String.class, ReadWritePolicy.class, SearchPolicy.class, boolean.class); final Property newInstance = (Property) constructor.newInstance(this, f.getName(), getReadWritePolicy(f), getSearchPolicy(f), isRequired(f)); - set(f.getName(), newInstance); + final String propertyName = f.getName(); + assert propertyName != null && propertyName.length() > 0; + assert newInstance != null; + propertiesMap.put(propertyName, newInstance); if (ContainsElements.class.isAssignableFrom(type)) { ContainsElements container = (ContainsElements) newInstance; container.setElementsType(getElementsType(f)); } - Mapping mapping = f.getAnnotation(Mapping.class); + final Mapping mapping = f.getAnnotation(Mapping.class); if (mapping != null && newInstance instanceof AbstractProperty) { AbstractProperty prop = (AbstractProperty) newInstance; PersistentObjectMapper persistentObjectMapper = mapping.boMapping().newInstance(); @@ -119,17 +122,11 @@ public abstract class AbstractVO implements ValueObject { } } } catch (IllegalArgumentException | IllegalAccessException | InstantiationException | InvocationTargetException - | NoSuchMethodException | SecurityException | UserException | ClassNotFoundException e) { + | NoSuchMethodException | SecurityException | ClassNotFoundException e) { throw new TechnicalException(e); } } - private void set(final String propertyName, final Property propertyInstance) throws UserException { - assert propertyName != null && propertyName.length() > 0; - assert propertyInstance != null; - propertiesMap.put(propertyName, propertyInstance); - } - private SearchPolicy getSearchPolicy(final Field f) { final Search search = f.getAnnotation(Search.class); SearchPolicy searchPolicy = SearchPolicy.NONE; diff --git a/framework/src/main/java/de/hsadmin/service/property/PropertyService.java b/framework/src/main/java/de/hsadmin/service/property/PropertyService.java index fff838d..3876c79 100644 --- a/framework/src/main/java/de/hsadmin/service/property/PropertyService.java +++ b/framework/src/main/java/de/hsadmin/service/property/PropertyService.java @@ -1,7 +1,6 @@ package de.hsadmin.service.property; import java.io.IOException; -import java.lang.reflect.Field; import java.util.Enumeration; import java.util.List; import java.util.Properties; @@ -14,6 +13,7 @@ import javax.validation.constraints.Size; import de.hsadmin.common.error.TechnicalException; import de.hsadmin.common.error.UserException; +import de.hsadmin.common.util.ReflectionUtil; import de.hsadmin.login.RequestContext; import de.hsadmin.login.RequiredScope; import de.hsadmin.login.Role; @@ -22,6 +22,7 @@ import de.hsadmin.module.ValueObject; import de.hsadmin.module.impl.AbstractModule; import de.hsadmin.module.property.Display; import de.hsadmin.module.property.DisplayPolicy; +import de.hsadmin.module.property.Property; import de.hsadmin.module.property.ReadWrite; import de.hsadmin.module.property.ReadWritePolicy; import de.hsadmin.module.property.Search; @@ -31,6 +32,8 @@ import de.hsadmin.xmlrpc.AbstractRemote; @Stateless public class PropertyService extends AbstractModule implements PropertyServiceLocal { + public static final String DEFAULT_VALIDATION_REGEXP = "[a-zA-Z0-9\\_\\-\\.\\,\\ ]*"; + @PersistenceContext(name="hsar") private EntityManager entityManager; @@ -47,6 +50,7 @@ public class PropertyService extends AbstractModule implements Prope } @Override + @SuppressWarnings("unchecked") @RequiredScope({@ScopePolicy(Role.ANY)}) public List read(final RequestContext requestContext, final PropertyVO criteria) throws UserException, TechnicalException { @@ -55,56 +59,57 @@ public class PropertyService extends AbstractModule implements Prope final String requestedModuleName = criteria.getModule(); try { remoteServicesProperties.load(getClass().getClassLoader().getResourceAsStream("org/apache/xmlrpc/webserver/XmlRpcServlet.properties")); - final Enumeration propertyNames = remoteServicesProperties.propertyNames(); - while (propertyNames.hasMoreElements()) { - final String properyName = (String) propertyNames.nextElement(); - if (requestedModuleName != null && !requestedModuleName.equals(properyName)) { + final Enumeration remoteModuleNames = remoteServicesProperties.propertyNames(); + while (remoteModuleNames.hasMoreElements()) { + final String moduleName = (String) remoteModuleNames.nextElement(); + if (requestedModuleName != null && !requestedModuleName.equals(moduleName)) { continue; } - final Class serviceRemoteClass = Class.forName(remoteServicesProperties.getProperty(properyName)); - @SuppressWarnings("unchecked") + final Class serviceRemoteClass = Class.forName(remoteServicesProperties.getProperty(moduleName)); final AbstractRemote serviceRemote = (AbstractRemote) serviceRemoteClass.newInstance(); final ValueObject valueObject = serviceRemote.createValueObject(); - final Field[] declaredFields = valueObject.getClass().getDeclaredFields(); - for (Field f : declaredFields) { + final Class voClass = valueObject.getClass(); + final List> propertiesList = valueObject.properties(); + for (final Property prop : propertiesList) { final PropertyVO vo = buildVO(); - vo.setModule(properyName); - vo.setName(f.getName()); - final ReadWrite readWrite = f.getAnnotation(ReadWrite.class); + final String propName = prop.getName(); + setStringValue(vo, "module", moduleName); + setStringValue(vo, "name", propName); + final ReadWrite readWrite = (ReadWrite) ReflectionUtil.getAnnotation(voClass, propName, ReadWrite.class); if (readWrite == null) { - vo.setReadwriteable(ReadWritePolicy.NONE.name().toLowerCase()); + setStringValue(vo, "readwriteable", ReadWritePolicy.NONE.name().toLowerCase()); } else { - vo.setReadwriteable(readWrite.value().name().toLowerCase()); + setStringValue(vo, "readwriteable", readWrite.value().name().toLowerCase()); } - final Search search = f.getAnnotation(Search.class); + final Search search = (Search) ReflectionUtil.getAnnotation(voClass, propName, Search.class); if (search == null) { - vo.setSearchable(SearchPolicy.NONE.name().toLowerCase()); + setStringValue(vo, "searchable", SearchPolicy.NONE.name().toLowerCase()); } else { - vo.setSearchable(search.value().name().toLowerCase()); + setStringValue(vo, "searchable", search.value().name().toLowerCase()); } - final Display sequence = f.getAnnotation(Display.class); + final Display sequence = (Display) ReflectionUtil.getAnnotation(voClass, propName, Display.class); if (sequence == null) { - vo.setDisplaySequence(Integer.valueOf(9999)); - vo.setDisplayVisible(DisplayPolicy.ALWAYS.name().toLowerCase());; + setIntValue(vo, "displaySequence", 9999); + setStringValue(vo, "displayVisible", DisplayPolicy.ALWAYS.name().toLowerCase()); } else { - vo.setDisplaySequence(sequence.sequence()); - vo.setDisplayVisible(sequence.visible().name().toLowerCase());; + setIntValue(vo, "displaySequence", sequence.sequence()); + setStringValue(vo, "displayVisible", sequence.visible().name().toLowerCase()); } - final Pattern pattern = f.getAnnotation(Pattern.class); + final Pattern pattern = (Pattern) ReflectionUtil.getAnnotation(voClass, propName, Pattern.class); if (pattern == null) { - vo.setValidationRegexp("[a-zA-Z0-9\\_\\-\\.\\,\\ ]*"); + setStringValue(vo, "validationRegexp", DEFAULT_VALIDATION_REGEXP); } else { - vo.setValidationRegexp(pattern.regexp()); + setStringValue(vo, "validationRegexp", pattern.regexp()); } - final Size size = f.getAnnotation(Size.class); + final Size size = (Size) ReflectionUtil.getAnnotation(voClass, propName, Size.class); if (size == null) { - vo.setMinLength(Integer.valueOf(0)); - vo.setMaxLength(Integer.valueOf(999)); + setIntValue(vo, "minLength", 0); + setIntValue(vo, "maxLength", 999); } else { - vo.setMinLength(size.min()); - vo.setMaxLength(size.max()); + setIntValue(vo, "minLength", size.min()); + setIntValue(vo, "maxLength", size.max()); } - vo.setType(printableTypeName(valueObject.get(f.getName()).getValueType())); + setStringValue(vo, "type", printableTypeName(valueObject.get(propName).getValueType())); emptyList.add(vo); } } @@ -114,6 +119,18 @@ public class PropertyService extends AbstractModule implements Prope return emptyList; } + private void setStringValue(final PropertyVO vo, final String propertyName, final String value) throws TechnicalException, UserException { + @SuppressWarnings("unchecked") + final Property property = (Property) vo.get(propertyName); + property.setValue(value); + } + + private void setIntValue(final PropertyVO vo, final String propertyName, final int value) throws TechnicalException, UserException { + @SuppressWarnings("unchecked") + final Property property = (Property) vo.get(propertyName); + property.setValue(value); + } + private String printableTypeName(Class type) { String name = type.getName().toLowerCase(); if (name.indexOf('.') >= 0) {