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