Componentes.Terceros.DevExp.../official/x.30/ExpressWeb Framework/Sources/cxWebDsgnWebContext.pas
2007-12-16 17:06:54 +00:00

689 lines
21 KiB
ObjectPascal

{*******************************************************************}
{ }
{ ExpressWeb Framework by Developer Express }
{ Designer Module }
{ }
{ Copyright (c) 2000-2007 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSWEB FRAMEWORK AND ALL }
{ ACCOMPANYING VCL CLASSES AS PART OF AN EXECUTABLE WEB }
{ APPLICATION ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit cxWebDsgnWebContext;
interface
{$I cxVer.inc}
uses SysUtils, Classes, DesignIntf,
{$IFDEF VCL}
Windows;
{$ELSE}
Qt;
{$ENDIF}
function cxGetDesignWebContent(ADesigner: IDesigner): string;
implementation
uses
TypInfo, HTTPApp, HTTPProd, WebCntxt,
cxWebIntf, cxWebSess, cxWebDsgnBaseModules, cxWebDsgnHTMLSource,
cxWebDsgnUtils, cxWebFileCacheManager, cxWebPathConst;
var
FWebContext: TAbstractWebContext;
function cxGetWebContext: TAbstractWebContext;
begin
Result := FWebContext;
end;
procedure cxSetWebContext(AWebContext: TAbstractWebContext);
begin
FWebContext := AWebContext;
end;
type
TcxWebDesignPageInfo = class(TAbstractWebPageInfo)
private
FPageModule: TComponent;
FDesigner: IDesigner;
protected
constructor Create(const APageModule: TComponent; ADesigner: IDesigner);
function GetPageFile: string; override;
function GetPageName: string; override;
end;
constructor TcxWebDesignPageInfo.Create(const APageModule: TComponent; ADesigner: IDesigner);
begin
FPageModule := APageModule;
FDesigner := ADesigner;
end;
function TcxWebDesignPageInfo.GetPageFile: string;
var
AHTMLSource: TcxWebDsgnHTMLSource;
begin
AHTMLSource := TcxWebDsgnHTMLSource.Create('', FDesigner);
if AHTMLSource.HasHTMLFile then
Result := FPageModule.Name + '.html'
else Result := '';
AHTMLSource.Free;
end;
function TcxWebDesignPageInfo.GetPageName: string;
begin
Result := FPageModule.Name;
end;
type
TcxWebDesignModuleFactory = class(TAbstractWebPageModuleFactory)
private
FPageModule: TComponent;
FPageInfo: TcxWebDesignPageInfo;
protected
function GetModuleName: string; override;
function GetIsAppModule: Boolean; override;
function GetCreateMode: TWebModuleCreateMode; override;
function GetCacheMode: TWebModuleCacheMode; override;
function GetComponentClass: TComponentClass; override;
function GetWebPageInfo: TAbstractWebPageInfo; override;
public
constructor Create(APageModule: TComponent; ADesigner: IDesigner);
destructor Destroy; override;
function GetModule: TComponent; override;
procedure PreventDestruction; override;
end;
constructor TcxWebDesignModuleFactory.Create(APageModule: TComponent; ADesigner: IDesigner);
begin
FPageModule := APageModule;
FPageInfo := TcxWebDesignPageInfo.Create(APageModule, ADesigner);
FPageInfo.SetFactory(self);
end;
destructor TcxWebDesignModuleFactory.Destroy;
begin
FPageInfo.Free;
inherited Destroy;
end;
function TcxWebDesignModuleFactory.GetModule: TComponent;
begin
Result := FPageModule;
end;
procedure TcxWebDesignModuleFactory.PreventDestruction;
begin
end;
function TcxWebDesignModuleFactory.GetModuleName: string;
begin
Result := FPageModule.ClassName;
end;
function TcxWebDesignModuleFactory.GetIsAppModule: Boolean;
begin
Result := False;
end;
function TcxWebDesignModuleFactory.GetCreateMode: TWebModuleCreateMode;
begin
Result := crOnDemand;
end;
function TcxWebDesignModuleFactory.GetCacheMode: TWebModuleCacheMode;
begin
Result := caDestroy;
end;
function TcxWebDesignModuleFactory.GetComponentClass: TComponentClass;
begin
Result := TComponentClass(FPageModule.ClassInfo)
end;
function TcxWebDesignModuleFactory.GetWebPageInfo: TAbstractWebPageInfo;
begin
Result := FPageInfo;
end;
type
TcxWebDesignModuleList = class(TAbstractWebModuleList)
private
FPageModule: TComponent;
FModuleFactory: TcxWebDesignModuleFactory;
protected
function GetItem(I: Integer): TComponent; override;
function GetItemCount: Integer; override;
function GetOnModuleAdded: TModuleAddedProc; override;
function GetFactoryCount: Integer; override;
function GetFactory(I: Integer): TAbstractWebModuleFactory; override;
procedure SetOnModuleAdded(AProc: TModuleAddedProc); override;
public
constructor Create(const APageModule: TComponent; ADesigner: IDesigner);
destructor Destroy; override;
function FindModuleClass(AClass: TComponentClass): TComponent; override;
function FindModuleName(const AName: string): TComponent; override;
function AddModuleClass(AClass: TComponentClass): TComponent; override;
function AddModuleName(const AName: string): TComponent; override;
end;
constructor TcxWebDesignModuleList.Create(const APageModule: TComponent; ADesigner: IDesigner);
begin
FPageModule := APageModule;
FModuleFactory := TcxWebDesignModuleFactory.Create(APageModule, ADesigner);
end;
destructor TcxWebDesignModuleList.Destroy;
begin
FModuleFactory.Free;
inherited Destroy;
end;
function TcxWebDesignModuleList.FindModuleClass(AClass: TComponentClass): TComponent;
begin
if AClass = TComponentClass(FPageModule.ClassType) then
Result := FPageModule
else Result := nil;
end;
function TcxWebDesignModuleList.FindModuleName(const AName: string): TComponent;
begin
if CompareText(AName, FPageModule.Name) = 0 then
Result := FPageModule
else Result := nil;
end;
function TcxWebDesignModuleList.AddModuleClass(AClass: TComponentClass): TComponent;
begin
Result := nil;
end;
function TcxWebDesignModuleList.AddModuleName(const AName: string): TComponent;
begin
Result := nil;
end;
function TcxWebDesignModuleList.GetItem(I: Integer): TComponent;
begin
if I = 0 then
Result := FPageModule
else Result := nil;
end;
function TcxWebDesignModuleList.GetItemCount: Integer;
begin
Result := 1;
end;
function TcxWebDesignModuleList.GetOnModuleAdded: TModuleAddedProc;
begin
end;
function TcxWebDesignModuleList.GetFactoryCount: Integer;
begin
Result := 1;
end;
function TcxWebDesignModuleList.GetFactory(I: Integer): TAbstractWebModuleFactory;
begin
if I = 0 then
Result := FModuleFactory
else Result := nil;
end;
procedure TcxWebDesignModuleList.SetOnModuleAdded(AProc: TModuleAddedProc);
begin
end;
type
TcxWebDesignRequest = class(TWebRequest)
protected
function GetStringVariable(Index: Integer): string; override;
function GetDateVariable(Index: Integer): TDateTime; override;
function GetIntegerVariable(Index: Integer): Integer; override;
function GetInternalPathInfo: string; override;
function GetInternalScriptName: string; override;
public
function GetFieldByName(const Name: string): string; override;
function ReadClient(var Buffer; Count: Integer): Integer; override;
function ReadString(Count: Integer): string; override;
function TranslateURI(const URI: string): string; override;
function WriteClient(var Buffer; Count: Integer): Integer; override;
function WriteString(const AString: string): Boolean; override;
function WriteHeaders(StatusCode: Integer; const StatusString, Headers: string): Boolean; override;
end;
function TcxWebDesignRequest.GetFieldByName(const Name: string): string;
begin
Result := '';
end;
function TcxWebDesignRequest.ReadClient(var Buffer; Count: Integer): Integer;
begin
Result := 0;
end;
function TcxWebDesignRequest.ReadString(Count: Integer): string;
begin
Result := '';
end;
function TcxWebDesignRequest.TranslateURI(const URI: string): string;
begin
Result := '';
end;
function TcxWebDesignRequest.WriteClient(var Buffer; Count: Integer): Integer;
begin
Result := 0;
end;
function TcxWebDesignRequest.WriteString(const AString: string): Boolean;
begin
Result := False;
end;
function TcxWebDesignRequest.WriteHeaders(StatusCode: Integer; const StatusString, Headers: string): Boolean;
begin
Result := False;
end;
function TcxWebDesignRequest.GetStringVariable(Index: Integer): string;
begin
Result := '';
end;
function TcxWebDesignRequest.GetDateVariable(Index: Integer): TDateTime;
begin
Result := Date;
end;
function TcxWebDesignRequest.GetIntegerVariable(Index: Integer): Integer;
begin
Result := 0;
end;
function TcxWebDesignRequest.GetInternalPathInfo: string;
begin
Result := '';
end;
function TcxWebDesignRequest.GetInternalScriptName: string;
begin
Result := '';
end;
type
TcxWebDesignResponse = class(TWebResponse)
private
FContent: string;
protected
function GetContent: string; override;
function GetDateVariable(Index: Integer): TDateTime; override;
function GetIntegerVariable(Index: Integer): Integer; override;
function GetLogMessage: string; override;
function GetStatusCode: Integer; override;
function GetStringVariable(Index: Integer): string; override;
procedure SetContent(const Value: string); override;
procedure SetDateVariable(Index: Integer; const Value: TDateTime); override;
procedure SetIntegerVariable(Index: Integer; Value: Integer); override;
procedure SetLogMessage(const Value: string); override;
procedure SetStatusCode(Value: Integer); override;
procedure SetStringVariable(Index: Integer; const Value: string); override;
public
procedure SendResponse; override;
procedure SendRedirect(const URI: string); override;
procedure SendStream(AStream: TStream); override;
function Sent: Boolean; override;
end;
procedure TcxWebDesignResponse.SendResponse;
begin
end;
procedure TcxWebDesignResponse.SendRedirect(const URI: string);
begin
end;
procedure TcxWebDesignResponse.SendStream(AStream: TStream);
begin
end;
function TcxWebDesignResponse.Sent: Boolean;
begin
Result := False;
end;
function TcxWebDesignResponse.GetContent: string;
begin
Result := FContent;
end;
function TcxWebDesignResponse.GetDateVariable(Index: Integer): TDateTime;
begin
Result := Date;
end;
function TcxWebDesignResponse.GetIntegerVariable(Index: Integer): Integer;
begin
Result := 0;
end;
function TcxWebDesignResponse.GetLogMessage: string;
begin
Result := '';
end;
function TcxWebDesignResponse.GetStatusCode: Integer;
begin
Result := 0;
end;
function TcxWebDesignResponse.GetStringVariable(Index: Integer): string;
begin
Result := '';
end;
procedure TcxWebDesignResponse.SetContent(const Value: string);
begin
FContent := Value;
end;
procedure TcxWebDesignResponse.SetDateVariable(Index: Integer; const Value: TDateTime);
begin
end;
procedure TcxWebDesignResponse.SetIntegerVariable(Index: Integer; Value: Integer);
begin
end;
procedure TcxWebDesignResponse.SetLogMessage(const Value: string);
begin
end;
procedure TcxWebDesignResponse.SetStatusCode(Value: Integer);
begin
end;
procedure TcxWebDesignResponse.SetStringVariable(Index: Integer; const Value: string);
begin
end;
type
TcxWebDesignerFileManager = class(TInterfacedObject, IDesignerFileManager)
private
FRoot: TComponent;
FDesigner: IDesigner;
function GetGlobalPath: string;
function GetJSScriptPath: string;
function GetImagePath: string;
protected
function QualifyFileName(const AFileName: string): string;
function GetStream(const AFileName: string; var AOwned: Boolean): TStream;
constructor Create(ARoot: TComponent; ADesigner: IDesigner);
end;
constructor TcxWebDesignerFileManager.Create(ARoot: TComponent; ADesigner: IDesigner);
begin
FRoot := ARoot;
FDesigner := ADesigner;
end;
function TcxWebDesignerFileManager.GetGlobalPath: string;
begin
Result := ExcludeTrailingPathDelimiter(ExtractFilePath(cxGetDesignerApplicationFileName));
if ExtractFileName(Result) = 'Lib' then
Result := ExtractFilePath(Result) // old installation
else
Result := ExtractFilePath(ExcludeTrailingPathDelimiter(ExtractFilePath(Result))); // new installation
end;
function TcxWebDesignerFileManager.GetJSScriptPath: string;
begin
Result := GetGlobalPath + cxWebJScriptDTPath + PathDelim;
end;
function TcxWebDesignerFileManager.GetImagePath: string;
begin
Result := GetGlobalPath + cxWebImageDTPath + PathDelim;
end;
function TcxWebDesignerFileManager.QualifyFileName(const AFileName: string): string;
var
AExt: string;
begin
AExt := UpperCase(ExtractFileExt(AFileName));
if (AExt <> '') and (AExt[1] = '.') then
AExt := Copy(AExt, 2, Length(AExt));
if AExt = 'JS' then
Result := GetJSScriptPath + AFileName
else
if (AExt = 'GIF') or (AExt = 'JPEG') or (AExt = 'BMP') or
(AExt = 'JPG') then
Result := GetImagePath + AFileName
else Result := AFileName;
Result := StringReplace(Result, '\', '/', [rfReplaceAll, rfIgnoreCase]);
end;
function TcxWebDesignerFileManager.GetStream(const AFileName: string; var AOwned: Boolean): TStream;
var
AHTMLSource: TcxWebDsgnHTMLSource;
AFile: string;
AFileStream: TFileStream;
begin
AHTMLSource := TcxWebDsgnHTMLSource.Create('', FDesigner);
try
if (Pos(FRoot.Name, AFileName) = 1) and
(Length(AFileName) > Length(FRoot.Name)) and
(AFileName[Length(FRoot.Name) + 1] = '.') then
Result := TStringStream.Create(AHTMLSource.HTML)
else
begin
AFile := ExtractFilePath(AHTMLSource.SourceEditor.FileName) + AFileName;
if FileExists(AFile) then
begin
AFileStream := TFileStream.Create(AFile, fmOpenRead, fmShareDenyNone);
Result := TMemoryStream.Create;
Result.CopyFrom(AFileStream, AFileStream.Size);
AFileStream.Free;
if Result.Size > 0 then
Result.Position := 0;
end else Result := TStringStream.Create('');
end;
finally
AHTMLSource.Free;
end;
end;
type
TRootReader = class(TReader)
private
FRoot: TComponent;
procedure DoFindMethodEvent(Reader: TReader; const MethodName: string;
var Address: Pointer; var Error: Boolean);
procedure DoFindComponentClassEvent(Reader: TReader; const ClassName: string;
var ComponentClass: TComponentClass);
public
constructor Create(ARoot: TComponent; AStream: TStream);
end;
constructor TRootReader.Create(ARoot: TComponent; AStream: TStream);
begin
inherited Create(AStream, 4096);
FRoot := ARoot;
OnFindMethod := DoFindMethodEvent;
OnFindComponentClass := DoFindComponentClassEvent;
end;
procedure TRootReader.DoFindMethodEvent(Reader: TReader; const MethodName: string;
var Address: Pointer; var Error: Boolean);
begin
Error := False;
end;
procedure TRootReader.DoFindComponentClassEvent(Reader: TReader; const ClassName: string;
var ComponentClass: TComponentClass);
var
I: Integer;
begin
if ComponentClass <> nil then exit;
for I := 0 to FRoot.ComponentCount - 1 do
if CompareText(ClassName, FRoot.Components[I].ClassName) = 0 then
begin
ComponentClass := TComponentClass(FRoot.Components[I].ClassType);
break;
end;
end;
type
TComponentAccess = class(TComponent);
function cxGetDesignWebContent(ADesigner: IDesigner): string;
var
AModuleList: TcxWebDesignModuleList;
ARequest: TcxWebDesignRequest;
AResponse: TcxWebDesignResponse;
ASession: TAbstractWebSession;
ASaveDesignerFileManager: IDesignerFileManager;
ASaveWebContext: TAbstractWebContext;
ASaveGetWebContextProc: TGetWebContextProc;
ASaveSetWebContextProc: TSetWebContextProc;
ADummyRoot: TComponent;
function CreateDummyRootComponent: TComponent;
var
AStream: TMemoryStream;
AReader: TRootReader;
ATypeData: PTypeData;
ADesignerModule: IcxWebDesignerModule;
begin
ATypeData := GetTypeData(ADesigner.Root.ClassInfo);
Result := nil;
while (ATypeData <> nil) and not cxWebIsBasePageModule(ATypeData.ClassType) and
(ATypeData.ParentInfo <> nil) do
ATypeData := GetTypeData(ATypeData.ParentInfo^);
if (ATypeData = nil) or (ATypeData.ParentInfo = nil) then exit;
AStream := TMemoryStream.Create;
try
AStream.WriteComponent(ADesigner.Root);
AStream.Seek(0, soFromBeginning);
Result := TComponentClass(ATypeData.ClassType).Create(nil);
AReader := TRootReader.Create(ADesigner.Root, AStream);
try
Result := AReader.ReadRootComponent(Result);
TComponentAccess(Result).SetDesigning(True, False);
finally
AReader.Free;
end;
Result.Name := ADesigner.Root.Name;
if Supports(Result, IcxWebDesignerModule, ADesignerModule) then
ADesignerModule.SetIsDesignerPreviewModule(True);
finally
AStream.Free;
end;
end;
procedure InitWebContext;
begin
AModuleList := TcxWebDesignModuleList.Create(ADummyRoot, ADesigner);
ARequest := TcxWebDesignRequest.Create;
AResponse := TcxWebDesignResponse.Create(nil);
ASession := TcxWebSession.Create;
ASaveWebContext := WebContext;
ASaveSetWebContextProc := SetWebContextProc;
ASaveGetWebContextProc := GetWebContextProc;
SetWebContextProc := cxSetWebContext;
GetWebContextProc := cxGetWebContext;
TWebContext.Create(AModuleList, ARequest, AResponse, ASession);
WebContext.DispatchedPageName := ADummyRoot.Name;
ASaveDesignerFileManager := DesignerFileManager;
DesignerFileManager := TcxWebDesignerFileManager.Create(ADummyRoot, ADesigner);
TcxWebFileCacheManager.Instance.IncDesignerCount;
end;
procedure DestroyWebContext;
begin
TcxWebFileCacheManager.Instance.DecDesignerCount;
DesignerFileManager := ASaveDesignerFileManager;
WebContext.Free;
GetWebContextProc := ASaveGetWebContextProc;
SetWebContextProc := ASaveSetWebContextProc;
if Assigned(SetWebContextProc) then
SetWebContextProc(ASaveWebContext);
ARequest.Free;
AResponse.Free;
ASession.Free;
AModuleList.Free;
end;
var
AWebPage: IcxWebPage;
begin
if Supports(ADesigner.Root, IcxWebPage) then
begin
if Supports(ADesigner.Root, IcxWebPageModule) then // TODO
begin
Classes.RegisterClass(TComponentClass(ADesigner.Root.ClassType));
ADummyRoot := CreateDummyRootComponent;
end else ADummyRoot := ADesigner.Root;
if (ADummyRoot <> nil) and Supports(ADummyRoot, IcxWebPage, AWebPage) then
begin
try
InitWebContext;
try
if AWebPage.DispatchPage(ADummyRoot.Name, AResponse) then
Result := AResponse.Content
else Result := '';
except
on E: Exception do
if Result = '' then Result := E.Message;
end;
finally
if Supports(ADesigner.Root, IcxWebPageModule) then
ADummyRoot.Free;
DestroyWebContext;
end;
end else Result := '';
if Supports(ADesigner.Root, IcxWebPageModule) then
Classes.UnregisterClass(TComponentClass(ADesigner.Root.ClassType));
end else Result := '';
end;
end.