Kwa Kil On Swa

Thursday, November 30, 2006

exports in config and ant test-all working again

moved the exports table context into the spring config file, so we don't need an exports table.
got ant test-all working again (against postgres)

Wednesday, November 29, 2006

Stock management - suppliers, makers and zones

Added Company dao for suppliers and makers
Added Zone dao for ... zones
Zones is complicated because when the user picks a zone its that zones and all its child zones and other descendant zones that should be selected.

Tuesday, November 21, 2006

appfuse iBatis SQL maps - no need for semicolons

appfuse standard sql maps such as defined in UserSQL.xml have semicolons ; on the end of every bit of SQL, this is unecessary/optional for postgres and illegal for derby. So its better to remove semicolons from the SQL in the iBatis sql maps.

Monday, November 20, 2006

ibatis caching configuration

http://www.jugsardegna.org/vqwiki/jsp/Wiki?action=action_view_attachment&attachment=Spring_iBatisJug28012006.pdf

See this bit

cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="false"
maxRequests="64"
maxSessions="20"
maxTransactions="8"
useStatementNamespaces="false"
/>

derby network server starup in embeddded mode in a tomcat application

To startup the derby network server you can put
set JAVA_OPTS=-Dderby.drda.startNetworkServer=true
at the top of catalina.bat

or put this code in the top of StartupListener.setupContext()
NetworkServerControl server;

