Java tutorial
/* * This file is part of ViDESO. * ViDESO 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. * * ViDESO 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 ViDESO. If not, see <http://www.gnu.org/licenses/>. */ package fr.crnan.videso3d.databases.aip; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.filter.AbstractFilter; import org.jdom2.filter.Filter; import org.jdom2.input.SAXBuilder; import fr.crnan.videso3d.Couple; import fr.crnan.videso3d.DatasManager; import fr.crnan.videso3d.FileParser; import fr.crnan.videso3d.databases.DatabaseManager; import fr.crnan.videso3d.graphics.Route; /** * Lecteur des exports en xml du SIA * @author Adrien Vidal * @version 0.3.5 */ public class AIP extends FileParser { private final Integer numberFiles = 23; /** * Le nom de la base de donnes. */ private String name; /** * Le chemin du fichier xml utilis */ private String fileName; /** * Connection la base de donnes */ private Connection conn; /** * Le <code>document</code> construit partir du fichier xml. */ private Document document = null; private List<Couple<Integer, String>> TSAs; private List<Couple<Integer, String>> SIVs; private List<Couple<Integer, String>> CTRs; private List<Couple<Integer, String>> TMAs; private List<Couple<Integer, String>> Ps; private List<Couple<Integer, String>> Rs; private List<Couple<Integer, String>> Ds; private List<Couple<Integer, String>> FIRs; private List<Couple<Integer, String>> UIRs; private List<Couple<Integer, String>> LTAs; private List<Couple<Integer, String>> UTAs; private List<Couple<Integer, String>> CTAs; private List<Couple<Integer, String>> OCAs; private List<Couple<Integer, String>> PRNs; private List<Couple<Integer, String>> CTLs; private List<Couple<Integer, String>> Pjes; private List<Couple<Integer, String>> Aers; private List<Couple<Integer, String>> Vols; private List<Couple<Integer, String>> Bals; private List<Couple<Integer, String>> TrPlas; public final static int Partie = 0, TSA = 1, SIV = 2, CTR = 3, TMA = 4, R = 5, D = 6, FIR = 7, UIR = 8, LTA = 9, UTA = 10, CTA = 11, CTL = 12, Pje = 13, Aer = 14, Vol = 15, Bal = 16, TrPla = 17, OCA = 18, P = 19, PRN = 20, AWY = 21, PDR = 22, TAC = 23, DMEATT = 30, L = 31, NDB = 32, PNP = 33, TACAN = 34, VFR = 35, VOR = 36, VORDME = 37, VORTAC = 38, WPT = 39, AERODROME = 40, ALTI = 41, PRIVE = 42; public AIP(String path) { super(path); this.fileName = path; //construction du document partir du fichier xml SAXBuilder sxb = new SAXBuilder(); try { document = sxb.build(new File(path)); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public AIP() { this.TSAs = new ArrayList<Couple<Integer, String>>(); this.SIVs = new ArrayList<Couple<Integer, String>>(); this.CTRs = new ArrayList<Couple<Integer, String>>(); this.TMAs = new ArrayList<Couple<Integer, String>>(); this.Ps = new ArrayList<Couple<Integer, String>>(); this.Rs = new ArrayList<Couple<Integer, String>>(); this.Ds = new ArrayList<Couple<Integer, String>>(); this.FIRs = new ArrayList<Couple<Integer, String>>(); this.UIRs = new ArrayList<Couple<Integer, String>>(); this.LTAs = new ArrayList<Couple<Integer, String>>(); this.UTAs = new ArrayList<Couple<Integer, String>>(); this.CTAs = new ArrayList<Couple<Integer, String>>(); this.OCAs = new ArrayList<Couple<Integer, String>>(); this.PRNs = new ArrayList<Couple<Integer, String>>(); this.CTLs = new ArrayList<Couple<Integer, String>>(); this.Pjes = new ArrayList<Couple<Integer, String>>(); this.Aers = new ArrayList<Couple<Integer, String>>(); this.Vols = new ArrayList<Couple<Integer, String>>(); this.Bals = new ArrayList<Couple<Integer, String>>(); this.TrPlas = new ArrayList<Couple<Integer, String>>(); final SAXBuilder sxb = new SAXBuilder(); try { this.name = DatabaseManager.getCurrentName(DatasManager.Type.AIP); //on rcupre le chemin d'accs au fichier xml parser Statement st = DatabaseManager.getCurrent(DatasManager.Type.Databases); ResultSet rs; rs = st.executeQuery("select * from clefs where name='path' and type='" + DatabaseManager.getCurrentName(DatasManager.Type.AIP) + "'"); if (rs.next()) { this.fileName = rs.getString(4); //Construction du document dans un autre thread afin de ne pas bloquer l'initialisation //TODO trouver une autre mthode car cela empche le chargement d'un projet // new Thread(){ // @Override // public void run(){ try { document = sxb.build(new File(name + "_files", fileName)); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // } // }.start(); } //TODO prendre en compte la possibilit qu'il n'y ait pas de bdd AIP Statement aipDB = DatabaseManager.getCurrentAIP(); if (aipDB != null) { //on rcupre tous les volumes ResultSet rSet = aipDB.executeQuery("select * from volumes"); while (rSet.next()) { Couple<Integer, String> id_name = new Couple<Integer, String>(rSet.getInt(2), rSet.getString(4)); String type = rSet.getString(3); getZones(string2type(type)).add(id_name); } } } catch (SQLException e) { e.printStackTrace(); } } /** * Determine if the file is a AIP file (XML containing AIP datas) * TODO Do it better * @param file * @return <code>true</code> if it is an AIP xml database */ public static boolean isAIPFile(File file) { SAXBuilder sxb = new SAXBuilder(); boolean isAIP = false; try { isAIP = sxb.build(file).getRootElement().getName().equals("SiaExport"); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return isAIP; } @Override public Integer doInBackground() { try { //rcupration du nom de la base crer this.createName(); if (!DatabaseManager.databaseExists(DatasManager.Type.AIP, this.name)) { //cration de la connection la base de donnes this.conn = DatabaseManager.selectDB(DatasManager.Type.AIP, this.name); this.conn.setAutoCommit(false); //fixes performance issue //cration de la structure de la base de donnes DatabaseManager.createAIP(this.name, path); //parsing des fichiers et stockage en base this.getFromFiles(); this.conn.commit(); this.setProgress(this.numberFiles()); } else { DatabaseManager.selectDatabase(this.name, DatasManager.Type.AIP); } } catch (SQLException e) { e.printStackTrace(); this.cancel(true); } return this.numberFiles(); } /** * * @return L'lment Situation, qui contient tous les objets qui nous intressent. */ public Element getDocumentRoot() { return document.getRootElement().getChild("Situation"); } /** * Cre le nom de la base : AIP_date d'entre en vigueur */ private void createName() { this.name = "AIP_" + document.getRootElement().getChild("Situation").getAttributeValue("effDate"); } @Override public String getName() { return this.name; } @Override protected void getFromFiles() throws SQLException { int progress = 0; Element racineVolumes = document.getRootElement().getChild("Situation").getChild("VolumeS"); this.TSAs = new ArrayList<Couple<Integer, String>>(); this.SIVs = new ArrayList<Couple<Integer, String>>(); this.CTRs = new ArrayList<Couple<Integer, String>>(); this.TMAs = new ArrayList<Couple<Integer, String>>(); this.Ps = new ArrayList<Couple<Integer, String>>(); this.Rs = new ArrayList<Couple<Integer, String>>(); this.Ds = new ArrayList<Couple<Integer, String>>(); this.FIRs = new ArrayList<Couple<Integer, String>>(); this.UIRs = new ArrayList<Couple<Integer, String>>(); this.LTAs = new ArrayList<Couple<Integer, String>>(); this.UTAs = new ArrayList<Couple<Integer, String>>(); this.CTAs = new ArrayList<Couple<Integer, String>>(); this.OCAs = new ArrayList<Couple<Integer, String>>(); this.PRNs = new ArrayList<Couple<Integer, String>>(); this.CTLs = new ArrayList<Couple<Integer, String>>(); this.Pjes = new ArrayList<Couple<Integer, String>>(); this.Aers = new ArrayList<Couple<Integer, String>>(); this.Vols = new ArrayList<Couple<Integer, String>>(); this.Bals = new ArrayList<Couple<Integer, String>>(); this.TrPlas = new ArrayList<Couple<Integer, String>>(); this.setFile("Aerodromes"); this.setProgress(progress); this.getAerodromes(); this.setFile("TSA"); this.setProgress(progress++); this.getTSAs(racineVolumes); this.setFile("SIV"); this.setProgress(progress++); this.getZones(racineVolumes, "SIV"); this.setFile("CTR"); this.setProgress(progress++); this.getZones(racineVolumes, "CTR"); this.setFile("TMA"); this.setProgress(progress++); this.getZones(racineVolumes, "TMA"); this.setFile("P"); this.setProgress(progress++); this.getZones(racineVolumes, "P"); this.setFile("R"); this.setProgress(progress++); this.getZones(racineVolumes, "R"); this.setFile("D"); this.setProgress(progress++); this.getZones(racineVolumes, "D"); this.setFile("FIR"); this.setProgress(progress++); this.getZones(racineVolumes, "FIR"); this.setFile("UIR"); this.setProgress(progress++); this.getZones(racineVolumes, "UIR"); this.setFile("LTA"); this.setProgress(progress++); this.getZones(racineVolumes, "LTA"); this.setFile("UTA"); this.setProgress(progress++); this.getZones(racineVolumes, "UTA"); this.setFile("CTA"); this.setProgress(progress++); this.getZones(racineVolumes, "CTA"); this.setFile("OCA"); this.setProgress(progress++); this.getZones(racineVolumes, "OCA"); this.setFile("PRN"); this.setProgress(progress++); this.getZones(racineVolumes, "PRN"); this.setFile("CTL"); this.setProgress(progress++); this.getZones(racineVolumes, "CTL"); this.setFile("Parachutages"); this.setProgress(progress++); this.getZones(racineVolumes, "Pje"); this.setFile("Aer"); this.setProgress(progress++); this.getZones(racineVolumes, "Aer"); this.setFile("Voltige"); this.setProgress(progress++); this.getZones(racineVolumes, "Vol"); this.setFile("Ballons"); this.setProgress(progress++); this.getZones(racineVolumes, "Bal"); this.setFile("Treuils planeurs"); this.setProgress(progress++); this.getZones(racineVolumes, "TrPla"); this.setFile("Routes"); this.setProgress(progress++); this.getRoutes(); this.setFile("Navigation Fix"); this.setProgress(progress++); this.getBalises(); this.setFile("Frquences"); this.setProgress(progress++); this.getFrequences(); this.setProgress(progress++); } private void getFrequences() { try { Element racineFrequenceS = getDocumentRoot().getChild("FrequenceS"); List<Element> frequences = racineFrequenceS.getChildren(); for (Element freq : frequences) { Element secteur = freq.getChild("SecteurSituation"); if (secteur != null) { String frequence = freq.getChildText("Frequence"); if (frequence.startsWith("1")) insertFrequence(secteur.getText(), frequence); } } } catch (Exception e) { e.printStackTrace(); } } private void insertFrequence(String secteur, String frequence) { String[] secteurs = secteur.split("/"); for (String sect : secteurs) { PreparedStatement ps; try { ps = this.conn.prepareStatement("insert into frequences (nom, frequence) VALUES (?, ?)"); ps.setString(1, sect); ps.setString(2, frequence); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } } private void getAerodromes() throws SQLException { try { Element racineAds = getDocumentRoot().getChild("AdS"); List<Element> ads = racineAds.getChildren(); for (Element ad : ads) { if (!ad.getChildText("AdStatut").equals("OFF")) insertAerodrome(ad); } Element racineRwys = getDocumentRoot().getChild("RwyS"); List<Element> rwys = racineRwys.getChildren(); for (Element rwy : rwys) { insertRunway(rwy); } } catch (Exception e) { e.printStackTrace(); } } private void insertAerodrome(Element ad) throws SQLException { int pk = Integer.parseInt(ad.getAttributeValue("pk")); String code = ad.getAttributeValue("lk").replaceAll("\\p{Punct}", "").toUpperCase(Locale.ENGLISH); String nom = ad.getChildText("AdNomComplet"); int type = code.matches("[A-Z]{4}") ? 0 : (code.matches("LF[0-9]{2}") ? 2 : 1); double latRef = Double.parseDouble(ad.getChildText("ArpLat")); double lonRef = Double.parseDouble(ad.getChildText("ArpLong")); PreparedStatement ps = this.conn.prepareStatement( "insert into aerodromes (pk, code, nom, type, latRef, lonRef) VALUES (?, ?, ?, ?, ?, ?)"); ps.setInt(1, pk); ps.setString(2, code); ps.setString(3, nom); ps.setInt(4, type); ps.setDouble(5, latRef); ps.setDouble(6, lonRef); ps.executeUpdate(); } private void insertRunway(Element rwy) throws SQLException { int pk = Integer.parseInt(rwy.getAttributeValue("pk")); int pkAerodrome = Integer.parseInt(rwy.getChild("Ad").getAttributeValue("pk")); String rwyName = rwy.getChildText("Rwy"); int orientation = getRunwayOrientation(rwyName); String largeurString = rwy.getChildText("Largeur"); double largeur = -1; if (largeurString != null) largeur = Double.parseDouble(largeurString); String longueurString = rwy.getChildText("Longueur"); double longueur = -1; if (longueurString != null) longueur = Double.parseDouble(longueurString); PreparedStatement ps = this.conn.prepareStatement( "insert into runways (pk, pk_ad, nom, orientation, longueur, largeur) VALUES (?, ?, ?, ?, ?, ?)"); ps.setInt(1, pk); ps.setInt(2, pkAerodrome); ps.setString(3, rwyName); ps.setInt(4, orientation); ps.setDouble(5, longueur); ps.setDouble(6, largeur); ps.executeUpdate(); String latThr1 = rwy.getChildText("LatThr1"); String lonThr1 = rwy.getChildText("LongThr1"); String latThr2 = rwy.getChildText("LatThr2"); String lonThr2 = rwy.getChildText("LongThr2"); if (latThr1 != null && latThr2 != null) { PreparedStatement ps2 = this.conn .prepareStatement("update runways set lat1=?, lon1=?,lat2=?,lon2=? where pk=?"); ps2.setDouble(1, Double.parseDouble(latThr1)); ps2.setDouble(2, Double.parseDouble(lonThr1)); ps2.setDouble(3, Double.parseDouble(latThr2)); ps2.setDouble(4, Double.parseDouble(lonThr2)); ps2.setInt(5, pk); ps2.executeUpdate(); } } private int getRunwayOrientation(String rwyName) { String firstQFU = rwyName.split("/")[0]; if (firstQFU.startsWith("NW")) { return 45; } if (firstQFU.endsWith("R") || firstQFU.endsWith("L") || firstQFU.endsWith("C")) { firstQFU = firstQFU.substring(0, firstQFU.length() - 1); } if (firstQFU.equals("XX")) { return -1; } return Integer.parseInt(firstQFU); } private void getBalises() throws SQLException { Element racineNavFix = document.getRootElement().getChild("Situation").getChild("NavFixS"); List<Element> navFix = racineNavFix.getChildren(); for (Element fix : navFix) { insertNavFix(fix); } } private void insertNavFix(Element navFix) throws SQLException { String pk = navFix.getAttributeValue("pk"); String type = navFix.getChildText("NavType"); String name = navFix.getChildText("Ident"); String territoireID = navFix.getChild("Territoire").getAttributeValue("pk"); double latitude = Double.parseDouble(navFix.getChildText("Latitude")); double longitude = Double.parseDouble(navFix.getChildText("Longitude")); if (!territoireID.equals("100")) { name += " - " + getTerritoireName(territoireID); } double freq = 0; if (!type.equals("VFR") && !type.equals("WPT") && !type.equals("PNP")) { List<Element> elts = findElementsByChildId( document.getRootElement().getChild("Situation").getChild("RadioNavS"), "NavFix", pk); if (elts.size() > 0) { freq = Double.parseDouble(elts.get(0).getChildText("Frequence")); } } PreparedStatement ps = this.conn.prepareStatement( "insert into NavFix (pk, type, nom, lat, lon, frequence) VALUES (?, ?, ?, ?, ?, ?)"); ps.setInt(1, Integer.parseInt(pk)); ps.setString(2, type); ps.setString(3, name); ps.setDouble(4, latitude); ps.setDouble(5, longitude); ps.setDouble(6, freq); ps.executeUpdate(); } private void getRoutes() throws SQLException { Element racineRoutes = document.getRootElement().getChild("Situation").getChild("RouteS"); List<Element> routes = racineRoutes.getChildren(); for (Element route : routes) { insertRoute(route); } } private void insertRoute(Element route) throws SQLException { String pkRoute = route.getAttributeValue("pk"); int routeID = Integer.parseInt(pkRoute); String routeName = route.getChildText("Prefixe") + " " + route.getChildText("Numero"); String territoireID = route.getChild("Territoire").getAttributeValue("pk"); if (!territoireID.equals("100")) { routeName += " - " + getTerritoireName(territoireID); } PreparedStatement ps; int navFixExtremite = Integer.parseInt(route.getChild("Origine").getAttributeValue("pk")); ps = this.conn.prepareStatement("insert into routes (pk,type,nom, navFixExtremite) VALUES (?, ?, ?, ?)"); ps.setInt(1, routeID); ps.setString(2, route.getChildText("RouteType")); ps.setString(3, routeName); ps.setInt(4, navFixExtremite); ps.executeUpdate(); Element racineSegments = document.getRootElement().getChild("Situation").getChild("SegmentS"); List<Element> segments = findElementsByChildId(racineSegments, "Route", pkRoute); for (Element segment : segments) { int segmentID = Integer.parseInt(segment.getAttributeValue("pk")); int sequence = Integer.parseInt(segment.getChildText("Sequence")); navFixExtremite = Integer.parseInt(segment.getChild("NavFixExtremite").getAttributeValue("pk")); ps = this.conn.prepareStatement( "insert into segments (pk, pkRoute, sequence, navFixExtremite) VALUES (?, ?, ?, ?)"); ps.setInt(1, segmentID); ps.setInt(2, routeID); ps.setInt(3, sequence); ps.setInt(4, navFixExtremite); ps.executeUpdate(); //Insertion des centres traverss par la route : pour chaque segment, on ajoute le centre la liste des centres traverss String nomACC = segment.getChildText("Acc"); if (nomACC != null) { if (nomACC.contains(" ")) { String[] nomsACCs = nomACC.split(" "); insertACCs(nomsACCs, pkRoute); } else if (nomACC.contains("#")) { String[] nomsACCs = nomACC.split("#"); insertACCs(nomsACCs, pkRoute); } else { insertACC(nomACC, pkRoute); } } } } private void insertACCs(String[] nomsACCs, String pkRoute) throws SQLException { for (String nom : nomsACCs) { insertACC(nom, pkRoute); } } private void insertACC(String nomACC, String pkRoute) throws SQLException { boolean insertACC = true; PreparedStatement ps = this.conn.prepareStatement("select * from ACCTraverses where routes_pk = ?"); ps.setString(1, pkRoute); ResultSet rs = ps.executeQuery(); while (rs.next()) { if (rs.getString(2).equals(nomACC)) { insertACC = false; break; } } if (insertACC) { ps = this.conn.prepareStatement("insert into ACCTraverses (routes_pk, nomACC) VALUES (?, ?)"); ps.setString(1, pkRoute); ps.setString(2, nomACC); ps.executeUpdate(); } } /** * Cherche tous les lments Volume qui sont des TSA, et insre leur nom dans la base de donnes * @throws SQLException */ private void getTSAs(Element racine) throws SQLException { List<Element> cbaList = findVolumes(racine, "lk", "CBA"); List<Element> tsaList = findVolumes(racine, "lk", "TSA"); Iterator<Element> itCBA = cbaList.iterator(); Iterator<Element> itTSA = tsaList.iterator(); while (itCBA.hasNext()) { Element cba = itCBA.next(); this.insertZone(cba, getVolumeName(cba.getAttributeValue("lk")), false, "TSA"); } while (itTSA.hasNext()) { Element tsa = itTSA.next(); this.insertZone(tsa, getVolumeName(tsa.getAttributeValue("lk")), false, "TSA"); } } /** * * @param racine * @param type * @throws SQLException */ private void getZones(Element racine, String type) throws SQLException { List<Element> zoneList; if (type.equals("P")) { zoneList = findVolumes(racine, "lk", "P "); } else { zoneList = findVolumes(racine, "lk", type); } Iterator<Element> it1 = zoneList.iterator(); Iterator<Element> it2 = zoneList.iterator(); HashSet<String> sameNames = new HashSet<String>(); ArrayList<String> names = new ArrayList<String>(); while (it1.hasNext()) { Element zone = it1.next(); String zoneName = getVolumeName(zone.getAttributeValue("lk")); if (!names.contains(zoneName)) { names.add(zoneName); } else { sameNames.add(zoneName); } } while (it2.hasNext()) { Element zoneElement = it2.next(); String zoneName = getVolumeName(zoneElement.getAttributeValue("lk")); if (sameNames.contains(zoneName)) { this.insertZone(zoneElement, zoneName, true, type); } else { this.insertZone(zoneElement, zoneName, false, type); } } } /** * Insre dans la base de donnes la zone passe en paramtre * @param zone Le secteur (ou zone...) insrer dans la base. * @param displaySequence Boolen indiquant s'il faut afficher le numro de squence de la zone ou pas. * @param type * @throws SQLException */ private void insertZone(Element zone, String name, boolean displaySequence, String type) throws SQLException { int zoneID = Integer.parseInt(zone.getAttributeValue("pk")); //on teste s'il s'agit d'une zone Pje, Aer, Vol, Bal ou TrPla en regardant si le deuxime caractre est en minuscule : si c'est le cas, // on recherche le nom usuel. On cherche aussi le nom usuel pour les zones P et PRN. if (type.length() > 1) { if (Character.isLowerCase(type.charAt(1)) || type.equals("PRN")) { String usualName = getUsualName(zone); if (usualName != null) { name += " -- " + usualName; } } } else if (type.equals("P")) { String usualName = getUsualName(zone); if (usualName != null) { name += " -- " + usualName; } } if (displaySequence) { name += " " + zone.getChildText("Sequence"); } getZones(string2type(type)).add(new Couple<Integer, String>(zoneID, name)); PreparedStatement ps = this.conn.prepareStatement("insert into volumes (pk,type,nom) VALUES (?, ?, ?)"); ps.setInt(1, zoneID); ps.setString(2, type); ps.setString(3, removeType(name)); ps.executeUpdate(); } /** * Rcupre le nom du volume en enlevant les [] et les caractres inutiles. */ private String getVolumeName(String fullName) { String name = fullName.substring(5); String region = fullName.substring(1, 3); if (name.charAt(1) == ']') { name = name.substring(3); } int firstBracket = name.indexOf("["); if (!name.substring(firstBracket + 1, firstBracket + 3).equals(".]")) { name = name.replaceFirst("[\\]]", " "); name = name.replaceFirst("[\\[]", ""); } int bracketIndex = name.indexOf(']'); return region.equals("LF") ? name.substring(0, bracketIndex) : name.substring(0, bracketIndex) + " " + region; } private String getUsualName(Element zone) { String usualName = null; String partieID = zone.getChild("Partie").getAttributeValue("pk"); Element partie = this.findElement(document.getRootElement().getChild("Situation").getChild("PartieS"), partieID); usualName = partie.getChildText("NomUsuel"); return usualName; } /** * Vrifie si le nom de la zone commence par le type (CTR, TMA,...) * @param name Le nom vrifier * @return Le nom amput du type de zone, sauf si c'est une zone P, R ou D. */ private String removeType(String name) { int lettersToRemove = 0; if (name.startsWith("SIV") || name.startsWith("CTR") || name.startsWith("TMA") || name.startsWith("FIR") || name.startsWith("UIR") || name.startsWith("LTA") || name.startsWith("UTA") || name.startsWith("CTA") || name.startsWith("OCA") || name.startsWith("CTL") || name.startsWith("Pje") || name.startsWith("Aer") || name.startsWith("Vol") || name.startsWith("Bal")) { lettersToRemove = 4; } if (name.startsWith("TrPla")) lettersToRemove = 6; return name.substring(lettersToRemove); } @Override public int numberFiles() { return this.numberFiles; } public List<Couple<Integer, String>> getZones(int type) { switch (type) { case TSA: return TSAs; case SIV: return SIVs; case CTR: return CTRs; case TMA: return TMAs; case P: return Ps; case R: return Rs; case D: return Ds; case FIR: return FIRs; case UIR: return UIRs; case LTA: return LTAs; case UTA: return UTAs; case CTA: return CTAs; case OCA: return OCAs; case PRN: return PRNs; case CTL: return CTLs; case Pje: return Pjes; case Aer: return Aers; case Vol: return Vols; case Bal: return Bals; case TrPla: return TrPlas; } return null; } public static String type2String(int type) { switch (type) { case TSA: return "TSA"; case SIV: return "SIV"; case CTR: return "CTR"; case TMA: return "TMA"; case P: return "P"; case R: return "R"; case D: return "D"; case FIR: return "FIR"; case UIR: return "UIR"; case LTA: return "LTA"; case UTA: return "UTA"; case CTA: return "CTA"; case OCA: return "OCA"; case PRN: return "PRN"; case CTL: return "CTL"; case Pje: return "Pje"; case Aer: return "Aer"; case Vol: return "Vol"; case Bal: return "Bal"; case TrPla: return "TrPla"; case AWY: return "AWY"; case PDR: return "PDR"; case TAC: return "TAC"; case DMEATT: return "DME-ATT"; case L: return "L"; case NDB: return "NDB"; case PNP: return "PNP"; case TACAN: return "TACAN"; case VFR: return "VFR"; case VOR: return "VOR"; case VORDME: return "VOR-DME"; case VORTAC: return "VORTAC"; case WPT: return "WPT"; case AERODROME: return "Aerodromes"; case ALTI: return "Altisurfaces"; case PRIVE: return "Terrains privs"; default: return ""; } } public static int string2type(String type) { if (type.equals("0")) { return AERODROME; } if (type.equals("1")) { return ALTI; } if (type.equals("2")) { return PRIVE; } if (type.equals("TSA")) { return TSA; } if (type.equals("TMA")) { return TMA; } if (type.equals("CTR")) { return CTR; } if (type.equals("SIV")) { return SIV; } if (type.equals("P")) { return P; } if (type.equals("R")) { return R; } if (type.equals("D")) { return D; } if (type.equals("FIR")) { return FIR; } if (type.equals("UIR")) { return UIR; } if (type.equals("LTA")) { return LTA; } if (type.equals("UTA")) { return UTA; } if (type.equals("CTA")) { return CTA; } if (type.equals("OCA")) { return OCA; } if (type.equals("PRN")) { return PRN; } if (type.equals("CTL")) { return CTL; } if (type.equals("Pje")) { return Pje; } if (type.equals("Aer")) { return Aer; } if (type.equals("Vol")) { return Vol; } if (type.equals("Bal")) { return Bal; } if (type.equals("TrPla")) { return TrPla; } if (type.equals("AWY")) { return AWY; } if (type.equals("PDR")) { return PDR; } if (type.equals("TAC")) { return TAC; } if (type.equals("DME-ATT")) { return DMEATT; } if (type.equals("L")) { return L; } if (type.equals("NDB")) { return NDB; } if (type.equals("PNP")) { return PNP; } if (type.equals("TACAN")) { return TACAN; } if (type.equals("VFR")) { return VFR; } if (type.equals("VOR")) { return VOR; } if (type.equals("VOR-DME")) { return VORDME; } if (type.equals("VORTAC")) { return VORTAC; } if (type.equals("WPT")) { return WPT; } if (type.equals("Arodromes")) { return AERODROME; } if (type.equals("Altisurfaces")) { return ALTI; } if (type.equals("Terrains privs")) { return PRIVE; } return -1; } public String RouteType2AIPType(String routeName, Route.Space type) { if (routeName.startsWith("T") && routeName.charAt(1) != ' ') { return "TAC"; } else { return type.equals(Route.Space.FIR) ? "AWY" : "PDR"; } } @Override public void done() { if (this.isCancelled()) {//si le parsing a t annul, on fait le mnage try { DatabaseManager.deleteDatabase(name, DatasManager.Type.AIP); } catch (SQLException e) { e.printStackTrace(); } firePropertyChange("done", true, false); } else { firePropertyChange("done", false, true); } } /** * Liste tous les lments dont le champ fieldParam <b>commence</b> par la chane de caractres "value", parmi les fils de l'lment racine. * <i>A n'utiliser que pour chercher des volumes par leur nom.</i> * @param root Le noeud contenant les lments parmi lesquels on effectue la recherche * @param fieldParam Le champ sur lequel porte la recherche * @param value La valeur du champ fieldParam * @return la liste des lments rpondant au critre. */ public List<Element> findVolumes(Element root, String fieldParam, String value) { final String field = fieldParam; final String identity = value; Filter<Element> f = new AbstractFilter<Element>() { @Override public Element filter(Object o) { if (o instanceof Element) { Element element = (Element) o; String name = getVolumeName(element.getAttributeValue(field)); if (name.startsWith(identity)) { return element; } } return null; } }; return root.getContent(f); } /** * Permet de trouver un volume par son nom et son type (TMA, CTA,...) * @param type * @param name * @return l'lment recherch. */ public Element findElementByName(int type, String name) { Element racine = document.getRootElement().getChild("Situation").getChild("VolumeS"); return findElement(racine, getID(type, name)); } /** * Renvoie l'lment dont l'attribut "pk" correspond <code>idNumber</code> parmi les fils de l'lment <code>racine</code> * @param racine * @param idNumber * @return L'lment demand ou <code>null</code> si celui-ci n'a pas t trouv. */ public Element findElement(Element racine, String idNumber) { final String id = idNumber; Filter<Element> f = new AbstractFilter<Element>() { @Override public Element filter(Object o) { if (o instanceof Element) { Element element = (Element) o; if (element.getAttributeValue("pk").equals(id)) { return element; } } return null; } }; List<Element> elements = racine.getContent(f); if (elements != null) { if (elements.size() > 0) return elements.get(0); } return null; } public List<Element> findElementsByChildId(Element root, String childParam, String value) { final String child = childParam; final String childID = value; Filter<Element> f = new AbstractFilter<Element>() { @Override public Element filter(Object o) { if (o instanceof Element) { Element element = (Element) o; String pkChild = element.getChild(child).getAttributeValue("pk"); if (pkChild.equals(childID)) { return (Element) o; } } return null; } }; return root.getContent(f); } public Element findNavFixInfosByName(String name) { PreparedStatement st; String pk = ""; try { st = DatabaseManager.prepareStatement(DatasManager.Type.AIP, "select pk from NavFix where nom = ?"); st.setString(1, name); ResultSet rs = st.executeQuery(); if (rs.next()) { pk = rs.getString(1); } } catch (SQLException e) { e.printStackTrace(); } if (pk.equals("")) { return null; } return findElement(getDocumentRoot().getChild("RadioNavS"), pk); } /** * Renvoie l'identifiant de l'objet de type <code>type</code> et de nom <code>name</code>. * @param type le type de l'objet * @param name le nom de l'objet * @return L'attribut pk qui identifie l'objet dans le fichier xml. */ public static String getID(int type, String name) { String pk = null; if (type >= AIP.AWY) { String table = (type >= AIP.DMEATT) ? "NavFix" : "routes"; try { PreparedStatement st = DatabaseManager.prepareStatement(DatasManager.Type.AIP, "select pk from " + table + " where nom = ?"); st.setString(1, name); ResultSet rs = st.executeQuery(); if (rs.next()) { pk = rs.getString(1); } } catch (SQLException e) { e.printStackTrace(); } } else { String typeString = type2String(type); try { PreparedStatement st = DatabaseManager.prepareStatement(DatasManager.Type.AIP, "select pk from volumes where type = ? AND nom = ?"); st.setString(1, typeString); st.setString(2, name); ResultSet rs = st.executeQuery(); if (rs.next()) { pk = rs.getString(1); } } catch (SQLException e) { e.printStackTrace(); } } return pk; } public String getZoneAttributeValue(String zoneID, String attribute) { Element zone = findElement(document.getRootElement().getChild("Situation").getChild("VolumeS"), zoneID); return zone != null ? zone.getChildText(attribute) : null; } /** * Mme chose que org.jdom.Element.getChildText mais renvoie null si l'enfant n'existe pas au lieu de lever une exception. * @param e * @param childName * @return */ public String getChildText(Element e, String childName) { Element child = e.getChild(childName); return child != null ? child.getText() : null; } public String getTerritoireName(String territoireID) { Element territoire = findElement(document.getRootElement().getChild("Situation").getChild("TerritoireS"), territoireID); return territoire.getChildText("Nom"); } /** * Renvoie les niveaux plancher et plafond d'une zone, sous forme de couple d'<code>Altitude</code>. * Attention : Ne teste pas si l'lment contient bien un champ plafond et un champ plancher. * @param e L'lment dont on cherche le plancher et le plafond. * @return Un couple d'<code>Altitude</code> dont le premier lment est le plancher et le second est le plafond. * @see Altitude */ public Couple<Altitude, Altitude> getLevels(Element e) { Altitude plancher = new Altitude(e.getChild("PlancherRefUnite").getValue(), Integer.parseInt(e.getChild("Plancher").getValue())); Altitude plafond = new Altitude(e.getChild("PlafondRefUnite").getValue(), Integer.parseInt(e.getChild("Plafond").getValue())); return new Couple<Altitude, Altitude>(plancher, plafond); } /** * * @return Une liste de couples dont le premier lment est le nom de la route et le deuxime son type. */ public List<Couple<String, String>> getRouteNamesFromDB() { ArrayList<Couple<String, String>> routeNames = new ArrayList<Couple<String, String>>(); try { this.getName(); this.conn = DatabaseManager.selectDB(DatasManager.Type.AIP, this.name); PreparedStatement ps = this.conn.prepareStatement("select nom, type from routes"); ResultSet rs = ps.executeQuery(); while (rs.next()) { routeNames.add(new Couple<String, String>(rs.getString(1), rs.getString(2))); } } catch (SQLException e) { e.printStackTrace(); } return routeNames; } /** * Classe conservant l'unit et la rfrence (AMSL,ASFC...) d'un plafond ou plancher fourni pour un Volume, et qui permet d'avoir l'quivalent en FL. * @author VIDAL Adrien * */ public class Altitude { private int unite; private int ref; private int originalValue; private int FL; private String fullText; static final int sfc = 0, ft = 1, fl = 2; static final int refSFC = 0, amsl = 1, asfc = 2, qnh = 3, unl = 4; public Altitude(String refUnite, int value) { originalValue = value; if (refUnite.startsWith("ft")) { FL = value / 100; unite = Altitude.ft; String reference = refUnite.substring(3); if (reference.equals("ASFC")) { this.fullText = value + " ft ASFC"; ref = Altitude.asfc; } else { this.fullText = value + " ft AMSL"; ref = Altitude.amsl; } } if (refUnite.equals("SFC")) { FL = 0; unite = Altitude.sfc; ref = Altitude.refSFC; this.fullText = "SFC"; } if (refUnite.equals("FL")) { FL = value; unite = Altitude.fl; ref = Altitude.qnh; String valueString = "" + value; if (value < 100) { valueString = "0" + value; } if (value < 10) { valueString = "00" + value; } this.fullText = "FL " + valueString; } if (refUnite.equals("UNL")) { originalValue = 660; FL = 660; unite = Altitude.fl; ref = Altitude.unl; this.fullText = "ILLIMIT"; } } public int getUnite() { return unite; } public int getRef() { return ref; } public int getOriginalValue() { return originalValue; } public int getFL() { return FL; } public String getFullText() { return fullText; } public boolean isTerrainConforming() { if (ref == Altitude.asfc || ref == Altitude.refSFC) return true; return false; } public int getMeters() { if (unite == Altitude.sfc) return 0; if (unite == Altitude.ft) return (int) (((double) originalValue) / 3.2808); return (int) (((double) originalValue * 100) / 3.2808); } } @Override public DatasManager.Type getType() { return DatasManager.Type.AIP; } @Override public List<String> getRelevantFileNames() { // TODO Auto-generated method stub return null; } }