Constants in Java

Java language has a reserved word const intended for future use. However this keyword was never implemented and has no function. The original intent of the const keyword was to implement readable only references (which means a const reference cannot be used to modify object instance). However Java language designers decided NOT to implement this keyword.

Java however supports read only references using the final keyword. When you declare a variable as final, the variable itself cannot be reassigned to point to another instance. The default coding standard in Java for constants is to use upper case words separated with underscores.

Usually Java programmers define all the constants in the program in a single interface as public static final variables. However this is considered as a bad practice.

public interface MyConstants {

    public static final int NUMBER_OF_MONTHS = 12;
    public static final String DATE_FORMAT = "dd/mm/yyyy";
}

The variable is public so that it can be accessed from anywhere. It is static so that it can be accessed without an instance. It is declared as final and hence the value cannot be changed.

A better approach to defining constant values is to define it in the class which is the most suitable location for the constant. For example, the above interface can be removed and the constants can be moved to its appropriate classes,

public class MyCalendar {
    public static final String DATE_FORMAT = "dd/mm/yyyy";
    // Other Calendar data and methods here
}

An important thing to note here is that final  indicates that the variable cannot be assigned to another instance. However you can modify the instance itself. The final keyword doesn't make the object instance immutable. The following code is perfectly valid,

public static final Circle MY_CIRCLE = new Circle(5);

public static void main(String[] args){
    MY_CIRCLE.radius = 10;  // final instances are mutable
}

 

Using Enums as Constants

Java 5 (1.5) and above supports enumerators and it can be used for defining constants. The following code fragment illustrates the use of Java enums for constant values,

// save in Color.java
public enum Color {
    BLACK, WHITE
}

// save in EnumTest.java
public class EnumTest {

    public static void test(Color c) {
        System.out.println(c);
    }
    
    public static void main(String[] args) {
        test(Color.BLACK);
    }
    
}

Recursively Listing Files in a Directory in Java

Using the File class in Java IO package (java.io.File) you can recursively list all files and directories under a specific directory. There is no specific recursive search API in File class, however writing a recursive method is trivial.

Recursively Listing Files in a Directory

The following method uses a recursive method to list all files under a specific directory tree. The isFile() method is used to filter out all the directories from the list. We iterate through all folders, however we will only print the files encountered. If you are running this example on a Linux system, replace the value of the variable rootFolder with a path similar to /home/user/.

import java.io.File;

public class FileFinder {

    public void listAllFiles(String path) {

        File root = new File(path);
        File[] list = root.listFiles();

        if (list != null) {  // In case of access error, list is null
            for (File f : list) {
                if (f.isDirectory()) {
                    System.out.println(f.getAbsoluteFile());
                    listAllFiles(f.getAbsolutePath());
                } else {
                    System.out.println(f.getAbsoluteFile());
                }
            }
        }

    }

    public static void main(String[] args) {
        FileFinder ff = new FileFinder();
        String rootFolder = "c:\\windows";
        System.out.println("List of all files under " + rootFolder);
        System.out.println("------------------------------------");
        ff.listAllFiles(rootFolder); // this will take a while to run!
    }
}

The return  value of listFiles() will be null if the directory cannot be accessed by the Java program (for example when a folder access requires administrative privileges). If you run it on the root folder in your file system, this program will take a while to run!

How to Get List of Files in a Directory in Java

Java IO package (java.io) provides class named File which is abstraction of file and directory names. This class provides an abstract, system independent view of path names. The following sample Java program prints a list of files and folders in a specified directory. The program also uses File attributes to indicate whether a directory entry is a file or a directory. Use the isFile() method to distinguish between files and directories.

If you are running this example on a Linux system, replace the rootFolder variable value with an appropriate path such as /home/user/.

Getting List of Files in a Directory in Java

import java.io.File;

public class FileDemo {

    public static void main(String[] args) {
        String rootFolder = "c:\\";
        File aFile = new File(rootFolder);
        System.out.println("Type      | Name");
        for(File file: aFile.listFiles()) { // Java 5 style for loop
            System.out.print(file.isFile()? "File     ":"Directory");
            System.out.print(" | ");
            System.out.println(file.getName() );
        }
    }
    
}
 

Note that listFiles() method returns everything including hidden files and folders. You can use the isHidden() method to check whether a file or folder is hidden in the file system. You can also use the File class to create directories, rename files/folders or to delete files and folders.

Since Java 7, java.nio.file package provides better handling of file systems and file attributes. If you are supporting Java 7 and above only use this package as it is more reliable.

Writing a Struts 2 Plugin

Struts 2 has built-in support for plugins which can extend the core framework functionality. Plugins can potentially add, replace or extend Struts 2 functionality. Whenever you want to share a set of reusable components across multiple Struts 2 Web applications, it is better to package them as plugins.

