/******************************************************************************* * 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(); } }