blob: 15dd39d938b25da21d000660f768cb64520a3b54 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 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 API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.web.core.internal.java;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.Position;
import org.eclipse.wst.jsdt.core.IBuffer;
import org.eclipse.wst.jsdt.core.ICompilationUnit;
import org.eclipse.wst.jsdt.core.IJavaElement;
import org.eclipse.wst.jsdt.core.IJavaProject;
import org.eclipse.wst.jsdt.core.IPackageDeclaration;
import org.eclipse.wst.jsdt.core.IPackageFragment;
import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
import org.eclipse.wst.jsdt.core.ISourceRange;
import org.eclipse.wst.jsdt.core.JavaCore;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
import org.eclipse.wst.jsdt.internal.core.JavaModel;
import org.eclipse.wst.jsdt.internal.core.SourceRefElement;
import org.eclipse.wst.jsdt.ui.StandardJavaElementContentProvider;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
/**
* <p>
* An implementation of IJSPTranslation. <br>
* This object that holds the java translation of a JSP file as well as a
* mapping of ranges from the translated Java to the JSP source, and mapping
* from JSP source back to the translated Java.
* </p>
*
* <p>
* You may also use JSPTranslation to do CompilationUnit-esque things such as:
* <ul>
* <li>code select (get java elements for jsp selection)</li>
* <li>reconcile</li>
* <li>get java regions for jsp selection</li>
* <li>get a JSP text edit based on a Java text edit</li>
* <li>determine if a java offset falls within a jsp:useBean range</li>
* <li>determine if a java offset falls within a jsp import statment</li>
* </ul>
* </p>
*
* @author pavery
*/
public class JSPTranslation implements IJSPTranslation {
// for debugging
private static final boolean DEBUG;
static {
String value = Platform
.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsptranslation"); //$NON-NLS-1$
DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
}
/** the name of the class (w/out extension) * */
private String fClassname = ""; //$NON-NLS-1$
private IJavaProject fJavaProject = null;
private HashMap fJava2JspMap = null;
private HashMap fJsp2JavaMap = null;
private HashMap fJava2JspImportsMap = null;
/*
* private HashMap fJava2JspUseBeanMap = null; private HashMap
* fJava2JspIndirectMap = null;
*/
// don't want to hold onto model (via translator)
// all relevant info is extracted in the constructor.
private JSPTranslator fTranslator = null;
private String fJavaText = ""; //$NON-NLS-1$
private String fJspText = ""; //$NON-NLS-1$
private ICompilationUnit fCompilationUnit = null;
private IProgressMonitor fProgressMonitor = null;
/** lock to synchronize access to the compilation unit * */
private byte[] fLock = null;
private String fMangledName;
private String fJspName;
private static StandardJavaElementContentProvider fStandardJavaElementContentProvider;
public JSPTranslation(IJavaProject javaProj, JSPTranslator translator) {
fLock = new byte[0];
fJavaProject = javaProj;
fTranslator = translator;
// can be null if it's an empty document (w/ NullJSPTranslation)
if (translator != null) {
fJavaText = translator.getTranslation().toString();
fJspText = translator.getJspText();
fClassname = translator.getClassname();
fJava2JspMap = translator.getJava2JspRanges();
fJsp2JavaMap = translator.getJsp2JavaRanges();
fJava2JspImportsMap = translator.getJava2JspImportRanges();
// fJava2JspUseBeanMap = translator.getJava2JspUseBeanRanges();
// fJava2JspIndirectMap = translator.getJava2JspIndirectRanges();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJavaProject()
*/
public IJavaProject getJavaProject() {
return fJavaProject;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.IJSPTranslation#getJavaText()
*/
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJavaText()
*/
public String getJavaText() {
System.out.println("JSPTranslation.getJavaText():\n" + fJavaText
+ "-----------");
return (fTranslator != null) ? fTranslator.getTranslation().toString()
: ""; //$NON-NLS-1$
// return fJavaText;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJspText()
*/
public String getJspText() {
return (fTranslator != null) ? fTranslator.getJspText() : ""; //$NON-NLS-1$
// System.out.println("JSPTranslation.getJspText():\n" + fJspText +
// "-----------");
// return fJspText;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJavaPath()
*/
public String getJavaPath() {
// create if necessary
ICompilationUnit cu = getCompilationUnit();
return (cu != null) ? cu.getPath().toString() : ""; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJavaOffset(int)
*/
public int getJavaOffset(int jspOffset) {
int result = -1;
int offsetInRange = 0;
Position jspPos, javaPos = null;
// iterate all mapped jsp ranges
Iterator it = fJsp2JavaMap.keySet().iterator();
while (it.hasNext()) {
jspPos = (Position) it.next();
// need to count the last position as included
if (!jspPos.includes(jspOffset)
&& !(jspPos.offset + jspPos.length == jspOffset)) {
continue;
}
offsetInRange = jspOffset - jspPos.offset;
javaPos = (Position) fJsp2JavaMap.get(jspPos);
if (javaPos != null) {
result = javaPos.offset + offsetInRange;
} else {
Logger.log(Logger.ERROR, "JavaPosition was null!" + jspOffset); //$NON-NLS-1$
}
break;
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJspOffset(int)
*/
public int getJspOffset(int javaOffset) {
int result = -1;
int offsetInRange = 0;
Position jspPos, javaPos = null;
// iterate all mapped java ranges
Iterator it = fJava2JspMap.keySet().iterator();
while (it.hasNext()) {
javaPos = (Position) it.next();
// need to count the last position as included
if (!javaPos.includes(javaOffset)
&& !(javaPos.offset + javaPos.length == javaOffset)) {
continue;
}
offsetInRange = javaOffset - javaPos.offset;
jspPos = (Position) fJava2JspMap.get(javaPos);
if (jspPos != null) {
result = jspPos.offset + offsetInRange;
} else {
Logger.log(Logger.ERROR, "jspPosition was null!" + javaOffset); //$NON-NLS-1$
}
break;
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJava2JspMap()
*/
public HashMap getJava2JspMap() {
return fJava2JspMap;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJsp2JavaMap()
*/
public HashMap getJsp2JavaMap() {
return fJsp2JavaMap;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#javaSpansMultipleJspPartitions(int,
* int)
*/
public boolean javaSpansMultipleJspPartitions(int javaOffset, int javaLength) {
HashMap java2jsp = getJava2JspMap();
int count = 0;
Iterator it = java2jsp.keySet().iterator();
Position javaRange = null;
while (it.hasNext()) {
javaRange = (Position) it.next();
if (javaRange.overlapsWith(javaOffset, javaLength)) {
count++;
}
if (count > 1) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getJavaRanges(int,
* int)
*/
public Position[] getJavaRanges(int offset, int length) {
List results = new ArrayList();
Iterator it = getJava2JspMap().keySet().iterator();
Position p = null;
while (it.hasNext()) {
p = (Position) it.next();
if (p.overlapsWith(offset, length)) {
results.add(p);
}
}
return (Position[]) results.toArray(new Position[results.size()]);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#isImport(int)
*/
public boolean isImport(int javaOffset) {
return isInRanges(javaOffset, fJava2JspImportsMap);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#isUseBean(int)
*/
public boolean isUseBean(int javaOffset) {
System.out.println("REMOVE JSPTranslation.isUseBean(int javaOffset)");
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#isIndirect(int)
*/
public boolean isIndirect(int javaOffset) {
System.out
.println("IMPLEMENT JSPTranslation.isIndirect(int javaOffset)");
return false;
// return isInRanges(javaOffset, fJava2JspIndirectMap, false);
}
private boolean isInRanges(int javaOffset, HashMap ranges) {
return isInRanges(javaOffset, ranges, true);
}
/**
* Tells you if the given offset is included in any of the ranges
* (Positions) passed in. includeEndOffset tells whether or not to include
* the end offset of each range in the test.
*
* @param javaOffset
* @param ranges
* @param includeEndOffset
* @return
*/
private boolean isInRanges(int javaOffset, HashMap ranges,
boolean includeEndOffset) {
Iterator it = ranges.keySet().iterator();
while (it.hasNext()) {
Position javaPos = (Position) it.next();
// also include the start and end offset (only if requested)
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=81687
if (javaPos.includes(javaOffset)
|| (includeEndOffset && javaPos.offset + javaPos.length == javaOffset)) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getCompilationUnit()
*/
public ICompilationUnit getCompilationUnit() {
synchronized (fLock) {
try {
if (fCompilationUnit == null) {
fCompilationUnit = createCompilationUnit();
}
reconcileCompilationUnit();
} catch (JavaModelException jme) {
if (DEBUG) {
Logger.logException(
"error creating JSP working copy... ", jme); //$NON-NLS-1$
}
}
}
return fCompilationUnit;
}
public IJavaElement getJavaElementAtOffset(int htmlstart){
IJavaElement elements=null;
int jsOffset = getJavaOffset(htmlstart);
// Position[] positions = getJavaRanges(htmlOffset, length);
//
ICompilationUnit cu = getCompilationUnit();
synchronized(cu){
try {
elements = cu.getElementAt(jsOffset);
} catch (JavaModelException e) {
// TODO Auto-generated catch block
if(DEBUG){
Logger.logException(
"error retrieving java elemtnt from compilation unit... ", e); //$NON-NLS-1$
}
}
}
return elements;
}
private String getMangledName() {
return fMangledName;
}
private void setMangledName(String mangledName) {
fMangledName = mangledName;
}
private String getJspName() {
return fJspName;
}
private void setJspName(String jspName) {
fJspName = jspName;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#fixupMangledName(java.lang.String)
*/
public String fixupMangledName(String displayString) {
if (displayString == null) {
return null;
}
if (getJspName() == null || getMangledName() == null) {
// names not set yet
initJspAndServletNames();
}
return displayString.replaceAll(getMangledName(), getJspName());
}
private ISourceRange getJSSourceRangeOf(IJavaElement element){
// returns the offset in html of given element
ISourceRange range = null;
if(element instanceof SourceRefElement){
try {
range = ((SourceRefElement)element).getSourceRange();
} catch (JavaModelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return range;
}
private void initJspAndServletNames() {
ICompilationUnit cu = getCompilationUnit();
if (cu != null) {
String cuName = null;
synchronized (cu) {
// set some names for fixing up mangled name in proposals
// set mangled (servlet) name
cuName = cu.getPath().lastSegment();
}
if (cuName != null) {
setMangledName(cuName.substring(0, cuName.lastIndexOf('.')));
// set name of jsp file
String unmangled = JSP2ServletNameUtil.unmangle(cuName);
setJspName(unmangled.substring(unmangled.lastIndexOf('/') + 1,
unmangled.lastIndexOf('.')));
}
}
}
/**
* Originally from ReconcileStepForJava. Creates an ICompilationUnit from
* the contents of the JSP document.
*
* @return an ICompilationUnit from the contents of the JSP document
*/
private ICompilationUnit createCompilationUnit() throws JavaModelException {
IPackageFragment packageFragment = null;
IJavaElement je = getJavaProject();
if (je == null || !je.exists()) {
return null;
}
switch (je.getElementType()) {
case IJavaElement.PACKAGE_FRAGMENT:
je = je.getParent();
// fall through
case IJavaElement.PACKAGE_FRAGMENT_ROOT:
IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) je;
packageFragment = packageFragmentRoot
.getPackageFragment(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH);
break;
case IJavaElement.JAVA_PROJECT:
IJavaProject jProject = (IJavaProject) je;
if (!jProject.exists()) {
if (DEBUG) {
System.out
.println("** Abort create working copy: cannot create working copy: JSP is not in a Java project"); //$NON-NLS-1$
}
return null;
}
// packageFragmentRoot = null;
// packageFragmentRoot=JavaModelUtil.getPackageFragmentRoot(jProject);
// IPackageFragmentRoot[] packageFragmentRoots =
// jProject.getPackageFragmentRoots();
packageFragmentRoot = jProject.getPackageFragmentRoot(jProject
.getUnderlyingResource());
if (packageFragmentRoot instanceof ICompilationUnit) {
return (ICompilationUnit) packageFragmentRoot;
}
/*
* int i = 0; while (i < packageFragmentRoots.length) { if
* (!packageFragmentRoots[i].isArchive() &&
* !packageFragmentRoots[i].isExternal() ) { packageFragmentRoot =
* packageFragmentRoots[i]; System.out.println("Accepting package
* fragment root:" + packageFragmentRoots[i].getElementName());
* System.out.println("this is fragment number" + i + " out of
* "+packageFragmentRoots.length ); break; } i++; }
*/
if (packageFragmentRoot == null) {
if (DEBUG) {
System.out
.println("** Abort create working copy: cannot create working copy: JSP is not in a Java project with source package fragment root"); //$NON-NLS-1$
}
return null;
}
/*
* for(int j =0; j<packageFragmentRoots.length;j++){
* System.out.println(packageFragmentRoots[j].getElementName());; }
*/
packageFragment = packageFragmentRoot
.getPackageFragment(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH);
break;
default:
return null;
}
// JavaModelManager.createCompilationUnitFrom(file, project)
ICompilationUnit cu = packageFragment.getCompilationUnit(
getClassname() + JsDataTypes.BASE_FILE_EXTENSION)
.getWorkingCopy(getWorkingCopyOwner(), getProblemRequestor(),
getProgressMonitor());
setContents(cu);
// cu.makeConsistent(getProgressMonitor());
// cu.reconcile(ICompilationUnit.NO_AST, true, getWorkingCopyOwner(),
// getProgressMonitor());
if (DEBUG) {
String cuText = cu.toString();
System.out
.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); //$NON-NLS-1$
System.out
.println("(+) JSPTranslation [" + this + "] finished creating CompilationUnit: " + cu); //$NON-NLS-1$ //$NON-NLS-2$
System.out
.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); //$NON-NLS-1$
IPackageDeclaration[] ipd = cu.getPackageDeclarations();
for (int i = 0; i < ipd.length; i++) {
System.out.println("JSPTranslation.getCU() Package:"
+ ipd[i].getElementName());
}
}
return cu;
}
/**
*
* @return the problem requestor for the CompilationUnit in this
* JSPTranslation
*/
private JSPProblemRequestor getProblemRequestor() {
return CompilationUnitHelper.getInstance().getProblemRequestor();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getWorkingCopyOwner()
*/
public WorkingCopyOwner getWorkingCopyOwner() {
return CompilationUnitHelper.getInstance().getWorkingCopyOwner();
}
/**
*
* @return the progress monitor used in long operations (reconcile, creating
* the CompilationUnit...) in this JSPTranslation
*/
private IProgressMonitor getProgressMonitor() {
if (fProgressMonitor == null) {
fProgressMonitor = new NullProgressMonitor();
}
return fProgressMonitor;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getProblems()
*/
public List getProblems() {
List problems = getProblemRequestor().getCollectedProblems();
return problems != null ? problems : new ArrayList();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getELProblems()
*/
public List getELProblems() {
System.out.println("Remove JSPTranslation.getELProblems()");
return null;
// return fELProblems != null ? fELProblems : new ArrayList();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#setProblemCollectingActive(boolean)
*/
public void setProblemCollectingActive(boolean collect) {
ICompilationUnit cu = getCompilationUnit();
if (cu != null) {
getProblemRequestor().setIsActive(collect);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#reconcileCompilationUnit()
*/
public void reconcileCompilationUnit() {
ICompilationUnit cu = fCompilationUnit;
if(fCompilationUnit==null) return;
if (cu != null) {
try {
synchronized (cu) {
cu.makeConsistent(getProgressMonitor());
cu.reconcile(ICompilationUnit.NO_AST, true,
getWorkingCopyOwner(), getProgressMonitor());
}
} catch (JavaModelException e) {
Logger.logException(e);
}
}
}
/**
* Set contents of the compilation unit to the translated jsp text.
*
* @param the
* ICompilationUnit on which to set the buffer contents
*/
private void setContents(ICompilationUnit cu) {
if (cu == null) {
return;
}
synchronized (cu) {
IBuffer buffer;
try {
buffer = cu.getBuffer();
} catch (JavaModelException e) {
e.printStackTrace();
buffer = null;
}
if (buffer != null) {
buffer.setContents(getJavaText());
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getElementsFromJspRange(int,
* int)
*/
// public IJavaElement[] getElementsFromJspRange(int jspStart, int jspEnd) {
//
// int javaPositionStart = getJavaOffset(jspStart);
// int javaPositionEnd = getJavaOffset(jspEnd);
//
// IJavaElement[] EMTPY_RESULT_SET = new IJavaElement[0];
// IJavaElement[] result = EMTPY_RESULT_SET;
// try {
// ICompilationUnit cu = getCompilationUnit();
// // cu.makeConsistent(getProgressMonitor());
// //cu.reconcile(ICompilationUnit.NO_AST, true, getWorkingCopyOwner(), getProgressMonitor());
// if (cu != null) {
// synchronized (cu) {
// int cuDocLength = cu.getBuffer().getLength();
// int javaLength = javaPositionEnd - javaPositionStart;
// if (cuDocLength > 0 && javaPositionStart >= 0
// && javaLength >= 0 && javaPositionEnd <= cuDocLength) {
//
// result = cu.codeSelect(javaPositionStart, javaLength,getWorkingCopyOwner());
//
// }
// }
// }
//
// if (result == null || result.length == 0) {
// return EMTPY_RESULT_SET;
// }
// } catch (JavaModelException x) {
// Logger.logException(x);
// }
//
// return result;
// }
public IJavaElement[] getElementsFromJspRange(int jspStart, int jspEnd){
return getElementsFromJspRange(jspStart,jspEnd,false);
}
public IJavaElement[] getElementsFromJspRange(int jspStart, int jspEnd,boolean precise) {
int javaPositionStart = getJavaOffset(jspStart);
int javaPositionEnd = getJavaOffset(jspEnd);
IJavaElement[] EMTPY_RESULT_SET = new IJavaElement[0];
IJavaElement[] result = EMTPY_RESULT_SET;
ICompilationUnit cu = getCompilationUnit();
IJavaElement[] allChildren = null;
synchronized(cu){
try {
allChildren = cu.getChildren();
} catch (JavaModelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Vector validChildren = new Vector();
for(int i = 0;i< allChildren.length;i++ ){
if(allChildren[i] instanceof IJavaElement && allChildren[i].getElementType()!= IJavaElement.PACKAGE_DECLARATION){
ISourceRange range = getJSSourceRangeOf((IJavaElement)allChildren[i]);
if(precise && javaPositionStart<=range.getOffset() && range.getLength()+range.getOffset() <= (javaPositionEnd)){
//if(precise && range.getOffset()>=javaPo && range.getLength()+range.getOffset() <= (javaPositionEnd)){
validChildren.add(allChildren[i]);
}else if(!precise && range.getOffset()<=javaPositionStart && ((range.getOffset() + range.getLength())>= javaPositionEnd)){
validChildren.add(allChildren[i]);
}
}
}
if(validChildren.size()>0) result = (IJavaElement[])validChildren.toArray(new IJavaElement[]{});
if (result == null || result.length == 0) {
return EMTPY_RESULT_SET;
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#getClassname()
*/
public String getClassname() {
return fClassname;
}
public static StandardJavaElementContentProvider getElementProvider(){
if(fStandardJavaElementContentProvider==null){
fStandardJavaElementContentProvider = new StandardJavaElementContentProvider();
}
return fStandardJavaElementContentProvider;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslation_Interface#release()
*/
public void release() {
synchronized (fLock) {
if (fCompilationUnit != null) {
try {
if (DEBUG) {
System.out
.println("------------------------------------------------------------------"); //$NON-NLS-1$
System.out
.println("(-) JSPTranslation [" + this + "] discarding CompilationUnit: " + fCompilationUnit); //$NON-NLS-1$ //$NON-NLS-2$
System.out
.println("------------------------------------------------------------------"); //$NON-NLS-1$
}
fCompilationUnit.discardWorkingCopy();
} catch (JavaModelException e) {
// we're done w/ it anyway
}
}
}
}
}