org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ecj Show documentation
Show all versions of ecj Show documentation
Eclipse Compiler for Java(TM)
/*******************************************************************************
* Copyright (c) 2000, 2013 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.problem;
import java.util.Enumeration;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
import org.eclipse.jdt.internal.compiler.util.Util;
@SuppressWarnings("rawtypes")
public class DefaultProblemFactory implements IProblemFactory {
public HashtableOfInt messageTemplates;
private Locale locale;
private static HashtableOfInt DEFAULT_LOCALE_TEMPLATES;
private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
private final static char[] FIRST_ARGUMENT = "{0}".toCharArray(); //$NON-NLS-1$
public DefaultProblemFactory() {
this(Locale.getDefault());
}
/**
* @param loc the locale used to get the right message
*/
public DefaultProblemFactory(Locale loc) {
setLocale(loc);
}
/**
* Answer a new IProblem created according to the parameters value
*
* - originatingFileName the name of the file name from which the problem is originated
*
- problemId the problem id
*
- problemArguments the fully qualified arguments recorded inside the problem
*
- messageArguments the arguments needed to set the error message (shorter names than problemArguments ones)
*
- severity the severity of the problem
*
- startPosition the starting position of the problem
*
- endPosition the end position of the problem
*
- lineNumber the line on which the problem occured
*
* @param originatingFileName char[]
* @param problemId int
* @param problemArguments String[]
* @param messageArguments String[]
* @param severity int
* @param startPosition int
* @param endPosition int
* @param lineNumber int
* @return CategorizedProblem
*/
@Override
public CategorizedProblem createProblem(
char[] originatingFileName,
int problemId,
String[] problemArguments,
String[] messageArguments,
int severity,
int startPosition,
int endPosition,
int lineNumber,
int columnNumber) {
return new DefaultProblem(
originatingFileName,
this.getLocalizedMessage(problemId, messageArguments),
problemId,
problemArguments,
severity,
startPosition,
endPosition,
lineNumber,
columnNumber);
}
@Override
public CategorizedProblem createProblem(
char[] originatingFileName,
int problemId,
String[] problemArguments,
int elaborationId,
String[] messageArguments,
int severity,
int startPosition,
int endPosition,
int lineNumber,
int columnNumber) {
return new DefaultProblem(
originatingFileName,
this.getLocalizedMessage(problemId, elaborationId, messageArguments),
problemId,
problemArguments,
severity,
startPosition,
endPosition,
lineNumber,
columnNumber);
}
private final static int keyFromID(int id) {
return id + 1; // keys are offsetted by one in table, since it cannot handle 0 key
}
/**
* Answer the locale used to retrieve the error messages
* @return java.util.Locale
*/
@Override
public Locale getLocale() {
return this.locale;
}
public void setLocale(Locale locale) {
if (locale == this.locale) return;
this.locale = locale;
if (Locale.getDefault().equals(locale)){
if (DEFAULT_LOCALE_TEMPLATES == null){
DEFAULT_LOCALE_TEMPLATES = loadMessageTemplates(locale);
}
this.messageTemplates = DEFAULT_LOCALE_TEMPLATES;
} else {
this.messageTemplates = loadMessageTemplates(locale);
}
}
@Override
public final String getLocalizedMessage(int id, String[] problemArguments) {
return getLocalizedMessage(id, 0, problemArguments);
}
@Override
public final String getLocalizedMessage(int id, int elaborationId, String[] problemArguments) {
String rawMessage = (String) this.messageTemplates.get(keyFromID(id & IProblem.IgnoreCategoriesMask));
if (rawMessage == null) {
return "Unable to retrieve the error message for problem id: " //$NON-NLS-1$
+ (id & IProblem.IgnoreCategoriesMask) + ". Check compiler resources."; //$NON-NLS-1$
}
char[] message = rawMessage.toCharArray();
if (elaborationId != 0) {
String elaboration = (String) this.messageTemplates.get(keyFromID(elaborationId));
if (elaboration == null) {
return "Unable to retrieve the error message elaboration for elaboration id: " //$NON-NLS-1$
+ elaborationId + ". Check compiler resources."; //$NON-NLS-1$
}
message = CharOperation.replace(message, FIRST_ARGUMENT, elaboration.toCharArray());
}
// for compatibility with MessageFormat which eliminates double quotes in original message
message = CharOperation.replace(message, DOUBLE_QUOTES, SINGLE_QUOTE);
if (problemArguments == null) {
return new String(message);
}
int length = message.length;
int start = 0;
int end = length;
StringBuffer output = null;
if ((id & IProblem.Javadoc) != 0) {
output = new StringBuffer(10+length+problemArguments.length*20);
output.append((String) this.messageTemplates.get(keyFromID(IProblem.JavadocMessagePrefix & IProblem.IgnoreCategoriesMask)));
}
while (true) {
if ((end = CharOperation.indexOf('{', message, start)) > -1) {
if (output == null) output = new StringBuffer(length+problemArguments.length*20);
output.append(message, start, end - start);
if ((start = CharOperation.indexOf('}', message, end + 1)) > -1) {
try {
output.append(problemArguments[CharOperation.parseInt(message, end + 1, start - end - 1)]);
} catch (NumberFormatException nfe) {
output.append(message, end + 1, start - end);
} catch (ArrayIndexOutOfBoundsException e) {
return "Cannot bind message for problem (id: " //$NON-NLS-1$
+ (id & IProblem.IgnoreCategoriesMask)
+ ") \"" //$NON-NLS-1$
+ new String(message)
+ "\" with arguments: {" //$NON-NLS-1$
+ Util.toString(problemArguments)
+"}"; //$NON-NLS-1$
}
start++;
} else {
output.append(message, end, length);
break;
}
} else {
if (output == null) {
return new String(message);
}
output.append(message, start, length - start);
break;
}
}
return output.toString();
}
/**
* @param problem CategorizedProblem
* @return String
*/
public final String localizedMessage(CategorizedProblem problem) {
return getLocalizedMessage(problem.getID(), problem.getArguments());
}
/**
* This method initializes the MessageTemplates class variable according
* to the current Locale.
* @param loc Locale
* @return HashtableOfInt
*/
public static HashtableOfInt loadMessageTemplates(Locale loc) {
ResourceBundle bundle = null;
String bundleName = "org.eclipse.jdt.internal.compiler.problem.messages"; //$NON-NLS-1$
try {
bundle = ResourceBundle.getBundle(bundleName, loc);
} catch(MissingResourceException e) {
System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$
throw e;
}
HashtableOfInt templates = new HashtableOfInt(700);
Enumeration keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
try {
int messageID = Integer.parseInt(key);
templates.put(keyFromID(messageID), bundle.getString(key));
} catch (NumberFormatException | MissingResourceException e) {
// available ID
}
}
return templates;
}
}