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