Re: Business Logic Beanies

2001-01-06 Thread Ted Husted

The "Struts with a Fruit Glaze" example has been updated to demonstrate
filling option tags from a DBMS query, and changing another query using
those options, along with inserting a new record. Still alpha, but
available nonetheless if anyone is interested. 

Of course, it still also demonstrates an approach to using business
logic beans in Struts. Right now, I'm defining a base data-bean, that
is used by one or more query-beans -- and also by one or more
form-beans. The action commutes the data-bean from the form to the
query (along with a connection from the pool). The data-bean is not
linked to Struts; the query-bean is only loosely linked through the
ActionForm class (which is fairly generic anyway).

The queries here are using prepared statements, and linked to host
variables in the data-bean(s), so narrowing the query can by done
automagically by changing options on the forms (which share the
data-beans with the query-beans). 

 http://husted.com/about/struts/ 





Re: Business Logic Beanies

2001-01-05 Thread Ted Husted

A kind soul sent me this link to a Powered-by-Struts auction
application, 

BrewTrade by Java-Genius - http://www.java-genius.com/

that uses a neat mechanism to abstract a database result into a generic
list of fields (KeyValuePairs), which can then be used to populate a
data bean. The method that gathers the database results packages each
value with its column name, which the data bean can then use to match
it up with one of its own properties. 

This comes very close to turning a result into an array of standard
Java Beans, using the metadata to generate the "introspective" layer. 

Has anyone seen a type of factory that would do this; take a resultset
and spit out a list of JavaBeans, where the column names automatically
become "get" accessors. 





Re: Business Logic Beanies

2001-01-04 Thread Ted Husted

On 1/4/2001 at 8:00 AM Michael Gerdau wrote:
 The current approach is to have them hardwired in a helperclass which
does provide these ... What I think one should have is a generic (XML
?) file that holds all these parameters very much like a resource
bundle.

How about a helper bean with properties that can be specified in the
struts-config.xml?

Something like what Craig mentioned here:

 form-bean name="SearchForm"
  type="com.mycompany.mypackage.SearchFormBean"
 set-property property="resource" value="...path to
resource..."/
 /form-bean

If Martin Cooper gets the Digester running standalone, you should be
able to write a utility that could plug into another Java application
and read in the same helper beans!

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 425-0252; Fax 716 223-2506.
-- http://www.husted.com/





Re: Business Logic Beanies

2001-01-03 Thread Michael Gerdau

Being able to autogenerate the "logical data beans" would be excellent!
And very much in keeping with the rest of the Struts framework.
Ideally, this would be a mechanism that could also be used in other
applications (e.g. Swing-based). 

So, in general terms, it seems we're coming down to this:

(data bean) :: (query bean) :: (action form) :: (action object) | JSP

Where the DataBean is totally unaware of Struts, and the QueryBean
might be only vaguely aware, through use of the GenericConnection and
GenericDataSource classes. 

Sounds good.

In my ignorance (and still being somewhat new to struts) I wasn't
aware of the aforementioned generic classes. Of course the generic
outline I just posted in another mail should be adjusted to use these.

I would also say that the QueryBean should be able to read its base
query from a resource file, so that these can be adjusted without
recompiling (and centralized for control and documentation). 

Agreed.

Talking about this I think struts also needs some kind of application
configuration file. AFAICT the resources won't suffice as I might need
configuration information inside my EJB etc. as well.

Or is there something already which simply escaped me ?

Best,
Michael



Re: Business Logic Beanies

2001-01-03 Thread Craig R. McClanahan

Ted Husted wrote:

 Being able to autogenerate the "logical data beans" would be excellent!
 And very much in keeping with the rest of the Struts framework.
 Ideally, this would be a mechanism that could also be used in other
 applications (e.g. Swing-based).

 So, in general terms, it seems we're coming down to this:

 (data bean) :: (query bean) :: (action form) :: (action object) | JSP

 Where the DataBean is totally unaware of Struts, and the QueryBean
 might be only vaguely aware, through use of the GenericConnection and
 GenericDataSource classes.


You should program in terms of the javax.sql.DataSource interface, rather than
hard coding GenericDataSource.  That way, you will not be tying yourself to the
Struts connection pool implementation.

By the same reasoning, the thing you get back from DataSource.getCoinnection()
is just a java.sql.Connection -- you do *not* want to be dependent on any
particular underlying implementation.


 I would also say that the QueryBean should be able to read its base
 query from a resource file, so that these can be adjusted without
 recompiling (and centralized for control and documentation).


If you do it this way, do you need more than one QueryBean?  Couldn't you create
a generic one that processes different kinds of query strings based on the name
of the resource you told it to read?


 In my own work, I subclassed the QueryBean from ActionFormBean (in case
 I figure out how to read it from the struts-config file).

Let's say your QueryFormBean has a property named "resource", with corresponding
getResource() and setResource() methods.  This should be configured by doing
something like this in struts-config.xml:

form-bean name="SearchForm"
 type="com.mycompany.mypackage.SearchFormBean"
