The Melati Project

Release Notes

last updated 2015/06/20 - timp

Release 0.7.9

Release 0.7.9

2015/06/20


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

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


Release 0.55.6

Release 0.55.6

01/03/2002


Release 0.55.5

Release 0.55.5

15/02/2002


Release 0.55.4

Release 0.55.4

17/12/2001


Release 0.55.3

18/09/2001


Release 0.55.2

17/08/2001


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

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

 


 

Release 0.54.1

20/06/2001

 


 

Release 0.54

11/06/2001

WebMacro 0.97

  1. 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.
  2. 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)
  3. 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.
  4. 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.

  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.
  2. 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

 


 

Release 0.53.5

23/03/2001

0.53.5 introduces the following changes.

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.

This release patches the memory problems experienced with Webmacro previously.

 


 

Release 0.53.3

26/02/2001

0.53.3 introduces the following changes.

Please 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.

 

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 directory

FormDataAdaptorFactory - 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:

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:

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.

 

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:

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:

 

 

Warning

 

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

 

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:

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.