class DynamicQueryHelper
extends java.lang.Object
Modifier and Type | Class and Description |
---|---|
private static class |
DynamicQueryHelper.ParametrizedJast
A container for holding a JAST and its default parameters.
|
private static class |
DynamicQueryHelper.QueryCacheKey
Class that keys the already generated JAST trees within the
LFUAgingCache caches of
DynamicQueryHelper . |
private static interface |
DynamicQueryHelper.QueryProcessor
Allows to customize the processing of a predicate for generation of the dynamic query.
|
private static class |
DynamicQueryHelper.WorkArea
Container of context-local data.
|
Modifier and Type | Field and Description |
---|---|
static char |
BACK_SLASH
Back slash.
|
static char |
COLON
Colon.
|
static char |
DOT
Dot.
|
static char |
DOUBLE_QUOTE
Double quote.
|
private static java.lang.String |
DYN_GEN_QUERY_CLASS
The name of the generated java class.
|
private static java.lang.String |
FIND_FIRST_TOK
Token to prepend to a find-first predicate in order to obtain a well formed P4GL query.
|
private static ContextLocal<DynamicQueryHelper.WorkArea> |
local
Reference to context-local data.
|
private static java.util.logging.Logger |
LOG
Logger.
|
private static java.lang.String |
LVL1_CACHE_SIZE
The name of the directory key for the size of level 1 cache holding converted queries.
|
private static ExpiryCache<DynamicQueryHelper.QueryCacheKey,DynamicQueryHelper.ParametrizedJast> |
lvl1Cache
1st level cache.
|
private static java.lang.String |
LVL2_CACHE_SIZE
The name of the directory key for the size of level 2 cache holding converted queries.
|
private static ExpiryCache<DynamicQueryHelper.QueryCacheKey,JavaAst> |
lvl2Cache
2nd level cache.
|
private static java.util.concurrent.atomic.AtomicLong |
queryCounter
A counter of compiled dynamic query classes.
|
static char |
QUOTE
Single quote.
|
static char |
TILDE
Tilde.
|
private static java.util.Map<java.lang.String,java.lang.Integer> |
wrapperToTokenType
Map of P2J wrappers to their associated token type.
|
Constructor and Description |
---|
DynamicQueryHelper() |
Modifier and Type | Method and Description |
---|---|
private static void |
addToCache1(JavaAst jAst,
DynamicQueryHelper.QueryCacheKey cacheKey,
java.util.Map<java.lang.String,java.lang.Object> params)
Adds a computed JAST to first level cache along with its default parameters.
|
private static void |
addToCache2(JavaAst jAst,
DynamicQueryHelper.QueryCacheKey cacheKey)
Adds a computed JAST to second level cache.
|
private static DataModelAst |
buildDataModelClass(Buffer buf,
RecordBuffer rbuf)
Create a
data model object AST for the specified buffer. |
private static DataModelAst |
buildIndex(Buffer buf,
RecordBuffer rbuf,
P2JIndex index,
java.lang.String idxName,
java.util.Map<java.lang.String,DataModelAst> propMap)
Build a
index for the specified buffer. |
private static DataModelAst |
buildIndexComponent(P2JIndexComponent comp,
DataModelAst propAst)
Build an
index component associated with the given property AST. |
private static DataModelAst |
buildProperty(Buffer buf,
java.lang.reflect.Field field,
int extent)
Create a
property AST for the specified DMO java field. |
private static DataModelAst |
buildRootDataModel(java.lang.String schema)
Build the
root AST and associated with the given schema. |
private static ProgressAst |
buildRootSchema(java.lang.String schema)
Build the root
ProgressAst node for the schema dictionary AST. |
private static ProgressAst |
buildTempTable(DataModelAst p2o,
RecordBuffer rbuf,
integer order)
Build a temp-table definition to be loaded in the
SchemaDictionary . |
private static java.util.List<java.lang.String> |
collectBuffers(ProgressAst result)
Get the buffer names used by the AST produced for converted predicated.
|
private static DataModelAst |
createDataModelAst(int type,
java.lang.String text)
Create a
DataModelAst with the given token type and text. |
private static ProgressAst |
createProgressAst(int type,
java.lang.String text)
Create a
ProgressAst with the given token type and text. |
private static java.util.Map<java.lang.String,java.lang.Object> |
extractParams(ProgressAst progAst)
Process the
progAst and replace all literals by confectioned variables of the
required type. |
private static java.lang.String |
getCacheKey(java.lang.String predicate,
ProgressAst progAst,
int cacheLevel)
Computes a string that will be used in the cache key to uniquely and quickly identify the
query.
|
private static ProgressAst |
getSibling(ProgressAst progAst)
Obtain the other operand of a binary operator node.
|
private static java.lang.Object |
injectVariable(ProgressAst litAst,
java.lang.String varName,
ProgressAst progAst)
Injects a new variable in place of a literal.
|
private static DynamicQueryHelper.WorkArea |
locate()
Locate the context-local
DynamicQueryHelper.WorkArea instance. |
private static int |
locateBuffer(java.lang.String name)
Locate a
Buffer with the given name , from the DynamicQueryHelper.WorkArea.buffers
list and return its position. |
private static P2JQuery |
parse(DynamicQueryHelper.QueryProcessor processor,
java.util.List<Buffer> buffers,
java.lang.String predicate,
java.lang.String qname)
Private worker for parsing a given query string using the QueryProcessor and return a
P2JQuery instance. |
(package private) static P2JQuery |
parseFindQuery(Buffer buffer,
java.lang.String predicate,
LockType lock,
java.lang.String qname)
Parse the given predicate string and return a
FindQuery instance. |
(package private) static P2JQuery |
parseQuery(java.util.List<Buffer> buffers,
java.lang.String predicate,
java.lang.String qname)
Parse the given query string and return a
P2JQuery instance. |
private static void |
prepareQueryTree(AnnotatedAst root)
Prepare the query AST by placing the appropriate annotations with the converted java names
for the external program and also by created bogus
ProgressParserTokenTypes.DEFINE_TEMP_TABLE nodes (which would be created from a
DEFINE TEMP-TABLE tt. statement, with no fields); the later is needed to allow
proper conversion of the default buffer name. |
private static void |
prepareTempTable(SchemaDictionary dict,
java.lang.StringBuilder pcode)
Process the definitions of the temp-tables (associated with the temporary buffers in the
given list) to create the associated dictionary and p2o ASTs.
|
private static void |
showConversionError(java.lang.Exception exc,
java.lang.String operation,
java.lang.String pCode)
Shows a conversion error in a modal dialog and registers it in the error message list; does
not set the ERROR-STATUS:ERROR flag.
|
private static boolean |
validateBuffers(java.util.List<java.lang.String> realBuffers)
Validate the list of buffers against the buffers loaded by this QUERY resource (loaded in
the
DynamicQueryHelper.WorkArea.buffers list. |
public static final char COLON
public static final char DOT
public static final char QUOTE
public static final char DOUBLE_QUOTE
public static final char BACK_SLASH
public static final char TILDE
private static final java.lang.String FIND_FIRST_TOK
pcode
is an FIND-FIRST
or OPEN QUERY statement.private static final java.lang.String DYN_GEN_QUERY_CLASS
private static final java.lang.String LVL1_CACHE_SIZE
private static final java.lang.String LVL2_CACHE_SIZE
private static final java.util.logging.Logger LOG
private static final java.util.Map<java.lang.String,java.lang.Integer> wrapperToTokenType
private static final java.util.concurrent.atomic.AtomicLong queryCounter
private static final ContextLocal<DynamicQueryHelper.WorkArea> local
private static final ExpiryCache<DynamicQueryHelper.QueryCacheKey,DynamicQueryHelper.ParametrizedJast> lvl1Cache
private static final ExpiryCache<DynamicQueryHelper.QueryCacheKey,JavaAst> lvl2Cache
private static P2JQuery parse(DynamicQueryHelper.QueryProcessor processor, java.util.List<Buffer> buffers, java.lang.String predicate, java.lang.String qname)
P2JQuery
instance.
This method is only called by the package-public methods parseQuery(java.util.List<com.goldencode.p2j.persist.Buffer>, java.lang.String, java.lang.String)
and
parseFindQuery(com.goldencode.p2j.persist.Buffer, java.lang.String, com.goldencode.p2j.persist.lock.LockType, java.lang.String)
.processor
- The processor that will generate the Progress code to be converted and later
post-process the AST before generating the java code.buffers
- The list of buffers used by the query.predicate
- The query predicate.qname
- The query's name.P2JQuery
instance representing the given legacy query string.private static void addToCache1(JavaAst jAst, DynamicQueryHelper.QueryCacheKey cacheKey, java.util.Map<java.lang.String,java.lang.Object> params)
jAst
- The JAST to be added.cacheKey
- The cache key. For level 1 cache, the key should have the default parametersparams
- The default parameters for this query.private static void addToCache2(JavaAst jAst, DynamicQueryHelper.QueryCacheKey cacheKey)
jAst
- The JAST to be added.cacheKey
- The cache key. For level 1 cache, the key should have the default parametersprivate static java.lang.String getCacheKey(java.lang.String predicate, ProgressAst progAst, int cacheLevel)
In the case of 1st level cache key, the predicate is used (it should be a trimmed predicate with simplified spaces but this is time costly).
For the 2nd level cache, the key is this method returns the UPPERCASED (since the
predicate
contains no literals) string obtained from the traversal of the
progAst
in pre-fixed order (as obtained from AnnotatedAst
iterator). To
reduce the length (simplify) the key string, some of the nodes (that do not add any useful
information for our purpose) are removed in the process. The result is usually composed from
the list of the list of injected parameters, followed by the actual query. As noted above,
the WHERE clause is in prefixed form (operator then operands).
The method returns different key depending on cache key. Usually, the level 1 cache will use the predicate for generating a key while 2nd level cache will use the Progress AST as the primary source for creating the key.
predicate
- The original predicate.progAst
- The AST tree that was generated on that tree. Not available in level 1 cache.cacheLevel
- The cache level. In the case that cacheLevel = 1
the progAst
is
ignored as it is not expected that the Progress AST tree to be built at that time.static P2JQuery parseQuery(java.util.List<Buffer> buffers, java.lang.String predicate, java.lang.String qname)
P2JQuery
instance.buffers
- The list of buffers used by the query.predicate
- The query predicate.qname
- The query's name.P2JQuery
instance representing the given legacy query string.static P2JQuery parseFindQuery(Buffer buffer, java.lang.String predicate, LockType lock, java.lang.String qname)
FindQuery
instance.buffer
- The buffer used by the query.predicate
- The predicate to be parsed.lock
- The locking mode, may include the NO-WAIT flag.qname
- The query's name.P2JQuery
instance representing the given legacy query string.private static void prepareTempTable(SchemaDictionary dict, java.lang.StringBuilder pcode) throws PersistenceException
Also, it appends to the progress code string any needed 4GL code (like DEFINE BUFFER statements for explicit buffers, to refer back the originating table.
dict
- The schema dictionary where the temp-tables will be loaded.pcode
- Append any new progress code here.PersistenceException
- In case of problems during preparation of the temp-table schema and p2o ASTs.private static java.util.Map<java.lang.String,java.lang.Object> extractParams(ProgressAst progAst)
progAst
and replace all literals by confectioned variables of the
required type. The variable names are of a specific pattern so that they don't collide with
items from converted code and can be easily identified later.progAst
- The Progress AST of a procedure just parsed.BaseDataType
values of the literal they replaced. If no literals are found in the process,
null
is returned.private static ProgressAst getSibling(ProgressAst progAst)
null
.progAst
- The node to search for sibling.null
is
returned. In case of ternary operator, the result is irrelevant.private static java.lang.Object injectVariable(ProgressAst litAst, java.lang.String varName, ProgressAst progAst)
progAst
tree:
varName
variable of
the type requiredpost-parse-fixup.xml
was tun against it.BaseDataType
that will be returned. This will be used to initialize the
variable just created.litAst
- The AST of a literal to be replaced by a variable.varName
- The name of the variable to be created.progAst
- The root of the procedure. It is only needed to inject the definition of the new
variable.BaseDataType
of the literal replaced by the new variable.private static void prepareQueryTree(AnnotatedAst root)
ProgressParserTokenTypes.DEFINE_TEMP_TABLE
nodes (which would be created from a
DEFINE TEMP-TABLE tt.
statement, with no fields); the later is needed to allow
proper conversion of the default buffer name.root
- The root AST of the converted progress code.private static java.util.List<java.lang.String> collectBuffers(ProgressAst result)
result
- The list of buffer names.private static boolean validateBuffers(java.util.List<java.lang.String> realBuffers)
DynamicQueryHelper.WorkArea.buffers
list.
The buffers must have (all conditions must be true):
realBuffers
- The list of buffer names used at the query predicated.true
if the buffers are valid.private static int locateBuffer(java.lang.String name)
Buffer
with the given name
, from the DynamicQueryHelper.WorkArea.buffers
list and return its position.name
- The buffer name.private static ProgressAst buildTempTable(DataModelAst p2o, RecordBuffer rbuf, integer order)
SchemaDictionary
. Use the given
data model object
AST as the source.p2o
- The data model object AST.rbuf
- The record buffer instance.order
- The order of this temp-table AST.private static ProgressAst buildRootSchema(java.lang.String schema)
ProgressAst
node for the schema dictionary AST.schema
- The schema name.private static DataModelAst buildRootDataModel(java.lang.String schema)
root
AST and associated with the given schema.schema
- The schema name.private static DataModelAst buildDataModelClass(Buffer buf, RecordBuffer rbuf) throws PersistenceException
data model object
AST for the specified buffer.buf
- The buffer instance.rbuf
- The RecordBuffer
instance for the buffer.DataModelAst
buffer definition.PersistenceException
- In case of problems during preparation of the temp-table schema and p2o ASTs.private static DataModelAst buildProperty(Buffer buf, java.lang.reflect.Field field, int extent)
property
AST for the specified DMO java field.buf
- The Buffer
instance to which the property belongs.field
- The java field defining this property at the DMO.extent
- The legacy extent of this property.DataModelAst
property definition.private static DataModelAst buildIndex(Buffer buf, RecordBuffer rbuf, P2JIndex index, java.lang.String idxName, java.util.Map<java.lang.String,DataModelAst> propMap)
index
for the specified buffer.buf
- The Buffer
instance to which the index belongs.rbuf
- The RecordBuffer
instance.index
- The index definition.idxName
- The index name.propMap
- A map with the property
ASTs by their legacy name.index
definition.private static DataModelAst buildIndexComponent(P2JIndexComponent comp, DataModelAst propAst)
index component
associated with the given property AST.comp
- The index componentpropAst
- The associated property AST
.private static DataModelAst createDataModelAst(int type, java.lang.String text)
DataModelAst
with the given token type and text.type
- The node's token type.text
- The node's text.DataModelAst
instance setup as noted above.private static ProgressAst createProgressAst(int type, java.lang.String text)
ProgressAst
with the given token type and text.type
- The node's token type.text
- The node's text.ProgressAst
instance setup as noted above.private static DynamicQueryHelper.WorkArea locate()
DynamicQueryHelper.WorkArea
instance.private static void showConversionError(java.lang.Exception exc, java.lang.String operation, java.lang.String pCode)
Could not [details] the 'This method does the best effort to match the Progress message by analyzing the failing token.DynamicQueryHelper.WorkArea.predicate
' predicate for queryDynamicQueryHelper.WorkArea.qname
exc
- The exception causing the conversion error.operation
- The type of operation that failed.pCode
- The progress code being processed.