package org.eclipse.jdt.postfixcompletion.resolver;
import java.util.List;
import org.eclipse.jdt.internal.corext.template.java.JavaVariable;
import org.eclipse.jdt.internal.ui.text.template.contentassist.MultiVariable;
import org.eclipse.jdt.postfixcompletion.core.JavaStatementPostfixContext;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.text.templates.TemplateVariableResolver;
import org.eclipse.text.edits.TextEdit;
@SuppressWarnings("restriction")
public class NewFieldResolver extends TemplateVariableResolver {
private static final int PUBLIC_ARG = 1;
private static final boolean PUBLIC_DEFAULT_VALUE = false;
private static final int FORCE_STATIC_ARG = 2;
private static final boolean FORCE_STATIC_DEFAULT_VALUE = false;
private static final int FINAL_FIELD_ARG = 3;
private static final boolean FINAL_FIELD_DEFAULT_VALUE = false;
private static final int INIT_VALUE_ARG = 4;
private static final boolean INIT_VALUE_DEFAULT_VALUE = false;
private final String defaultType;
public NewFieldResolver() {
this("java.lang.Object"); //$NON-NLS-1$
}
NewFieldResolver(String defaultType) {
this.defaultType = defaultType;
}
/*
* @see org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable, org.eclipse.jface.text.templates.TemplateContext)
*/
@SuppressWarnings("unchecked")
@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
List<String> params = variable.getVariableType().getParams();
String param;
if (params.size() == 0)
param = defaultType;
else
param = params.get(0);
JavaStatementPostfixContext jc = (JavaStatementPostfixContext) context;
TemplateVariable ref = jc.getTemplateVariable(param);
MultiVariable mv = (MultiVariable) variable;
String type = param;
if (ref instanceof MultiVariable) {
// Reference is another variable
JavaVariable refVar = (JavaVariable) ref;
jc.addDependency(refVar, mv);
type = refVar.getParamType();
}
boolean initValue = getInitValueParam(params);
boolean forceStatic = getForceStaticParam(params);
boolean publicField = getPublicParam(params);
boolean finalField = getFinalField(params);
String newType = type;
String[] names = jc.suggestFieldName(newType, finalField, forceStatic);
mv.setChoices(names);
TextEdit te = jc.addField(newType, names[0], publicField, forceStatic, finalField, (initValue && ref instanceof JavaVariable) ? getValueFromVariable((JavaVariable) ref) : null);
if (te != null) {
jc.markAsUsed(names[0]);
// We can apply it to the context
jc.applyTextEdit(te);
mv.setResolved(true);
jc.registerOutOfRangeOffset(mv, findAbsolutePositionOfFieldNameBeginning(jc.getDocument(), te, names[0]) - jc.getAffectedSourceRegion().getOffset());
} else {
// Field was not created so better do nothing
}
}
private boolean getPublicParam(List<String> params) {
if (params.size() >= PUBLIC_ARG + 1) {
String val = params.get(PUBLIC_ARG);
return convertBooleanStringParam(val);
}
return PUBLIC_DEFAULT_VALUE;
}
private boolean getForceStaticParam(List<String> params) {
if (params.size() >= FORCE_STATIC_ARG + 1) {
String val = params.get(FORCE_STATIC_ARG);
return convertBooleanStringParam(val);
}
return FORCE_STATIC_DEFAULT_VALUE;
}
private boolean getInitValueParam(List<String> params) {
if (params.size() >= INIT_VALUE_ARG + 1) {
String val = params.get(INIT_VALUE_ARG);
return convertBooleanStringParam(val);
}
return INIT_VALUE_DEFAULT_VALUE;
}
private boolean getFinalField(List<String> params) {
if (params.size() >= FINAL_FIELD_ARG + 1) {
String val = params.get(FINAL_FIELD_ARG);
return convertBooleanStringParam(val);
}
return FINAL_FIELD_DEFAULT_VALUE;
}
private String getValueFromVariable(JavaVariable var) {
for (String s : var.getValues()) {
if (s != null && s.trim().length() > 0) {
return s;
}
}
return null;
}
private boolean convertBooleanStringParam(String value) {
if ("true".equals(value)) {
return true;
} else {
return false;
}
}
private int findAbsolutePositionOfFieldNameBeginning(IDocument doc, TextEdit te, String name) {
try {
String temp = doc.get(te.getOffset(), te.getLength());
if (temp.contains("=")) {
temp = temp.substring(0, temp.indexOf("="));
}
int nameOcc = temp.lastIndexOf(name);
if (nameOcc != -1) {
return te.getOffset() + nameOcc;
}
// Variable name not included
// We try if we can determine the position with some basic logic
// This case should not happen but it's a good idea to have a fallback
int offset = temp.length();
boolean semiColonFound = false;
while (offset >= 0 && semiColonFound == false) {
if (temp.charAt(offset) == ' ' && semiColonFound) return te.getOffset() + offset;
if (temp.charAt(offset) == ';') semiColonFound = true;
}
} catch (BadLocationException e) {
}
return te.getOffset();
}
}