set-property property="resource" value="...path to resource..."/
/form-bean

but it won't work until tonight's nightly build, when I make it legal to embed
set-property/ inside a form-bean :-)


 In the
 meantime, I tried to give it a standard properties file to read the
 base SQL strings. No problem if I hardcode a system path, but no go if
 I try to find it on the classpath. To wit:

   public void resetQuery() throws IOException {
 // Must call setName first!
 Properties props = new Properties();
 String name = "d:\\QueryFormBean.properties";

 /*
 InputStream is = null;
 is = this.getClass().getClassLoader().getResourceAsStream(name);

 if (is != null) {
   props.load(is);
   is.close();
   setQuery(props.getProperty(getName()));
 }
 */

 FileInputStream in = new FileInputStream(name);
 props.load(in);
 setQuery(props.getProperty(getName()));
 in.close();

   }

 The commented code was taken from the Struts PropertyMessageResource,
 but doesn't seem to work. (Not that I understand what it's doing - I'm
 just banging the rocks together!) If I hardcode the path, everything is
 hunky-dory.


If you want to use ClassLoader().getResourceAsStream(name), the name you pass
should look like a Java class name, but with periods changed to slashes.  In
other words, if your class is in package com.mycompany.mypackage, and your
resource file name is "QueryFormBean.properties", the resource name is:

com/mycompany/mypackage/QueryFormBean.properties

This resource will be looked up along the runtime classpath for your web app,
just like classes are looked up.



 A hacked example of all this, that works around the properties glitch,
 is available as a ZIP file at
  http://husted.com/about/struts   as "Struts with a Fruit Glaze".

 Comments appreciated!

 -- Ted Husted, Husted dot Com, Fairport NY USA.
 -- Custom Software ~ Technical Services.
 -- Tel 716 425-0252; Fax 716 223-2506.
 -- http://www.husted.com/

Craig





Re: Business Logic Beanies

2001-01-03 Thread Craig R. McClanahan

"Craig R. McClanahan" wrote:


 form-bean name="SearchForm"
  type="com.mycompany.mypackage.SearchFormBean"
 set-property property="resource" value="...path to resource..."/
 /form-bean


