Saturday, February 28, 2009

Get Week and Month names in Java

More and more applications these days are becoming global. Globalized applications are usually multilingual. Most applications need somewhere a calendar input.The web offers a lot of calendar solutions. These solutions usually allows passing to the calendar information regarding the day and month names. This data can be easily extracted by Java without needing to maintain resources list for all desired languages.

The class that holds all this information is named: DateFormatSymbols. This class accepts the Locale as a parameter. The Locale will determine the language in which the week and month information will be shown.

Here is an example of how to get week names:

public static String[] getShortWeekDays(Locale locale)
{
  String[] weekDays = new DateFormatSymbols(locale).getShortWeekdays();
  String[] retWeekDays = new String[7];
  System.arraycopy(weekDays, 1, retWeekDays, 0, 7);
  return retWeekDays;
}
Note, that the first element in the array was ignored. Java returns the first item as empty, and the actual values are starting from index 1. That is to be correlated with Calendar.SUNDAY which returns the number: 1 rather than: 0. If you will want in some way to do: weekDays[Calendar.SUNDAY], it was smarter to leave the original array untouched.

In the same way it is very simple to get long week days:

String[] weekDays = new DateFormatSymbols(locale).getWeekdays();

Getting the short month names:
public static String[] getShortMonths(Locale locale)
{
  String[] months = new DateFormatSymbols(locale).getShortMonths();
  String retMonths[] = new String[12];
  System.arraycopy(months, 0, retMonths, 0, 12);
  return retMonths;
}

This time the returned original array starts from index: 0, but has an additional last empty element. This code fixes this issue, by ignoring the last element. In months Java has chosen to start the index from: 0 and in weeks from: 1. This is a bit inconsistent, and I believe that there will always be someone that can give a long speech for what were the reasons for choosing this way.

Anyway, here is a simple example application that outputs week and month names in both short and regular formats in US Locale:

public static void main(String[] args) {
  System.out.println(Arrays.toString(getShortWeekDays(Locale.US)));
  System.out.println(Arrays.toString(getLongWeekDays(Locale.US)));
  System.out.println(Arrays.toString(getShortMonths(Locale.US)));
  System.out.println(Arrays.toString(getMonths(Locale.US)));
}

And here is the output for this code:
[Sun, Mon, Tue, Wed, Thu, Fri, Sat]
[Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
[Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
[January, February, March, April, May, June, July, August, September, October, November, December]

Sunday, February 22, 2009

RichFaces new TinyMCE Editor

JSF RichFaces released a new HTML/Rich Text editor on their latest version (3.3).Frankly, it is about time… It definitely took them a while. But better later than never…

The editor is a wrapper for the JavaScript WYSIWYG editor open source project.

Using the editor is very simple, assuming your project already using JSF RichFaces:

<rich:editor id="article" width="700" height="400"
    value="#{myBean.text}" required="true">
</rich:editor>


It is also possible to control the editor properties in the same manner TinyMCE editor is manipulated, buy simply adding editor specific properties. For example, in order to position the toolbar on the “top” and align the buttons to the left:

<rich:editor id="article" theme="advanced" viewMode="visual"
  width="700" height="400" value="#{myBean.text}" required="true">
  <f:param name="theme_advanced_toolbar_location" value="top" />
  <f:param name="theme_advanced_toolbar_align" value="left" />
</rich:editor>

Monday, February 16, 2009

Sending Email alerts with Log4j - SMTPAppender

Log4j is a great open source logging framework. It offers easy, modular and extensive way of adding logging capabilities to your application. But, the truth is, I don’t really like log files. I prefer the task of analyzing thousands lines of logs as last option. I always prefer to know about problems as soon as they happen. The sooner the better… Luckily, log4j supplies out of the box Appender for sending email alerts. If you use log4j in your application. You can easily configure log4 to send email alerts for all your error level errors.
By default mails are sent only for error level logs, but if you insist you can configure it to lower level logs (it is not a good idea doing this. You don’t want your application to start sending tons of emails…). The Appender used for sending mail is called: org.apache.log4j.net.SMTPAppender
Note that older versions of log4j may not have this Appender.
This is a typical properties file adding SMTPAppender:
log4j.rootLogger=INFO, a, email
log4j.appender.a=org.apache.log4j.ConsoleAppender
log4j.appender.a.layout=org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern=%d{HH:mm:ss} %-5p [%c{1}]: %m%n
log4j.appender.email=org.apache.log4j.net.SMTPAppender
log4j.appender.email.BufferSize=10
log4j.appender.email.SMTPHost=mysmtp.mailserver.net
log4j.appender.email.From=admin@mycompany.com
log4j.appender.email.To=me@mycompany.com
log4j.appender.email.Subject=My Module Error
log4j.appender.email.layout=org.apache.log4j.PatternLayout
log4j.appender.email.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n

Don’t forget that in order to send mail using java you will have to add: mail.jar and activation.jar to your class path.
The nice thing in this Appender is that you can send email alerts containing more than just your Exception. You can also add lines that were logged before the exception. This will make it much easier to understand the cause of your exception. The number of log lines that will be sent can be determine by “BufferSize” property. For example: if BufferSize=10, then your email will also contain the 9 lines logged before the exception.
If your SMTP mail server is not on the same network of your server, you would probably won’t be able to send emails without authentication. You can easily overcome this problem by simply adding username and password properties:
log4j.appender.email.SMTPUsername=myusername@mycompany.com
log4j.appender.email.SMTPPassword=mypassword

Note that also here, older versions of log4j may not have support for “username” and “password” properties.
That’s it. you can now check you mail box. You should be able to get email alerts every time an exception is logged on your application. You can also make a fake test to your configuration. This will make it easier to see how your mail will look:
log.info("some fake info");
try
{
throw new Exception("some fake exception");
}
catch (Exception e)
{
log.error("Fake exception occurred", e);
}

I found only one disturbing this with this Appender: It doesn’t send the mail on a different Thread. This causes the the current thread to be stuck for a second when sending mail. I don’t find it as a big problem, since usually Exceptions don’t happen much often (at least on production environments where this Appender will mostly be used). But once such exception happens and it is being repeated in a loop, the system may hang and unpleasant things might happen. On the other hand, sending the mail on a different Thread won’t cause the current thread to be stuck, but may flood the system with big amount of mails.