-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' of https://github.com/progress/Spark-Toolkit i…
…nto develop
- Loading branch information
Showing
32 changed files
with
2,761 additions
and
915 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
763 changes: 574 additions & 189 deletions
763
src/OpenEdge/BusinessLogic/Filter/AblFilterParser.cls
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/************************************************ | ||
Copyright (c) 2019 by Progress Software Corporation. All rights reserved. | ||
*************************************************/ | ||
/*------------------------------------------------------------------------ | ||
File : FilterParser | ||
Purpose : A parent/abstract filter parse class for creating | ||
objects data requests for a CCS Business Entity's getData() | ||
and getResultCount() operations | ||
Syntax : | ||
Description : | ||
Author(s) : pjudge | ||
Created : 2016-12-07 | ||
Notes : | ||
----------------------------------------------------------------------*/ | ||
block-level on error undo, throw. | ||
|
||
using Ccs.BusinessLogic.IGetDataRequest. | ||
using Ccs.BusinessLogic.IQueryEntry. | ||
using Ccs.BusinessLogic.IQuerySortEntry. | ||
using OpenEdge.Core.Assert. | ||
|
||
class OpenEdge.BusinessLogic.Filter.FilterParser abstract: | ||
/* An ordered set of table names used to create this filter. | ||
Typically just one, but potentially more */ | ||
define public property FilterTable as character extent no-undo | ||
get. | ||
private set. | ||
|
||
/* Default constructor. */ | ||
constructor public FilterParser(): | ||
this-object('':u). | ||
end constructor. | ||
|
||
/* Constructor. | ||
@param character (mandatory) A table name for which to construct the filter */ | ||
constructor public FilterParser(input pTable as character): | ||
super(). | ||
Assert:NotNull(pTable, 'Table name'). | ||
assign extent(FilterTable) = 1 | ||
this-object:FilterTable[1] = pTable | ||
. | ||
end constructor. | ||
|
||
/* Constructor. | ||
@param character[] (mandatory) An array of table name for which to construct the filter */ | ||
constructor public FilterParser(input pTable as character extent): | ||
super(). | ||
Assert:NotNull(pTable, 'Table name'). | ||
assign this-object:FilterTable = pTable. | ||
end constructor. | ||
|
||
/* Reads and processes (parses) a complete data filter. | ||
@param P.L.Object The filter data | ||
@param IGetDataRequest A new filter object */ | ||
method abstract public IGetDataRequest Parse(input pData as Progress.Lang.Object). | ||
|
||
/* Parses where/filter phrase and returns an IQueryEntry object for a single table | ||
@param P.L.Object The filter/where clause data | ||
@return IQueryEntry The query entry.We return one of an IQueryPredicate (single clause) | ||
or an IQueryGroup (many clauses) */ | ||
method abstract public IQueryEntry ParseWhere(input pWhere as Progress.Lang.Object). | ||
|
||
/* Parses an SORT-BY phrase and returns an array of IQuerySortEntry objects. | ||
@param P.L.Object The SORT-BY data | ||
@return IQuerySortEntry[] An array of sort phrases. An indeterminate array is returned if the input phrase is empty */ | ||
method abstract public IQuerySortEntry extent ParseSortBy(input pSortBy as Progress.Lang.Object). | ||
|
||
end class. |
218 changes: 218 additions & 0 deletions
218
src/OpenEdge/BusinessLogic/Filter/FilterParserBuilder.cls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
/* ************************************************************************************************************************* | ||
Copyright (c) 2018, 2021 by Progress Software Corporation and/or one of its subsidiaries or affiliates. All rights reserved. | ||
************************************************************************************************************************** */ | ||
/*------------------------------------------------------------------------ | ||
File : FilterParserBuilder | ||
Purpose : Contains a registry of objects used to parse JSON or other (typically) | ||
string-based filters and create strongly-typed objects | ||
Description : | ||
Author(s) : pjudge | ||
Created : 2018-08-05 | ||
----------------------------------------------------------------------*/ | ||
block-level on error undo, throw. | ||
|
||
using OpenEdge.BusinessLogic.Filter.FilterParser. | ||
using OpenEdge.BusinessLogic.Filter.FilterParserBuilder. | ||
using OpenEdge.BusinessLogic.Filter.FilterParserRegistry. | ||
using OpenEdge.Core.Assert. | ||
using OpenEdge.Core.ISupportInitialize. | ||
using OpenEdge.Core.Util.BuilderRegistry. | ||
using OpenEdge.Core.Util.ConfigBuilder. | ||
using Progress.Json.ObjectModel.JsonObject. | ||
using Progress.Json.ObjectModel.JsonDataType. | ||
using Progress.Json.ObjectModel.JsonArray. | ||
|
||
class OpenEdge.BusinessLogic.Filter.FilterParserBuilder inherits ConfigBuilder: | ||
/* (mandatory) The filter pattern for which we create the Parser */ | ||
define public property FilterPattern as character no-undo | ||
get. | ||
private set. | ||
|
||
/** Each concrete builder will implement this differently */ | ||
define public property Parser as FilterParser no-undo | ||
get(): | ||
return BuildParser(). | ||
end get. | ||
|
||
/** Registry for mapping build types to their implementations */ | ||
define static public property Registry as BuilderRegistry no-undo | ||
get(): | ||
define variable oRegistry as BuilderRegistry no-undo. | ||
if not valid-object(FilterParserBuilder:Registry) then | ||
do: | ||
assign oRegistry = new BuilderRegistry(get-class(FilterParserBuilder)). | ||
oRegistry:Put(get-class(FilterParserBuilder):TypeName, get-class(FilterParserBuilder)). | ||
assign FilterParserBuilder:Registry = oRegistry. | ||
end. | ||
return FilterParserBuilder:Registry. | ||
end get. | ||
private set. | ||
|
||
/* Constructor | ||
@param character The filter type that we're constructing a parser for */ | ||
constructor public FilterParserBuilder (input pPattern as character): | ||
Assert:NotNullOrEmpty(pPattern, 'Filter pattern'). | ||
|
||
assign this-object:FilterPattern = pPattern. | ||
end constructor. | ||
|
||
/* Returns a parser builder for a give filter pattern. | ||
@param character The filter pattern name | ||
@return FilterParserBuilder A builder for a parser for that pattern. */ | ||
method static public FilterParserBuilder Build(input pPattern as character): | ||
define variable builderType as Progress.Lang.Class no-undo. | ||
define variable builder as FilterParserBuilder no-undo. | ||
|
||
Assert:NotNull(pPattern, 'Filter data'). | ||
|
||
assign builderType = FilterParserBuilder:Registry:Get(get-class(FilterParserBuilder):TypeName). | ||
if valid-object(builderType) then | ||
do: | ||
Assert:IsType(builderType, get-class(FilterParserBuilder)). | ||
|
||
builder = dynamic-new string(builderType:TypeName)(pPattern). | ||
end. | ||
else | ||
builder = new FilterParserBuilder(pPattern). | ||
|
||
if type-of(builder, ISupportInitialize) then | ||
cast(builder, ISupportInitialize):Initialize(). | ||
|
||
return builder. | ||
end method. | ||
|
||
/* Builds a parser for a JSON filter. This array version loops through the | ||
array and passes any OBJECT or STRING entries to the relevant Build() | ||
method. | ||
@param JsonArray The entire filter | ||
@return FilterParserBuilder The filter parser builder to use */ | ||
method static public FilterParserBuilder Build(input pFilter as JsonArray): | ||
define variable builder as FilterParserBuilder no-undo. | ||
define variable loop as integer no-undo. | ||
define variable cnt as integer no-undo. | ||
|
||
Assert:NotNull(pFilter, 'JSON Filter'). | ||
|
||
assign cnt = pFilter:Length. | ||
do loop = 1 to cnt | ||
while not valid-object(builder): | ||
|
||
case pFilter:GetType(loop): | ||
when JsonDataType:ARRAY then | ||
assign builder = FilterParserBuilder:Build(pFilter:GetJsonArray(loop)). | ||
when JsonDataType:OBJECT then | ||
assign builder = FilterParserBuilder:Build(pFilter:GetJsonObject(loop)). | ||
when JsonDataType:STRING then | ||
assign builder = FilterParserBuilder:Build(pFilter:GetCharacter(loop)). | ||
end case. | ||
end. | ||
|
||
return builder. | ||
end method. | ||
|
||
/* Builds a parser for a JSON filter | ||
Specialised JSON filter parsers are used. To figure out which on to | ||
use | ||
1. Look for a string property called mappingType and use that property value | ||
2. Loop for a property in the JSON that matches one of the | ||
registered filter parsers. | ||
3. Return without raising error. | ||
@param JsonObject The entire filter | ||
@return FilterParserBuilder The filter parser builder to use */ | ||
method static public FilterParserBuilder Build(input pFilter as JsonObject): | ||
define variable builder as FilterParserBuilder no-undo. | ||
define variable keyCnt as integer no-undo. | ||
define variable keyMax as integer no-undo. | ||
// AS CHARACTER suffers from ADAS-7500 | ||
define variable propNames as longchar extent no-undo. | ||
|
||
Assert:NotNull(pFilter, 'JSON Filter'). | ||
|
||
// 1. shortcut via a string mappingType property | ||
if pFilter:Has('mappingType':u) | ||
and pFilter:GetType('mappingType':u) eq JsonDataType:STRING | ||
then | ||
assign builder = FilterParserBuilder:Build(pFilter:GetCharacter('mappingType':u)). | ||
|
||
// we found a builder. If not we'll try the slow way. | ||
if valid-object(builder) then | ||
return builder. | ||
|
||
assign propNames = pFilter:GetNames() | ||
keyMax = extent(propNames) | ||
. | ||
// no data | ||
if extent(propNames) eq ? then | ||
return builder. | ||
|
||
// 2. Loop through the list of properties, by property name (not value) | ||
do keyCnt = 1 to keyMax | ||
while not valid-object(builder): | ||
{&_proparse_ prolint-nowarn(overflow)} | ||
assign builder = FilterParserBuilder:Build(string(propNames[keyCnt])). | ||
end. | ||
|
||
// 3. Return | ||
return builder. | ||
end method. | ||
|
||
/* Builds a parser for a JSON filter | ||
@param character The name of the parser to find | ||
@return FilterParser A usable parser, if one exists. May return NULL */ | ||
method protected FilterParser BuildParser(): | ||
define variable parserType as class Progress.Lang.Class no-undo. | ||
define variable fp as FilterParser no-undo. | ||
define variable filterTable as character extent no-undo. | ||
|
||
assign parserType = FilterParserRegistry:Registry:Get(this-object:FilterPattern). | ||
if not valid-object(parserType) then | ||
return parser. | ||
|
||
if HasOption('filterTable':u) then | ||
assign filterTable = GetOptionStringArrayValue('filterTable':u). | ||
|
||
// no option or empty data | ||
if extent(filterTable) eq ? then | ||
assign extent(filterTable) = 1 | ||
filterTable[1] = '':u | ||
. | ||
fp = dynamic-new string(parserType:TypeName) (filterTable). | ||
|
||
if type-of(fp, ISupportInitialize) then | ||
cast(fp, ISupportInitialize):Initialize(). | ||
|
||
return fp. | ||
end method. | ||
|
||
/* Sets the table for which this filter applies, if any | ||
@param character A table name for this filter | ||
@return FilterParserBuilder this object */ | ||
method public FilterParserBuilder TableName(input pTable as character): | ||
define variable tables as character extent 1 no-undo. | ||
|
||
Assert:NotNull(pTable, 'Table name'). | ||
assign tables[1] = pTable. | ||
|
||
return TableName(tables). | ||
end method. | ||
|
||
/* Sets the table for which this filter applies, if any | ||
@param character[] Table names for this filter | ||
@return FilterParserBuilder this object */ | ||
method public FilterParserBuilder TableName(input pTable as character extent): | ||
Assert:NotNull(pTable, 'Table name'). | ||
|
||
SetOption('filterTable':u, pTable). | ||
|
||
return this-object. | ||
end method. | ||
|
||
end class. |
52 changes: 52 additions & 0 deletions
52
src/OpenEdge/BusinessLogic/Filter/FilterParserRegistry.cls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* ************************************************************************************************************************* | ||
Copyright (c) 2018 by Progress Software Corporation and/or one of its subsidiaries or affiliates. All rights reserved. | ||
************************************************************************************************************************** */ | ||
/*------------------------------------------------------------------------ | ||
File : FilterParserRegistry | ||
Purpose : Contains a registry of objects used to parse JSON or other (typically) | ||
string-based filters and create strongly-typed objects | ||
Description : | ||
Author(s) : pjudge | ||
Created : 2018-08-05 | ||
----------------------------------------------------------------------*/ | ||
block-level on error undo, throw. | ||
|
||
using OpenEdge.BusinessLogic.Filter.AblFilterParser. | ||
using OpenEdge.BusinessLogic.Filter.FilterParser. | ||
using OpenEdge.BusinessLogic.Filter.FilterParserRegistry. | ||
using OpenEdge.BusinessLogic.Filter.JfpFilterParser. | ||
using OpenEdge.BusinessLogic.Filter.KendoFilterParser. | ||
using OpenEdge.Core.Util.BuilderRegistry. | ||
|
||
class OpenEdge.BusinessLogic.Filter.FilterParserRegistry: | ||
|
||
/** Registry for mapping build types to their implementations */ | ||
define static public property Registry as BuilderRegistry no-undo | ||
get(): | ||
define variable oRegistry as BuilderRegistry no-undo. | ||
if not valid-object(FilterParserRegistry:Registry) then | ||
do: | ||
assign oRegistry = new BuilderRegistry(get-class(FilterParser)). | ||
InitializeRegistry(oRegistry). | ||
assign FilterParserRegistry:Registry = oRegistry. | ||
end. | ||
return FilterParserRegistry:Registry. | ||
end get. | ||
private set. | ||
|
||
/** Adds initial values into the registry | ||
@param BuilderRegistry The registry to populate */ | ||
method static private void InitializeRegistry(input poRegistry as BuilderRegistry): | ||
// Register known parsers | ||
poRegistry:Put('WHERE':u, get-class(AblFilterParser)). | ||
poRegistry:Put('ABL':u, get-class(AblFilterParser)). | ||
|
||
poRegistry:Put('ablFilter':u, get-class(JfpFilterParser)). | ||
poRegistry:Put('JFP':u, get-class(JfpFilterParser)). | ||
|
||
poRegistry:Put('field':u, get-class(KendoFilterParser)). | ||
poRegistry:Put('KENDO':u, get-class(KendoFilterParser)). | ||
end method. | ||
|
||
end class. |
Oops, something went wrong.