/* * WBI Indicator Explorer * * Copyright 2015 Sebastian Nogara <snogaraleal@gmail.com> * * This file is part of WBI. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package data.api; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import models.Country; import models.Indicator; import models.Point; import models.Region; import models.Series; import models.Source; import models.Topic; public class WorldBank { public static class API { public static String BASE = "http://api.worldbank.org"; public static String PATH_INDICATORS = "/indicators"; public static String PATH_COUNTRIES = "/countries"; public static String PATH_INDICATOR = "/countries/indicators/:ident"; public static String PER_PAGE = "per_page"; public static int PER_PAGE_MAX = 15000; } public static class Schema { public static String ID = "id"; public static String NAMESPACE = "http://www.worldbank.org"; public static String INDICATORS = "indicators"; public static String INDICATOR = "indicator"; public static String TOPICS = "topics"; public static String TOPIC = "topic"; public static String COUNTRIES = "countries"; public static String COUNTRY = "country"; public static String NAME = "name"; public static String ISO = "iso2Code"; public static String REGION = "region"; public static String SOURCE = "source"; public static String SOURCE_NOTE = "sourceNote"; public static String SOURCE_ORGANIZATION = "sourceOrganization"; public static String DATA = "data"; public static String DATE = "date"; public static String VALUE = "value"; public static String DECIMAL = "decimal"; } private Map<String, Indicator> indicatorMap; private Map<Integer, Topic> topicMap; private Map<Integer, Source> sourceMap; private Map<String, Region> regionMap; private Map<String, Country> countryMap; private Map<Country, Series> seriesMap; private List<Point> pointList; public WorldBank() { } public Map<String, Indicator> getIndicatorMap() { return indicatorMap; } public Map<Integer, Topic> getTopicMap() { return topicMap; } public Map<Integer, Source> getSourceMap() { return sourceMap; } public Map<String, Region> getRegionMap() { return regionMap; } public Map<String, Country> getCountryMap() { return countryMap; } public Map<Country, Series> getSeriesMap() { return seriesMap; } public List<Point> getPointList() { return pointList; } public WorldBank fetchIndicatorList() { String[][] params = new String[][] { {API.PER_PAGE, Integer.toString(API.PER_PAGE_MAX)} }; String url = HTTP.URL.get( API.BASE, API.PATH_INDICATORS, params).toString(); String response = HTTP.get(url); Document document = XML.getDocument(response); NodeList nodeList = document.getElementsByTagNameNS( Schema.NAMESPACE, Schema.INDICATOR); int nodeListLength = nodeList.getLength(); indicatorMap = new HashMap<String, Indicator>(); topicMap = new HashMap<Integer, Topic>(); sourceMap = new HashMap<Integer, Source>(); for (int i = 0; i < nodeListLength; i++) { Element indicatorElement = (Element) nodeList.item(i); String indicatorIdent = indicatorElement.getAttribute(Schema.ID); if (indicatorMap.containsKey(indicatorIdent)) { continue; } Element nameElement = (Element) indicatorElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.NAME).item(0); Element sourceElement = (Element) indicatorElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.SOURCE).item(0); Element topicsElement = (Element) indicatorElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.TOPICS).item(0); List<Topic> topics = new ArrayList<Topic>(); NodeList topicNodeList = topicsElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.TOPIC); int topicNodeListLength = topicNodeList.getLength(); for (int n = 0; n < topicNodeListLength; n++) { Element topicElement = (Element) topicNodeList.item(n); int topicIdent = Integer.valueOf( topicElement.getAttribute(Schema.ID)); Topic topic = topicMap.get(topicIdent); if (topic == null) { topic = new Topic( topicIdent, topicElement.getTextContent()); topicMap.put(topicIdent, topic); } if (!topics.contains(topic)) { topics.add(topic); } } int sourceIdent = Integer.valueOf( sourceElement.getAttribute(Schema.ID)); Source source = sourceMap.get(sourceIdent); if (source == null) { source = new Source( sourceIdent, sourceElement.getTextContent()); sourceMap.put(sourceIdent, source); } indicatorMap.put(indicatorIdent, new Indicator( indicatorIdent, nameElement.getTextContent(), topics, source)); } return this; } public WorldBank fetchCountryList() { String[][] params = new String[][] { {API.PER_PAGE, Integer.toString(API.PER_PAGE_MAX)} }; String url = HTTP.URL.get( API.BASE, API.PATH_COUNTRIES, params).toString(); String response = HTTP.get(url); Document document = XML.getDocument(response); NodeList nodeList = document.getElementsByTagNameNS( Schema.NAMESPACE, Schema.COUNTRY); int nodeListLength = nodeList.getLength(); regionMap = new HashMap<String, Region>(); countryMap = new HashMap<String, Country>(); for (int i = 0; i < nodeListLength; i++) { Element countryElement = (Element) nodeList.item(i); Element isoElement = (Element) countryElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.ISO).item(0); String countryISO = isoElement.getTextContent(); if (countryMap.containsKey(countryISO)) { continue; } Element nameElement = (Element) countryElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.NAME).item(0); Element regionElement = (Element) countryElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.REGION).item(0); String regionIdent = regionElement.getAttribute(Schema.ID); Region region = regionMap.get(regionIdent); if (region == null) { region = new Region( regionIdent, regionElement.getTextContent()); regionMap.put(regionIdent, region); } countryMap.put(countryISO, new Country( countryISO, nameElement.getTextContent(), region)); } return this; } public WorldBank fetchSeries( Indicator indicator, List<Country> countryList) { countryMap = new HashMap<String, Country>(); for (Country country : countryList) { countryMap.put(country.getISO(), country); } String[][] params = new String[][] { {API.PER_PAGE, Integer.toString(API.PER_PAGE_MAX)} }; String url = HTTP.URL.get( API.BASE, API.PATH_INDICATOR.replace(":ident", indicator.getIdent()), params).toString(); String response = HTTP.get(url); Document document = XML.getDocument(response); NodeList nodeList = document.getElementsByTagNameNS( Schema.NAMESPACE, Schema.DATA); int nodeListLength = nodeList.getLength(); seriesMap = new HashMap<Country, Series>(); pointList = new ArrayList<Point>(); for (int i = 0; i < nodeListLength; i++) { Element dataElement = (Element) nodeList.item(i); Element countryElement = (Element) dataElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.COUNTRY).item(0); Element dateElement = (Element) dataElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.DATE).item(0); Element valueElement = (Element) dataElement.getElementsByTagNameNS( Schema.NAMESPACE, Schema.VALUE).item(0); String countryISO = countryElement.getAttribute(Schema.ID); Country country = countryMap.get(countryISO); Series series = seriesMap.get(country); if (series == null) { series = new Series(indicator, country); seriesMap.put(country, series); } try { pointList.add(new Point( series, Integer.valueOf(dateElement.getTextContent()), Double.valueOf(valueElement.getTextContent()))); } catch (NumberFormatException exception) { continue; } } return this; } }