/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package net.sourceforge.phpdt.internal.corext.template.php;
import java.lang.reflect.InvocationTargetException;
import net.sourceforge.phpdt.core.ICompilationUnit;
import net.sourceforge.phpdt.core.JavaModelException;
import net.sourceforge.phpdt.internal.corext.Assert;
import net.sourceforge.phpdt.internal.corext.template.ContextType;
import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
import net.sourceforge.phpdt.internal.corext.template.Template;
import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitCompletion.LocalVariable;
import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
import net.sourceforge.phpeclipse.PHPeclipsePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Shell;
/**
* A context for java source.
*/
public class JavaContext extends PHPUnitContext {
/** The platform default line delimiter. */
private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$
/** A code completion requestor for guessing local variable names. */
private CompilationUnitCompletion fCompletion;
/**
* Creates a java template context.
*
* @param type the context type.
* @param document the document.
* @param completionOffset the completion offset within the document.
* @param completionLength the completion length.
* @param unit the compilation unit (may be null
).
*/
public JavaContext(ContextType type, IDocument document, int completionOffset, int completionLength,
ICompilationUnit compilationUnit)
{
super(type, document, completionOffset, completionLength); //, compilationUnit);
}
/**
* Returns the indentation level at the position of code completion.
*/
private int getIndentation() {
// int start= getStart();
// IDocument document= getDocument();
// try {
// IRegion region= document.getLineInformationOfOffset(start);
// String lineContent= document.get(region.getOffset(), region.getLength());
// return Strings.computeIndent(lineContent, CodeFormatterUtil.getTabWidth());
// } catch (BadLocationException e) {
// return 0;
// }
return 0;
}
/*
* @see TemplateContext#evaluate(Template template)
*/
public TemplateBuffer evaluate(Template template) throws CoreException {
if (!canEvaluate(template))
return null;
TemplateTranslator translator= new TemplateTranslator();
TemplateBuffer buffer= translator.translate(template.getPattern());
getContextType().edit(buffer, this);
String lineDelimiter= null;
try {
lineDelimiter= getDocument().getLineDelimiter(0);
} catch (BadLocationException e) {
}
if (lineDelimiter == null)
lineDelimiter= PLATFORM_LINE_DELIMITER;
IPreferenceStore prefs= PHPeclipsePlugin.getDefault().getPreferenceStore();
// boolean useCodeFormatter= prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);
//
// ITemplateEditor formatter= new JavaFormatter(lineDelimiter, getIndentation(), useCodeFormatter);
// formatter.edit(buffer, this);
return buffer;
}
/*
* @see TemplateContext#canEvaluate(Template templates)
*/
public boolean canEvaluate(Template template) {
String key= getKey();
if (fForceEvaluation)
return true;
return
template.matches(key, getContextType().getName()) &&
key.length() != 0 && template.getName().toLowerCase().startsWith(key.toLowerCase());
}
/*
* @see DocumentTemplateContext#getCompletionPosition();
*/
public int getStart() {
try {
IDocument document= getDocument();
if (getCompletionLength() == 0) {
int start= getCompletionOffset();
while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
start--;
if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
start--;
return start;
} else {
int start= getCompletionOffset();
int end= getCompletionOffset() + getCompletionLength();
while (start != 0 && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
start--;
while (start != end && Character.isWhitespace(document.getChar(start)))
start++;
if (start == end)
start= getCompletionOffset();
return start;
}
} catch (BadLocationException e) {
return super.getStart();
}
}
/*
* @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getEnd()
*/
public int getEnd() {
if (getCompletionLength() == 0)
return super.getEnd();
try {
IDocument document= getDocument();
int start= getCompletionOffset();
int end= getCompletionOffset() + getCompletionLength();
while (start != end && Character.isWhitespace(document.getChar(end - 1)))
end--;
return end;
} catch (BadLocationException e) {
return super.getEnd();
}
}
/*
* @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getKey()
*/
public String getKey() {
if (getCompletionLength() == 0)
return super.getKey();
try {
IDocument document= getDocument();
int start= getStart();
int end= getCompletionOffset();
return start <= end
? document.get(start, end - start)
: ""; //$NON-NLS-1$
} catch (BadLocationException e) {
return super.getKey();
}
}
/**
* Returns the character before start position of completion.
*/
public char getCharacterBeforeStart() {
int start= getStart();
try {
return start == 0
? ' '
: getDocument().getChar(start - 1);
} catch (BadLocationException e) {
return ' ';
}
}
private CompilationUnitCompletion guessVariableNames() {
// ICompilationUnit unit= getCompilationUnit();
// int start= getStart();
//
// if (unit == null)
// return null;
//
// try {
// CompilationUnitCompletion collector= new CompilationUnitCompletion(unit);
// unit.codeComplete(start, collector);
// return collector;
//
// } catch (JavaModelException e) {
// handleException(null, e);
// return null;
// }
return null;
}
private static void handleException(Shell shell, Exception e) {
String title= PHPTemplateMessages.getString("JavaContext.error.title"); //$NON-NLS-1$
if (e instanceof CoreException)
ExceptionHandler.handle((CoreException)e, shell, title, null);
else if (e instanceof InvocationTargetException)
ExceptionHandler.handle((InvocationTargetException)e, shell, title, null);
else {
PHPeclipsePlugin.log(e);
MessageDialog.openError(shell, title, e.getMessage());
}
}
private CompilationUnitCompletion getCompletion() {
// ICompilationUnit compilationUnit= getCompilationUnit();
// if (fCompletion == null) {
// fCompletion= new CompilationUnitCompletion(compilationUnit);
//
// if (compilationUnit != null) {
// try {
// compilationUnit.codeComplete(getStart(), fCompletion);
// } catch (JavaModelException e) {
// // ignore
// }
// }
// }
//
// return fCompletion;
return null;
}
/**
* Returns the name of a guessed local array, null
if no local
* array exists.
*/
public String guessArray() {
CompilationUnitCompletion completion= getCompletion();
LocalVariable[] localArrays= completion.findLocalArrays();
if (localArrays.length > 0)
return localArrays[localArrays.length - 1].name;
return null;
}
/**
* Returns the name of the type of a local array, null
if no local
* array exists.
*/
public String guessArrayType() {
CompilationUnitCompletion completion= getCompletion();
LocalVariable[] localArrays= completion.findLocalArrays();
if (localArrays.length > 0) {
LocalVariable localArray= localArrays[localArrays.length - 1];
String arrayTypeName= localArray.typeName;
String typeName= getScalarType(arrayTypeName);
int dimension= getArrayDimension(arrayTypeName) - 1;
Assert.isTrue(dimension >= 0);
String qualifiedName= createQualifiedTypeName(localArray.typePackageName, typeName);
String innerTypeName= completion.simplifyTypeName(qualifiedName);
return innerTypeName == null
? createArray(typeName, dimension)
: createArray(innerTypeName, dimension);
}
return null;
}
private static String createArray(String type, int dimension) {
StringBuffer buffer= new StringBuffer(type);
for (int i= 0; i < dimension; i++)
buffer.append("[]"); //$NON-NLS-1$
return buffer.toString();
}
private static String getScalarType(String type) {
return type.substring(0, type.indexOf('['));
}
private static int getArrayDimension(String type) {
int dimension= 0;
int index= type.indexOf('[');
while (index != -1) {
dimension++;
index= type.indexOf('[', index + 1);
}
return dimension;
}
private static String createQualifiedTypeName(String packageName, String className) {
StringBuffer buffer= new StringBuffer();
if (packageName.length() != 0) {
buffer.append(packageName);
buffer.append('.');
}
buffer.append(className);
return buffer.toString();
}
/**
* Returns a proposal for a variable name of a local array element, null
* if no local array exists.
*/
public String guessArrayElement() {
// CompilationUnitCompletion completion= getCompletion();
// LocalVariable[] localArrays= completion.findLocalArrays();
//
// if (localArrays.length > 0) {
// int idx= localArrays.length - 1;
//
// LocalVariable var= localArrays[idx];
//
// IJavaProject project= getCompilationUnit().getJavaProject();
// String typeName= var.typeName;
// String baseTypeName= typeName.substring(0, typeName.lastIndexOf('['));
//
// String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, baseTypeName, 0, completion.getLocalVariableNames());
// if (proposals.length > 0) {
// return proposals[0];
// }
// }
return null;
}
/**
* Returns an array index name. 'i', 'j', 'k' are tried until no name collision with
* an existing local variable occurs. If all names collide, null
is returned.
*/
public String getIndex() {
CompilationUnitCompletion completion= getCompletion();
String[] proposals= {"i", "j", "k"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
for (int i= 0; i != proposals.length; i++) {
String proposal = proposals[i];
if (!completion.existsLocalName(proposal))
return proposal;
}
return null;
}
/**
* Returns the name of a local collection, null
if no local collection
* exists.
*/
public String guessCollection() {
CompilationUnitCompletion completion= getCompletion();
try {
LocalVariable[] localCollections= completion.findLocalCollections();
if (localCollections.length > 0)
return localCollections[localCollections.length - 1].name;
} catch (JavaModelException e) {
PHPeclipsePlugin.log(e);
}
return null;
}
/**
* Returns an iterator name ('iter'). If 'iter' already exists as local variable,
* null
is returned.
*/
public String getIterator() {
CompilationUnitCompletion completion= getCompletion();
String[] proposals= {"iter"}; //$NON-NLS-1$
for (int i= 0; i != proposals.length; i++) {
String proposal = proposals[i];
if (!completion.existsLocalName(proposal))
return proposal;
}
return null;
}
// public void addIteratorImport() {
//
// try {
// CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings();
// ImportsStructure structure= new ImportsStructure(getCompilationUnit(), settings.importOrder, settings.importThreshold, true);
// structure.addImport("java.util.Iterator"); //$NON-NLS-1$
// structure.create(false, null);
//
// } catch (CoreException e) {
// handleException(null, e);
// }
// }
/**
* Evaluates a 'java' template in thecontext of a compilation unit
*/
public static String evaluateTemplate(Template template, ICompilationUnit compilationUnit, int position) throws CoreException {
ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
if (contextType == null)
throw new CoreException(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, PHPTemplateMessages.getString("JavaContext.error.message"), null)); //$NON-NLS-1$
IDocument document= new Document();
// if (compilationUnit != null && compilationUnit.exists())
// document.set(compilationUnit.getSource());
JavaContext context= new JavaContext(contextType, document, position, 0, compilationUnit);
context.setForceEvaluation(true);
TemplateBuffer buffer= context.evaluate(template);
if (buffer == null)
return null;
return buffer.getString();
}
}