Adept Open Source Library

This is a blog to provide in-depth information on the Adept open source library - the core of which is a Java object database component. In addition there is lots of Java code and solutions for many development problems.

http://marringtons.com

Friday, July 29, 2005

Message - Server to User Communications

What happens when a user fills in a form and presses the submit button? If all goes well he will move on as expected. But what if the data in the form is not adequate to the task? Perhaps a field was not filled in, or business logic dictates that the answers do not match. The server code needs to stay on the same form and give meaningful messages.

Enter the Messages class. It is designed to be used by the SOA tier, although in truth it can be used at whichever layer knows enough to be able to give the user meaningful feedback. The user does not want to be confused by being told that idxdb43a has a duplicate entry. They want to be told that they have already registered and should type in their password.

Generally messages are created by the validation code and business logic. Sometimes, as above, the business tier creates a message based on an error reported by a more technical tier.

Retrieving the Message List

Messages that relate directly to the converstation between user and machine can be retrieved with the getThreadInstance() method. A conversation interchange between browser and server runs on a single thread. The thread message instance is cleared as soon as the browser communicates to the server. Messages are collected here during server processing. Once complete the messages are sent to the browser as part of the response.

Messages can also be held in the session and retrieved with getSessionInstance(). Used to collate messages from non-interactive threads with information for the user. A classic example is an alarm or countdown timer.

The Message Structure

Because I designed the message system for thin-client browser/server applications, messages needed a text based structure. Consequently a message consists of key and display parts separated by double colons (::).
key::this is the message portion to display

 

In the most basic form, you can add a message without a key. It is saved under the special global key of start (*). The following three add() statements are identical:
Messages messages = Messages.getThreadInstance();
messages.add( "This is a global message");
messages.add( "*::This is a global message");
messages.add( "*", "This is a global message");

 

Reporting Programming Errors

In many environments I have worked in it was common practice for programming errors and system problems to throw an exception that was then passed all the way back to the client. Said client then gets an generic error page and the thrown exception is written to the log. I do not consider this acceptable. All complex systems will generate unexpected errors and attempt to pass them back to the user. If these message are processed like any other, the user has the opportunity to work around the issue. Message in these curcumstances should include a key to be used by support staff to investigate the log. Messages does this with overloaded add() methods that take a Throwable argument. Since exception messages are less likely to be understood by a user, it includes an automatically generated reference to the log that support staff can use to track down the issue.
Device /dev/hd1 out of space (see log reference 20050722-21:44:53.531)

 

When to Generate a Message List

The Service or business tier needs to process a user request and send back the results for the user to read. If exceptions were to be used in their basic form, the user would get a single problem reported. Once this is fixed and the request submitted again the next problem is found and reported again. We have all worked with systems such as this - when we have to. They are very frustrating. It is far better to find and report on as many problems together. The user can then fix them in one pass also.

With Messages the code continues to work until it finds a problem that stops further processings. It then passes the menu structure back to the GUI tier for display. Actually it does not need to pass it since the GUI tier can also retrieve a reference using the static method getThreadInstance().

A typical service may work as follows:

Messages problems = Messages.getThreadInstance();
validateData( data):
if (! problems.none()) return;
applyBusinessRules( data);
if (! problems.none()) return;
writeResults( data);
if (! problems.none()) return;
commitAllProcessing();

 

Why Do Messages Have Keys?

When the messages are retrieved, they are sorted in key order with the message for a key being stored in a multi-line string in the order they were generated. The use for multiple keys is implementation dependant. It can be used to ensure that messages are sorted by priority, associated with fields, or both. The GUI, for example can cycle through the messages. Those with a key the same as an input field can be displayed beside that field while others can be listed in a special messages region. Since the general messages are sorted alphabetically, they can be given a numeric key with the highest priority having the lowest number. It would even be possible to assign different colours for different priority messages:
0: Urgent error message (typically system failure) - displayed in bright red.
1: Validation or similar error message - displayed in dark red.
2: Warnings - displayed in orange.
3: Informational messages - displayed in blue.

 

Note that these are examples only. Implementation is dependant on the user of the Message class.

How Messages are Retrieved

