Cleaning Old Makumba Application Code
This document is intended to providea guide to developers that want to
cleanup code by taking advantage of latest mak features.
This
version is a paste from an e-mail dating Jan 6th 2005, which itself
contained a forward from an email from mid 2004. It may not be
entirely up-to-date but it may be worth updating.
Since 0.5.14
- search is more supported (bug 63)
- the form orderBy="label.$fieldName" will change to
label.#{fieldName}, etc (bug 786)
- complex chosers containing scriptlets should be replaced with
mak:option (bug???)
- scriptlet code that limits mak:list iterations should be replaced by
limit= and offset= (bug???)
Since 0.5.11 (or stuff that should have been there anyway) are
- bug 25 (count(*) instead of <mak:list .../>)
- JSTL/EL.
- mak:count(), mak:lastCount(), mak:maxCount()
- mak:list and query offset and limit (bug 55, 57)
- mak:option (bug 59, 60)
***********
Karamba, the flagship Makumba app was mostly written using makumba
0.5.3. since then then we added a lot of features that are used at
present. karamba is still full of workarounds for these features or
bugs. such workarounds are dangerous for new BEST programmers, since
they learn a lot by example from existing code. using the new makumba
features will lead to much cleaner code => easier to follow by the
newcommers.
new features typically replace java code. so whenever you see <%
java scriptlets %> in JSP pages or complicated/long methods in the
business logic, you should start becoming suspicious and wonder if the
respective problem can't be solved with new makumba features or simply
using a formerly buggy makumba feature. if not, try to see if the
problem is an unfixed bug, especially a bug targeted 0.6. please group
these problems and add them to makumba's bugzilla. please try to
specify which of these bugs are most important for BEST, to give
priorities to the makumba development process.
here are the main improvements since 0.5.3 (the numbers show the
bugzilla entries for those interested). if i forget some, please
correct me. do note that _loads_
of _bugs_ (i.e. not new features) were fixed
by dedicated volunteers like Stefan and Fred. Adler also helped. thanks
to all.
- (3, 4) many BL methods (only) do uniqueness tests (such tests were
not even correct: in another thread, some other user may insert
precisely the same value). instead, the "unique" MDD keyword can be
used, and the uniqueness test is done automatically in the DB rather
than at java level. this feature may still need improvement to ensure
the right experience for the user. try it out.
don't forget to set alter#typeName=true when you set a field to unique
in typeName.mdd; follow the log output and see that a new index is
created, after that, remove the alter# directive!
mind you, for now only individual fields can be made unique (513)
- (48) some very complicated BL methods (many written by Fred in
Johnny) try to achieve synchronization between concurrent
accesses. since 0.5.10, all BL is executed in separate transactions
("transaction isolation" which usually provides synchronization), so
this problem is gone away. it's high time to review such code.
- (48) if you still need synchroniztion, makumba now offers named
locks. you can lock a symbol using org.makumba.Database#lock(String),
and as long it's locked, all simmultaneous accesses that want to lock
it will block. you can unlock it explicitely, or it will unlock when
your BL method finishes (with or without error), or when you use
close() your db object. this is similar to ordinary java locking
(Object#wait() and Object#notify()) but unlike java locking, it works
across java virtual machines (JVMs) that access the same makumba
databases.
- (62) mak:if can replace a lot of Java <%if( )%>. mind you, the
expression of mak:if will be evaluated _in_the_database_.
that's very good if you are making comparisons between values in the
database and/or constants. if you are, however, testing java variables
declared in the page, keep using java if(), but do ask yourself if a
makumba feature could help eliminate that
- lots of mak:forms have action=<%=java expression %> . that ugly
detour into java can be eliminated using <mak:...form...>
<mak:action> compose the action </mak:action> ...
</mak:form>
- (37) mak:...form can now include other mak:...form's ("multiple
forms"), resulting into very complicated actions that can be taken by
your page. all these little actions are executed together, in a single
transaction, so they only make sense together (if one produces error,
the effect of all others is cancelled). this can eliminate a lot of JSP
scriptlets, Javascript and Java business logic.
look at the present johnny evaluation and compare with the multiple
form version...
http://tallinn.best.eu.org/cristi/MF.jsp
http://tallinn.best.eu.org/cristi/MFedit.jsp
- (17, 371, 372, 375, 451) mak:input has a much more powerful value= as
follows:
* "new" means the OQL label "new". if the mak:input is not inside a
mak:list/object, this makes no sense.
* "$new" is an attribute (not really OQL syntax, but makumba JSP-OQL
syntax).
* "\'new\'" is a string constant. value="'new'" also works
* "\'2003-03-28\'" is a date constant. value="'2003-03-28'" should also
work
* "0" is an integer constant
* "nil" is the OQL null value
all of the above can be combined into OQL expressions ("new=nil" will
be an int, boolean-like expression, "\'2003-03-28\'<\'2003-03-29\'"
will be an int of value 1
- mak:input supports new attributes like default=, empty= (572, 501).
choices can now be presented as lists or radio buttons, etc (585)
- in general, lots of bugs were fixed on forms and inputs. if you see a
form that contains lots of scriptlets, or a place where a html <form
> or a generic <mak:form> is used instead of
<mak:new/add/edit Form > (though it does a DB operation in the
end), please become suspicious and try to do it again the "clean" way,
eliminating scriptlets, reducing business logic code (eventually also
using multiple forms described above)
- (28) int{"name1"=1 "name2"=2 } now supports deprecation of some
alternatives. when deprecated, they won't be shown in newForms so new
records with that value won't be created.
- (601) int{"name1"=-1 "name2"=2 } negative values allowed
- (544) makumba now supports @include. if you want to repeat the same
piece of code across many pages, it is ideal. for example, suppose two
mak:lists below use the same labels, a, b, c, of the same types (A.mdd,
B.mdd, C.mdd). then they can @include the same body that has
mak:value's using a, b, and c. unlike when using jsp:include, the
@include-d page cannot be executed on its own! however, you can't do
the above code repetition (two mak:lists that include the same body)
with jsp:include
@include is also handy when you want to use two kinds of forms (e.g. a
newForm and an editForm) that have the same content (mak:input's and
all).
the above MF.jsp and MF.edit.jsp can use common, @include'd code, to
display the form fields
http://tallinn.best.eu.org/cristi/MF-include.jsp
http://tallinn.best.eu.org/cristi/MFedit-include.jsp
the included file:
http://tallinn.best.eu.org/cristi/MFfields.jsp
do note that @include (textual inclusion) is in a way a step back as a
programming paradigm, yet there is no alternative in makumba today
(since this stuff can't be done with jsp:include). the included pages
really make no sense without the pages that include them, and make no
reference to them (there is no "contract" between the two). e.g.
MFfields above should be able to specify "i can only be included in a
<mak:...form> that creates or edits data of the type
general.survey.Response".
finally, note that in some simple cases (e.g. HTML-only JSP)
jsp:include and @include are interchangeable. @include is faster,
though jsp:include was recommended up to now. you will have to test
@include more before changing that recommendation
- (430) float (real) type is now supported
- (101) you now have much more HTML CSS and javascript power in the
mak:tags by being able to use class= id= onSubmit=, etc (i.e. most
standard attributes supported by HTML)
- mak:value now supports maxLength= (449), default= (572), empty= (501)
(default and empty do not yet accept OQL expressions)
- (41) you may find that orderBy="label.$someArgument" works better
now. some pages may want to sort information by different columns,
depending on a certain CGI argument. there used to be problems with
that (though it worked) in makumba. see http://bugs.best.eu.org/show_bug.cgi?id=41
. please try to avoid making 2 JSPs only because you need to sort in
two ways, and the rest of the page is the same. if that can't be
avoided, please give input to bug 41 and say why/how, and at least use
@include to avoid repeating code, because if you repeat code, you'll
have to fix it twice (or more times)
- (93) org.makumba.copy was fixed (had been long broken since some
0.5.3) and can be used to copy from a mak database in any format
supported (mysql, informix, db2, odbc, etc), to another mak database.
similar fixes were done for for org.makumba.delete and
org.makumba.db.open (which checks whether the physical DB corresponds
to the MDDs)
- (34) mak:logout now support wildcard (*). that logs out every actor
who logged in in the session (lbg, member, johnny student, etc)
- (557) mak:list/object header= and footer= will _not_ be supported anymore. please
remove them (use jsp:include or @include instead)
******
some advice:
- (444) choose carefully when to use UnauthenticatedException (no
rights) and when to use UnauthorizedException (no good password)
- (351) whenever you create a org.makumba.Database object, make sure
you close() it in a finally{} block
******
two ugly workarounds are present in many pages and not needed anymore
(indeed, they are not _desirable_):
- (6, 36, 85, etc) workarounds for "first-makumba-tag" (fixed since
0.5.6)
you will see a lot of <mak:attribute... "dummyFirst"
..."dummyMak"/> . they are obsolete. take them away. the only effect
that they have left is to puzzle newcomers.
- (5, 384, etc) workarounds for "first-load-errors" (fixed since 0.5.7)
you will see a lot of instanceof tests in the karamba JSPs. they are
obsolete. take them away. a <mak:value printVar /> will always
have type String, and a <mak:value var /> will always have the
Java type that corresponds to the respective makumba type
(java.lang.Integer for OQL int, java.util.Date for OQL date, etc). most
null tests are also obsolete, especially if the field is not null in
the mdd
*********
become suspicious when you see pageContext.setAttribute,
pageContext.getAttribute, pageContext.findAttribute,
request.get/setAttribute, session.get/setAttribute.
either the thing can be done in a simpler way (see example below) or
there is a need for some makumba feature.
for example, the right way to use a countVar is
<mak:list ... countVar="cnt" >
<% int count= cnt.intValue(); %>
...
and not
<%int count=
((Integer)pageContext.findAttribute("cnt")).intValue()); %>
that is, mak:list countVar is always an Integer, so is maxCountVar.
mak:value printVar is always a String. mak:value var= is an Object and
that will need casts to more specialized classes (see bug 718)
so: become suspicious when you see casts in karamba JSPs :) . if the casted
variables were defined with countVar, maxCountVar or printVar, the cast
is most probably useless. if the cast is used to read a page, request
or session attribute, the whole attribute usage is questionable.
what's more, when you will upgrade to Java 1.5 (presently in beta 2),
you will be able to transparently use Integers as ints, so in the
example above you can use cnt directly, no need for count.