2017-04-29 23:56:56 +02:00
|
|
|
unit MVCFramework.SystemJSONUtils;
|
|
|
|
|
|
|
|
{$I dmvcframework.inc}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2018-11-24 16:56:21 +01:00
|
|
|
System.JSON, MVCFramework.RESTClient, System.Rtti;
|
2017-04-29 23:56:56 +02:00
|
|
|
|
|
|
|
type
|
|
|
|
TSystemJSON = class sealed
|
|
|
|
private
|
|
|
|
class var CTX: TRttiContext;
|
|
|
|
public
|
2017-05-25 16:57:49 +02:00
|
|
|
class function StringToJSONValue(const Value: string): TJSONValue;
|
2022-05-25 15:13:49 +02:00
|
|
|
class function StringToJSONValueNoException(const Value: string): TJSONValue;
|
2017-05-25 16:57:49 +02:00
|
|
|
class function StringAsJSONObject(const Value: string): TJSONObject;
|
2022-05-25 15:13:49 +02:00
|
|
|
class function StringAsJSONObjectNoException(const Value: string): TJSONObject;
|
2017-05-25 16:57:49 +02:00
|
|
|
class function StringAsJSONArray(const Value: string): TJSONArray;
|
|
|
|
class function JSONValueToString(JSONValue: TJSONValue; const Owns: Boolean = true): string;
|
2017-04-29 23:56:56 +02:00
|
|
|
class function GetPair(JSONObject: TJSONObject; PropertyName: string)
|
|
|
|
: TJSONPair;
|
|
|
|
class function GetStringDef(JSONObject: TJSONObject; PropertyName: string;
|
|
|
|
DefaultValue: string = ''): string;
|
|
|
|
class function GetNumberDef(JSONObject: TJSONObject; PropertyName: string;
|
|
|
|
DefaultValue: Extended = 0): Extended;
|
|
|
|
class function GetJSONObj(JSONObject: TJSONObject; PropertyName: string)
|
|
|
|
: TJSONObject;
|
|
|
|
class function GetJSONArray(JSONObject: TJSONObject; PropertyName: string)
|
|
|
|
: TJSONArray;
|
|
|
|
class function GetIntegerDef(JSONObject: TJSONObject; PropertyName: string;
|
|
|
|
DefaultValue: Integer = 0): Integer;
|
|
|
|
class function GetInt64Def(JSONObject: TJSONObject; PropertyName: string;
|
|
|
|
DefaultValue: Int64 = 0): Int64;
|
|
|
|
class function GetBooleanDef(JSONObject: TJSONObject; PropertyName: string;
|
|
|
|
DefaultValue: boolean = false): boolean;
|
2017-05-25 16:57:49 +02:00
|
|
|
class function GetProperty(Obj: TObject;
|
|
|
|
const PropertyName: string): TValue; static;
|
2017-04-29 23:56:56 +02:00
|
|
|
class function PropertyExists(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string): boolean;
|
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2017-05-25 16:57:49 +02:00
|
|
|
MVCFramework.Commons, System.SysUtils, MVCFramework.DuckTyping,
|
|
|
|
System.Classes, MVCFramework.Serializer.Commons;
|
2017-04-29 23:56:56 +02:00
|
|
|
|
2017-05-25 16:57:49 +02:00
|
|
|
class function TSystemJSON.StringAsJSONArray(const Value: string): TJSONArray;
|
2017-04-29 23:56:56 +02:00
|
|
|
begin
|
2017-05-25 16:57:49 +02:00
|
|
|
Result := TSystemJSON.StringToJSONValue(Value) as TJSONArray;
|
2017-04-29 23:56:56 +02:00
|
|
|
end;
|
|
|
|
|
2017-05-25 16:57:49 +02:00
|
|
|
class function TSystemJSON.StringAsJSONObject(const Value: string): TJSONObject;
|
2017-04-29 23:56:56 +02:00
|
|
|
begin
|
2017-05-25 16:57:49 +02:00
|
|
|
Result := TSystemJSON.StringToJSONValue(Value) as TJSONObject;
|
2017-04-29 23:56:56 +02:00
|
|
|
end;
|
|
|
|
|
2022-05-25 15:13:49 +02:00
|
|
|
class function TSystemJSON.StringAsJSONObjectNoException(
|
|
|
|
const Value: string): TJSONObject;
|
|
|
|
begin
|
|
|
|
Result := TSystemJSON.StringToJSONValueNoException(Value) as TJSONObject;
|
|
|
|
end;
|
|
|
|
|
2017-05-25 16:57:49 +02:00
|
|
|
class function TSystemJSON.StringToJSONValue(const Value: string): TJSONValue;
|
2017-04-29 23:56:56 +02:00
|
|
|
var
|
|
|
|
lBodyAsJSONValue: TJSONValue;
|
|
|
|
begin
|
2017-05-25 16:57:49 +02:00
|
|
|
lBodyAsJSONValue := TJSONObject.ParseJSONValue(Value);
|
2017-04-29 23:56:56 +02:00
|
|
|
if lBodyAsJSONValue = nil then
|
|
|
|
raise EMVCException.Create('Invalid JSON');
|
|
|
|
Result := lBodyAsJSONValue;
|
|
|
|
end;
|
|
|
|
|
2022-05-25 15:13:49 +02:00
|
|
|
class function TSystemJSON.StringToJSONValueNoException(
|
|
|
|
const Value: string): TJSONValue;
|
|
|
|
begin
|
|
|
|
Result := TJSONObject.ParseJSONValue(Value);
|
|
|
|
end;
|
|
|
|
|
2017-04-29 23:56:56 +02:00
|
|
|
class function TSystemJSON.JSONValueToString(JSONValue: TJSONValue;
|
2017-05-25 16:57:49 +02:00
|
|
|
const Owns: Boolean): string;
|
2017-04-29 23:56:56 +02:00
|
|
|
begin
|
|
|
|
Result := JSONValue.ToJSON;
|
|
|
|
if Owns then
|
|
|
|
begin
|
|
|
|
JSONValue.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetBooleanDef(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string; DefaultValue: boolean): boolean;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(DefaultValue);
|
|
|
|
if pair.JsonValue is TJSONFalse then
|
|
|
|
Exit(false)
|
|
|
|
else if pair.JsonValue is TJSONTrue then
|
|
|
|
Exit(True)
|
|
|
|
else
|
|
|
|
raise EMVCException.CreateFmt('Property %s is not a Boolean Property',
|
|
|
|
[PropertyName]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetInt64Def(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string; DefaultValue: Int64): Int64;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(DefaultValue);
|
|
|
|
if pair.JsonValue is TJSONNumber then
|
|
|
|
Exit(TJSONNumber(pair.JsonValue).AsInt64)
|
|
|
|
else
|
|
|
|
raise EMVCException.CreateFmt('Property %s is not a Int64 Property',
|
|
|
|
[PropertyName]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetIntegerDef(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string; DefaultValue: Integer): Integer;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(DefaultValue);
|
|
|
|
if pair.JsonValue is TJSONNumber then
|
|
|
|
Exit(TJSONNumber(pair.JsonValue).AsInt)
|
|
|
|
else
|
|
|
|
raise EMVCException.CreateFmt('Property %s is not an Integer Property',
|
|
|
|
[PropertyName]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetJSONArray(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string): TJSONArray;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(nil);
|
|
|
|
if pair.JsonValue is TJSONArray then
|
|
|
|
Exit(TJSONArray(pair.JsonValue))
|
|
|
|
else
|
|
|
|
raise EMVCException.Create('Property is not a JSONArray');
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetJSONObj(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string): TJSONObject;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(nil);
|
|
|
|
if pair.JsonValue is TJSONObject then
|
|
|
|
Exit(TJSONObject(pair.JsonValue))
|
|
|
|
else
|
|
|
|
raise EMVCException.Create('Property is not a JSONObject');
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.PropertyExists(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string): boolean;
|
|
|
|
begin
|
|
|
|
Result := Assigned(GetPair(JSONObject, PropertyName));
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetNumberDef(JSONObject: TJSONObject;
|
|
|
|
PropertyName: string; DefaultValue: Extended): Extended;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(DefaultValue);
|
|
|
|
if pair.JsonValue is TJSONNumber then
|
|
|
|
Exit(TJSONNumber(pair.JsonValue).AsDouble)
|
|
|
|
else
|
|
|
|
raise EMVCException.Create('Property is not a Number Property');
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetPair(JSONObject: TJSONObject; PropertyName: string)
|
|
|
|
: TJSONPair;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
if not Assigned(JSONObject) then
|
|
|
|
raise EMVCException.Create('JSONObject is nil');
|
|
|
|
pair := JSONObject.Get(PropertyName);
|
|
|
|
Result := pair;
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetProperty(Obj: TObject;
|
|
|
|
const PropertyName: string): TValue;
|
|
|
|
var
|
|
|
|
Prop: TRttiProperty;
|
|
|
|
ARTTIType: TRttiType;
|
|
|
|
begin
|
|
|
|
ARTTIType := ctx.GetType(Obj.ClassType);
|
|
|
|
if not Assigned(ARTTIType) then
|
|
|
|
raise EMVCException.CreateFmt('Cannot get RTTI for type [%s]',
|
|
|
|
[ARTTIType.ToString]);
|
|
|
|
Prop := ARTTIType.GetProperty(PropertyName);
|
|
|
|
if not Assigned(Prop) then
|
|
|
|
raise EMVCException.CreateFmt('Cannot get RTTI for property [%s.%s]',
|
|
|
|
[ARTTIType.ToString, PropertyName]);
|
|
|
|
if Prop.IsReadable then
|
|
|
|
Result := Prop.GetValue(Obj)
|
|
|
|
else
|
|
|
|
raise EMVCException.CreateFmt('Property is not readable [%s.%s]',
|
|
|
|
[ARTTIType.ToString, PropertyName]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TSystemJSON.GetStringDef(JSONObject: TJSONObject;
|
|
|
|
PropertyName, DefaultValue: string): string;
|
|
|
|
var
|
|
|
|
pair: TJSONPair;
|
|
|
|
begin
|
|
|
|
pair := GetPair(JSONObject, PropertyName);
|
|
|
|
if pair = nil then
|
|
|
|
Exit(DefaultValue);
|
|
|
|
if pair.JsonValue is TJSONString then
|
|
|
|
Exit(TJSONString(pair.JsonValue).Value)
|
|
|
|
else
|
|
|
|
raise EMVCException.Create('Property is not a String Property');
|
|
|
|
end;
|
|
|
|
|
2017-05-25 16:57:49 +02:00
|
|
|
|
|
|
|
|
2017-04-29 23:56:56 +02:00
|
|
|
end.
|