try {
server = new NetworkServerControl();
server.start (null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

or put derby.properties in %TOMCAT_HOME%\bin (which is also where the database created by the embedded derby goes)
# When derby is started in embedded mode by the tomcat web application, this
# flag will cause the network server to start too in another thread.
# This allows other clients such as "ij" to connect to the same database.
derby.drda.startNetworkServer=true
#derby.drda.portNumber=1110
#derby.drda.host=myhost
#derby.connection.requireAuthentication=true
#derby.authentication.provider=BUILTIN
#derby.user.judy=no12see
This is currently my preffered solution.
(Unfortunately its not being picked of the classpath, but from the current directory.)

I think that this directory could be changed by setting derby.system.home, possibly in StartupListener.setupContext(), but I haven't tried it.

Friday, November 17, 2006

scratch

<suppliers_for_parts supplier_id="3" part_id="4" currency_cd="EUR" supplier_ref="ENG-B12-AC-2.04" last_price="54000.00" last_price_dttm="2006-06-18 00:00:00.0"/>

Thursday, November 16, 2006

appfuse libraries

  • oscache - made for caching snippets of jsp - half enabled in appfuse (need to uncomment cacheFilter filter-mapping), but not used anyway apart from the flush cache page . Simple example
    • <cache:cache key="foobar" scope="session">
      <%= myBean.getTitle() %>
      </cache:cache>
  • ehcache- made for caching java objects - enabled in appfuse, but not used (I think!). I think it can generally be used more easily with hibernate, although it can be used as a general purpose cache. There is a spring bean called "userCache" that can be used to access ehcache functionality. Slightly annoying is each time you start tomcat you get a new empty directory in C:\Documents and Settings\azzoti\Local Settings\Temp c called for example ehcache_auto_created_1161994081609 etc.
  • ibatis - has caching

appfuse and ibatis dynamic queries

for some reason appfuse defines the iBatis queries in a CDATA section.

<select id="getStockMaintenanceQueryCriterias" resultMap="stockMaintenanceQueryCriteriaResult">
<!-- Can say also say part_nm like '%$partNm$%', but partNm will need to have escape processing carried out -->
<![CDATA[
select * from stock_maintenance_query
where 1=1
<isNotEmpty prepend="and" property="partNm" >
part_nm like '%' || #partNm# || '%'
</isNotEmpty>
]]>
</select>
but if you want to use the dynamic sql then you have to remove the CDATA. Not sure why the CDATA was there in the first place in appfuse.

<select id="getStockMaintenanceQueryCriterias" resultMap="stockMaintenanceQueryCriteriaResult">
<!-- Can say also say part_nm like '%$partNm$%', but partNm will need to have escape processing carried out -->
select * from stock_maintenance_query
where 1=1
<isNotEmpty prepend="and" property="partNm" >
part_nm like '%' || #partNm# || '%'
</isNotEmpty>
</select>

There is a good reason for the CDATA - its

3.3.3.1. Escaping XML symbols

Because you are combining SQL and XML in a single document, conflicts can occur. The most common conflict is the greater-than and less-than symbols (><). SQL statements use these symbols as operators, but they are reserved symbols in XML. A simple solution is to escape the SQL statements that uses XML reserved symbols within a CDATA element. Example 3.6 demonstrates this.
Example 3.6. Using CDATA to "escape" SQL code

<statement id="SelectPersonsByAge" parameterClass="int" resultClass="Person">
<![CDATA[
SELECT * FROM PERSON WHERE AGE > #value#
]]>
</statement>

Last Identity value in Derby

ij> create table t1(c1 int generated always as identity, c2 int);
0 rows inserted/updated/deleted
ij> insert into t1(c2) values (8);
1 row inserted/updated/deleted
ij> values IDENTITY_VAL_LOCAL();
1
-------------------------------

(cf. Derby Reference Doc: CREATE TABLE statement and IDENTITY_VAL_LOCAL funtion ).

We actually need to use this form which allows rows to be inserted that include an id already.
CREATE TABLE role
(
id int generated by default as identity,
name varchar(20) NOT NULL,
description varchar(64),
CONSTRAINT role_pkey PRIMARY KEY (id)
);

derby auto generated keys identity autoincrement

ij> create table t1(c1 int generated always as identity, c2 int);
0 rows inserted/updated/deleted
ij> insert into t1(c2) values (8);
1 row inserted/updated/deleted
ij> values IDENTITY_VAL_LOCAL();

Wednesday, November 15, 2006

appfuse displaytag

displaytag http://displaytag.sourceforge.net/11/ gives you sortable pagable tables

the messages can be set either in displaytag.properties (and overriden in displaytag_fr.properties)


or the default values in displaytag.properties can be overridden in each jsp

<display:table name="stockMaintenanceQueryList" cellspacing="0" cellpadding="0" requestURI=""
id="stockMaintenanceQueryList" pagesize="4" class="table" export="true">

<display:setProperty name="basic.msg.empty_list_row">
<tr class="empty"><td colspan="5"><fmt:message key="stockMaintenanceQueryCriteria.noMatch"/></td></tr>
</display:setProperty>

<display:setProperty name="paging.banner.no_items_found" value="no items"/>

note the value of stockMaintenanceQueryCriteria.noMatch can be set in ApplicationResources.properties

appfuse tomcat setup

C:\apps\apache-tomcat-5.5.20\conf\tomcat-users.xml

new bits in red

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager"/>
<user username="tomcat" password="tomcat" roles="tomcat,manager"/>
<user username="role1" password="tomcat" roles="role1"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
</tomcat-users>


In appfuse properties.xml

<!-- Application options that will likely vary between applications -->
<property name="http.port" value="80"/>
<property name="dao.type" value="ibatis"/>
<property name="jsp.precompile" value="false"/>

<!-- Properties for running unit tests with tomcat -->
<property name="tomcat.server" value="localhost"/>
<property name="tomcat.manager.url" value="http://${tomcat.server}:${http.port}/manager"/>
<property name="tomcat.username" value="tomcat"/>
<property name="tomcat.password" value="tomcat"/>

todo

  • search labels on top
  • merge user and app_user

unit and web tests
manager classes overkill
dojo - anjuta integration
eclipse setup (laurent)
selenium!


understanding different ways of specifying values in jsp/webwork
list="#application.availableRoles"
value="%{boat.name}"

derby boolean/smallint

Tuesday, November 14, 2006

appfuse disable hibernate in build

As i'm usng appgen still, I can't uninstall hibernate yet (as appgen requires it), but I think i can disable the hibernatedoclet task in the main build.

I'm doing this because I started getting xdoclet.XDocletException on the hibernate generation, which, I think that we don't care about. This happened because I removed the dummyId primary key field from StockMaintenanceQueryCriteria and I think that hibernate must have a primary key. (But this is not a real table).

This is one way of stopping the build doing the hibernate generation.
<!-- tim replaced depends="hibernatedoclet" with depends="prepare" -->
<target name="compile-dao" depends="prepare" description="Compile dao module">
<compile module="dao"/>
</target>

but actually i fixed it by removing all the hibernate comments from StockMaintenanceQueryCriteria.java

Monday, November 13, 2006

appfuse webwork tags classes and themes???

<ww:checkbox name="stockMaintenanceQueryCriteria.stockAlert" id="stockMaintenanceQueryCriteria.stockAlert" value="%{stockMaintenanceQueryCriteria.stockAlert}" fieldValue="true" theme="simple"/>
<label for="stockMaintenanceQueryCriteria.stockAlert" class="choice"><fmt:message key="stockMaintenanceQueryCriteria.stockAlert"/></label>

Thursday, November 09, 2006

appfuse appgen tips creating a seach by criteria screen

create search fields screen using appgen on a dummy table and use the generated "add" functionality to capture the fields.

0. Hot tip for using appgen - go into middlegen first and do an "ant clean" otherwise your pojos will get overwritten.

1. appgen needs a primmary key to generate properly which is why dummy_id is defined in the table create below

2. appgen does not like postgres domains (user defined types) and will not generate some of the files properly if there is a single column with a domain type.

3. Unless you have at least one NOT NULL column in your table, then the MyTable-validation.xml is not a legal webwork validation file.

4. If using appgen on a postgres table with "boolean" columns, the generate MyTable class needs to have all occurrences of "Boolean" replaced by "boolean". Otherwise you get a very confusing error when webwork validates: The content of element type "validators" is incomplete, it must match (field|validator)+"



drop table stock_maintenance_query_criteria;

select
p.part_id as dummy_id,
f.fleet_id, vt.type_id, v.vessel_id,
ec.class_cd, e.equipment_nm,
p.part_nm,
c.company_id as maker_company_id, p.maker_ref,
c.company_id as supplier_company_id, sp.supplier_ref,
l.zone_id, l.location_id, true as stock_alert,
p.drawing_ref
into stock_maintenance_query_criteria
from
fleets f,
vessels_types vt,
vessels v,
vessels_in_fleets vf,
equipments_classes ec,
equipments e,
companies c,
parts p,
suppliers_for_parts sp,
locations l
where 1=1
and f.fleet_id = -1
and vt.type_id = -1
and v.vessel_id = -1
and vf.vessel_id = -1
and ec.class_cd = -1
and e.equipment_id = -1
and c.company_id = -1
and p.part_id = -1
and sp.part_id = -1
and l.location_id = -1;

alter table stock_maintenance_query_criteria add CONSTRAINT pk PRIMARY KEY (dummy_id);

postgress unicode and latin-1 - Moral use unicode !

http://archives.postgresql.org/pgsql-jdbc/2004-11/msg00075.php

1. Create the database with the proper encoding.
In our experience, the best thing to do is simply choose Unicode as the database's character encoding if you think there's a chance of storing Latin1 or other characters. You could choose Latin1, and this should work in most cases. However, there are times when normal-looking characters refuse to be stored in a Latin1 database, such as character 239, which is the same in Latin1 as it is is Utf-8. Rather than attempt to beat our heads against this wall, we went with Unicode because it will hold whatever we need to hold.

Wednesday, November 08, 2006

appfuse webwork drop down

for struts dropdown see
http://raibledesigns.com/wiki/Wiki.jsp?page=HibernateRelationshipsUI#ref-HibernateRelationshipsUI-7

for webwork drop down see:
http://www.nabble.com/Using-ww%3Aselect-for-Lists-set-in-StartupListener-tf2198175s2369.html#a6084253
http://www.nabble.com/webwork-type-conversion-question-tf2352778s2369.html#a6552629

See LookupManager beans, initialized in StartupListener#setupContext()

context.setAttribute(Constants.AVAILABLE_ROLES, mgr.getAllRoles());

Had this in boatForm.jsp to test drop downs
<ww:select
label="getText('boat.name')"
name="'boat.name'"
id="boat.name"
list="#application.availableRoles"
value="%{boat.name}"
required="true"
listKey="value"
listValue="label"
emptyOption="true"/>

appfuse sample data

rebuild your sample-data.xml file using ant db-export and then cp db-export.xml metadata/sql/sample-data.xml.

Labels:

Tuesday, November 07, 2006

appfuse 1.9.4 p6spy integration

1. Download p6spy (google it!)

2. Put the unaltered spy.properties in C:\apps\myappfuseapp\web\WEB-INF\classes
update the logfile entry to point to somewhere sensible: for example
logfile = C:/spy.log

3. put the p6spy.jar in C:\apps\apache-tomcat-5.5.20\common\lib
(may not be the best place but it works)

4. Find applicationContext-resources.xml and change (blog rules mean I have to put a space after every less than sign otherwise the xml will not display on the blog entry)
Change
bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
to read
bean id="dataSourceTarget" class="org.apache.commons.dbcp.BasicDataSource"


5. Add the following bean defintion
{bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource"
{destroy-method="close">
{constructor-arg>
{ref local="dataSourceTarget">
{/constructor-arg>
{/bean>


Please note that I can't put the xml tags properly in this blog, otherwise it will not display properly. So I have used { in stead of a less than sign - Grrrrr!


Labels:

postgres primary key generation and fetch

CREATE TABLE boat
(
id serial NOT NULL,
name varchar(40) NOT NULL,
built timestamp NOT NULL,
CONSTRAINT id PRIMARY KEY (id)
)
WITHOUT OIDS;

insert into boat (name,built) values ( 'bigboat', '1965-08-11' );
-- get the generated key back
select currval(pg_get_serial_sequence('boat', 'id'));
-- or better still
select lastval();

apache-tomcat-5.5.20 appfuse

tomcat-users.xml


< ?xml version='1.0' encoding='utf-8'?>
< tomcat-users>
< role rolename="tomcat"/>
< role rolename="role1"/>
< user username="tomcat" password="tomcat" roles="tomcat"/>
< user username="both" password="tomcat" roles="tomcat,role1"/>
< user username="role1" password="tomcat" roles="role1"/>
< /tomcat-users>

Thursday, November 02, 2006

Appfuse and DWR quickstart

Appfuse 1.9.4 already has dwr included:

web.xml is already configured (sear for dwr to see where)

edit dwr.xml and uncomment the commented out xml and restart tomcat:

go to http://localhost:8080/myapp/dwr/ which is a sort of "see whats available" list of the dwr javascript proxies to java objjects.