Usually Struts 2 plugins are packaged as Jar files and is dropped into the Web application's library folder (WEB-INF/lib). Struts 2 plugins usually contain a configuration file named struts-plugin.xml. Struts 2 framework scans all the jar files looking for struts-plugin.xml and if it finds one, automatically configures and executes the plugin features. Struts 2 plugin can contain actions, interceptors, results, resources and javabeans.

The structure of struts-plugin.xml is similar to Struts 2 configuration file, struts.xml. Hence a Struts 2 plugin has the capability to define results, interceptors etc. The order of execution of configuration files in Struts 2 is,

  • struts-default.xml (core framework configuration)
  • struts-plugin.xml (multiple files since there could be multiple plugins used in the project)
  • struts.xml (application level configuration)

Since struts.xml is executed after plugin configuration files, plugins may expose new features to struts.xml. It can also override most of the Struts 2 core implementation by replacing core classes.

A plugin can replace a core class by providing its own customized instance under pre-defined property names. For example, by overriding the struts.objectFactory property, a plugin can provide a custom version of com.opensymphony.xwork2.ObjectFactory. See the official page for a complete list of extension points/classes in Struts 2.

It is possible to embed static content in a Struts 2 plugin jar. All the static files added under a folder "static" is available through the URL path /struts.  So if you jar has /static/main.js, you can access it through the URL - /struts/main.js.

Writing a Struts 2 Plugin

This is a step by step tutorial on writing a Struts 2 plugin. In this example, we will write a plugin which automatically defines a new xml result type. Whenever the xml result type is used, the action member variables will be automatically converted into an xml file.

We will be using NetBeans for creating the Struts 2 plugin project. We will also need a Struts 2 web application up and running in NetBeans for testing our plugin. We will modify the Hello World application written earlier (this project needs to be renamed as Struts2PluginClient) as our testing Web application. Hence we will be working with two projects in NetBeans,

  • Struts2-XML-Plugin - This is the Struts 2 plugin project and it provides a new result type "xml". If the result type is configured as xml, the response received from the request will be an XML corresponding to the member variables of the action class invoked. This implementation is only a demo and is not intended for production use.
  • Struts2PluginClient - Simple Struts 2 Web application for testing our plugin. We would change the result from the JSP to the "xml" type to get the "Hello World!" message in an XML file!

Creating Struts 2 Plugin Project in NetBeans

A Struts 2 Plugin project is just like any other Java class library. From NetBeans, click on File => New Project and select Java Class Library as shown below. Click on Next.

Creating Struts 2 Plugin Project in NetBeans

Enter the name of the project as Struts2-XML-Plugin and click on Finish.

Creating a Struts 2 Plugin

From the projects tab, right click on Libraries folder and then click on Add JAR/Folder as shown below,

Adding dependency jars to Struts 2 plugin project

Add the following jar files from the Struts 2 distribution zip file (see this article for details on downloading Struts 2 distribution file).

  • Required libraries in Struts 2 Plugin projectstruts2-core-2.3.1.2.jar
  • ognl-3.0.4.jar
  • xwork-core-2.3.1.2.jar
  • freemarker-2.3.18.jar

Right click on Libraries and then click on Add Library. From the Global Libraries list, add Java EE 6 API Library. This reference is required for compiling our plugin since we would be using servlet classes such as HttpServletRequest.

Now we have the plugin project ready for development. For this plugin project we need the following components,

  • struts-plugin.xml - This will configure a new result type "xml".
  • XMLResult.java - This will implement the XML result type. This class will implement the com.opensymphony.xwork2.Result interface.

struts-plugin.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="xml-default" extends="struts-default">
        <result-types>
            <result-type name="xml" class="com.quickprogrammingtips.demo.XMLResult"/>
        </result-types>
    </package>
</struts>

We have added a new package xml-default which defines a new result type for "xml". Whenever a result of type of xml is configured, it is rendered by the XMLResult class.

XMLResult.java (Result handler for xml type)

XMLResult implements the Result interface and hence can be used as a view renderer. In the execute() method we use reflection to get the message from action class and then create the corresponding XML file.

package com.quickprogrammingtips.demo;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.StrutsStatics;
public class XMLResult implements Result{

