/*
* @(#)TreeManager.java
*/
package javax.ide.model.java.source;
import java.io.IOException;
import java.net.URI;
import javax.ide.model.java.source.tree.FileT;
/**
* The TreeManager serves as a FileT factory. Clients obtain FileTs by
* requesting a FileT from the manager and by creating empty FileTs
* through the manager. Clients change the writability of FileTs by
* opening and closing TreeTransactions. For the sake of transaction
* consistency, a FileT belongs to exactly one TreeManager for the
* lifetime of the FileT.
*
* The TreeManager owns a single lockable resource (which may be itself)
* which must, at the minumum, provide the functionality of a read-write
* lock. Each FileT is tied to a single lockable resource (which may be
* itself) which is defined by the owning IDE. This may be an IDE lock
* controlling the writable of the underlying resource. Because the
* FileT's lock is not defined by the owning IDE and not the owning
* TreeManager, it is the responsibility (or neglect) of the owning
* IDE to safeguard against deadlocks and starvation.
*
* Attempting to make any change to a FileT marked as read-only will
* result in an IllegalStateException. Attempting to mark a FileT as
* writable when the FileT's underlying resource is not writable may
* result in a RuntimeException, at the discretion of the owning IDE.
* Although a FileT is logically writable only on the thread that made
* it writable, this manager does not enforce that policy.
*
* To start a transaction, call beginTransaction
on the
* FileT in question.
*
* Opening a new transaction that conflicts with an already open
* transaction results in an IllegalStateException. This TreeManager
* does not provide blocking operations on its transaction state.
* Attempting to close a transaction on a thread different than than
* the opening thread results in a IllegalStateException. A nested
* transaction is not considered to be at conflict with its enclosing
* transaction.
*
*
* Write on commit
*
* The change to the underlying source file is not made until the
* owning transaction is committed. Transactions collect changes made
* to a FileT and then write them out to disk on commit. The only
* exception to this is anonymous FileTs, which have no underlying
* file. This is done to ensure that IDE listeners fire at the right
* time. Thus, a FileT change is not considered to be "done" by the
* IDE until its owning transaction has been committed.
*
* The scope of a transaction is a single FileT. In a read-only state,
* no changes are allowed. All FileTs areinitially marked as read-only
* except for anonymous files. A FileT is writable if and only if
* there is an open transaction on it.
*
* A transaction is nested if and only if, on open, there was already
* an open transaction on the target FileT. At this writing, nested
* transactions are not supported and result in an
* IllegalStateException. They may be supported in a later release.
*
*
* @author Andy Yu
*/
public interface TreeManager
{
// ----------------------------------------------------------------------
/**
* Fetches the FileT for at the given URI (usually of the form
* *.java). The classes contained in the file represented by the URI
* can be fetched from the source file. If the URI does not
* represent a Java source file (e.g. it is a JPEG file), or if the
* URI points to a non-existing file, then null is returned.
*
* Newly fetched FileTs are marked read-only. Previously fetched
* FileTs retain their previous read-only/writable state.
*
* @param sourceURI The target URI.
*
* @return The FileT representing the compilation unit at the
* specified URI.
*
* @throws IllegalArgumentException if the URI is not recognized as
* a Java source file.
*/
public FileT getSourceFile(URI sourceURI);
/**
* Creates a new FileT for the given Java source URI (*.java). This
* will create a new empty file for the given URI, and return the
* FileT instance for it. If the file already exists on disk, then
* this will return null.
*
* @param sourceURI The target URI.
*
* @return The FileT for the newly created compilation unit at the
* specified URI, null if the file was not created.
*
* @throws IOException if the new file cannot be created.
*
* @throws IllegalArgumentException if the URI is not recognized as
* a Java source file.
*/
public FileT createSourceFile(URI sourceURI) throws IOException;
/**
* Fetches an anonymous file. This file is not tied to a URI.
*
* An anonymous file is not attached to any URI or lockable
* resource, can not be referenced outside, is always writable, and
* does not participate in transaction mechanics. All TreeResolver
* operations may be validly performed on the anonymous file as on
* any other file.
*
* This is useful for debugging features who may need to parse
* anonymous expressions.
*
* Must always return a different non-null FileT each time.
*
* @return A FileT for an anonymous file.
*/
public FileT getAnonymousFile();
/**
* Clears the destination FileT (unlinks all its children), clones
* the source FileT contents, and links the cloned Trees into the
* destination FileT. No transactions are opened in the process.
* The source FileT may be an anonymous file and may even belong to
* a different TreeManager.
*
* If the destination FileT cannot be written to, an exception will
* be thrown.
*
* @param source The source FileT.
* @param destination The destination FileT.
*/
public void cloneSourceFile(FileT source, FileT destination);
}