blob: 46fd1b4ba22c82c2de6360fbc05b39efe2a055f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 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 API and implementation
*******************************************************************************/
package org.eclipse.jdt.core;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.core.BufferManager;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.ExternalJavaProject;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
/**
* The owner of an {@link ICompilationUnit} handle in working copy mode.
* An owner is used to identify a working copy and to create its buffer.
* <p>
* Clients should subclass this class to instantiate a working copy owner that is specific to their need and that
* they can pass in to various APIs (e.g. {@link IType#resolveType(String, WorkingCopyOwner)}.
* Clients can also override the default implementation of {@link #createBuffer(ICompilationUnit)}.
* </p><p>
* Note: even though this class has no abstract method, which means that it provides functional default behavior,
* it is still an abstract class, as clients are intended to own their owner implementation.
* </p>
* @see ICompilationUnit#becomeWorkingCopy(org.eclipse.core.runtime.IProgressMonitor)
* @see ICompilationUnit#discardWorkingCopy()
* @see ICompilationUnit#getWorkingCopy(org.eclipse.core.runtime.IProgressMonitor)
* @since 3.0
*/
public abstract class WorkingCopyOwner {
/**
* Sets the buffer provider of the primary working copy owner. Note that even if the
* buffer provider is a working copy owner, only its <code>createBuffer(ICompilationUnit)</code>
* method is used by the primary working copy owner. It doesn't replace the internal primary
* working owner.
* <p>
* This method is for internal use by the jdt-related plug-ins.
* Clients outside of the jdt should not reference this method.
* </p>
*
* @param primaryBufferProvider the primary buffer provider
*/
public static void setPrimaryBufferProvider(WorkingCopyOwner primaryBufferProvider) {
DefaultWorkingCopyOwner.PRIMARY.primaryBufferProvider = primaryBufferProvider;
}
/**
* Creates a buffer for the given working copy.
* The new buffer will be initialized with the contents of the underlying file
* if and only if it was not already initialized by the compilation owner (a buffer is
* uninitialized if its content is <code>null</code>).
* <p>
* Note: This buffer will be associated to the working copy for its entire life-cycle. Another
* working copy on same unit but owned by a different owner would not share the same buffer
* unless its owner decided to implement such a sharing behaviour.
* </p>
*
* @param workingCopy the working copy of the buffer
* @return IBuffer the created buffer for the given working copy
* @see IBuffer
*/
public IBuffer createBuffer(ICompilationUnit workingCopy) {
return BufferManager.createBuffer(workingCopy);
}
/**
* Returns the problem requestor used by a working copy of this working copy owner.
* <p>
* By default, no problem requestor is configured. Clients can override this
* method to provide a requestor.
* </p>
*
* @param workingCopy The problem requestor used for the given working copy.
* @return the problem requestor to be used by working copies of this working
* copy owner or <code>null</code> if no problem requestor is configured.
*
* @since 3.3
*/
public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
return null;
}
/**
* Returns the source of the compilation unit that defines the given type in
* the given package, or <code>null</code> if the type is unknown to this
* owner.
* <p>This method is called before the normal lookup (i.e. before looking
* at the project's classpath and before looking at the working copies of this
* owner.)</p>
* <p>This allows to provide types that are not normally available, or to hide
* types that would normally be available by returning an empty source for
* the given type and package.</p>
* <p>Example of use:
* <pre>
* WorkingCopyOwner owner = new WorkingCopyOwner() {
* public String findSource(String typeName, String packageName) {
* if ("to.be".equals(packageName) && "Generated".equals(typeName)) {
* return
* "package to.be;\n" +
* "public class Generated {\n" +
* "}";
* }
* return super.findSource(typeName, packageName);
* }
* public boolean isPackage(String[] pkg) {
* switch (pkg.length) {
* case 1:
* return "to".equals(pkg[0]);
* case 2:
* return "to".equals(pkg[0]) && "be".equals(pkg[1]);
* }
* return false;
* }
* };
* // Working copy on X.java with the following contents:
* // public class X extends to.be.Generated {
* // }
* ICompilationUnit workingCopy = ...
* ASTParser parser = ASTParser.newParser(AST.JLS3);
* parser.setSource(workingCopy);
* parser.setResolveBindings(true);
* parser.setWorkingCopyOwner(owner);
* CompilationUnit cu = (CompilationUnit) parser.createAST(null);
* assert cu.getProblems().length == 0;
* </pre>
* </p>
*
* @param typeName the simple name of the type to lookup
* @param packageName the dot-separated name of the package of type
* @return the source of the compilation unit that defines the given type in
* the given package, or <code>null</code> if the type is unknown
* @see #isPackage(String[])
* @since 3.5
*/
public String findSource(String typeName, String packageName) {
return null;
}
/**
* Returns whether the given package segments represent a package.
* <p>This method is called before the normal lookup (i.e. before looking
* at the project's classpath and before looking at the working copies of this
* owner.)</p>
* <p>This allows to provide packages that are not normally available.</p>
* <p>If <code>false</code> is returned, then normal lookup is used on
* this package.</p>
*
* @param pkg the segments of a package to lookup
* @return whether the given package segments represent a package.
* @see #findSource(String, String)
* @since 3.5
*/
public boolean isPackage(String[] pkg) {
return false;
}
/**
* Returns a new working copy with the given name using this working copy owner to
* create its buffer.
* <p>
* This working copy always belongs to the default package in a package
* fragment root that corresponds to its Java project, and this Java project never exists.
* However this Java project has the given classpath that is used when resolving names
* in this working copy.
* </p><p>
* A DOM AST created using this working copy will have bindings resolved using the given
* classpath, and problem are reported to the given problem requestor.
* <p></p>
* <code>JavaCore#getOptions()</code> is used to create the DOM AST as it is not
* possible to set the options on the non-existing Java project.
* </p><p>
* When the working copy instance is created, an {@link IJavaElementDelta#ADDED added delta} is
* reported on this working copy.
* </p><p>
* Once done with the working copy, users of this method must discard it using
* {@link ICompilationUnit#discardWorkingCopy()}.
* </p><p>
* Note that when such working copy is committed, only its buffer is saved (see
* {@link IBuffer#save(IProgressMonitor, boolean)}) but no resource is created.
* </p><p>
* This method is not intended to be overriden by clients.
* </p>
*
* @param name the name of the working copy (e.g. "X.java")
* @param classpath the classpath used to resolve names in this working copy
* @param problemRequestor a requestor which will get notified of problems detected during
* reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
* that the client is not interested in problems.
* @param monitor a progress monitor used to report progress while opening the working copy
* or <code>null</code> if no progress should be reported
* @throws JavaModelException if the contents of this working copy can
* not be determined.
* @return a new working copy
* @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
* @since 3.2
*
* @deprecated Use {@link #newWorkingCopy(String, IClasspathEntry[], IProgressMonitor)} instead.
* Note that if this deprecated method is used, problems may be reported twice
* if the given requestor is not the same as the current working copy owner one.
*/
public final ICompilationUnit newWorkingCopy(String name, IClasspathEntry[] classpath, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
ExternalJavaProject project = new ExternalJavaProject(classpath);
IPackageFragment parent = ((PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject())).getPackageFragment(CharOperation.NO_STRINGS);
CompilationUnit result = new CompilationUnit((PackageFragment) parent, name, this);
result.becomeWorkingCopy(problemRequestor, monitor);
return result;
}
/**
* Returns a new working copy with the given name using this working copy owner to
* create its buffer.
* <p>
* This working copy always belongs to the default package in a package
* fragment root that corresponds to its Java project, and this Java project never exists.
* However this Java project has the given classpath that is used when resolving names
* in this working copy.
* </p><p>
* If a DOM AST is created using this working copy, then given classpath will be used
* if bindings need to be resolved. Problems will be reported to the problem requestor
* of the current working copy owner problem if it is not <code>null</code>.
* <p></p>
* Options used to create the DOM AST are got from {@link JavaCore#getOptions()}
* as it is not possible to set the options on a non-existing Java project.
* </p><p>
* When the working copy instance is created, an {@link IJavaElementDelta#ADDED added delta} is
* reported on this working copy.
* </p><p>
* Once done with the working copy, users of this method must discard it using
* {@link ICompilationUnit#discardWorkingCopy()}.
* </p><p>
* Note that when such working copy is committed, only its buffer is saved (see
* {@link IBuffer#save(IProgressMonitor, boolean)}) but no resource is created.
* </p><p>
* This method is not intended to be overriden by clients.
* </p>
*
* @param name the name of the working copy (e.g. "X.java")
* @param classpath the classpath used to resolve names in this working copy
* @param monitor a progress monitor used to report progress while opening the working copy
* or <code>null</code> if no progress should be reported
* @throws JavaModelException if the contents of this working copy can
* not be determined.
* @return a new working copy
* @see ICompilationUnit#becomeWorkingCopy(IProgressMonitor)
*
* @since 3.3
*/
public final ICompilationUnit newWorkingCopy(String name, IClasspathEntry[] classpath, IProgressMonitor monitor) throws JavaModelException {
ExternalJavaProject project = new ExternalJavaProject(classpath);
IPackageFragment parent = ((PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject())).getPackageFragment(CharOperation.NO_STRINGS);
CompilationUnit result = new CompilationUnit((PackageFragment) parent, name, this);
result.becomeWorkingCopy(getProblemRequestor(result), monitor);
return result;
}
}