    @Override
    public void execute(ActionInvocation ai) throws Exception {
        Object action = ai.getAction();
        ActionContext actionContext = ai.getInvocationContext();
        HttpServletResponse response = (HttpServletResponse) actionContext
                .get(StrutsStatics.HTTP_RESPONSE);
        
        Class cls = action.getClass();
        Method meth = cls.getMethod("getMessage", null);
        Object m = meth.invoke(action, null);
        
        Class cls2 = m.getClass();
        Method meth2 = cls2.getMethod("getMessage", null);
        Object m2 = meth2.invoke(m, null);
        response.getWriter().print("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
        response.getWriter().print("<xml>"+m2+"</xml>");
        
    }
    
}

Note that currently XMLResult is hardcoded to return getMessage().getMessage() from action class. In a real plugin, we should use the reflection recursively on the action class to generate the XML file.

Struts 2 Plugin and Web projects in NetBeansCreating a Plugin Client Web application in NetBeans (Struts2PluginClient)

Follow this tutorial to create the Struts2PluginClient project (rename Struts2Demo to Struts2PluginClient) in NetBeans. Right click the Libraries folder in the Struts2PluginClient Web application and click on Add Project. Select Struts2-XML-Plugin project. This creates a plugin project dependency on the Web application and latest plugin code will be deployed as a jar file in the client Web application.

Once both projects are configured, your NetBeans projects tab should like the one on the right side picture.

We need to modify the struts.xml so that xml result type is invoked instead of dispatching to JSP,

struts.xml (Struts 2 configuration)

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="struts2demo" extends="xml-default">
        <action name="HelloWorld" class="controller.HelloWorld">
            <result name="success" type="xml"></result>
        </action>
    </package>
</struts>

Note that the result type is set as xml. Also note that the package now extends from xml-default instead of struts-default.

HelloWorld.java (action class)

package controller;

import com.opensymphony.xwork2.ActionSupport;
import model.Message;

public class HelloWorld extends ActionSupport {
    private Message message;
    
    @Override
    public String execute() {
        setMessage(new Message()); // get data from model
        return SUCCESS;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }
    
}

 

Message.java (model)

package model;

public class Message {
    private String message = "Hello World!";

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <display-name>Struts2 Demo App</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>    
</web-app>

To test the plugin, Run the Struts2PluginClient application (F6) and then invoke the HelloWorld action class using the following URL,

http://localhost:8084/Struts2PluginClient/HelloWorld.action

You should see the XML output on the browser window,

Struts 2 Plugin Example

A zip file containing both the projects can be downloaded from here. Please note in order to keep the download size small, I have removed Struts 2 jars from the zip file. You need to download them from the Struts2 repository.

Palindrome Program in Java

A string is called a Palindrome if it is spelled the same forward and backward. Following are some examples of palindrome strings,

Madam, Noon, Rotor, Rotator, Radar, Malayalam

Checking whether a string is palindrome or not is a common programming assignment given to programmers learning a new language.

Checking Whether a String is a Palindrome in Java

The following Java program checks whether a given string is a palindrome or not. There are various ways to program this. In this example we will first reverse the string and then check whether the string is equal to the original string.

public class PalindromeChecker {

    public static void main(String[] args) {
        String string_to_check="rotator";
        if(isPalindrome(string_to_check)) {
            System.out.println(string_to_check+" is a palindrome");
        }else {
            System.out.println(string_to_check+" is NOT a palindrome");
        }
    }
    
    public static boolean isPalindrome(String s) {
        
        String reverse="";
        for(int i=s.length()-1;i>=0;i--) {
            reverse = reverse+s.charAt(i);
        }
        if(s.equalsIgnoreCase(reverse)) {  // case insensitive check
            return true;
        }else {
            return false;
        }
    }
    
}

A number is called a Palindrome number if the number remains the same when digits are reversed.

Checking Whether a Number is a Palindrome in Java

The following Java program checks whether a given number is a palindrome or not. In this example we first convert the number to a string. Then we check whether the reversed string is same as the original.

public class PalindromeNumberChecker {

    public static void main(String[] args) {
        int number_to_check=1001;
        String s = String.valueOf(number_to_check);
        if(isPalindrome(s)) {
            System.out.println(number_to_check+" is a palindrome number");
        }else {
            System.out.println(number_to_check+" is NOT a palindrome number");
        }
    }
    
    public static boolean isPalindrome(String s) {
        
        String reverse="";
        for(int i=s.length()-1;i>=0;i--) {
            reverse = reverse+s.charAt(i);
        }
        if(s.equalsIgnoreCase(reverse)) { 
            return true;
        }else {
            return false;
        }
    }
 
}

Another way to check for palindrome numbers without converting them to strings is given below. In this example, we convert the number to the reverse number and then check whether they are same.

public class PalindromeNumberChecker2 {

    public static void main(String[] args) {
        int number_to_check=882;
        if(isPalindrome(number_to_check)) {
            System.out.println(number_to_check+" is a palindrome number");
        }else {
            System.out.println(number_to_check+" is NOT a palindrome number");
        }
    }
    
    public static boolean isPalindrome(int n) {
        
        int reverse_number = 0;
        int original_number = n;
        while(n > 0) {
            int digit = n % 10;
            reverse_number = reverse_number * 10 + digit;
            n = n / 10;
        }
        if(original_number == reverse_number) {
            return true;
        }else {
            return false;
        }
    }
    
}