Introduction▲
Une des grandes nouveautés de XMLRAD 2005 c'est le débogueur intégré. C'est un débogueur de haut niveau, c'est-à-dire qu'il ne travaille pas sur le code, mais au niveau applicatif. Plus précisément, au niveau du framework XMLCLX qui est la base de toutes applications XMLRAD.
Ce débogueur est une aubaine pour les développeurs XMLRAD, car certaines parties de l'exécution de l'application à la charge du framework n'étaient pas faciles à tracer ou à comprendre. Avec le débogueur toutes ces parties deviennent beaucoup plus transparentes et permettent un diagnostic des problèmes plus rapides.
Dans cet article, nous allons dans un premier temps aborder ce que sont les Context et l'OutputDoc, qui sont essentiels dans une application XMLRAD, mais qui auparavant n'étaient pas faciles à comprendre et à suivre. Puis nous montrerons comment utiliser le débogueur dans l'IDE XMLRAD, comment placer dans le code de l'application des points de debug et enfin comment il fonctionne.
Le Context et l'OutputDoc▲
Le Context▲
Le Context est un élément central dans l'architecture d'une application XMLRAD. Toutes les données de l'application transitent dans ce pot de données. C'est une liste d'association de noms et de valeurs. Graphiquement le Context peut être représenté par un tableau :
Clé |
Valeur |
---|---|
Nom |
Bempel |
Prenom |
Jean-Philippe |
ORG_ID |
101 |
Ce context vit tout au long du traitement de la requête. Des valeurs sont ajoutées ou modifiées en fonction des opérations qui sont faites. On l'utilise aussi pour transmettre des paramètres à une requête SQL, les champs d'un formulaire HTML y sont aussi présents et toutes extractions de la base de données passent par le Context. Une explication plus complète de cet objet est faite dans l'article Le Context ou comment transmettre des valeurs d'une page à l'autre.
Malheureusement cela reste un simple objet mémoire, dont il est difficile de voir le contenu à tout moment, même avec un débogueur de code. Et au vu des données qui y transitent, il est impératif de pouvoir connaître en permanence l'état du Context, c'est-à-dire quelles sont les valeurs qui y sont présentes. Le Debugger XMLRAD va nous permettre de suivre les états du Context tout au long du traitement de la requête HTTP.
L'OutputDoc▲
L'OutputDoc est tout simplement le document XML qui va être transformé par la feuille XSL. Toutes les données que l'on veut afficher dans la page HTML doivent être présentent dans ce document. On va y trouver toutes sortes de données. Des données standards du framework comme les XMLC_Params, les Locales et le Profile. Mais surtout les données issues de la base de données, les enregistrements que l"on aura préalablement extraits avec le XMLGram.
voici un exemple d'OutputDoc :
<document>
<XMLC_Params>
<XMLC_Date>
2004/12/22 22:40:07</XMLC_Date>
<XMLC_RequestNo>
13</XMLC_RequestNo>
<XMLC_XMLModule>
PubsWM</XMLC_XMLModule>
<XMLC_Action>
Listpublishers</XMLC_Action>
<XMLC_NavigatorName>
Mozilla</XMLC_NavigatorName>
<XMLC_NavigatorVersion>
5</XMLC_NavigatorVersion>
<XMLC_InstanceName>
Pubs</XMLC_InstanceName>
<XMLC_HTTPS>
0</XMLC_HTTPS>
<XMLC_Host>
amaryl</XMLC_Host>
<XMLC_ScriptName>
/DemosBin/Pubs/Bin/Pubs.dll</XMLC_ScriptName>
<XMLC_InputParams/>
<XMLC_NavigationParams/>
<XMLC_AbsolutePortal>
0</XMLC_AbsolutePortal>
<XMLC_Portal>
SharedPortal</XMLC_Portal>
<XMLC_Skin>
graylight</XMLC_Skin>
<XMLC_Pictos>
msn</XMLC_Pictos>
<XMLC_TrapJavascriptError/>
<XMLC_DisplayTabControl>
1</XMLC_DisplayTabControl>
<XMLC_DisplayTabs>
1</XMLC_DisplayTabs>
<XMLC_DisplayToolbar>
0</XMLC_DisplayToolbar>
<XMLC_DisplayPageTitle>
1</XMLC_DisplayPageTitle>
<XMLC_DisplayActionMenu>
0</XMLC_DisplayActionMenu>
<XMLC_DisplayButtonRollover>
1</XMLC_DisplayButtonRollover>
<XMLC_DisplayToolbarRollover>
1</XMLC_DisplayToolbarRollover>
<XMLC_Culture>
EN</XMLC_Culture>
<XMLC_Language>
FRANCAIS</XMLC_Language>
<XMLC_UserID>
1003</XMLC_UserID>
<XMLC_UserName>
supervisor@mycorp.com</XMLC_UserName>
<XMLC_Authenticated>
0</XMLC_Authenticated>
<XMLC_Administrator>
1</XMLC_Administrator>
<XMLC_Supervisor>
1</XMLC_Supervisor>
<XMLC_User>
1</XMLC_User>
<XMLC_Guest>
0</XMLC_Guest>
<XMLC_PoweredBy>
Powered by XMLRAD</XMLC_PoweredBy>
<XMLC_RegisteredEmail>
jpbempel@fr.delos.us</XMLC_RegisteredEmail>
<XMLC_RegisterURL>
http://e-delos.com/index.html?http://e-delos.com/DownloadBin/Download.dll/</XMLC_RegisterURL>
<XMLC_ProductName>
XMLRAD</XMLC_ProductName>
<XMLC_OptionMail>
1</XMLC_OptionMail>
<XMLC_OptionMessenger>
1</XMLC_OptionMessenger>
</XMLC_Params>
<publishersS
EOF
=
"1"
StartingRow
=
"0"
LastRow
=
"7"
RowCount
=
"8"
MaxRows
=
"10"
RecordName
=
"publishers"
>
<publishers>
<pub_id>
0736</pub_id>
<pub_name>
New Moon Books</pub_name>
<city>
Boston</city>
</publishers>
<publishers>
<pub_id>
0877</pub_id>
<pub_name>
Binnet &
Hardley</pub_name>
<city>
Washington</city>
</publishers>
<publishers>
<pub_id>
1389</pub_id>
<pub_name>
Algodata Infosystems</pub_name>
<city>
Berkeley</city>
</publishers>
<publishers>
<pub_id>
1622</pub_id>
<pub_name>
Five Lakes Publishing</pub_name>
<city>
Chicago</city>
</publishers>
<publishers>
<pub_id>
1756</pub_id>
<pub_name>
Ramona Publishers</pub_name>
<city>
Dallas</city>
</publishers>
<publishers>
<pub_id>
9901</pub_id>
<pub_name>
GGG&G</pub_name>
<city>
München</city>
</publishers>
<publishers>
<pub_id>
9952</pub_id>
<pub_name>
Scootney Books</pub_name>
<city>
New York</city>
</publishers>
<publishers>
<pub_id>
9999</pub_id>
<pub_name>
Lucerne Publishing</pub_name>
<city>
Paris</city>
</publishers>
</publishersS>
<XMLC_Profile>
<XMLC_ProfileName>
Standard</XMLC_ProfileName>
<XMLC_ActionMenuPosition>
LEFT</XMLC_ActionMenuPosition>
<XMLC_Culture>
EN</XMLC_Culture>
<XMLC_DisplayActionMenu>
0</XMLC_DisplayActionMenu>
<XMLC_DisplayButtonPad>
1</XMLC_DisplayButtonPad>
<XMLC_DisplayButtonRollover>
1</XMLC_DisplayButtonRollover>
<XMLC_DisplayHeaderGradient>
0</XMLC_DisplayHeaderGradient>
<XMLC_DisplayPageTitle>
1</XMLC_DisplayPageTitle>
<XMLC_DisplayTabControl>
1</XMLC_DisplayTabControl>
<XMLC_DisplayTabs>
1</XMLC_DisplayTabs>
<XMLC_DisplayToolbar>
0</XMLC_DisplayToolbar>
<XMLC_DisplayToolbarButtonPad>
0</XMLC_DisplayToolbarButtonPad>
<XMLC_DisplayToolbarGradient>
0</XMLC_DisplayToolbarGradient>
<XMLC_DisplayToolbarRollover>
1</XMLC_DisplayToolbarRollover>
<XMLC_Language>
FRANCAIS</XMLC_Language>
<XMLC_MainAction/>
<XMLC_MenuWidth>
300</XMLC_MenuWidth>
<XMLC_Pictos>
msn</XMLC_Pictos>
<XMLC_Skin>
graylight</XMLC_Skin>
<TreeviewStyle>
XP</TreeviewStyle>
<DisplayPageTitle>
0</DisplayPageTitle>
</XMLC_Profile>
<Aliases>
<PubsDLL>
/DemosBin/Pubs/Bin/Pubs.dll/</PubsDLL>
<XMLRADDLL>
/XMLRADBin/XMLRAD.dll/</XMLRADDLL>
</Aliases>
<Locales>
<New>
Nouveau</New>
<publishers>
Editeurs</publishers>
<pub_name>
Editeur</pub_name>
<city>
Ville</city>
<Listpublishers>
Editeurs</Listpublishers>
<DataGridpublishers>
Grille des éditeurs</DataGridpublishers>
<Searchpublishers>
Recherche éditeurs</Searchpublishers>
<ListpublishersTitle>
Liste éditeurs</ListpublishersTitle>
<Done>
Sauvegarder et archiver l'événement</Done>
<Save>
Sauvegarder</Save>
<Permissions>
Permissions</Permissions>
<Submit>
Valider</Submit>
<Reset>
Réinitialiser</Reset>
<Refresh>
Rafraîchir</Refresh>
<Delete>
Supprimer</Delete>
<DoublePrevious>
2 pages en arrière</DoublePrevious>
<Previous>
Page précédente</Previous>
<More>
Page suivante</More>
<DoubleMore>
2 pages en avant</DoubleMore>
<ShowHideActionMenu>
Afficher / Masquer le menu action</ShowHideActionMenu>
<errorMessageNotNull>
Ce champ doit être saisi : </errorMessageNotNull>
<questionDeleteRecordBegin>
Etes vous sûr de vouloir supprimer ce </questionDeleteRecordBegin>
<questionDeleteRecordEnd>
?\nCliquez OK pour confirmer.</questionDeleteRecordEnd>
<DeletePrompt>
Etes vous sûre de vouloir supprimer cet élément ?</DeletePrompt>
<AltEmail>
Envoyer cette page par e-mail</AltEmail>
<AltFax>
Faxer le document attaché </AltFax>
<AltIM>
Envoyer cette page par message instantané</AltIM>
<AltPrint>
Imprimer cette page</AltPrint>
<AltHome>
Accueil</AltHome>
<AltHelp>
Aide</AltHelp>
<AltLogin>
Login</AltLogin>
<AltLogout>
Logout</AltLogout>
<AltOpenThisActionInXMLRAD>
Ouvrir XMLRAD</AltOpenThisActionInXMLRAD>
<AltRefresh>
Rafraîchir</AltRefresh>
<AltXMLOutputFormat>
Afficher le document XML</AltXMLOutputFormat>
<PublishersActionTitle>
Editeurs</PublishersActionTitle>
<ListpublishersAction>
Liste éditeurs</ListpublishersAction>
<DataGridpublishersAction>
Edition éditeurs</DataGridpublishersAction>
<SearchFormpublishersAction>
Recherche éditeur</SearchFormpublishersAction>
<FormCreatepublishersAction>
Nouvel éditeur</FormCreatepublishersAction>
<TitlesActionTitle>
Livres</TitlesActionTitle>
<ListtitlesAction>
Liste livres</ListtitlesAction>
<DataGridtitlesAction>
Edition livres</DataGridtitlesAction>
<SearchFormtitlesAction>
Recherche livre</SearchFormtitlesAction>
<FormpublishersAction>
Edition éditeur</FormpublishersAction>
</Locales>
</document>
De même, l'OutputDoc est seulement une représentation mémoire. Au mieux on peut obtenir ce document final et éviter la transformation XSL, en passant le paramètre HTTP XMLC_OutputFormat=XML, qui permet de visualiser le document ci-dessus dans son navigateur. Le Debugger XMLRAD va nous permettre de suivre la construction du document OutputDoc au fur et à mesure du traitement de la requête dans le framework.
Le débogueur XMLRAD▲
Utilisation▲
Nous allons tout d'abord déboguer une WebForm assez simple et classique de la demo Training : FormSearchORGANIZATION. Pour cela nous allons procéder aux étapes suivantes :
- dans les InitParams, mettre le paramètre XMLC_Debug à 1 ;
- dans l'écran de configuration de FormSearchORGANIZATION, on coche la case Debug ;
- lancez l'application et exécutez FormSearchORGANIZATION. Les informations de débogage sont alors générées dans le répertoire c:\Program Files\e-delos\Demos\Training\Data\Debug\FormSearchORGANIZATION. L'exécution en est un peu plus longue ;
- revenez sur l'écran de configuration du XMLService et cliquez sur View Last Debug pour visualiser les informations de debug précédemment générées.
Vous vous retrouvez avec les étapes de l'exécution du XMLService sous forme d'un arbre. En bas vous avez l'état du Context courant et à droite le document OutputDoc. Par défaut, les vues du Context et L'OutputDoc ne montrent que les informations (en gras) qui ont changé par rapport à l'étape précédente. Ceci permet de se concentrer seulement sur les valeurs qui ont été modifiées par le traitement de l'étape (ou Step). Dans l'exemple ci-dessus, on se trouve à l'étape BeforeInternalInstruction de l'instruction DBExtract ORGANIZATION. On voit que de nouvelles valeurs ont été insérées dans le Context. Celles-ci proviennent de l'extraction de la base de données de l'enregistrement (Fetch). Dans L'OutputDoc un nœud conteneur ORGANIZATIONS vient d'être rajouté dans lequel on aura la liste des enregistrements.
En cliquant sur « Show/Hide Context Delta », vous pourrez voir non seulement les dernières valeurs modifiées, mais aussi toutes les valeurs contenues dans le Context. De la même manière avec L'OutputDoc en cliquant sur « Show/Hide OutputDoc Delta ».
Il vous est possible de suivre une ou plusieurs valeurs en permanence tout au long de votre débogage en ajoutant un « context watch » ou en cliquant sur la case à cocher qui se trouve en face de la valeur.
Dans l'exemple précédent, nous n'avons que l'exécution du XMLService FormSearchORGANIZATION, puisque nous avons coché la case debug qui indique que lors d'une exécution normale, lorsque l'on exécutera FormSearchORGANIZATION, celui-ci générera des informations de débogage. Or, on aimerait bien débogueur le dispatch de la requête, la vérification d'authentification, bref l'ensemble de la chaine de traitement et non pas seulement le XMLService. Pour cela nous devons utiliser l'option « Debug XMLService » de l'écran de configuration de FormSearchOrganization. Cette option lance une exécution cachée du XMLService avec les valeurs de paramètres fixés à la conception dans XMLRAD.
Nous pouvons alors voir tout le processus depuis l'arrivée de la requête HTTP jusqu'à son traitement dans le XMLService. Dans l'exemple ci-dessus, on peut ainsi voir les valeurs des cookies qui sont transmis par la requête et bien sûr ajoutées dans le Context. On va pouvoir faire de même avec les HTTPParams, utile par exemple pour voir si la validation d'un formulaire POST contient bien toutes les valeurs dont on a besoin.
Qu'en est-il du code que l'on peut mettre dans les gestionnaires d'événement ? Le débogueur de XMLRAD va pouvoir aussi détecter le changement dans le Context avant et après l'exécution d'un gestionnaire d'événement. Nous allons par exemple implémenter dans le langage que vous voulez, un BeforeXMLGram sur FormSearchORGANIZATION. Ici je vais le faire en Delphi :
procedure
TTrainingWM.FormSearchORGANIZATIONBeforeXMLGram(XMLGram: IXMLGram; e: TBeforeXMLGramEventArgs);
begin
Context.SetValue('MyValue'
, 'toto'
);
e.OutputDoc.AppendChild('MyXMLValue'
, Context.GetValue('MyValue'
));
end
;
private
void
FormSearchORGANIZATION_BeforeXMLGram
(
XMLCLX.
IXMLGram XMLGram,
XMLComponent.
TBeforeXMLGramEventArgs e)
{
Context.
SetValue
(
"MyValue"
,
"toto"
);
e.
OutputDoc.
AppendChild
(
"MyXMLValue"
,
Context.
GetValue
(
"MyValue"
));
}
public
void
FormSearchORGANIZATION_BeforeXMLGram
(
XMLGram xmlGram, XMLComponent.BeforeXMLGramEventArgs e)
{
context.setValue
(
"MyValue"
, "toto"
);
e.outputDoc.appendChild
(
"MyXMLValue"
, context.getValue
(
"MyValue"
));
}
Si nous déboguons à nouveau notre XMLService nous obtenons :
Une nouvelle item est apparue indiquant que le gestionnaire d'événement BeforeXMLGram contient du code. En cliquant dessus, le débogueur affiche les valeurs qui ont été modifiées par rapport à l'état précédent l'exécution du gestionnaire. On peut donc voir que j'ai rajouté une nouvelle valeur dans le context et une autre dans l'OutputDoc.
Cependant il se peut que le code du BeforeXMLGram soit très long avec pas mal de traitement. Ici on ne pourra voir que le résultat de ce traitement et non pas les étapes intermédiaires. Pour résoudre ce problème et avoir une vue plus fine, on va introduire de nouveaux steps dans le code en utilisant la méthode XMLRequest.DebugSimple.
procedure
TTrainingWM.FormSearchORGANIZATIONBeforeXMLGram(XMLGram: IXMLGram; e: TBeforeXMLGramEventArgs);
var
XMLRequest2: IXMLRequest2;
begin
XMLRequest2 := IXMLRequest2(XMLRequest);
Context.SetValue('MyValue'
, 'toto'
);
XMLRequest2.DebugSimple('MyDebugPoint1'
, e.OutputDoc, nil
);
Context.SetValue('MyValue'
, 'toto2'
);
XMLRequest2.DebugSimple('MyDebugPoint2'
, e.OutputDoc, nil
);
Context.SetValue('MyValue'
, 'toto3'
);
XMLRequest2.DebugSimple('MyDebugPoint3'
, e.OutputDoc, nil
);
e.OutputDoc.AppendChild('MyXMLValue'
, Context.GetValue('MyValue'
));
end
;
private
void
FormSearchORGANIZATION_BeforeXMLGram
(
XMLCLX.
IXMLGram XMLGram,
XMLComponent.
TBeforeXMLGramEventArgs e)
{
StdXMLC.
XMLRequest2 XMLRequest2 =
(
IXMLRequest2) XMLRequest;
Context.
SetValue
(
"MyValue"
,
"toto"
);
XMLRequest2.
DebugSimple
(
"MyDebugPoint1"
,
e.
OutputDoc,
null
);
Context.
SetValue
(
"MyValue"
,
'toto2'
);
XMLRequest2.
DebugSimple
(
"MyDebugPoint2"
,
e.
OutputDoc,
null
);
Context.
SetValue
(
"MyValue"
,
"toto3"
);
XMLRequest2.
DebugSimple
(
"MyDebugPoint3"
,
e.
OutputDoc,
null
);
e.
OutputDoc.
AppendChild
(
"MyXMLValue"
,
Context.
GetValue
(
"MyValue"
));
}
public
void
FormSearchORGANIZATION_BeforeXMLGram
(
XMLGram xmlGram, XMLComponent.BeforeXMLGramEventArgs e)
{
context.setValue
(
"MyValue"
, "toto"
);
xmlRequest.debugSimple
(
"MyDebugPoint1"
, e.OutputDoc, null
);
context.setValue
(
"MyValue"
, 'toto2'
);
xmlRequest.debugSimple
(
"MyDebugPoint2"
, e.OutputDoc, null
);
context.setValue
(
"MyValue"
, "toto3"
);
xmlRequest.debugSimple
(
"MyDebugPoint3"
, e.OutputDoc, null
);
e.outputDoc.appendChild
(
"MyXMLValue"
, context.getValue
(
"MyValue"
));
}
Dans l'exemple ci-dessus, on modifie plusieurs fois la valeur MyValue.
Si dans un gestionnaire d'événement ou dans le XMLGram on invoque un autre XMLService, le débogueur va aussi afficher le détail de l'exécution de ce dernier.
Fonctionnement du débogueur▲
Nous allons maintenant entrer un peu plus profondément dans le débogueur et surtout dans les informations de debug qui sont générées et qui vont permettre la visualisation.
Si on reprend le premier débogage de l'action FormSearchORGANIZATION, les informations de débogage vont être générées pendant l'exécution, dans le répertoire C:\Program Files\e-delos\Demos\Trainig\Data\Debug\FormSearchORGANIZATION.
Dans ce répertoire on retrouve une centaine de fichiers XML :
- 1.Context.xml
- 2.Context.xml
- 3.Context.xml
- 3.OutputDoc.xml
- 4.Context.xml
- …
- 45.Context.xml
- 45.OutputDoc.xml
- 46.Context.xml
- 47.Context.xml
- 48.Context.xml
- 49.Context.xml
- Debug.xml
Pour chaque étape, l'état complet du Context est enregistré dans un fichier XML. Lorsque pour une étape, l'OutputDoc est modifié, on a également son état qui est stocké. Le fichier Debug.xml contient les informations de structure des étapes et la liste de toutes les étapes.
Dans le fichier Debug.xml, on a tout d'abord la stack qui représente la pile d'exécution, avec l'imbrication (structure) des steps. Elle fait référence aux steps qui sont listés à plat à la suite du fichier.
le débogueur de XMLRAD s'appuie donc sur ce fichier pour la visualisation et calcule pour chaque step, la différence entre les valeurs du Context du step précédent et celles du step courant. Le résultat de cette différence est affiché en gras dans le débogueur. De même pour l'OutputDoc.
Le fait d'appeler la méthode DebugSimple dans notre gestionnaire d'événement crée une étape supplémentaire et génère sur disque un fichier contenant toutes les valeurs du Context au moment de l'appel et éventuellement un OutputDoc.
Conclusion▲
Après avoir décrit le Context et l'OutputDoc, nous avons vu comment utiliser le débogueur XMLRAD 2005 dans une application simple et comment l'utiliser avec des gestionnaires d'événements. Puis nous avons expliqué son fonctionnement.
Cette nouveauté de XMLRAD 2005 permet de maintenant diagnostiquer de façon plus rapide et transparente les erreurs que l'on pourrait commettre lors du développement d'application: oublie de déclaration d'un HTTP Params, voir si les cookies sont bien passés, erreur de nommage de valeurs dans le Context, etc. Il apporte donc un gain de productivité dans le développement d'application Web avec XMLRAD.