All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.mmm.util.nls.base.NlsBundleHelper Maven / Gradle / Ivy

/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.nls.base;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.inject.Named;

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

import net.sf.mmm.util.nls.api.NlsBundle;
import net.sf.mmm.util.nls.api.NlsBundleKey;
import net.sf.mmm.util.nls.api.NlsBundleMessage;
import net.sf.mmm.util.nls.api.NlsMessage;

/**
 * Helper class to deal with {@link NlsBundle} interfaces.
 *
 * @author Joerg Hohwiller (hohwille at users.sourceforge.net)
 * @since 3.0.0
 */
public class NlsBundleHelper {

  private static final Logger LOG = LoggerFactory.getLogger(NlsBundleHelper.class);

  /** @see #getInstance() */
  public static final NlsBundleHelper INSTANCE = new NlsBundleHelper();

  /**
   * The constructor.
   */
  public NlsBundleHelper() {

    super();
  }

  /**
   * @return the singleton instance of this class.
   * @since 4.0.0
   */
  public static NlsBundleHelper getInstance() {

    return INSTANCE;
  }

  /**
   * This method gets the location of the {@link java.util.ResourceBundle} base name for the given {@link NlsBundle}
   * interface.
   *
   * @param nlsBundleInterface is the {@link NlsBundle} interface.
   * @return the fully qualified {@link java.util.ResourceBundle} base name for the given {@link NlsBundle} interface.
   */
  public String getQualifiedLocation(Class nlsBundleInterface) {

    String fqn = nlsBundleInterface.getName();
    if (fqn.endsWith(NlsBundle.INTERFACE_NAME_SUFFIX)) {
      fqn = fqn.substring(0, fqn.length() - NlsBundle.INTERFACE_NAME_SUFFIX.length());
    } else {
      LOG.error("Illegal NlsBundle interface '" + nlsBundleInterface.getName() + "': has to end with the suffix '" + NlsBundle.INTERFACE_NAME_SUFFIX + "'.");
    }
    return fqn;
  }

  /**
   * @param method is the {@link Method} of a {@link NlsBundle}.
   * @return the {@link NlsBundleKey#value() key} of the {@link Method} (defaults to {@link Method#getName()} if not
   *         annotated with {@link NlsBundleKey}).
   */
  public String getKey(Method method) {

    String key;
    NlsBundleKey keyAnnotation = method.getAnnotation(NlsBundleKey.class);
    if (keyAnnotation == null) {
      key = method.getName();
    } else {
      key = keyAnnotation.value();
    }
    return key;
  }

  /**
   * @param qualifiedBundleName the {@link Class#getName() qualified name} of the {@link ResourceBundle} to load.
   * @param locale the {@link Locale} to translate to.
   * @return the requested {@link ResourceBundle}.
   */
  public ResourceBundle getResourceBundle(String qualifiedBundleName, Locale locale) {

    return ResourceBundle.getBundle(qualifiedBundleName, locale, ResourceBundleControlUtf8WithNlsBundleSupport.INSTANCE);
  }

  /**
   * @param method the {@link NlsBundle} {@link Method}.
   * @return the {@link NlsBundleMessage#value() bundle message} or {@code null} if not present.
   * @since 4.0.0
   */
  public String getMessage(Method method) {

    NlsBundleMessage messageAnnotation = method.getAnnotation(NlsBundleMessage.class);
    if (messageAnnotation != null) {
      return messageAnnotation.value();
    }
    return null;
  }

  /**
   * @param method the {@link NlsBundle} {@link Method}.
   * @return the {@link NlsMessageDescriptor} for the given {@link Method}.
   */
  public NlsMessageDescriptor getDescriptor(Method method) {

    return new NlsMessageDescriptor(method);
  }

  /**
   *
   * @param method is the {@link Method} of a {@link NlsBundle}.
   * @return an array of {@link NlsArgumentDescriptor}s describing the method parameters.
   * @since 7.3.0
   */
  public NlsArgumentDescriptor[] getArguments(Method method) {

    Class[] parameterTypes = method.getParameterTypes();
    if (parameterTypes.length == 0) {
      return NlsArgumentDescriptor.EMPTY_ARRAY;
    }
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    NlsArgumentDescriptor[] arguments = new NlsArgumentDescriptor[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++) {
      String name = getName(parameterAnnotations[i], i);
      NlsArgumentDescriptor arg = new NlsArgumentDescriptor(name, parameterTypes[i], i);
      arguments[i] = arg;
    }
    return arguments;
  }

  private String getName(Annotation[] annotations, int i) {

    for (Annotation currentAnnotation : annotations) {
      if (currentAnnotation instanceof Named) {
        Named namedAnnotation = (Named) currentAnnotation;
        return namedAnnotation.value();
      }
    }
    return Integer.toString(i);
  }

  /**
   * Converts the given {@link NlsBundle} class to a {@link ResourceBundle}.
   *
   * @param bundleClass is the class reflecting a {@link NlsBundle}.
   * @return a {@link ResourceBundle} with the key/value pairs of the given {@code bundleClass} for
   *         {@link java.util.Locale#ROOT}.
   * @since 4.0.0
   */
  public ResourceBundle toResourceBundle(Class bundleClass) {

    Hashtable bundleProperties = new Hashtable<>();
    for (Method method : bundleClass.getMethods()) {
      if (isNlsBundleMethod(method, false)) {
        String key = getKey(method);
        String message = getMessage(method);
        bundleProperties.put(key, message);
      }
    }
    GenericResourceBundle bundle = new GenericResourceBundle(bundleProperties);
    return bundle;
  }

  /**
   * This method determines if the given {@link Method} is a regular {@link NlsBundle}-method.
   *
   * @param method the {@link Method} to check.
   * @param ignoreIllegalMethods - {@code true} if illegal methods (non NlsBundleMethods other than those defined by
   *        {@link Object}) should be ignored, {@code false} if they should cause an exception.
   * @return {@code true} if the given {@link Method} is a legal {@link NlsBundle} method, {@code false} otherwise (e.g.
   *         for {@code toString()}).
   */
  public boolean isNlsBundleMethod(Method method, boolean ignoreIllegalMethods) {

    Class declaringClass = method.getDeclaringClass();
    assert (declaringClass.isInterface());
    if (NlsMessage.class.equals(method.getReturnType())) {
      assert (NlsBundle.class.isAssignableFrom(declaringClass));
      return true;
    } else if (!declaringClass.isAssignableFrom(NlsBundle.class)) {
      if (!ignoreIllegalMethods) {
        throw new IllegalArgumentException(declaringClass.getName() + "." + method.getName());
      }
    }
    return false;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy