WEB4J Version History
web4j.jar version 3.8.0 (Published - June 7, 2008)
Small update (backwards compatible) :
- TroubleTicket - add alternate constructor for specifying custom content for the email body.
- PerformanceMonitor - add periodic 'ping' of a fixed URL, and
send a TroubleTicket if a problem is detected. This feature is available only for
the Full Version of web4j.jar.
- Controller - fix NullPointerException thrown when Controller is
initialized outside of normal runtime environment (that is, when testing outside the container).
- Log Viewer (Full Version Only) - fix error for viewing Parsed Logs. Last record was missing.
This update is mostly about improving support for typical unit testing, by providing a
number of test doubles. The test doubles aren't provided as part of web4j.jar, but
rather as source code in the example application. They are provided as
source code since they are usually incomplete, and may need to be edited occasionally.
(They are incomplete since some methods, typically not needed for unit testing,
are left unimplemented.)
For more information on unit testing, please see the User Guide.
web4j.jar version 3.7.0 (Published - May 12, 2008)
Small update (backwards compatible) :
- allow serving binary content under the main Controller.
Add ResponsePage.withBinaryData() factory method.
For such ResponsePages, the Controller will not perform a forward or redirect.
Instead, the Action is responsible for serving the response.
- in web.xml, the default value for the CharacterEncoding setting has been changed to UTF-8 (from ISO-88591-1).
(Technically, this isn't backwards compatible. In practice, it's very likely that all of your apps have this item set in web.xml, such that its default value is almost never used in the first place.)
- change PerformanceMonitor to insert blank PerformanceSnapshots to explicitly indicate periods with no activity.
(This provides a way of detecting problems with Apache connections. For example, if Apache connections are being hogged by some process, then
your app will show a 'black hole' of inactivity, even though your app is functioning correctly.)
web4j.jar version 3.6.1 (Published - April 8, 2008)
Minor bug fixes (all backwards compatible) :
- Controller - correct logging of request parameter names and values
- ModelFromRequest - correction to javadoc
- internal, unpublished class used for Model Object construction now emits improved error message
web4j.jar version 3.6.0 (Published - March 11, 2008)
A single change is not backwards compatible (sorry) :
- RequestParserImpl -
The URI Mapping String no longer includes the .do (or whatever) extension at the end.
Implicit mappings are not affected by this change.
Any actions that use explicit mappings, however, need to remove the extension.
Since explicit mappings are relatively rare, this change should not cause excessive pain.
This change was needed to implement fine-grained security constraints (see below).
(In retrospect, including the .do extension in the first place was a design error - it violated the Don't Repeat Yourself rule.)
As well, the related setting ImplicitMappingAddSuffix has been removed from web.xml.
All other changes are backwards compatible :
- WEB4J now handles file upload forms more naturally.
To implement file upload, a third party tool must still be used to parse the underlying request. In this way, WEB4J itself avoids unnecessary dependencies on third party tools.
See Fish & Chips Club for an example using the Apache Commons FileUpload tool.
- The behavior of ApplicationFirewallImpl has been extended, and its javadoc has been clarified.
It now uses a new setting in web.xml called FullyValidateFileUploads.
- Fine-grained security using extensions such as .list and .add is now supported.
- ActionImpl.getOperation() has been added.
It returns the operation, extracted in one of two ways: first from a request parameter, and second from the extension used in the URL.
- Operation.valueOf(String) is no longer case-sensitive.
- a new field called 'Do' has been added to Operation.
- EscapeChars.forReplacementString(String) has been added.
- Fix : EscapeChars.forReplacementString(String) is now used in
CsrfFilter, AppResponseMessages, Tooltips, TextFlow, Pager, and HighlightCurrentPage.
web4j.jar version 3.5.0 (Published - February 16, 2008)
Two changes are not backwards compatible. Both are related to startup operations :
- StartupTasks - this interface
now has only a single method startApplication(ServletConfig), taking
a single parameter.
- ConnectionSource - this
interface has an additional method called init(ServletConfig).
In effect, any ConnectionSource initialization tasks have been moved directly into
ConnectionSource itself.
All other items are backwards compatible :
- Controller logging - session scope items are now logged at FINEST.
Sometimes large lists of items are held in session.
- Controller validation - upon startup, the Controller will scan for public Model Objects having
public getXXX methods that return a String instead of SafeText.
- Stopwatch - the stopwatch value can now be examined without having to
stop the stopwatch.
There is now a distinction between the behavior of the trial version of web4j.jar and the
full version of web4j.jar. These distinctions are minor, and affect only the execution
of the following startup validations :
- one-to-one matching of identifiers in .sql files to public static final SqlId fields
- scanning for possible Cross-Site Scripting vulnerabilities in Model Objects
web4j.jar version 3.4.0 (Published - January 22, 2008)
The sorting mechanism has been changed (and the changes are not backwards compatible).
the <w:sort> tag has been removed, for these reasons :
- sorting items is more of a programming task, than a presentation task
- the most natural tool available for sorting items is the ORDER BY clause in an SQL statement
- the DynamicCriteria class already exists, and is capable of implementing sorting
- the implementation of <w:sort> was defective
The <w:sort> tag might have been fixed, but given the other issues, it was
decided to drop it entirely, in favor of a more satisfying mechanism, implemented in code instead
of the JSP.
Changes include :
- the name of the class SearchCriteria has been changed to DynamicCriteria, to
more accurately reflect its use outside of search operations.
- DynamicCriteria now allows the WHERE clause to be optional.
This corresponds to the common case of adding sorting criteria to an arbitrary SELECT statement,
which does not necessarily have a WHERE clause.
- all methods of the Report class have been changed to accept an additional
DynamicCriteria parameter. Given that sorting columns is
so beneficial, it is likely best to treat 'sortability' as the preferred, default case.
If no sorting is desired, it is recommeneded that DynamicCriteria.NONE be used to indicate that fact.
- ActionImpl has a new method called getOrderBy().
web4j.jar version 3.3.1 (Published - January 15, 2008)
All changes are backwards compatible :
- Added - case of not using a database at all. To indicate no database is in use, the application's
implementation of ConnectionSource.getDatabaseNames() should just return an empty set.
- Added - the Operation class now has a valueFor(String) method. It is similar to valueOf(String),
but has different behavior for empty and unknown values, useful for Action constructors.
- Added - If a request parameter value is invalid, then ApplicationFirewallImpl
will log the occurence at SEVERE level in addition to throwing a BadRequestException.
- Fixed - the scope of the Check constructor was changed from private to protected.
The private scope was preventing the creation of subclasses, and thus preventing one style of implementing custom validations.
- Fixed - the behavior of ActionTemplateShowAndApply was not quite right when an error occured
during the Apply operation. Instead of doing a 're-show', it is better to populate the form with the data which caused
the errors in the first place, instead of showing the 'original' data.
- Fixed - The javadoc for Populate had an error in its example getXXX methods
web4j.jar version 3.3.0 (Published - December 19, 2007)
Changed (not backwards compatible - sorry) :
- Fixed StartupTasks - this interface should have been separated into two methods, one for extracting config from web.xml, the other for doing the startup task.
To fix existing implementations, you will need to split the old implementation into two parts : one which reads the config params (if any), and one which actually performs the startup task.
Added/Changed (backwards compatible) :
- Controller - now attempts recovery when one or more databases are down upon startup.
- Controller - destroy method now logs the application name and version. This will aid in determining when the application was shut down.
- Check - add Check.range(min, max) methods. This is a nice, simple, addition, which makes Model Object validation code noticeably more legible.
- Util.textHasContent() is now overloaded to accept SafeText as well as String.
- ConvertParamImpl and ConvertColumnImpl extended to include int.class, as well as Integer.class (and so on, for various primitive types).
- LoggingConfigImpl will now attempt to create the logging directory if it doesn't already exist.
- Code constructor will now accept null for Id. Needed for 'add' operations.
- Code is now Serializable
web4j.jar version 3.2.0 (Published - November 15, 2007)
Added :
Response Headers - the Controller now sets the charset HTTP
header for every response, according to the existing CharacterEncoding
setting in web.xml. Thus, JSPs no longer need to repeatedly set
this header. If desired, you may override in a JSP by using the
page directive.
web4j.jar version 3.1.0 (Published - October 27, 2007)
Tools for building more secure web apps, and other items.
Only two new classes have been added.
Added :
- Add SafeText as new building block class.
Provides excellent protection against XSS attacks, by automatically
escaping for special characters in its toString() method.
- Add CsrfFilter for defense against CSRF attacks.
Warning - there is a bug related to this filter, and all filters that
use a response wrapper: the error page mechanism does not work as expected for wrapped responses.
That is, when an error occurs, the server's default, generic error page is shown, and not the error
page you have configured in web.xml.
- SqlId - add fromStringId(String) factory method,
to build SqlId from text which may or may not be qualified by the database name.
- EscapeChars - add new method forXML(String)
- Operation - add new method hasSideEffects()
Fixed :
WEB4J source did not compile/run under JDK 6! (Sorry about that. A single call to Class.getConstructors() failed.
This call generated only a warning under JDK 5. WEB4J source now compiles/runs under both JDK 5 and JDK 6.)
This failure was apparently an instance of the following (taken from JDK 6 docs) :
"The cast implementation adheres more closely to the Java Language Specification. In general, this means
that javac will accept more programs. However, in some rare cases, javac can now reject previously accepted,
yet incorrect programs." - see link (point 5).
- EscapeChars.forHTML() now extended to 12 chars, to match recommendations of OWASP.
- Report class - 'raw' and formatted cases now returns not String, but SafeText as the column value.
Caller can decide how to escape, by using default SafeText.toString(), or other method.
- ConvertColumnImpl had inadequate javadoc.
- Id class - implementation of Comparable should have been JDK 5 version.
- Operation.isDatastoreEdit() should have included the DeleteAll Operation.
- Populate tag javadoc - should have mentioned the escaping done for input type='text' tags.
- Populate tag - 'recycle params' mode will now coerce null param/param values to the empty String.
(Needed to allow delete operations to be a POST instead of a link.)
Changed (backwards compatible) :
- Check.min() and Check.max() extended to include SafeText.
- ConvertParamImpl extended to include SafeText.
- Db extended to include SafeText.
- Formats.objectToText() extended for SafeText.
- ApplicationFirewallImpl - extended to perform security checks agains CSRF attacks.
- AppResponseMessage - will do some escaping. Will escape parameters only (except if it is already SafeText).
Doesn't escape base pattern text, only parameters.
- ApplicationFirewallImpl - increased security. If an Operation param is present and
Operation.hasSideEffects() is true, then the underlying request must be a POST.
Changed (not backwards compatible - sorry) :
- Four items moved to the new hirondelle.web4j.security package: ApplicationFirewall, SpamDetector, and
their respective default implementations. (Sorry about this change. Best for the long-term health of the
tool, since security is such an important issue.)
- EscapeChars - method name changed from forHTMLTextFlow() to forHTML(), since not accurate:
applicable to more than regular text flow.
- Text tag - wiki formatting was using '-' for special formatting (bullets and horizontal bars).
That was interfering with escaping, since '-' is a special character. Change to use '~' for both bullets and horizontal bars.
- Formats.objectToTextForReport() now returns SafeText, not String.
This broke some items in Fish and Chips, where private methods in Report Actions returning
'List<Map<String, String>>'
needed a change to
'List<Map<String, SafeText>>'.
- ActionImpl.getLoggedInUserName() now returns SafeText instead of String, since user name
is so often displayed in the view.
web4j.jar version 3.0.0 (Published - September 8, 2007)
Very large number of changes, deletions, and additions. (Unfortunately, there are too many to list here.)
The overall number of classes has actually decreased slightly.
The tool has been improved substantially, and is now both more elegant and robust.
Some highlights include :
- now requires JDK 1.5
- package-by-feature : all items related to a feature can live in the same directory - code, JSPs, .sql files
- automated mapping of URI to Action
- better Action templates
- configuration-by-reflection : the RequestParamters allowed for each Action are found by reflection
- excellent services for multilingual apps. Apps can assist in their own translation.
- removed onerous requirements on thread-safety
- simpler implementation of equals, hashCode
- SpamDetector, ApplicationFirewall
- many others...
web4j.jar version 2.3.0 (Published - November 11, 2006)
Items not backwards-compatible with version 2.2.0 :
- Change parsing of decimal numbers to no longer use DecimalFormat. See
web.xml in the example application for more information.
- Change parsing and formatting of dates. Instead of using SimpleDateFormat and
settings in web.xml, the
DateConverter interface has been added.
It allows the application programmer to explicitly define how Dates are parsed and formatted.
- Change ConnectionSource by adding a second method, to allow more than
one database to be used by an application.
All other items are backwards-compatible with version 2.2.0 :
- Add Validator and
Check to help Model Objects implement validation.
In the example app, include a subclass of Check, and change Model Objects to
use this validation mechanism. (This is a nice addition. It makes Model Object implementations significantly more legible.)
- Add the Tooltip tag to translate all TITLE and ALT attributes.
This tag is placed in a template, and can translate all TITLE and ALT attributes served in the body of the template.
- Add the TextFlow tag to implement bulk translation of
all regular text flow in the tag's body.
- Add Util.removeQuotes and
Util.maxDecimals
- Fix javadoc in RequestParser.
web4j.jar version 2.2.0 (Published - September 9, 2006)
Items not backwards-compatible with version 2.1.0 :
- several changes caused by internationalization (see below)
- Change name of PickListValue to
PickListItem,
since it often contains more than one value. This change is annoying but desirable. For many people,
the word "value" conventionally means a single, simple value such as a Date or an Integer.
- Change output of
Util's various logOnePerLine methods
WEB4J now has good support for multilingual applications. WEB4J generates user-visible output in these ways :
showing response messages (AppResponseMessage),
viewing ResultSets (ReportBuilder),
showing dates (ShowDate),
and prepopulating forms (Prepopulate).
All of these areas have been affected (some of the changes are unfortunately not backwards compatible).
Here is a summary of the changes :
- Add LocaleSource
to allow programmer to define how Locale is to be deduced for a given request.
Add LocaleSourceImpl as a simle default
implementation, which simply uses a single Locale specified in web.xml.
- Add ConversionError
to allow programmer to define error messages for low level parsing problems,
such as translating text into an Integer.
- Add a getLocale method to WebActionImpl,
such that any WebAction can get quick access to the Locale returned by
LocaleSource
- Change Formats methods to be instance methods, not static ones.
Pass a Locale to its constructor, instead of relying on a configuration item passed to its static init method.
LocaleSource will be the source of the Locale passed to the constructor.
- Change ReportBuilder - delete the ApplyFormats
type-safe enumeration, and replace it by passing a Formats
object directly. If the object is null, then no formatting is applied.
- Change signature of
AppResponseMessage.forCompound
- Delete the Web4jResource ResourceBundle mechanism, since now obsoleted by
ConversionError
All other changes are backwards-compatible with version 2.1.0 :
- Add a "test" precompile of SQL statements upon startup. The principal benefit is
finding errors more effectively : a possibly-rare runtime error is changed into a
much more obvious "startup-time" error.
This is a very nice feature, but JDBC does not require implementations to precompile
SQL statements during calls to Connection.prepareStatement(String). In the example application,
precompilation works for MySQL and JavaDB, but not for Oracle.
- Add Id class as a new kind of
'base' object. This allows Model Objects to read at a slightly higher level, since the
identifier - always of central importance in a Model Object - is clearly distinguished from
all other items.
The example application has been refactored to use this class for its identifiers.
The parsing of requests and ResultSets has been extended to include Id.
- Add new verbs to the Operation enumeration.
Add an
isDatastoreEdit
method, to identify operations which edit the database.
Update docs for related class
WebActionTemplateB.
- Add a new interface/implementation pair for the conversion of ResultSet
columns into 'base' objects :
ColumnToObject, and
ColumnToObjectImpl.
In the example application's config package, ColToObject is the name
assigned to the configured class. The application programmer can now override default behavior
for this translation, if desired.
- Add more flexibility to the
RequestParser,
to allow binary data to be
posted as well. The Servlet API is still disturbingly primitive at handling file uploads.
WEB4J now has minimal support for file uploads : such data can be posted, but
no direct assistance is provided for examining the file length, MIME type, and
so on. (Instead, some other tool must be used. The example application uses the
Jakarta FileUpload tool, but other tools exist as well.)
New files added to example application : UploadFile.jsp, UploadFile.java.
New item added to web.xml : MaxFileUploadRequestSize.
Changes to
RequestParameter and
RequestParser were made as well.
Note : prepopulation of file upload controls is not implemented. It does not seem
to make sense, since popular browsers do not render the value attribute for such controls.
- Add JavaDB as third database option for the example application.
This port is about 95% functional. It is not 100% functional since a couple of items
need actual code modifications in a Data Access Object, and not simple translation of SQL statements.
(The cause was JavaDB's minimal set of built-in functions.)
Such code modifications are "left as an exercise to the reader". This partial porting to
JavaDB is unfortunate - but a 95%-complete port is better than no port at all.
- Add the convenience method getRequest to
CommonBodyTag
and CommonEmptyTag.
- Delete from the example application all items related to the Admin screen, since they do not offer any real value.
Remove myadmin directory : Admin.jsp, Login.html, and Error.html
Remove related entries in web.xml as well: security-constraint, login-config, and
security-role. (This deletion does not break backwards-compatibility, since it was part of the
example application, not of WEB4J itself.)
- Change controls names from coder keys (emailAddr) to user-friendly style (Email Address). This allows
error messages regarding from input to reuse the control name directly, instead of requiring continual,
trivial translation from a coder key into user-friendly text
- Fix :
SqlStatement items increased to public
scope, to render their javadoc visible to the programmer. Although these items are not called directly
by the programmer, they should still be visible. (Silly error - my apologies).
- Fix : Bug in Pager.
'Missing' links should have been empty Strings, not null. Bug present since version 2.0.0 (Feb 2006).
- Fix : Bug in TroubleTicket.
Did not properly parse the web.xml setting (dumb). Bug present since version 2.1.0 (?).
web4j version 2.1.0 (Published - March 26, 2006)
One item in 2.1.0 is not backwards-compatible with version 2.0.0 :
-
Change to using CDATA in the web.xml entries for formatting boolean items
in reports. (The previous style erroneously forced the programmer to drop
any special < and > characters, instead of using the standard CDATA
escape mechanism for xml files.)
All other changes are backwards-compatible with version 2.0.0 :
-
Change the mechanism for finding .sql files upon startup, to allow
.sql
files to appear anywhere under WEB-INF, instead of only in WEB-INF
itself. This allows .sql files to appear immediately beside classes
which use them. This makes features more modular, by allowing items related
to a single feature to appear in a single location. This change is reflected
by ConfigReader.
Both styles are illustrated in the example application. For the MySQL version,
the .sql files are located beside their related classes. In addition,
two "disabled" .SQL files, for both MySQL and Oracle, are provided
in the WEB-INF directory. (As before, a .SQL file is
enabled by altering its extension to .sql - lower case.)
-
Change all web4j init-params in web.xml to have default values
if not present. (Not included in this mechanism are webmaster email address
and mail server, which are context parameters, not init-params.)
The reason for this is to allow portions of web4j to be used without requiring
large amounts of undesired configuration. For example, the web4j data layer
services might be used to implement an application's data layer, while
some other tool may be used for other parts of the application. Items can
be included only if needed, and only if its value differs from the default.
(The default values are documented in the web.xml of the example application.)
-
Add a new interface/implementation pair called ConnectionSource
and ConnectionSrc,
to give the application programmer complete control over how an application
creates or accesses Connections. (The example implementation's ConnectionSrc
has the same policy as in all previous versions - accessing a Datasource
using JNDI.)
-
Add a web.xml setting for character encoding. This item is used in the
Controller.
In addtion, it is also made accessible as an application scope item named
web4j_character_encoding, which may be easily referenced in an
application's template JSPs, to set the desired encoding.
-
Add a second version number. Previously, one was defined in AppInfo
for the example application. Now, the name and version of the web4j.jar
itself is also compiled into the Controller. (Both items are logged
upon startup.)
-
Add Util.logOnePerLine for both Collections and Maps. These
Util
methods are used to eliminate long lines when logging. It simply places
each item in a Collection/Map on its own line. This simple technique makes
some log entries much more legible, since horizontal scrolling is usually
eliminated.
-
Fix javadoc by generating with -protected instead of -public.
This will add a few items which should have been visible, but were not.
In particular, this affected items in the hirondelle.web4j.ui.tag
package.
web4j.jar version 2.0.0 (Published - February 18, 2006)
-
Large changes to how code is arranged, plus a few new fixes and features.
-
Split old code base into web4j.jar plus an example application.
-
Discard the 'MyXXX' naming convention. This corresponds to the separation
into web4j.jar and the example application.
-
Add InterfaceToObject
as a plug-in mechanism, used with various new interfaces used to control
the behavior of web4j.
-
Add hirondelle.web4j.config
package.
-
Add interface ApplicationInfo,
with AppInfo
example implementation.
-
Add interface ParameterNameToText,
with ParameterNameToTextImpl
as example implementation.
-
Add interface RequestParameterEnumeration,
with ReqParam
as example implementation.
-
Add interface SqlIdEnumeration,
with SQL
as example implementation.
-
Add interface StartupTasks,
with Startup
as example implementation.
-
Add Web4jResources.
-
Add Web4jBean, for "reserved"
names of objects used by web4j.
-
Add AppResponseMessage.
-
Add two new elements to Operation
- List and ListForChange.
-
Add line number to all reports.
-
Add an alternative paging mechanism - Pager
and PagerLink - which
can be added to any existing JSP without code changes to the WebAction
or DAO
-
Move asList utility methods for building Lists to Util.
-
Remove some unused import statements, etc.
-
Change NumDaysOfRecentHistory setting in web.xml, for PerformanceMonitor,
to actual number of items stored
-
Move the 51200 max request size into web.xml, as configured item.
-
Changed names : AbstractRequestParser to RequestParser,
MyBean to Bean,
DestinationPage to ResponsePage,
MyActionEnsureLogin to ForceLogin,
SqlReader to ConfigReader,
MyWebActionMapping to RequestToWebAction,
Sql to SqlStatement.
-
Change the PerformanceMonitor links to tooltips. Reason: underlying request
might actually be a GET which edits the database (common error), or may
be a POST. For POST, the POSTed data is absent from the presented URL.
-
Change the Controller to
allow limited subclassing.
-
BUG : ConcurrentModificationException with PerformanceMonitor. Change the
synchronization of PerformanceMonitor to use lock on the collection, return
a synchronized version to the caller, and add a synchronized block around
the JSTL snippet which iterates over it.
web4j.jar version 1.9.0 (Published - November 12, 2005)
-
Add PerformanceMonitor
filter. Add PerformanceSnapshot,
MyActionShowPerformanceReport, and PerformanceMonitor.jsp. (Here is the
page in the example
deployment.)
-
Add TxIsolationLevel,
and allow changes to transaction isolation level. Edit web.xml, DbConfig,
SqlEditor, SqlFetcher, TxTemplate, DbConnection, MyReportDAO, MyUserDAO.
Configure default transaction isolation level for SqlEditor and SqlFetcher
in web.xml.
-
Add AbstractResponseFilter
-
Add Trim filter as alternative
implementation to custom tag which does the same thing
-
Add CommonEmptyTag,
as base class for common style of custom tag Add ShowDate
as concrete impl
-
Add CommonBodyTag,
as base class for another common style of custom tag. Refactor most tags
to use it as ABC
-
Add Trim tag for removal
initial whitespace from markup
-
Add Util.getLogger
to centralize policy for logger names, and change all Logger users to call
it.
-
Add Util.quote,
and use it where string data is logged.
-
Change the text file containing SQL statements from a properties file to
a .sql file, with a much improved style. No more line continuation characters
are needed. In addition, simple substitution variables can be used to avoid
repetition, both of magic numbers and of sub-queries. For details on the
file format, see Sql, and
the example .sql files themselves.
-
Change - rename WebInfProperties to ConfigReader.
Allow ConfigReader to read in .sql files, in addition to .properties files.
Add SqlReader.
-
Change - rename some important abstract base classes, to clarify and simplify
the names. AbstractLocalTx -> TxTemplate
, MyRequestParser -> MyWebActionMapper,
AbstractWebAction
-> WebActionImpl,
AbstractStandardWebAction -> WebActionTemplateA,
AbstractStandardOpsWebAction -> WebActionTemplateB
-
Change - remove AbstractValidatingWebAction. Almost the same as WebActionTemplateA
-
Change - rename ModelFromParams to RequestToObject,
since so similar to RowToObject. Clearer, simpler name.
-
Change - treatment of duplicate keys. If detected, translate into a new
kind of exception (DuplicateException,
a subclass of DAOException), instead of returning 0. Forces caller to be
aware of the problem. Allows much cleaner transaction implementation, since
no need to continually check-for-failure. SqlEditor now throws both DAOException
and DuplicateException. Applies to add/change operations only. The asymmetry
between this kind of SQLException and all others has been eliminated, while
still allowing for its special nature.
-
Change - the API of SqlEditor to follow the superior style of SqlFetcher.
-
Change - replace the constructors of SqlFetcher
and SqlEditor with factory
methods, to make much more clear to the reader that a transaction is or
is not involved.
-
Change - remove ad hoc timings from MyPersonDAO, since now handled by PerformanceMonitor.
-
Change - move name/version/author from Consts to Controller, since this
data is not really constant.
-
Change - improve Sql.getPS() - stored procedure branch referred to field
fSqlText, which should have been aSqlText (worked ok anyway, in this case).
-
Change - DbUtil.isSuccess
now returns true only if arg > 0 (instead of only if != 0). This allows
more than one value to denote an error condition. For example, returning
-1 can now be used to indicate an error condition.
-
Bug Fix - Extended Pick Lists. Add/Change of a duplicate does not fail
as expected. Should have been checking the return value of the INSERT operation,
and then asking for rollback
-
Bug Fix - TxTemplate. Should have been catching DAOException, in addition
to SQLException. Important since SqlEditor can only throw a DAOException.
web4j.jar version 1.8.4 (Published - September 4, 2005)
-
improve the look and feel, and use a robust cascading style sheet. Firefox
renders well. Internet Explorer 6 renders less well (especially the input
forms), since IE6 does not have robust support for CSS
-
allow multiple sql.properties files to be used, using a simple
naming convention - see Sql
-
change the level of almost all logging statements to conform with a more
typical style - CONFIG for startup, SEVERE for problems, FINE for debugging
-
change two CSS class names to lower case (HIGHLIGHT, ROW_HIGHLIGHT), simply
to match other class names
-
remove AddToppingsEtc.jsp, which was not being used
-
recommend the CSS empty-cells property instead of the ReportEmptyOrNull
workaround present in web.xml
web4j.jar version 1.8.3 (Published - June 11, 2005)
The main addition to this version is Pick Lists. See MyPickListDAO
for an extended discussion of WEB4J's design for Pick Lists.
Add two items which model Pick Lists :
-
PickListValue.java
-
MyPickListTitle.java
Add two JSPs to allow an administrator to edit Pick Lists :
-
PickListSimple.jsp
-
PickListExtended.jsp
Add corresponding WebActions for such edits :
-
MyActionFetchPickList.java
-
MyActionEditExtendedPickList.java
-
MyActionEditSimplePickList.java,
Extensive changes to MyPickListDAO.java were needed, along with minor changes
to
-
MyPerson.java
-
ModelFromParams.java
-
AbstractRequestParser.java
-
ConvertColumToObject.java
-
sql.properties and CreateTable statements for Pick Lists
Other items included in this version :
-
Add WebUtil.java. Like Util.java, but specific to web. Move a method from
MyDestinationPage to this class ( the method which added a param to a URL).
Change that method to either append or add. Add TESTWebUtil JUnit class
for it as well.
-
Change the template method of AbstractStandardWebAction.java, to allow
errors to be added during doFailure, if desired, in the same way that success
messages can be added in doSuccess
-
Allow messages to survive a redirect when redirecting to a second WebAction.
Place errors and messages in session only if they have content. Change
AbstractWebAction.java, AppException.java.
-
Add Util.checkNumItemsInTypeSafeEnumeration, for catching common error
related to type safe enumerations
-
Change AbstractLocalTx to follow the style of SqlEditor, by catching duplicate
key errors explicitly
-
Change SqlFetcher.fetchValueObjects to return maps whose keys/values can
be swapped as desired
-
Change ModelCtorUtil.java to allow Model Objects to have multiple public
constructors
-
Add AlternatingRow tag to Report.jsp to improve legibility
-
Bug Fix : CONCAT and the || operator both return null if an argument
is null. Fix needed for Artist names.
-
Bug Fix : Report.jsp. Fix date format for Style 2 of report, from mm/dd/yyyy
to MM/dd/yyyy
-
Bug Fix : ModelFromParams.java was calling AbstractRequestParser.getRawParamValue,
and should have been calling getParamValue. This applies the proper filtering
to raw request param values.
web4j.jar version 1.8.2 (Published - April 23, 2005)
-
Add StoredProcedureTemplate.java to reduce repeated code associated with
CallableStatements. Exercise in MyPersonDAO.java, for updating the
number of neurons for MyPersons.
-
Change Sql.java to allow '{call }' syntax, but treat only as PreparedStatement,
and return either a single ResultSet or a single update count. Reject the
{?= } syntax at load-time, since explicit return values are not supported
by this mechanism (Use StoredProcedureTemplate.java for most use cases
of stored procedures). Reject intersection of {0} style and stored procedures
: if operation is backed by a stored procedure, then the MessageFormat
style is not applicable. Exercise in MyPersonDAO.java.
-
Add DbConfig.java to carry all data related to database configuration,
and to decouple the data layer more effectively from the web server environment.
-
Change ConvertColumnToObject.java to add support for CLOB data.
-
Bug Fix : AbstractWebAction.hasExistingSession() had reversed logic. This
error was introduced in 1.8.0, and caused the logout mechanism to fail.
(Sorry about that.)
-
Re-implement the paging mechanism with ANSI-compliant SQL, without the
LIMIT keyword, which is not portable. Altered SqlFetcher.java by adding
limitRowsToRange. Altered MyMessageDAO.java to exercise the changes.
-
Change the name of "Configured Selection" to the more natural "Pick List".
MySelectionDAO.java => MyPickListDAO.java, with related changes to callers.
Add Oracle 9.2 as a second database example, in addition to MySQL. Provide
CREATE TABLE statements for Oracle, and a second version of the sql.properties
file. As an illustration, the issues encountered during the port were :
-
MyPerson table - 'Name' is an illegal identifier in Oracle, and was
changed to FullName
-
sql.properties - remove trailing semi-colons from all statements (done
for MySql as well)
-
sql.properties - Report queries - 'AS' aliases need to be quoted identifiers,
to avoid being converted to upper case by Oracle.
-
sql.properties - replace some functions FORMAT -> TO_CHAR, DATEFORMAT
-> TO_DATE, IF -> CASE (done for MySql as well), CONCAT (x,y,z) ->
||
-
sql.properties - LIMIT is not an Oracle (or ANSI) keyword
-
Oracle has no autoincrement feature - use sequence.nextval for some INSERTS
-
Sql.java - autogenerated keys are now indicated by a web.xml setting
-
SqlEditor.java - the error code for duplicate key is now in web.xml
web4j.jar version 1.8.1 (Published - March 5, 2005)
-
Change the Data Access Object implementations to forgo the use of interfaces
altogether, in favor of simple concrete classes. This is much closer to
the style needed by the typical application, which only supports one database
at a time. (Remove all DAO interfaces, and MyDAOFactory.java. Change the
name of all MyXXXDAOSql classes to MyXXXDAO.)
-
Model classes are now permitted to have a no-argument constructor. Such
constructors are not used in web4j, but are now silently ignored, instead
of causing an exception. (Change ModelBuilder.java, ModelFromParams.java,
and MyPerson.java.)
-
Add ModelCtorUtil.java to eliminate code repetition.
-
In all JSPs, simplify the names of the custom tags from 'web4j' to 'w',
using the standard tag prefixing mechanism.
web4j.jar version 1.8.0 (Published - Feb 5, 2005)
-
Add support for SqlEditor with no params. Edit sql.properties, SqlId, SqlEditor
gets new constructor. EditPerson.jsp gets new button, MyRequestParser.java
gets new branch. Add MyActionUpdateNumNeurons. Add updateNumNeurons method
to DAO interface and corresponding implementation.
-
Update the db driver in the example deployment from version 3.0.8 to version
3.0.16.
-
Add config of max rows, as safeguard against retrieving too many rows.
Add config of fetch size as well. Edit: web.xml, Sql.java
-
Improve class and method names, to use simpler, more natural language :
SelectorEditor -> FormPopulator, VOParserMatchOrder -> ModelBuilder,
SimpleVOParser -> ValueBuilder, VOException -> ModelCtorException,
VOFromParams -> ModelFromParams, AbstractVOParser -> RowToObject, SqlFetcher.fetchModelObject(s)
-> fetchObject(s). Now follows Martin Fowler's advice, and the term Value
Object has been replaced with Model Object.
-
Add ReportBuilder, a tool for quickly building reports, and exercise in
an example report. Add Report.jsp, MyReportDAO, MyReportDAOSql, ActionShowReport,
Formats.objectToTextForReport added. web.xml has new settings settings
as well
-
Add mechanism to save messages across a redirect. Add MessageList.java,
MessageListImpl.java. Edit DisplayErrors.jsp (rename DisplayMessages.jsp,
and move to Template.jsp), MyActionEditPerson.java, AppException.java,
AbstractStandardWebAction (no more returnToSender, different template adds
messages). AbstractWebAction has more liberal creation of sessions, in
part to allow messages to survive redirects.
-
Refactor WebAction ABC's. At the top are all final methods, while the abstract
subclasses are 'pure template'. Some changes to the templates themselves,
to accomodate the addition of messages.
-
Upon failure to load sql.properties, add message regarding line continuation
characters.
-
Allow SqlFetcher to use a shared connection, in a transaction. AbstractLocalTx
executeMultipleSqls can now throw DAOException as well as SQLException
as well.
-
Bug Fix : for ToStringUtil for factory methods which return objects of
the native class.
-
Bug Fix : MyActionDeleteUser.java must fetch Login Name from session
-
Bug Fix : Browse.do ServletError: if on page two, and page size is increased,
then '2 not in range 1..1'. Cause : HIDDEN item formerly constant, was
being dynamically pre-populated (since 1.7.0). Simple Fix : wrap only part
of the form, not its entirety, in the web4j:prePopulate tag. Edit Browse.jsp,
add comment to Prepopulate.java regarding partial forms.
web4j.jar version 1.7.3 (Published - Dec 29,2004)
-
Template.jsp : added charset to head tag
-
bug fix : hidden form item in Browse.jsp should be outside the prepopulate
tag, since it needs a fixed, constant value.
-
bug fix : UpdateToppingsEtc.jsp was not rendering BigDecimals correctly
web4j.jar version 1.7.2 (Published - Dec 26, 2004)
-
Add method addQueryParam to MyDestinationPage.java. Allows dynamic addition
of any number of query parameters to a destination URL, with proper escaping
of special characters. Demo in MyActionChangeAccount.java, with redirect
to view of user's most recent messages. This was needed since it is the
only way to pass data to a redirect URL.
-
Add Float and Long to list of supported types. Exercise with new items
related to MyPerson.java. Edits to VOFromParams.java, AbstractRequestParser.java,
Sql.java, and VOParserMatchOrder.java. (No simple way to add support for
primitives, since primitives do not model nullable columns well.)
-
Add SimpleVOParser.java, to collect simple, common implementations of AbstractVOParser.
Exercise SimpleVOParser.java in MyPersonDAOSql.java, and display result
using EditPerson.jsp and MyActionEditPerson.java.
-
Add ConvertColumnToObject.java, to centralize policies for translation
of ResultSet columns into supported objects.
-
Add Stopwatch timings to MyPersonDAOSql.java, to help evaluate typical
response times.
-
Add new config item: number of seconds which denotes a problematic delay
in processing. Using a Stopwatch, the Controller detects when the response
time has exceeded this configured limit, and emails the Webmaster with
a message stating how much time it has taken. The messages are throttled.
-
Change ToStringUtil.java to use all public no-argument methods with a return
value, instead of only getXXX methods
-
Remove the prepop of the search box item in EditPerson.jsp.
-
Create javadoc using JDK 1.5.
web4j.jar version 1.7.1 (Published - Nov 8, 2004)
-
add EscapeChars.toDisableTags to escape only the start-of-tag and end-of-tag
characters. Use in MyMessage.java to correct bug in presentation of messages.
web4j.jar version 1.7.0 (Published - Nov 7, 2004)
-
Add prepopulation support for two new controls : HIDDEN tags and TEXTAREA
tags
-
Add AbstractStandardWebAction, to explicitly capture two species of failure,
instead of one : invalid user input (common), and db failures due mostly
to multi-user nature (rather rare). Refactor most WebActions to use it
instead of AbstractValidatingWebAction
-
add Operation.java, to enumerate common datastore operations
-
Add AbstractStandardOpsWebAction.java, for case where common fetch, add,
change, and delete operations are handled by a single class
-
All database operations have been made "as atomic as possible". Check-for-existence
was code has been entirely removed, since it is not robust in a multi-user
environment. This resulted in a large number of small edits, both to DAOs
and the WebActions which use them.
-
SqlFetcher.java now returns null if no record is found, not SqlFetcher.NO_RECORDS
-
Add MyPerson.java, MyPersonDAO.java, MyPersonDAOSql.java, to allow wide
open exercising of toy data.
-
Bug fix : posting an empty message caused a NullPointerException. Amend
MyMessage.java, MyActionAddMessage.java
web4j.jar version 1.6.0 (Published October 10, 2004)
-
Amend README, and some initial config issues
-
Prepopulation : collapse the old 'add' and 'change' use cases into a single
'edit' use case, to handle the common case of using the same form for multiple
operations. Retain but deprecate the old use cases
-
Add Edit page : demo of handling all four operations (Fetch, Add, Change,
Delete) with a single JSP, a single WebAction, and a single DAO. Add EditPerson.jsp,
Operation.java, MyActionEditPerson.java.
-
MyDestinationPage.java - bug fix, call EscapeChars.forURL on title text
-
AbstractValidatingWebAction.java - overload the returnToSender method,
to handle a common case.
web4j.jar 1.5.0 (Published July 3, 2004)
Configurable Selection scheme for enumerated items
-
MySelectionDAO.java, MySelectionDAOSql.java
-
tables : MyPizzaTopping, MyArtist
-
demo - Register.jsp, UpdateAccount.jsp, UpdateTheories.jsp, UpdateToppings.jsp
Better support for multi-valued parameters, and demo thereof
-
add methods in AbstractRequestParser.java, and some refactoring
-
some edits to SelectorEditor.java
-
demo - UpdateToppingsEtc.jsp, MyToppingsEtc.java, MyActionFetchToppingsEtc.java,
MyActionUpdateToppingsEtc.java
Variation of MyUser to demonstrate 1..N relation
-
MyUserTheories.java
-
UpdateTheories.jsp
-
MyActionFetchTheories.java, MyActionUpdateTheories.java
-
MyUserTheoriesDAO.java, MyUserTheoriesDAOSql.java
AbstractRequestParser.java
-
much improved design for parsing request parameters into java objects and
Collections
Small changes
-
web.xml - added IgnorableParamValue
-
MyRequestParser.java - if no overrides of default base class implementations
are provided, will now have sole task of translating URL to WebAction
-
MyReqParam - call MySelectionDAO for regexes related to Configured
Selections
-
Formats.java - add objectToText method, to make the formatting policy for
objects rendered in forms more obvious
-
Bug fix - SelectorEditor.java for selects and null bean properties
web4j.jar 1.4.0 (Published May 15, 2004)
Large changes
-
added VOFromParams.java, a much improved method for constructing Value
Objects from request parameters.
-
possibly-null items now used in Value Objects
Medium changes
-
web.xml : new entries standardize formats used in forms.
-
Formats.java added.
-
Regex.java expanded.
Small changes
-
Fixed bug in SelectorEditor.java : user input containing regex symbols
('$', for example) was not properly escaped
-
MyUser.java has additional fields, to exercise new cases. Corresponding
changes to underlying table.
-
Util.java has new some new methods
web4j.jar 1.3.0 (Published Feb 21, 2004)
There is a single, large edit to this version. A browsing mechanism,
suitable for browsing a large result set interactively, using various sort,
filter, and page criteria, has been implemented.
Added :
-
Browse.jsp - browse pages of a large result set, with various criteria
-
MyActionBrowseMessages.java - fetch a single page of a large result set
-
AlternatingRow.java - tag for alternating table row color
-
PagingLinks.java - tag for navigating large result sets
-
EchoParser - experimental helper class for tags which edit their body
Edited :
-
Sql.java - add '{0}' style in addition to '?' style, to handle the case
where a dynamic SQL statement cannot be easily parameterized in the usual
way.
-
Prepopulate.java - new use case
-
MyMessageDAO.java and MyMessageDAOSql.java - add getNumPages and
browse
methods
-
MyRequestParser.java, MyReqParam.java, MyDestinationPage.java, Template.jsp,
and sql.properties - various small edits
web4j.jar 1.2.0 (Published Feb 03, 2004)
Large changes
-
Prepopulate custom tag entirely rewritten, and now much less restrictive
-
Updated: Prepopulate.java, Register.jsp, UpdateAccount.jsp
-
Added: SelectorEditor.java (helper class for Prepopulate.java)
Medium changes
-
MyRequestParser, MyActionAddUser, MyActionChangeAccount - removed code
duplication for parsing the SendCard and StarRating request params. Placed
in MyRequestParser, not AbstractRequestParser.
-
Regex class added to collect common regular expressions.
Small changes
-
MyActionFetchMessages - remove VOException import, add logging statement
-
Sql and MyUserDAOSql - illustrate alternate method of passing List of params
to Sql constructor, using Object[] and Arrays.asList. Especially useful
when there are a large number of parameters.
-
Template.jsp - removed misleading comment near footer
-
custom.tld - Updated inaccurate description of Prepopulate custom tag.
-
package.html (data package) - correct link to zip file
-
Login.jsp - removed extraneous slash at the end of <input> tags
web4j 1.1.1
This is the first version sold as a zip file.