ERCoreBusinessLogic
ERCoreBusinessLogic has a nice new generic audit trail mechanism in the form of ERCAuditTrail. More documentation to come soon on this.
ERXKey
Chainable sort orders via ERXSortOrder (and/or ERXKey's sort order methods). For instance, you can do:
NSArray
ERXKey has "plural forms" of the sort order methods. For instance, Person.FIRST_NAME.ascs() (the "s" on the end will give you an NSArray containing a single eosortordering that represents "firstName asc") -- this is just a sort-cut for cases where you just have a single EOSortOrdering that you want to pass to a fetch spec.
Ajax
AjaxSubmitButton can perform a partial submit without having an updateContainerID specified now (which really could be considered a bug, which I usually don't list here, but it's handy to know). So it behaves similarly to AjaxUpdateLink and AjaxSubmitButton's without a partial submit in that it will turn into a background request only.
You can now control Ajax resource insertion by providing a delegate to ERXResponseRewriter via ERXResponseRewriter.setDelegate(yourDelegate). See ERXResponseRewriter.Delegate. This lets you override when the framework (or other code) asks to include "Ajax" "prototype.js" and instead replace it for your own custom resource. For instance, if you want to bundle all your js into a single file, you can provide a delegate that overrides requests for any of the individual files and instead use your custom ones, or replace files with a minimized version of the original which may only be used in production.
AjaxModalContainer
AjaxModalContainer got a bit of a face lift (this is quoted from my original post on wonder-disc:)
Previously if you put contents inside the container tag, it would always render, which could be really big if you have a repetition. Now you can set ajax=true, and it will fetch the contents in an Ajax request instead. If you set ajax=true, you must also provide an id binding.
Previously, all the Ajax requests that were happening were not tagged with the proper request header, so it made Ajax requests appear to the server to be non-ajax requests.
There is now an iBox.init() function that is exposed to allow reinitializing iBox. For instance, if you have iBoxes in an update
container, you will want to call this at the bottom of your container. We need to add a better, more generalized way, to address this problem at some point, because several of the libraries have similar requirements.
You really should carefully consider the use of the action binding. It does not execute as an Ajax request (I'm not sure why, but it's explicitly documented as such), which means you can burn your backtrack cache using it. The preferred method of use for modal container should really be external hrefs, direct contents, or the new ajax=true binding with contents. In fact, unless someone has an example where the action binding is valid (which is possible -- I just can't think of an example), I'm almost tempted to consider it deprecated, or at least the behavior might change to make it more like other action bindings on Ajax components.
Lastly, there's a new example in ModalContainerExample that shows AjaxModalContainer used inside a repetition with an ajax=true that contains a form that allows you to edit objects in the repetition.
Migrations
Migrations support more batch operations. For instance, previously you had to call .create() on a table prior to calling .setPrimaryKey(..). The Migration API now keeps track of whether or not it has been created and will work the same either way. Additionally, there are some new methods on ERXMigrationTable that provide support for PK generation through the usual EOF routes.
EOF
ERXQualifierInSubquery provides support for fetching objects of an entity where one of its to-many relationships matches a given qualifier.
ERXJDBCUtilities has some more convenience methods for doing ResultSet manipulation (for use primarily in complex migrations) via processConnection and processResultSetRows (see the javadoc for more info on using). Mainly these guys take care of opening and closing JDBC resources for you based on EOF adaptors.
ERXKeyGlobalID provides support for serializable EOKeyGlobalID's.
There is a new "globalID" prototype for storing globalID values in other EO's that uses ERXKeyGlobalID.
Rather than set the 4 or 5 recommended EC locking Properties, you can now just set er.extensions.ERXEC.safeLocking=true which will set all the recommended values for you instead.
Misc
ERXExtensions.initApp and ERXExtensions.initEOF static methods have been added to support running Wonder in test cases and main methods without wrapping your code in ERXMainRunner or a WOApplication.
ERXQuicksilverQualifier is a KeyValueQualifier that compares values with ERXStringUtilities.quicksilverContains, which considers "QS" to be 'equal' to "QuickSilver" -- matches the original string as long as the letters appear in sequence, but not necessarily contiguous. This does _NOT_ work in EOF -- only in memory.
"wo:img" and "wo:image" are now built-in shortcuts for the inline bindings parser.
Friday, May 30, 2008
Thi(e)s(e) (2.5) Week(s) in Wonder
Friday, May 16, 2008
Last Year's Last 20 Weeks in Wonder
We'll resume our regularly scheduled This Week in Wonder soon, but I had to go through all the ChangeLogs back to last year's WOWODC to figure out what I wanted to talk about at this year's WOWODC. I thought I'd go ahead and post my notes. There's very little detail here, but it was about 5000 lines of commit logs between June 2007 and January 2008, so these are just the ones that stood out to me. I'm sure there's a inadvertent bias towards thing I worked on (and things at the beginning of the list when I wasn't yet totally annoyed by changelogs).
5.4
* Lots of 5.4 compatibility work
Ajax
* AjaxPing - support very small Ajax poller that can refresh a larger container when the cache key changes
* AjaxInPlace - added support for link vs button submits + better support for being in an existing form
* AjaxLongResponse
Components
* ERXClickableContainer - makes arbitrary elements into links
* ERXWORepetition EO support - if er.extensions.ERXWORepetition.eoSupport=true, GIDs will be used instead of hashcodes
* ERXFlickrBatchNavigation/AjaxFlickrBatchNavigation
* ERXComponent - handy component baseclass
Deployment
* Wonder has slurped up JavaMonitor and wotaskd
* Lots of enhancements to JavaMonitor
EOF
* ERXJDBCConnectionAnalyzer (from GVC) to help debug when you have a connection problem
* Support for ordering adaptor operations (to support SQLServer)
* Put a nail in the coffin of editing context locking
* FrontBasePlugIn - predictable/stable constraint names (for use in migrations)
* Partial Entities (experimental) - more info
* JavaMemoryAdaptor - an in-memory "database" ... really handy for example apps and test cases
ERSelenium
* LOTS of enhancements
Migrations
* New ERXMigration baseclass for migrations that use SQL scripts
* Support for vendor-specific SQL scripts in script migrations
* ERXModelVersion is a top level class now
* Added new API-based migrations - ERXMigrationDatabase, ERXMigrationTable, ERXMigrationColumn
Qualifiers
* ERXFullTextQualifier (if your database supports it)
* ERXQ - shortcut methods for lots of different ways of creating qualifiers
* ERXS - shortcut methods for lots of different ways of creating sort orderings
WOOGNL
* Added support for // VALID on inline bindings
Misc
* New pluralizer for ERXLocalizer (ported from Rails)
* iPhone support in ERXBrowser
* Support for multiple connections in ERIMAdaptor
* Redesigned ERXCrypto to allow pluggable encryption algorithms
* Added support for encrypted properties
* ERXMutableURL
* ERXExpiringCache supports version numbers in addition to timeouts
* ERXStats / ERXStatisticsPage - much more powerful stats tracking
* Refuse new sessions on low memory
* ERXResourceManager supports WebServerResource versioning to control browser caching
* Finally a SINGLE Properties setting for default encoding - er.extensions.ERXApplication.DefaultEncoding
* Lots of enhancements to RuleModeler
New: ERAttachment.framework
Inspired by th attachment_fu rails gem. Provides drop-in support for attachments that can be easily stored locally as static resource, locally as proxied resources via a custom request handler, as in-database resources (not currently streamed out of the database, so this should really only be used for person icons and other small resources), or on S3 as remote resources. See package.html for more details.
ERAttachment, btw, might be my favorite framework in Wonder ... If you use in-database attachments, you're talking add one relationship to your entity and a almost-no-code migration, then drop an ERAttachmentUpload component in your edit page, and an ERAttachmentViewer in your view page, and that's it. Very high bang-for-the-buck.
New: ERChronic.framework
Natural language date parsing (well, assuming your "natural language" is English). Direct port of Chronic from ruby (see http://chronic.rubyforge.org/ and package.html for more details).
New: ERCaching.framework
Support for memcached with WO. I don't actually use this one yet, so Anjo can fill in more info here.
Friday, May 9, 2008
This Week in Wonder
Not the most exciting Week in Wonder, but they can't ALL be awesome :)
BugTracker
Attachments in BugTracker are now based on ERAttachments, and ERTags support has been added.
Migrations
Migrations now support creating blob columns without specifying a size (it appears most databases don't require it).
Migrations should work much more reliably with Derby.
Unique index declarations for Migrations now support passing the index length, which is necessary to support indexes on MySQL (which cannot exceed certain lengths).
Certain Migrations are now declared to be optional, meaning a failure of the plugin to generate SQL will not result in an exception, but instead a log error. Foreign keys is an example, as not all database support foreign key constraints, but it's not really a failure condition.
Migrations now support adding regular indexes (rather than just unique indexes).
ERAttachments
ERAttachments was converted from SQL-script-based migrations to api-based migrations. This should allow it to have much better support for other databases in the future.
Ajax
AjaxObserveField has a new "observeDelay" binding that gives better periodic refresh behavior. This is particularly useful for textfields so that it doesn't fire as often as it would with just the regular frequency setting. With frequency, if a change occurred within the frequency period, a request will fire. WIth observeDelay, the request will only fire after the specified observeDelay amount of idle time. So as long as you're typing, it won't fire. When you pause, it will then fire.
If you spell the name of an update container ID wrong, you will now get a javascript error from your update links and submit buttons telling you the specified update container could not be found rather than just getting an update with no response.
Batch Fetching
ERXBatchingDisplayGroup and ERXRecursiveBatchFetching have much better batch fetching behavior for to-one relationships to abstract entities (read: it works now vs ... it didn't before).
ERXBatchingDisplayGroup now supports defining and using prefetching relationship key paths.
ERXBatchingDisplayGroup now supports overriding the row count manually. If you have a better method of setting the number of rows in the results compared to the display group's, you can now set it yourself. For instance, if you know you're only ever going to fetch two pages, you could set your row count to page size * 2 and the display group will 1) not fetch more than the row count you set and 2) skip executing the count(*) query, which can potentially be expensive. If you guess too high, it will correct for you when it runs out of rows.
OGNL
Previously in OGNL, if you declared a helper function on a keypath and one of the elements of that keypath evaluated to null, WOOGNL was not able to identify which helper class to use. For instance, if you bound your value to "person.company.name|dosomething" and person was null, it would not know to use StringHelper.dosomething(..). Now when this happens, it will walk the keypath to figure out what classes are in use and properly pass a null to your helper function. This allows you to make helpers that can do null replacement (similar to valueWhenEmpty on WOString, but in the general case).
Misc
Instead of using ERXKey.append, you can now use ERXKey.dot, which makes sense when you read your code out loud, but more importantly it's three characters shorter, which is kind of nice.
Saturday, May 3, 2008
FishEye
Atlassian has provided a hosted FishEye for Project Wonder at http://fisheye1.cenqua.com/browse/wonder/.
This Belated Week in Wonder
EOF
If you use databases sequences for PK generation that have an increment greater than one, you can now set er.extensions.ERXPrimaryKeyBatchSize or entity.userInfo.ERXPrimaryKeyBatchSize and Wonder will automatically provide a high-low implementation in memory. This can be a big performance gain for insert-intensive applications.
This was actually last week, but I forgot to mention it. Sometimes in migrations, you have to drop down and perform JDBC operations. A common one is adding a column and needing to set computed values for those rows. ERXJDBCUtilities.processResultSet can make this a little bit easier:
ERXJDBCUtilities.processResultSet(channel, "select id from SomeTable", new ERXJDBCUtilities.IResultSetDelegate() {
public void processRow(EOAdaptorChannel rsChannel, ResultSet rs) throws Exception {
int id = rs.getInt("id");
ERXJDBCUtilities.executeUpdate(rsChannel, "update SomeTable set uuid = '" + something + "' where id = " + id);
}
});
There is now a longInt prototype added to ERPrototypes.
Qualifiers
ERXQ and chainable qualifiers now have qualifier.one(array) which will return the single object that matches the qualifier (or null if missing) or qualifier.requiredOne(array), which will do the same but throw an exception if it's not there. Additionally, you can call the variant qualifier.first(array), which will return the first object in the array (or null if there isn't one).
All qualifiers in Wonder now are chainable qualifiers.
ERXQ now provides the new shortcut methods .matches(..) (for regex qualification), .has(..) and .hasAtLeast(..) (for toMany qualifiers).
Properties
Often I find that it would be nice to not have my Properties defined inside my application bundle (so deployment of a new version is easier), but defining them in JavaMonitor can also be sort of annoying. Wonder now provides support for loading "machine global" properties. The default location for these Properties is /etc/WebObjects/[YourAppName]/Properties . You can change this default by setting er.extensions.ERXProperties.machinePropertiesPath .
ERRest
There were a bunch of extensions and additions to ERRest so that it can be used as an EO simple syncing framework. It's not designed to handle conflict resolution (yet), but if you have multiple applications or deployments that need to all share a common set of EO's, ERRest makes it relatively easy to do this. For syncing, you should either be using UUID PK's or there should be a globally unique attribute on your EO. You setup your master side just like a normal REST setup (except that you should set ERXRest.YourEntity.id=globallyUniqueAttributeName -- like ERXRest.Person.id=uuid). On the client, you can write:
EOEditingContext editingContext = ERXEC.newEditingContext();
ERXDefaultRestDelegate restDelegate = new ERXDefaultRestDelegate();
restDelegate.addDelegateForEntityNamed(new ERXUnsafeRestEntityDelegate(true), YourEntity1.ENTITY_NAME);
restDelegate.addDelegateForEntityNamed(new ERXUnsafeRestEntityDelegate(true), YourEntity2.ENTITY_NAME);
...
ERXRestContext restContext = new ERXRestContext(context(), editingContext, restDelegate);
String restPath = "Person";
URL remoteUrl = new URL("http://remotesite/rest/" + restPath + ".xml");
String contentStr = ERXFileUtilities.stringFromURL(remoteUrl);
ERXRestRequest restRequest = new ERXXmlRestRequestParser().parseRestRequest(restContext, contentStr, restPath);
ERXRestKey restResponse = restDelegate.process(restRequest, restContext);
editingContext.saveChanges();
This will sync all Person entities. You can sync arbitrary rest paths as well. For instance, in the example above, you could just as easily use a restPath of "Person/1231-23523-blah123234531-blah" to sync an individual person.
ERRest now also nested insertions, so you could have an update of a Person that does an insert of a new Company specified in the Person.company relationship. This is arbitrarily nested.
ERTaggable
If you use the default separator in ERTaggable, it now supports parsing tags surrounded by quotes with multiple words. For instance, you can now tag your objects: tag1 tag2 "multiple word tag3".
ERSelenium
ERSelenium now includes the necessary requirements for Selenium Remote Control -- see http://selenium-rc.openqa.org/. It's really cool.
Ajax
AjaxSelectionList can now grab focus (focus = true) and has lots of misc fixes.
AjaxBusyIndicator can now watch a particular updateContainerID and either apply styles to that container, or perform custom onCreate and onComplete functions when a request occurs (note, this is onCreate of the request, and onComplete of the request, to explain the odd naming). This makes it easier to make per-component busy indicators that don't just trigger on every request.
AjaxPing now has an onBeforeUpdate binding that you can provide a Javascript function that can deny the update.
AjaxSubmitButton now has an elementName binding like AjaxUpdateLink. This allows you to make "clickable divs" (like ERXClickableComponent) that are Ajax submits.
Some of the Ajax components cached their generated ID values. These generated values were previously based on the component's element ID. The problem with this is that when the page structure changes, these components could be left hanging onto an ID that now belongs to another component on the page. These components now use a new scheme for ID generation that takes advantage of the new ERXResponseRewriter's page userInfo, to generate unique cacheable IDs.
Misc
ERXFlickrBatchNavigation now supports changing the batch size (showBatchSizes and batchSizes) bindings.
ERXCommandLineTokenizer provides a parser for parsing "command line"-style parameters, where individual words are single tokens as well as multiple words in double quotes or single quotes.
ERXFileUtilities.stringFromURL(URL)
ERXFileUtilities.chmod(String, String) -- only works if you are on an OS that supports chmod
ERMovies was converted to migrations and should be a little easier to run out-of-the-box.
Thursday, April 24, 2008
This Week in Wonder
It's been a pretty busy week (and this is a lame effort to summarize 163 commit messages):
ERMovies
Ray Kiddy updated the movie example to 2008. New features include auto-populating DB and Apache Derby support.
Derby plugin
Used by BugTracker and ERMovies and now supported by ERPrototypes, it provides preliminary EOF support for Apache Derby. Most things seem to work, there are some issues with BLOBs, though.
ERXDelayedRequestHandler
If you ever have pages which *might* take a bit too long, but don't warrant a long response page, then this is for you. When you install this response handler (and use ERXApp) then a request that is taking too long is detached and the user is presented a "Uh, this might take a while, get some coffee" page - without you needing to do anything at all. And it has a "Stop now" button in case you don't actually want to finish the action.
This is also very useful when you are running in development and are dropped into a breakpoint. Normally, you'd get the adaptor error page but now it loops merrily until you continue.
loc:foo and negate:foo prefixes
These are the first implementations for the new prefix registration in the WOOgnl parser. They now also support carret bindings like ^title.
ERXLocalizerAssociationloc:value = bar
first asks the current localizer to handle the value of bar. This is way more powerful and readable than before, where you would either need to use
value = session.localizer.bar
or write an accessor method.
ERXNegateAssociation
Ever had an accessor that was just the opposite of what you needed?
not:disabled = bar
helps here.
ERXRuntimeUtilities
There is no easy way in Java to stop one thread from another. Actually, it's not possible at all unless the thread is waiting in the exact moment you try to stop it. We added a few crucial points where the current thread checks it it should quit: whe fetching a row from the DB and when the context sets a current component.
You just call ERXRuntimeUtilities.checkThreadInterrupt() at regular intervals and the thread that wants to stop calls ERXRuntimeUtilities.addThreadInterrupt(Thread thread, String message).
ERRest
The REST framework is getting quite a bit of work done on it (with more coming soon).
The entity delegates resolver will now guess names that aren't registered (for instance, if you request /Manufacturer, it will look for a ManufacturerRestEntityDelegate), and you can now specify delegate names in Properties (ERXRest.Manufacturer.delegate=ERXUnsafeReadOnlyRestEntityDelegate).
The beginnings of the JSON input/output for ERXRest was committed, though not on by default (still experimental).
There are several new convenience methods for registering ERXRest. The simplest is to add:
ERXRestRequestHandler.register(new YourRestAuthenticationDelegate(), true, true);
to your Application constructor and add Properties entries for registering delegates.
ERXRest now supports non-integer keys. If a key in the URL isn't the property of an entity, it is treated as a key. You can now also specify a custom attribute on your EO's to act as the "id" value by setting:
ERXRest.Manufacturer.id=nameOfAttribute
, which allows your EO's to expose non-PK attributes as the lookup value. For instance, you could have a UUID "external ID" that can be used for syncing EO's across multiple applications.
Ajax Load-on-Demand
[MS: This is a repost from of the announcement the wonder-disc list]
This is the largest change to Ajax framework in a while, and because it introduces some breaking API changes, I wanted to explain what it's all about.
Previously, if you had a page that revealed a new Ajax component (new = first use on the page) only in an Ajax refresh, you are probably familiar with the problem that the necessary Javascript dependencies were not loaded correctly. The cause of this is that the component was hidden and did not have a chance to inject its dependencies into the head tag. With this most recent commit, Ajax framework (transparently) supports load-on-demand of Javascript dependencies. It keeps track of which scripts (and CSS) have been loaded on your page (both on the original render as well as subsequent Ajax requests) and if a new component introduced in an Ajax update requires a script that has not been loaded, it will switch to render the dependency with the new load-on-demand method.
The Javascript side of load-on-demand is actually a feature that appears that it will be in Prototype 2.0 which we have brought forward into wonder.js, and the Java side is just the usual Project Wonder black magic :)
So about breaking API changes and behavior changes:
Most of the ERXWOContext response rewriting methods have been moved to ERXResponseRewriter. They never really made a lot of sense on ERXWOContext, but especially now that these methods actually potentially consider information that crosses contexts, it made sense to reorganize them. Additionally, several of the API's have been changed -- most just to take a WOContext where they didn't before. The most notable API change is that previously the insertion behavior was controlled with two booleans which have now been replaced by an enumerated type that more clearly defines what the behavior of the insertion methods will be when the head tag is not present (either because it's just missing or because you're in an Ajax update). For most people, the only change you may need to make is to add the missing WOContext parameter if it's needed (the other variant of the method probably was not used very much).
As for behavioral changes, there is really one PRIMARY one (well aside from the whole load-on-demand thing). The big behavioral change is that previously you could actually "insert" script and css into the head tag BEFORE it actually existed. Generally this is only even an issue when you try to add script/css in your Page Wrapper by overriding appendToResponse and calling those method BEFORE super.appendToResponse (meaning your page wrapper has not yet rendered the head tag, but you're asking to insert into it). Because of some of the API changes, it was necessary to REMOVE this ability (long story, but the API's require a WOContext and the method that previously provided this ability did not have access to the WOContext to fulfill the API). The fix for this is relatively simple -- Just move any calls to those functions in your page wrapper AFTER the super.appendToResponse. This probably won't impact many people, but if it DOES impact you, it will manifest as your CSS and Javascript not injecting into the head tag and a warning will be generated on the console explaining what happened.
ERXStyleSheet and ERXJavaScript have been modified to register their loaded resources with the same system, so if you use an ERXStyleSheet or ERXJavaScript, it will not double-load if you later load scripts/css with ERXResponseRewriter. ERXStyleSheet will now SKIP rendering its stylesheet if it has already been loaded (so you can put ERXStyleSheet in Ajax rendered components in addition to using ERXResponseRewriter and it will behave the same). ERXJavaScript right now does not skip rendering, but it DOES register that it has loaded, so it will satisfy dependencies if you later use ERXResponseRewriter to load scripts on-demand.
If for some reason you want to turn off load-on-demand, you can 1) just keep doing things the way you were -- declare your scripts at the top level so they have all been loaded by the time the Ajax components render, or 2) set er.extensions.loadOnDemand=false.
While the actually lines of code of these changes is relatively small, it's conceptually sort of significant, so please try out your Ajax apps and let me know if you see any oddities. Hopefully this will make the components much more encapsulated and far easier to use for everyone ... Apologies for any backwards compatibility issues this introduces in the short term.
Misc Ajax
AjaxDroppable has an onBeforeDrop binding that lets you connect a javascript function before the drop happens. AjaxDroppable can also now act like a submit button instead of a link by setting submit = true. Both AjaxDraggable and AjaxDroppable got a shiny new paint job, too -- all the javascript that used to generate in the component output is now moved to wonder.js and the generated output is substantially smaller.
AjaxObserveField has a new onBeforeSubmit binding that allows you to return false to deny the submit.
Misc
ERD2WDirectAction now supports
ErrorFoo?__message=bar calls which is an easy way to put up a error page.We moved the work-in-progress stuff from ERXFetchSpecification to ERXGroupingFetchSpecification.
ERXObjectStoreCoordinatorSynchronizer: The synchronizer now exposes the ability for fine-grained sync controls between stacks. For instance, if you application is a write-mostly app, it may be undesirable to have inserts synced between EOF stacks. You can now setDefaultSettings on the synchronizer (or set the settings per-object store) to control exactly which types of operations will be synced across stacks, including turning syncing off entirely for particular stacks.
Thursday, April 17, 2008
This Week in Wonder
This Week in Wonder's schedule is all thrown off, but to finally catch us back up:
ERXFetchSpecification
This is still new and under development, but ERXFetchSpecification extends the concepts of a fetch spec and adds:
- support for caching
- type safety via generics
- user info for tracking additional information as you pass a fetch spec around
- support for grouping results by keypaths
One of the primary features here is caching. In EOF, if you traverse a to-many relationship, the GIDs of the members of that relationship are cached, which ensures that you don't have to do a db roundtrip every time you want to traverse your relationship. Unfortunately, if you use a fetch spec, there is no such cache provided and you always hit the database. ERXFetchSpecification allows fetch spec results to be cached to avoid repeatedly hitting the database. Again, this is still being developed, but Anjo has some very cool ideas for integrating fetch caching with memcached.
WOOGNL
The WOOGNL template parser now supports registering custom association prefixes. You can now set WOOgnl.setAssociationClassForPrefix(associationClass, prefix). This allows you to implement associations like i18n:value="title", which could load the "title" key from your localized strings. We haven't yet provided any out-of-the-box association classes yet, but we have several ideas (happily stolen from other frameworks :) ) that we will be implementing.
JNDI/LDAP
ERXModelGroup has always allowed replacing connection dictionaries on a model based on Properties values, but it only supported JDBC adaptor models. JNDI models are now supported with the properties:
[modelName].serverUrl the per-model server URL to set
[modelName].user the per-model username to set
[modelName].password the per-model password to set
[modelName].authenticationModel the per-model authenticationMethod to set
JNDI.global.serverUrl the global JNDI serverUrl to use by default
JNDI.global.username the global JNDI username to use by default
JNDI.global.password the global JNDI password to use by default
JNDI.global.authenticationMethod the global JNDI authenticationMethod to use by default
Misc
The new ERXModelDoc component provides a convenient way to display model documentation for a model, entity, attribute, and relationship.
ERXStyleSheet is more versatile now and supports optionally inlining the stylesheet vs injecting into the head tag.
You can now provide a custom subclass of the WOOGNL template parser by setting the property "ognl.parserClassName" to your custom subclass.
Response compression now supports stream-based responses.
ERXInOrQualifier is no longer on by default. We had to remove it as the default in 5.4, anyway, because of compatibility problems. If you want to re-enable it in your application, add
EOQualifierSQLGeneration.Support.setSupportForClass(new ERXInOrQualifierSupport(), EOOrQualifier._CLASS); to your Application constructor.ERXQualifierTraversal provides an implementation of the visitor pattern on qualifiers.
ERXProxyAssociation allows you to wrap an existing WOAssociation and inject a fixed prefix or suffix to the existing value.
ERXExpiringCache now supports timeouts per-key rather than just a global timeout for all cache entries.
ERDLinkToEditObject can link to to-one's now.
ERXEnterpriseObjectChangeListener provides a base class for implementing cache invalidation or other classes that need to be notified of changes to specific entities.