zweb/src/main/java/org/zkoss/web/util/resource/ServletLabelLocator.java

Summary

Maintainability
A
45 mins
Test Coverage
/* ServletLabelLocator.java

    Purpose:
        
    Description:
        
    History:
        Sat Apr  8 19:51:08     2006, Created by tomyeh

Copyright (C) 2006 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
    This program is distributed under LGPL Version 2.1 in the hope that
    it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.web.util.resource;

import java.io.IOException;
import java.net.URL;
import java.util.Locale;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.zkoss.lang.Library;
import org.zkoss.lang.Objects;
import org.zkoss.util.resource.LabelLocator;
import org.zkoss.web.servlet.Servlets;

/**
 * Used by Labels to load labels from a servlet context.
 *
 * @author tomyeh
 */
public class ServletLabelLocator implements LabelLocator {
    private static final Logger log = LoggerFactory.getLogger(ServletLabelLocator.class);

    private final ServletContext _ctx;
    private final String _path;

    /** Constructs a locator where the properties file is decided
     * by the library property called org.zkoss.util.label.web.location.
     * If not defined, /WEB-INF/zk-label.properties is assumed
     */
    public ServletLabelLocator(ServletContext ctx) {
        this(ctx, null);
    }

    /** Constructs a locator for the given path.
     * @param path the path of the properties file<br/>
     * Notice that <code>file://path</code> is supported (but not http://).
     * @since 5.0.7
     */
    public ServletLabelLocator(ServletContext ctx, String path) {
        if (ctx == null)
            throw new IllegalArgumentException("null");
        _ctx = ctx;
        _path = path;
    }

    //-- LabelLocator --//
    public URL locate(Locale locale) throws IOException {
        boolean fallback = false;
        String path;
        if (_path != null) {
            path = _path;
        } else {
            path = Library.getProperty("org.zkoss.util.label.web.location");
            if (path == null) {
                path = "/WEB-INF/zk-label.properties";
                fallback = true;
            }
        }
        URL url = locate0(path, locale);
        if (url == null)
            if (fallback)
                url = locate0("/WEB-INF/i3-label.properties", locale);
            else if (locale == null)
                log.error("File not found in " + _ctx.getServletContextName() + ": " + path);
        //error is shown only if locale, since zh_TW will load zh_TW and zh
        //while users won't prepare zh
        return url;
    }

    private URL locate0(String path, Locale locale) throws IOException {
        final int j = path.lastIndexOf('.');
        final String prefix = j >= 0 ? path.substring(0, j) : path;
        final String suffix = j >= 0 ? path.substring(j) : "";
        path = locale == null ? prefix + suffix : prefix + '_' + locale + suffix;
        return path.toLowerCase(java.util.Locale.ENGLISH).startsWith("file://") ? Servlets.getResource(_ctx, path)
                : _ctx.getResource(path);
        //we don't accept http:// since we cannot detect if it exists
    }

    //-- Object --//
    public int hashCode() {
        return _ctx.hashCode() + Objects.hashCode(_path);
    }

    public boolean equals(Object o) {
        if (this == o)
            return true;
        return o instanceof ServletLabelLocator && ((ServletLabelLocator) o)._ctx.equals(_ctx)
                && Objects.equals(((ServletLabelLocator) o)._path, _path);
    }

    public String toString() {
        return "ServletLabelLocator" + (_path != null ? ": " + _path : "");
    }
}