001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: PrioritizedMessage.java,v 1.2 2006/09/29 12:32:07 drmlipp Exp $
021: *
022: * $Log: PrioritizedMessage.java,v $
023: * Revision 1.2 2006/09/29 12:32:07 drmlipp
024: * Consistently using WfMOpen as projct name now.
025: *
026: * Revision 1.1.1.1 2003/06/30 20:05:13 drmlipp
027: * Initial import
028: *
029: * Revision 1.8 2003/06/27 08:51:46 lipp
030: * Fixed copyright/license information.
031: *
032: * Revision 1.7 2003/03/13 17:03:24 schlue
033: * Spelling checked.
034: *
035: * Revision 1.6 2003/03/07 07:59:43 huaiyang
036: * add the method of unmappedMessage.
037: *
038: * Revision 1.5 2003/03/05 14:04:06 huaiyang
039: * Use resourceBundle to retrieve the error message.
040: *
041: * Revision 1.4 2003/03/04 08:28:59 lipp
042: * Prepared internationalization of import messages.
043: *
044: * Revision 1.3 2003/02/08 13:16:45 lipp
045: * Fixed comment added toString method.
046: *
047: * Revision 1.2 2002/12/04 08:53:35 lipp
048: * Optimized.
049: *
050: * Revision 1.1 2002/12/02 13:51:44 huaiyang
051: * Initial.
052: *
053: */
054: package de.danet.an.workflow.api;
055:
056: import java.io.Serializable;
057:
058: import java.util.HashMap;
059: import java.util.Locale;
060: import java.util.Map;
061: import java.util.ResourceBundle;
062: import java.text.MessageFormat;
063:
064: /**
065: * This class presents a prioritized message that will be internationalized
066: * using the specified resource bundle and the referenced entry. For details
067: * see the description of its class contructor.
068: */
069: public class PrioritizedMessage implements java.io.Serializable {
070: private Priority priority;
071: private String message;
072: private Object[] data;
073:
074: private boolean messageHasKey = false;
075:
076: /* the cache of all the used resource bundle.*/
077: private static Map cachedResourceBundles = new HashMap();
078:
079: /**
080: * This class represents the priority of a given message. It was
081: * taken over from org.apache.log4j.Priority to avoid the
082: * dependence of the log4j library.
083: */
084: public static class Priority implements Serializable, Comparable {
085: /**
086: * The <code>DEBUG</code> priority designates fine-grained
087: * informational events that are most useful to debug an
088: * application.
089: */
090: public static final Priority DEBUG = new Priority(0, "DEBUG");
091:
092: /**
093: * The <code>INFO</code> level designates informational messages
094: * that highlight the progress of the application at coarse-grained
095: * level.
096: */
097: public static final Priority INFO = new Priority(1, "INFO");
098:
099: /**
100: * The <code>WARN</code> level designates potentially harmful
101: * situations.
102: */
103: public static final Priority WARN = new Priority(2, "WARN");
104:
105: /**
106: * The <code>ERROR</code> level designates error events that
107: * might still allow the application to continue running.
108: */
109: public static final Priority ERROR = new Priority(3, "ERROR");
110:
111: /**
112: * The <code>FATAL</code> level designates very severe error
113: * events that will presumably lead the application to abort.
114: */
115: public static final Priority FATAL = new Priority(4, "FATAL");
116:
117: private static Priority[] prios = new Priority[] { DEBUG, INFO,
118: WARN, ERROR, FATAL };
119:
120: private int level;
121: private transient String levelStr;
122:
123: /**
124: * Constructor of the priority of a message.
125: * @param level the level of the priority.
126: * @param levelStr the string representation of the priority.
127: */
128: protected Priority(int level, String levelStr) {
129: this .level = level;
130: this .levelStr = levelStr;
131: }
132:
133: /**
134: * Returns the string representation of this priority.
135: * @return this priority in string.
136: */
137: public String toString() {
138: return levelStr;
139: }
140:
141: /**
142: * Perform instance substitution during serialization.
143: */
144: private Object readResolve() {
145: if (level < DEBUG.level || level > FATAL.level) {
146: throw new IllegalArgumentException(
147: "Unexpected error in deserialization");
148: }
149: return prios[level];
150: }
151:
152: /**
153: * Implements <code>Comparable</code>.
154: * @param other priority to compare with.
155: * @return a negative integer, zero, or a positive integer as
156: * this priority is less than, equal to, or greater than the
157: * given priority.
158: */
159: public int compareTo(Object other) {
160: return level - ((Priority) other).level;
161: }
162: }
163:
164: /**
165: * Constructs a prioritized message. If the message has the format
166: * "<code>a.resource.bundle.base.name#key</code>" it is interpreted as the
167: * base name of a {@link java.util.ResourceBundle
168: * <code>ReosurceBundle</code>} and the key of an entry in this
169: * resource bundle.
170: * @param priority the priority of the given message.
171: * @param message a message or a resource and key reference.
172: * @see #message
173: */
174: public PrioritizedMessage(Priority priority, String message) {
175: this (priority, message, null);
176: }
177:
178: /**
179: * Constructs a prioritized message. If the message has the format
180: * "<code>a.resource.bundle.base.name#key</code>" it is interpreted as the
181: * base name of a {@link java.util.ResourceBundle
182: * <code>ReosurceBundle</code>} and the key of an entry in this
183: * resource bundle.<P>
184: *
185: * If the parameter <code>data</code> is not <code>null</code>,
186: * the message (or the string looked up in the resource bundle)
187: * will be fomatted using {@link
188: * java.text.MessageFormat#format(String,Object[])
189: * <code>MessageFormat.format</code>}.
190: *
191: * @param priority the priority of the given message.
192: * @param message a message or a resource and key reference.
193: * @param data additional data used when formatting the message.
194: * @see #message
195: */
196: public PrioritizedMessage(Priority priority, String message,
197: Object[] data) {
198: this .priority = priority;
199: this .message = message;
200: this .data = data;
201: // determine if the message has the format of bundle.base.name#key
202: // and retrieve the resource bundle base
203: int posOfHash = message.lastIndexOf("#");
204: if ((posOfHash != -1) && (posOfHash != (message.length() - 1))) {
205: // if the message has the pattern as *#*, then this is
206: // a message with resource and key.
207: messageHasKey = true;
208: }
209:
210: }
211:
212: /**
213: * Returns the priority of the message.
214: * @return the priority of the message.
215: */
216: public Priority priority() {
217: return priority;
218: }
219:
220: /**
221: * Returns the message. If the message has the format
222: * "<code>a.resource.bundle.base.name#key</code>", it will be
223: * internationalized using the specified resource bundle and the
224: * referenced entry with the default {@link Locale
225: * <code>Locale</code>}.
226: * @return the message.
227: * @see #message(Locale)
228: */
229: public String message() {
230: if (messageHasKey) {
231: return message(Locale.getDefault());
232: } else {
233: return message;
234: }
235: }
236:
237: /**
238: * Returns the message. If the message has the format
239: * "<code>a.resource.bundle.base.name#key</code>", it will be
240: * internationalized using the specified resource bundle and the
241: * referenced entry using the given {@link Locale
242: * <code>Locale</code>}.
243: * @param locale the <code>Locale</code> to be used for
244: * resource bundle lookup.
245: * @return the message.
246: */
247: public String message(Locale locale) {
248: if (messageHasKey) {
249: String internationalizedMsg = internationalizedMessage(locale);
250: if (data == null) {
251: return internationalizedMsg;
252: } else {
253: MessageFormat formatter = new MessageFormat(
254: internationalizedMsg);
255: formatter.setLocale(locale);
256: return formatter.format(data);
257: }
258: } else {
259: return message;
260: }
261: }
262:
263: /**
264: * Returns the message that it is not internationalized.
265: * @return the message.
266: */
267: public String unmappedMessage() {
268: return message;
269: }
270:
271: private String internationalizedMessage(Locale locale) {
272: int posOfHash = message.lastIndexOf("#");
273: String bundleBase = message.substring(0, posOfHash);
274: String messageKey = message.substring(posOfHash + 1, message
275: .length());
276: String bundleBaseLocale = bundleBase
277: + ((locale == null) ? "" : locale.toString());
278: ResourceBundle resourceBundle = (ResourceBundle) cachedResourceBundles
279: .get(bundleBaseLocale);
280: if (resourceBundle == null) {
281: // current bundle is still not cached.
282: resourceBundle = ResourceBundle.getBundle(
283: "de.danet.an.workflow.resources." + bundleBase,
284: locale);
285: cachedResourceBundles.put(bundleBaseLocale, resourceBundle);
286: }
287: String internationalizedMsg = resourceBundle
288: .getString(messageKey);
289: return internationalizedMsg;
290: }
291:
292: /**
293: * Returns a string representation of the message.
294: * @return a string representation.
295: */
296: public String toString() {
297: return "[" + priority + "] " + message;
298: }
299:
300: }
|