NIHVIVO-3116 and assorted cleanup of legacy backend editor

This commit is contained in:
brianjlowe 2011-10-04 20:50:31 +00:00
parent a9e36bd8dd
commit 17a60cb81c
47 changed files with 442 additions and 662 deletions

View file

@ -33,7 +33,8 @@ public class BaseEditController extends VitroHttpServlet {
public static final String JSP_PREFIX = "/templates/edit/specific/";
protected static DateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
protected static DateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
protected static final int BASE_10 = 10;
private static final Log log = LogFactory.getLog(BaseEditController.class.getName());
private static final String DEFAULT_LANDING_PAGE = Controllers.SITE_ADMIN;

View file

@ -11,7 +11,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -23,6 +22,7 @@ import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
import edu.cornell.mannlib.vedit.listener.ChangeListener;
import edu.cornell.mannlib.vedit.listener.EditPreProcessor;
import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vedit.util.FormUtils.NegativeIntegerException;
import edu.cornell.mannlib.vedit.util.OperationUtils;
import edu.cornell.mannlib.vedit.validator.ValidationObject;
import edu.cornell.mannlib.vedit.validator.Validator;
@ -201,17 +201,6 @@ public class OperationController extends BaseEditController {
}
}
private void applySimpleMask(EditProcessObject epo, Object newObj) {
// apply the simple mask
//if (epo.getSimpleMask() != null) {
// Iterator smaskIt = epo.getSimpleMask().iterator();
// while (smaskIt.hasNext()){
// Object[] simpleMaskPair = (Object[]) smaskIt.next();
// FormUtils.beanSet(newObj,(String)simpleMaskPair[0],simpleMaskPair[1].toString());
// }
//}
}
private Object getNewObj(EditProcessObject epo) {
Object newObj = null;
if (epo.getOriginalBean() != null) { // we're updating or deleting an existing bean
@ -292,10 +281,14 @@ public class OperationController extends BaseEditController {
epo.getBadValueMap().remove(currParam);
} catch (NumberFormatException e) {
if (currValue.length()>0) {
valid=false;
valid = false;
epo.getErrMsgMap().put(currParam,"Please enter an integer");
epo.getBadValueMap().put(currParam,currValue);
}
} catch (NegativeIntegerException nie) {
valid = false;
epo.getErrMsgMap().put(currParam,"Please enter a positive integer");
epo.getBadValueMap().put(currParam,currValue);
} catch (IllegalArgumentException f) {
valid=false;
log.error("doPost() reports IllegalArgumentException for "+currParam);

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vedit.util;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@ -26,32 +27,45 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
public class FormUtils {
protected static final Log log = LogFactory.getLog(FormUtils.class.getName());
protected static final Log log = LogFactory.getLog(FormUtils.class.getName());
protected static final int BASE_10 = 10;
protected static final Class[] SUPPORTED_TYPES = { String.class,
int.class,
Integer.class,
boolean.class,
Date.class
};
protected static final List<Class> SUPPORTED_TYPE_LIST = Arrays
.asList(SUPPORTED_TYPES);
/* this class needs to be reworked */
public static String htmlFormFromBean (Object bean, String action, FormObject foo) {
return htmlFormFromBean(bean,action,null,foo,new HashMap());
public static void populateFormFromBean (Object bean,
String action,
FormObject foo) {
populateFormFromBean(bean,action,null,foo,new HashMap());
}
public static String htmlFormFromBean (Object bean, String action, FormObject foo, Map<String, String> badValuesHash) {
return htmlFormFromBean(bean,action,null,foo,badValuesHash);
public static void populateFormFromBean (Object bean,
String action,
FormObject foo,
Map<String, String> badValuesHash) {
populateFormFromBean(bean,action,null,foo,badValuesHash);
}
/**
* Creates a basic XHTML editing form for a bean class
*
* This is the simplest version, creating an input field for each and every setter method in the bean.
*
* @param bean the bean class for which an editing form should be built
* @return XHTML markup of an editing form for the specified class
* @author bjl23
* Populates form objects with bean values
*/
public static String htmlFormFromBean (Object bean, String action, EditProcessObject epo, FormObject foo, Map<String, String> BadValuesHash) {
String formMarkup = "";
Class beanClass = (epo != null && epo.getBeanClass() != null) ? epo.getBeanClass() : bean.getClass();
public static void populateFormFromBean (Object bean,
String action,
EditProcessObject epo,
FormObject foo,
Map<String, String> BadValuesHash) {
Class beanClass =
(epo != null && epo.getBeanClass() != null)
? epo.getBeanClass()
: bean.getClass();
Method[] meths = beanClass.getMethods();
@ -60,32 +74,16 @@ public class FormUtils {
if (meths[i].getName().indexOf("set") == 0) {
// we have a setter method
Method currMeth = meths[i];
Class[] currMethParamTypes = currMeth.getParameterTypes();
Class currMethType = currMethParamTypes[0];
String currMethTypeStr = currMethType.toString();
if (SUPPORTED_TYPE_LIST.contains(currMethType)) {
//we only want people directly to type in ints, strings, and dates
//of course, most of the ints are probably foreign keys anyway...
if (currMethTypeStr.equals("int") || currMethTypeStr.indexOf("class java.lang.String")>-1 || currMethTypeStr.indexOf("class java.util.Date")>-1) {
//we only want people directly to type in ints, strings, and dates
//of course, most of the ints are probably foreign keys anyway...
String elementName = currMeth.getName().substring(3,currMeth.getName().length());
formMarkup += "<tr><td align=\"right\">";
formMarkup += "<p><strong>"+elementName+"</strong></p>";
formMarkup += "</td><td>";
formMarkup += "<input name=\""+elementName+"\" ";
//if int, make a smaller box
if (currMethTypeStr.equals("int")){
formMarkup += " size=\"11\" maxlength=\"11\" ";
}
else
formMarkup += "size=\"75%\" ";
String elementName = currMeth.getName().substring(
3,currMeth.getName().length());
//see if there's something in the bean using
//the related getter method
@ -93,7 +91,8 @@ public class FormUtils {
Class[] paramClass = new Class[1];
paramClass[0] = currMethType;
try {
Method getter = beanClass.getMethod("get"+elementName,(Class[]) null);
Method getter = beanClass.getMethod(
"get" + elementName, (Class[]) null);
Object existingData = null;
try {
existingData = getter.invoke(bean, (Object[]) null);
@ -105,36 +104,40 @@ public class FormUtils {
if (existingData instanceof String){
value += existingData;
}
else if (!(existingData instanceof Integer && (Integer)existingData <= -10000)) {
else if (!(existingData instanceof Integer
&& (Integer)existingData < 0)) {
value += existingData.toString();
}
}
String badValue = (String) BadValuesHash.get(elementName);
if (badValue != null)
value = badValue;
formMarkup += " value=\""+StringEscapeUtils.escapeHtml(value)+"\" ";
if (badValue != null) {
value = badValue;
}
foo.getValues().put(elementName, value);
} catch (NoSuchMethodException e) {
// System.out.println("Could not find method get"+elementName+"()");
//ignore it
}
formMarkup += "/>\n";
formMarkup += "</td></tr>";
}
}
}
return formMarkup;
}
public static List /*of Option*/ makeOptionListFromBeans (List beanList, String valueField, String bodyField, String selectedValue, String selectedBody) {
return makeOptionListFromBeans (beanList, valueField, bodyField, selectedValue, selectedBody, true);
public static List<Option> makeOptionListFromBeans (List beanList,
String valueField,
String bodyField,
String selectedValue,
String selectedBody) {
return makeOptionListFromBeans (
beanList, valueField, bodyField, selectedValue, selectedBody, true);
}
public static List /*of Option*/ makeOptionListFromBeans (List beanList, String valueField, String bodyField, String selectedValue, String selectedBody, boolean forceSelectedInclusion) {
List optList = new LinkedList();
public static List<Option> makeOptionListFromBeans(List beanList,
String valueField,
String bodyField,
String selectedValue,
String selectedBody,
boolean forceSelectedInclusion) {
List<Option> optList = new LinkedList();
if (beanList == null)
return optList;
@ -149,10 +152,12 @@ public class FormUtils {
Method valueMeth = null;
Object valueObj = null;
try {
valueMeth = bean.getClass().getMethod("get"+valueField, (Class[]) null);
valueMeth = bean.getClass().getMethod(
"get" + valueField, (Class[]) null);
valueObj = valueMeth.invoke(bean, (Object[]) null);
} catch (Exception e) {
log.warn("Could not find method get"+valueField+" on "+bean.getClass());
log.warn("Could not find method get" + valueField + " on " +
bean.getClass());
}
if (valueObj != null){
@ -163,7 +168,8 @@ public class FormUtils {
Method bodyMeth = null;
Object bodyObj = null;
try {
bodyMeth = bean.getClass().getMethod("get"+bodyField, (Class[]) null);
bodyMeth = bean.getClass().getMethod(
"get" + bodyField, (Class[]) null);
bodyObj = bodyMeth.invoke(bean, (Object[]) null);
} catch (Exception e) {
log.warn(" could not find method get"+bodyField);
@ -195,11 +201,13 @@ public class FormUtils {
}
/* if the list of beans doesn't include the selected value/body, insert it anyway so we don't inadvertently change the value of the
field to the first thing that happens to be in the select list */
// if the list of beans doesn't include the selected value/body,
// insert it anyway so we don't inadvertently change the value of the
// field to the first thing that happens to be in the select list
boolean skipThisStep = !forceSelectedInclusion;
// for now, if the value is a negative integer, we won't try to preserve it, as the bean was probably just instantiated
// should switch to a more robust way of handling inital bean values later
// For now, if the value is a negative integer, we won't try to
// preserve it, as the bean was probably just instantiated.
// Should switch to a more robust way of handling inital bean values.
if (selectedValue == null) {
skipThisStep = true;
} else {
@ -225,17 +233,21 @@ public class FormUtils {
}
public static List<Option> makeVClassOptionList(WebappDaoFactory wadf, String selectedVClassURI) {
public static List<Option> makeVClassOptionList(WebappDaoFactory wadf,
String selectedVClassURI) {
List<Option> vclassOptionList = new LinkedList<Option>();
for (VClass vclass : wadf.getVClassDao().getAllVclasses()) {
Option option = new Option();
option.setValue(vclass.getURI());
if ( (selectedVClassURI != null) && (vclass.getURI() != null) && (selectedVClassURI.equals(vclass.getURI())) ) {
if ( (selectedVClassURI != null)
&& (vclass.getURI() != null)
&& (selectedVClassURI.equals(vclass.getURI())) ) {
option.setSelected(true);
}
String ontologyName = null;
if (vclass.getNamespace() != null) {
Ontology ont = wadf.getOntologyDao().getOntologyByURI(vclass.getNamespace());
Ontology ont = wadf.getOntologyDao().getOntologyByURI(
vclass.getNamespace());
if ( (ont != null) && (ont.getName() != null) ) {
ontologyName = ont.getName();
}
@ -257,51 +269,43 @@ public class FormUtils {
beanSet (newObj, field, value, null);
}
public static void beanSet(Object newObj, String field, String value, EditProcessObject epo) {
SimpleDateFormat standardDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat minutesOnlyDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Class cls = (epo != null && epo.getBeanClass() != null) ? epo.getBeanClass() : newObj.getClass();
Class[] paramList = new Class[1];
paramList[0] = String.class;
boolean isInt = false;
boolean isDate = false;
boolean isBoolean = false;
Method setterMethod = null;
try {
setterMethod = cls.getMethod("set"+field,paramList);
} catch (NoSuchMethodException e) {
//let's try int
paramList[0] = int.class;
try {
setterMethod = cls.getMethod("set"+field,paramList);
isInt = true;
} catch (NoSuchMethodException f) {
//boolean
paramList[0] = boolean.class;
try {
setterMethod = cls.getMethod("set"+field,paramList);
isBoolean = true;
//System.out.println("Found boolean field "+field);
} catch (NoSuchMethodException h) {
//let's try Date!
paramList[0] = Date.class;
try {
// this isn't so great ; should probably be in a validator
if(value != null && value.length() > 0 && value.indexOf(":") < 1) {
value += " 00:00:00";
}
setterMethod = cls.getMethod("set"+field,paramList);
isDate = true;
} catch (NoSuchMethodException g) {
//System.out.println("beanSet could not find a setter method for "+field+" in "+cls.getName());
}
}
}
}
public static void beanSet(Object newObj,
String field,
String value,
EditProcessObject epo) {
SimpleDateFormat standardDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
SimpleDateFormat minutesOnlyDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm");
Class cls =
(epo != null && epo.getBeanClass() != null)
? epo.getBeanClass()
: newObj.getClass();
Class[] paramList = new Class[1];
Method setterMethod = getSetterMethod(cls, field, SUPPORTED_TYPE_LIST);
if (setterMethod == null) {
log.warn("Could not find method set" + field + " on "
+ cls.getName());
return;
}
Class argumentType = setterMethod.getParameterTypes()[0];
Object[] arglist = new Object[1];
if (isInt)
arglist[0] = Integer.decode(value);
else if (isDate)
if (int.class.equals(argumentType)
|| Integer.class.equals(argumentType)) {
arglist[0] = (int.class.equals(argumentType)) ? -1 : null;
if (!value.isEmpty()) {
int parsedInt = Integer.parseInt(value, BASE_10);
if (parsedInt < 0) {
throw new FormUtils.NegativeIntegerException();
} else {
arglist[0] = parsedInt;
}
}
} else if (Date.class.equals(argumentType)) {
// this isn't so great ; should probably be in a validator
if (value != null && value.length() > 0 && value.indexOf(":") < 1) {
value += " 00:00:00";
}
if (value != null && value.length()>0) {
try {
arglist[0] = standardDateFormat.parse(value);
@ -309,28 +313,44 @@ public class FormUtils {
try {
arglist[0] = minutesOnlyDateFormat.parse(value);
} catch (ParseException q) {
log.error(FormUtils.class.getName()+" could not parse"+value+" to a Date object.");
throw new IllegalArgumentException("Please enter a date/time in one of these formats: '2007-07-07', '2007-07-07 07:07', or '2007-07-07 07:07:07'");
log.error(FormUtils.class.getName()+" could not parse" +
value + " to a Date object.");
throw new IllegalArgumentException(
"Please enter a date/time in one of these " +
"formats: '2007-07-07', '2007-07-07 07:07' " +
"or '2007-07-07 07:07:07'");
}
}
} else {
arglist[0] = null;
}
else if (isBoolean) {
} else if (boolean.class.equals(argumentType)) {
arglist[0] = (value.equalsIgnoreCase("true"));
//System.out.println("Setting "+field+" "+value+" "+arglist[0]);
} else {
arglist[0] = value;
}
try {
setterMethod.invoke(newObj,arglist);
} catch (Exception e) {
// System.out.println("Couldn't invoke method");
// System.out.println(e.getMessage());
// System.out.println(field+" "+arglist[0]);
log.error(e,e);
}
}
private static Method getSetterMethod(Class beanClass,
String fieldName,
List<Class> supportedTypes) {
for (Class clazz : supportedTypes) {
try {
Class[] argList = new Class[1];
argList[0] = clazz;
return beanClass.getMethod("set" + fieldName, argList);
} catch (NoSuchMethodException nsme) {
// just try the next type
}
}
return null;
}
/**
* Takes a bean and uses all of its setter methods to set null values
* @return
@ -344,7 +364,8 @@ public class FormUtils {
try{
meth.invoke(bean,(Object[]) null);
} catch (Exception e) {
log.error ("edu.cornell.mannlib.vitro.edit.FormUtils nullBean(Object) unable to use "+meth.getName()+" to set null.");
log.error ("unable to use " + meth.getName() +
" to set null.");
}
}
}
@ -384,11 +405,11 @@ public class FormUtils {
setterObjs[0] = overlayObj;
setterMeth.invoke(base,setterObjs);
} catch (NoSuchMethodException e) {
log.error("edu.cornell.mannlib.vitro.edit.FormUtils.overlayBean(Object,Object) could not find setter method "+setterName);
log.error("could not find setter method "+setterName);
}
}
} catch (Exception e) {
log.error("edu.cornell.mannlib.vitro.edit.FormUtils overlayBean(Object,Object) could not invoke getter method "+methName);
log.error("could not invoke getter method "+methName);
}
}
@ -398,7 +419,8 @@ public class FormUtils {
}
/**
* Decodes a Base-64-encoded String of format key:value;key2:value2;key3:value, and puts the keys and values in a Map
* Decodes a Base-64-encoded String of format
* key:value;key2:value2;key3:value, and puts the keys and values in a Map
* @param params
* @return
*/
@ -410,7 +432,8 @@ public class FormUtils {
beanParamMap.put(p[0],new String(Base64.decodeBase64(p[1].getBytes())));
}
return beanParamMap;
}
}
public static class NegativeIntegerException extends RuntimeException {}
}

View file

@ -7,8 +7,8 @@ import edu.cornell.mannlib.vedit.validator.ValidationObject;
public class IntValidator implements Validator {
protected int minVal = -1;
protected int maxVal = -1;
protected int minVal = 0; // the edit framework doesn't handle negative ints
protected int maxVal = Integer.MAX_VALUE;
public ValidationObject validate (Object obj) throws IllegalArgumentException {