|
Custom Tag Converter ExampleOverviewThis example creates and configures a custom tag converter for US format Zip Codes:
This example includes:
The tag converter class converts in the following ways:
It is used in JHTML like this: <VALUEOF PARAM="zip" converter="ZipCode">default</VALUEOF> Where zip may be either a string or a ZipCode object. Source Code and Configuration FilesZipCodeTagConverter.javapackage imagescript.atg.tagconverter;
import java.util.*;
import java.text.*;
import atg.servlet.DynamoHttpServletRequest;
import atg.droplet.*;
/**
* @copyright Copyright (c) 2001
* @company Art Technology Group
* @author Stuart Jones
* @version 1.0 ATG Training Supplemental Files
*/
public class ZipCodeTagConverter
extends atg.nucleus.GenericService
implements atg.droplet.TagConverter
{
static final String NAME = "ZipCode";
static final String NULLABLE_ATTRIBUTE = "nullable";
static final String REQUIRED_ATTRIBUTE = "required";
static final DecimalFormat nf1 = new DecimalFormat("00000");
static final DecimalFormat nf2 = new DecimalFormat("0000");
public ZipCodeTagConverter() {}
// Register the tag converter with the manager
public void doStartService()
{
TagConverterManager.registerTagConverter(this);
if(isLoggingInfo())
{
logInfo("Registered '" + getName() + "' tag converter");
}
}
private final static TagAttributeDescriptor[] sTagAttributeDescriptors = {
new TagAttributeDescriptor(NULLABLE_ATTRIBUTE,
"If this attribute is present, the ZipCode may be set to null",
true, false),
new TagAttributeDescriptor(REQUIRED_ATTRIBUTE,
"If this attribute is present, the ZipCode is required",
true, false)
};
public TagAttributeDescriptor [] getTagAttributeDescriptors() {
return sTagAttributeDescriptors;
}
public String getName() {
return NAME;
}
void log(String s)
{
if(isLoggingDebug()){ logDebug(s); }
}
void log(Exception e)
{
if(isLoggingError()){ logError(e); }
}
// Coverts a String which represents a ZipCode to a String
//
public Object convertStringToObject(DynamoHttpServletRequest pReq,
String pValue,
Properties pAttributes)
throws TagConversionException
{
String strResult = null;
boolean debugMode = isLoggingDebug();
log("convertStringToObject: '" + pValue + "'");
// Trim it
if (pValue != null) pValue = pValue.trim();
if (pValue == null || pValue.length() == 0)
{
// Should we allow a null value?
if (pAttributes.getProperty(NULLABLE_ATTRIBUTE) != null)
{
log("Returning TagConverterManager.SET_AS_NULL");
return TagConverterManager.SET_AS_NULL;
}
// is it required?
else if (pAttributes.getProperty(REQUIRED_ATTRIBUTE) == null)
{
log("Value is null or 0 length, but is required: Returning null");
return strResult;
}
// The value is null and it's required so that's an error
else
{
throw new TagConversionException("Missing or empty value supplied for "
+ "a required ZipCode field", "missingRequiredValue");
}
}
// Do the conversion
strResult = getZipCode(pValue);
if (strResult == null)
{
throw new TagConversionException("Unable to parse ZipCode from string: "
+ pValue, "invalidZipCode");
}
return strResult;
}
// Convert zipcode to a string
public String convertObjectToString(DynamoHttpServletRequest pReq,
Object pValue, Properties pAttributes)
throws TagConversionException
{
String strResult = "";
if (pValue == null)
{
if (pAttributes.getProperty(NULLABLE_ATTRIBUTE) == null)
{
log("Attempting to convert null object to String");
}
}
else if (pValue instanceof String)
{
log("Attempting to convert String '"+ pValue.toString());
strResult = getZipCode((String)pValue);
}
else if (pValue instanceof ZipCode)
{
log("Attempting to convert ZipCode '"+ pValue.toString());
strResult = ((ZipCode)pValue).getZipCode();
}
if(strResult == null)
{
throw new TagConversionException("Cannot convert: " + pValue
+ " into a ZipCode", "invalidZipCode");
}
return strResult;
}
String getZipCode(String str)
{
boolean debugMode = isLoggingDebug();
String strResult = null;
int iMain = 0;
int iSecond = 0;
boolean bFatalError = false;
try
{
boolean bDash = false;
log("getZipCode("+ str + ")");
if(str.length() >= 5)
{
String firstFive = str.substring(0,5);
iMain = Integer.parseInt(firstFive);
log("Main Zip Code Number = "+ iMain);
if(str.length() > 5)
{
int iStartSecond = 5;
if(str.length() >= 6)
{
bDash = (str.charAt(iStartSecond) == '-');
if(bDash)
{
iStartSecond++;
}
log("str.charAt(iStartSecond) ="+ str.charAt(iStartSecond));
log("bDash ="+ bDash);
}
logDebug("iStartSecond ="+ iStartSecond);
if(str.length() == (iStartSecond + 4))
{
String secondFour = str.substring(iStartSecond);
log("secondFour ="+ secondFour);
iSecond = Integer.parseInt(secondFour);
log("iSecond ="+ iSecond);
}
else
{
log("Wrong String length with optional second code");
bFatalError = true;
}
}// more than 5 chars
else
{
log("Code does not contain optional second code");
}
}
else
{
bFatalError = true;
}
}
catch(Exception e) //includes null
{
bFatalError = true;
if(isLoggingDebug())
{
logDebug("Error parsing '" + str + "' : " + e.getMessage());
}
}
if(!bFatalError)
{
strResult = assemble(iMain,iSecond);
}
return strResult;
}
public static String assemble(int nMain, int nSub)
{
String strResult = "";
try
{
strResult = nf1.format(nMain);
if(nSub > 0)
{
strResult = strResult + "-" + nf2.format(nSub);
}
}
catch(NumberFormatException e)
{
}
return strResult;
}
}
ZipCode.javaThis additional class is provided to show how to convert from objects other than strings. package imagescript.atg.tagconverter;
/**
*
*
* @copyright Copyright (c) 2001
* @company Art Technology Group
* @author Stuart Jones
* @version 1.0 ATG Training Supplemental Files
*/
public class ZipCode
{
public ZipCode() { }
int mMainCode;
int mSubCode;
public void setMainCode(int p) { mMainCode = p; }
public int getMainCode() { return mMainCode; }
public void setSubCode(int p) { mSubCode = p; }
public int getSubCode() { return mSubCode; }
public String toString()
{
return getClass().getName() + " : " + mMainCode + "-" + mSubCode;
}
public String getZipCode()
{
return ZipCodeTagConverter.assemble(mMainCode,mSubCode);
}
}
/training/sf/tagconverter/ZipCode.propertiesThis is the configuration file for the tag converter component. I made it a component so it could be included in an Initial.properties file to cause the self registration. # /training/sf/tagconverter/ZipCode #Tue Aug 07 15:10:40 PDT 2001 $class=imagescript.atg.tagconverter.ZipCodeTagConverter $description=ZipCode\ Converter $scope=global loggingDebug=true /Initial.propertiesThis is the configuration file to add the converter to the initial services. At startup time this starts the converter and ensures that it's doStartService method is called, this registers the tagConverter. # /Initial #Tue Aug 07 15:00:37 PDT 2001 initialServices+=/training/sf/tagconverter/ZipCode Test FilesThese files are not required to run the ZipCodeTagConverter. They are only used here as a simple demonstration and test harness. /test/MyZipCode.propertiesThis is the configuration file for the test ZipCode used in zipcode.jhtml # /august/MyZipCode #Tue Aug 07 17:35:10 PDT 2001 $class=imagescript.atg.tagconverter.ZipCode $scope=global mainCode=94706 subCode=1233 zipcode.jhtmlThis is the a demo file to test the tag converter. It uses a page fragment to actually display the zip code conversion. <IMPORTBEAN BEAN="/test/MyZipCode"> <HTML> <HEAD> <TITLE>ZipCode Form</TITLE> </HEAD> <BODY> <h1>ZipCode tag converter test</h1> <h2>Object Conversion Test</h2> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="bean:MyZipCode"> </DROPLET> <h2>Text Conversion</h2> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="923421234"> </DROPLET> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="92342"> </DROPLET> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="94109-2601"> </DROPLET> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="01234"> </DROPLET> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="01234-0023"> </DROPLET> <DROPLET SRC="zipfragment.jhtml"> <PARAM NAME="zip" VALUE="012340123"> </DROPLET> </BODY> </HTML> zipfragment.jhtmlThis is the a demo file to test the tag converter. It uses a page fragment to actually display the zip code conversion. <DECLAREPARAM NAME="zip" CLASS="java.lang.Object" DESCRIPTION="Any zip code"> <!-- Title: Display Zip Code Fragment --> <hr> Zip (<VALUEOF PARAM="zip">null</VALUEOF>) converts to = <VALUEOF PARAM="zip" converter="ZipCode">No Value</VALUEOF> <hr> |
|