|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.microsoft.tfs.core.checkinpolicies.PolicyBase
public abstract class PolicyBase
A convenient base class for checkin policy implementers.
Policy implementations can fire an event (PolicyStateChangedEvent
) to
indicate to upper layers in the framework that that policy has re-evaluated
itself, and has built a new set of failures (perhaps an empty set).
Simple policies that do not respond to external events like timers or events from other components do not need to fire this event. More complicated policies might re-evaluate their rules because of events fired by other components , so methods to register listeners and fire the event have been implemented for your convenience.
To fire the event, simply invoke
firePolicyStateChangedEvent(PolicyFailure[])
with the new array of
failures (an empty array signifies no failures).
A policy for the Plug-in for Eclipse wants to return policy failures if unit tests for the pending checkin do not pass. In this example, the unit tests are managed by a long-running component that fires events when the user runs the tests.
initialize(PendingCheckin, PolicyContext)
with the current pending
check-in.initialize(PendingCheckin, PolicyContext)
finds the running unit
test component, and registers itself to handle test pass/failure events.PolicyStateChangedEvent
with
failures describing the current test state ("Unit tests have not completed").
These failures prevent prevent a check-in.evaluate(PolicyContext)
on the policy, and it re-queries the
test component for results, returning the appropriate failures.PolicyStateChangedEvent
with a new set of failures (or an empty array
when all tests pass).
Later, when close()
is called, event handlers are removed from the
unit test component.
Make sure to override canEdit()
to return false if your policy does
not support user configuration (i.e. it has no settings to configure). If
canEdit()
returns true (the default), the "Edit" button or UI
element is enabled when a policy is displayed in user interfaces. If it
returns false, the user is prevented from editing the policy definition (
edit(PolicyEditArgs)
will not be invoked).
This class is thread-safe, but implementations are not required to be. The policy framework will not invoke policy methods from multiple threads concurrently. Policies that run in the Eclipse environment and interact with other components or Eclipse plug-ins with events should ensure their error handlers interact with policy data in a thread-safe way.
The framework does not guarantee which thread will be used to invoke
evaluate(PolicyContext)
. Implementations must marshall any
thread-sensitive work in this method (for example, user interface work in
SWT/Eclipse) to the correct thread manually. See the thread policy notice in
PolicyInstance
for important information.
Constructor Summary | |
---|---|
PolicyBase()
All policy implementations must include a zero-argument constructor, so they can be dynamically created by the policy framework. |
Method Summary | |
---|---|
void |
activate(PolicyFailure failure,
PolicyContext context)
Called when the user activates (by double-clicking or some other user interface) a failure generated by a previous call to PolicyInstance.evaluate(PolicyContext) . |
void |
addPolicyStateChangedListener(PolicyStateChangedListener listener)
Adds a policy state changed listener that receives a PolicyStateChangedEvent whenever this policy is evaluated and a
new set of failures is generated. |
boolean |
canEdit()
|
void |
close()
Removes all event listeners from this policy instance. |
void |
displayHelp(PolicyFailure failure,
PolicyContext context)
Shows help about the given failure if it was selected for help in the user interface. |
abstract boolean |
edit(PolicyEditArgs policyEditArgs)
Edits the policy's configuration by interacting with the graphical user interface, if appropriate, or by other means. |
abstract PolicyFailure[] |
evaluate(PolicyContext context)
Evaluates the pending checkin for policy compliance and returns any failures encountered. |
protected void |
firePolicyStateChangedEvent(PolicyFailure[] failures)
Fires the PolicyStateChangedEvent with the given event failures,
filling in the other PolicyStateChangedEvent fields
automatically. |
protected void |
firePolicyStateChangedEvent(PolicyStateChangedEvent event)
Fires the given PolicyStateChangedEvent , which must be
constructed manually. |
protected PendingCheckin |
getPendingCheckin()
|
abstract PolicyType |
getPolicyType()
|
void |
initialize(PendingCheckin pendingCheckin,
PolicyContext context)
Prepares a PolicyInstance for policy evaluation. |
abstract void |
loadConfiguration(Memento configurationMemento)
Loads run-time configuration information from the given Memento ,
which was previously build by a call to
PolicyInstance.saveConfiguration(Memento) . |
void |
removePolicyStateChangedListener(PolicyStateChangedListener listener)
Removes a policy state changed listener that was previously added via PolicyInstance.addPolicyStateChangedListener(PolicyStateChangedListener) . |
abstract void |
saveConfiguration(Memento configurationMemento)
Saves the run-time configuration of this instance to the given (empty except for name) Memento object, which will be persisted by the
framework in the policy definition in the Team Foundation Server. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public PolicyBase()
All policy implementations must include a zero-argument constructor, so they can be dynamically created by the policy framework.
Policies should prefer to hook up evaluation-specific events to other
objects in initialize(PendingCheckin, PolicyContext)
instead of
in the constructor, and unhook them in close()
. This is because
policy instances are constructed during configuration, when no evaluation
will be performed. Policies should also assure that events are only
hooked up as many times as needed in
initialize(PendingCheckin, PolicyContext)
, since it may be
called multiple times during a policy instance's lifetime.
Method Detail |
---|
public void addPolicyStateChangedListener(PolicyStateChangedListener listener)
PolicyStateChangedEvent
whenever this policy is evaluated and a
new set of failures is generated.
Policies being evaluated in a graphical context (in an application like the Plug-in for Eclipse, or Explorer) can fire this event to cause the graphical display of their state (including failures) to be updated.
addPolicyStateChangedListener
in interface PolicyInstance
listener
- the listener to add (must not be null
)public void removePolicyStateChangedListener(PolicyStateChangedListener listener)
PolicyInstance.addPolicyStateChangedListener(PolicyStateChangedListener)
.
changes.
removePolicyStateChangedListener
in interface PolicyInstance
listener
- the listener to remove (must not be null
)PolicyInstance.addPolicyStateChangedListener(PolicyStateChangedListener)
protected void firePolicyStateChangedEvent(PolicyFailure[] failures)
PolicyStateChangedEvent
with the given event failures,
filling in the other PolicyStateChangedEvent
fields
automatically.
This is the preferred way to fire the PolicyStateChangedEvent
.
failures
- the failures to include with other event information (may be null:
will be converted to an empty failure array).protected void firePolicyStateChangedEvent(PolicyStateChangedEvent event)
PolicyStateChangedEvent
, which must be
constructed manually.
firePolicyStateChangedEvent(PolicyFailure[])
fills in some
fields automatically, and is preferred to this method.
event
- the event to fire (must not be null
)firePolicyStateChangedEvent(PolicyFailure[])
protected PendingCheckin getPendingCheckin()
PolicyInstance
was configured
with. Never returns null.
java.lang.IllegalStateException
- if initialize(PendingCheckin, PolicyContext)
has not yet
been called on this object.public boolean canEdit()
canEdit
in interface PolicyInstance
public void activate(PolicyFailure failure, PolicyContext context)
Called when the user activates (by double-clicking or some other user
interface) a failure generated by a previous call to
PolicyInstance.evaluate(PolicyContext)
. Implementations should further explain
the failure, perhaps presenting additional information or proposing a
solution.
Always called after the framework has called
PolicyInstance.initialize(PendingCheckin, PolicyContext)
.
Thread Policy
The policy framework always invokes this method on the user-interface thread, if the graphical environment where the framework is hosted requires it. Implementations may use the graphical interface context objects directly, without marhsalling calls to the UI thread.
activate
in interface PolicyInstance
failure
- the failure to activate or display (must not be null
)context
- contextual settings that may include information about the user
interface, etc. (must not be null
)public void displayHelp(PolicyFailure failure, PolicyContext context)
Shows help about the given failure if it was selected for help in the user interface.
Always called after the framework has called
PolicyInstance.initialize(PendingCheckin, PolicyContext)
.
Thread Policy
The policy framework always invokes this method on the user-interface thread, if the graphical environment where the framework is hosted requires it. Implementations may use the graphical interface context objects directly, without marhsalling calls to the UI thread.
displayHelp
in interface PolicyInstance
failure
- the failure to display help for (must not be null
)context
- contextual settings that may include information about the user
interface, etc. (must not be null
)public void initialize(PendingCheckin pendingCheckin, PolicyContext context)
Prepares a PolicyInstance
for policy evaluation. The framework
tries to keep PolicyInstance
instances around as long as
possible, for performance reasons, so it will invoke this method
repeatedly to re-configure the object for a new pending checkin.
If you allocate resources in this method, Closable.close()
is a
good place to release them.
Implementations should not save the PolicyContext
object for
later use, because the framework may pass a different context to
PolicyInstance.evaluate(PolicyContext)
.
Implementations should not perform user interface work in this method because the framework tries to initialize a policy as lazily as it can, but also must call initialize many times as the checkin data changes.
initialize
in interface PolicyInstance
pendingCheckin
- the pending changes that will be evaluated by this
PolicyInstance
(must not be null
)context
- contextual settings that may include information about the user
interface, etc. (must not be null
)public void close()
close()
. Extending classes should make sure
to call super.close() if they override this method.
close
in interface com.microsoft.tfs.util.Closable
public abstract void loadConfiguration(Memento configurationMemento)
Loads run-time configuration information from the given Memento
,
which was previously build by a call to
PolicyInstance.saveConfiguration(Memento)
.
Implementations should not perform user interface work in this method.
loadConfiguration
in interface PolicyInstance
configurationMemento
- the Memento
to load settings from (must not be
null
)public abstract void saveConfiguration(Memento configurationMemento)
Saves the run-time configuration of this instance to the given (empty
except for name) Memento
object, which will be persisted by the
framework in the policy definition in the Team Foundation Server.
Implementations should not perform user interface work in this method.
Memento Notes
Implementations should not store text data directly inside the
given memento node (via Memento.putTextData(String)
, but instead
they should create child nodes to store text data. Any text data stored
on the given node will be discarded when it is saved. Implementations are
encouraged to set other types of attributes (Integer, String, Boolean,
etc.) directly on the given node or any child nodes they create.
saveConfiguration
in interface PolicyInstance
configurationMemento
- the empty (except for name) Memento
to save settings to
(must not be null
)public abstract boolean edit(PolicyEditArgs policyEditArgs)
Edits the policy's configuration by interacting with the graphical user
interface, if appropriate, or by other means. Implementations should
obtain references to user interface objects from the
PolicyEditArgs
map. This object's configuration is later
retrieved by the framework (via PolicyInstance.saveConfiguration(Memento)
) and
saved in the policy definition on the Team Foundation Server.
The policy framework will always invoke this method from the UI thread when running in Eclipse and Explorer.
Thread Policy
The policy framework always invokes this method on the user-interface thread, if the graphical environment where the framework is hosted requires it. Implementations may use the graphical interface context objects directly, without marhsalling calls to the UI thread.
edit
in interface PolicyInstance
policyEditArgs
- a map of strings to objects that can be used as context for
interface building.
public abstract PolicyType getPolicyType()
getPolicyType
in interface PolicyInstance
PolicyType
information for this instance.public abstract PolicyFailure[] evaluate(PolicyContext context) throws PolicyEvaluationCancelledException
Evaluates the pending checkin for policy compliance and returns any
failures encountered. Called by the checkin policy framework at various
times during the life of the PolicyInstance
object, but always
after PolicyInstance.initialize(PendingCheckin, PolicyContext)
was called with
a pending checkin and contextual information.
Implementations should not save the PolicyContext
object for
later use, becuase the objects inside it are not guaranteed to persist
after PolicyInstance.evaluate(PolicyContext)
returns. This restriction means
that policies which call their own PolicyInstance.evaluate(PolicyContext)
method (as a result of an external event or some other design decision)
must create their own PolicyContext
instances for this call. They
can re-use the values from the original, framework-called
PolicyInstance.evaluate(PolicyContext)
at their own risk--these objects may
become stale or invalid.
Thread Policy
Implementations must not assume this method will be invoked on any specific thread. More specifically, if the framework is running in an application with a graphical user interface, any user-interface work done in the policy (through objects obtained in the context, for example) must be marshalled to the correct thread, if required by the interface toolkit in use. For Eclipse plug-ins, this means access to all user-interface objects should be done by by org.eclipse.swt.widgets.Display's asyncExec(Runnable) or syncExec(Runnable) methods.
evaluate
in interface PolicyInstance
context
- contextual settings that may include information about the user
interface, etc. (must not be null
)
PolicyFailure
array if none encountered.
PolicyEvaluationCancelledException
- if the user cancelled the policy evaluation.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |