Quick.Config.pas 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. { ***************************************************************************
  2. Copyright (c) 2015-2018 Kike Pérez
  3. Unit : Quick.Config
  4. Description : Load/Save config from/to JSON file
  5. Author : Kike Pérez
  6. Version : 1.2
  7. Created : 26/01/2017
  8. Modified : 02/02/2018
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Config;
  22. interface
  23. uses
  24. System.Classes,
  25. System.SysUtils,
  26. System.Rtti,
  27. {$IF CompilerVersion >= 32.0}
  28. JSON.Types,
  29. JSON.Serializers;
  30. {$ELSE}
  31. Rest.Json.Types,
  32. Rest.Json;
  33. {$ENDIF}
  34. type
  35. TDateTimeZone = (tzLocal, tzUTC);
  36. IAppConfigProvider<T> = interface
  37. ['{D55B1EBF-47F6-478B-8F70-9444575CB825}']
  38. procedure Load(var cConfig : T);
  39. procedure Save(var cConfig : T);
  40. end;
  41. TAppConfigProviderBase<T : class> = class(TInterfacedObject,IAppConfigProvider<T>)
  42. private
  43. fCreateIfNotExists : Boolean;
  44. public
  45. constructor Create(var cConfig : T); virtual;
  46. property CreateIfNotExists : Boolean read fCreateIfNotExists write fCreateIfNotExists;
  47. function InitObject : T;
  48. procedure Load(var cConfig : T); virtual; abstract;
  49. procedure Save(var cConfig : T); virtual; abstract;
  50. end;
  51. TApplyConfigEvent = procedure of object;
  52. [JsonSerialize(TJsonMemberSerialization.&Public)]
  53. TAppConfig = class
  54. private
  55. {$IF CompilerVersion < 32.0}[JSONMarshalledAttribute(False)]{$ENDIF}
  56. fOnApplyConfig : TApplyConfigEvent;
  57. {$IF CompilerVersion < 32.0}[JSONMarshalledAttribute(False)]{$ENDIF}
  58. fDateTimeZone: TDateTimeZone;
  59. {$IF CompilerVersion < 32.0}[JSONMarshalledAttribute(False)]{$ENDIF}
  60. fJsonIndent: Boolean;
  61. {$IF CompilerVersion < 32.0}[JSONMarshalledAttribute(False)]{$ENDIF}
  62. fLastSaved : TDateTime;
  63. public
  64. constructor Create; virtual;
  65. //constructor Create(ADefaultValues : Boolean); overload; virtual; abstract;
  66. {$IF CompilerVersion >= 32.0}[JsonIgnoreAttribute]{$ENDIF}
  67. property OnApplyConfig : TApplyConfigEvent read fOnApplyConfig write fOnApplyConfig;
  68. {$IF CompilerVersion >= 32.0}[JsonIgnoreAttribute]{$ENDIF}
  69. property DateTimeZone : TDateTimeZone read fDateTimeZone write fDateTimeZone;
  70. {$IF CompilerVersion >= 32.0}[JsonIgnoreAttribute]{$ENDIF}
  71. property JsonIndent : Boolean read fJsonIndent write fJsonIndent;
  72. {$IF CompilerVersion >= 32.0}[JsonIgnoreAttribute]{$ENDIF}
  73. property LastSaved : TDateTime read fLastSaved write fLastSaved;
  74. procedure Apply;
  75. function ToJSON : string;
  76. end;
  77. {Usage: create a descend class from TAppConfig and add public properties to be loaded/saved
  78. TMyConfig = class(TAppConfig)
  79. private
  80. fName : string;
  81. fSurname : string;
  82. fStatus : Integer;
  83. public
  84. property Name : string read fName write fName;
  85. property SurName : string read fSurname write fSurname;
  86. property Status : Integer read fStatus write fStatus;
  87. end;
  88. AppConfigProvider := TAppConfigJsonProvider<TMyConfig>.Create(MyConfig);
  89. MyConfig.Name := 'John';
  90. }
  91. implementation
  92. { TAppConfigProviderBase }
  93. constructor TAppConfigProviderBase<T>.Create(var cConfig : T);
  94. begin
  95. fCreateIfNotExists := True;
  96. //create object with rtti
  97. if Assigned(cConfig) then cConfig.Free;
  98. cConfig := InitObject;
  99. end;
  100. function TAppConfigProviderBase<T>.InitObject : T;
  101. var
  102. AValue: TValue;
  103. ctx: TRttiContext;
  104. f : TRttiField;
  105. rType: TRttiType;
  106. AMethCreate: TRttiMethod;
  107. begin
  108. ctx := TRttiContext.Create;
  109. try
  110. rType := ctx.GetType(TypeInfo(T));
  111. for AMethCreate in rType.GetMethods do
  112. begin
  113. if (AMethCreate.IsConstructor) and (Length(AMethCreate.GetParameters) = 0) then
  114. begin
  115. AValue := AMethCreate.Invoke(rType.AsInstance.AsInstance.MetaclassType,[]);
  116. Result := AValue.AsType<T>;
  117. Break;
  118. end;
  119. end;
  120. finally
  121. ctx.Free;
  122. end;
  123. end;
  124. { TAppConfig }
  125. constructor TAppConfig.Create;
  126. begin
  127. fDateTimeZone := TDateTimeZone.tzLocal;
  128. fJsonIndent := True;
  129. fLastSaved := 0;
  130. end;
  131. procedure TAppConfig.Apply;
  132. begin
  133. if Assigned(fOnApplyConfig) then fOnApplyConfig;
  134. end;
  135. function TAppConfig.ToJSON : string;
  136. {$IF CompilerVersion >= 32.0}
  137. var
  138. Serializer : TJsonSerializer;
  139. {$ENDIF}
  140. begin
  141. Result := '';
  142. try
  143. {$IF CompilerVersion >= 32.0}
  144. Serializer := TJsonSerializer.Create;
  145. try
  146. Serializer.Formatting := TJsonFormatting.Indented;
  147. if JsonIndent then Serializer.Formatting := TJsonFormatting.Indented;
  148. if DateTimeZone = TDateTimeZone.tzLocal then
  149. begin
  150. Serializer.DateTimeZoneHandling := TJsonDateTimeZoneHandling.Local;
  151. Serializer.DateFormatHandling := TJsonDateFormatHandling.FormatSettings;
  152. end
  153. else Serializer.DateTimeZoneHandling := TJsonDateTimeZoneHandling.Utc;
  154. Result := Serializer.Serialize<TObject>(Self);
  155. finally
  156. Serializer.Free;
  157. end;
  158. {$ELSE}
  159. Result := TJson.ObjectToJsonString(Self);
  160. {$ENDIF}
  161. except
  162. on e : Exception do raise Exception.Create(e.Message);
  163. end;
  164. end;
  165. end.