/*
Copyright 2005-2013 Samuel Gesche

This file is part of ArcEnCiel.

ArcEnCiel is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ArcEnCiel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ArcEnCiel.  If not, see <http://www.gnu.org/licenses/>.
*/

package data;

import ihm.Charte;

import data.xml.XMLReader;
import data.xml.DOMCreationFailureException;

import javax.swing.JOptionPane;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import java.io.File;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
/**
 * Classe chargée de lire les fichiers de points de vue et de remplir les
 * Graphes correspondants. <br>
 * A l'heure actuelle, quatre formats sont lus : <ul>
 * <li>XML Leucippe (.leu)</li>
 * <li>XML Leucippe Anglais (.xml)</li>
 * <li>XML BCH (.bch)</li>
 * Ces deux premiers langages ne font pas l'objet d'une spécification. Il s'agit
 * de langages utilisés pour les tests.
 * <li>XML Towntology (DTD disponible sur www.towntology.net)
 * <li>XTM, XML for Topic Maps (DTD et spécification disponible sur
 * www.topicmaps.org)</li></ul>
 *
 * @author Samuel GESCHE
 * @version 3.5.1
 * @since 3.0
 */
public class Chargeur {

    /**
     * Lecture d'un fichier de données écrit dans un formalisme XML pour
     * Leucippe.
     * @param file le fichier à lire.
     * @return Graphe le graphe obtenu.
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 3.0
     */
    public static Graphe chargeLEU(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);

        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList noeuds = doc.getElementsByTagName("noeud");
            for (int i = 0; i < noeuds.getLength(); i++) {
                Node noeud = noeuds.item(i);
                NamedNodeMap atts = noeud.getAttributes();
                resultat.addNoeud(Integer.parseInt(
                        atts.getNamedItem("id").getNodeValue().trim()),
                                  new Noeud(atts.getNamedItem("nom").
                                            getNodeValue().trim(),
                                            new TypeNoeud(atts.getNamedItem(
                        "type").getNodeValue().trim())));
            }
            NodeList liens = doc.getElementsByTagName("lien");
            for (int i = 0; i < liens.getLength(); i++) {
                Node lien = liens.item(i);
                NamedNodeMap atts = lien.getAttributes();
                resultat.addLien(Integer.parseInt(
                        atts.getNamedItem("id").getNodeValue().trim()),
                                 new Lien(atts.getNamedItem("nom").getNodeValue().
                                          trim(), new TypeLien(
                                                  atts.getNamedItem("type").
                        getNodeValue().trim())));
            }
            NodeList typesNoeuds = doc.getElementsByTagName("typenoeud");
            for (int i = 0; i < typesNoeuds.getLength(); i++) {
                Node typeNoeud = typesNoeuds.item(i);
                NamedNodeMap atts = typeNoeud.getAttributes();
                resultat.addTypeNoeud(i, new TypeNoeud(atts.getNamedItem("nom").
                        getNodeValue().trim()));
            }
            NodeList associations = doc.getElementsByTagName("association");
            for (int i = 0; i < associations.getLength(); i++) {
                Node association = associations.item(i);
                NamedNodeMap atts = association.getAttributes();
                resultat.addAssociation(Integer.parseInt(
                        atts.getNamedItem("lien").getNodeValue().trim()),
                                        Integer.parseInt(
                                                atts.getNamedItem("orig").
                                                getNodeValue().trim()),
                                        Integer.parseInt(
                                                atts.getNamedItem("dest").
                                                getNodeValue().trim()));
            }
            NodeList typesLiens = doc.getElementsByTagName("typelien");
            for (int i = 0; i < typesLiens.getLength(); i++) {
                Node typeLien = typesLiens.item(i);
                NamedNodeMap atts = typeLien.getAttributes();
                NodeList props = typeLien.getChildNodes();
                Vector rangeP = new Vector();
                Vector rangeV = new Vector();
                for (int j = 0; j < props.getLength(); j++) {
                    Node prop = props.item(j);
                    if (prop.getNodeName().equalsIgnoreCase("propriete")) {
                        NamedNodeMap pv = prop.getAttributes();
                        rangeP.addElement(
                                pv.getNamedItem("nom").getNodeValue().trim());
                        rangeV.addElement(
                                pv.getNamedItem("val").getNodeValue().trim());
                    }
                }
                Propriete[] proprietes = new Propriete[rangeP.size()];
                for (int j = 0; j < rangeP.size(); j++) {
                    String s = ((String) (rangeV.elementAt(j))).trim();
                    int val = -1;
                    if (s.toLowerCase().equals("vrai") ||
                        s.toLowerCase().equals("true") ||
                        s.toLowerCase().equals("toujours") ||
                        s.toLowerCase().equals("always") ||
                        s.toLowerCase().equals("oui") ||
                        s.toLowerCase().equals("yes")) {
                        val = 1;
                    }
                    if (s.toLowerCase().equals("faux") ||
                        s.toLowerCase().equals("false") ||
                        s.toLowerCase().equals("jamais") ||
                        s.toLowerCase().equals("never") ||
                        s.toLowerCase().equals("non") ||
                        s.toLowerCase().equals("no")) {
                        val = 0;
                    }
                    proprietes[j] = new Propriete(rangeP.elementAt(j).toString(),
                                                  val);
                }
                resultat.addTypeLien(i,
                                     new TypeLien(atts.getNamedItem("nom").
                                                  getNodeValue().trim(),
                                                  proprietes));
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }
    
    
    /**
     * Lecture d'un fichier de données écrit dans un formalisme XML en anglais pour
     * Leucippe.
     * @param file le fichier à lire.
     * @return Graphe le graphe obtenu.
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 3.0
     */
    public static Graphe chargeLEUEN(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);

        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList noeuds = doc.getElementsByTagName("node");
            for (int i = 0; i < noeuds.getLength(); i++) {
                Node noeud = noeuds.item(i);
                NamedNodeMap atts = noeud.getAttributes();
                resultat.addNoeud(Integer.parseInt(
                        atts.getNamedItem("id").getNodeValue().trim()),
                                  new Noeud(atts.getNamedItem("name").
                                            getNodeValue().trim(),
                                            new TypeNoeud(atts.getNamedItem(
                        "type").getNodeValue().trim())));
            }
            NodeList liens = doc.getElementsByTagName("link");
            for (int i = 0; i < liens.getLength(); i++) {
                Node lien = liens.item(i);
                NamedNodeMap atts = lien.getAttributes();
                resultat.addLien(Integer.parseInt(
                        atts.getNamedItem("id").getNodeValue().trim()),
                                 new Lien(atts.getNamedItem("name").getNodeValue().
                                          trim(), new TypeLien(
                                                  atts.getNamedItem("type").
                        getNodeValue().trim())));
            }
            NodeList typesNoeuds = doc.getElementsByTagName("nodetype");
            for (int i = 0; i < typesNoeuds.getLength(); i++) {
                Node typeNoeud = typesNoeuds.item(i);
                NamedNodeMap atts = typeNoeud.getAttributes();
                resultat.addTypeNoeud(i, new TypeNoeud(atts.getNamedItem("name").
                        getNodeValue().trim()));
            }
            NodeList associations = doc.getElementsByTagName("edge");
            for (int i = 0; i < associations.getLength(); i++) {
                Node association = associations.item(i);
                NamedNodeMap atts = association.getAttributes();
                resultat.addAssociation(Integer.parseInt(
                        atts.getNamedItem("link").getNodeValue().trim()),
                                        Integer.parseInt(
                                                atts.getNamedItem("from").
                                                getNodeValue().trim()),
                                        Integer.parseInt(
                                                atts.getNamedItem("to").
                                                getNodeValue().trim()));
            }
            NodeList typesLiens = doc.getElementsByTagName("linktype");
            for (int i = 0; i < typesLiens.getLength(); i++) {
                Node typeLien = typesLiens.item(i);
                NamedNodeMap atts = typeLien.getAttributes();
                NodeList props = typeLien.getChildNodes();
                Vector rangeP = new Vector();
                Vector rangeV = new Vector();
                for (int j = 0; j < props.getLength(); j++) {
                    Node prop = props.item(j);
                    if (prop.getNodeName().equalsIgnoreCase("property")) {
                        NamedNodeMap pv = prop.getAttributes();
                        rangeP.addElement(
                                pv.getNamedItem("name").getNodeValue().trim());
                        rangeV.addElement(
                                pv.getNamedItem("value").getNodeValue().trim());
                    }
                }
                Propriete[] proprietes = new Propriete[rangeP.size()];
                for (int j = 0; j < rangeP.size(); j++) {
                    String s = ((String) (rangeV.elementAt(j))).trim();
                    int val = -1;
                    if (s.toLowerCase().equals("vrai") ||
                        s.toLowerCase().equals("true") ||
                        s.toLowerCase().equals("toujours") ||
                        s.toLowerCase().equals("always") ||
                        s.toLowerCase().equals("oui") ||
                        s.toLowerCase().equals("yes")) {
                        val = 1;
                    }
                    if (s.toLowerCase().equals("faux") ||
                        s.toLowerCase().equals("false") ||
                        s.toLowerCase().equals("jamais") ||
                        s.toLowerCase().equals("never") ||
                        s.toLowerCase().equals("non") ||
                        s.toLowerCase().equals("no")) {
                        val = 0;
                    }
                    proprietes[j] = new Propriete(rangeP.elementAt(j).toString(),
                                                  val);
                }
                resultat.addTypeLien(i,
                                     new TypeLien(atts.getNamedItem("name").
                                                  getNodeValue().trim(),
                                                  proprietes));
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }

    /**
     * Lecture d'un fichier de données tirées du Bulletin de Correspondance
     * Hellénique. Ces fichiers sont écrits dans un formalisme particulier
     * élaboré lors du Projet de Fin d'Etudes.
     * @param file le fichier à lire, écrit dans le formalisme du PFE.
     * @return Graphe le graphe obtenu
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 3.0
     */
    public static Graphe chargeBCH(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);


        // Les types de noeuds et de liens sont déterminés dans la sémantique
        // du formalisme : descripteurs et relations de spécialisation

        resultat.addTypeNoeud(0, new TypeNoeud("descripteur"));
        Propriete[] props = {new Propriete("Transitivité", Propriete.VRAI),
                            new Propriete("Réflexivité", Propriete.FAUX),
                            new Propriete("Symétrie", Propriete.FAUX),
                            new Propriete("Optionnel", Propriete.FAUX)
        };
        resultat.addTypeLien(0, new TypeLien("spécialisation", props));
        Propriete[] props2 = {new Propriete("Transitivité", Propriete.VRAI),
                             new Propriete("Réflexivité", Propriete.FAUX),
                             new Propriete("Symétrie", Propriete.FAUX),
                             new Propriete("Optionnel", Propriete.VRAI)
        };
        resultat.addTypeLien(1,
                             new TypeLien("spécialisation optionnelle", props2));

