001 // Copyright 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.hivemind.impl; 016 017 import java.text.MessageFormat; 018 import java.util.Locale; 019 020 import org.apache.hivemind.HiveMind; 021 import org.apache.hivemind.Messages; 022 import org.apache.hivemind.util.Defense; 023 024 /** 025 * Abstract base class for implementations of {@link org.apache.hivemind.Messages}. Subclasses must 026 * provide {@link #getLocale()}and {@link #findMessage(String)} implementations. 027 * 028 * @author Howard M. Lewis Ship 029 * @since 1.1 030 */ 031 public abstract class AbstractMessages implements Messages 032 { 033 public final String format(String key, Object[] args) 034 { 035 String pattern = getMessage(key); 036 037 for (int i = 0; i < args.length; i++) 038 { 039 Object arg = args[i]; 040 041 if (arg != null && arg instanceof Throwable) 042 args[i] = extractMessage((Throwable) arg); 043 } 044 045 // This ugliness is mandated for JDK 1.3 compatibility, which has a bug 046 // in MessageFormat ... the 047 // pattern is applied in the constructor, using the system default Locale, 048 // regardless of what locale is later specified! 049 // It appears that the problem does not exist in JDK 1.4. 050 051 MessageFormat messageFormat = new MessageFormat(""); 052 messageFormat.setLocale(getLocale()); 053 messageFormat.applyPattern(pattern); 054 055 return messageFormat.format(args); 056 } 057 058 private final String extractMessage(Throwable t) 059 { 060 String message = t.getMessage(); 061 062 return HiveMind.isNonBlank(message) ? message : t.getClass().getName(); 063 } 064 065 public final String format(String key, Object arg0) 066 { 067 return format(key, new Object[] 068 { arg0 }); 069 } 070 071 public final String format(String key, Object arg0, Object arg1) 072 { 073 return format(key, new Object[] 074 { arg0, arg1 }); 075 } 076 077 public final String format(String key, Object arg0, Object arg1, Object arg2) 078 { 079 return format(key, new Object[] 080 { arg0, arg1, arg2 }); 081 } 082 083 /** @since 1.2 */ 084 public final boolean containsMessage(String key) 085 { 086 return findMessage(key) != null; 087 } 088 089 public final String getMessage(String key) 090 { 091 Defense.notNull(key, "key"); 092 093 String result = findMessage(key); 094 095 if (result == null) 096 result = "[" + key.toUpperCase() + "]"; 097 098 return result; 099 } 100 101 /** 102 * Concrete implementations must provide a non-null Locale. 103 */ 104 105 protected abstract Locale getLocale(); 106 107 /** 108 * Concrete implementations must implement this method. 109 * <p> 110 * Note: starting with release 1.2, it is no longer considered an error if the key does not 111 * match a known message (i.e., due to {@link #containsMessage(String)}). Prior to 1.2, some 112 * implementations would log an error in that situation. 113 * 114 * @param key 115 * @return the localized message for the key, or null if no such message exists. 116 */ 117 118 protected abstract String findMessage(String key); 119 120 }