16-Jul-04 (Created: 16-Jul-04) | More in 'OSCON-2004'

Declarative Software Part: Code examples

Let us Consider a web transation called AppendText


#appendText(reportId, appendText)
#Append the passed in text to the identified report
request.appendText.classname=com.ai.db.DBPreTranslateArgsMultiRequestExecutor
request.appendText.db=reportsDB
request.appendText.query_type=update
request.appendText.request.1=AT.GetText
request.appendText.request.2=AT.ConcatenateText
request.appendText.request.3=AT.UpdateText
request.appendText.request=AT.UpdateDate

If the above transaction succeeds


request.appendText.redirectURL=\
/akc/servlet/DisplayServlet?\
    url=DisplayNoteMPURL&\
    reportId={reportId}\
    &ownerUserId={ownerUserId}

A generic part to get original text


request.AT.GetText.classname=com.ai.db.DBRequestExecutor2
request.AT.GetText.stmt=\
select st.statement as item_text \
	,st.statement_id as statementId \
from reports r \
	,sql_statements st \
where 1=1 \
	and r.report_content_id = st.statement_id \
	and r.report_id = {reportId}

Use a part to append the new text to the old text


#concatenate	
request.AT.concatenateText.classname=com.ai.parts.SubstitutionPart
request.AT.concatenateText.substitution={item_text} {appendtext}	
request.AT.concatenateText.resultName=newText

A generic part to update the database


#final update
request.AT.UpdateText.classname=com.ai.db.DBRequestExecutor2
request.AT.UpdateText.query_type=update
request.AT.UpdateText.stmt=\
	update sql_statements \
	set statement={newText.quote} \
	where statement_id = {statementId}

Another generic part to update the last updated date


request.AT.UpdateDate.classname=com.ai.db.DBRequestExecutor2
request.AT.UpdateDate.query_type=update
request.AT.UpdateDate.stmt=\
	update reports \
	set last_updated_on=Now() \
	where report_id={reportId}

Let us investigate code for one of the parts


/**
 * Transforms a specified string with substitution arguments in it and returns it
 *
 * Additional property file arguments
 * 1. substitution=
 *
 * Output
 * 1.resultName: The above value translated after substitution
 *
 */

public class SubstitutionPart extends AFactoryPart
{
    protected Object executeRequestForPart(String requestName, Map inArgs)
            throws RequestExecutionException
    {
       try
       {
          String substString = AppObjects.getValue(requestName + ".substitution");
          String newString = 
	     SubstitutorUtils.generalSubstitute(substString,new MapDictionary(inArgs));
          return newString;
       }
       catch(ConfigException x)
       {
          throw new RequestExecutionException("Error:config errror",x);
       }
    }//eof-function
}//eof-class

Lee me include the configuration one more time for this part


#concatenate	
request.AT.concatenateText.classname=com.ai.parts.SubstitutionPart
request.AT.concatenateText.substitution={item_text} {appendtext}	
request.AT.concatenateText.resultName=newText

How does the substitution part look using IOC


public class SubstitutionPart extends AFactoryPart
{
    protected Object executeRequestForPart(String substitution, Map inArgs)
            throws RequestExecutionException
    {
       try
       {
          String newString = 
	     SubstitutorUtils.generalSubstitute(substitution,new MapDictionary(inArgs));
          return newString;
       }
       catch(ConfigException x)
       {
          throw new RequestExecutionException("Error:config errror",x);
       }
    }//eof-function
}//eof-class

See how we no longer need the configuration context and how substitution is passed in by the container. The container will use the configuration context and configuration api to do this instead of the part.

References

1. General Introduction to other Server side Patterns in this series

2. OSCON 2004 Summary page for Server side patterns session