Trying to get some opinions:
One of the goals in Scarab is to develop a Pull template system to allow
maximum flexibility for the ui designers, separation of developer roles,
etc.
One of the ideas I had was that form field names should describe an
object as much as possible, for example:
ScarabIssueAttributeValue[100:201]OptionId=32 (100:201 is a compound id
issueid:attributeid)
Then regardless of what form this value came from, it is pretty apparent
the intent is to set the option_id property of the object with
id=100:201 of class ScarabIssueAttributeValue.
One problem with this approach is that it can result in a lot of String
parsing/manipulation to extract the data. It would also be nice to keep
the names a little shorter. Both of these can be helped using some
input processing helper classes. I was thinking along the lines of
torque - the inputs are defined in an xml file and java classes are
generated from the xml representation.
And we can throw the input validation into the helper class as well.
Example xml.
<appdata>
<inputs>
<class name="attribute" id="att">
<property name="option_id" id="o" type="int" mask="[0..9]+"
onError="-1" />
<property name="value" id="v" type="String" length="255" />
</class/>
...
</inputs>
<appdata>
This would allow the previous query parameter to be given by:
att100:201o=32
In order to cut down on String parsing, the object should be declared in
the form
att=100:201 <--> <input type="hidden" name="att" value="100:201">
The ui designer would get the object from a companion BO and use it to
populate a form
#foreach $attribute in $issue.attributes
#set inAttr = $attribute.InputAttribute
<input type="hidden" name="$inAttr.CID" value="$inAttr.OID">
<input type="text" name="$inAttr.ValueKey" value="$!inAttr.Value">
#end
The class generated would look something like:
public class InputAttribute implements ???
{
private String oid;
private int option_id;
private boolean option_id_flag = false;
private boolean option_id_valid_flag = false;
private String value;
private boolean value_flag = false;
private boolean value_valid_flag = false;
...
private static final String NEW = "0";
private static final int NEW_LENGTH = NEW.length();
private static final String CID = "att";
private static final int CID_LENGTH = CID.length();
private static final String OPTION_ID = "o";
private static final int OPTION_ID_LENGTH = OPTION_ID.length();
private static final RE OPTION_ID_REGEXP = new RE("[0-9]+");
private static final int OPTION_ID_ONERROR = -1;
private static final String VALUE = "V";
private static final int VALUE_LENGTH = OPTION_ID.length();
private static final INT VALUE_VALID_LENGTH = 255;
...
private static final String deleted = "d";
private static final int CID_LENGTH = CID.length();
public InputAttribute()
{
oid = NEW;
}
public InputAttribute(String oid)
{
this.oid = oid;
}
public InputAttribute(ParameterParser pp)
{
InputAttribute(NEW, pp);
}
public InputAttribute(String oid, ParameterParser pp)
{
this.oid = oid;
setOptionId(pp);
setValue(pp);
...
}
public static String getCID()
{
return cid;
}
public String getObjectKey()
{
return cid + oid;
}
public static ArrayList getObjects(ParameterParser pp)
{
ArrayList objs = null;
String[] oids = pp.getStrings(CID);
if (oids != null)
{
objs = new ArrayList(oids.length);
for (int i=0; i<oids.length; i++)
{
objs[i] = new Attribute(oids[i], pp);
}
}
return objs;
}
public String getOptionIdKey()
{
return getObjectKey() + OPTION_ID;
}
/**
* Get the value of option_id.
* @return value of option_id.
*/
public int getOptionId()
{
return option_id;
}
/**
* Set the value of option_id.
* @param option_id Value to assign to option_id.
*/
public void setOptionId(ParameterParser pp)
{
String key = new StringBuffer(CID_LENGTH + oid.length() +
OPTION_ID_LENGTH).append(CID).append(oid).append(OPTION_ID)
.toString();
if (pp.containsKey(key))
{
option_id_flag = true;
String val = pp.getString(key);
try
{
this.option_id = Integer.parseInt(val);
if ( validateOptionId(val) )
{
option_id_valid_flag = true;
}
}
catch (NumberFormatException nfe)
{
option_id_valid_flag = false;
this.option_id = OPTION_ID_ONERROR;
}
}
}
public boolean validateOptionId(String val)
{
option_id_valid_flag = OPTION_ID_REGEXP.match(val);
return option_id_valid_flag;
}
public boolean isOptionIdValid()
{
return option_id_valid_flag;
}
public boolean isOptionIdSet()
{
return option_id_flag;
}
public String getValueKey()
{
return getObjectKey() + VALUE;
}
/**
* Get the value of value.
* @return value of value.
*/
public String getValue()
{
return value;
}
/**
* Set the value of value.
* @param option_id Value to assign to value.
*/
public void setValue(ParameterParser pp)
{
String key = new StringBuffer(CID_LENGTH + oid.length() +
VALUE_LENGTH).append(CID).append(oid).append(VALUE)
.toString();
if (pp.containsKey(key))
{
value_flag = true;
String val = pp.getString(key);
this.value = val;
validateValue(val);
}
}
public boolean validateValue(String val)
{
value_valid_flag = VALUE_VALID_LENGTH >= val.length();
return value_valid_flag;
}
public boolean isValueValid()
{
return value_valid_flag;
}
public boolean isValueSet()
{
return value_flag;
}
}
The set flag would get set if the query parameter exists while the valid
flag is only set if the input format is correct. If the parameter
exists a good attempt is made to assign the value to the property
regardless of validity, so that it is available for redisplay.
I will probably create this parallel to torque, though not sharing the
schema. Unless consensus is to keep the <appdata> all in one file.
Comments please.
John McNally
------------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Search: <http://www.mail-archive.com/turbine%40list.working-dogs.com/>
Problems?: [EMAIL PROTECTED]