public class ExpressionConversionWorker.ExpressionHelper
extends java.lang.Object
Constructor and Description |
---|
ExpressionHelper() |
Modifier and Type | Method and Description |
---|---|
java.lang.String |
asciiCode(java.lang.String str)
Get the ASCII-code representation of the given string.
|
java.lang.String |
asString(int code)
Get the string-representation of the given ASCII code.
|
java.lang.String |
cleanDecimal(java.lang.String str,
boolean isInt)
Converts a Progress 4GL style string which represents an integer or
a decimal into a Java style string representing the same number.
|
java.lang.String |
cleanFormattedDate(java.lang.String input)
Remove unnecessary characters and extra zero digits from input that represents
a valid date.
|
java.lang.String |
convertToRegEx(java.lang.String text)
Exposes a helper method to convert Progress match patterns into regular expressions using
the static method
SQLHelper.convertToRegEx(String, boolean) . |
java.lang.String |
convertToSQLBegins(java.lang.String text)
Exposes a helper method to convert a second operand of the "op1 BEGINS op2" function into
corresponding SQL LIKE expression using the static method
SQLHelper.convertToSQLBegins(String, boolean) |
java.lang.String |
convertToSQLContains(java.lang.String text)
Exposes a helper method to convert a second operand of the "op1 CONTAINS op2" function
into corresponding SQL LIKE expression using the static method
SQLHelper.convertToSQLContains(String, boolean) |
java.lang.String |
convertToSQLLike(java.lang.String text)
Exposes a helper method to convert Progress match patterns into SQL LIKE match
expressions using the static method
character.convertToSQLLike() . |
java.lang.String |
encodeToJavaSource(java.lang.String string)
Converts a runtime string to text representation of a java string literal.
|
java.lang.String |
evaluateCharacterExpression(Aast expr)
Evaluate the given expression by concatenating all the operands.
|
java.lang.String |
expressionType(Aast source)
Walks the
ProgressAst node specified and determines the
data type of the wrapper object returned by that sub-expression. |
java.lang.String |
expressionType(Aast source,
boolean infer)
Walks the
ProgressAst node specified and determines the
data type of the wrapper object returned by that sub-expression. |
int |
formattedResultSize(Aast node,
java.lang.String fmt,
boolean java)
Calculates the correct maximum size of the text output using the
given format string for the given data type.
|
BaseDataType |
instanceOfBDT(java.lang.String clsname)
Create an instance of the BDT that is specified by the given class name.
|
boolean |
isAssignmentCompatible(java.lang.String ftype,
java.lang.String stype)
Analyzes the type of operands and infers if the two types are assignment
compatible.
|
boolean |
isCaseInsensitive(Aast ast)
Walks the
ProgressAst node specified and determines if the expression
is a case-insensitive character expression. |
boolean |
isExpressionNode(Aast source)
Walks the
ProgressAst node specified and determines if
the given node is a valid part of an expression. |
boolean |
isFormatCompatible(Aast source,
java.lang.String format)
Check if specified format string is compatible with type of
expression passed as a parameter.
|
boolean |
isQuoted(java.lang.String text)
Detects if the first and last characters of the string are 4GL quote
characters.
|
java.lang.String |
parameterTypeName(Aast ast,
int idx,
boolean fuzzy)
Lookup the parameter type at the specified index position for the built-in function
or method specified by given AST.
|
java.lang.String |
parseProgressCharLiteral(java.lang.String progress)
Parses a Progress 4GL compatible string, by stripping off enclosing quotes/string options
and converting the contents (including rewriting escape sequences).
|
java.lang.String |
preprocessFormatString(java.lang.String fmt)
Expands Progress format strings into the full text, explicit form
of the format string.
|
java.lang.String |
processEscapes(java.lang.String text)
Exposes a helper method to convert a Java string literal into
a runtime Java string (by processing the text of all escape
sequences into the corresponding character).
|
java.lang.String |
progressToJavaString(java.lang.String text)
Exposes a helper method to convert Progress string literals into
the correct Java string literal using the static method
character.progressToJavaString() . |
java.lang.String |
progressToJavaString(java.lang.String text,
boolean isPathName)
Exposes a helper method to convert Progress string literals into
the correct Java string literal using the static method
character.progressToJavaString() . |
java.lang.String |
stripQuotes(java.lang.String text)
Remove a matching pair first and last characters if they both exist and if they are one
of the 4GL quote characters.
|
java.lang.String |
toUpperCase(java.lang.String text)
Exposes a helper method which allows to return the uppercased
version of the runtime or hardcoded string using the static method
TextOps.toUpperCase(String, boolean) |
public java.lang.String asString(int code)
code
- The ASCII code.public java.lang.String asciiCode(java.lang.String str)
str
- Character to be converted.public java.lang.String progressToJavaString(java.lang.String text)
character.progressToJavaString()
.text
- A valid Progress string literal enclosed in double or
single quotes and possibly with string options.public java.lang.String progressToJavaString(java.lang.String text, boolean isPathName)
character.progressToJavaString()
.text
- A valid Progress string literal enclosed in double or
single quotes and possibly with string options.isPathName
- Boolean flag indicating the first parameter is the path string
to be handled differently than usual string.public boolean isQuoted(java.lang.String text)
text
- The text to check.true
if this is a quoted string.public java.lang.String stripQuotes(java.lang.String text)
text
- The text to modify.public java.lang.String parseProgressCharLiteral(java.lang.String progress)
Escaped characters (using either the tilde or the backslash character) and special formations will be converted to in-memory values and any escaped characters will be replaced with that value.
The flow of processing of string literals:
parseProgressCharLiteral(string)
. This method. Constructs an
in-memory of the string exactly as the Progress lexer sees it. The specially
escaped characters are expanded in memory as their ASCII values. Because the
plain text, further processing is clean and correct.
convertToSQL___
. Optional. The set of methods will transform the
previously read string into a pattern for SQL LIKE clause. These methods handles
the input string using Progress matching rules. Wildcard are converted to SQL
equivalents, escaping at the same time the native ones. They are aware of the
unix-escapes. Optionally, if P2J decided to execute on server side, the string
literal is SQL encoded.
encodeToJavaSource(String)
. This will
add necessary escapes so that the string is a valid java string literal. The
time the literal stays in this 'serialization' is rather short because the java
source file is compiled after a successful conversion. It will then be loaded
by the runtime and stored in memory.
HQLPreprocessor
.
Otherwise, the (back) unencoded string is passed to query as parameter, in which
case the SQL driver will automatically handle it.
If the string literal do not need special processing at conversion time, it is safe to
convert it from progress encoding directly to java encoding using
progressToJavaString(String)
.
progress
- The string as read from Progress source file with possible Progress encodings.public java.lang.String encodeToJavaSource(java.lang.String string)
string
- The runtime string.public java.lang.String processEscapes(java.lang.String text)
text
- A valid Java string literal (not enclosed in double quotes).public java.lang.String preprocessFormatString(java.lang.String fmt)
fmt
- A valid Progress format string.public int formattedResultSize(Aast node, java.lang.String fmt, boolean java)
The given format should not have had its escape sequences processed into a runtime form.
node
- The expression or sub-expression node for which the format
string is to be used.fmt
- A valid format string.java
- false
if the given string is as encoded in
the original source file (it should not have been
converted to a Java string). true
if this
format string is text that is valid for encoding in a
Java source file.public BaseDataType instanceOfBDT(java.lang.String clsname)
clsname
- The classname of a BDT subclass, in the proper case (generally all
lowercase).null
or not a valid
BDT subclass, then an instance of the unknown.class
will
be returned.public java.lang.String convertToRegEx(java.lang.String text)
SQLHelper.convertToRegEx(String, boolean)
.text
- A valid Progress match pattern. It uses Progress encoding (including quotes).parseProgressCharLiteral(String)
,
SQLHelper.convertToRegEx(String, boolean)
,
encodeToJavaSource(String)
public java.lang.String convertToSQLLike(java.lang.String text)
character.convertToSQLLike()
.text
- A valid Progress match pattern.parseProgressCharLiteral(String)
public java.lang.String convertToSQLBegins(java.lang.String text)
SQLHelper.convertToSQLBegins(String, boolean)
text
- A second operand of the "op1 BEGINS op2" function.parseProgressCharLiteral(String)
public java.lang.String convertToSQLContains(java.lang.String text)
SQLHelper.convertToSQLContains(String, boolean)
text
- A second operand of the "op1 CONTAINS op2" function.parseProgressCharLiteral(String)
public java.lang.String toUpperCase(java.lang.String text)
TextOps.toUpperCase(String, boolean)
text
- The string to convertpublic java.lang.String cleanFormattedDate(java.lang.String input)
input
- The text to cleanup.public java.lang.String cleanDecimal(java.lang.String str, boolean isInt)
On input in the 4GL, only the following characters may be present:
During scanning, if any other character (than those noted above) is encountered, it will cause an invalid character error if some other error has not been found previously.
The parsing can be considered as having 3 phases:
Phase 1 (pre-number) ends when the first digit or "near digit" character is encountered. The near digits are the group and decimal separators. In the pre-number phase, there can be zero or one sign characters, zero or more asterisks and any amount of whitespace. The whitespace can be anywhere in this section and the amount of contiguous whitespace is not limited. If there are more one asterisk, they may be separated by whitespace however, all asterisks must occur on only one side of the sign (not on both sides of any sign character). Once phase 1 is complete, asterisks may no longer be present in the string.
Phase 2 (number parsing) is the only phase in which digits or near digits may be present. In addition, no other characters besides digits and near digits may be present in this phase. So there can be no whitespace, sign characters or asterisks. The first non-digit (or non-near-digit) ends number parsing. There may be zero or more group separators in any configuration in the number parsing phase. Group separators are simply dropped and have no meaning other than being a near-digit (and thus affecting parsing). There may be zero or one decimal separator in the number parsing section. There may be any number of digits (so long as it is not larger than can be converted into a valid integer or decimal). Leading zeros (in the portion before the decimal point) and trailing zeros (in the portion after the decimal point) are dropped. This corresponds to the 4GL behavior where an unlimited number of leading and trailing zeros can be present and are ignored (since they have no effect on the value of the number).
Phase 3 (post-number) extends after phase 2 to the end of the string. Any amount of whitespace is allowed in this section. In addition, if there was no sign character in the pre-number section, then one sign character is allowed here (as a post-fixed sign). Any other character is invalid.
There is a special case where the number parsing phase is empty. This can happen if there are no digits (or near-digits) on input. If the first sign character follows an asterisk, this is taken as the end of the number parsing phase, even if there were no digits and/or there are digits following the sign. If there were such following digits, they would be in the post-number phase and would trigger an error. If there are no digits on output (effectively the empty string or just a "-", this is a valid string and will be converted to the number "0".
Translations:
Input Character Output Result ------------------ -------------------------------------------------- digit 0 If a leading 0 to the left of the decimal point or if a trailing 0 to the right of the decimal point, then this zero is dropped. Otherwise it is copied to the output string. digit (1 - 9) Copied to output string. group separator Dropped. decimal separator 1st is copied to output string. 2nd causes an error. whitespace Dropped. + sign character 1st is dropped. 2nd causes one of 2 possible errors. - sign character 1st is prefixed in the output string. 2nd causes one of 2 possible errors. asterisks Dropped.
Sign characters are normalized (prefixed and postfixed '+' is removed, '-'. The 2nd sign character will always cause an error, but the error that occurs will depend on the parsing phase. A post-fixed sign is fine so long as it is the first sign character encountered. But any sign character (first or second) appearing in the post-number phase will generate an invalid character error. Before the 3rd phase, the 1st sign will be honored and the second sign character will raise a "more than 1 sign" error. Note that for the purposes of counting sign characters, the direction of the sign has no meaning (-+, --, ++, +- are all equivalent errors).
The decimal separator is '.' and the group separator is ',' for this method, which is sufficient for processing 4GL decimal literals.
Do not pass invalid input to this method. It uses
NumberType.parseDecimal()
as a worker, which expects the
runtime to be operational and will raise error conditions. This won't
work during conversion.
str
- The Progress style integer or decimal encoded as a string.
If this is an empty string, then the value 0 will be returned
(just like Progress).isInt
- true
if the result of this function will be
interpreted as an integer. Affects error handling.double
or into a BigDecimal
.public java.lang.String evaluateCharacterExpression(Aast expr)
expressionType(Aast, boolean)
is not character
, return
null
.expr
- The AST expression.public java.lang.String expressionType(Aast source)
ProgressAst
node specified and determines the
data type of the wrapper object returned by that sub-expression. This
method processes the subtree recursively as needed to determine the
proper type.
At this time there is support for all basic data types (date,
character, integer, decimal, logical, recid, rowid, raw and memptr).
The special FUNC_POLY
type is only supported for the
following built-in functions:
ABSOLUTE IF INPUT MAXIMUM MINIMUM
The INPUT built-in function normally returns the same type as the
single parameter (which must be an lvalue which is found in a frame
that is in scope). However, this function can be used in an
expression that requires a character
data type even in
the case where the parameter is NOT of the character
type! This is like an override option and it must be detected from
the SURROUNDING expression (above the FUNC_POLY node). This support
is implemented except for one case: the usage of INPUT as a
parameter to another built-in function (or presumably a method) which
expects a character
parameter will also cause this
conversion. At this time there is no support in these cases. The
resulting type (if not already character
) will cause the
wrong type to be emitted.
Attributes and methods are fully supported except for the
ATTR_POLY and METH_POLY
which are recognized but no
specific cases are currently handled. In particular, the
BUFFER-VALUE
is particularly difficult and has not been
resolved.
source
- The AST node to be inspected.public java.lang.String expressionType(Aast source, boolean infer)
ProgressAst
node specified and determines the
data type of the wrapper object returned by that sub-expression. This
method processes the subtree recursively as needed to determine the
proper type.
At this time there is support for all basic data types (date,
character, integer, decimal, logical, recid, rowid, raw and memptr).
The special FUNC_POLY
type is only supported for the
following built-in functions:
ABSOLUTE IF INPUT MAXIMUM MINIMUM
The INPUT built-in function normally returns the same type as the
single parameter (which must be an lvalue which is found in a frame
that is in scope). However, this function can be used in an
expression that requires a character
data type even in
the case where the parameter is NOT of the character
type! This is like an override option and it must be detected from
the SURROUNDING expression (above the FUNC_POLY node). This support
is implemented except for one case: the usage of INPUT as a
parameter to another built-in function (or presumably a method) which
expects a character
parameter will also cause this
conversion. At this time there is no support in these cases. The
resulting type (if not already character
) will cause the
wrong type to be emitted.
Attributes and methods are fully supported except for the
ATTR_POLY and METH_POLY
which are recognized but no
specific cases are currently handled. In particular, the
BUFFER-VALUE
is particularly difficult and has not been
resolved.
source
- The AST node to be inspected.infer
- If true
AND if the type is indeterminate (this typically only
can occur for polymorphic return types), then the type will be inferred
from the surrounding context (e.g. containing nodes) when possible.public boolean isCaseInsensitive(Aast ast)
ProgressAst
node specified and determines if the expression
is a case-insensitive character expression.
This method is called when deciding if a P4GL CASE expression that will be converted to
a java switch will be evaluated as case sensitive or not.ast
- The AST node to be inspected.true
if the expression is a case sensitive character expression and
false
if the expression is NOT a character expression or it is a
case-insensitive character expression.public boolean isAssignmentCompatible(java.lang.String ftype, java.lang.String stype)
ftype
- The type of the first operand.stype
- The type of the second operand.true
if the two types can be assigned interchangeably.public java.lang.String parameterTypeName(Aast ast, int idx, boolean fuzzy)
ast
- The parent AST of the parameter which needs its type resolved.idx
- The zero-based index position of the parameter to lookup.fuzzy
- Determines if "fuzzy" function signature matching is allowed. See SignatureHelper.getSignature(int, int, String[], boolean)
.public boolean isFormatCompatible(Aast source, java.lang.String format)
source
- The expression to check compatibility with.format
- Format string.true
if expression and format string are
compatible with each other.public boolean isExpressionNode(Aast source)
ProgressAst
node specified and determines if
the given node is a valid part of an expression.source
- The AST node to be inspected.true
if the given node is a valid expression
or sub-expression node. If false
, then this
node and its subtree cannot be processed as part of an
expression.