public class SectionManager extends Object implements Cloneable, SectionInfo
This class is a repository for information about (Z) specs/sections (and its extensions). It
stores all the objects used during CZT processing, such as parsed ASTs (abstract syntax trees)
type environments, and so on. It provides several services, depending on the kind of key
requested. For instance, it can compute the operator table or the LaTeX markup function for a
given section, or typecheck or domain check a given Term/Spec/ZSect. The keys to access an object
within the section manager are a (Name,Class) pair (see Key), which means that several
different kinds of objects can be associated with the same name.
One of the main goals of this class is to cache commonly used objects, such as the parsed ASTs of toolkit sections, so that they do not have to be repeatedly processed. This can give great performance improvements. For instance, we envisage one section manager per project, where a project is a collection of files representing sections (e.g., an IDE project like in Netbeans/Eclipse).
Nevertheless, a fundamental problem is that data can become inconsistent if you add a section
A, then add other sections that uses it (e.g., B parent A, so that B
depends on A). If A changes, it must be invalidated within the section
manager and have its new version reloaded. Its dependent information must also be reloaded (e.g.
B may not be the same if A changes.
Our current solution is to have transactions that compute implicit dependencies whilst computing information, as well as explicit (extra) dependencies given by the user. This dependency calculation is quite hard to get right and this is an experimental feature at the moment. That is, the safest choice is to keep fresh(er) section managers if that is of concern (i.e., have section managers per file/buffer rather than projects) greater than performance gains.
We track duplicate objects as well as transaction scopes raising SectionManagerException at appropriate places. We are still experimenting with the best approach. The section manager also contain tracing methods to enable better debugging: tracing data is added to the console or Logger handler in order to output all information stored during transaction processing.
There are currently three ways of getting/reusing a section manager object.
new SectionManager(Dialect) - which starts with an empty cache, so gives you the overhead of
parsing toolkits again.oldSectMan.reset() - this clears everything in the cache, except for the prelude and
any sections called *_toolkit.oldSectMan.clone() - depending upon WHEN you do this clone, you can decide just how
much you want to leave in the cache.As well as the main cache of specification-related objects, this class maintains several other kinds of information, including:
There are two main operations available, get and put (see start-end transactions), and both
expect a Key<Class<?>> as input. The output is the same type of the key's
Class<?> type parameter. For instance, a call to
get(new Key<Spec>(string, Spec.class)) returns a Spec object if successful, or
throws a CommandException otherwise. There are two main maps for a section manager. One
that stores Command processing objects for a given Class<?>. That is, each kind
of Class<?> within a key must have a corresponding Command
within the map. For instance, for type checking Z we have SectTypeEnvAnn.class mapped to
net.sourceforge.czt.typecheck.z.TypeCheckCommand. These mappings are according to
associated .command files within the session project.
The second map is between Key and its corresponding resource, as calculated by the
Key's associated command. For instance, when parsing Z we have Key<Spec> mapped
to the underlying Spec object resulting from the computation of the command. One
important distinction to be made is regarding managed and non-managed resources. That is,
resources produced within CZT tools and resources used by CZT tools, respectively. The only
non-managed resources are mappings for Source keys: these are usually file or URI
resources from external sources. Everything else (so far) is managed by some CZT tool, like
specifications by the parser(s), and type environments by the type checker(s).
| Modifier and Type | Field and Description |
|---|---|
protected Map<Key<?>,Object> |
content_
The Cache storing computed values (e.g.
|
static Dialect |
DEFAULT_EXTENSION |
static Level |
DEFAULT_LOGLEVEL |
static Level |
DEFAULT_TRACELEVEL |
static boolean |
DEFAULT_TRACING |
protected Map<Key<?>,Set<Key<?>>> |
dependants_
Mapping of relationships from (LHS) Key to the set of other (RHS) keys that depend on it.
|
protected Map<Key<?>,Set<Key<?>>> |
dependencies_
Mapping of relationships from (LHS) Key to the set of other (RHS) keys that it depends on.
|
static Level |
EXTRA_TRACELEVEL |
protected List<Key<?>> |
pendingDeps_
The list of pending implicit dependencies, collected via the
get(Key) calls. |
static String |
SECTION_MANAGER_LIST_PROPERTY_SEPARATOR |
protected Stack<Pair<? extends Key<?>,Integer>> |
transactionStack_
The transaction stack contains tracks active transactions.
|
| Constructor and Description |
|---|
SectionManager(Dialect extension)
Creates a new section manager for a given Z extension/dialect.
|
SectionManager(Dialect extension,
boolean doTrace,
Level logLevel,
Level tracingLevel) |
| Modifier and Type | Method and Description |
|---|---|
protected void |
assertCurrentTransaction(Key<?> expected)
Checks that the top of transaction stack (the current transaction) is the given
key -
throws an exception otherwise. |
protected void |
assertNewTransaction(Key<?> key)
Checks that there are no existing transaction for the given
key (thus the transaction
is new) - throws and exception otherwise. |
protected void |
assertNotCached(Key<?> key)
Checks that the given
key is not cached in the section manager - throws an exception
otherwise. |
protected void |
assertNoTransactions(Key<?> expected)
Checks that there are no transactions at all - throws an exception otherwise.
|
Set<Key<?>> |
cancelTransaction(Key<?> key)
Cancels the ongoing transaction in the section manager.
|
SectionManager |
clone()
Returns a new SectionManager with the same content, commands, and properties.
|
<T> void |
endTransaction(Key<T> key,
T value)
This is a convenience method for
SectionInfo.endTransaction(Key, Object, Collection), with no
explicit dependencies. |
<T> void |
endTransaction(Key<T> key,
T value,
Collection<? extends Key<?>> explicitDependencies)
Ends the transaction for the given key and associates the computed value to this key in the
section manager cache.
|
void |
ensureTransaction(Key<?> key)
Ensures that the indicated transaction is active in the section manager.
|
<T> T |
get(Key<T> key)
Lookup a key in the section manager.
|
boolean |
getBooleanProperty(String propertyKey) |
Command |
getCommand(Class<?> infoType)
Returns the command for calculating the given type of information.
|
Iterator<Class<?>> |
getCommandKeys() |
Key<?> |
getCurrentTransaction()
Retrieves the currently active transaction.
|
Set<Key<?>> |
getDependants(Key<?> key)
Retrieves keys of all elements that depend on the given
key. |
Set<Key<?>> |
getDependencies(Key<?> key)
Retrieves keys of all elements, that the given
key depends on. |
Dialect |
getDialect()
Returns the current language extension dialect is being managed (see
Dialect). |
int |
getIntegerProperty(String propertyKey) |
List<String> |
getListProperty(String propertyKey) |
Logger |
getLogger() |
Properties |
getProperties()
Returns all the current property settings.
|
String |
getProperty(String key)
Returns a property.
|
Level |
getTracingLevel()
Get current section manager tracing level as set by
SectionInfo.setTracing(boolean, Level). |
boolean |
hasProperty(String key) |
protected boolean |
hasTransaction() |
boolean |
isCached(Key<?> key)
Returns whether the given Key has already been computed
and is cached.
|
boolean |
isPermanentKey(Key<?> key) |
boolean |
isTracing()
Returns whether debugging tracing is on or not as set by
SectionInfo.setTracing(boolean, Level). |
<T> Set<Key<? extends T>> |
keysOf(Class<T> clsName)
Retrieve all the keys involving a given class type
|
Set<Key<?>> |
keysOf(String name)
Retrieve all the keys involving a given name (e.g., ZSect, Spec, Source, etc for given string name)
|
void |
postponeTransaction(Key<?> postponeKey,
Key<?> nextKey)
Postpones the just-started transaction to ensure a correct transaction order.
|
<T> void |
put(Key<T> key,
T value)
This is a convenience method for
SectionInfo.put(Key, Object, Collection), with no explicit
dependencies. |
<T> void |
put(Key<T> key,
T value,
Collection<? extends Key<?>> explicitDependencies)
Adds the value to the section manager cache.
|
void |
putCommand(Class<?> infoType,
Command command)
Add a new command for calculating information, overriding any
existing commands used for calculating this type of information.
|
boolean |
putCommand(String type,
String commandClassName)
Add a new command for calculating information of a given type.
|
void |
putCommands(Dialect extension)
Adds the default commands for the given Z extension/dialect.
|
void |
putCommands(Properties props)
Adds a set of default commands from a Properties object.
|
void |
putCommands(URL url)
Loads a collection of commands from the given properties file/url.
|
protected void |
registerDefaultPermanentKeys() |
protected boolean |
registerPermanentKey(String key) |
boolean |
removeKey(Key<?> key)
Removes the key and its value from the section manager cache.
|
protected boolean |
removePermanentKey(String key) |
void |
reset()
Resets the section manager.
|
<T> Key<? super T> |
retrieveKey(T value)
Returns whether the given value has already been computed
and is cached.
|
void |
setProperties(Properties props)
Sets a whole bunch of properties to the given values.
|
Object |
setProperty(String key,
String value)
Sets a property to the given value.
|
boolean |
setTracing(boolean on) |
boolean |
setTracing(boolean on,
Handler handler,
Level level) |
boolean |
setTracing(boolean on,
Level level)
Set section management tracing on/off.
|
void |
startTransaction(Key<?> key)
Starts a section manager transaction.
|
String |
toString() |
static void |
traceConfig(String msg) |
static void |
traceInfo(String msg) |
static void |
traceLog(String msg) |
static void |
traceWarning(String msg) |
public static final Dialect DEFAULT_EXTENSION
public static final boolean DEFAULT_TRACING
public static final Level DEFAULT_LOGLEVEL
public static final Level DEFAULT_TRACELEVEL
public static final Level EXTRA_TRACELEVEL
public static final String SECTION_MANAGER_LIST_PROPERTY_SEPARATOR
protected final Map<Key<?>,Object> content_
T val = (T) content_.get(Key<T>).protected final Map<Key<?>,Set<Key<?>>> dependants_
For example if
We would have a mapping that (excludingA parents Prelude B parents A C parents B
Prelude)
A -> { B, C }
B -> { C }
C -> { }
This way, when removing dependants for A, we know that {B, C} and all their
dependants need removing. This way, we calculate the transitive closure of dependants. So, if
A is removed then by calculating the transitive closure of dependants we would get that
{B, C} need removing as well.
protected final Map<Key<?>,Set<Key<?>>> dependencies_
For the example in dependants_, we would get the following map (excluding
Prelude)
A -> { }
B -> { A }
C -> { B, A }
protected final Stack<Pair<? extends Key<?>,Integer>> transactionStack_
pendingDeps_, where the transaction's
dependencies start. See pendingDeps_ for an example.
The top of the transaction stack is the currently active transaction.
protected final List<Key<?>> pendingDeps_
get(Key) calls. Each
transaction in the transactionStack_ reference a particular point in this list. It
means that the dependencies of that particular transactions are the ones above
the index. When the transaction is ended, its dependencies from the pending list will be added
to the dependency maps.
For example, let the transactionStack_ be [ (A, 0), (B, 2) ], and
pendingDeps_ be [C, B, D, E]. Then the dependencies of B are {D, E}, and dependencies
of A are {C, B, D, E}.
#get(parent, ThmTable). This means that the outer transaction (e.g. Sect)
would have these ThmTables as dependencies, even though it actually does not depend on them.public SectionManager(Dialect extension)
extension - A Z dialect ("z", "zpatt", "oz", "circus", etc.)public final Dialect getDialect()
SectionInfoDialect).getDialect in interface SectionInfopublic SectionManager clone()
The maps for storing content, commands, and properties are copied, however the content of the maps is not cloned. That is, content can be added to the new section manager without affecting the old one, but destructive changes to its content will show up in this section manager as well.
If cloning happens during a transaction, it will only have information from already finished transaction. This includes objects in the section manager, dependencies, etc. The pending transactions and their dependencies, however, are not cloned. Even more, pending transaction keys are removed from the cloned section manager, thus removing everything that may have been depending on the pending transactions (e.g. a LMF is computed before ZSect computation ends, so cloning in the middle of this transaction, will remove the computed LMF for the pending ZSect transaction).
protected final void registerDefaultPermanentKeys()
protected boolean registerPermanentKey(String key)
protected boolean removePermanentKey(String key)
public boolean isPermanentKey(Key<?> key)
public void reset()
throws SectionInfoException
SectionInfoThus after resetting, there is no need to redo the work on CZT core toolkits.
The section manager cannot be reset if there are any ongoing transactions, because it will destroy the transactional integrity.
reset in interface SectionInfoSectionInfoException - Unchecked exception if there are ongoing transactions.public String getProperty(String key)
Returns a property.
Properties are used to store global settings for the commands. For example, the "czt.path" property defines the directory where specifications can be loaded from.
key - property namepublic boolean hasProperty(String key)
public Properties getProperties()
Returns all the current property settings.
Properties are used to store global settings for the commands. For example, the "czt.path" property defines the directory where specifications can be loaded from.
public Object setProperty(String key, String value)
Properties are used to store global settings for the commands. See getProperty.
key - property keyvalue - property valuepublic void setProperties(Properties props)
Sets a whole bunch of properties to the given values.
This sets all the properties defined by props
including its default properties (if it has any).
Properties are used to store global settings for the commands. See getProperty.
props - public boolean getBooleanProperty(String propertyKey)
public int getIntegerProperty(String propertyKey)
public final void putCommands(Dialect extension)
extension - public void putCommands(URL url)
url - location where to looc for XML-formated list of commands.NullPointerException - if url is null.public void putCommands(Properties props)
props - Properties object to get the commands frompublic boolean putCommand(String type, String commandClassName)
type - the name of a Java class. This defines the type of object
that this command is expected to compute when it is called.commandClassName - the name of a subclass of
net.sourceforge.czt.session.Command.public void putCommand(Class<?> infoType, Command command)
infoType - The type of information the command will calculate.command - The command that will calculate the information.public Command getCommand(Class<?> infoType)
infoType - type of commandprotected void assertNoTransactions(Key<?> expected) throws SectionInfoException
expected - SectionInfoException - if transaction stack is not emptyprotected void assertNotCached(Key<?> key) throws SectionInfoException
key is not cached in the section manager - throws an exception
otherwise.key - SectionInfoException - if the key is cached.protected void assertNewTransaction(Key<?> key) throws SectionInfoException
key (thus the transaction
is new) - throws and exception otherwise.key - SectionInfoException - if a transaction exists for the keyprotected void assertCurrentTransaction(Key<?> expected) throws SectionInfoException
key -
throws an exception otherwise.expected - SectionInfoException - if there are not transactions at all, or the top of transaction stack is not the
key.protected boolean hasTransaction()
public Set<Key<?>> keysOf(String name)
SectionInfokeysOf in interface SectionInfopublic <T> Set<Key<? extends T>> keysOf(Class<T> clsName)
SectionInfokeysOf in interface SectionInfoT - type of key classpublic boolean isCached(Key<?> key)
isCached in interface SectionInfokey - The key to be looked up.public <T> Key<? super T> retrieveKey(T value)
retrieveKey in interface SectionInfoT - returned key typevalue - value to search for keypublic Key<?> getCurrentTransaction()
SectionInfogetCurrentTransaction in interface SectionInfonull otherwise.public <T> void put(Key<T> key, T value) throws SectionInfoException
SectionInfoSectionInfo.put(Key, Object, Collection), with no explicit
dependencies. Thus the call on this method indicates that the given key has no
dependencies altogether (neither implicit, nor explicit). See
SectionInfo.put(Key, Object, Collection) for details.put in interface SectionInfoT - The type of the value, as indicated by the key.key - The key referencing the value in the section manager. A transaction on this
key must will be started and immediately ended with this method.value - The value, which can be referenced by the key in the section manager
afterwards. The value must exist and be of the type indicated by key.SectionInfoException - Unchecked exception if constraints for starting and ending the transaction are
violated. See SectionInfo.put(Key, Object, Collection) for details.SectionInfo.put(Key, Object, Collection)public <T> void put(Key<T> key, T value, Collection<? extends Key<?>> explicitDependencies) throws SectionInfoException
SectionInfokey. This method should be used when
there is no computation of the value, and thus no implicit dependencies are needed. So by using
this method, the value is simply put in the section manager, indicating no gap in the
transaction.
Note that the method starts a transaction, thus it must not be used if a transaction is already
active. In that case, SectionInfo.endTransaction(Key, Object, Collection) must be used. Which is
the usual case for section manager commands.
The shorthand SectionInfo.put(Key, Object, Collection) method is good for putting things that do
not depend on anything in the section manager, e.g. initial Source objects. However, the method
allows indicating explicit dependencies in explicitDependencies parameter.
put in interface SectionInfoT - The type of the value, as indicated by the key.key - The key referencing the value in the section manager. A transaction on this
key must will be started and immediately ended with this method.value - The value, which can be referenced by the key in the section manager
afterwards. The value must exist and be of the type indicated by key.explicitDependencies - Explicit dependencies, if needed, for the indicated key (e.g. the set of keys
that the value depends on - parents, etc.).SectionInfoException - Unchecked exception if constraints for starting and ending the transaction are
violated. See SectionInfo.startTransaction(Key) and
SectionInfo.endTransaction(Key, Object, Collection) for details.SectionInfo.startTransaction(Key),
SectionInfo.endTransaction(Key, Object, Collection)public void ensureTransaction(Key<?> key) throws SectionInfoException
SectionInfoSectionInfo.startTransaction(Key)
).
This method is used very similarly as the SectionInfo.startTransaction(Key), however it does not
start a transaction if one has already been started. This can be used when it is not know if
the transaction has been started before, say, via a command.
Otherwise, the method is the same as SectionInfo.startTransaction(Key), so refer to its comments
for details.
ensureTransaction in interface SectionInfokey - The key of the transaction to start (or check has already been started).SectionInfoException - Unchecked exception if constraints for ensuring the transaction are violated:
key transaction has already been started, it must be the currently
active transaction.key transaction has not been started, see exception cases in
SectionInfo.startTransaction(Key).SectionInfo.startTransaction(Key)public void startTransaction(Key<?> key) throws SectionInfoException
SectionInfo
The section manager is updated with new results via transactions. So when computing a result to
cache in the section manager, a transaction needs to be started first, and then ended by
putting the computed result (see SectionInfo.endTransaction(Key, Object)). Alternatively, if the
computation fails, the started transaction needs to be cancelled (see
SectionInfo.cancelTransaction(Key)).
The transactional approach to section manager computations allows us to capture implicit
dependencies of the computed result. Between the start and end of transaction, all calls to
SectionInfo.get(Key) in the section manager are tracked. E.g. when typechecking a ZSect "foo", the
command retrieves the parsed ZSect via #get(new Key<ZSect>("foo", ZSect.class)), and
typecheck results of parent ZSects, among others. These, in turn, will have implicit
dependencies on parent sections, etc. All these implicit dependencies through SectionInfo.get(Key)
calls are assigned to the transaction upon its end.
By default, the implementors of section manager Commands do not need to start the transactions
manually. The SectionInfo.get(Key) method starts the transaction automatically before the command
is executed - see SectionInfo.get(Key) for details. However, in some cases, e.g. when the
computations are started on-the-fly (as opposed to via section manager commands, e.g.
calculating LatexMarkupFunction during parse), the transactions need to be started by this
method (or SectionInfo.ensureTransaction(Key)). Other cases include postponing a transaction (see
SectionInfo.postponeTransaction(Key, Key)), and then manually starting a transaction in the
correct order.
Note that if a transaction is started manually, handling of its cancellation upon
exceptions needs to be done manually as well. See SectionInfo.cancelTransaction(Key) for details.
The start/end/cancel transaction functionality supersedes the previous put() style of updating
the section manager. The SectionInfo.put(Key, Object) methods now are just a convenience for
starting and immediately ending the transaction.
In addition to transactions in the section manager, duplicate computations are no longer allowed. This means that a transaction cannot be started if the result has already been cached - it is required to remove the previous result before starting a new transaction. This is necessary to get correct dependencies. During removal of the key, all dependant objects are also cleaned from the section manager.
As part of the SectionInfo.postponeTransaction(Key, Key), this method checks that the started
transaction is the one expected during the last SectionInfo.postponeTransaction(Key, Key).
startTransaction in interface SectionInfokey - The key of the new transaction, indicating start of computation for the result.SectionInfoException - Unchecked exception if constraints for starting the transaction are violated:
key transaction cannot be already started - no overlapping transactions
on the same key.key result cannot be cached - no duplicate/overwritten results.key must be the one indicated as "expected" in the last call of
SectionInfo.postponeTransaction(Key, Key).SectionInfo.endTransaction(Key, Object),
SectionInfo.cancelTransaction(Key),
SectionInfo.ensureTransaction(Key),
SectionInfo.get(Key)public <T> void endTransaction(Key<T> key, T value) throws SectionInfoException
SectionInfoSectionInfo.endTransaction(Key, Object, Collection), with no
explicit dependencies. See SectionInfo.endTransaction(Key, Object, Collection) for details.endTransaction in interface SectionInfoT - The type of the computed value, as indicated by the key.key - The key referencing the value in the section manager. A transaction on this
key must be started, and will be completed with this method.value - The computed value, which can be referenced by the key in the section manager
afterwards. The value must exist and be of the type indicated by key.SectionInfoException - Unchecked exception if constraints for ending the transaction are violated, see
SectionInfo.endTransaction(Key, Object, Collection).SectionInfo.endTransaction(Key, Object, Collection)public <T> void endTransaction(Key<T> key, T value, Collection<? extends Key<?>> explicitDependencies) throws SectionInfoException
SectionInfoSectionInfo.get(Key) calls since the start of transaction), as well as given
explicit dependencies are used.
The computed results can be stored in the section manager only as a part of the completed
transaction, using this method. This ensures strict contract on using the section manager, and
allows capturing implicit dependencies of the computation (see SectionInfo.startTransaction(Key)
for more details). Note that transaction can only be ended upon successful computation (when
the result is available). Otherwise, it must be cancelled.
Ending of transactions is the main method to use in section manager Commands. When the result
is calculated, it should be put into the section manager using this method. In the default
case, the starting and cancelling (upon exception) of transaction is handled inside
SectionInfo.get(Key), thus only ending the transaction is required in the command.
Note that the transactions must be nested, and cannot overlap. So we can only end the currently active transaction.
For the manually started transactions and exception-cancellation issues, please refer to
SectionInfo.startTransaction(Key) and SectionInfo.cancelTransaction(Key).
As outlined in SectionInfo.startTransaction(Key), all SectionInfo.get(Key) calls since the start of
transaction are collected as dependencies of this key. So in the case of parsing a ZSect, it
will collect dependencies on parent ZSects, its info tables, etc. These, in turn, will collect
their own dependencies on their parents, etc. This is achieved by a nesting of start-end of
transactions. The dependencies are stored in the section manager, and when one of the
dependencies is removed, this key is also (transitively) removed.
If some of the dependencies cannot be captured implicitly, the explicitDependencies
parameter allows indicating explicit dependencies. The following are several examples of such
cases:
endTransaction in interface SectionInfoT - The type of the computed value, as indicated by the key.key - The key referencing the value in the section manager. A transaction on this
key must be started, and will be completed with this method.value - The computed value, which can be referenced by the key in the section manager
afterwards. The value must exist and be of the type indicated by key.explicitDependencies - Explicit dependencies, if needed, for the indicated key.SectionInfoException - Unchecked exception if constraints for ending the transaction are violated:
null.key transaction must be the currently active one.key result cannot be cached - no duplicate/overwritten results.SectionInfo.startTransaction(Key),
SectionInfo.cancelTransaction(Key)public Set<Key<?>> cancelTransaction(Key<?> key) throws SectionInfoException
SectionInfoNote that cancelling a transaction does not remove successful nested transactions, if they do not depend on the cancelled one. This means that after cancelling a top-level transaction, there can still be "leftovers" from its dependencies.
For example, if we parse a Z section "bar parents foo". Thus a transaction for "bar"
ZSect is started, which in turn has a nested transaction to calculate its parent, "foo" ZSect.
If "bar" fails with a parse exception, we still want to keep the successfully parsed parent
"foo" ZSect. Then when the "bar" error is corrected, there is no need to re-parse "foo" ZSect.
Note that "foo" does not depend on "bar" in any way, so we can leave it in the section manager
when cancelling "bar".
By default, the implementors of section manager Commands do not need to cancel the transactions
manually. The SectionInfo.get(Key) method wraps the computation into a try-catch and cancels the
started transaction if an exception is encountered - see SectionInfo.get(Key) for details.
However, when the commands are started manually via SectionInfo.startTransaction(Key) (or
SectionInfo.ensureTransaction(Key)), there is a need to handle exceptions manually as well. If
possible, the paths that can throw exceptions should catch them, cancel the transaction, and
re-throw the exception.
This method can also be used to end the transaction, when the result cannot be calculated. In
this case, it should be somewhere alongside SectionInfo.endTransaction(Key, Object, Collection),
but cancelling if the value is null or invalid.
As a last resort, SectionInfo.get(Key) implementations should cancel all nested un-cancelled
transactions if caught in exceptions. However, for good transactional implementation, the
errors of manual transactions should be managed by the commands themselves.
cancelTransaction in interface SectionInfokey - The key of currently active transaction, which needs to be cancelled. The key, and
everything that depends on it, will be removed from the section manager.SectionInfoException - Unchecked exception if constraints for cancelling the transaction are violated:
key cannot be null.key transaction must be the currently active one.SectionInfo.startTransaction(Key),
SectionInfo.get(Key)public void postponeTransaction(Key<?> postponeKey, Key<?> nextKey) throws SectionInfoException
SectionInfo
Some of the commands may calculate their results as part of a bigger calculation. The following
are several examples the illustrating need and use case for
SectionInfo.postponeTransaction(Key, Key):
SectionInfo.postponeTransaction(Key, Key) method is used to perform this reorder, indicating that
the LMF transaction will be postponed in favor of the ZSect, which may in turn perform the LMF
transaction again (i.e., postponed).SectionInfo.get(Key)), the transactional
chain would be ZSect > Spec > ZSect. The initial ZSect transaction is postponed to get Spec >
ZSect.
This method is a strict version of the SectionInfo.cancelTransaction(Key). It requires to indicate
the next expected transaction - it should be known when postponing. This will be verified when
the next transaction is started in SectionInfo.startTransaction(Key). Furthermore, this method can
only be used for just-started transaction (which do not have any marked dependencies - no
SectionInfo.get(Key) calls since starting it). This constraint ensures that we are not losing any
dependencies by postponing.
Because of these constraints, postponing (and thus reordering) the transactions should be used
as the first action in the command. If an inappropriate transaction has been started within
SectionInfo.get(Key) right before launching the command, postponing it in favor of another
(larger) transaction allows to achieve the desired order.
postponeTransaction in interface SectionInfopostponeKey - The key of an active transaction to be be postponed. The indicated transaction must be
at the top of transaction stack (currently active). It will be cancelled by this
method. The transaction cannot have any dependencies marked for it (via
SectionInfo.get(Key)).nextKey - The key for the next expected transaction. Indicates the transaction that the
postponed key is postponed in favor of. The next call to
SectionInfo.startTransaction(Key) must match the indicated key.SectionInfoException - Unchecked exception if constraints for postponing the transaction are violated:
postponedKey and nextKey cannot be null.postponedKey must be the currently active transaction.postponedKey cannot have dependencies marked for it (via
SectionInfo.get(Key)).nextKey cannot be already cached.nextKey cannot be an already active transaction.SectionInfo.cancelTransaction(Key),
SectionInfo.startTransaction(Key)public boolean removeKey(Key<?> key) throws SectionInfoException
SectionInfo
For example, let A parents B, B parents C. Now if we remove B from the section
manager, it will also remove A, which depends on it, but not C. So now if we
want to recompute B, we no longer need to recompute C.
removeKey in interface SectionInfokey - The key to be removed, including all of its dependants. It cannot be part of an
ongoing transaction.true if the removal was successful, false if there was no cached value
for the given key.SectionInfoException - Unchecked exception if the key or any of its dependent keys are current in a
transaction.public Set<Key<?>> getDependants(Key<?> key)
SectionInfokey.
For example, let A parents B, B parents C. Then if key is for C,
the result is A and B, because they depend on C.
Note that the relationship can be transitive, i.e. not all keys are returned would need to be followed transitively to collect everything.
getDependants in interface SectionInfokey - The key, which dependants are requested.key.public Set<Key<?>> getDependencies(Key<?> key)
SectionInfokey depends on.
For example, let A parents B, B parents C. Then if key is for A,
the result is B and C, because A depends on them.
Note that the relationship can be transitive, i.e. not all keys are returned would need to be followed transitively to collect everything.
getDependencies in interface SectionInfokey - The key, which dependencies are requested.key depends.public <T> T get(Key<T> key) throws CommandException, SectionInfoException
Lookup a key in the section manager. It will never return null.
That means, it calculates with the command associated with the key type, the
resulting value for that key. If it is already present (i.e., isCached(Key) is true),
then no further calculation is needed.
See SectionInfo.get(Key) for the "big picture" description of this method,
and for the information about transactions/dependencies.
Each extension may install different commands to process each type of key. Having this dynamic scheme minimises the source code dependencies the section manager has. The default commands can be found in the .commands files within the czt.jar. For instance, for the (default) Z extension, the mapping and the lookup algorithm is defined below. For each item we add the tool that (usually) performs the corresponding algorithm. Obviously, each extension has its own version of some of these commands (see extension corresponding .commands file).
Source.class.
The associations for each kind of Source are detailed below.
FileSource fs = new FileSource("./foo.tex");
// For file resource location...
String filename = "./foo.tex";
Source source = manager.get(new Key<Source>(name, Source.class));
Term term = ParseUtils.parse(source, manager);
See SourceLocator for details.
Term parsing (parser)Term are detailed below.
ParseException
returns the ParseException containing a list of CztError. One
rarely needs to directly use this, unless creating a top-level tool using the parser,
such as ZLive. The key name must contain the corresponding Source name.
LatexMarkupFunction and a section name returns the
table containing all the LaTeX markup directive information of a parsed
specification. That includes information about the directive type (i.e., infix,
posfix, prefix, nofix), its LaTeX and Unicode markup, the section where it belongs,
and so on.
OpTable and a section name returns the
table containing all the operator template information of a parsed specification.
That includes the section where the operator belongs, its associativity,
binding power, operator type, its underlying OpTempPara, and so on.
A key with DefinitionTable and a section name returns the
table containing all the information about declared types of definitions
of a parsed specification. That includes the section where the definition
appears, as well as its generic types, name and declared expression.
Note that the typechecker returns the carrier set for every name, whereas the definition table returns the declared (non-maximal) type. It is recommended that one only use definition tables of typechecked sections in order to avoid problems with overloaded names in schemas with type incompatible carrier sets, for instance.
CztPrintString class and named with the Z section
to print, or filename without path or extension for specifications.
For Standard Z, there are four possible options for pretty printing:
LatexString typed keys;OldLatexString typed keys;UnicodeString typed keys;XMLString typed keys.SectTypeEnv and named with a Z section name
return a SectTypeEnv, which contains a list of NameSectTypeTriple
containing a triple formed by the section name, the declared name, and its
carrier set type. The typechecker guarantees the specification is syntactically type-consistent.
Note that to typecheck specifications, one needs to typecheck
(manually) each one of its ZSect lements. See typechecker's TypeCheckUtils for details.
Spec terms generate SpecDCEnvAnn,
which contains a list of ZSectDCEnvAnn for each
ZSect it contains, and the name that can be used to locate the
enviroment original resource's (i.e., Spec filename without extension).
It is also possible to retrieve a Spec
containing ZSect with a list of conjectures for the
correspondent ZSect where they were originated.
ZSect terms generate ZSectDCEnvAnn,
which contain a list of pairs containing each ZSect
Para that generates a corresponding Pred
domain check verification condition, and the original Z section name.
It is also possible to retrieve a ZSect
containing a list of conjectures for the correspondent ZSect
where they were originated.
For other extensions the lookup is similar, except that different classes get associated with each one of these commands. Furthermore, new commands may be added or dynamically modified at any time. This way both the user or a developer may change the stub used to compute each available lookup functionality.
Finally, as the lookup operation may involve the recursive execution of
several commands, the underlying section manager cache will observe
intermediate side-effects whilst performing a top-level command by the user.
These results are cached/permanent until the SectionManager is reset().
get in interface SectionInfoT - type of keykey - The key to be looked up.CommandException - if the lookup was unseccessful.SectionInfoException - if the transactions for computation fail.SectionInfo.get(Key)public final Logger getLogger()
public Level getTracingLevel()
SectionInfoSectionInfo.setTracing(boolean, Level).getTracingLevel in interface SectionInfopublic boolean isTracing()
SectionInfoSectionInfo.setTracing(boolean, Level).isTracing in interface SectionInfopublic final boolean setTracing(boolean on,
Level level)
setTracing in interface SectionInfoon - flag to set it on or offpublic final boolean setTracing(boolean on)
public static void traceLog(String msg)
public static void traceConfig(String msg)
public static void traceWarning(String msg)
public static void traceInfo(String msg)
Copyright © 2003–2016 Community Z Tools Project. All rights reserved.