blob: 7387a4c1b2fd90c2d6ca1a2624127511179fe741 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.actions.IVariableValueEditor;
import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import com.ibm.icu.text.MessageFormat;
/**
* A variable value editor that prompts the user to set a primitive's value.
*/
public class JavaPrimitiveValueEditor implements IVariableValueEditor {
/**
* The signature of the edited variable.
*/
private String fSignature= null;
/**
* Creates a new editor for a variable with the given signature
* @param signature the signature of the primitive to be edited
*/
public JavaPrimitiveValueEditor(String signature) {
fSignature= signature;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IVariableValueEditor#editVariable(org.eclipse.debug.core.model.IVariable, org.eclipse.swt.widgets.Shell)
*/
public boolean editVariable(IVariable variable, Shell shell) {
try {
String name= variable.getName();
String title= ActionMessages.JavaPrimitiveValueEditor_0;
String message= MessageFormat.format(ActionMessages.JavaPrimitiveValueEditor_1, new String[] {name});
String initialValue= variable.getValue().getValueString();
PrimitiveValidator validator= new PrimitiveValidator();
InputDialog dialog= new InputDialog(shell, title, message, initialValue, validator){
protected Control createDialogArea(Composite parent) {
IWorkbench workbench = PlatformUI.getWorkbench();
workbench.getHelpSystem().setHelp(parent, IJavaDebugHelpContextIds.DEFAULT_INPUT_DIALOG);
return super.createDialogArea(parent);
}
};
if (dialog.open() == Window.OK) {
String stringValue = dialog.getValue();
stringValue = formatValue(stringValue);
if (stringValue.length() > 1 && stringValue.charAt(0) == '\\') {
// Compute value of octal of hexadecimal escape sequence
int i= validator.getEscapeValue(stringValue);
if (i != Integer.MAX_VALUE) {
stringValue= new String(new char[] { (char) i });
}
}
variable.setValue(stringValue);
}
} catch (DebugException e) {
JDIDebugUIPlugin.errorDialog(shell, ActionMessages.JavaPrimitiveValueEditor_2, ActionMessages.JavaPrimitiveValueEditor_3, e); //
}
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IVariableValueEditor#saveVariable(org.eclipse.debug.core.model.IVariable, java.lang.String, org.eclipse.swt.widgets.Shell)
*/
public boolean saveVariable(IVariable variable, String expression, Shell shell) {
return false;
}
String formatValue(String value) {
try {
switch (fSignature.charAt(0)) {
case 'I':
return Integer.toString(ASTInstructionCompiler.parseIntValue(value));
case 'J':
return Long.toString(ASTInstructionCompiler.parseLongValue(value));
case 'S':
return Short.toString(ASTInstructionCompiler.parseShortValue(value));
case 'F':
case 'D':
return ASTInstructionCompiler.removePrefixZerosAndUnderscores(value, false);
case 'B':
return Byte.toString(ASTInstructionCompiler.parseByteValue(value));
}
}
catch(NumberFormatException nfe) {}
return value;
}
/**
* Input validator for primitive types
*/
protected class PrimitiveValidator implements IInputValidator {
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
*/
public String isValid(String newText) {
String type= null;
switch (fSignature.charAt(0)) {
case 'B':
try {
Byte.parseByte(newText);
} catch (NumberFormatException e) {
type= "byte"; //$NON-NLS-1$
}
break;
case 'C':
if (newText.length() > 1 && newText.charAt(0) == '\\') {
// Possibly an escaped character
if (isSpecialCharacter(newText) ||
isOctalEscape(newText) ||
isUnicode(newText)) {
break;
}
}
if (newText.length() != 1) {
type="char"; //$NON-NLS-1$
}
break;
case 'D':
try {
Double.parseDouble(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false));
} catch (NumberFormatException e) {
type="double"; //$NON-NLS-1$
}
break;
case 'F':
try {
Float.parseFloat(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false));
} catch (NumberFormatException e) {
type="float"; //$NON-NLS-1$
}
break;
case 'I':
try {
ASTInstructionCompiler.parseIntValue(newText);
} catch (NumberFormatException e) {
type="int"; //$NON-NLS-1$
}
break;
case 'J':
try {
ASTInstructionCompiler.parseLongValue(newText);
} catch (NumberFormatException e) {
type="long"; //$NON-NLS-1$
}
break;
case 'S':
try {
ASTInstructionCompiler.parseShortValue(newText);
} catch (NumberFormatException e) {
type="short"; //$NON-NLS-1$
}
break;
case 'Z':
if (!("true".equals(newText) || "false".equals(newText))) { //$NON-NLS-1$ //$NON-NLS-2$
type="boolean"; //$NON-NLS-1$
}
break;
}
if (type != null) {
return MessageFormat.format(ActionMessages.JavaPrimitiveValueEditor_4, new String[] { type });
}
return null;
}
private boolean isUnicode(String newText) {
if (newText.length() == 6) {
if (newText.charAt(1) == 'u') {
char[] chars = newText.toCharArray();
for (int i = 2; i < chars.length; i++) {
if (!isHexDigit(chars[i])) {
return false;
}
}
return true;
}
}
return false;
}
private boolean isOctalEscape(String newText) {
char[] chars= newText.toCharArray();
if (chars.length < 4) {
for (int i = 1; i < chars.length; i++) {
if (!isOctalDigit(chars[i])) {
return false;
}
}
return true;
} else if (chars.length == 4) {
char ch= chars[1];
if (ch < '0' || ch > '3') {
return false;
}
for (int i = 2; i < chars.length; i++) {
if (!isOctalDigit(chars[i])) {
return false;
}
}
return true;
}
return false;
}
private boolean isSpecialCharacter(String newText) {
char ch= newText.charAt(1);
return newText.length() == 2 &&
(ch == 'b' ||
ch == 't' ||
ch == 'n' ||
ch == 'f' ||
ch == 'r' ||
ch == '"' ||
ch == '\'' ||
ch == '\\');
}
private boolean isOctalDigit(char ch) {
return Character.digit(ch, 8) != -1;
}
private boolean isHexDigit(char ch) {
return Character.digit(ch, 16) != -1;
}
/**
* Returns the integer value specified by the given string, which
* represents an octal or hexadecimal escape sequence. Returns
* Integer.MAX_VALUE if the given string is not a valid octal or
* hexadecimal escape sequence.
*
* @param string
* @return
*/
protected int getEscapeValue(String string) {
return ASTInstructionCompiler.parseIntValue(string);
}
}
}