If keys are not used at all in the application, getGeneral() can be used to retrieve all the messages. Otherwise, firstKey() and nextKey() are used to retrieve each message group, with get() for retrieving the messages for the group.
for (String key = messages.first();  key != null;  key = messages.next())
  displayMessages( key, messages.get( key);

 

The messages retrieved by get() are an array of the messages. The array is in the order the messages were generated by the application.

Thursday, July 07, 2005

Fractions are Useful Too

Fractions are Useful Too

There was a time before floating point co-processors and built-in floating point arithmetic that some systems chose to hold real numbers as fractions.

The Advantages of Fractions

  1. Some numbers can be held more accurately as fractions. 1/3 cannot be accurately represented in floating point.
  2. All fractions that do not cause an overflow are accurate, whereas floating point is always an approximation. It's common, for example, to see a result of 0.999999999998 when the result should have been one. This is particularly true when passing the number around. Writing a floating point to a relational database and retrieving it again for comparison to the original value can return false. This is because the floating point representation may change inside different systems.
  3. The calculations are faster than floating point emulators. This advantage doesn't hold out against dedicated floating point hardware.
  4. It was very cool for numbers that could be displayed as a fraction. The human mind mostly finds it easier and quicker to visualise two and an eigth, as compared to 2.125.
  5. Some areas of use are more comfortable with fractions than decimals. Shares in a property or horse, for example, are commonly things like 1/3, 1/2 and 1/6.

The Disadvantages of Fractions

  1. Floating point holds a more limited representation. A Java long is only 19 decimal digits. This is still a big number. If a fraction were to represent microseconds, it would hold nearly 585 thousand years. If course if it were to represent nanoseconds, it would be limited to 585 years.
  2. All fractions that do not cause an overflow are accurate. Yes, this is a disadvantage also. Accuracy requires space. Each calculation can potentially increase the size of the denominator, thereby decreasing the largest number that can be held. 1/3 + 1/5 = 8/15. The largest possible number has now been reduced by 1/3. This is an implementation restriction that could be eradicated by having a separate whole part to fraction. A lot of the internal maths becomes more complicated and expensive, so I have chosen to keep the limitation.
  3. Fractions are not as fast as integers at arithmetic. To minimise the issues with lost maximum whole parts, each calculation reduces the fraction to the smallest it can be. 1/3 + 1/6 is kept as 1/2, not 3/6. It might be possible to make the Fraction class smarter and only do the expensive greatest-common-denominator when converting to a viewable string or when a calculation is at risk of overflowing.

The Fraction Class

The Fraction class is an immutable class for creating and manipulating fractions. Immutable means that once a fraction has been created it cannot be changed, operations create a new instance. So,
Fraction result
  = new Fraction( 1, 1, 2)
    .times( new Fraction( 2, 0, 0));

 

creates 3 instances of Fraction. Creating these fractions is non-trivial since the fraction is normalised as part of the operation. Don't be scared. Normalisation isn't that intensive, but it is well to be concious that any method call can take valuable CPU time. I believe that it's always a good idea to save data in a variable with a lifetime to match it's static nature. In the previous example, given that I may often want to multiply by 2, I would create a final static called two and create it only once.

Why Immutable?

There are very few uses for immutable classes outside of the primative wrappers provided in the standard library. Fractions are one of them. Here are the benefits:
  1. No synchronisation needed if used in threaded code. It can't change so it won't be changed accidentally.
  2. The internal data is private, so it can be open to the world for read access safely.
  3. They are safe from fiddly or unexpected side-effects.
Besides, an immutable class is easier to implement.

Creating a Fraction

The standard numerical constructor was shown before. It takes 3 long values for whole part, numerator and denominator. There is also a short form that just takes a whole number. Because whole numbers are used commonly and don't require normalisation, this becomes a good optimisation technique.

Fractions often come from text sources, so there's also a constructor that takes a string. It provides a more flexible way of representing a fraction. It can be a standard whole-numerator/denominator (i.e. 5-3/16). The whole part can be separated from the numerator by a space, a colon or a dash. String fractions can be decimal representations (as in 5.1875). Lastly, just for fun, it can be a percentage (10% == 1/10). With text entry comes the possibilty that the data cannot be interpreted as a fraction or decimal. In these cases, a public variable empty is set. If you want an exception, throw one. Since the fraction may be only part of the text, a public int is set to the next index in the string not used to build the fraction.

String fractionString = "1/3rd";
Fraction result = new Fraction( fractionString);
if (result.empty)
  throw new NumberConversionException(
    fractionString+" not a fraction");
String rest = fractionString.substring( result.after);
assertTrue( rest.equals( "rd");

 

The Greatest Common Denominator

The greatest common denominator is the largest integer that divides into both numbers without a remainder. Obviously it is useful in fractions as we have discussed above. It has other uses, too. Some PKI formulae use it. If the GCD (for short) is 1 then both numbers are relatively prime.
if (Fraction.greatestCommonDenominator( numerator, denominator) == 1)
 System.out.println(
   numerator+"/"+denominator+" are relatively prime");

 

Note that this is a static method so it can be used without generating a fraction.

Fractional Output

A Fraction instance has a toString() method that will display the fraction in the form W-N/D.
assertTrue( new Fraction( "1.5").toString()
  .equals( "1-1/2");
assertTrue( new Fraction( "24%").toString()
  .equals( "6/25");

 

It also has a toHTML() method that uses subscripts and superscripts to display a fraction. One and a half would display as 11/2 If you want to do anything else with the fractions, the numerator and denominator are public (if final).
// Display a fraction as a decimal value.
System.out.println(
  (Double) fraction.numerator
    / (Double) fraction.denominator);

 

Sorting and Maps

The Fraction class implements Comparable, equals() and hashCode(), so it can be used for sorting and as HashMap keys.

Fractional Maths

The Fraction class only implements basic math at this stage. It's all I've needed for dealing with shares.
  • negative()
  • inverse()
  • plus()
  • minus()
  • times()
  • divide()
So, if you need to play with fractions, this class is freely available in the Adept library at http://library.marringtons.com,