1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.problem;
13 import java.util.Enumeration;
14 import java.util.Locale;
15 import java.util.MissingResourceException;
16 import java.util.ResourceBundle;
18 import org.eclipse.jdt.core.compiler.*;
19 import org.eclipse.jdt.core.compiler.IProblem;
20 import org.eclipse.jdt.internal.compiler.IProblemFactory;
21 import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
22 import org.eclipse.jdt.internal.compiler.util.Util;
24 public class DefaultProblemFactory implements IProblemFactory {
26 public HashtableOfInt messageTemplates;
27 private Locale locale;
28 private static HashtableOfInt DEFAULT_LOCALE_TEMPLATES;
29 private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
30 private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
32 public DefaultProblemFactory() {
33 this(Locale.getDefault());
36 * @param loc the locale used to get the right message
38 public DefaultProblemFactory(Locale loc) {
40 if (Locale.getDefault().equals(loc)){
41 if (DEFAULT_LOCALE_TEMPLATES == null){
42 DEFAULT_LOCALE_TEMPLATES = loadMessageTemplates(loc);
44 this.messageTemplates = DEFAULT_LOCALE_TEMPLATES;
46 this.messageTemplates = loadMessageTemplates(loc);
50 * Answer a new IProblem created according to the parameters value
52 * <li>originatingFileName the name of the file name from which the problem is originated
53 * <li>problemId the problem id
54 * <li>problemArguments the fully qualified arguments recorded inside the problem
55 * <li>messageArguments the arguments needed to set the error message (shorter names than problemArguments ones)
56 * <li>severity the severity of the problem
57 * <li>startPosition the starting position of the problem
58 * <li>endPosition the end position of the problem
59 * <li>lineNumber the line on which the problem occured
61 * @param originatingFileName char[]
62 * @param problemId int
63 * @param problemArguments String[]
64 * @param messageArguments String[]
66 * @param startPosition int
67 * @param endPosition int
68 * @param lineNumber int
69 * @return org.eclipse.jdt.internal.compiler.IProblem
71 public IProblem createProblem(
72 char[] originatingFileName,
74 String[] problemArguments,
75 String[] messageArguments,
81 return new DefaultProblem(
83 this.getLocalizedMessage(problemId, messageArguments),
91 private final static int keyFromID(int id) {
92 return id + 1; // keys are offsetted by one in table, since it cannot handle 0 key
95 * Answer the locale used to retrieve the error messages
96 * @return java.util.Locale
98 public Locale getLocale() {
101 public final String getLocalizedMessage(int id, String[] problemArguments) {
102 String message = (String) this.messageTemplates.get(keyFromID(id & IProblem.IgnoreCategoriesMask));
103 if (message == null) {
104 return "Unable to retrieve the error message for problem id: " //$NON-NLS-1$
105 + (id & IProblem.IgnoreCategoriesMask)
106 + ". Check compiler resources."; //$NON-NLS-1$
109 // for compatibility with MessageFormat which eliminates double quotes in original message
110 char[] messageWithNoDoubleQuotes =
111 CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
113 if (problemArguments == null) return new String(messageWithNoDoubleQuotes);
115 int length = messageWithNoDoubleQuotes.length;
118 StringBuffer output = null;
119 if ((id & IProblem.Javadoc) != 0) {
120 if (output == null) output = new StringBuffer(10+length+problemArguments.length*20);
121 output.append((String) this.messageTemplates.get(keyFromID(IProblem.JavadocMessagePrefix & IProblem.IgnoreCategoriesMask)));
124 if ((end = CharOperation.indexOf('{', messageWithNoDoubleQuotes, start)) > -1) {
125 if (output == null) output = new StringBuffer(length+problemArguments.length*20);
126 output.append(messageWithNoDoubleQuotes, start, end - start);
127 if ((start = CharOperation.indexOf('}', messageWithNoDoubleQuotes, end + 1)) > -1) {
129 String argId = new String(messageWithNoDoubleQuotes, end + 1, start - end - 1);
131 index = Integer.parseInt(argId);
132 output.append(problemArguments[index]);
133 } catch (NumberFormatException nfe) {
134 output.append(messageWithNoDoubleQuotes, end + 1, start - end);
135 } catch (ArrayIndexOutOfBoundsException e) {
136 return "Cannot bind message for problem (id: " //$NON-NLS-1$
137 + (id & IProblem.IgnoreCategoriesMask)
138 + ") \"" //$NON-NLS-1$
140 + "\" with arguments: {" //$NON-NLS-1$
141 + Util.toString(problemArguments)
146 output.append(messageWithNoDoubleQuotes, end, length);
150 if (output == null) return new String(messageWithNoDoubleQuotes);
151 output.append(messageWithNoDoubleQuotes, start, length - start);
156 return output.toString();
159 * @param problem org.eclipse.jdt.internal.compiler.IProblem
162 public final String localizedMessage(IProblem problem) {
163 return getLocalizedMessage(problem.getID(), problem.getArguments());
167 * This method initializes the MessageTemplates class variable according
168 * to the current Locale.
170 * @return HashtableOfInt
172 public static HashtableOfInt loadMessageTemplates(Locale loc) {
173 ResourceBundle bundle = null;
174 String bundleName = "org.eclipse.jdt.internal.compiler.problem.messages"; //$NON-NLS-1$
176 bundle = ResourceBundle.getBundle(bundleName, loc);
177 } catch(MissingResourceException e) {
178 System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$
181 HashtableOfInt templates = new HashtableOfInt(700);
182 Enumeration keys = bundle.getKeys();
183 while (keys.hasMoreElements()) {
184 String key = (String)keys.nextElement();
186 int messageID = Integer.parseInt(key);
187 templates.put(keyFromID(messageID), bundle.getString(key));
188 } catch(NumberFormatException e) {
190 } catch (MissingResourceException e) {