public class AstManager
extends java.lang.Object
To create the singleton instance, the backing plugin of type
AstManagerPlugin
must be installed via initialize(com.goldencode.ast.AstManagerPlugin)
.
Maintains a project-specific bidirectional indexing facility for mapping ASTs to project-unique IDs. Given a 64-bit unique ID, one can lookup the specific AST name that is associated with that ID. Likewise, given an AST name, one can obtain the 64-bit unique ID. In addition, this class tracks the next available 64-bit node ID for each tree.
A long
is used to store and represent the 64-bit IDs. These
64-bit IDs are 'partitioned' into an upper DWORD (32-bit unsigned value) and
a lower DWORD. The upper DWORD is associated with the name that is the source
of a given AST. Each tree name in a project will have a unique upper DWORD
that is assigned when the tree is added to the registry using the
addTree(java.lang.String)
method. All AST nodes in the tree created from/for that
tree will share the same upper DWORD. This upper DWORD is called the
'tree portion' of the ID. A 'tree ID' is an ID with the lower DWORD set
to 0x00000000 and the upper DWORD set to the tree portion of the specific
tree being referenced. The lower DWORD holds a value that is unique to
each AST node in that tree. This lower DWORD is called the 'node portion'
of the ID. When a node portion is combined with the tree portion of an
ID, the result is a 64-bit ID that uniquely identifies a specific AST node
in a specific tree. For this reason, such IDs can be used as persistent
references between ASTs in different trees or even between AST nodes in
the same tree.
An ID of 0xFFFFFFFFFFFFFFFF is invalid and is the equivalent to a
null
ID. Similarly, a tree ID (which by definition has a
a lower DWORD of 0x00000000) can never refer to a specific node and only
refers to a tree (to the entire tree rather than any given node of that
tree).
This class provides the assignment facility for obtaining unique tree IDs
as well as unique node IDs (see getNextNodeId(long)
).
Name lookups are done on a case sensitive basis.
To facilitate multi-threaded applications, a tree level locking facility
is provided. lockTree(java.lang.String)
and unlockTree(java.lang.String)
provide a mechanism
to obtain and release this lock respectively. This locking has nothing to
do with file system locks nor is there any non-Java locking backing this
lock. Rather, this lock is a cooperative agreement between all callers
that no use of the given tree will be made except when the caller holds
this exclusive lock to the tree.
Modifier and Type | Field and Description |
---|---|
static long |
INVALID_ID
An invalid AST ID.
|
private static AstManager |
mgr
Singleton instance of this class.
|
private AstManagerPlugin |
plugin
Core worker that provides the services implementation.
|
Modifier | Constructor and Description |
---|---|
private |
AstManager(AstManagerPlugin plugin)
Private constructor to enforce the singleton model.
|
Modifier and Type | Method and Description |
---|---|
long |
addTree(java.lang.String name)
Adds a mapping from the specified AST to a new ID.
|
static AstManager |
get()
Obtain the singleton instance of this class.
|
long |
getNextNodeId(long id)
Access the next unassigned node ID for the specified tree.
|
long |
getTreeId(long id)
Returns the tree ID portion of a node ID.
|
long |
getTreeId(java.lang.String name)
Reverse lookup of the ID that corresponds to a given AST name.
|
java.lang.String |
getTreeName(long id)
Lookup the name associated with the tree specified by this ID.
|
static AstManager |
initialize(AstManagerPlugin plugin)
Instantiate the singleton instance (or return the already existing
instance).
|
boolean |
isExistingAst(java.lang.String name)
Check if the AST specified by the given name exists already in the plugin's storage.
|
static boolean |
isPluginOfType(java.lang.Class<?> type)
Check if the plugin is of the specified type.
|
Aast |
loadTree(java.lang.String name)
Load a named AST from persistent storage.
|
void |
lockTree(long id)
Obtains a process-wide lock on any processing related to the given tree.
|
void |
lockTree(java.lang.String name)
Obtains a process-wide lock on any processing related to the given tree
name.
|
boolean |
removeTree(long id)
Removes all mapping data referencing the specified tree.
|
boolean |
removeTree(java.lang.String name)
Removes all mapping data referencing the specified tree.
|
void |
resetNextNodeId(long treeId)
Resets the next unassigned AST node ID for the specified tree to the
first possible value (tree ID + 1).
|
void |
save()
Persistently store the current state of the AST manager plugin.
|
void |
saveTree(Aast ast,
java.lang.String name,
boolean terse)
Save the given AST to persistent storage under the given name.
|
void |
unlockTree(long id)
Releases the process-wide lock on any processing related to the given
tree.
|
void |
unlockTree(java.lang.String name)
Releases the process-wide lock on any processing related to the given
tree.
|
boolean |
usesMemoryStorage()
Indicates whether the AST manager, as currently configured, uses memory as its primary
storage medium.
|
public static final long INVALID_ID
private static AstManager mgr
private AstManagerPlugin plugin
private AstManager(AstManagerPlugin plugin)
plugin
- Core worker that provides the services implementation.AstException
- If the plugin instance provided is null
.public boolean usesMemoryStorage()
true
if ASTs are stored primarily in memory, else false
.public static AstManager initialize(AstManagerPlugin plugin)
plugin
- Core worker that provides the services implementation. Ignored
if the singleton instance already exists.public static AstManager get()
AstException
- If the singleton instance has not yet been initialized.public static boolean isPluginOfType(java.lang.Class<?> type)
type
- The expected type.true
if the plugin
has the same or is a sub-type of the
specified type.public java.lang.String getTreeName(long id)
id
- The ID to use as a key in the lookup. This ID may be a tree ID
or a specific node ID.null
if no
such tree ID exists.public long getTreeId(java.lang.String name)
name
- Tree name whose unique ID should be returned.INVALID_ID
if the tree name doesn't exist or
if it is null
.public long getTreeId(long id)
id
- The ID to use as a key in the lookup. This ID may be a tree ID
or a specific node ID.INVALID_ID
if the ID is invalid.public Aast loadTree(java.lang.String name) throws AstException, java.lang.IllegalArgumentException
name
- The name of the tree. Often this is a file name.AstException
- On any error during the loading process.java.lang.IllegalArgumentException
- If the name is invalid or the specified resource doesn't exist.public boolean isExistingAst(java.lang.String name)
name
- The name (including path) of the AST file to be checked.true
if the specified AST is in the plugin's storage.public void saveTree(Aast ast, java.lang.String name, boolean terse) throws AstException, java.lang.IllegalArgumentException
ast
- The tree to save.name
- The name of the tree. Often this is a file name.terse
- Do not store line and column data when the node data is saved.AstException
- On any error during the saving process.java.lang.IllegalArgumentException
- If the name is invalid or the specified resource cannot be
used as a target to store the AST.public void lockTree(java.lang.String name) throws java.lang.InterruptedException, java.lang.IllegalArgumentException
unlockTree(java.lang.String)
is called the same number of times as this lock method. Thus the calls
to this lock method and to unlock
must always be
balanced.
This locking has nothing to do with file system locks nor is there any non-Java locking backing this lock. Rather, this lock is a cooperative agreement between all callers (within the same JVM) that no use of the given tree will be made except when the caller holds this exclusive lock to the resource.
name
- Tree name that is associated with the lock. This must be a
valid tree name which can be used to uniquely identify the
tree to be locked.java.lang.InterruptedException
- When an interruption occurs during blocking for the lock. If
this is thrown, the caller will NOT be holding the lock.java.lang.IllegalArgumentException
- If the name does not represent a valid tree.public void lockTree(long id) throws java.lang.InterruptedException, java.lang.IllegalArgumentException
unlockTree(java.lang.String)
is called the same number of times
as this lock method. Thus the calls to this lock method and to
unlock
must always be balanced.
This locking has nothing to do with file system locks nor is there any non-Java locking backing this lock. Rather, this lock is a cooperative agreement between all callers (within the same JVM) that no use of the given tree will be made except when the caller holds this exclusive lock to the resource.
id
- Tree ID that is associated with the lock.java.lang.InterruptedException
- When an interruption occurs during blocking for the lock. If
this is thrown, the caller will NOT be holding the lock.java.lang.IllegalArgumentException
- If the ID is not a valid tree ID.public void unlockTree(java.lang.String name) throws java.lang.IllegalMonitorStateException, java.lang.IllegalArgumentException
lockTree(java.lang.String)
method. Thus the calls to this unlock method must always
be balanced with calls to this method.
This locking has nothing to do with file system locks nor is there any non-Java locking backing this lock. Rather, this lock is a cooperative agreement between all callers (within the same JVM) that no use of the given tree will be made except when the caller holds this exclusive lock to the resource.
name
- Tree name that is associated with the lock. This must be a
valid tree name which can be used to uniquely identify the
tree to be locked.java.lang.IllegalMonitorStateException
- If the calling thread does not own the lock.java.lang.IllegalArgumentException
- If the name does not represent a valid tree.public void unlockTree(long id) throws java.lang.IllegalMonitorStateException, java.lang.IllegalArgumentException
lockTree(java.lang.String)
method. Thus the calls to this unlock method must always
be balanced with calls to this method.
This locking has nothing to do with file system locks nor is there any non-Java locking backing this lock. Rather, this lock is a cooperative agreement between all callers (within the same JVM) that no use of the given tree will be made except when the caller holds this exclusive lock to the resource.
id
- Tree ID that is associated with the lock.java.lang.IllegalMonitorStateException
- If the calling thread does not own the lock.java.lang.IllegalArgumentException
- If the ID is not a valid tree ID.public long getNextNodeId(long id) throws AstException
id
- The ID that specifies a tree.INVALID_ID
if no such
tree exists.AstException
- If too many AST nodes exist.public void resetNextNodeId(long treeId) throws AstException
WARNING: there is no check on the current usage of node IDs for this file, so if AST nodes exist already they will have IDs at or above this value and duplicate IDs may (probably will) result!
treeId
- The ID that specifies a valid tree.AstException
- If the file ID is invalid.public long addTree(java.lang.String name) throws AstException
name
- The tree name. Often this will be the name of a file.AstException
- If too many ASTs exist in the registry or if the input
name is null
.public boolean removeTree(long id) throws AstException
id
- The ID the tree to remove.true
if the tree existed in the registry (and
was removed), false
if the tree didn't exist.AstException
public boolean removeTree(java.lang.String name) throws AstException
name
- The tree name to remove.true
if the tree existed in the registry (and
was removed), false
if the tree didn't exist.AstException
public void save() throws AstException
AstException
- On any failure.