        int idLien = -1;
        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList lieux = doc.getElementsByTagName("LIEU");
            for (int i = 0; i < lieux.getLength(); i++) {
                Node lieu = lieux.item(i);
                NamedNodeMap atts = lieu.getAttributes();
                NodeList liste = lieu.getChildNodes();
                int id = Integer.parseInt(atts.getNamedItem("ID").getNodeValue().
                                          trim());
                String nom = "";
                Vector idLiens = new Vector();
                Vector idSL = new Vector();
                for (int j = 0; j < liste.getLength(); j++) {
                    Node item = liste.item(j);
                    if (item.getNodeName().equals("NOM")) {
                        nom = item.getChildNodes().item(0).getNodeValue().trim();
                    }
                    if (item.getNodeName().equals("ID_SOUS_LIEU")) {
                        idSL.add(Integer.valueOf(
                                item.getChildNodes().item(0).getNodeValue().
                                trim()));
                        if (item.getAttributes().getNamedItem("CERTAIN").
                            getNodeValue().equals("OUI")) {
                            resultat.addLien(++idLien, new Lien("contient",
                                    new TypeLien("spécialisation")));
                            idLiens.add(new Integer(idLien));
                        } else {
                            resultat.addLien(++idLien, new Lien("contient",
                                    new TypeLien("spécialisation optionnelle")));
                            idLiens.add(new Integer(idLien));
                        }
                    }
                }
                resultat.addNoeud(id, new Noeud(nom,
                                                new TypeNoeud("descripteur")));
                for (int j = 0; j < idLiens.size(); j++) {
                    resultat.addAssociation(((Integer) (idLiens.elementAt(j))).
                                            intValue(), id,
                                            ((Integer) (idSL.elementAt(j))).
                                            intValue());
                }
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }


    /**
     * Lecture d'une ontologie Towntology.
     * @param file le fichier XML à lire, écrit selon la DTD de Towntology.
     * @return Graphe le graphe obtenu
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 3.0
     */
    public static Graphe chargeTWO(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);


        TypeNoeud image = new TypeNoeud("Image");
        resultat.addTypeNoeud(image);
        TypeNoeud son = new TypeNoeud("Son");
        resultat.addTypeNoeud(son);

