|
Intraweb Architecture - Felix John COLIBRI.
|
- abstract : the architecture of the IntraWeb web site building tool.
Explains how Delphi "rad html generator" work, and presents the CLASS
organization
- key words : Intraweb - Delphi HTML Web site generator
- software used : Windows XP Home Edition, Delphi 6
- hardware used : Pentium 2.800Mhz, 512 M memory, 140 G hard disc
- scope : Delphi 6, Delphi 7, Delphi 8, Delphi 2005, Delphi 2006, Turbo
Delphi for Windows, Delphi 2007
- level : Delphi Web developer
- plan :
1 - Intraweb, the VCL for the Web
IntraWeb is a Delphi Tool used to build web sites. The developer creates pages
in the same way that he builds Windows application:
- by selecting controls from the Palette
- and droping them on a design surface which is the template of the future
window (HTML page) that the User will see.
Things get a little bit more complex since the HTML pages are not directly
loaded from the User PC, but are requested from a Web Server. So IntraWeb
places the templates on the Web Server, and the Server loads them and ships
them to the User.
In this paper, we will present:
- a general explanation about how the Delphi Rad, machinery, Palette, Object
Inspector and tForm, can be used to produce .HTML pages
- the two basic IntraWeb working modes: Application mode and Page mode
- finally the IntraWeb CLASS architecture
2 - How a RAD HTML generator works
Let's assume that we want to generate the following simple .HTML page:
To produce .HTML pages, we must generate an .HTML file with a content similar
to:
<HTML>
<BODY>
<FORM method="POST" ACTION="http://127.0.0.1/scripts/training.exe"><BR>
<TABLE width="100%">
<TR >
<TD >
<TABLE width="100%" bgcolor="#FFBBFF">
<TR >
<TD width="22%" valign=top>
<IMG SRC="pascal_institute_2.jpg">
</TD>
<TD >
<H3>Delphi Training Courses</H3>
</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR >
<TD >
<TABLE width="100%" cellpadding=4>
<TR >
<TD width="23%" bgcolor="#FFBBFF" valign=top>
<A HREF="delphi_tutorial">Delphi Tutorial</A><BR>
<A HREF="dellphi_2006">Delphi 2006</A><BR>
<A HREF="interbase_client_server">Interbase C/S</A>
</TD>
<TD bgcolor="#FFFFFF">
The Pascal Institute organizes each month
Delphi Trainings. To get the list of all
available dates:<BR>
<UL>
<LI> Delphi Tutorial
<LI> Delphi 2006 for .Net
<LI> Interbase Client Server<BR>
</UL>
To get the full documentation, and the
calendar of the next sessions, please
enter your e-mail and
clic the "Submit" button:<BR>
<INPUT TYPE="text" NAME="Edit1" VALUE="my.mail@xxx"> <BR>
<INPUT TYPE="submit" NAME="Button1" VALUE="submit"> <BR>
</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR >
<TD >
<TABLE width="100%" bgcolor="#FFBBFF">
<TR >
<TD width="23%" valign=top>
</TD>
<TD >
<A HREF="index">Felix Colibri Home</A><BR>
<A HREF="source_code">Articles</A> with
full Source Code<BR>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>
|
And to do so, we can
- create a Delphi tForm, with tPanels used as layout containers:
- analyze the tForm.Controls array to generate the .HTML page
A complete Delphi feasability project transforming a standard tForm with
tPanels used as formating containers into an .HTML page has been presented in
the Delphi Web Designer paper.
Instead of using standard tPanel as layout containers, IntraWeb offers many
dedicated components, usually descending from the standard Delphi tEdit,
tButton, tCheckBox. And in addition, IntraWeb offers either the complete
.HTTP Server (the Application mode) or allows to call the generated pages as
ISAPI filters (the Page mode)
3 - Intraweb "Application mode" and "Page mode"
IntraWeb contains 2 sets of components:
- those used at design time
- those included in the runtime project
The design-time components (Wizards, PROPERTY Editors, Designers) will help
us to create the web pages. They are incorporated in the Delphi IDE, and using
them will produce UNITs which represents our pages.
The produced pages can
- either be sent to the User by using an IntraWeb .HTTP Server
- or used as ISAPI .DLLs, called by Microsoft IIS (Internet Information
Server) or the Apache Server
This can be represented by the following figure:
where:
- the Delphi + IntraWeb framework are used to generate the pages (the deep
blue rectangles)
- a runtime, we can use
- either the IntraWeb standalone .HTTP Server
- or any standard Server, like IIS
The runtime block diagram looks like this:
On the Client side
- the User can load IntraWeb pages from a large variety of Browsers,
including Internet Explorer, Opera etc
- the pages sent to the User include JavaScript code, which is interpreted
by the JavaScript interpreter installed on the User PC
- we can also use .XML files to cache some data at the User PC
4 - The Intraweb Class Library
4.1 - The Intraweb CLASSes
We looked at the Intraweb 5.3 classes and, based on the inheritance of each
CLASS, we came up with the following organization:
TIWBaseControl= Class(TControl)
TIWControl= Class(TIWBaseControl, IIWControl)
TIWCustomObject= Class(TIWControl)
TIWActiveX= Class(TIWCustomObject)
TIWCustomFlash= Class(TIWCustomObject)
TIWFlash= Class(TIWCustomFlash)
TIWCustomQuickTime= Class(TIWCustomObject)
TIWQuickTime= Class(TIWCustomQuickTime)
TIWMPEG= Class(TIWCustomObject)
TIWApplet= Class(TIWControl)
TIWCSCustomNavigator= Class(TIWControl)
TIWCSNavigator= Class(TIWCSCustomNavigator)
TIWCustomButton= Class(TIWControl)
TIWButton= Class(TIWCustomButton)
TIWCustomCheckBox= Class(TIWControl)
TIWCheckBox= Class(TIWCustomCheckBox)
TIWDBCheckBox= Class(TIWCustomCheckBox)
TIWCustomDynamicChart= Class(TIWControl)
TIWDynamicChart= Class(TIWCustomDynamicChart)
TIWCustomDynamicChartLegend= Class(TIWControl)
TIWDynamicChartLegend= Class(TIWCustomDynamicChartLegend)
TIWCustomDynGrid= Class(TIWControl)
TIWDynGrid= Class(TIWCustomDynGrid)
TIWCustomEdit= Class(TIWControl)
TIWCustomFile= Class(TIWCustomEdit)
TIWDBFile= Class(TIWCustomFile)
TIWFile= Class(TIWCustomFile)
TIWDBEdit= Class(TIWCustomEdit)
TIWEdit= Class(TIWCustomEdit)
TIWCustomGrid= Class(TIWControl)
TIWCalendar= Class(TIWCustomGrid)
TIWDBGrid= Class(TIWCustomGrid)
TIWGrid= Class(TIWCustomGrid)
TIWCustomImage= Class(TIWControl)
TIWDynamicImage= Class(TIWCustomImage)
TIWImage= Class(TIWDynamicImage)
TIWDBImage= Class(TIWDynamicImage)
TIWImageFile= Class(TIWCustomImage)
TIWCustomLabel= Class(TIWControl)
TIWCustomCSLabel= Class(TIWCustomLabel)
TIWCSLabel= Class(TIWCustomCSLabel)
TIWDBLabel= Class(TIWCustomLabel)
TIWLabel= Class(TIWCustomLabel)
TIWCustomListCombo= Class(TIWControl)
TIWCustomComboBox= Class(TIWCustomListCombo)
TIWComboBox= Class(TIWCustomComboBox)
TIWDBComboBox= Class(TIWCustomComboBox)
TIWDBLookupComboBox= Class(TIWCustomComboBox)
TIWCustomListbox= Class(TIWCustomListCombo)
TIWDBListbox= Class(TIWCustomListbox)
TIWDBLookupListBox= Class(TIWCustomListbox)
TIWListbox= Class(TIWCustomListbox)
TIWCustomMemo= Class(TIWControl)
TIWDBMemo= Class(TIWCustomMemo)
TIWMemo= Class(TIWCustomMemo)
TIWCustomRadioGroup= Class(TIWControl)
TIWRadioGroup= Class(TIWCustomRadioGroup)
TIWDBRadioGroup= Class(TIWCustomRadioGroup)
TIWCustomRectangle= Class(TIWControl)
TIWRectangle= Class(TIWCustomRectangle)
TIWCustomText= Class(TIWControl)
TIWDBText= Class(TIWCustomText)
TIWText= Class(TIWCustomText)
TIWDBNavigator= Class(TIWControl)
TIWHRule= Class(TIWControl)
TIWLinkBase= Class(TIWControl)
TIWCustomURL= Class(TIWLinkBase)
TIWURL= Class(TIWCustomURL)
TIWLink= Class(TIWLinkBase)
TIWList= Class(TIWControl)
TIWMenu= Class(TIWControl)
TIWProgressBar= Class(TIWControl)
TIWTimer= Class(TIWControl)
TIWTreeView= Class(TIWControl)
TIWURLWindow= Class(TIWControl)
TIWControlAccess= Class(TIWBaseControl)
TIWContainer= Class(TScrollingWinControl)
TIWModuleDsn= Class(TIWContainer)
TIWBaseForm= Class(TIWModuleDsn)
TIWForm= Class(TIWBaseForm)
TIWAppForm= Class(TIWForm)
TIWShowMessage= Class(TIWAppForm)
TIWPageForm= Class(TIWForm)
TIWRegion= Class(TIWContainer)
===
TIWPaintHandler= Class(TObject)
TIWPaintHandlerDsn= Class(TIWPaintHandler)
TIWPaintHandlerButton= Class(TIWPaintHandlerDsn)
TIWPaintHandlerCheckBox= Class(TIWPaintHandlerDsn)
TIWPaintHandlerComboBox= Class(TIWPaintHandlerDsn)
TIWPaintHandlerComponent= Class(TIWPaintHandlerDsn)
TIWPaintHandlerCSNavigator= Class(TIWPaintHandlerDsn)
TIWPaintHandlerDBNavigator= Class(TIWPaintHandlerDsn)
TIWPaintHandlerEdit= Class(TIWPaintHandlerDsn)
TIWPaintHandlerHRule= Class(TIWPaintHandlerDsn)
TIWPaintHandlerImage= Class(TIWPaintHandlerDsn)
TIWPaintHandlerLabel= Class(TIWPaintHandlerDsn)
TIWPaintHandlerLink= Class(TIWPaintHandlerDsn)
TIWPaintHandlerList= Class(TIWPaintHandlerDsn)
TIWPaintHandlerListBox= Class(TIWPaintHandlerDsn)
TIWPaintHandlerMemo= Class(TIWPaintHandlerDsn)
TIWPaintHandlerProgressBar= Class(TIWPaintHandlerDsn)
TIWPaintHandlerRadioGroup= Class(TIWPaintHandlerDsn)
TIWPaintHandlerRectangle= Class(TIWPaintHandlerDsn)
TIWPaintHandlerText= Class(TIWPaintHandlerDsn)
TIWBase= Class(TObject)
TIWFileParser= Class(TObject)
TIWFormListManager= Class(TObject)
TIWFormPreviewGenerator= Class(TObject)
TIWLicense= Class(TObject)
TIWFileReference= Class(TPersistent)
TIWBackground= Class(TIWFileReference)
TIWGridBorderColors= Class(TPersistent)
TIWDynGridBorderColors= Class(TIWGridBorderColors)
TIWBorderOptions= Class(TPersistent)
TIWDBNavConfirmations= Class(TPersistent)
TIWDBNavImages= Class(TPersistent)
TIWDefaultDynGridCell= Class(TPersistent)
TIWFont= Class(TPersistent)
TIWJpegOptions= Class(TPersistent)
TIWMenuStyle= Class(TPersistent)
TIWURLTarget= Class(TPersistent)
TIWReEntryOptions= Class(TPersistent)
TIWSSLOptions= Class(TPersistent)
TIWTemplateFiles= Class(TPersistent)
TIWTreeViewImages= Class(TPersistent)
TIWLayoutMgrBase= Class(TComponent)
TIWLayoutMgr= Class(TIWLayoutMgrBase)
TIWLayoutMgrForm= Class(TIWLayoutMgr)
TIWLayoutMgrHTML= Class(TIWLayoutMgr, IIWLayoutMgrHTML)
TIWTemplateProcessorHTML= Class(TIWLayoutMgr)
TIWApplication= Class(TComponent)
TIWHTTPServerModule= Class(TComponent)
TIWHTMLManager= Class(TComponent, IDesignNotification, IHTMLLayoutComponent)
TIWStandAloneServer= Class(TComponent)
TIWModuleController= Class(TComponent, IWebDispatch)
TIWClientSideDatasetBase= Class(TComponent)
TIWClientSideDataset= Class(TIWClientSideDatasetBase)
TIWClientSideDatasetDBLink= Class(TIWClientSideDatasetBase)
TIWHTMLElement= Class(TCollectionItem)
TIWHTMLTag= Class(TIWHTMLElement)
TIWHTMLTable= Class(TIWHTMLTag)
TIWTextElement= Class(TIWHTMLElement)
TIWGridCell= Class(TCollectionItem)
TIWCalendarCell= Class(TIWGridCell)
TIWDBGridColumn= Class(TIWGridCell)
TIWColorForm= Class(TForm)
TIWDsnTreeView= Class(TForm, IIWTreeViewDesigner)
TIWServerControllerBase= Class(TDataModule)
TIWPageProducer= Class(TCustomPageProducer)
TIWServer= Class(TCustomWebDispatcher)
TIWSessions= Class(TThreadList)
TIWStream= Class(TStream)
TIWTagParamsStringList= Class(TStringList)
===
TIWCalendarCells= Class(TOwnedCollection)
TIWDBGridColumns= Class(TOwnedCollection)
TIWGridCells= Class(TOwnedCollection)
TIWHTMLTagCollection= Class(TCollection)
TIWObjectParam= Class(TCollectionItem)
TIWObjectParams= Class(TOwnedCollection)
TIWScriptEvents= Class(TOwnedCollection)
TIWScriptEventsItem= Class(TCollectionItem)
TIWTreeViewItem= Class(TCollectionItem)
TIWTreeViewItems= Class(TOwnedCollection)
TIWApplicationWizard= Class(TNotifierObject, IUnknown, IOTARepositoryWizard, IOTAProjectWizard, IOTAWizard)
TIWDataModuleCreator= Class(TNotifierObject, IOTAModuleCreator, IOTACreator)
TIWDataModuleFile= Class(TNotifierObject, IOTAFile)
TIWDataModuleFormFile= Class(TNotifierObject, IOTAFile)
TIWDataModuleHeader= Class(TNotifierObject, IOTAFile)
TIWProjectCreator= Class(TNotifierObject, IOTAProjectCreator50, IOTAProjectCreator, IOTACreator)
TIWProjectFile= Class(TNotifierObject, IOTAFile)
TIWServerControllerCreator= Class(TNotifierObject, IOTAModuleCreator, IOTACreator)
TIWServerControllerFile= Class(TNotifierObject, IOTAFile)
TIWServerControllerFormFile= Class(TNotifierObject, IOTAFile)
TIWServerControllerHeader= Class(TNotifierObject, IOTAFile)
TIWUnitCreator= Class(TNotifierObject, IOTAModuleCreator, IOTACreator)
TIWUnitFile= Class(TNotifierObject, IOTAFile)
TIWUnitFormFile= Class(TNotifierObject, IOTAFile)
TIWUnitHeader= Class(TNotifierObject, IOTAFile)
TIWUnitWizard= Class(TNotifierObject, IUnknown, IOTARepositoryWizard, IOTAProjectWizard, IOTAWizard)
TIWMainUpdateSessions= Class(TIdNotifyMethod)
TIWColorEditor= Class(TColorProperty, ICustomPropertyListDrawing, ICustomPropertyDrawing)
TIWPreviewForm= Class(TDefaultEditor)
TIWImageList= Class(TImageList)
TIWTreeViewComponent= Class(TComponentEditor)
===
TLayoutMgrHTMLComponent= Class(TComponentEditor)
TLayoutMgrHTMLProperty= Class(TPropertyEditor)
TLocalSelection= Class(TDesignerSelections)
TPersistentCracker= Class(TPersistent)
TRC4= Class(TObject)
TSessionTimeoutThread= Class(TThread)
TSWServiceModule= Class(TService)
TSWServiceThread= Class(TThread)
TSyncLog= Class(TIdNotify)
TTreeViewItemsProperty= Class(TPropertyEditor)
TformAppWizard= Class(TForm)
TformFormWizard= Class(TForm)
TFormIWMain= Class(TForm)
TfrmEventsEditor= Class(TForm)
THTMLPaletteItem= Class(TObject)
THTTPFile= Class(TObject)
THTTPFiles= Class(TObjectList)
|
It would have been possible to present those in simplified block diagrams, or
in full fledged UML CLASS diagram, but, given the sheer number of those
CLASSES, we feel that the resulting huge map would have been difficult to use.
In addition, the Intraweb hierarchy is not very deep.
4.2 - The CLASS Organization
The above structure is a pure syntactical construction. It would be more
helpful to separate the classes according to where they are used
- at design time only: those CLASSEs are used to integrate IntraWeb to the
Delphi IDE. The developer will use them implicitely to build the pages, but
they will not be part of the deployed files. In this category, we can place:
- all the Property Editors
- OTA (Open Tool Api) extensions (the CLASSes that help expand the
base IDE
- at runtime
- by the IntraWeb Server
- by the WebBroker or DataSnap ISAPI libraries
In addition, to better group the CLASSes, it would be necessary to fully
analyze the IntraWeb feature list. For instance, IntraWeb:
- manages sessions
- has access to databases
- manages several .HMTL pages
4.3 - Intraweb UML Class Diagram
We wrote a 160 K IntraWeb tutorial (referenced by GOOGLE), and therefore had
to dwelve more into the Page mode CLASSes.
For the Page mode:
All those CLASS diagram were build by looking into the help, the Object
Inspector and the Delphi 6 IntraWeb .DCUs. It goes without saying that it
would have been a lot easier if AToZed (the IntraWeb editor) somehow published
the UNIT INTERFACEs.
5 - Building Web Sites with Delphi
5.1 - IntraWeb in perspective
There are many other way to build Web sites with Delphi. To name a few:
- non-RAD approaches:
- CGI or ISAPI helper libraries (hRef or similar)
- WebBroker and DataSnap, which are part of Delphi
- RAD building tools
- from Developper Express, there is Internet Express Web (IEW)
- on the Microsoft front, there are .ASP and .ASP .NET
- and, of course, IntraWeb
The first Delphi tools available (WebBroker and WebSnap) were non-RAD.
Nobody could understand why Borland, who had offered us the Delphi IDE, never
added a true .HTML RAD tool. Well, IntraWeb did the trick, and since
Delphi 7, it seems to be one of the most popular tools.
Here are a couple of links with comparisons of the IntraWeb, Developer
Express and Asp.Net approaches, and they contain additional references:
5.2 - Our Site Building Framework
Note that we use a different approach to create our pages. First we created our
site before IntraWeb was offered on the Delphi Palette. And, more important,
our site mainly contains static text pages with a couple of images. So a text
editor is more appropriate than a "control layouter".
Therefore:
- we simply write pages with our custom ColiEd editor. This is a simple text
editor like Notepad, and writing the text is lightning fast. In addition to
the ASCII content that you see, each page also contains
- some markers to incorporate .PNG images
- some simple typographic tags to delimit .HTML links or headers, add
bullets or other typographic features like bold italic etc
- the .ED file is placed in the appropriate folder. The disc organization
exactly mirrors the hierarchical site path organization
- we then use a Delphi project, SiteEditor to transform each .ED editor
file into an .HTML file.
The generator then adds the purple outer region which contains:
- the top location link (where you are in the page tree)
- the left-side indented menu
- the bottom addresses
And navigation links between pages are built according to the disk pathes
6 - Your Comments
As usual:
- please tell us at fcolibri@felix-colibri.com if you found some errors, mistakes, bugs or had
some problem downloading the file. Resulting corrections will be helpful
for other readers
- we welcome any comment, criticism, enhancement, other sources or reference
suggestion. Just send an e-mail to fcolibri@felix-colibri.com.
- or more simply, enter your (anonymous or with your e-mail if you want an
answer) comments below and clic the "send" button
- and if you liked this article, talk about this site to your fellow
developpers, add a link to your links page ou mention our articles in
your newsgroup posts when relevant. That's the way we operate: the more
traffic and Google references we get, the more articles we will write.
7 - Intraweb Home Page
IntraWeb was originally designed by Chad Z. HOWER, alias
KUDZU, back in 1996/97, and was then called Portcullis/IAG. Chad was the
creator of Winshoes, later renamed Indy, which is the
actual Socket and TCP/IP Protocol component suite implementation for Delphi.
This explains why IntraWeb includes a full featured .HTTP Server, even
including the very nice SSL layer.
The current version of IntraWeb is maintained by a developer team at Atozed
Software. Chad is no longer actively involved with IntraWeb's further
development. He is still an end user of IntraWeb and gives input to the
development team.
We also wish to thank all of those who corrected our first presentation of this
Intraweb history.
The IntraWeb product as such is available since Delphi 7. The 5.3 version is
also backward compatible with Delphi 6. With Delphi 2006 Architect, we had
the version 8. We usually do not perform third product overview, but since this
once came with Delphi ...
The above CLASS list was analyzed on the 5.3 free trial version. This is
mainly because we have a Delphi 6 .DCU analyzer, and analyzing the IntraWeb
version which comes with Delphi 2006 would require the upgrade of our .DCU
analyzer to handle those binaries.
You will find more information, as well as demo versions (not time limited, but
some features are not available) and the full version at:
8 - The author
Felix John COLIBRI works at the Pascal
Institute. He programs in Pascal since 1979, and is mainly active in the area
of custom software
development and training, and is a frequent speaker at Borland
Developer Conferences. His web site features
tutorials, technical papers about programming with full downloadable source
code, and the description and calendar of forthcoming Delphi,
Interbase, Asp.Net, Ado.Net and OOP / UML training sessions.
|