org.wso2.carbon.server.util.Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.server.util.Utils.java

Source

/*
*  Copyright (c) 2005-2012, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.server.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.server.LauncherConstants;
import java.io.*;
import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Utils {

    public static final String JAR_TO_BUNDLE_DIR = System.getProperty("java.io.tmpdir").endsWith(File.separator)
            ? System.getProperty("java.io.tmpdir") + "jarsToBundles"
            : System.getProperty("java.io.tmpdir") + File.separator + "jarsToBundles";
    private static File bundleBackupDir;

    static {
        File jarsToBundlesDir = new File(JAR_TO_BUNDLE_DIR);
        if (jarsToBundlesDir.exists()) {
            deleteDir(jarsToBundlesDir);
        }
    }

    public static String getCarbonRepoPath() {
        String carbonRepo = System.getenv("CARBON_REPOSITORY");
        if (carbonRepo == null) {
            carbonRepo = System.getProperty("carbon.repository");
        }
        if (carbonRepo == null) {
            carbonRepo = System.getProperty("carbon.home") + File.separator + "repository";
        }
        return carbonRepo;
    }

    public static File getCarbonComponentRepo() {
        String carbonRepo = Utils.getCarbonRepoPath();
        String carbonComponentsRepository = carbonRepo + File.separator + "components";
        File componentRepo = new File(carbonComponentsRepository);
        if (!componentRepo.exists() && !componentRepo.mkdirs()) {
            System.err.println("Fail to create the directory: " + componentRepo.getAbsolutePath());
        }
        return componentRepo;
    }

    public static void printUsages() {
        String osName = System.getProperty("os.name");

        System.out.println("Usage: wso2server." + ((osName.toLowerCase().indexOf("win") == -1) ? "sh" : "bat ")
                + " [command] [system-properties]");
        System.out.println();
        System.out.println("command:");
        System.out.println("\t--debug <port> \tStart the server in remote debugging mode."
                + "\n\t\t\tport: The remote debugging port.");
        if (osName.toLowerCase().indexOf("win") == -1) {
            System.out.println("\t--start\t\tStart Carbon using nohup in the background");
            System.out.println("\t--stop\t\tStop the Carbon server process");
            System.out.println("\t--restart\tRestart the Carbon server process");

        }
        System.out
                .println("\t--cleanRegistry\t\t\tClean registry space. [CAUTION] All Registry data will be lost.");
        System.out.println("\t--version\t\t\tWhat version of the product are you running?");
        System.out.println();
        System.out.println("system-properties:");
        System.out.println(
                "\t-DhttpPort=<httpPort>\t\tOverrides the HTTP port defined in the mgt-transports.xml file");
        System.out.println(
                "\t-DhttpsPort=<httpsPort>\t\tOverrides the HTTPS port defined in the mgt-transports.xml file");
        System.out.println("\t-DosgiConsole=[port]\t\tStart Carbon with Equinox OSGi console. "
                + "\n\t\t\t\t\tIf the optional 'port' parameter is provided, a telnet port will be opened");
        System.out.println("\t-DosgiDebugOptions=[options-file]"
                + "\n\t\t\t\t\tStart Carbon with OSGi debugging enabled. "
                + "\n\t\t\t\t\tIf the optional 'options-file is provided, the OSGi debug options will be loaded from it.");
        System.out.println(
                "\t-Dsetup\t\t\t\tClean the Registry & other configuration, recreate DB, re-populate the configuration, and start Carbon");
        System.out.println("\t-Dwso2.transports.xml=<transportXmlPath>\tLocation of the mgt-transports.xml file.");
        System.out.println("\t-DserverRoles=<roles>\t\tA comma separated list of roles. Used in deploying cApps");
        System.out.println("\t-Dcarbon.use.registry.repo\tUse registry based repository.");
        System.out.println("\t-DdisableHttpLog\t\tDisable HTTP access logging");
        System.out.println(
                "\t-DapplyPatches\t\t\tUse this system property when there are patches to be applied/reverted to/from the system. ");
        System.out.println(
                "\t\t\t\t\tDrop the patches to $CARBON_HOME/repository/componenets/patches directory and restart the system with this property. ");
        System.out.println(
                "\t\t\t\t\tWhen you want to revert a patch, delete it from the patches directory and restart the system with this property");
        System.out.println("\t-DworkerNode\t\t\tSet this system property when starting as a worker node.");
        System.out.println("\t\t\t\t\tThis is required in clustered setups with master and worker nodes.");
        System.out.println();
    }

    public static String searchFor(final String target, String start) {
        FileFilter filter = new FileFilter() {
            public boolean accept(File candidate) {
                return candidate.getName().equals(target) || candidate.getName().startsWith(target + "_");
            }
        };
        File[] candidates = new File(start).listFiles(filter);
        if (candidates == null) {
            return null;
        }
        String[] arrays = new String[candidates.length];
        for (int i = 0; i < arrays.length; i++) {
            arrays[i] = candidates[i].getName();
        }
        int result = findMax(arrays);
        if (result == -1) {
            return null;
        }
        return candidates[result].getAbsolutePath().replace(File.separatorChar, '/')
                + (candidates[result].isDirectory() ? "/" : "");
    }

    static int findMax(String[] candidates) {
        int result = -1;
        Object maxVersion = null;
        for (int i = 0; i < candidates.length; i++) {
            String name = candidates[i];
            String version = ""; // Note: directory with version suffix is always > than directory without version suffix
            int index = name.indexOf('_');
            if (index != -1) {
                version = name.substring(index + 1);
            }
            Object currentVersion = getVersionElements(version);
            if (maxVersion == null) {
                result = i;
                maxVersion = currentVersion;
            } else {
                if (compareVersion((Object[]) maxVersion, (Object[]) currentVersion) < 0) {
                    result = i;
                    maxVersion = currentVersion;
                }
            }
        }
        return result;
    }

    static int compareVersion(Object[] left, Object[] right) {

        int result = ((Integer) left[0]).compareTo((Integer) right[0]); // compare major
        if (result != 0) {
            return result;
        }

        result = ((Integer) left[1]).compareTo((Integer) right[1]); // compare minor
        if (result != 0) {
            return result;
        }

        result = ((Integer) left[2]).compareTo((Integer) right[2]); // compare service
        if (result != 0) {
            return result;
        }

        return ((String) left[3]).compareTo((String) right[3]); // compare qualifier
    }

    static Object[] getVersionElements(String version) {
        if (version.endsWith(".jar")) {
            version = version.substring(0, version.length() - 4);
        }
        Object[] result = { 0, 0, 0, "" };
        StringTokenizer t = new StringTokenizer(version, ".");
        String token;
        int i = 0;
        while (t.hasMoreTokens() && i < 4) {
            token = t.nextToken();
            if (i < 3) {
                // major, minor or service ... numeric values
                try {
                    result[i++] = new Integer(token);
                } catch (Exception e) {
                    // invalid number format - use default numbers (0) for the rest
                    break;
                }
            } else {
                // qualifier ... string value
                result[i++] = token;
            }
        }
        return result;
    }

    public static String[] getArgs() {
        List<String> args = new ArrayList<String>();

        // Enable osgi console
        // First try to get from the System property
        String enableOsgiConsole = System.getProperty(LauncherConstants.ENABLE_OSGI_CONSOLE);

        if (enableOsgiConsole != null && !enableOsgiConsole.toLowerCase().equals("true")) {
            try {
                enableOsgiConsole = "-console " + String.valueOf(Integer.parseInt(enableOsgiConsole));
            } catch (NumberFormatException ignored) {
                enableOsgiConsole = "-console";
            }
        } else if (enableOsgiConsole != null) {
            enableOsgiConsole = "-console";
        }

        if (enableOsgiConsole != null) {
            StringTokenizer tokenizer = new StringTokenizer(enableOsgiConsole, LauncherConstants.WS_DELIM);
            while (tokenizer.hasMoreTokens()) {
                String arg = tokenizer.nextToken();
                if (arg.startsWith("\"")) {
                    if (arg.endsWith("\"")) {
                        if (arg.length() >= 2) {
                            // strip the beginning and ending quotes
                            arg = arg.substring(1, arg.length() - 1);
                        }
                    } else {
                        String remainingArg = tokenizer.nextToken("\"");
                        arg = arg.substring(1) + remainingArg;
                        // skip to next whitespace separated token
                        tokenizer.nextToken(LauncherConstants.WS_DELIM);
                    }
                } else if (arg.startsWith("'")) {
                    if (arg.endsWith("'")) {
                        if (arg.length() >= 2) {
                            // strip the beginning and ending quotes
                            arg = arg.substring(1, arg.length() - 1);
                        }
                    } else {
                        String remainingArg = tokenizer.nextToken("'");
                        arg = arg.substring(1) + remainingArg;
                        // skip to next whitespace separated token
                        tokenizer.nextToken(LauncherConstants.WS_DELIM);
                    }
                }
                args.add(arg);
            }
            System.out.println("OSGi console has been enabled with options: " + enableOsgiConsole);
        }

        // Enable osgi debug
        // First try to get from the System property
        String enableOsgiDebug = System.getProperty(LauncherConstants.ENABLE_OSGI_DEBUG);
        if (enableOsgiDebug != null && enableOsgiDebug.toLowerCase().equals("true")) {
            String carbonRepo = System.getProperty(LauncherConstants.CARBON_HOME) + File.separator + "repository";
            enableOsgiDebug = carbonRepo + File.separator + "conf" + File.separator + "etc" + File.separator
                    + "osgi-debug.options";
            args.add("-debug");
            args.add(enableOsgiDebug);
            System.out.println("OSGi debugging has been enabled with options: " + enableOsgiDebug);
        }

        return args.toArray(new String[] {});
    }

    /**
     * Create & return the bundle directory
     *
     * @param bundleDir The relative path of directory which contains the jars to be made into bundles
     * @return The bundle directory
     */
    public static File getBundleDirectory(String bundleDir) {
        //TODO The name of this utils class is incorrect - Refactor - Sameera
        String carbonHome = System.getProperty("carbon.home");

        if (carbonHome == null) {
            carbonHome = System.getenv("CARBON_HOME");
        }

        if (carbonHome == null || carbonHome.length() == 0) {
            throw new RuntimeException("CARBON_HOME not found");
        }
        File dir = new File(carbonHome, bundleDir);
        if (!dir.exists() && !dir.mkdirs()) {
            System.out.println("Fail to create the directory: " + dir.getAbsolutePath());
        }
        return dir;
    }

    /**
     * Create an OSGi bundle out of a JAR file
     *
     * @param jarFile         The jarfile to be bundled
     * @param targetDir       The directory into which the created OSGi bundle needs to be placed into.
     * @param mf              The bundle manifest file
     * @param extensionPrefix Prefix, if any, for the bundle
     * @throws java.io.IOException If an error occurs while reading the jar or creating the bundle
     */
    public static void createBundle(File jarFile, File targetDir, Manifest mf, String extensionPrefix)
            throws IOException {
        if (mf == null) {
            mf = new Manifest();
        }
        String exportedPackages = Utils.parseJar(jarFile);

        String fileName = jarFile.getName();
        fileName = fileName.replaceAll("-", "_");
        if (fileName.endsWith(".jar")) {
            fileName = fileName.substring(0, fileName.length() - 4);
        }
        String symbolicName = extensionPrefix + fileName;
        String pluginName = extensionPrefix + fileName + "_1.0.0.jar";
        File extensionBundle = new File(targetDir, pluginName);

        Attributes attribs = mf.getMainAttributes();
        attribs.putValue(LauncherConstants.MANIFEST_VERSION, "1.0");
        attribs.putValue(LauncherConstants.BUNDLE_MANIFEST_VERSION, "2");
        attribs.putValue(LauncherConstants.BUNDLE_NAME, fileName);
        attribs.putValue(LauncherConstants.BUNDLE_SYMBOLIC_NAME, symbolicName);
        attribs.putValue(LauncherConstants.BUNDLE_VERSION, "1.0.0");
        attribs.putValue(LauncherConstants.EXPORT_PACKAGE, exportedPackages);
        attribs.putValue(LauncherConstants.BUNDLE_CLASSPATH, ".," + jarFile.getName());

        Utils.createBundle(jarFile, extensionBundle, mf);
    }

    /**
     * Create an OSGi bundle out of a JAR file
     *
     * @param jarFile  The jarfile to be bundled
     * @param bundle   The bundle to be created
     * @param manifest The manifest file
     * @throws IOException If an error occurs while reading the jar or creating the bundle
     */
    public static void createBundle(File jarFile, File bundle, Manifest manifest) throws IOException {
        String extractedDirPath = JAR_TO_BUNDLE_DIR + File.separator + System.currentTimeMillis() + Math.random();
        File extractedDir = new File(extractedDirPath);
        if (!extractedDir.mkdirs()) {
            throw new IOException("Fail to create the directory: " + extractedDir.getAbsolutePath());
        }
        FileOutputStream mfos = null;
        FileOutputStream p2InfOs = null;
        try {
            Utils.copyFileToDir(jarFile, extractedDir);
            String metaInfPath = extractedDirPath + File.separator + "META-INF";
            if (!new File(metaInfPath).mkdirs()) {
                throw new IOException("Failed to create the directory: " + metaInfPath);
            }
            mfos = new FileOutputStream(metaInfPath + File.separator + "MANIFEST.MF");
            manifest.write(mfos);

            File p2InfFile = new File(metaInfPath + File.separator + "p2.inf");
            if (!p2InfFile.createNewFile()) {
                throw new IOException("Fail to create the file: " + p2InfFile.getAbsolutePath());
            }
            p2InfOs = new FileOutputStream(p2InfFile);
            p2InfOs.write("instructions.configure=markStarted(started:true);".getBytes());
            p2InfOs.flush();

            Utils.archiveDir(bundle.getAbsolutePath(), extractedDirPath);
            Utils.deleteDir(extractedDir);

        } finally {
            try {
                if (mfos != null) {
                    mfos.close();
                }
            } catch (IOException e) {
                System.out.println("Unable to close the OutputStream " + e.getMessage());
                e.printStackTrace();
            }

            try {
                if (p2InfOs != null) {
                    p2InfOs.close();
                }
            } catch (IOException e) {
                System.out.println("Unable to close the OutputStream " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * Deletes all files and subdirectories under dir.
     * Returns true if all deletions were successful.
     * If a deletion fails, the method stops attempting to delete and returns false.
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            if (children != null) {
                for (String aChildren : children) {
                    boolean success = deleteDir(new File(dir, aChildren));
                    if (!success) {
                        return false;
                    }
                }
            }
        }

        // The directory is now empty so delete it
        if (!dir.delete()) {
            dir.deleteOnExit();
        }
        return true;
    }

    /**
     * Archive a directory
     *
     * @param destArchive
     * @param sourceDir
     * @throws java.io.IOException
     */
    public static void archiveDir(String destArchive, String sourceDir) throws IOException {
        File zipDir = new File(sourceDir);
        if (!zipDir.isDirectory()) {
            throw new RuntimeException(sourceDir + " is not a directory");
        }

        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destArchive));
        zipDir(zipDir, zos, sourceDir);
        zos.close();
    }

    protected static void zipDir(File zipDir, ZipOutputStream zos, String archiveSourceDir) throws IOException {
        //get a listing of the directory content
        String[] dirList = zipDir.list();
        byte[] readBuffer = new byte[40960];
        int bytesIn = 0;
        //loop through dirList, and zip the files
        for (String aDirList : dirList) {
            File f = new File(zipDir, aDirList);
            //place the zip entry in the ZipOutputStream object
            zos.putNextEntry(new ZipEntry(getZipEntryPath(f, archiveSourceDir)));
            if (f.isDirectory()) {
                //if the File object is a directory, call this
                //function again to add its content recursively
                zipDir(f, zos, archiveSourceDir);
                //loop again
                continue;
            }
            //if we reached here, the File object f was not a directory
            //create a FileInputStream on top of f
            FileInputStream fis = new FileInputStream(f);
            try {
                //now write the content of the file to the ZipOutputStream
                while ((bytesIn = fis.read(readBuffer)) != -1) {
                    zos.write(readBuffer, 0, bytesIn);
                }
            } finally {
                try {
                    //close the Stream
                    fis.close();
                } catch (IOException e) {
                    System.out.println("Unable to close the InputStream " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
    }

    protected static String getZipEntryPath(File f, String archiveSourceDir) {
        String entryPath = f.getPath();
        entryPath = entryPath.substring(archiveSourceDir.length() + 1);
        if (File.separatorChar == '\\') {
            entryPath = entryPath.replace(File.separatorChar, '/');
        }
        if (f.isDirectory()) {
            entryPath += "/";
        }
        return entryPath;
    }

    /**
     * Copies src file to dst directory.
     * If the dst directory does not exist, it is created
     */
    public static void copyFileToDir(File src, File dst) throws IOException {
        String dstAbsPath = dst.getAbsolutePath();
        String dstDir = dstAbsPath.substring(0, dstAbsPath.lastIndexOf(File.separator));
        File dir = new File(dstDir);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new IOException("Fail to create the directory: " + dir.getAbsolutePath());
        }

        File file = new File(dstAbsPath + File.separator + src.getName());
        copyFile(src, file);
    }

    /**
     * Copies src file to dst file.
     * If the dst file does not exist, it is created
     */
    public static void copyFile(File src, File dst) throws IOException {
        OutputStream out = null;
        InputStream in = new FileInputStream(src);

        try {
            String dstAbsPath = dst.getAbsolutePath();
            String dstDir = dstAbsPath.substring(0, dstAbsPath.lastIndexOf(File.separator));
            File dir = new File(dstDir);
            if (!dir.exists() && !dir.mkdirs()) {
                throw new IOException("Fail to create the directory: " + dir.getAbsolutePath());
            }

            out = new FileOutputStream(dst);
            // Transfer bytes from in to out
            byte[] buf = new byte[10240];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                System.out.println("Unable to close the InputStream " + e.getMessage());
                e.printStackTrace();
            }

            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                System.out.println("Unable to close the OutputStream " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public static void extract(String archive, String extractDir) throws IOException {
        FileInputStream inputStream = new FileInputStream(archive);
        extractFromStream(inputStream, extractDir);
    }

    public static void extractFromStream(InputStream inputStream, String extractDir) throws IOException {
        ZipInputStream zin = null;
        try {
            File unzipped = new File(extractDir);
            // Open the ZIP file
            zin = new ZipInputStream(inputStream);
            if (!unzipped.mkdirs()) {
                throw new IOException("Fail to create the directory: " + unzipped.getAbsolutePath());
            }
            ZipEntry entry;
            while ((entry = zin.getNextEntry()) != null) {
                String entryName = entry.getName();
                File f = new File(extractDir + File.separator + entryName);

                if (entryName.endsWith("/") && !f.exists()) { // this is a
                    // directory
                    if (!f.mkdirs()) {
                        throw new IOException("Fail to create the directory: " + f.getAbsolutePath());
                    } else {
                        continue;
                    }
                }

                // This is a file. Carry out File processing
                int lastIndexOfSlash = entryName.lastIndexOf('/');
                String dirPath = "";
                if (lastIndexOfSlash != -1) {
                    dirPath = entryName.substring(0, lastIndexOfSlash);
                    File dir = new File(extractDir + File.separator + dirPath);
                    if (!dir.exists() && !dir.mkdirs()) {
                        throw new IOException("Failed to create the directory: " + dir.getAbsoluteFile());
                    }
                }

                if (!f.isDirectory()) {
                    OutputStream out = new FileOutputStream(f);
                    byte[] buf = new byte[40960];

                    // Transfer bytes from the ZIP file to the output file
                    int len;
                    while ((len = zin.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                    out.close();
                }
            }
        } catch (IOException e) {
            String msg = "Cannot unzip archive. It is probably corrupt";
            System.out.println(msg);
            throw e;
        } finally {
            try {
                if (zin != null) {
                    zin.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param jarFile jar file location
     * @return package name list separated by ","
     * @throws IOException IOException
     */
    public static String parseJar(File jarFile) throws IOException {
        List<String> exportedPackagesList = new ArrayList<String>();
        ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(new FileInputStream(jarFile)));
        List<ZipEntry> entries = populateList(zipInputStream);
        zipInputStream.close();

        for (ZipEntry entry : entries) {
            String path = entry.getName();
            if (!path.endsWith("/") && path.endsWith(".class")) {
                //This is package that contains classes. Thus, exportedPackagesList
                int index = path.lastIndexOf('/');
                if (index != -1) {
                    path = path.substring(0, index);
                    path = path.replaceAll("/", ".");
                    if (!exportedPackagesList.contains(path)) {
                        exportedPackagesList.add(path);
                    }
                }
            }
        }

        String[] packageArray = exportedPackagesList.toArray(new String[exportedPackagesList.size()]);
        StringBuffer exportedPackages = new StringBuffer();
        for (int i = 0; i < packageArray.length; i++) {
            exportedPackages.append(packageArray[i]);
            if (i != (packageArray.length - 1)) {
                exportedPackages.append(",");
            }
        }
        return exportedPackages.toString();
    }

    /**
     * @param zipInputStream zipInputStream
     * @return return zipetry map
     * @throws IOException IOException
     */
    private static List<ZipEntry> populateList(ZipInputStream zipInputStream) throws IOException {
        List<ZipEntry> listEntry = new ArrayList<ZipEntry>();
        while (zipInputStream.available() == 1) {
            ZipEntry entry = zipInputStream.getNextEntry();
            if (entry == null) {
                break;
            }
            listEntry.add(entry);
        }
        return listEntry;
    }

    public static File getBundleConfigDirectory() {
        String carbonRepo = System.getenv("CARBON_REPOSITORY");
        if (carbonRepo == null) {
            carbonRepo = System.getProperty("carbon.repository");
        }
        if (carbonRepo == null) {
            carbonRepo = System.getProperty("carbon.home") + File.separator + "repository";
        }
        String bundleConfigDirLocation = carbonRepo + File.separator + "conf" + File.separator + "etc"
                + File.separator + "bundle-config";
        File bundleConfigDir = new File(bundleConfigDirLocation);
        if (!bundleConfigDir.exists()) {
            return null;
        }
        return bundleConfigDir;
    }

    public static class JarFileFilter implements FileFilter {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(".jar");
        }
    }

    /**
     * clearPrefixedSystemProperties clears System Properties by writing null properties in
     * the targetPropertyMap that match a prefix
     *
     * @param prefix            prefix
     * @param targetPropertyMap targetPropertyMap
     */
    public static void clearPrefixedSystemProperties(String prefix, Map<String, String> targetPropertyMap) {
        for (Object o : System.getProperties().keySet()) {
            String propertyName = (String) o;
            if (propertyName.startsWith(prefix) && !targetPropertyMap.containsKey(propertyName)) {
                targetPropertyMap.put(propertyName, null);
            }
        }
    }

    /**
     * loadProperties is a convenience method to load properties from a servlet context resource
     *
     * @param filePath - path to load properties from
     * @return the properties
     */
    public static Properties loadProperties(String filePath) {
        Properties properties = new Properties();
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(filePath);
            properties.load(fileInputStream);

        } catch (MalformedURLException e) {
            // no url to load from
        } catch (IOException e) {
            // its ok if there is no file
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return properties;
    }

}