ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Using the Singleton Pattern
Pages: 1, 2

Using the StringManager Class

The following example demonstrates how to use StringManager from an application to support localized error messages in English and German. The application takes two numbers from the user and shows the result of addition of the numbers. The commands and result are displayed in either English (the default) or German. The application consists of two packages: myPackage1 and myPackage2. Listings 3 and 4 show the LocalStrings.properties and LocalStrings_de.properties files in myPackage1.



Listing 3. The LocalStrings.properties file in myPackage1

promptInput=Please enter 2 numbers which are smaller than 100.
firstNumberRequest=Enter the First Number.
secondNumberRequest=Enter the Second Number.
invalidInput=Please type in a number.
result=Result

Listing 4. The LocalStrings_de.properties file in myPackage1

promptInput=Tragen Sie bitte 2 Zahlen die sind kleiner als 100 ein.
firstNumberRequest=Tragen Sie die Erste Zahl ein.
secondNumberRequest=Tragen Sie die Zweite Zahl ein.
invalidInput=Bitte tippen eine Zahl ein.
result=Ergebnis

The LocalStrings.properties and LocalString_de.properties in myPackage2 are given in Listings 5 and 6, respectively.

Listing 5. The LocalStrings.properties file in myPackage2

smallNumbersOnlyWarning=One of the numbers is more than 100

Listing 6. The LocalStrings_de.properties file in myPackage2

smallNumbersOnlyWarning=Eine der Zahlen ist mehr als 100.

The main class in this application is myPackage1.Test1, given in Listing 7.

Listing 7. The myPackage1.Test1 class

package myPackage1;

import java.io.*;
import org.apache.catalina.util.StringManager;
import myPackage2.Adder;

public class Test1 {
    int a, b;

    protected static StringManager sm =
        StringManager.getManager("myPackage1");

    public void getInput() {
        System.out.println(sm.getString("promptInput"));
        InputReader inputReader = new InputReader();

        a = inputReader.getFirstNumber();
        b = inputReader.getSecondNumber();
    }

    private int add() {
        Adder adder = new Adder();
        return adder.addSmallNumbers(a, b);
    }

    public void printResult() {
        System.out.println(sm.getString("result") + " : " + add());
    }

    public static void main(String[] args) {
        Test1 test = new Test1();
        test.getInput();
        test.printResult();
    }
}

First note the sm variable reference that gets an instance of StringManager:

protected static StringManager sm =
    StringManager.getManager("myPackage1");

The main method instantiates the class and calls the getInput method and the printResult method. The getInput method instantiates the InputReader class in myPackage1 and calls its getFirstNumber and getSecondNumber methods. The InputReader class in listed in Listing 8.

Listing 8. The myPackage1.InputReader class

package myPackage1;

import java.io.*;
import org.apache.catalina.util.StringManager;

public class InputReader {
    protected static StringManager sm =
        StringManager.getManager("myPackage1");

    public int getFirstNumber() {
        int input = 0;
        boolean inputValid = false;

        while (!inputValid) {
            System.out.println(sm.getString("firstNumberRequest"));
            try {
                BufferedReader userInput = new BufferedReader(new
                    InputStreamReader(System.in));
                input = Integer.parseInt(userInput.readLine());
                inputValid = true;
            }
            catch (Exception e) {
                System.out.println(sm.getString("invalidInput"));
            }
        }

        return input;
    }

    public int getSecondNumber() {
        int input = 0;
        boolean inputValid = false;

        while (!inputValid) {
            System.out.println(sm.getString("secondNumberRequest"));
            try {
                BufferedReader userInput = new BufferedReader(new
                    InputStreamReader(System.in));
                input = Integer.parseInt(userInput.readLine());
                inputValid = true;
            }
            catch (Exception e) {
                System.out.println(sm.getString("invalidInput"));
            }
        }

        return input;
    }
}

The InputReader class also has a variable reference to an instance of StringManager. Both the getFirstNumber and getSecondNumber methods use the following code to obtain user input:

BufferedReader userInput = new BufferedReader(new
    InputStreamReader(System.in));
input = Integer.parseInt(userInput.readLine());

In the getFirstNumber method, the following line of code is used to prompt the user to enter the first number:

System.out.println(sm.getString("firstNumberRequest"));

If the user entered an invalid input, the following line prints an error message:

System.out.println(sm.getString("invalidInput"));

The printResult method in the Test1 class instantiates the Adder class in myPackage2 and calls its addSmallNumbers method. The Adder class is given in Listing 9.

Listing 9. The myPackage2.Adder class

package myPackage2;

import org.apache.catalina.util.StringManager;

public class Adder {
    protected static StringManager sm =
        StringManager.getManager("myPackage2");

    public int addSmallNumbers(int a, int b) {
        if (a>100 || b>100) {
            // print warning
            System.out.println(sm.getString("smallNumbersOnlyWarning"));
        }

        return a + b;
    }
}

Again, this class has the reference to an instance of StringManager.

protected static StringManager sm =
    StringManager.getManager("myPackage2");

This time however, the getManager method gets myPackage2 as the argument; therefore, a different instance of StringManager is used than the one in the myPackage1.Test1 and myPackage.InputReader classes. The addSmallNumber method will print a warning if one of the two arguments passed into it is greater than 100:

System.out.println(sm.getString("smallNumbersOnlyWarning"));

Now, run the myPackage1.Test1 class. If your computer's language setting is English or a language other than German, here is what you should see on the console after entering one number, one non-number, and another number:

Please enter 2 numbers which are smaller than 100.Enter the
First Number.120

Enter the Second Number.3r

Please type in a number.Enter the Second Number.3

One of the numbers is more than 100Result : 123

If your computer setting uses German as its language, here is the result:

Tragen Sie bitte 2 Zahlen die sind kleiner als 100 ein.Tragen
Sie die Erste Zahl ein.120

Tragen Sie die Zweite Zahl ein.3r

Bitte tippen eine Zahl ein.Tragen Sie die Zweite Zahl ein.3

Eine der Zahlen ist mehr als 100.Ergebnis : 21123

Summary

The Singleton pattern is used to limit an instance of a class to one by creating a private or protected constructor. You have learned a simple example of the Singleton pattern in the SingletonFrame class. In other uses, you can also use the Singleton pattern to restrict the number of instances of a class to n. In this case, you need a way to maintain the instances. A real-world example given is the StringManager class in Tomcat. You have also seen how to use this class from your application.

Budi Kurniawan is a senior J2EE architect and author.


Return to ONJava.com.