        Propriete[] props0 = {new Propriete("Transitivité", Propriete.FAUX),
                            new Propriete("Réflexivité", Propriete.FAUX),
                            new Propriete("Symétrie", Propriete.FAUX),
                            new Propriete("Optionnel", Propriete.FAUX)};
        TypeLien ressourceDe = new TypeLien("ressource de", props0);
        // L'id 10000 ne sera vraisemblablement pas utilisé
        resultat.addTypeLien(10000, ressourceDe);


        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList typesLiens = doc.getElementsByTagName("RELATION_TYPE");
            for (int i = 0; i < typesLiens.getLength(); i++) {
                Node typeLien = typesLiens.item(i);
                NamedNodeMap atts = typeLien.getAttributes();
                int id = Integer.parseInt(atts.getNamedItem("ID").getNodeValue());
                NodeList data = typeLien.getChildNodes();
                String nom = "";
                boolean sym = false;
                boolean trns = false;
                boolean mbo = false;
                String desc = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("RELATION_NAME")) {
                        nom = data.item(j).getChildNodes().item(0).getNodeValue().
                              trim();
                    }
                    if (data.item(j).getNodeName().equals("RELATION_DEF")) {
                        desc = data.item(j).getChildNodes().item(0).
                               getNodeValue().trim();
                    }
                    if (data.item(j).getNodeName().equals("RELATION_PROPERTIES")) {
                        NamedNodeMap prop = data.item(j).getAttributes();
                        sym = Boolean.getBoolean(
                                prop.getNamedItem("SYMMETRIC").getNodeValue().
                                trim());
                        trns = Boolean.getBoolean(
                                prop.getNamedItem("TRANSITIVE").getNodeValue().
                                trim());
                        mbo = Boolean.getBoolean(
                                prop.getNamedItem("MAYBEOPTIONAL").getNodeValue().
                                trim());
                    }
                }
                Propriete p = new Propriete(Propriete.SYMETRIE,
                                            sym ? Propriete.VRAI :
                                            Propriete.CONTINGENT);
                Propriete p2 = new Propriete(Propriete.TRANSITIVITE,
                                             trns ? Propriete.VRAI :
                                             Propriete.CONTINGENT);
                Propriete p3 = new Propriete("Optionnel",
                                             mbo ? Propriete.CONTINGENT :
                                             Propriete.FAUX);
                Propriete[] props = {p, p2, p3};
                TypeLien tL = new TypeLien(nom, props);
                tL.setDescription(desc);
                resultat.addTypeLien(id+1, tL);
            }

            NodeList domaines = doc.getElementsByTagName("DOMAIN");
            for (int i = 0; i < domaines.getLength(); i++) {
                Node domaine = domaines.item(i);
                NamedNodeMap atts = domaine.getAttributes();
                int id = Integer.parseInt(atts.getNamedItem("ID").getNodeValue().
                                          trim());
                NodeList data = domaine.getChildNodes();
                String nom = "";
                String desc = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("DOMAIN_NAME")) {
                        nom = data.item(j).getChildNodes().item(0).getNodeValue().
                              trim();
                    }
                    if (data.item(j).getNodeName().equals("DOMAIN_DEF")) {
                        desc = data.item(j).getChildNodes().item(0).
                               getNodeValue().trim();
                    }
                }
                TypeNoeud tN = new TypeNoeud(nom);
                tN.setDescription(desc);
                resultat.addTypeNoeud(id, tN);
            }

            NodeList concepts = doc.getElementsByTagName("CONCEPT");
            for (int i = 0; i < concepts.getLength(); i++) {
                Node concept = concepts.item(i);
                NamedNodeMap atts = concept.getAttributes();
                int id = Integer.parseInt(atts.getNamedItem("ID").getNodeValue().
                                          trim());
                NodeList data = concept.getChildNodes();
                String nom = "";
                String desc = "";
                Vector images = new Vector();
                Vector sons = new Vector();
                int dom = 0;
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("CONCEPT_NAME")) {
                        nom = data.item(j).getChildNodes().item(0).getNodeValue().
                              trim();
                    }
                    if (data.item(j).getNodeName().equals("CONCEPT_DOMAIN")) {
                        dom = Integer.parseInt(
                                data.item(j).getAttributes().
                                getNamedItem("ID").getNodeValue().trim());
                    }
                    if (data.item(j).getNodeName().equals("CONCEPT_DEFS")) {
                        NodeList defs = data.item(j).getChildNodes();
                        boolean defTrouvee = false;
                        for (int k = 0; k < defs.getLength(); k++) {
                            Node df = defs.item(k);
                            if (df.getNodeName().equals("CONCEPT_DEF")) {
                                NodeList sdf = df.getChildNodes();
                                for (int l = 0; l < sdf.getLength(); l++) {
                                    if (sdf.item(l).getNodeName().equals(
                                            "CONCEPT_DEF_TEXT")) {
                                        if (defTrouvee) {
                                            desc += "<br><br>";
                                        }
                                        desc += sdf.item(l).getChildNodes().
                                                item(0).getNodeValue().trim();
                                        defTrouvee = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if(data.item(j).getNodeName().equals("MULTIMEDIA")){
                        NodeList ress = data.item(j).getChildNodes();
                        for (int k = 0; k < ress.getLength(); k++) {
                            Node res = ress.item(k);
                            if(res.getNodeName().equals("RESOURCE")){
                                NodeList datars = res.getChildNodes();
                                 for (int l = 0; l < datars.getLength(); l++) {
                                     Node datar = datars.item(l);
                                     if(datar.getNodeName().equals("URI")){
                                         String uri = datar.getChildNodes().
                                                 item(0).getNodeValue().trim();
                                         if(uri.endsWith("jpg") ||
                                            uri.endsWith("gif") ||
                                            uri.endsWith("png")){
                                             Noeud n = new Noeud("file:/"+
                                                     new File("dat/pdv/"+uri).
                                                     getAbsolutePath().replaceAll("\\\\", "/"), image);
                                             images.addElement(n);
                                         }
                                         if(uri.endsWith("au") ||
                                            uri.endsWith("mid") ||
                                            uri.endsWith("wav")){
                                             Noeud n = new Noeud("file:/"+
                                                     new File("dat/pdv/"+uri).
                                                     getAbsolutePath().replaceAll("\\\\", "/"), son);
                                             sons.addElement(n);
                                         }
                                     }
                                 }
                            }
                        }
                    }
                }
                Noeud n = new Noeud(nom, resultat.getTypeNoeud(dom));
                n.setDescription(desc);
                resultat.addNoeud(id, n);

                for(int j=0; j<images.size(); j++){
                    Noeud nn = (Noeud)(images.elementAt(j));
                    // les concepts ont un id en 3xxxxx,
                    // donc les ids en yyy03xxxxx sont libres.
                    int id0 = Integer.parseInt((j+1)+"0"+id);
                    int idL0 = Integer.parseInt("1"+id0);
                    resultat.addNoeud(id0, nn);
                    Lien l = new Lien("", ressourceDe);
                    // les liens ont un id à partir de 0,
                    // donc les ids en 1yyy03xxxxx sont libres.
                    resultat.addLien(idL0, l);
                    resultat.addAssociation(new Association(l, nn, n));
                }
                for(int j=0; j<sons.size(); j++){
                    Noeud nn = (Noeud)(sons.elementAt(j));
                    // les concepts ont un id en 3xxxxx,
                    // donc les ids en yyy13xxxxx sont libres.
                    int id0 = Integer.parseInt((j+1)+"1"+id);
                    int idL0 = Integer.parseInt("1"+id0);
                    resultat.addNoeud(id0, nn);
                    Lien l = new Lien("", ressourceDe);
                    // les liens ont un id à partir de 0,
                    // donc les ids en 1yyy13xxxxx sont libres.
                    resultat.addLien(idL0, l);
                    resultat.addAssociation(new Association(l, nn, n));
                }
            }

            NodeList relations = doc.getElementsByTagName("RELATION");
            for (int i = 0; i < relations.getLength(); i++) {
                Node relation = relations.item(i);
                NodeList data = relation.getChildNodes();
                int type = 0;
                int orig = 0;
                int dest = 0;
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("CONCEPT_ORIG")) {
                        orig = Integer.parseInt(
                                data.item(j).getAttributes().
                                getNamedItem("ID").getNodeValue().trim());
                    }
                    if (data.item(j).getNodeName().equals("CONCEPT_DEST")) {
                        dest = Integer.parseInt(
                                data.item(j).getAttributes().
                                getNamedItem("ID").getNodeValue().trim());
                    }
                    if (data.item(j).getNodeName().equals("TYPE")) {
                        type = Integer.parseInt(
                                data.item(j).getAttributes().
                                getNamedItem("ID").getNodeValue().trim());
                    }
                }
                Lien l = new Lien("", resultat.getTypeLien(type+1));
                Association a = new Association(l, resultat.getNoeud(orig),
                                                resultat.getNoeud(dest));
                resultat.addLien(i, l);
                resultat.addAssociation(a);
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }

    /**
     * Lecture d'une carte de thèmes (Topic Map) au format XTM. De préférence,
     * les IDs des topics doivent être explicites (donc pas des nombres).
     * @param file le fichier XML à lire, écrit selon la DTD XTM.
     * @return Graphe le graphe obtenu
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 3.2.3
     */
    public static Graphe chargeXTM(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);

        //...
        try {
            Document doc = XMLReader.getDOM(file);

            TypeNoeud theme = new TypeNoeud("Thème");
            resultat.addTypeNoeud(theme);
            TypeNoeud asso = new TypeNoeud("Association");
            resultat.addTypeNoeud(asso);
            TypeLien instanceOf = new TypeLien("est une instance de");
            resultat.addTypeLien(instanceOf);
            TypeLien role = new TypeLien("a pour rôle");
            resultat.addTypeLien(role);
            TypeLien membre = new TypeLien("est membre de");
            resultat.addTypeLien(membre);
            TypeLien subject = new TypeLien("a pour sujet");
            resultat.addTypeLien(subject);

            Map ids = new HashMap();
            int unnamedAsso = 1;
            int idLienSuivant = 0;
            NodeList topics = doc.getElementsByTagName("topic");
            NodeList associations = doc.getElementsByTagName("association");

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            // Noeuds de type Topic et Association

            for (int i = 0; i < topics.getLength(); i++) {
                Node topic = topics.item(i);
                NamedNodeMap atts = topic.getAttributes();
                String id = atts.item(0).getNodeValue();
                NodeList data = topic.getChildNodes();
                String desc = "Noms alternatifs : ";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("baseName")) {
                        NodeList data2 = data.item(j).getChildNodes();
                        for (int k = 0; k < data2.getLength(); k++) {
                            if (data2.item(k).getNodeName().equals(
                                    "baseNameString")) {
                                String s = data2.item(k).getChildNodes().item(0).
                                           getNodeValue().trim();
                                desc += "<br> * " + s;
                            }
                        }
                    }
                }
                ids.put(id, new Integer(i));
                Noeud n = new Noeud(id, theme);
                n.setDescription(desc);
                resultat.addNoeud(i, n);
            }
            for (int i = 0; i < associations.getLength(); i++) {
                Node association = associations.item(i);
                NamedNodeMap atts = association.getAttributes();
                String id = "";
                try {
                    id = atts.item(0).getNodeValue();
                } catch (NullPointerException npe) {
                    id = "Association non nommée " + unnamedAsso;
                    unnamedAsso++;
                }
                String desc = "Association";
                ids.put(id, new Integer(i + topics.getLength()));
                Noeud n = new Noeud(id, asso);
                n.setDescription(desc);
                resultat.addNoeud(i + topics.getLength(), n);
            }

            // Liens de type Instance

            for (int i = 0; i < topics.getLength(); i++) {
                NodeList data = topics.item(i).getChildNodes();
                String id = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("instanceOf")) {
                        NodeList data2 = data.item(j).getChildNodes();
                        for (int k = 0; k < data2.getLength(); k++) {
                            if (data2.item(k).getNodeName().equals("topicRef") ||
                                data2.item(k).getNodeName().equals(
                                        "subjectIndicatorRef")) {
                                id = data2.item(k).getAttributes().item(0).
                                     getNodeValue();
                                id = id.substring(1, id.length());
                            }
                        }
                    }
                    Object o = ids.get(id);
                    if (!(o == null)) {
                        int idBase = i;
                        int idDest = ((Integer) (o)).intValue();
                        Lien l = new Lien("", instanceOf);
                        resultat.addLien(idLienSuivant, l);
                        resultat.addAssociation(idLienSuivant, idBase, idDest);
                        idLienSuivant++;
                    }
                }
            }
            for (int i = 0; i < associations.getLength(); i++) {
                NodeList data = associations.item(i).getChildNodes();
                String id = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("instanceOf")) {
                        NodeList data2 = data.item(j).getChildNodes();
                        for (int k = 0; k < data2.getLength(); k++) {
                            if (data2.item(k).getNodeName().equals("topicRef") ||
                                data2.item(k).getNodeName().equals(
                                        "subjectIndicatorRef")) {
                                id = data2.item(k).getAttributes().item(0).
                                     getNodeValue();
                                id = id.substring(1, id.length());
                            }
                        }
                    }
                }
                Object o = ids.get(id);
                if (!(o == null)) {
                    int idBase = i + topics.getLength();
                    int idDest = ((Integer) (o)).intValue();
                    Lien l = new Lien("", instanceOf);
                    resultat.addLien(idLienSuivant, l);
                    resultat.addAssociation(idLienSuivant, idBase, idDest);
                    idLienSuivant++;
                }
            }

            // Liens de type Rôle et Membre

            for (int i = 0; i < associations.getLength(); i++) {
                NodeList data = associations.item(i).getChildNodes();
                int idAsso = i + topics.getLength();
                String idCible = "";
                String idRole = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("member")) {
                        NodeList data2 = data.item(j).getChildNodes();
                        for (int k = 0; k < data2.getLength(); k++) {
                            if (data2.item(k).getNodeName().equals("roleSpec")) {
                                NodeList data3 = data2.item(k).getChildNodes();
                                for (int l = 0; l < data3.getLength(); l++) {
                                    if (data3.item(l).getNodeName().equals(
                                            "topicRef") ||
                                        data3.item(l).getNodeName().equals(
                                                "subjectIndicatorRef")) {
                                        idRole = data3.item(l).getAttributes().
                                                 item(0).getNodeValue();
                                        idRole = idRole.substring(1,
                                                idRole.length());
                                    }
                                }
                            }
                            if (data2.item(k).getNodeName().equals("topicRef") ||
                                data2.item(k).getNodeName().equals(
                                        "subjectIndicatorRef")) {
                                idCible = data2.item(k).getAttributes().item(0).
                                          getNodeValue();
                                idCible = idCible.substring(1, idCible.length());
                            }
                        }
                        Object o = ids.get(idRole);
                        if (!(o == null)) {
                            int idDest = idAsso;
                            int idBase = ((Integer) (o)).intValue();
                            Lien l = new Lien("", membre);
                            resultat.addLien(idLienSuivant, l);
                            resultat.addAssociation(idLienSuivant, idBase,
                                    idDest);
                            idLienSuivant++;
                            Object o2 = ids.get(idCible);
                            if (!(o2 == null)) {
                                idDest = idBase;
                                idBase = ((Integer) (o2)).intValue();
                                l = new Lien("", role);
                                resultat.addLien(idLienSuivant, l);
                                resultat.addAssociation(idLienSuivant, idBase,
                                        idDest);
                                idLienSuivant++;
                            }
                        }
                    }
                }
            }

            // Liens de type Sujet

            for (int i = 0; i < topics.getLength(); i++) {
                NodeList data = topics.item(i).getChildNodes();
                String id = "";
                for (int j = 0; j < data.getLength(); j++) {
                    if (data.item(j).getNodeName().equals("subjectIdentity")) {
                        NodeList data2 = data.item(j).getChildNodes();
                        for (int k = 0; k < data2.getLength(); k++) {
                            if (data2.item(k).getNodeName().equals("topicRef") ||
                                data2.item(k).getNodeName().equals(
                                        "subjectIndicatorRef")) {
                                id = data2.item(k).getAttributes().item(0).
                                     getNodeValue();
                                id = id.substring(1, id.length());
                            }
                        }
                    }
                }
                Object o = ids.get(id);
                if (!(o == null)) {
                    int idBase = i;
                    int idDest = ((Integer) (o)).intValue();
                    Lien l = new Lien("", subject);
                    resultat.addLien(idLienSuivant, l);
                    resultat.addAssociation(idLienSuivant, idBase, idDest);
                    idLienSuivant++;
                }
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }

    /**
     * Lecture d'un fichier de catégories de journal, au format XML.
     * @param file le fichier à lire, écrit selon la DTD suivante :
     * <! ELEMENT JOURNAL (NOM, CATEGORIE*) >.
     * <! ELEMENT CATEGORIE (NOM, CATEGORIE*) >
     * <! ELEMENT NOM (#PCDATA) >
     * @return Graphe le graphe obtenu
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 4.0.1
     */
    public static Graphe chargeJOU(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);


        resultat.addTypeNoeud(0, new TypeNoeud("Catégorie"));
        Propriete[] props = {new Propriete("Transitivité", Propriete.VRAI),
                            new Propriete("Réflexivité", Propriete.FAUX),
                            new Propriete("Symétrie", Propriete.FAUX),
                            new Propriete("Optionnel", Propriete.FAUX)
        };
        resultat.addTypeLien(0, new TypeLien("Est une Catégorie de", props));

        idCat = 1;
        idCatL = 0;
        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList journaux = doc.getElementsByTagName("JOURNAL");
            if(journaux.getLength()<1 || journaux.getLength()>1){
                throw new IllegalStateException("Il ne peut y avoir "+
                                                "qu'un journal par fichier");
            }
            Node journal = journaux.item(0);
            NodeList categories = journal.getChildNodes();
            //System.err.println(categories.getLength());
            String nom = "";
            for (int i = 0; i < categories.getLength(); i++) {
                Node categorie = categories.item(i);
                if(categorie.getNodeName().equals("NOM")){
                    nom = categorie.getChildNodes().item(0).getNodeValue().trim();
                    resultat.addNoeud(0, new Noeud(nom, resultat.getTypeNoeud(0)));
                } else if(categorie.getNodeName().equals("CATEGORIE")){
                    lisCategorie(categorie, 0, resultat);
                }
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }
    private static int idCat = 1;
    private static int idCatL = 0;
    private static void lisCategorie(Node n, int idPere, Graphe resultat){
        NodeList categories = n.getChildNodes();
        String nom = "";
        int id = idCat++;
        for (int i = 0; i < categories.getLength(); i++) {
            Node categorie = categories.item(i);
            if (categorie.getNodeName().equals("NOM")) {
                nom = categorie.getChildNodes().item(0).getNodeValue().trim();
                resultat.addNoeud(id, new Noeud(nom, resultat.getTypeNoeud(0)));
                int idL = idCatL++;
                resultat.addLien(idL, new Lien("", resultat.getTypeLien(0)));
                resultat.addAssociation(idL, id, idPere);
            } else if (categorie.getNodeName().equals("CATEGORIE")) {
                lisCategorie(categorie, id, resultat);
            }
        }
    }


    /**
     * Lecture d'un fichier d'articles de journaux, au format XML.
     * @param file le fichier à lire, écrit selon la DTD suivante :
     * <! ELEMENT JOURNAL (NOM, THEME*) >
     * <! ELEMENT THEME (NOM, SUJET*) >
     * <! ELEMENT SUJET (NOM, ARTICLE*) >
     * <! ELEMENT NOM (#PCDATA) >
     * <! ELEMENT ARTICLE (#PCDATA) >
     * @return Graphe le graphe obtenu
     * @throws ImportException en cas d'erreur d'import (l'exception est
     * renvoyée après l'affichage d'un message d'erreur)
     * @since 4.0.1
     */
    public static Graphe chargeMDN(File file) throws ImportException {
        String nomPDV = file.getPath();
        try{
            nomPDV = nomPDV.split("pdv")[1]; // suppression du chemin commun
            nomPDV = nomPDV.substring(1, nomPDV.length()); // suppression du \
        } catch(Exception e){
            // Exception à renvoyer : chemin invalide
        }
        Graphe resultat = new Graphe(nomPDV);


        resultat.addTypeNoeud(0, new TypeNoeud("Thème"));
        resultat.addTypeNoeud(1, new TypeNoeud("Sujet"));
        resultat.addTypeNoeud(2, new TypeNoeud("Article"));
        Propriete[] props = {new Propriete("Transitivité", Propriete.VRAI),
                            new Propriete("Réflexivité", Propriete.FAUX),
                            new Propriete("Symétrie", Propriete.FAUX),
                            new Propriete("Optionnel", Propriete.FAUX)
        };
        resultat.addTypeLien(0, new TypeLien("est une catégorie de", props));
        Propriete[] props2 = {new Propriete("Transitivité", Propriete.FAUX),
                            new Propriete("Réflexivité", Propriete.FAUX),
                            new Propriete("Symétrie", Propriete.FAUX),
                            new Propriete("Optionnel", Propriete.FAUX)
        };
        resultat.addTypeLien(1, new TypeLien("est traité par", props2));

        try {
            Document doc = XMLReader.getDOM(file);

            // Lecture du XML... âmes sensibles s'abstenir de fouiller

            NodeList journaux = doc.getElementsByTagName("JOURNAL");
            if(journaux.getLength()<1 || journaux.getLength()>1){
                throw new IllegalStateException("Il ne peut y avoir "+
                                                "qu'un journal par fichier");
            }
            Node journal = journaux.item(0);
            NodeList themes = journal.getChildNodes();
            for (int i = 0; i < themes.getLength(); i++) {
                String nom = "";
                Node theme = themes.item(i);
                if (theme.getNodeName().equals("THEME")) {
                    NodeList sujets = theme.getChildNodes();
                    for (int j = 0; j < sujets.getLength(); j++) {
                        String nom2 = "";
                        Node sujet = sujets.item(j);
                        if (sujet.getNodeName().equals("NOM")) {
                            nom = sujet.getChildNodes().item(0).getNodeValue().
                                  trim();
                            //System.out.println(nom);
                            resultat.addNoeud(100+i, new Noeud(
                                    nom, resultat.getTypeNoeud(0)));
                        }
                        if (sujet.getNodeName().equals("SUJET")) {
                            NodeList articles = sujet.getChildNodes();
                            for (int k = 0; k < articles.getLength(); k++) {
                                String nom3 = "";
                                Node article = articles.item(k);
                                if (article.getNodeName().equals("NOM")) {
                                    nom2 = article.getChildNodes().item(0).
                                           getNodeValue().
                                           trim();
                                    resultat.addNoeud(10000 + 100 * i + j,
                                            new Noeud(
                                            nom2, resultat.getTypeNoeud(1)));
                                    resultat.addLien(10000 + 100 * i + j,
                                            new Lien("", resultat.getTypeLien(0)));
                                    resultat.addAssociation(10000 + 100 * i + j,
                                            10000 + 100 * i + j, 100+i);
                                }
                                if (article.getNodeName().equals("ARTICLE")) {
                                    nom3 = article.getChildNodes().item(0).
                                           getNodeValue().
                                           trim();
                                    resultat.addNoeud(1000000 + 10000 *
                                            i + 100 * j + k,
                                            new Noeud(
                                            nom3, resultat.getTypeNoeud(2)));
                                    resultat.addLien(1000000 + 10000 *
                                            i + 100 * j + k,
                                            new Lien("", resultat.getTypeLien(1)));
                                    resultat.addAssociation(1000000 + 10000 *
                                            i + 100 * j + k,
                                            1000000 + 10000 * i + 100 * j + k,
                                            10000 + 100 * i + j);
                                }
                            }
                        }
                    }
                }
            }
        } catch (DOMCreationFailureException dcfe) {
            // Impossibilité de lire le XML
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_MalformedXML") +
                                          " (" + dcfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(dcfe);
        } catch (NullPointerException npe) {
            // Une donnée recherchée est absente
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Critical_Info"),
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(npe);
        } catch (NumberFormatException nfe) {
            // Un nombre attendu n'est pas lisible
            JOptionPane.showMessageDialog(null,"<html>"+
                                          Charte.getMessage("Error_Id_Not_Number") +
                                          " (" + nfe.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(nfe);
        } catch (IllegalStateException ise) {
            JOptionPane.showMessageDialog(null, "<html>"+Charte.getMessage("Error_Entry") +
                                          " (" + ise.getMessage() + ")",
                                          Charte.getMessage("Error_In") +
                                          " " + file.getName(),
                                          JOptionPane.ERROR_MESSAGE);
            throw new ImportException(ise);
        }
        return resultat;
    }

}
