// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.czechaddress.parser; import static org.openstreetmap.josm.plugins.czechaddress.StringUtils.capitalize; import static org.openstreetmap.josm.plugins.czechaddress.StringUtils.tryTrim; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.plugins.czechaddress.DatabaseLoadException; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithHouses; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithStreets; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Region; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Suburb; import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ViToCi; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; /** * Parser for handling database from 'www.mvcr.cz/adresy'. * * @author Radomír Černoch, radomir.cernoch@gmail.com */ public class MvcrParser extends XMLParser { Region curRegion = null; ViToCi curViToCi = null; Suburb curSuburb = null; Street curStreet = null; //============================================================================== // IMPLEMENTING THE ContentHandler //============================================================================== @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { // ========== PARSING HOUSE ========== // if (name.equals("a")) { String cp = tryTrim(attributes.getValue("p")); String co = tryTrim(attributes.getValue("o")); if ((cp == null) && (co == null)) return; ElementWithHouses topElem = curStreet; if (topElem == null) topElem = curSuburb; if (topElem == null) topElem = curViToCi; if (topElem == null) topElem = curRegion; topElem.addHouse(new House(cp, co)); return; } // ========== PARSING STREET ========== // if (name.equals("ulice")) { String nazev = tryTrim(attributes.getValue("nazev")); // If the street filter is on, apply it! if (filStreet != null && !nazev.equals(filStreet)) { curStreet = null; return; } ElementWithStreets topElem = curSuburb; if (topElem == null) topElem = curViToCi; if (topElem == null) topElem = curRegion; //curStreet = topElem.findStreet(attributes.getValue("nazev")); //if (curStreet == null) { curStreet = new Street(capitalize(nazev)); // System.out.println("Parser: " + curStreet); topElem.addStreet(curStreet); //} return; } // ========== PARSING SUBURB ========== // if (name.equals("cast")) { if (curViToCi == null) return; String nazev = tryTrim(attributes.getValue("nazev")); // If the suburb filter is on, apply it! if (filSuburb != null && !nazev.equals(filSuburb)) { curSuburb = null; curStreet = null; return; } //curSuburb = curViToCi.findSuburb(attributes.getValue("nazev")); //if (curSuburb == null) { curSuburb = new Suburb(capitalize(nazev)); // System.out.println("Parser: " + curSuburb); curViToCi.addSuburb(curSuburb); //} return; } // ========== PARSING ViToCi ========== // if (name.equals("obec")) { String nazev = tryTrim(attributes.getValue("nazev")); // If the viToCi filter is on, apply it! if (filViToCi != null && !nazev.equals(filViToCi)) { curViToCi = null; curSuburb = null; curStreet = null; return; } //curViToCi = curRegion.findViToCi(attributes.getValue("nazev")); //if (curViToCi == null) { curViToCi = new ViToCi(capitalize(nazev)); // System.out.println("Parser: " + curViToCi); curRegion.addViToCi(curViToCi); //} return; } // ========== PARSING REGION ========== // if (name.equals("oblast")) { // If the region filter is on, apply it! if (filRegion != null && !attributes.getValue("nazev").trim().equals(filRegion)) { curRegion = null; curViToCi = null; curSuburb = null; curStreet = null; return; } /*curRegion = target.findRegion( attributes.getValue("nazev"), attributes.getValue("kraj"), attributes.getValue("okres")); if (curRegion == null) {*/ curRegion = new Region( capitalize(tryTrim(attributes.getValue("nazev"))), capitalize(tryTrim(attributes.getValue("kraj"))), capitalize(tryTrim(attributes.getValue("okres")))); target.regions.add(curRegion); //} return; } } @Override public void endElement(String uri, String localName, String name) throws SAXException { if (name.equals("cast")) { curSuburb = null; } else if (name.equals("obec")) { curSuburb = null; curViToCi = null; } else if (name.equals("oblast")) { curSuburb = null; curViToCi = null; curRegion = null; } else if (name.equals("ulice")) { curStreet = null; } } @Override public void setDocumentLocator(Locator locator) {} @Override public void startDocument() throws SAXException {} @Override public void endDocument() throws SAXException {} @Override public void startPrefixMapping(String prefix, String uri) throws SAXException {} @Override public void endPrefixMapping(String prefix) throws SAXException {} @Override public void characters(char[] ch, int start, int length) throws SAXException {} @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {} @Override public void processingInstruction(String target, String data) throws SAXException {} @Override public void skippedEntity(String name) throws SAXException {} //============================================================================== // FILTERING //============================================================================== String filRegion = null; String filViToCi = null; String filSuburb = null; String filStreet = null; public void setFilter(String filterRegion, String filterViToCi, String filterSuburb, String filterStreet) { if (filterRegion != null) filRegion = filterRegion.toUpperCase(); if (filterViToCi != null) filViToCi = filterViToCi.toUpperCase(); if (filterSuburb != null) filSuburb = filterSuburb.toUpperCase(); if (filterStreet != null) filStreet = filterStreet.toUpperCase(); } //============================================================================== // IMPLEMENTING THE DatabaseParser //============================================================================== static final String URL_DEFAULT = "http://aplikace.mvcr.cz/adresy/Download.aspx"; static final String URL_PREFERENCES_KEY = "czechaddress.databaseurl"; static final String[] OLD_URLS = { "http://aplikace.mvcr.cz/adresa/adresy.zip" // Removed around 12.01.2013 }; @Override protected String getDatabaseUrl() { /* If an outdated URL is found in the preferences, replace it by the * new one. However the urls from the list should be removed after * a reasonable amount of time (one year?), because this is a * non-systematic solution. */ for (String oldUrl : OLD_URLS) { if (Main.pref.get(URL_PREFERENCES_KEY, URL_DEFAULT).equals(oldUrl)) { Main.pref.put(URL_PREFERENCES_KEY, URL_DEFAULT); break; } } return Main.pref.get(URL_PREFERENCES_KEY, URL_DEFAULT); } @Override protected String getDatabasePath() { return storageDir + "-adresy.zip"; } @Override protected InputStream getDatabaseStream() throws DatabaseLoadException { ZipInputStream zis; ZipEntry zipEntry = null; try { zis = new ZipInputStream(new FileInputStream(getDatabasePath())); while ((zipEntry = zis.getNextEntry()) != null) if (zipEntry.getName().equals("adresy.xml")) break; } catch (IOException ioexp) { throw new DatabaseLoadException("Chyba při čtení archivu s databází.", ioexp); } if (zipEntry == null) throw new DatabaseLoadException( "ZIP archiv s databází neobsahuje soubor 'adresy.xml'."); return zis; } }