started generic remote implementation

This commit is contained in:
Peter Hormanns 2012-07-27 16:02:24 +00:00
parent ba1d525cbe
commit 3611be9661
13 changed files with 292 additions and 128 deletions

View File

@ -8,6 +8,7 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface AnnFieldIO {
String validation() default "[A-Za-z0-9\\_\\-]";
String validation() default "[A-Za-z0-9\\_\\-]*";
ReadWriteAccess rw() default ReadWriteAccess.WRITEONCE;
Class<?> referTo() default Object.class;
}

View File

@ -1,10 +1,11 @@
package de.hsadmin.core.model;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Pattern;
import de.hsadmin.core.util.ReflectionUtil;
public class GenericModuleImpl implements ModuleInterface {
private Transaction tx;
@ -84,8 +85,7 @@ public class GenericModuleImpl implements ModuleInterface {
AnnFieldIO fieldValidation = f.getAnnotation(AnnFieldIO.class);
if (fieldValidation != null) {
try {
Method method = clasz.getMethod(getterName(f));
Object valueObject = method.invoke(anEntity);
Object valueObject = ReflectionUtil.invokeGetter(anEntity, clasz, f);
if (valueObject instanceof String) {
if (!Pattern.matches(fieldValidation.validation(), (String) valueObject)) {
throw new HSAdminException("validation of field " + f.getName() + " failed, pattern: " + fieldValidation.validation());
@ -98,14 +98,4 @@ public class GenericModuleImpl implements ModuleInterface {
}
}
private String getterName(Field f) {
String name = f.getName();
char firstChar = Character.toUpperCase(name.charAt(0));
Class<?> type = f.getType();
if (type.getCanonicalName().startsWith("boolean")) {
return "is" + firstChar + name.substring(1);
}
return "get" + firstChar + name.substring(1);
}
}

View File

@ -0,0 +1,118 @@
package de.hsadmin.core.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import de.hsadmin.cliClientConnector.TechnicalException;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AnnFieldIO;
public class ReflectionUtil {
public static synchronized Object invokeGetter(AbstractEntity entity, Class<?> clasz, Field f) {
Object valueObject = null;
try {
Method method = clasz.getMethod(getterName(f));
valueObject = method.invoke(entity);
if (valueObject instanceof Boolean) {
valueObject = valueObject.toString();
} else
if (valueObject instanceof Number) {
valueObject = valueObject.toString();
} else
if (valueObject instanceof Date) {
valueObject = TextUtil.format((Date) valueObject);
} else
if (valueObject instanceof Set) {
Set<?> s = (Set<?>) valueObject;
List<String> nameList = new ArrayList<String>();
for (Object o : s) {
Class<?> t = o.getClass();
nameList.add((String) invokeGetter((AbstractEntity) o, t, t.getDeclaredField("name")));
}
} else
if (valueObject instanceof List<?>) {
List<?> l = (List<?>) valueObject;
List<String> nameList = new ArrayList<String>();
for (Object o : l) {
Class<?> t = o.getClass();
nameList.add((String) invokeGetter((AbstractEntity) o, t, t.getDeclaredField("name")));
}
} else
if (valueObject instanceof AbstractEntity) {
Class<?> t = f.getType();
valueObject = invokeGetter((AbstractEntity) valueObject, t, t.getDeclaredField("name"));
}
} catch (Exception e) {
throw new TechnicalException(e);
}
return valueObject;
}
public static synchronized void invokeSetter(AbstractEntity entity,
Class<?> clasz, Field f, Object valueObject) {
try {
Class<?> type = f.getType();
if (type.equals(String.class)) {
clasz.getMethod(setterName(f), String.class).invoke(entity, valueObject);
} else
if (type.equals(Date.class)) {
clasz.getMethod(setterName(f), Date.class).invoke(entity, TextUtil.parse((String) valueObject));
} else
if (type.getCanonicalName().equals("long")) {
clasz.getMethod(setterName(f), long.class).invoke(entity, Long.parseLong((String) valueObject));
} else
if (type.getCanonicalName().equals("int")) {
clasz.getMethod(setterName(f), int.class).invoke(entity, Integer.parseInt((String) valueObject));
} else
if (type.getCanonicalName().equals("boolean")) {
clasz.getMethod(setterName(f), boolean.class).invoke(entity, Boolean.valueOf((String) valueObject));
} else
if (type.equals(Set.class)) {
AnnFieldIO annotation = f.getAnnotation(AnnFieldIO.class);
Class<?> referTo = annotation.referTo();
Set<Object> newSet = new TreeSet<Object>();
clasz.getMethod(setterName(f), Set.class).invoke(entity, newSet);
if (valueObject != null && valueObject instanceof Object[]) {
for (Object item : ((Object[]) valueObject)) {
if (item instanceof String && referTo.getDeclaredField("name") != null) {
Object instance = referTo.newInstance();
if (instance instanceof AbstractEntity) {
invokeSetter((AbstractEntity) instance, referTo, referTo.getDeclaredField("name"), item);
newSet.add(instance);
}
}
}
}
} else {
Object newInstance = type.newInstance();
clasz.getMethod(setterName(f), type).invoke(entity, newInstance);
type.getMethod("setName", String.class).invoke(newInstance, valueObject);
}
} catch (Exception e) {
throw new TechnicalException(e);
}
}
private static String getterName(Field f) {
String name = f.getName();
char firstChar = Character.toUpperCase(name.charAt(0));
Class<?> type = f.getType();
if (type.getCanonicalName().equals("boolean")) {
return "is" + firstChar + name.substring(1);
}
return "get" + firstChar + name.substring(1);
}
private static String setterName(Field f) {
String name = f.getName();
char firstChar = Character.toUpperCase(name.charAt(0));
return "set" + firstChar + name.substring(1);
}
}

View File

@ -1,8 +1,15 @@
package de.hsadmin.core.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TextUtil {
public static String replaceUmlautCharacters(String umlautString) {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
public static synchronized String replaceUmlautCharacters(String umlautString) {
StringBuffer buffer = new StringBuffer();
for (char c : umlautString.toCharArray()) {
if ( (c >= 'a' && c <= 'z') ||
@ -42,4 +49,21 @@ public class TextUtil {
return buffer.toString();
}
public static synchronized String format(Date date) {
return df.format(date);
}
public static synchronized Date parse(String dateString) {
try {
return df.parse(dateString);
} catch (ParseException e) {
try {
return df.parse("01.01.1970");
} catch (ParseException e1) {
// don't care
return null;
}
}
}
}

View File

@ -42,7 +42,7 @@ public class Domain extends AbstractEntity {
@Column(name = "domain_name", columnDefinition = "character varying(256)", nullable = false)
private String name;
@AnnFieldIO(rw=ReadWriteAccess.WRITEONCE)
@AnnFieldIO(validation="[a-z0-9\\_\\-\\.]*", rw=ReadWriteAccess.WRITEONCE)
@JoinColumn(name = "domain_owner", columnDefinition = "integer", nullable = false)
@ManyToOne(fetch = EAGER)
private UnixUser user;
@ -56,12 +56,12 @@ public class Domain extends AbstractEntity {
@Column(name = "domain_dns_master", columnDefinition = "character varying(64)")
private String dnsMaster;
@AnnFieldIO(validation="[a-zA-Z0-9\\-\\.]*", rw=ReadWriteAccess.READWRITE)
@AnnFieldIO(validation="[a-zA-Z0-9\\-\\.]*", rw=ReadWriteAccess.READWRITE, referTo=DomainOption.class)
@ManyToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinTable(name="domain__domain_option",
joinColumns={@JoinColumn(name="domain_id", referencedColumnName="domain_id")},
inverseJoinColumns={@JoinColumn(name="domain_option_id", referencedColumnName="domain_option_id")})
private Set<DomainOption> domainOptions;
private Set<DomainOption> domainoptions;
public Domain() {
}
@ -172,12 +172,12 @@ public class Domain extends AbstractEntity {
"obj.user=:loginUser";
}
public Set<DomainOption> getDomainOptions() {
return domainOptions;
public Set<DomainOption> getDomainoptions() {
return domainoptions;
}
public void setDomainOptions(Set<DomainOption> domainOptions) {
this.domainOptions = domainOptions;
public void setDomainoptions(Set<DomainOption> domainOptions) {
this.domainoptions = domainOptions;
}
}

View File

@ -155,7 +155,7 @@ public class DomainModuleImpl extends AbstractModuleImpl {
Query q = em.createQuery("SELECT opt FROM " +
DomainOption.class.getAnnotation(javax.persistence.Entity.class).name() +
" opt WHERE opt.name=:optName");
Set<DomainOption> domainOptions = updatedDom.getDomainOptions();
Set<DomainOption> domainOptions = updatedDom.getDomainoptions();
for (DomainOption opt : domainOptions) {
q.setParameter("optName", opt.getName());
List<?> list = q.getResultList();

View File

@ -33,7 +33,7 @@ public class DomainOption extends AbstractEntity {
@Column(name = "domain_option_name", columnDefinition = "character varying(256)", nullable = false)
private String name;
@ManyToMany(mappedBy="domainOptions", fetch=FetchType.LAZY)
@ManyToMany(mappedBy="domainoptions", fetch=FetchType.LAZY)
private List<Domain> domains;
@Override

View File

@ -23,7 +23,7 @@ public abstract class AbstractRemote implements IRemote {
protected abstract void entity2map(AbstractEntity entity, Map<String, Object> resultMap);
protected abstract void map2entity(Map<String, Object> setParams, AbstractEntity entity);
protected abstract void map2entity(Map<String, Object> setParams, AbstractEntity entity) throws HSAdminException;
protected abstract void regularizeKeys(Map<String, String> whereParams);

View File

@ -1,21 +1,17 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.util.TextUtil;
import de.hsadmin.mods.cust.BankAccount;
import de.hsadmin.mods.cust.Contact;
import de.hsadmin.mods.cust.Customer;
public class CustomerRemote extends AbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return Customer.class;
@ -30,24 +26,24 @@ public class CustomerRemote extends AbstractRemote {
resultMap.put("memberno", Integer.toString(cust.getMemberNo()));
Date memberSince = cust.getMemberSince();
if (assertNotNull(memberSince)) {
resultMap.put("membersince", df.format(memberSince));
resultMap.put("membersince", TextUtil.format(memberSince));
}
Date memberUntil = cust.getMemberUntil();
if (assertNotNull(memberUntil)) {
resultMap.put("memberuntil", df.format(memberUntil));
resultMap.put("memberuntil", TextUtil.format(memberUntil));
}
resultMap.put("memberrole", cust.getMemberRole());
Date authorContract = cust.getAuthorContract();
if (assertNotNull(authorContract)) {
resultMap.put("authorcontract", df.format(authorContract));
resultMap.put("authorcontract", TextUtil.format(authorContract));
}
Date nonDiscContract = cust.getNonDiscContract();
if (assertNotNull(nonDiscContract)) {
resultMap.put("nondisccontract", df.format(nonDiscContract));
resultMap.put("nondisccontract", TextUtil.format(nonDiscContract));
}
Date sharesUpdated = cust.getSharesUpdated();
if (assertNotNull(sharesUpdated)) {
resultMap.put("sharesupdated", df.format(sharesUpdated));
resultMap.put("sharesupdated", TextUtil.format(sharesUpdated));
}
resultMap.put("sharessigned", Integer.toString(cust.getSharesSigned()));
resultMap.put("uidvat", cust.getUidVAT());
@ -104,19 +100,11 @@ public class CustomerRemote extends AbstractRemote {
}
String memberSince = (String) setParams.get("membersince");
if (assertNotNull(memberSince)) {
try {
cust.setMemberSince(df.parse(memberSince));
} catch (ParseException e) {
// don't care
}
cust.setMemberSince(TextUtil.parse(memberSince));
}
String memberUntil = (String) setParams.get("memberuntil");
if (assertNotNull(memberUntil)) {
try {
cust.setMemberUntil(df.parse(memberUntil));
} catch (ParseException e) {
// don't care
}
cust.setMemberUntil(TextUtil.parse(memberUntil));
}
String memberRole = (String) setParams.get("memberrole");
if (assertNotNull(memberRole)) {
@ -124,27 +112,15 @@ public class CustomerRemote extends AbstractRemote {
}
String authorContract = (String) setParams.get("authorcontract");
if (assertNotNull(authorContract)) {
try {
cust.setAuthorContract(df.parse(authorContract));
} catch (ParseException e) {
// don't care
}
cust.setAuthorContract(TextUtil.parse(authorContract));
}
String nonDiscContract = (String) setParams.get("nondisccontract");
if (assertNotNull(nonDiscContract)) {
try {
cust.setNonDiscContract(df.parse(nonDiscContract));
} catch (ParseException e) {
// don't care
}
cust.setNonDiscContract(TextUtil.parse(nonDiscContract));
}
String sharesUpdated = (String) setParams.get("sharesupdated");
if (assertNotNull(sharesUpdated)) {
try {
cust.setSharesUpdated(df.parse(sharesUpdated));
} catch (ParseException e) {
// don't care
}
cust.setSharesUpdated(TextUtil.parse(sharesUpdated));
}
String sharesSigned = (String) setParams.get("sharessigned");
if (assertNotNull(sharesSigned)) {

View File

@ -1,7 +1,5 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
@ -10,72 +8,71 @@ import java.util.Map;
import java.util.Set;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.util.TextUtil;
import de.hsadmin.mods.dom.Domain;
import de.hsadmin.mods.dom.DomainOption;
import de.hsadmin.mods.user.UnixUser;
public class DomainRemote extends AbstractRemote {
public class DomainRemote extends GenericAbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return Domain.class;
}
@Override
protected void entity2map(AbstractEntity entity, Map<String, Object> resultMap) {
Domain dom = (Domain) entity;
String id = Long.toString(dom.getId());
resultMap.put("id", id);
String name = dom.getName();
resultMap.put("name", name);
String user = dom.getUser().getName();
resultMap.put("user", user);
String hive = dom.getHiveName();
resultMap.put("hive", hive);
String pac = dom.getUser().getPac().getName();
resultMap.put("pac", pac);
Date sDate = dom.getSince();
if (assertNotNull(sDate)) {
String since = df.format(sDate);
resultMap.put("since", since);
}
List<String> domainOptionsList = new ArrayList<String>();
resultMap.put("domainoptions", domainOptionsList);
Set<DomainOption> domainOptions = dom.getDomainOptions();
if (domainOptions != null) {
for (DomainOption opt : domainOptions) {
domainOptionsList.add(opt.getName());
}
}
}
// @Override
// protected void entity2map(AbstractEntity entity, Map<String, Object> resultMap) {
// Domain dom = (Domain) entity;
// String id = Long.toString(dom.getId());
// resultMap.put("id", id);
// String name = dom.getName();
// resultMap.put("name", name);
// String user = dom.getUser().getName();
// resultMap.put("user", user);
// String hive = dom.getHiveName();
// resultMap.put("hive", hive);
// String pac = dom.getUser().getPac().getName();
// resultMap.put("pac", pac);
// Date sDate = dom.getSince();
// if (assertNotNull(sDate)) {
// String since = TextUtil.format(sDate);
// resultMap.put("since", since);
// }
// List<String> domainOptionsList = new ArrayList<String>();
// resultMap.put("domainoptions", domainOptionsList);
// Set<DomainOption> domainOptions = dom.getDomainOptions();
// if (domainOptions != null) {
// for (DomainOption opt : domainOptions) {
// domainOptionsList.add(opt.getName());
// }
// }
// }
@Override
protected void map2entity(Map<String, Object> setParams, AbstractEntity entity) {
Domain dom = (Domain) entity;
String name = (String) setParams.get("name");
String user = (String) setParams.get("user");
if (assertNotNull(name)) {
dom.setName(name);
}
if (assertNotNull(user)) {
UnixUser u = new UnixUser();
u.setName(user);
dom.setUser(u);
}
Object domOptsObj = setParams.get("domainoptions");
if (domOptsObj != null && domOptsObj instanceof Object[]) {
Set<DomainOption> domainOptionsSet = new HashSet<DomainOption>();
Object[] domOptions = (Object[]) domOptsObj;
for (int i=0; i<domOptions.length; i++) {
DomainOption domainOption = new DomainOption();
domainOption.setName((String)domOptions[i]);
domainOptionsSet.add(domainOption);
}
dom.setDomainOptions(domainOptionsSet);
}
}
// @Override
// protected void map2entity(Map<String, Object> setParams, AbstractEntity entity) {
// Domain dom = (Domain) entity;
// String name = (String) setParams.get("name");
// String user = (String) setParams.get("user");
// if (assertNotNull(name)) {
// dom.setName(name);
// }
// if (assertNotNull(user)) {
// UnixUser u = new UnixUser();
// u.setName(user);
// dom.setUser(u);
// }
// Object domOptsObj = setParams.get("domainoptions");
// if (domOptsObj != null && domOptsObj instanceof Object[]) {
// Set<DomainOption> domainOptionsSet = new HashSet<DomainOption>();
// Object[] domOptions = (Object[]) domOptsObj;
// for (int i=0; i<domOptions.length; i++) {
// DomainOption domainOption = new DomainOption();
// domainOption.setName((String)domOptions[i]);
// domainOptionsSet.add(domainOption);
// }
// dom.setDomainOptions(domainOptionsSet);
// }
// }
@Override
protected void regularizeKeys(Map<String, String> whereParams) {

View File

@ -0,0 +1,64 @@
package de.hsadmin.remote;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import de.hsadmin.cliClientConnector.TechnicalException;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AnnFieldIO;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.model.ReadWriteAccess;
import de.hsadmin.core.util.ReflectionUtil;
public abstract class GenericAbstractRemote extends AbstractRemote {
@Override
protected abstract Class<? extends AbstractEntity> getEntityClass();
@Override
protected abstract void regularizeKeys(Map<String, String> whereParams);
@Override
protected void entity2map(AbstractEntity entity, Map<String, Object> resultMap) {
Class<? extends AbstractEntity> entityClass = getEntityClass();
Field[] fields = entityClass.getDeclaredFields();
for (Field f : fields) {
if (f.getName().equals("id") && f.getType().getCanonicalName().equals("long")) {
resultMap.put("id", (ReflectionUtil.invokeGetter(entity, entityClass, f)).toString());
} else {
AnnFieldIO fieldIO = f.getAnnotation(AnnFieldIO.class);
if (fieldIO != null && fieldIO.rw() != ReadWriteAccess.WRITEONLY) {
resultMap.put(f.getName(), ReflectionUtil.invokeGetter(entity, entityClass, f));
}
}
}
}
@Override
protected void map2entity(Map<String, Object> paramsMap, AbstractEntity entity) throws HSAdminException {
Class<? extends AbstractEntity> entityClass = getEntityClass();
Set<String> keySet = paramsMap.keySet();
for (String key : keySet) {
Object valueObj = paramsMap.get(key);
try {
Field f = entityClass.getDeclaredField(key);
AnnFieldIO fieldIO = f.getAnnotation(AnnFieldIO.class);
if (valueObj != null && valueObj instanceof String && !Pattern.matches(fieldIO.validation(), (String) valueObj)) {
throw new HSAdminException("validation of field " + f.getName() + " failed, pattern: " + fieldIO.validation());
}
if (fieldIO.rw() != ReadWriteAccess.READONLY) {
ReflectionUtil.invokeSetter(entity, entityClass, f, valueObj);
} else {
throw new HSAdminException("field " + f.getName() + " is readonly");
}
} catch (SecurityException e) {
throw new TechnicalException(e);
} catch (NoSuchFieldException e) {
throw new HSAdminException("no such field: " + key, e);
}
}
}
}

View File

@ -1,7 +1,5 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
@ -9,6 +7,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.util.TextUtil;
import de.hsadmin.mods.cust.Customer;
import de.hsadmin.mods.pac.BasePac;
import de.hsadmin.mods.pac.Hive;
@ -18,8 +17,6 @@ import de.hsadmin.mods.pac.PacComponent;
public class PacRemote extends AbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected void entity2map(AbstractEntity entity, Map<String, Object> resultMap) {
Pac pac = (Pac) entity;
@ -28,7 +25,7 @@ public class PacRemote extends AbstractRemote {
resultMap.put("hive", pac.getHiveName());
resultMap.put("customer", pac.getCustomer().getName());
resultMap.put("curinetaddr", pac.getCurINetAddr().getInetAddr());
resultMap.put("created", df.format(pac.getCreated()));
resultMap.put("created", TextUtil.format(pac.getCreated()));
resultMap.put("basepac", pac.getBasepac().getName());
SortedSet<PacComponent> sortedComponents = new TreeSet<PacComponent>(new Comparator<PacComponent>() {
@Override

View File

@ -1,19 +1,16 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.QueueTask;
import de.hsadmin.core.qserv.QueueTask.QueueTaskStatus;
import de.hsadmin.core.util.TextUtil;
import de.hsadmin.mods.user.UnixUser;
public class QueueTaskRemote extends AbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return QueueTask.class;
@ -32,11 +29,11 @@ public class QueueTaskRemote extends AbstractRemote {
if (user != null) resultMap.put("user", user.getName());
Date started = task.getStarted();
if (assertNotNull(started)) {
resultMap.put("started", df.format(started));
resultMap.put("started", TextUtil.format(started));
}
Date finished = task.getFinished();
if (assertNotNull(finished)) {
resultMap.put("finished", df.format(finished));
resultMap.put("finished", TextUtil.format(finished));
}
}