Hello Jonathan,
It is easy stuff. 8) For me, of course, but not for another people,
because it lives in my head... Now I trying to write documentation for
bean-factory - hard work really. One little step to implement idea in
code and another - great step - to describe it in clear manner.
Main idea is to build common mechanism to declare bean descriptions in
config file and generate it automatically at request processing.
Core class is BeanFactoryServlet - it extends ActionServlet, defines
additional digester calls and overload
ActionServlet.processPreprocess() method. New version of this method
do all work to generate beans after form processing and before action
calling.
There are exists such abstractions as -
1. factory - class to generate beans
2. template - bean description
3. parameter - parameter decribtion for the bean-template
4. registration - subscribtion to bean generation in action mapping
5. parameter-value - setter for parameter in registration
Here is a sample config with comments -
<struts-config>
<data-sources>
<data-source
autoCommit="false"
description="INET"
driverClass="COM.ibm.db2.jdbc.app.DB2Driver"
url="jdbc:db2:TEST"
maxCount="3"
minCount="1">
<set-property property="user" value="tester"/>
<set-property property="password" value="test"/>
</data-source>
</data-sources>
<!-- Bean factories list. Each bean factory implement its own logic
and sometimes uses its own parameter set. -->
<bean-factories>
<!-- Simple factory - collect all parameters, search constructor
for this parameters and create bean. Really simple. -->
<factory name="simple" type="org.apache.struts.factory.SimpleFactory"/>
<!-- JDBC family factories. All it uses struts data-source. Data
source can be specified by dataSource attribute. If none
specified then default data source name will be used. First
parameter for bean, generated by this factories must be string
with SQL query. SQL query can has parameters. All parameters
(if exists in parameters list for the bean) after first
parameter (SQL query) treated as placeholders for prepared
statement. Factory binds it to the query, execute query and...
And result of this query must be processed by the concrete
factory in its own manner. Every class of this family uses
common strategy to process row of data and store values from
it - bean of target type must implement DataBean interface and
define populateFrom(ResultSet) method for data retrieving. -->
<!-- Array factory. Walk throw result set and fill ArrayList with
beans of target type. For every row it creates bean, call for
it populateFrom(ResultSet) method and save it in the
ArrayList. This factory copy all result set to the ArrayList
and return it as result. -->
<factory name="arrayJDBC"
type="org.apache.struts.factory.jdbc.JDBCArrayFactory"
className="org.apache.struts.factory.jdbc.JDBCFactoryMapping"/>
<!-- Slide factory. Cut from the result set window of rows and
store it ArrayList as beans of target type (call
populateFrom(ResultSet) to fill bean with values). Result is
special container - object of Slide class. It store link to
ArrayList, offset of the window in result set length of
the window and total length of the result set.
This factory can be used for result set 'slicing' to
view it page by page via jsp pages. There are exists special
tag in this package - pager - to display rows in such manner.
Bean templates for this factory must define two parameters of
Integer type after SQL query - offset and pageSize.
-->
<factory name="slideJDBC"
type="org.apache.struts.factory.jdbc.JDBCSlideFactory"
className="org.apache.struts.factory.jdbc.JDBCFactoryMapping"/>
<!-- Single bean factory. Retrieve first row from the result set,
create bean, call populateFrom(ResultSet) for this bean and
return bean as result. -->
<factory name="singleJDBC"
type="org.apache.struts.factory.jdbc.JDBCSingleFactory"
className="org.apache.struts.factory.jdbc.JDBCFactoryMapping"/>
</bean-factories>
<!-- Bean templates. Each bean template defines pattern to be used
in factory - type of the target bean, name, parameter set. Each
factory can interpret bean template by its own way. For each parameter
can be specified default value and source to retrieve value for
this parameter.
Available sources for parameters -
request.parameter - parameter of the request by name from
name attribute from parameterMapping
request or request.attribute - attribute from request named
by name from name attribute from
parameterMapping
session or session.attribute - attribute from
session named by name from name attribute
from parameterMapping
application or application.attribute - attribute from
application scope named by name from name
attribute from parameterMapping
application.property - value of the servlet property named by
name from name attribute from
parameterMapping
form or form.property - value from mapped to this action
form, if exists one. Name attribute
from parameterMapping used as name of the
property. -->
<bean-templates>
<!-- Bean template to retrive single row. First parameter is SQL
query (has attribute force to avoid values from request,
session or another sources) and second parameter is id of the
document and must be retrieved from source "request.parameter"
- default source if none source specified. -->
<bean-template name="sample" type="bf.beans.Sample">
<parameter
name="query"
type="java.lang.String"
value="select * from bf.sample where id = ?"
force="true"/>
<parameter name="docId" type="java.lang.Integer"/>
</bean-template>
<!-- List of beans of bf.beans.Sample type. This bean template
intended to be used in JDBCArrayFactory. -->
<bean-template name="sampleList" type="bf.beans.Sample">
<parameter
name="query"
type="java.lang.String"
value="SELECT id, name FROM bf.sample"
force="true"/>
</bean-template>
<!-- Sample of the bean template for the slide factory. -->
<bean-template name="sampleSlide" type="bf.beans.Sample">
<parameter
name="query"
type="java.lang.String"
value="SELECT id, name FROM bf.sample"
force="true"/>
<parameter name="offset" type="java.lang.Integer" value="8"/>
<parameter name="pageSize" type="java.lang.Integer" value="12"/>
</bean-template>
<!-- Sample of the bean template with parametrized SQL query. For
the "level" attribute default value 6 is specified. This value
will be used if none will be found in default source -
'request.parameter'.-->
<bean-template name="sampleParList" type="bf.beans.Sample">
<parameter
name="query"
type="java.lang.String"
value="SELECT id, name FROM bf.sample where id > ?"
force="true"/>
<parameter name="level" type="java.lang.String" value="6"/>
</bean-template>
</bean-templates>
<!-- ========== Global Forward Definitions ============================== -->
<global-forwards>
<forward name="index" path="/index.jsp"/>
<forward name="array" path="/array.do"/>
<forward name="pager" path="/pager.do"/>
<forward name="slide" path="/slide.do"/>
<forward name="single" path="/single.do"/>
<forward name="parameter" path="/parameter.do"/>
</global-forwards>
<!-- ========== Action Mapping Definitions ============================== -->
<!-- For any action mapping we can define bean registraions. Bean
registration is link between factory and bean-template. -->
<action-mappings>
<action path="/array"
type="org.apache.struts.actions.ViewAction">
<!-- This registration uses 'alias' attribute (name to store
bean in target scope, if none specified then name
attribute will be used) and flag 'necessary' - if bean
was not created then error will be generated. Bean can be
saved in request or session scope. There is 'scope'
attribute for this purpose. -->
<bean name="sampleList" alias="list" factory="arrayJDBC" necessary="true"/>
<forward name="view" path="/sample.jsp"/>
</action>
<action path="/pager"
type="org.apache.struts.actions.ViewAction">
<bean name="samplePager" alias="slide" factory="slideJDBC" necessary="true"/>
<forward name="view" path="/pager.jsp"/>
</action>
<action path="/slide"
type="org.apache.struts.actions.ViewAction">
<bean name="sampleSlide" alias="slide" factory="slideJDBC" necessary="true"/>
<forward name="view" path="/sample.jsp"/>
</action>
<action path="/single"
type="org.apache.struts.actions.ViewAction">
<bean name="sample" alias="item" factory="singleJDBC" necessary="true"/>
<forward name="view" path="/single.jsp"/>
</action>
<action path="/parameter"
type="org.apache.struts.actions.ViewAction">
<bean name="sampleParList" alias="list" factory="arrayJDBC" necessary="true"/>
<forward name="view" path="/sample.jsp"/>
</action>
</struts-config>
Wednesday, June 13, 2001, 4:56:27 PM, you wrote:
JA> Hello Oleg.
JA> I have been following your progress on your bean-factory, and have
JA> downloaded the classes. However, I still have not fully grasped what it is
JA> substituting in struts, and what the sequence of events is when they are
JA> called and used. Could you provide a brief summary and sequence of events?
JA> I was not able to get a complete picture of what is happening from the
JA> earlier e-mails to the list.
JA> Sincerely
JA> Jonathan
JA> ----- Original Message -----
JA> From: "Oleg V Alexeev" <[EMAIL PROTECTED]>
JA> To: <[EMAIL PROTECTED]>
JA> Sent: Wednesday, June 13, 2001 8:29 AM
JA> Subject: New BeanFactory build
>> Hello struts-dev,
>>
>> This day (13 June) I place new build of BeanFactory (Struts extension
>> to support unattended bean generation at pre action processing)
>>
>> Last additions - hard parameter setters for bean registrations, new
>> Pager version, new PagerTag class - wrapper around Pager class (sample
>> of using in pager.jsp in sample application).
>>
>> You can review it here -
>>
>> http://www.sura.ru/~gonza/bean-factory/
>>
>> --
>> Best regards,
>> Oleg mailto:[EMAIL PROTECTED]
>>
>>
--
Best regards,
Oleg mailto:[EMAIL PROTECTED]