The Melati Project
Release Notes
last updated 2015/06/20 - timp
Release 0.7.9
Release 0.7.9
2015/06/20
Migrate to git and host on github
No more CVS
Unify webmacro and velocity templet directories
The templets of both flavours are now sored in the same directory.
Generate generic classes
Generated classes now use generics.
Generate referencesToThis() methods
This method is so prevalent that it moved into the generated classes.
Add String Key Reference Types
Sometimes you fall from the one true way and use string key references, now you can in POEM too, but don't.
Addition of JSON as an output language
An initial stab at a json putput.
Generation ensure() methods.
<> A simple method to ensure that a table has a row is now generated from the known required fields.Test with Java 8
Release 0.7.5-RC6
Release 0.7.5-RC6
29/01/2007
Major refactoring of org.melati.utils such that all dependencies are now on poem.utils if the particular util is used in POEM at all.
The main work is in moving StringUtils, which is used extensivley in and outside of POEM.
The other gotcha is the move of org.melati.util.MelatiLocale to org.melati.poem.PoemLocale, so check your templates as well as your code.
The transaction api has moved to org.melati.poem.transaction.
org.melati.LogicalDatabase now relies upon org.melati.poem.PoemDatabaseFactory.
The enclosed class Persistent.Saved has been removed.
The LogSQL, LogCommits and AddConstaints properties are applied from the properties file.
Release 0.7.5
Release 0.7.5
06/02/2005
Support for command line apps.
Additional support for Oracle and HSQLDB.
You will need to change references to org.melati.servlet.MelatiContext to org.melati.PoemContext and remove direct access to its members, use the setters and getters. Eg in templates $melati.Context.logicalDatabase should now be $melati.PoemContext.LogicalDatabase
Release 0.7.4
Release 0.7.4
10/01/2005
Addition of support for Oracle.
Release 0.7.3
Release 0.7.3
22/12/2004
Fixes to TemplateServlet to allow reading templates from jars.
Separation of JUnit tests into own tree.
You will need to change melati-static to point to /dist/melati/src/main.
Release 0.7.2
Release 0.7.2
26/02/2004
Upgrade of Velocity jars.
Fixes to statictrees.js to accomodate variations in EACMA script.
Addition of a JSP handling servlet.
Better setting of content-type to reflect Accept-charset.
Support for canselect columns and filtering out of rows for which the user does not have the capability.
Support for other joins and use of Persistent to represent selection criteria on joins.
Fixed bug affecting rollback of Persistent objects.
Persistent.postEdit() hook called by Admin system to allow processing rows after user creation/edit.
Release 0.7.1
Release 0.7.1
11/07/2003
A new PoemType BigDecimal has been added.
The preprocessor has been modified to generate checkstyle compliant javadoc which has been retrofitted to existing POEM classes.
An additional method on TemplateEngine now allows exception templates to be discovered on the classpath in addition to the relevant templet directory.
Release 0.7.0
Release 0.7.0
04/06/2003
In Table.appendWhereClause() Column names are now qualified with the table name to allow rows of the table to be selected using joins.
Webmacro 1.1 is now assumed.
New DSD method added to Admin.
The source tree has been massively cleaned up, due to the use of Eclipse and Maven highlighting silly format issues.
Trees can be rendered using Velocity as well as webmacro.
User Locale is now inferred from the user session.
Release 0.6.1
Release 0.6.1
11/06/2002
- Support for MckoiDB
- Support for HSQLDB
- Bundling of jetty and hsqldb
- Website improvements
- Ant build improvements
The template path convention has been changed, so that there is no need to have org/melati in your classpath. This is because both WebMacro and Velocity now default to a classpath template loader. This change should make no difference to existing installation.
the major change is the bundling of Jetty and HSQLDB with the distribution as a step towards a Melati Developer's Kit.
Release 0.6.0
Release 0.6.0
19/04/2002
- Support for MySQL
Release 0.55.6
Release 0.55.6
01/03/2002
- Add Tree rendering to Admin
- Tidy JSStatic tree
- Incidently added support for MySQL, but this requires testing prior to 0.6.0 release
Release 0.55.5
Release 0.55.5
15/02/2002
- Improve Admin frame handling
- Add edit links for Reference Type objects in Admin
- Add JSStatic tree
Release 0.55.4
Release 0.55.4
17/12/2001
- Improve connection pending error message
Release 0.55.3
18/09/2001
- Add javascript email validation
- when extracting fields, trim whitespace from values. This allows users to enter '19 ' in an integer field, and not generate an error.
- fix trailing / for upload in ConfigServletTest
- allow melati to run from an IP address under jserv
Release 0.55.2
17/08/2001
- Adds a 'remember me' feature to login. This stores the user's password in the cookie.
Release 0.55.1
25/07/2001
This is a minor maintenance release that fixes problems with uploading items for objects that don't yet exist.
12/07/2001
- support for JSDK 2.2, specifically Tomcat
- modifications to the upload process, allowing access to the Melati / MelatiContext
- Improvements to error handling
JSDK 2.2 / Tomcat
If you only want to install one melati, but would like to run several contexts (analog of servlet zone), you should copy or make softlink of melati dir to WEB-INF/classes for each context (or melati jar to WEB-INF/lib/).
Upload Process
A limitation of the Upload Process was that the Melati / MelatiContext was not set up before the file upload begun. This meant that the location where the file is stored could not be manipulated depending on the User/Object/Field currently in use. Additionally no Access check was made, potentilly causing security problems. This has now been fixed.
Error Handling
You can now avoid Red Stacktrace Of Death effect when the user creates duplicate keys
If you have specialised org/melati/error.wm for your site, you will have to rename your version to org/melati/template/webmacro/templets/html/error/java.lang.Exception.wm
org.melati.servlet.TemplateServlet has been changed to handle exception conditions by searching for a templet named after the exception or a superclass, prefixed by "error/". In general this winds up as
org/melati/template/webmacro/templets/html/error/java.lang.Exception.wm
and that file has superseded the top level "error.wm" (now deleted from CVS). The immediate purpose of this is to enable us to supply a specialised file
org/melati/template/webmacro/templets/html/error/org.melati.poem.DuplicateKeySQLPoemException.wm
for handling the case in which the user inserts or modifies a record in a way which breaks index uniqueness (e.g. duplicate user name) without making it seem as if the world has ended.
The implementation leverages a new feature of (ClassName)TempletLoader: you can optionally supply a "purpose" parameter, in this case "error", to direct it to look in a subdirectory of the standard templet repository corresponding to the purpose for which you want the templet. This makes it possible to use class names for templets without messing up the namespace when you want to do different things with the same class.
Release 0.54.2
03/07/2001
- fix to default rendering of html elements - \n is translated to <br> for elements that are displayed, but not if they are 'rendered for input'.
- please use WebMacro 0.98, as 0.97 has a bug which menas that AccessExceptions do not always return a login page
Release 0.54.1
20/06/2001
- fixes to templates and templets required for Webmacro 0.97.
- change to default rendering of html elements - \n is now translated to <br>.
Release 0.54
11/06/2001
- support for Webmacro 0.97. Previous versions of webmacro are no longer supported.
- support for Velocity 1.1
WebMacro 0.97
- Cleaning up. We have removed all 'hacked' webmacro classes from Melati. If you have any org.webmacro.* classes hanging arround, please ensure you delete them.
- FastWriter. FastWriter is now constructed with a Broker. So, you will need to replace any construction (eg):
MelatiFastWriter(OutputStream output, String encoding) with
MelatiFastWriter(Broker broker, OutputStream output, String encoding)- Exception Handling in Templates. Melati sets a PropagateExceptionHandler by default (forcing a logon page on encountering a AccessPoemException). If you want to use a PassbackExceptionHandler, you must set it in your template:
$melati.setVariableExceptionHandler($melati.PassbackVariableExceptionHandler). Please ensure you check your Templates.- Be careful with your templates (WM0.97 is not fully backward compatible). Please see http://www.webmacro.org/SyntaxChanges. Run this command to see if you have problems; grep -H -n "\\$\(\\w*\\.*\)*;" *.wm
Velocity
Melati now supports Velocity 1.1.
- At this stage, we don't ship any Velocity specific templates, instead we translate the webmacro templates 'on the fly'. To do this, we override the Velocity file.resource.loader.class with our own org.melati.template.velocity.WebMacroFileResourceLoader. If a .vm template with the correct name is found it will be used, otherwise, the .wm template will be loaded and translated.
- The template path for Velocity is set in org.melati.MelatiServlet.properties. It may be a good idea to do this for WebMacro as well, but it wasn't obvious how to do this, so it has been left for the time being.
Release 0.53.6
09/04/2001
Minor housekeeping release.
Release 0.53.5
23/03/2001
0.53.5 introduces the following changes.
- DSDs can now be imported into other DSDs
Importing DSDs into other DSDs
You can now import DSDs into other DSDs. For instance, in my ImportBoards.dsd I have a line:
import org.paneris.melati.boards.model.boards.dsd;This adds all the tables defined in the boards.dsd file into my ImportBoardsDatabase in such a way that you can access them in the same way as any tables defined in ImportBoards.dsd. In particular, the objects in these tables are instances of org.paneris.melati.boards.model.boards.* (i.e. any custom code is available).
All the imported tables are included into the new database. Note that all Tables/Persistents are cast to the "base" table/persistent with the same name - you will have to manually cast them to the correct type. Here "base" means the oldest (nearest the root) base class. E.g. Poem.dsd defines User. boards.dsd defines a new persistent, org.paneris.melati.boards.model.User (and ImportBoards.dsd defines a org.paneris.melati.playing.importboards.User). If you call getUserTable() on any of these databases you will get a org.melati.poem.User object (which can be cast to org.paneris.melati.boards.User or org.paneris.melati.playing.importboards.User).
Changes required to projects:
1) We no longer provide a getXxxxDatabase() function in each Table and Persistent. Instead you should either just use getDatabase() or you can use getXxxxDatabaseTables() to access tables specific to your project. In particular, getPoemDatabase() is no longer available in the Poem tables/persisents. So if you call getPoemDatabase() in your code, you should change it one of getDatabase() or getPoemDatabaseTables(). Similarly, if you re-run DSD on your project Xxxx then you will need to handle any calls to getXxxxDatabase(). You can either change them to getXxxxDatabaseTables(), getDatabase(), or you can add the old function into your non-generated files: e.g. in MyTable.java add:
XxxxDatabase getXxxxDatabase() { (XxxxDatabase)getDatabase(); }2) I have tested this on several databases and although I am fairly confident that it should work, IF YOU RE-RUN DSD ON YOUR OWN DATABASES YOU MAY EXPERIENCE PROBLEMS.
3) Your .dsd file must live in the same directory as your compiled code because it is loaded as a Resource.
Release 0.53.4
13/03/2001
0.53.4 introduces the following changes.
- Support for Webmacro 0.95b3. Previous versions of webmacro are no longer supported.
- Improved support for MS SQLServer
This release patches the memory problems experienced with Webmacro previously.
Release 0.53.3
26/02/2001
0.53.3 introduces the following changes.
- Support for Webmacro 2000-12-06. Previous versions of webmacro are no longer supported.
- PoemTransaction monitoring, please see
http://localhost/<servlet zone>/org.melati.poem.SessionAnalysisServletPlease note, this is an experimental release. we have found problems with Webmacro 2000-12-06 eating memory.
Release 0.53.2.1
01/03/2001
Provides a workarround for the bug where Webmacro0.94 Fastwriter silently failed to write context of > 512 chars
Release 0.53
13/02/2001
0.53 introduces the following changes.
- support for Webmacro 0.94. Previous versions of webmacro are no longer supported.
- improved file uploading (streaming to file, preventing "out of memory" errors).
- cascading deletion in POEM
Webmacro 0.94
Webmacro 0.94 uses a FastWriter which writes to the underlying OutputStream. It no longer uses a PrintWriter. So; Melati now has the following new classes:
abstract class MelatiWriter - for classes writing direct to the Servlet (or another) OutputStream / Writer
class MelatiStringWriter extends MelatiWriter - for writing to a String
class MelatiSimpleWriter extends MelatiWriter - writes to a given Writer
class MelatiBufferedWriter extends MelatiWriter - writes to a given Writer (with buffering)
for using melati with webmacro:
class MelatiFastWriter extends MelatiWriter - writes to a FastWriter
class MelatiBufferedFastWriter extends MelatiFastWriter - writes to a FastWriter (with full buffering, output also available as a String)melati.getWriter() will ask your template engine (if you have one) for an appropiate writer, otherwise it will give you a SimpleMelatiWriter or a BufferedMelatiWriter depending on if you have got buffering on or off. MelatiWriter will also start a Flusher if appropiate.
The only API change you need to be aware of is the alternate constructor for melati (for use in 'stand alone' mode) is now:
public Melati(MelatiConfig config, MelatiWriter writer)
If melati can't get an encoding from response.getCharacterEncoding(), it uses the default "UFT8".
Improved Uploading
Access properties of an uploaded file (or "normal" form fields) through MultipartFormField. Some of these properties are supplied by FormDataAdaptors which save each field somehow (e.g. to memory or to a file).
You can handle uploaded files how you want by supplying a FormDataAdaptorFactory to MultipartDataDecoder. If you are using TemplateServlet then this is done automatically for you: It uses the FormDataAdaptorFactory set in the MelatiConfig (which can be set in org.melati.MelatiServlet.properties). You can override the default in your TemplateServlet by doing something like:
protected MelatiConfig melatiConfig() throws MelatiException { MelatiConfig config = super.melatiConfig(); DefaultFileDataAdaptorFactory factory = new DefaultFileDataAdaptorFactory(); factory.setUploadDir("/tmp"); config.setFormDataAdaptorFactory(factory); return config; }For an example of how to parse an uploaded file manually, see org.melati.test.ConfigServletTest. org.melati.test.TemplateServletTestWM also allows you to upload files.
If you are using UploadURLPoemType.wm for the renderinfo for a field (so you can upload files in Admin) then you need to make sure your FormDataAdaptorFactory implements getURL (e.g. use PoemFileDataAdaptorFactory)
In summary, then, the important classes (in org.melati.servlet) are:
MultipartDataDecoder - parses a Multipart form into
MultipartFormField
MultipartFormField - allows access to properties of uploaded fields (normal form fields and uploaded files)FormDataAdaptor - tell us how "save" an uploaded field:
MemoryDataAdaptor - save the data in a byte array in memory
TemporyFileDataAdaptor - save the data to a temporary file
DefaultFileDataAdaptor - save the data in a (unique) file in the given directoryFormDataAdaptorFactory - allows us to implement a policy for saving uploaded files (not normal form fields)
MemoryDataAdaptorFactory - save all files in memory
TemporyFileDataAdaptorFactory - save all files to a temporary file on disk
DefaultFileDataAdaptorFactory - save all files in a (unique) file in the given directory
PoemFileDataAdaptorFactory - save all files to in a directory specified in the database's setting table
Cascading Deletion in POEM
0.53 has the following improvements to Melati's object deletion mechanism:
- Facility for deleting referring objects, or NULLing out referring links, rather than aborting the delete in order to maintain referential integrity.
- Intra-transation delete (which can be rolled back): handier than deleteAndCommit.
Action required/risk analysis
These changes have only been lightly tested, so administrators are advised to try the updated system out before deploying it.
In principle, no action is required unless you are a programmer and your code overrides `Persistent.deleteAndCommit()'. In that case you should change it to override the new `Persistent.delete(java.util.Map)' instead.
If you wish to use `Persistent.delete()' in your code in future, you should recreate the generated/*.java files from your application's DSD and recompile. Otherwise there is an unlocked race condition which might cause loss of referential integrity. Existing code which only calls `Persistent.deleteAndCommit()', and does not override it, does not need to be recompiled.
A new field is introduced into the `columninfo' table, but POEM's unification mechanism will handle that automatically. (The field is nullable, so does not need initialising.)
Adding support for the intra-transaction delete method involved introducing additional record locking in the case that a POEM thread creates a link to an object but does not examine its contents. Previously this would not read-lock the object; now it does. This is most unlikely to cause problems.
Detailed description
Flexible integrity fixes
Previously, if there were objects in the database containing references to the object to be deleted, the deletion would simply fail. That is still the default, but two alternative behaviours are now also available: NULL out the offending links, or delete the linking objects too. The policy followed is configurable for each referring column in the database, so that ephemeral records associated with a master object can be set selectively to auto-delete rather than inappropriately obstruct deletion of the parent.
To make a link delete its source when its target is deleted o in the DSD:
- use "(integrityfix = delete)". For instance,
table BookStocking (description = "A record that a bookshop stocks a book") {
(primary) Integer id; Bookshop shop (description = "The bookshop");
Book book (description = "The stocked book") (integrityfix = delete); ...
}
The BookStocking record will be removed transparently if its `book' is deleted, but will (defaulting to the standard behaviour) prevent deletion of its `shop'.- via the admin system: find the column in the `Column' metadata table, and set its `Integrity fix' field to `delete'
- via POEM directly: column.setIntegrityFix(StandardIntegrityFix.delete);
To make the link instead NULL itself out, use `clear' rather than `delete'.
Applications programmers are also able to override these settings for each individual delete operation, by passing an optional argument to the `Persistent.delete' method.
Cancellable intra-transaction deletes
The new `Persistent.delete' method differs from the existing `Persistent.deleteAndCommit' in that (a) it does not wait for exclusive access to the database before attempting to delete the object, and (b) it does not perform a `commit' (`rollback') immediately upon (un)successful completion. This means that it can be rolled back later if necessary, and makes it more like the normal get/set/create operations. Both methods will remain for now, and both support the new, more flexible integrity maintenance scheme.
Release 0.52.1
21//01/2001
The main motivation for this release is to seperate the Java doc from the rest of the code so that each can be downloaded seperately. The JavaDocs are no longer in CVS, but are available on the website for browsing and download.
Additionally, the following changes are included.
- ability to override Melati Config settings.
- support for BINARY types in POEM
Release 0.52
18/01/2001
Introduction
This release involves a major overhaul of the Melati servlet API and templet API.
This has been done to provide the following:
- a cleaner Servlet API that allows more flexible interaction with Melati, notable the ability to use Melati outside of a POEM Session
- a cleaner relationship with Webmacro, allowing us to plug in other Template Engines, and to prepare the code to provide support the latest WebMacro release (0.95). Note, this release still only supports the July 19, 2000 WebMacro snapshot.
This release does not introduce any significant new functionality, but does provide an API against which this can be done. Some minor new functaionality has been added:
- File upload
- Melati Test suite
Warning
- You existing 0.50 applications will not work with this release
The new Servlet API
MelatiServlet and MelatiWMServlet have been removed, and have been replaced by the following hierarchy:
org.melati.servlet.ConfigServlet extends HttpServlet
org.melati.servlet.PoemServlet extends ConfigServlet
org.melati.servlet.TemplateServlet extends PoemServlet
org.melati.template.webmacro.WebmacroMelatiServlet extends TemplateServlet
These are explained in more detail here:
org.melati.servlet.ConfigServlet
This simply creates a Melati using the configuration given in org.melati.MelatiServlet.properties, and a MelatiContext. The PathInfo is parsed to provide a 'Method'. Extending ConfigServlet is useful when writing servlets that do no want to run entirely within a POEM Session. Eg, a servlet that does a lengthy task not associated with POEM (like streaming a download) could tie up POEM Transactions for a long time unnecessarily.
To use ConfigServlet, implement:
protected abstract void doConfiguredRequest(Melati melati) throws Exception;
org.melati.servlet.PoemServlet
This does further parsing of the PathInfo into MelatiContext in order to provide a LogicalDatabase, Table and Troid. It then sets up a POEM Session (using the configuration given in org.melati.LogicalDatabase.properties.). PoemServlet is useful when you want to do build servlets without a Template Engine getting in the way. Eg, you want direct access to the Servlet Request, or want control over the response (using say Response.OutputStream).
To use PoemServlet, implement:
protected abstract void doPoemRequest(Melati melati) throws Exception;
org.melati.servlet.TemplateServlet
This initialises the Template Engine (given in org.melati.MelatiServlet.properties). TemplateServlet is used as the base servlet for generic Melati Servlets eg Admin, Login.
To use TemplateServlet, implement:
protected abstract String doTemplateRequest(Melati melati, TemplateContext context) throws Exception;
You should return the template name without the extension which is added by the TemplateServlet
org.melati.template.webmacro.WebmacroTemplateServlet
This is provided for convenience. It simply provides an API for using melati with WebMacro. This API is a little different from the 0.50 MelatiServlet API. to use
public abstract String handle( Melati melati, WebContext webContext ) throws Exception;
So, instead of returning a template, simply return the template name (including the extension).
Changes to the Packages
Some stuff has been moved, and new packages have been created:
org.melati.template
This now contains the Template Engine Interface code (see below). It also contains org.melati.template.webmacro and org.melati.template.jtemplater. Package org.melati.template also now contains MarkupLanguage and associated classes.
org.melati.templet
Has gone. Everything has been moved to org.melati.template. It was basically too confusing to have packages with such similar names, and they are very intertwined anyway.
org.melati.servlet
Has the generic classes that implement HttpServlet. Also now contains MelatiContext.
org.melati.test
Has some nice servlets that allow you to test your installation. Bloody useful.
Key Objects
The objects used by Melati have changed a bit, here are the important ones
org.melati.MelatiConfig
This loads in org.melati.Melatiservlet.properties. Importantly it allows you to get a Melati ;
public Melati getContext(HttpServletRequest request, HttpServletResponse response) throws MelatiException
org.melati.Melati
This is where everything happens, it does all the usual stuff (access to the servlet API) and much of what was in org.melati.Melati. Importantly, is also has:
public Writer getWriter() throws IOException;
This give you access to the output stream at all times. By default, this is fully buffered, but you can turn this off completely or use a ThrowingPrintWriter which periodically flushes. Templets are now expanded directly to the output stream without haveing to be buffered in strings first.
org.melati.MelatiContext
This is unchanged.
org.melati.template.TemplateContext
This is the interface to the context against which your templates / templets are expanded. It provides get and set methods that (in the case of WebMacro) map directly onto the WebContext
Changes to .properties
You will need to add the following line to org.melati.Melatiservlet.properties
org.melati.MelatiServlet.templateEngine=org.melati.template.webmacro.WebmacroTemplateEngine
Also, if you have an entry for TempletLoader, it should now read:
org.melati.MelatiServlet.templetLoader=org.melati.template.ClassNameTempletLoader
And javascriptLibraryURL should read
org.melati.MelatiServlet.javascriptLibraryURL=/melati-static/template/webmacro/templets/html
(although it is not clear that it belongs here)
Exception Handling
I believe that exceptions are now presented better. Any exception that is not part of the Initialisation process should now be presented with a full stack trace to the browser, and logged with a full stack trace to System.err. If you get a Server Error, it means you have a problem in the initialisation and you need to review the error_log.
What has not been done
- source code documentation (some has been done)
- complete seperation from WebMacro (we are still using the hacked Variable stuff), but this should be possible when we introduce WebMacro 0.95
Installation Instructions
Follow the usual instructions and then open:
http://localhost/<servlet zone>/org.melati.test.ConfigServletTest/
This should lead you through testing Melati and allow you to debug your installation easily.
Release 0.50
23/11/2000
This is the first public beta release of Melati.
Melati has been used as Alpha software for over 9 months, and there are several sites in production.
This beta release offers the following improvements over Alpha versions of Melati:
- Testing and numerous bug fixes
- Now available as a downloadable zip / tar.gz.
- Precompiled melati-snapshot.jar allowing easier install.
- Ant build script
- Mailing list hosted on SourceForge
- More documentation
- Revised licensing - Dual ASF / GPL licensing.
See the LICENSE.txt file for details about your rights and obligations with respect to the software, plus legal disclaimers, and so forth.
Upgrading from Melati Alpha Software
Please follow the Installation instructions.