public class WidgetPool
extends java.lang.Object
A widget pool is a a mechanism to explicitly define the scope at which resources get an "implicit" DELETE OBJECT when the control flow causes the program to exit that particular scope. At its most basic, a widget pool is just a list of resources that get deleted, an optional name, an optional persistent flag and an association with a block scope that exists at a "top-level" block (external proc, internal proc, user-defined function and trigger). A block scope will only open and close at top-level blocks (external program, procedure, function or trigger). Inner blocks don't cause any scoping behavior.
All pools are context-local, as they are private to the user's session. No session-level widget-pool cleanup is implemented at this time. The current implementation of all the poolable resources does not require any session-level cleanup processing that is driven by widget pools. Should the implementation of any one of the poolable resources be modified to be dependent upon session-level widget-pool cleanup, then this feature will have to be added.
A pool will contain only resources which are dynamically created (and must be removed using a DELETE statement), and only a sub-set of them can be pooled. From the list of CREATE statements, only the following statements accept a named pool:
CREATE { BUTTON | COMBO-BOX | CONTROL-FRAME | DIALOG-BOX | EDITOR | FILL-IN | FRAME | IMAGE | MENU-ITEM | RADIO-SET | RECTANGLE | SELECTION-LIST | MENU | SLIDER | SUB-MENU | TEXT | TOGGLE-BOX | WINDOW | VALUE ( string-expression ) }
The following rules describe how named and unnamed pools are implemented:
1: DEF VAR h1 AS HANDLE. 2: DEF VAR h2 AS HANDLE. 3: CREATE WIDGET-POOL. // U1 4: CREATE BUTTON h1. 5: CREATE WIDGET-POOL. // U2 6: CREATE BUTTION h2. 7: DELETE WIDGET-POOL. // U2 8: DELETE WIDGET-POOL. // U1At step 3 and 5, an unnamed pool is created, identified by U1 and U2. At step 4, the resource referenced by handle
h1
(R1) is added to unnamed pool U1 and at step 6, the
resource referenced by handle h2
(R2) is added to unnamed pool U2 (the last created
one). Step 7 will delete unnamed pool U2 (and resource R2), while step 8 will delete unnamed
pool U1 (and resource R1).
Once a persistent unnamed pool is created, a DELETE WIDGET-POOL statement will not be able to delete it, if the persistent pool is on top of the stack. For this reason, a CREATE WIDGET-POOL PERSISTENT statement will do nothing if the unnamed pool at the top of the stack is persistent too.
When the current scope ends, all non-persistent unnamed pools will be deleted. But, if there is an unnamed persistent pool on the top of the stack for scope S2, this one will be "leaked" to the previous scope, S1. The reason for this is that if scope S1 has an active unnamed non-persistent pool, then this pool must be deleted when S1 ends. There are no restriction for S1 to already have its own persistent unnamed pool. Thus, when S2 ends and leaks the top persistent unnamed pool to S1, will result in S1 to have more than one persistent pool. But this will not alter how persistent pools behave for S1: non-persistent unnamed pools can still be created on top of the persistent unnamed pool, and unnamed pool deletion will stop when the first persistent unnamed pool is back on the top of the stack.
1: CREATE WIDGET-POOL. // U1 2: PROCEDURE proc0. 3: CREATE WIDGET-POOL PERSISTENT. // U2 4: // create resource R1 5: DELETE WIDGET-POOL. 6: END. 7: RUN proc0. 8: DELETE WIDGET-POOL. 9: CREATE WIDGET-POOL. // U3 10: // create resource R2 11: DELETE WIDGET-POOL. 12: DELETE WIDGET-POOL. 13: CREATE WIDGET-POOL. // U4 14: // create resource R3 15: CREATE WIDGET-POOL PERSISTENT. // U5 16: // create resource R4 17: DELETE WIDGET-POOL.
proc0
which creates unnamed pool U2. On step 5, the active
pool contains resource R1, but will not be deleted. After proc0
ends, pool U2
is placed on top of the stack for scope S1, and the pool stack looks like [ U2 -> U1 ].
Resource R2 will not be deleted.This unnamed pool property which doesn't allow a persistent unnamed pool to be deleted will force it to exist for the duration of the user's session.
Adding a resource to an unnamed pool will search for the first active unnamed pool, either in current scope or any previous scope. Once a resource is added to a named or unnamed pool, it will survive until that pool gets deleted (or the resource is deleted).
When an external procedure is ran persistent, all resources will survive until the procedure is deleted; when the procedure is deleted, it will delete all the resources in the non-persistent pools.
Modifier and Type | Class and Description |
---|---|
private static class |
WidgetPool.WidgetPoolData
The data needed for a widget pool, named or unnamed.
|
(package private) static class |
WidgetPool.WidgetPoolHelper
Helper to expose APIs which have direct access to the context-local state.
|
private static class |
WidgetPool.WorkArea
Container for the widget-pool data.
|
Modifier and Type | Field and Description |
---|---|
private static java.util.Deque<java.lang.Integer> |
EMPTY_DEQUE
A marker instance for an empty dequeu.
|
private static ContextLocal<WidgetPool.WorkArea> |
local
The widget pools are private per each context.
|
private static java.util.logging.Logger |
LOG
Logger
|
Constructor and Description |
---|
WidgetPool() |
Modifier and Type | Method and Description |
---|---|
static void |
addResource(WrappedResource resource,
character name)
Adds the specified resource to the pool.
|
static void |
create()
Create an unnamed pool.
|
static void |
create(boolean persistent)
Create an unnamed pool.
|
static void |
create(character name)
Create a pool with the given name.
|
static void |
create(character name,
boolean persistent)
Create a pool with the given name and the given "persistent" option.
|
static void |
create(java.lang.String name)
Create a pool with the given name.
|
static void |
create(java.lang.String name,
boolean persistent)
Create a pool with the given name and the given "persistent" option.
|
static void |
delete()
Delete an unnamed pool.
|
static void |
delete(character name)
Delete a pool with the given name.
|
static void |
delete(java.lang.String name)
Delete a pool with the given name.
|
private static void |
deleteNonPersistentPools(WidgetPool.WorkArea wa,
java.util.Set<java.lang.Integer> ids)
Filter the set of pool IDs and from it, delete only the non-persistent widget-pools.
|
private static void |
deletePool(WidgetPool.WorkArea wa,
WidgetPool.WidgetPoolData data)
Delete the specified pool.
|
(package private) static void |
deleteWidgetPools(java.lang.Object proc)
Delete all the non-persistent widget-pools associated with the specified procedure.
|
private static WidgetPool.WidgetPoolData |
findActivePool(WidgetPool.WorkArea wa,
java.lang.String name,
boolean currentScope)
Determine the active pool.
|
(package private) static WidgetPool.WidgetPoolHelper |
getHelper()
Get an instance of
WidgetPool.WidgetPoolHelper , which has the context-local instance saved,
so API access can be done without a context-local query. |
private static WidgetPool.WidgetPoolData |
getPool(WidgetPool.WorkArea wa,
int id)
Get the
pool with the given ID. |
private static WidgetPool.WorkArea |
locate()
Locate the context's
WidgetPool.WorkArea instance. |
private static WidgetPool.WidgetPoolData |
newPool(WidgetPool.WorkArea wa,
java.lang.String name,
boolean persistent)
Create a new pool and register it in the appropriate maps/sets.
|
(package private) static void |
removeResource(WrappedResource resource)
Remove the given resource from its pool, if it was pooled.
|
static boolean |
validWidgetPool(character name)
Determine if the specified
name targets a known widget pool. |
private static final java.util.logging.Logger LOG
private static final java.util.Deque<java.lang.Integer> EMPTY_DEQUE
private static final ContextLocal<WidgetPool.WorkArea> local
public static void delete()
public static void delete(java.lang.String name)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.public static void delete(character name)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.public static void create()
public static void create(boolean persistent)
persistent
- true
if the pool is persistent.public static void create(character name)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.public static void create(java.lang.String name)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.public static void create(java.lang.String name, boolean persistent)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.persistent
- true
if the pool is persistent.public static void create(character name, boolean persistent)
name
- The name of the newly created pool. Specify null
is the pool is
unnamed.persistent
- true
if the pool is persistent.public static void addResource(WrappedResource resource, character name)
resource
- The resource to be pooled.name
- The pool name, set to null
if the unnamed pool is to be used.java.lang.IllegalStateException
- The exception is throw if the call of this method targets a named pool (the
name
parameter is specified) and either the name is unknown or a pool
with the specified name does not exist.
If the exception is thrown, there must be an error in the code which creates the
resource. That code must validate the pool name (by calling
validWidgetPool(com.goldencode.p2j.util.character)
) before any other resource-related validation
and before the resource is created.
public static boolean validWidgetPool(character name)
name
targets a known widget pool.
A missing unnamed pool will be an error.
name
- The pool name, set to null
if the unnamed pool is to be used.true
if a pool was found with the specified name.static void deleteWidgetPools(java.lang.Object proc)
proc
- The external procedure instance.static void removeResource(WrappedResource resource)
resource
- The resource to be removed.static WidgetPool.WidgetPoolHelper getHelper()
WidgetPool.WidgetPoolHelper
, which has the context-local instance saved,
so API access can be done without a context-local query.private static WidgetPool.WorkArea locate()
WidgetPool.WorkArea
instance.private static WidgetPool.WidgetPoolData newPool(WidgetPool.WorkArea wa, java.lang.String name, boolean persistent)
wa
- The context-local state in WidgetPool.WorkArea
.name
- The name of this pool. Is null
if the pool is unnamed.persistent
- Flag identifying if this pool is persistent.definition
for the new pool.private static void deleteNonPersistentPools(WidgetPool.WorkArea wa, java.util.Set<java.lang.Integer> ids)
wa
- The context-local state in WidgetPool.WorkArea
.ids
- A set of pool IDs.private static void deletePool(WidgetPool.WorkArea wa, WidgetPool.WidgetPoolData data)
When a pool is deleted, all its contained resources will be deleted too.
wa
- The context-local state in WidgetPool.WorkArea
.data
- The definition of the pool to be deleted.private static WidgetPool.WidgetPoolData findActivePool(WidgetPool.WorkArea wa, java.lang.String name, boolean currentScope)
name
is not null
, than the active
named pool will be used.wa
- The context-local state in WidgetPool.WorkArea
.name
- The pool name. May be null
for an unnamed pool.currentScope
- true
when search must be done only in current scope.null
if no pool is found, else its
definition
is returned.private static WidgetPool.WidgetPoolData getPool(WidgetPool.WorkArea wa, int id)
pool
with the given ID.wa
- Context-local work area.id
- The pool's ID.