Introduction

Une des grandes nouveautés de XMLRAD 2005 c'est le debugger intégré. C'est un debugger 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 debugger est une aubaine pour les développeurs XMLRAD, car certaines parties de l'exécution de l'application à la charge du framework n'était pas facile à tracer ou à comprendre. Avec le debugger toutes ces parties deviennent beaucoup plus transparentes et permettent un disgnostic 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 facile à comprendre et à suivre. Puis nous montrerons comment utiliser le debugger 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 debugger 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 quelle 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:

 
Sélectionnez

<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 debugger XMLRAD

Utilisation

Nous allons tout d'abord debugger 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écuter FormSearchORGANIZATION. Les informations de débuggage 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.
Image non disponible

Vous vous retrouvez avec les étapes de l'exécution du XMLService sous forme d'un arbre. En bas vous avez l'etat 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ées 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 noeud 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 debuggage en ajoutant un "context watch" ou en cliquant sur la case à cocher qui se trouve en face de la valeur.

Image non disponible

Dans l'exemple précédent nous n'avons que l'execution du XMLService FormSearchORGANIZATION, puisque nous avons coché la case debug qui indique que lors d'une execution normale, lorsque l'on executera FormSearchORGANIZATION, celui-ci générera des informations de debuggage. Or, on aimerait bien debugguer 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.

Image non disponible

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 transmises par la requête et bien sûr ajoutée 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 debugger de XMLRAD va pouvoir aussi détecter le changement dans le Context avant et après l'execution 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:

Delphi
Sélectionnez

procedure TTrainingWM.FormSearchORGANIZATIONBeforeXMLGram(XMLGram: IXMLGram; e: TBeforeXMLGramEventArgs);
begin
  Context.SetValue('MyValue', 'toto');
  e.OutputDoc.AppendChild('MyXMLValue', Context.GetValue('MyValue'));
end;
C#
Sélectionnez

private void FormSearchORGANIZATION_BeforeXMLGram(XMLCLX.IXMLGram XMLGram, XMLComponent.TBeforeXMLGramEventArgs e)
{
  Context.SetValue("MyValue", "toto");
  e.OutputDoc.AppendChild("MyXMLValue", Context.GetValue("MyValue"));
}
Java
Sélectionnez

public void FormSearchORGANIZATION_BeforeXMLGram(XMLGram xmlGram, XMLComponent.BeforeXMLGramEventArgs e)
{
  context.setValue("MyValue", "toto");
  e.outputDoc.appendChild("MyXMLValue", context.getValue("MyValue"));
}

Si nous debuggons a nouveau notre XMLService nous obtenons:

Image non disponible

Une nouvelle item est apparue indiquant que le gestionnaire d'événement BeforeXMLGram contient du code. En cliquant dessus, le debugger 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.

Delphi
Sélectionnez

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;
C#
Sélectionnez

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"));
}
Java
Sélectionnez

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.

Image non disponible

Si dans un gestionnaire d'événement ou dans le XMLGram on invoque un autre XMLService, le debugger va aussi afficher le détail de l'exécution de ce dernier.

Fonctionnement du Debugger

Nous allons maintenant entrer un peu plus profondément dans le debugger et surtout dans les informations de debugs qui sont générées et qui vont permettre la visualisation.

Si on reprend le premier debuggage de l'action FormSearchORGANIZATION, les informations de debuggage 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.

Image non disponible

le debugger 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 debugger. 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 debugger 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 commetre 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.