Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

javax.ide.model.java.source.write
Interface TreeManager  view TreeManager download TreeManager.java


public interface TreeManager

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 and which must NOT coincide with the TreeManager's lock. This is usually an IDE lock controlling the writable of the underlying resource, e.g. java.io.File. 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 multi-tree transaction, call beginMultiTransaction on this manager. To start a single-tree transaction, call beginTransaction on the FileT in question.

Opening a new transaction that conflicts with an already open transaction results in a TreeTransactionException. 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 TreeTransactionException. A nested transaction is not considered to be at conflict with its enclosing transaction. Please see the section on nested transactions further below for more detail.

TODO: If we were to provide such blocking operations, what would they look like?

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.

Transaction states

A TreeManager can be in one of three states: read-only, single-tree transactions open, multi-tree transaction open. These states map directly to the state of a single read-write lock: read-only, locked shared, locked exclusive. The scope of a single-tree transaction is a single FileT. The scope of a multi-tree transaction is a TreeManager and all its owned FileTs.

In a read-only state, no changes are allowed. All owned FileTs are marked as read-only. Opening a single-tree transaction on a FileT belonging to this manager moves this manager into a single-tree transactions open state. Opening a multi-tree transaction on this manager moves this manager into a multi-tree transaction open state.

In a single-tree transactions open state, multiple single-tree transactions may be open with at most one transaction open per FileT. In this state, an owned FileT is writable if and only if there is an open single-tree transaction on said FileT. When all open transactions are closed on FileTs belonging to this manager, this manager moves into a read-only state.

In a multi-tree transaction open state, there is a single open multi-tree transaction. Any change to a FileT belonging to this manager automatically marks it as writable. When the open transaction is closed, this manager moves into a read-only state.

TODO: Should we provide the ability to upgrade from a single-tree transactions open state to a multi-tree transaction open state? Clearly, such an ability requires the ability of the manager's underlying lock to upgrade from a locked shared to a locked exclusive state.

Nested transactions

A single-tree transaction is nested if and only if, on open, there was already an open single-tree transaction on the target FileT or there was already an open multi-tree transaction on the owning manager. A multi-tree transaction is nested if and only if, on open, there was already on open multi-tree transaction on the target manager.

At this writing, nested transactions are not supported and result in a TreeTransactionException. They may be supported in a later release.


Method Summary
 MultiTreeTransaction beginMultiTransaction()
          Places this FileFactory in an exclusive open transaction state.
 void cloneSourceFile(javax.ide.model.java.source.tree.FileT source, javax.ide.model.java.source.tree.FileT destination)
          Clears the destination FileT (unlinks all its children), clones the source FileT contents, and links the cloned Trees into the destination FileT.
 javax.ide.model.java.source.tree.FileT createSourceFile(java.net.URI sourceURI)
          Creates a new FileT for the given Java source URI (*.java).
 javax.ide.model.java.source.tree.FileT getAnonymousFile()
          Fetches an anonymous file.
 MultiTreeTransaction getMultiTransaction()
          Returns the in-progress multi-tree transaction, null if none.
 javax.ide.model.java.source.tree.FileT getSourceFile(java.net.URI sourceURI)
          Fetches the FileT for the given Java source URI (*.java).
 

Method Detail

getSourceFile

public javax.ide.model.java.source.tree.FileT getSourceFile(java.net.URI sourceURI)
Fetches the FileT for the given Java source URI (*.java). The classes contained in teh file represented by the URI can be fetched from the source file. If the URI does not represent a valid Java source 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.


createSourceFile

public javax.ide.model.java.source.tree.FileT createSourceFile(java.net.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.

FileTs may only be created when the TreeManager is in a multi-tree transaction open state. Hence, the FileT becomes writable once touched.


getAnonymousFile

public javax.ide.model.java.source.tree.FileT getAnonymousFile()
Fetches an anonymous file.

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. In particular, an anonymous file can not have open transactions, is not affected by the owning manager's transaction state, and does not affect the owning manager's transaction state. 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.


cloneSourceFile

public void cloneSourceFile(javax.ide.model.java.source.tree.FileT source,
                            javax.ide.model.java.source.tree.FileT destination)
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 anoymous file and may even belong to a different TreeManager.

If the destination FileT cannot be written to, an exception will be thrown.


beginMultiTransaction

public MultiTreeTransaction beginMultiTransaction()
Places this FileFactory in an exclusive open transaction state. Begins a multi-tree transaction. End the transaction with either TreeTransaction.abort() 55 or TreeTransaction.commit() 55 .


getMultiTransaction

public MultiTreeTransaction getMultiTransaction()
Returns the in-progress multi-tree transaction, null if none.