Add TMVCAbstractSerializer

This commit is contained in:
Desenvolvimento 2017-03-02 08:57:40 -03:00
parent 6a27680a0a
commit 97d3c552ca
3 changed files with 103 additions and 110 deletions

View File

@ -53,6 +53,20 @@ uses
type
TMVCAbstractSerializer = class abstract(TInterfacedObject)
private
FRttiContext: TRttiContext;
FTypeSerializers: TDictionary<PTypeInfo, IMVCTypeSerializer>;
protected
function GetRttiContext: TRttiContext;
function GetTypeSerializers: TDictionary<PTypeInfo, IMVCTypeSerializer>;
function IsIgnoredAttribute(const AAttributes: array of string; const AName: string): Boolean;
procedure RegisterTypeSerializer(const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
public
constructor Create;
destructor Destroy; override;
end;
TMVCSerializerHelpful = class sealed
public
class function GetKeyName(const AField: TRttiField; const AType: TRttiType): string; overload; static;
@ -476,4 +490,47 @@ begin
FValue := AValue;
end;
{ TMVCAbstractSerializer }
constructor TMVCAbstractSerializer.Create;
begin
inherited Create;
FRttiContext := TRttiContext.Create;
FTypeSerializers := TDictionary<PTypeInfo, IMVCTypeSerializer>.Create;
end;
destructor TMVCAbstractSerializer.Destroy;
begin
FTypeSerializers.Free;
FRttiContext.Free;
inherited Destroy;
end;
function TMVCAbstractSerializer.GetRttiContext: TRttiContext;
begin
Result := FRttiContext;
end;
function TMVCAbstractSerializer.GetTypeSerializers: TDictionary<PTypeInfo, IMVCTypeSerializer>;
begin
Result := FTypeSerializers;
end;
function TMVCAbstractSerializer.IsIgnoredAttribute(
const AAttributes: array of string; const AName: string): Boolean;
var
I: Integer;
begin
Result := False;
for I := Low(AAttributes) to High(AAttributes) do
if (AAttributes[I] = AName) then
Exit(True);
end;
procedure TMVCAbstractSerializer.RegisterTypeSerializer(
const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
begin
FTypeSerializers.AddOrSetValue(ATypeInfo, AInstance);
end;
end.

View File

@ -44,10 +44,8 @@ uses
type
TMVCJSONSerializer = class(TInterfacedObject, IMVCSerializer)
TMVCJSONSerializer = class(TMVCAbstractSerializer, IMVCSerializer)
private
FRttiContext: TRttiContext;
FTypeSerializers: TDictionary<PTypeInfo, IMVCTypeSerializer>;
procedure ObjectToJSONObject(
const AObject: TObject;
const AJSONObject: TJSONObject;
@ -83,10 +81,7 @@ type
const AType: TMVCSerializationType;
const AIgnoredAttributes: array of string
);
function IsIgnoredAttribute(const AAttributes: array of string; const AName: string): Boolean;
protected
procedure RegisterTypeSerializer(const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
function SerializeObject(const AObject: TObject): string; overload;
function SerializeObject(const AObject: TObject; const AType: TMVCSerializationType): string; overload;
function SerializeObject(const AObject: TObject; const AType: TMVCSerializationType; const AIgnoredAttributes: array of string): string; overload;
@ -108,8 +103,7 @@ type
procedure DeserializeDataSet(const ASerializedDataSet: string; const ADataSet: TDataSet);
public
constructor Create;
destructor Destroy; override;
procedure AfterConstruction; override;
end;
implementation
@ -119,6 +113,14 @@ uses
{ TMVCJSONSerializer }
procedure TMVCJSONSerializer.AfterConstruction;
begin
inherited AfterConstruction;
GetTypeSerializers.Add(System.TypeInfo(TStream), TStreamSerializerJSON.Create);
GetTypeSerializers.Add(System.TypeInfo(TStringStream), TStreamSerializerJSON.Create);
GetTypeSerializers.Add(System.TypeInfo(TMemoryStream), TStreamSerializerJSON.Create);
end;
procedure TMVCJSONSerializer.AttributeToJSONDataValue(
const AJSONObject: TJSONObject; const AName: string;
const AValue: TValue; const AType: TMVCSerializationType;
@ -140,10 +142,10 @@ begin
Exit;
end;
if FTypeSerializers.ContainsKey(AValue.TypeInfo) then
if GetTypeSerializers.ContainsKey(AValue.TypeInfo) then
begin
ChildJSONValue := nil;
FTypeSerializers.Items[AValue.TypeInfo].Serialize(AValue, TObject(ChildJSONValue), ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Serialize(AValue, TObject(ChildJSONValue), ACustomAttributes);
if Assigned(ChildJSONValue) then
begin
if ChildJSONValue is TJSONValue then
@ -281,16 +283,6 @@ begin
end;
end;
constructor TMVCJSONSerializer.Create;
begin
inherited Create;
FRttiContext := TRttiContext.Create;
FTypeSerializers := TDictionary<PTypeInfo, IMVCTypeSerializer>.Create;
FTypeSerializers.Add(System.TypeInfo(TStream), TStreamSerializerJSON.Create);
FTypeSerializers.Add(System.TypeInfo(TStringStream), TStreamSerializerJSON.Create);
FTypeSerializers.Add(System.TypeInfo(TMemoryStream), TStreamSerializerJSON.Create);
end;
procedure TMVCJSONSerializer.DeserializeCollection(
const ASerializedList: string; const AList: TObject;
const AClazz: TClass; const AType: TMVCSerializationType);
@ -361,11 +353,11 @@ begin
JSONObject := TJSONObject.ParseJSONValue(ASerializedObject) as TJSONObject;
try
ObjType := FRttiContext.GetType(AObject.ClassType);
if FTypeSerializers.ContainsKey(ObjType.Handle) then
ObjType := GetRttiContext.GetType(AObject.ClassType);
if GetTypeSerializers.ContainsKey(ObjType.Handle) then
begin
ObjValue := TValue.From<TObject>(AObject);
FTypeSerializers.Items[ObjType.Handle].Deserialize(JSONObject, ObjValue, []);
GetTypeSerializers.Items[ObjType.Handle].Deserialize(JSONObject, ObjValue, []);
Exit;
end;
JSONObjectToObject(JSONObject, AObject, AType, AIgnoredAttributes);
@ -380,24 +372,6 @@ begin
DeserializeObject(ASerializedObject, AObject, stDefault);
end;
destructor TMVCJSONSerializer.Destroy;
begin
FTypeSerializers.Free;
FRttiContext.Free;
inherited Destroy;
end;
function TMVCJSONSerializer.IsIgnoredAttribute(
const AAttributes: array of string; const AName: string): Boolean;
var
I: Integer;
begin
Result := False;
for I := Low(AAttributes) to High(AAttributes) do
if (AAttributes[I] = AName) then
Exit(True);
end;
procedure TMVCJSONSerializer.JSONArrayToList(const AJSONArray: TJSONArray;
const AList: IMVCList; const AClazz: TClass;
const AType: TMVCSerializationType;
@ -426,9 +400,9 @@ begin
if not Assigned(AJSONObject.Values[AName]) then
Exit;
if FTypeSerializers.ContainsKey(AValue.TypeInfo) then
if GetTypeSerializers.ContainsKey(AValue.TypeInfo) then
begin
FTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJSONObject.Values[AName], AValue, ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJSONObject.Values[AName], AValue, ACustomAttributes);
Exit;
end;
@ -502,7 +476,7 @@ var
Fld: TRttiField;
AttributeValue: TValue;
begin
ObjType := FRttiContext.GetType(AObject.ClassType);
ObjType := GetRttiContext.GetType(AObject.ClassType);
case AType of
stDefault, stProperties:
begin
@ -537,7 +511,7 @@ var
Prop: TRttiProperty;
Fld: TRttiField;
begin
ObjType := FRttiContext.GetType(AObject.ClassType);
ObjType := GetRttiContext.GetType(AObject.ClassType);
case AType of
stDefault, stProperties:
begin
@ -554,12 +528,6 @@ begin
end;
end;
procedure TMVCJSONSerializer.RegisterTypeSerializer(
const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
begin
FTypeSerializers.AddOrSetValue(ATypeInfo, AInstance);
end;
function TMVCJSONSerializer.SerializeCollection(
const AList: TObject): string;
begin
@ -636,11 +604,11 @@ begin
if AObject is TJSONValue then
Exit(TJSONValue(AObject).ToJSON);
ObjType := FRttiContext.GetType(AObject.ClassType);
if FTypeSerializers.ContainsKey(ObjType.Handle) then
ObjType := GetRttiContext.GetType(AObject.ClassType);
if GetTypeSerializers.ContainsKey(ObjType.Handle) then
begin
ChildJSONValue := nil;
FTypeSerializers.Items[ObjType.Handle].Serialize(AObject, TObject(ChildJSONValue), []);
GetTypeSerializers.Items[ObjType.Handle].Serialize(AObject, TObject(ChildJSONValue), []);
if Assigned(ChildJSONValue) then
begin
try

View File

@ -55,10 +55,8 @@ type
property Value: string read FValue write FValue;
end;
TMVCJsonDataObjectsSerializer = class(TInterfacedObject, IMVCSerializer)
TMVCJsonDataObjectsSerializer = class(TMVCAbstractSerializer, IMVCSerializer)
private
FRttiContext: TRttiContext;
FTypeSerializers: TDictionary<PTypeInfo, IMVCTypeSerializer>;
procedure ObjectToJsonObject(
const AObject: TObject;
const AJsonObject: TJsonObject;
@ -94,10 +92,7 @@ type
const AType: TMVCSerializationType;
const AIgnoredAttributes: array of string
);
function IsIgnoredAttribute(const AAttributes: array of string; const AName: string): Boolean;
protected
procedure RegisterTypeSerializer(const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
function SerializeObject(const AObject: TObject): string; overload;
function SerializeObject(const AObject: TObject; const AType: TMVCSerializationType): string; overload;
function SerializeObject(const AObject: TObject; const AType: TMVCSerializationType; const AIgnoredAttributes: array of string): string; overload;
@ -119,8 +114,7 @@ type
procedure DeserializeDataSet(const ASerializedDataSet: string; const ADataSet: TDataSet);
public
constructor Create;
destructor Destroy; override;
procedure AfterConstruction; override;
end;
implementation
@ -130,6 +124,14 @@ uses
{ TMVCJsonDataObjectsSerializer }
procedure TMVCJsonDataObjectsSerializer.AfterConstruction;
begin
inherited AfterConstruction;
GetTypeSerializers.Add(System.TypeInfo(TStream), TStreamSerializerJsonDataObject.Create);
GetTypeSerializers.Add(System.TypeInfo(TStringStream), TStreamSerializerJsonDataObject.Create);
GetTypeSerializers.Add(System.TypeInfo(TMemoryStream), TStreamSerializerJsonDataObject.Create);
end;
procedure TMVCJsonDataObjectsSerializer.AttributeToJsonDataValue(
const AJsonObject: TJsonObject;
const AName: string;
@ -153,10 +155,10 @@ begin
Exit;
end;
if FTypeSerializers.ContainsKey(AValue.TypeInfo) then
if GetTypeSerializers.ContainsKey(AValue.TypeInfo) then
begin
ChildJsonValue := nil;
FTypeSerializers.Items[AValue.TypeInfo].Serialize(AValue, ChildJsonValue, ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Serialize(AValue, ChildJsonValue, ACustomAttributes);
if Assigned(ChildJsonValue) then
begin
if ChildJsonValue is TJsonObject then
@ -296,16 +298,6 @@ begin
end;
end;
constructor TMVCJsonDataObjectsSerializer.Create;
begin
inherited Create;
FRttiContext := TRttiContext.Create;
FTypeSerializers := TDictionary<PTypeInfo, IMVCTypeSerializer>.Create;
FTypeSerializers.Add(System.TypeInfo(TStream), TStreamSerializerJsonDataObject.Create);
FTypeSerializers.Add(System.TypeInfo(TStringStream), TStreamSerializerJsonDataObject.Create);
FTypeSerializers.Add(System.TypeInfo(TMemoryStream), TStreamSerializerJsonDataObject.Create);
end;
procedure TMVCJsonDataObjectsSerializer.DeserializeCollection(
const ASerializedList: string;
const AList: TObject;
@ -370,24 +362,6 @@ begin
DeserializeObject(ASerializedObject, AObject, stDefault);
end;
destructor TMVCJsonDataObjectsSerializer.Destroy;
begin
FTypeSerializers.Free;
FRttiContext.Free;
inherited Destroy;
end;
function TMVCJsonDataObjectsSerializer.IsIgnoredAttribute(
const AAttributes: array of string; const AName: string): Boolean;
var
I: Integer;
begin
Result := False;
for I := Low(AAttributes) to High(AAttributes) do
if (AAttributes[I] = AName) then
Exit(True);
end;
procedure TMVCJsonDataObjectsSerializer.JsonArrayToList(
const AJsonArray: TJsonArray; const AList: IMVCList;
const AClazz: TClass; const AType: TMVCSerializationType;
@ -417,21 +391,21 @@ var
ChildListOfAtt: MVCListOfAttribute;
ChildJsonValue: TJsonValue;
begin
if FTypeSerializers.ContainsKey(AValue.TypeInfo) then
if GetTypeSerializers.ContainsKey(AValue.TypeInfo) then
begin
case AJsonObject[AName].Typ of
jdtNone:
Exit;
jdtObject:
FTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJsonObject[AName].ObjectValue, AValue, ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJsonObject[AName].ObjectValue, AValue, ACustomAttributes);
jdtArray:
FTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJsonObject[AName].ArrayValue, AValue, ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Deserialize(AJsonObject[AName].ArrayValue, AValue, ACustomAttributes);
else
begin
ChildJsonValue := TJsonValue.Create;
try
ChildJsonValue.Value := AJsonObject[AName].Value;
FTypeSerializers.Items[AValue.TypeInfo].Deserialize(ChildJsonValue, AValue, ACustomAttributes);
GetTypeSerializers.Items[AValue.TypeInfo].Deserialize(ChildJsonValue, AValue, ACustomAttributes);
finally
ChildJsonValue.Free;
end;
@ -522,7 +496,7 @@ var
Fld: TRttiField;
AttributeValue: TValue;
begin
ObjType := FRttiContext.GetType(AObject.ClassType);
ObjType := GetRttiContext.GetType(AObject.ClassType);
case AType of
stDefault, stProperties:
begin
@ -559,7 +533,7 @@ var
Prop: TRttiProperty;
Fld: TRttiField;
begin
ObjType := FRttiContext.GetType(AObject.ClassType);
ObjType := GetRttiContext.GetType(AObject.ClassType);
case AType of
stDefault, stProperties:
begin
@ -576,12 +550,6 @@ begin
end;
end;
procedure TMVCJsonDataObjectsSerializer.RegisterTypeSerializer(
const ATypeInfo: PTypeInfo; AInstance: IMVCTypeSerializer);
begin
FTypeSerializers.AddOrSetValue(ATypeInfo, AInstance);
end;
function TMVCJsonDataObjectsSerializer.SerializeCollection(
const AList: TObject; const AType: TMVCSerializationType;
const AIgnoredAttributes: array of string): string;
@ -653,11 +621,11 @@ begin
if AObject is TJsonBaseObject then
Exit(TJsonBaseObject(AObject).ToJSON(False));
ObjType := FRttiContext.GetType(AObject.ClassType);
if FTypeSerializers.ContainsKey(ObjType.Handle) then
ObjType := GetRttiContext.GetType(AObject.ClassType);
if GetTypeSerializers.ContainsKey(ObjType.Handle) then
begin
ChildJsonValue := nil;
FTypeSerializers.Items[ObjType.Handle].Serialize(AObject, TObject(ChildJsonValue), []);
GetTypeSerializers.Items[ObjType.Handle].Serialize(AObject, TObject(ChildJsonValue), []);
if Assigned(ChildJsonValue) then
begin
try
@ -711,11 +679,11 @@ begin
JsonObject := TJsonObject.Parse(ASerializedObject) as TJsonObject;
try
ObjType := FRttiContext.GetType(AObject.ClassType);
if FTypeSerializers.ContainsKey(ObjType.Handle) then
ObjType := GetRttiContext.GetType(AObject.ClassType);
if GetTypeSerializers.ContainsKey(ObjType.Handle) then
begin
ObjValue := TValue.From<TObject>(AObject);
FTypeSerializers.Items[ObjType.Handle].Deserialize(JsonObject, ObjValue, []);
GetTypeSerializers.Items[ObjType.Handle].Deserialize(JsonObject, ObjValue, []);
Exit;
end;
JsonObjectToObject(JsonObject, AObject, AType, AIgnoredAttributes);