Tags:
create new tag
, view all tags

Quelques notes importantes sur les changements effectués ou à faire

Etat d'avancement au 07/08/09

Ce qui fonctionne à l'heure actuelle:
  • on peut passer les urls fits et votable en utilisant une url de la forme http://server/SimPlay.html#mode=generic&fits=http://.../fits&votable=http://.../votable (cf 3. Passer l'url d'un FITS et d'un VOTable)
  • le mode générique récupère les urls, les passe à un CGI (fictif pour le moment), et récupère un xml de description classique
  • le mode générique modifie le comportement graphique de SimPlay par défaut en supprimant les panneaux droit et gauche (cf 2. Permettre de supprimer les panneaux de l'application)
  • le parsing récupère dans un premier temps les champs ayant ID=X et ID=Y. On récupère ensuite tous les fields contenant un UCD (et n'ayant pas ID=X et ID=Y pour ne pas avoir de doublons dans le cas ou un field serait défini, par exemple, par ID=X et UCD=X). Ceci pose des problèmes parce que l'UCD n'est pas unique (cf 4. Parsing d'un VOTable générique, problème de doublons)
  • on affiche dans le tableau tous les champs récupérés lors du parsing
  • on affiche dans les toolips les données correspondant au nom (si existe), au type (si existe), ra et dec (considérés comme obligatoire)
  • un type graphique générique a été défini: toutes les données se dessinent sur l'image selon un seul et même type graphique, on considère tous les objets contenus dans le VOTable comme appartenant au même type d'objet
  • SimPlay peut être embarqué dans des pages hébergés sur d'autres serveurs, mais il y a quelques limitations (cf 1. Permettre d'embarquer facilement l'application dans une page quelconque)
Ce qui reste à faire:
  • gérer le passage de paramètres via les flashVars [OK]
  • gérer les types des données du VOTable générique (pour le moment, on considère toutes les données comme étant de type String), ce qui permettrait de définir les tris (numérique ou alphabétique) au niveau du tableau des données [OK]
  • définir comment récupérer les fields du VOTable de manière unique et fiable [OK]
    -> On identifie les champs X et Y par l'attribut ID, et les champs RA, DEC, mainId et OType par l'attribut ucd. Si ucd n'est pas présent, on prend comme valeur une chaine de caractères vide. Les noms des colonnes du tableau de données sont identifiés par l'attribut name ou, le cas échéant, par l'attribut ID. Si name et ID sont absent, on génère dynamiquement un nom de la forme 'field_x' avec x étant la position de la colonne dans le tableau (de gauche à droite).
  • faire plusieurs tests avec des fits et votable variés pour tester le comportement du mode générique
Urls de test:
1. Permettre d'embarquer facilement l'application dans une page quelconque

Il est possible d'incorporé l'application SimPlay au sein d'une page quelconque sous certaines conditions:
  • il doit être inclus une portion de code javascript: il s'agit des scripts permettant de gérer la molette de la souris sous Mac et de forcer le navigateur à donner le focus à l'application Flex (partiellement fonctionnel, dépend des navigateurs)
  • dans le but de ressembler le plus possible au genre de code que l'on retrouve sur youTube par exemple, toute la partie javascript qui permet de tester l'existence sur le client du Flash Player n'est pas présente (mais rien n'empêche de l'ajouter, cela alourdi juste le code à insérer).

Exemple fonctionnel de code à insérer (version simplifiée):

  • 1ère partie: dans le head
          <script src="http://192.168.0.12/dev/SimPlay/script/js/extMouseWheel.js" language="javascript"></script>
          <script src="http://192.168.0.12/dev/SimPlay/script/js/manageFocus.js" language="javascript"></script>
       
  • 2ème partie: dans le body
         <div style="width:100%; height:100%;" id="flexContainerDiv">
           <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="SimPlay" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
             <param name="movie" value="SimPlay.swf" />
             <param name="quality" value="high" />
             <param name="bgcolor" value="#869ca7" />
             <param name="allowScriptAccess" value="always" />
             <param name="flashVars" value="imgurl=http://truc.fr/img.fits&votableurl=http://truc.fr/votable.xml" />
             <embed src="http://192.168.0.12/dev/SimPlay/SimPlay.swf" flashVars="imgurl=http://truc.fr/img.fits&votableurl=http://truc.fr/votable.xml" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="SimPlay" align="middle" play="true" loop="false" quality="high" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" />
           </object>
         </div>
       

Exemple fonctionnel de code à insérer (version complète):
  • 1ère partie: dans le head
         <script src="http://192.168.0.12/dev/SimPlay/script/js/extMouseWheel.js" language="javascript"></script>
         <script src="http://192.168.0.12/dev/SimPlay/script/js/manageFocus.js" language="javascript"></script>
         <script src="http://192.168.0.12/dev/SimPlay/AC_OETags.js" language="javascript"></script>
         <script src="http://192.168.0.12/dev/SimPlay/history/history.js" language="javascript"></script>
         <script language="JavaScript" type="text/javascript">
           <!--
           // Globals
           // Major version of Flash required
           var requiredMajorVersion = 9;
           // Minor version of Flash required
           var requiredMinorVersion = 0;
           // Minor version of Flash required
           var requiredRevision = 28;
           // -->
         </script>
       
  • 2ème partie: dans le body
       <script language="JavaScript" type="text/javascript">
       <!--
          // Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
          var hasProductInstall = DetectFlashVer(6, 0, 65);
          
          // Version check based upon the values defined in globals
          var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
          
          //alternative text in case of no player or bad player version installed 
          var alternateContent = '<div style="padding:40px"><b><font size=4>The Flash Player was not found on your system or you have an old version.</font></b></br></br>'
                         + 'This application requires the Adobe Flash Player 10 (highly recomanded). It can be also run with the Adobe Flash Player 9, but it\'s depreciated. '
                         + '<a href=http://www.adobe.com/go/getflash/>Please, get the last version of Flash Player.</a>'
                         + '</br></br>'
                         + 'If you cannot or don\'t want to install Flash Player plugin, you can try a standalone version by downloading a package including external flash player for your system. '
                         + 'You can <a href="http://get.adobe.com/flashplayer/">download it</a> by choosing your package.</br></br></div>';
                         
          if(!hasRequestedVersion || !hasProductInstall) 
          {
             document.write(alternateContent);
          }
          else
          {
             var imgurl = "http://truc.fr/img.fits";
             var votableurl = "http://truc.fr/votable.xml";
             var flexContent = '<div style="width:100%; height:100%;" id="flexContainerDiv">'
                         +  '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="SimPlay" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">'
                         +  '<param name="movie" value="SimPlay.swf" />'
                         +  '<param name="quality" value="high" />'
                         +  '<param name="bgcolor" value="#869ca7" />'
                         +  '<param name="allowScriptAccess" value="always" />'
                         +  '<param name="flashVars" value="imgurl='+imgurl+'&votableurl='+votableurl+'" />'            
                         +  '<embed src="http://192.168.0.12/dev/SimPlay/SimPlay.swf" flashVars="imgurl='+imgurl+'&votableurl='+votableurl+'" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="SimPlay" align="middle" play="true" loop="false" quality="high" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" />'
                         +  '</object>'
                         + '</div>';
       
             document.write(flexContent);
          }
       // -->
       </script>
       

Petites remarques

  • On remarque au passage qu'il est plus pratique et plus lisible de passer des paramètres à l'application via les flashVars dans le second cas: elles ne sont à déclarer qu'une seule fois dans des variables javascript. Dans la version simplifiée qui n'utilise pas de javascript pour incorporer l'objet embed, li faut les saisir "en dur", dans les balises embed et object. Le passage des paramètres via les flashVars n'a pas encore été testé (il s'agit d'un autre point à voir plus tard), il est possible que l'utilisation de javascript soit inévitable afin d'encoder les urls qui seront passées en paramètres, à voir.
  • L'url du serveur hébergeant SimPlay doit être inscrite en dur dans le code (pour référencer le swf et les scripts js). On peut facilement imaginer un script php ou autre qui permettrait de générer automatiquement le code à insérer. On pourrait alors changer l'application de serveur sans avoir à modifier l'url en dur dans le code à incorporer. Cependant, les pages qui incorporerait ce code avant changement de serveur ne fonctionneraient plus...
  • L'attribut allowScriptAccess="always" est extrêmement important, il permet à l'application Flex d'exécuter des scripts javascript déclarés dans la page qui incorpore l'application. Si cet attribut n'est pas présent, l'application retourne une erreur "Violation access sandbox".
  • La page embarquant l'application doit obligatoirement se trouver sur un serveur. Dans le cas contraire, c'est-à-dire si j'exécute ma page en ouvrant directement le fichier dans mon navigateur, l'application retourne une erreur "SecurityError: Error #2060: Violation de la sécurité Sandbox". Cette erreur est logique car l'application (distante) tente d'exécute des scripts javascript contenus dans "file:///home/utilisateur/maPage.html", et les règles de sécurité du Flash Player empêche d'accéder aux ressources de la machine du client.
  • Une page embarquant SimPlay peut initialiser l'application via des paramètres dans l'url seulement si la page inclut le javascript history.js. Dans tous les cas, un changement des paramètres dans l'url sans recharger la page n'aura aucun effet: il faut recharger la page pour que le navigateur passe les paramètres au swf.

Questions

  • quels sont les paramètres que l'on peut passer via flashVars? Uniquement urlfits et urlvotable, ou bien également une target et les paramètres de recherche et d'affichage de l'interface graphique? [OK]
    -> les mêmes paramètres que ceux qu'on passe par url
  • ces paramètres peuvent-ils/doivent-ils être sur-définis par un passage par url? [OK]
    -> Si des paramètres sont passés par flashVars, on ne prend pas en compte les paramètres passés par url

Les changements côté simPlay: modification de la manière dont SimPlay accède aux ressources (ex: le fichier de conf)

Un cas d'utilisation pour illustrer: Nous disposons de 3 serveurs: server1, server2, et server3.
  • server1 héberge l'application SimPlay.
  • server2 héberge les données dont à besoin SimPlay. Pour permettre au Flash Player d'accéder à ces données, il faut insérer, à la racine de server2 (localisation par défaut), un fichier crossdomain.xml. Ce fichier déclare les serveurs autorisés à accéder à ses ressources.
  • server3 héberge une page html, simplayEmbedded.html qui incorpore l'application distante SimPlay dont l'url d'accès est http://server1/simplay/SimPlay.swf

Lorsqu'on exécute simplayEmbedded.html, l'application http://server1/simplay/SimPlay.swf se charge. L'application tente alors de charger /config/web-conf.xml ("/config/web-conf.xml" est spécifié en dur dans le code) pour s'initialiser et charger les urls des différentes ressources nécessaires. simplayEmbedded.html étant hébergé sur server3, l'application recherche /config/web-conf.xml sur server3, et bien évidemment ne le trouve pas. Idem avec tous les autres fichiers de configuration de l'application. L'idée est donc de passer à SimPlay l'url complète d'accès aux ressources de configuration. Coder en dur dans le code l'url du serveur est une très mauvaise idée pour 3 raisons:

  • si l'application vient à changer de serveur, il faudrait recompiler le swf
  • la modification devrait également être répercutée dans le fichier web-conf.xml pour langListLocation et thumbnailLocation, et toutes les entrées de exampleList.xml devraient aussi être modifier, ce qui est assez lourd en terme de maintenance
  • l'application en mode offline ne doit pas aller chercher les ressources sur http://server1/simplay/config mais bien en local sur /config/.
La solution a donc été de récupérer dynamiquement par SimPlay l'url complète du serveur qui héberge le swf (soit http://server1/simplay/), et, selon le mode de connexion (online/offline), on rajoute dynamiquement "http://server1/simplay" ou non à la localisation des ressources (à savoir "config/"). De la même manière, lors du parsing de exampleList.xml, on ajoute ou non l'url des ressources distantes. Ceci implique par contre que les ressources contenues dans exampleList.xml doivent impérativement se trouver dans le même domaine que l'application: imaginons que nous sommes en mode online, et que exampleList.xml contient la ligne suivante <image target="M 1" thumbnail="http://server4/config/thumbnails/M1.png"/>. Dans ce cas, au moment du parsing, l'adresse du thumbnail pour M1 deviendrait "http://server1/simplay/http://server4/config/thumbnails/M1.png".

Ce problème de localisation des ressources ne se posait pas avant, puisque la page qui embarque SimPlay se situe dans le domaine que l'application elle-même.


2. Permettre de supprimer les panneaux de l'application

Il est désormais possible de ne pas afficher sur l'application un ou plusieurs de ses panneaux. Cette fonctionnalité s'utilise à travers les paramètres passés dans l'url. Jusqu'ici, il était possible de forcer l'interface graphique à afficher tel ou tel panneau (sur-défini par défaut, dans ce cas, les règles des préférences) via les paramètres d'url lp, rp, et bp, qui pouvaient prendre comme valeur "true" ou "false". Désormais ces attributs peuvent prendre comme valeur "rm", qui permet de ne pas afficher le panneau sur l'interface graphique. Attention: il est nécessaire de préciser que les panneaux n'apparaissent plus mais sont toujours présents en mémoire et connus de l'application. Ainsi il est possible, pendant l'exécution, de changer un paramètre de l'url pour ré-afficher le panneau manquant. Il est également possible de sur-définir le comportement en passant par un changement au niveau des préférences utilisateur.

Exemple d'utilisation: http://serveur/SimPlay.html#lp=false&rp=rm&bp=true&target=m51


3. Passer l'url d'un FITS et d'un VOTable à http://cdsweb.../SimPlayGeneric

On peut avoir une page embarquant SimPlay et qui se nommerait "SimPlayGeneric", mais elle référencerait toujours simplay.swf. Je vois dans cas plusieurs solutions:

  1. ajouter un attribut "mode=generic" dans l'url: http://serveur/simPlayGeneric.html#mode=generic&urlfits=...&urlvotable=... (ce qui revient exactement au même que d'avoir .../SimPlay.html#mode=generic&urlfits=...&urlvotable=...
  2. avoir deux swf différents, mais ce n'est pas terrible point de vue maintenance du code
  3. faire de SimPlayGeneric une page PHP et passer urlfits et urlvotable à cette page PHP, laquelle générerait un rendu html embarquant SimPlay et passant les 2 urls à SimPlay via flashVars (cf 1. de cette page).
  4. déléguer le passage des urls à un script php qui s'occuperait de charger SimPlay en lui passant directement l'url du fichier de description généré par le CGI (un peu similaire au point 3).
  5. ajouter une option, permettant de saisir, via l'interface graphique de SimPlay les deux urls.

Je pense que la première solution correspond le mieux aux attentes: un seul swf et le travail de chargement des urls n'est pas délégué à un script extérieur.

  • Si l'url d'appel a SimPlay est de la forme http://serveur/SimPlay.html#mode=generic, on entre en mode générique, dans ce cas la présence ou non de l'attribut "target" dans l'url n'a pas d'incidence, elle est ignorée, le mode générique primant sur la target. Si l'attribut mode prend une autre valeur ou est laissé vide, et qu'un attribut target est présent, dans ce cas la target est prise en compte et les données du mode générique sont ignorées (les deux urls). En conclusion, dès que mode=generic, target est ignorée.
  • Si l'url d'appel a SimPlay est de la forme http://serveur/SimPlay.html#mode=generic&fits=http://.../imgfits&votable=http://.../votable, on vérifie que les attributs fits et votable n'ont pas été laissés vide. Dans ce cas on considère le mode générique comme étant valide, et on force l'application à ne pas afficher les panneaux de droite et de gauche. Tous les paramètres décrivant l'interface graphique présents dans l'url sont alors ignorés. Si au moins un attribut est invalide, on laisse l'interface graphique dans son état avant le passage des paramètres du mode générique. Si un paramètre décrivant l'interface est présent dans l'url (ex: lp=false), dans ce cas ce paramètre sera appliqué.

Questions:
4. Parsing d'un VOTable générique

Lors du parsing, on crée désormais un identifiant unique, "objectId", que l'on associe à chaque objet. C'est également valable pour le mode classique. Ainsi un objet n'est plus référencé par son "mainId" (qui peut ne pas exister en mode générique). Ceci à nécessité des modifications au niveau du tableau des données. Il y a maintenant une colonne, invisible, dans laquelle est contenue l'objectId de chaque objet, ce qui permet de retrouver l'objet lorsque l'on clique sur sa ligne correpondante dans le tableau, ou bien inversement, de retrouver la ligne correspondant à l'objet cliqué.

Questions:
  • Etant donné que l'on ne connait pas les données, que doit-on afficher dans le tableau des données? [OK]
    • est-ce que l'on se base sur le modèle défini pour un VOTable "classique", c'est-à-dire on recherche dans le VOTable les données correspondant aux champs OTYPE, MAIN_ID, RA, DEC, etc... Dans ce cas il faudrait savoir pour chaque donnée la manière dont elle définie (ex: ucd="pos.eq.ra;..." pour RA, etc.). Si elles existent alors on les affiche sinon on laisse vide la colonne correpondante dans le tableau.
    • ou bien est-ce qu'on affiche toutes les données présentes dans le VOTable "générique", et dans ce cas le nombre de colonne du tableau dépendra du nombre de données décrites, les noms des colonnes correspondront à la propriété "name" définie dans les tag "FIELD".
--> On va afficher dans le tableau l'ensemble des colonnes décrites dans la VOTable, ces colonnes seront désignés effectivement par l'attribut name (obligatoire) du tag FIELD
  • l'attribut "datatype" sera-t-il toujours présent? [OK]
--> Cet attribut est obligatoire ("required" dans le schéma XML décrivant un document VOTable). Cependant, il peut arriver avec des VOTable non valides qu'il soit absent. Dans ce cas, considérer qu'il s'agit d'un type "string"
  • est-ce que l'on considère que toutes les données sont du même type? Si oui, tous les objets s'afficheront avec le même aspect (même diamètre, même couleur). [OK]
--> Pour le moment, oui.
  • L'ascension droite est la colonne possédant un UCD commençant par pos.eq.ra, alors que la déclinaison est la colonne avec un UCD débutant par pos.eq.dec. Cette info devrait toujours être présente. Mais dans "I_209A_main-090526.vot.xml", "pos.eq.ra;meta.main" est présent 2 fois: l'une avec name="RA2000" et l'autre avec name="_RAJ2000", lequel choisir? [OK]
--> C'est mon fichier qui est erroné. L'attribut meta.main d'un UCD ne peut pas être associé (dans le même document) plus d'une fois au même UCD. Il n'y a donc en principe qu'un seul champ avec un UCD pos.eq.ra;meta.main L'algo pour trouver la colonne d'ascension droite est le suivante : [OK]
- on cherche un champ avec ucd=pos.eq.ra;meta.main
- sinon, on cherche celui avec ucd=POS_EQ_RA_MAIN
- sinon, on cherche celui avec ucd=pos.eq.ra
- sinon, on cherche celui avec ucd=POS_EQ_RA
- sinon, message d'erreur (sans cette info, Aladin ne pourra pas calculer les (X,Y))

Pour trouver la colonne de déclinaison, c'est très similaire : [OK]
- on cherche un champ avec ucd=pos.eq.dec;meta.main
- sinon, on cherche celui avec ucd=POS_EQ_DEC_MAIN
- sinon, on cherche celui avec ucd=pos.eq.dec
- sinon, on cherche celui avec ucd=POS_EQ_DEC
- sinon, message d'erreur

Pour trouver la colonne portant le nom de l'objet : [OK]
- chercher un champ avec ucd=meta.id;meta.main
- sinon, chercher celui avec ucd=ID_MAIN
- sinon, chercher celui avec ucd=meta.id

Pour trouver la colonne portant le type d'objet : [OK]
- chercher un champ avec ucd=src.class
- sinon, chercher celui avec ucd=CLASS_OBJECT

Dans tous ces cas, si plusieurs champs devaient avoir le même UCD, prendre le premier champ rencontré [OK]

  • Et plus généralement, que choisir comme identifiant unique pour récupérer les différents fields? ucd peut ne pas être unique (cf question précédente), "name" est-il toujours présent? [OK]

L'attribut name devrait toujours être présent. S'il ne l'était pas, prendre l'ID. Si l'ID n'est pas non plus là, prendre un label générique "field1", puis "field2", etc [OK]

Topic revision: r11 - 2009-08-28 - CedricCapoulun
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback