FastReport_2022_VCL/LibD28/frxServerConfig.pas
2024-01-01 16:13:08 +01:00

496 lines
14 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport VCL }
{ Report Server Configurator }
{ }
{ Copyright (c) 1998-2021 }
{ by Fast Reports Inc. }
{ }
{******************************************}
unit frxServerConfig;
{$I frx.inc}
interface
{$R frxServerConfig.res}
uses
{$IFNDEF Linux}
Windows,
{$ELSE}
LCLType, LCLIntf, LazHelper, Types,
{$ENDIF}
Classes, SysUtils, SyncObjs, frxXML, frxUtils,
frxServerUtils, inifiles, frxServerLog;
type
TfrxConfig = class (TObject)
private
FXML: TfrxXMLDocument;
FErrors: TStrings;
FLines: TStringList;
FCS: TCriticalSection;
FFileName: String;
FConfigFolder: String;
procedure UpdateLines;
procedure AddLine(const Name: String; const Value: String; XMLItem: TfrxXMLItem);
function GetCount: Integer;
public
ServerMessage: String;
constructor Create;
destructor Destroy; override;
function LoadFromStream(Stream: TStream): HRESULT;
function SaveToStream(Stream: TStream): HRESULT;
function LoadFromFile(const FileName: String): HRESULT;
function SaveToFile(const FileName: String): HRESULT;
function GetValue(const Name: String): String;
function GetNumber(const Name: String): Integer;
function GetBool(const Name: String): Boolean;
function CheckValue(const Name: String; const Current: String): String;
procedure SetValue(const Name: String; const Value: String);
procedure SetBool(const Name: String; const Value: Boolean);
procedure Clear;
procedure ConfigListToFile(const FileName: String);
procedure Reload;
property Lines: TStringList read FLines;
property XML: TfrxXMLDocument read FXML;
property Count: Integer read GetCount;
property ConfigFolder: String read FConfigFolder write FConfigFolder;
end;
TfrxConfigItem = class (TObject)
private
FValue: String;
FXMLItem: TfrxXMLItem;
public
property Value: String read FValue write FValue;
property XMLItem: TfrxXMLItem read FXMLItem write FXMLItem;
end;
TfrxServerConfig = class(TPersistent)
private
FGzip: Boolean;
FIndexFileName: String;
FLogging: Boolean;
FLogin: String;
FLogPath: String;
FMIC: Boolean;
FNoCacheHeader: Boolean;
FOutputFormats: TfrxServerOutputFormats;
FPassword: String;
FPort: Integer;
FReportPath: String;
FRootPath: String;
FSessionTimeOut: Integer;
FSocketTimeOut: Integer;
FReportCachePath: String;
FDefaultCacheLatency: Integer;
FReportCaching: Boolean;
FMaxLogFiles: Integer;
FMaxLogSize: Integer;
FDatabase: String;
FDatabaseLogin: String;
FDatabasePassword: String;
FReportsList: Boolean;
FConfigFolder: String;
public
procedure LoadFromFile(const FileName: String);
procedure SaveToFile(const FileName: String);
published
property Compression: Boolean read FGzip write FGzip;
property IndexFileName: String read FIndexFileName write FIndexFileName;
property Logging: Boolean read FLogging write FLogging;
property MaxLogSize: Integer read FMaxLogSize write FMaxLogSize;
property MaxLogFiles: Integer read FMaxLogFiles write FMaxLogFiles;
property Login: String read FLogin write FLogin;
property LogPath: String read FLogPath write FLogPath;
property MIC: Boolean read FMIC write FMIC;
property NoCacheHeader: Boolean read FNoCacheHeader write FNoCacheHeader;
property OutputFormats: TfrxServerOutputFormats read FOutputFormats
write FOutputFormats;
property Password: String read FPassword write FPassword;
property Port: Integer read FPort write FPort;
property ReportPath: String read FReportPath write FReportPath;
property ReportCachePath: String read FReportCachePath write FReportCachePath;
property ReportCaching: Boolean read FReportCaching write FReportCaching;
property DefaultCacheLatency: Integer read FDefaultCacheLatency write FDefaultCacheLatency;
property RootPath: String read FRootPath write FRootPath;
property SessionTimeOut: Integer read FSessionTimeOut write FSessionTimeOut;
property SocketTimeOut: Integer read FSocketTimeOut write FSocketTimeOut;
property Database: String read FDatabase write FDatabase;
property DatabaseLogin: String read FDatabaseLogin write FDatabaseLogin;
property DatabasePassword: String read FDatabasePassword write FDatabasePassword;
property ReportsList: Boolean read FReportsList write FReportsList;
property ConfigFolder: String read FConfigFolder write FConfigFolder;
end;
var
ServerConfig: TfrxConfig;
const
FR_SERVER_CONFIG_VERSION = '2.4.0';
implementation
{ TfrxConfig }
procedure TfrxConfig.AddLine(const Name: String; const Value: String; XMLItem: TfrxXMLItem);
var
FValue: TfrxConfigItem;
i: Integer;
begin
i := FLines.IndexOf(LowerCase(Name));
if i <> -1 then
begin
TfrxConfigItem(FLines.Objects[i]).Value := Value;
TfrxConfigItem(FLines.Objects[i]).XMLItem := XMLItem;
end
else
begin
FValue := TfrxConfigItem.Create;
FValue.Value := Value;
FValue.XMLItem := XMLItem;
FLines.AddObject(LowerCase(Name), FValue);
end;
end;
function TfrxConfig.CheckValue(const Name, Current: String): String;
begin
Result := GetValue(Name);
if Result = '' then
Result := Current;
end;
procedure TfrxConfig.Clear;
var
i: Integer;
begin
for i:= 0 to FLines.Count - 1 do
TfrxConfigItem(FLines.Objects[i]).Free;
FLines.Clear;
end;
procedure TfrxConfig.ConfigListToFile(const FileName: String);
var
f: TFileStream;
s: String;
i: Integer;
begin
f := TFileStream.Create(FileName, fmCreate);
try
for i := 0 to FLines.Count - 1 do
begin
s := FLines[i] + ' = ' + TfrxConfigItem(FLines.Objects[i]).Value + #13#10;
f.Write(s[1], Length(s));
end;
finally
f.Free;
end;
end;
constructor TfrxConfig.Create;
begin
FCS := TCriticalSection.Create;
FXML := TfrxXMLDocument.Create;
FXML.AutoIndent := True;
FErrors := TStringList.Create;
FLines := TStringList.Create;
FLines.Sorted := True;
FConfigFolder := GetAppPath;
end;
destructor TfrxConfig.Destroy;
begin
Clear;
FLines.Free;
FErrors.Free;
FXML.Free;
FCS.Free;
inherited;
end;
function TfrxConfig.GetBool(const Name: String): Boolean;
begin
Result := GetValue(Name) = 'yes';
end;
function TfrxConfig.GetCount: Integer;
begin
Result := FLines.Count;
end;
function TfrxConfig.GetNumber(const Name: String): Integer;
var
s: String;
begin
s := GetValue(Name);
if s = '' then
Result := 0
else
Result := StrToInt(s);
end;
function TfrxConfig.GetValue(const Name: String): String;
var
i: Integer;
begin
FCS.Enter;
try
i := FLines.IndexOf(LowerCase(Name));
if i <> -1 then
{$IFNDEF Linux}
Result := TfrxConfigItem(FLines.Objects[i]).Value
{$ELSE}
Result := StringReplace(TfrxConfigItem(FLines.Objects[i]).Value, '\', '/',[rfReplaceAll])
{$ENDIF}
else
Result := '';
finally
FCS.Leave;
end;
end;
function TfrxConfig.LoadFromFile(const FileName: String): HRESULT;
var
f: TFileStream;
// frc: TResourceStream;
begin
FCS.Enter;
try
//try
// frc := TResourceStream.Create(HInstance, 'TfrxConfig', RT_RCDATA);
// try
// Result := LoadFromStream(frc);
// finally
// frc.Free;
// end;
//except
// Result := E_FAIL;
//end;
if FileExists(FileName) then
begin
try
f := TFileStream.Create(FileName, fmOpenRead + fmShareDenyWrite);
try
Result := LoadFromStream(f);
FFileName := FileName;
finally
f.Free;
end;
except
Result := E_FAIL;
end;
end
else
Result := E_FAIL;
finally
FCS.Leave;
end;
end;
function TfrxConfig.LoadFromStream(Stream: TStream): HRESULT;
begin
Result := S_OK;
FCS.Enter;
try
try
FXML.LoadFromStream(Stream);
UpdateLines;
except
Result := E_FAIL;
end;
finally
FCS.Leave;
end;
end;
procedure TfrxConfig.Reload;
begin
LoadFromFile(FFileName);
end;
function TfrxConfig.SaveToFile(const FileName: String): HRESULT;
var
f: TFileStream;
begin
try
f := TFileStream.Create(FileName, fmCreate);
try
Result := SaveToStream(f);
FFileName := FileName;
finally
f.Free;
end;
except
Result := E_FAIL;
end;
end;
function TfrxConfig.SaveToStream(Stream: TStream): HRESULT;
begin
Result := S_OK;
FCS.Enter;
try
try
FXML.Root.Prop['configversion'] := FR_SERVER_CONFIG_VERSION;
FXML.SaveToStream(Stream);
UpdateLines;
except
Result := E_FAIL;
end;
finally
FCS.Leave;
end;
end;
procedure TfrxConfig.SetBool(const Name: String; const Value: Boolean);
begin
if Value then
SetValue(Name, 'yes')
else
SetValue(Name, 'no');
end;
procedure TfrxConfig.SetValue(const Name, Value: String);
var
i: Integer;
begin
i := FLines.IndexOf(Name);
if (i <> -1) and (FLines.Objects[i] <> nil) then
begin
TfrxConfigItem(FLines.Objects[i]).Value := Value;
if TfrxConfigItem(FLines.Objects[i]).XMLItem.Name = 'set' then
TfrxConfigItem(FLines.Objects[i]).XMLItem.Prop['value'] := Value;
end;
end;
procedure TfrxConfig.UpdateLines;
procedure AddItemToLines(const Prefix: String; Item: TfrxXMLItem);
var
s: String;
i: Integer;
begin
if Item <> nil then
begin
s := Prefix;
if s = '' then
s := Item.Name
else if Item.PropExists('desc') and (Item.Name <> 'set') then
s := s + '.' + Item.Name;
if Item.Name = 'set' then
AddLine(s + '.' + Item.Prop['name'], Item.Prop['value'], Item)
else
begin
if Item.PropExists('name') then
AddLine(s + '.name', Item.Prop['name'], Item);
for i := 0 to Item.Count - 1 do
AddItemToLines(s, Item.Items[i]);
end;
end;
end;
begin
//Clear;
AddLine('configversion', FXML.Root.Prop['configversion'], nil);
AddItemToLines('', FXML.Root.FindItem('server'));
end;
{ TfrxServerConfig }
procedure TfrxServerConfig.LoadFromFile(const FileName: String);
var
Ini: TIniFile;
begin
// compatibility code
if FileExists(FileName) then
begin
LogWriter.Write(SERVER_LEVEL, 'Borrow old-style config. You should delete the file ' + FileName + ' after this launch.');
Ini := TIniFile.Create(FileName);
try
Port := Ini.ReadInteger('Server', 'Port', 8097);
ServerConfig.SetValue('server.http.port', IntToStr(Port));
SessionTimeOut := Ini.ReadInteger('Server', 'SessionTimeOut', 300);
ServerConfig.SetValue('server.http.sessiontimeout', IntToStr(SessionTimeOut));
SocketTimeOut := Ini.ReadInteger('Server', 'SocketTimeOut', 300);
ServerConfig.SetValue('server.http.sockettimeout', IntToStr(SocketTimeOut));
IndexFileName := Ini.ReadString('Server', 'IndexFileName', 'index.html');
ServerConfig.SetValue('server.http.indexfile', IndexFileName);
LogPath := frxGetAbsPath(Ini.ReadString('Server', 'LogPath', 'logs'));
ServerConfig.SetValue('server.logs.path', frxGetRelPath(LogPath));
ReportPath := frxGetAbsPath(Ini.ReadString('Server', 'ReportPath', 'reports'));
ServerConfig.SetValue('server.reports.path', frxGetRelPath(ReportPath));
RootPath := frxGetAbsPath(Ini.ReadString('Server', 'RootPath', 'htdocs'));
ServerConfig.SetValue('server.http.rootpath', frxGetRelPath(RootPath));
NoCacheHeader := Ini.ReadBool('Server', 'NoCacheHeader', True);
ServerConfig.SetBool('server.http.nocacheheader', NoCacheHeader);
Compression := Ini.ReadBool('Server', 'Compression', True);
ServerConfig.SetBool('server.http.compression', Compression);
Login := Ini.ReadString('Server', 'Login', '');
ServerConfig.SetValue('server.security.login', Login);
Password := Ini.ReadString('Server', 'Password', '');
ServerConfig.SetValue('server.security.password', Password);
MIC := Ini.ReadBool('Server', 'MessageIntegrityCheck', True);
ServerConfig.SetBool('server.http.mic', MIC);
ReportsList := Ini.ReadBool('Server', 'ReportsList', True);
ServerConfig.SetBool('server.security.reportslist', ReportsList);
Logging := Ini.ReadBool('Server', 'WriteLogs', False);
ServerConfig.SetBool('server.logs.active', Logging);
MaxLogSize := Ini.ReadInteger('Server', 'MaxLogSize', 1024);
ServerConfig.SetValue('server.logs.rotatesize', IntToStr(MaxLogSize));
MaxLogFiles := Ini.ReadInteger('Server', 'MaxLogFiles', 5);
ServerConfig.SetValue('server.logs.rotatefiles', IntToStr(MaxLogFiles));
ReportCaching := Ini.ReadBool('ReportsCache', 'Enabled', False);
ServerConfig.SetBool('server.cache.active', ReportCaching);
ReportCachePath := frxGetAbsPath(Ini.ReadString('ReportsCache', 'CachePath', 'cache'));
ServerConfig.SetValue('server.cache.path', frxGetRelPath(ReportCachePath));
DefaultCacheLatency := Ini.ReadInteger('ReportsCache', 'DefaultLatency', 300);
ServerConfig.SetValue('server.cache.defaultlatency', IntToStr(DefaultCacheLatency));
Database := frxGetAbsPath(Ini.ReadString('Database', 'Connection', ''));
ServerConfig.SetValue('server.database.pathtodatabase', frxGetRelPath(Database));
ServerConfig.SaveToFile(frxGetAbsPath('config.xml'));
ServerConfig.ServerMessage := 'Please restart server!';
finally
Ini.Free;
end;
end;
end;
procedure TfrxServerConfig.SaveToFile(const FileName: String);
begin
// compatibility code
ServerConfig.SaveToFile(FileName);
end;
initialization
ServerConfig := TfrxConfig.Create;
finalization
ServerConfig.Free;
end.