Oops, this really needs to include a reference to the custom ActionFormBean subclass
to use.  You can do this (again, as of tonight's nightly build) in one of two ways:

*   Set an initialization parameter named "formBean" on the
controller servlet that names the class to be used for
all form-bean elements.

*   On each individual formBean, include a "className"
attribute that identifies the ActionFormBean subclass to
use for this particular entry (so you can have different ones).

Craig





Re: Business Logic Beanies

2001-01-03 Thread Ted Husted

On 1/3/2001 at 11:06 AM Craig R. McClanahan wrote:
If you do it this way, do you need more than one QueryBean?  Couldn't
you create a generic one that processes different kinds of query
strings based on the name of the resource you told it to read?

Now that you mention, it could be used a generic bean now; I've been
using the name property as the key into the resource, which is meant to
store all the queries used anywhere by the application. So that part is
probably working already. 

I was subclassing it to provide a way to hand Struts a collection
(based on the ResultSet) for the tags to play with. When we upgrade the
tags for rowsets, I might be able to skip this step and use the rowset
where I'm generate a collection now. Today, I'm just using the subclass
to do something like

  public FruitSalesDetail[] fetchDetail(int from, int count) throws
SQLException {
// TODO - Generate exception if from  1
setFrom(from);
// optimistic result
setCountResult(count);
// calculate where Prev would have been; but don't go negative
if (fromcount) {setPrev(from-count);} else {setPrev(1);}
FruitSalesDetail[] detail = new FruitSalesDetail[count];
// resultSet.absolute(from); // FIXME if 1 starts at 2 ?
for (int i = 1; i  from; i++) {
  result.next();
}
for (int i = 0; i  count; i++) {
  if (result.next()) {
detail[i] = new FruitSalesDetail();
detail[i].setYear(result.getInt(1));
detail[i].setQuarter(result.getInt(2));
detail[i].setApples(result.getInt(3));
detail[i].setApplesales (result.getFloat(4));
detail[i].setOranges(result.getInt(5));
detail[i].setOrangesales (result.getFloat(6));
detail[i].setTopseller(result.getString(7));
from++;
  }
  else {
setCountResult(i);
break;
  }
}
if (result.next()) {setNext(from);} else {setNext(1);}
return(detail);
  }

The "detail" it returns gets inserted directly into the page context

  page.setAttribute("fruitSalesDetail",salesQuery.fetchDetail());

where iterate can snag it with 

  logic:iterate id="row" name="fruitSalesDetail" length="length"
scope="page"

The next/prev stuff lets me call the JSP again for the next block of
records, or rollback with 

  if (action.equals("prev")) { sQuery.setNext(sQuery.getPrev()); } 
  // where sQuery is a QueryBean property of my ActionForm.

The 30,000 foot view is 

ActionForm - ActionDataForm - FruitSalesForm
// Provides JDBC and PageContext hooks

ActionFormBean - QueryFormBean - FruitSalesQuery
// Implements JDBC calls; Maintains query state between requests.

Action - FruitSalesAction
// Resets FruitSalesQuery bean to start new round of requests.

FruitSalesDetail
// Generic bean to encapsulate fields returned by query
// Inserted as an array into page context by FruitSalesForm

Of course, suggestions for an alternate model would be appreciated! The
endgame is just to provide something the iterate and option tags can
use.

A working example is available at http://husted.com/about/struts 


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 425-0252; Fax 716 223-2506.
-- http://www.husted.com/





Re: Business Logic Beanies

2001-01-02 Thread Ted Husted

I'm finishing up on a model for executing JDBC retrievals from a JSP,
using a scriptlet like 

% 
  FruitSalesForm fruitSalesForm = (FruitSalesForm)
session.getAttribute("fruitSalesForm");
  fruitSalesForm.setPageContext(pageContext); 
%

to execute pooled JDBC connetions, and transfer the results into
page-scope collections,  for use by the iterate or option tags. 

To get there, I 

Setup straight "data beans" to represent the rows of a table (or a form
option). 

Subclassed a "QueryFormBean" from ActionFormBean to encapsulate the
query string, execute the query given a GenericConnection, and to track
the last relative position in the result set.

Subclassed QueryFormBean to return an array of data beans from the
object's ResultSet (a RowSet would be better). This array is ultimately
inserted directly into the page context, for use by an iterate or
option tag.

Subclassed a "ActionDataForm" from ActionForm, and added methods to
expose key JSP and Struts resources via the page context, and a method
for obtaining a GenericConnection from the servlet. 

Implemented the ActionDataForm with the subclassed QueryFormBean as a
property. Overrode setPageContext to execute the QueryFormBean, and
insert the databean array into the page context. 

I'm working on adding metadata and other convenience methods now. I'll
post the working example soon. Just wondering what similar solutions
others might have found to handling JDBC queries within Struts.





Re: Business Logic Beanies

2001-01-02 Thread Michael Gerdau

[scriptlets to execute JDBC inside a JSP]

I'm working on adding metadata and other convenience methods now. I'll
post the working example soon. Just wondering what similar solutions
others might have found to handling JDBC queries within Struts.

The design I us works like this:
- for each logical item of data write a trivial class with all the
  get/set methods (the Entity class).
- for each such trivial data class write a likewise trivial class that
  does know how to map a ResultSet to the Entity class. Some SQL-Stmt
  merging code is added as well to tune the query (the Retriever class).
- for each logical query add a more or less trivial class that does the
  actual JDBC stuff (the Controller class).

For all of the above there exists base classes that make writing the
code very simple.

The Entity class can easily be exposed to Struts and used there.

Th Controller class is invoked from Action; if there is some initialization
to be done for a JSP create an action that's executed before the JSP is
actually displayed.


AFAICT the design outlined above does facilitate a better separation
between the underlying physical data model and the way this data is
represented to the user than can be achieved by using scriplets.

If anyone is interested I'd be willing to share the code (though I'd
have to check on copyright before).

Best,
Michael
--
 Vote against SPAM - see http://www.politik-digital.de/spam/
 Michael Gerdau   email: [EMAIL PROTECTED]
 Windows loading; please take a nap...
 PGP-keys available on request or at public keyserver





Re: Business Logic Beanies

2001-01-02 Thread Craig R. McClanahan

Michael Gerdau wrote:

 [scriptlets to execute JDBC inside a JSP]

 I'm working on adding metadata and other convenience methods now. I'll
 post the working example soon. Just wondering what similar solutions
 others might have found to handling JDBC queries within Struts.

 The design I us works like this:
 - for each logical item of data write a trivial class with all the
   get/set methods (the Entity class).

If we have any XSLT gurus in our midst, this sounds like it is something that
could be auto-generated from an XML-based description of the "logical item", no?


 - for each such trivial data class write a likewise trivial class that
   does know how to map a ResultSet to the Entity class. Some SQL-Stmt
   merging code is added as well to tune the query (the Retriever class).

As above, could such a "trivial" class be auto-generated?


 - for each logical query add a more or less trivial class that does the
   actual JDBC stuff (the Controller class).


The EJB analogue for this would be to add a finder method that implemented the
logical query.


 For all of the above there exists base classes that make writing the
 code very simple.

 The Entity class can easily be exposed to Struts and used there.

 Th Controller class is invoked from Action; if there is some initialization
 to be done for a JSP create an action that's executed before the JSP is
 actually displayed.

 AFAICT the design outlined above does facilitate a better separation
 between the underlying physical data model and the way this data is
 represented to the user than can be achieved by using scriplets.

 If anyone is interested I'd be willing to share the code (though I'd
 have to check on copyright before).


I'd like to see design patterns like this available to the Struts community --
*especially* if we can create some tools that reduce the tedium of creating
"trivial" classes.


 Best,
 Michael

Craig McClanahan