WaterLocations_CDSN.java [src/WaterLocations] Revision: default  Date:
package WaterLocations;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;

/**
 * Last Updated: 27-June-2019
 * @author robert, Tyler Wible
 * @since April-2017
 */
public class WaterLocations_CDSN implements WaterLocationsInterface {
    String database = "CDSN";
    
    @Override
    public ArrayList<String> downloadStations(String minLat, String maxLat, String minLong, String maxLong, boolean keepHistoricTF) throws WaterLocationsException {
        //http://awqms.goldsystems.com/api/MonitoringLocationsVer1?ContentType=xml&MinimumLatitude=40.43&MaximumLatitude=40.5&MinimumLongitude=-104.7&MaximumLongitude=-105.9&IncludeResultSummary=TRUE
        String requestCDSN = "http://awqms.goldsystems.com/api/MonitoringLocationsVer1?ContentType=xml" +
                "&MinimumLatitude=" + minLat + "&MaximumLatitude=" + maxLat +
                "&MinimumLongitude=" + minLong + "&MaximumLongitude=" + maxLong;
        ArrayList<String> pageData = new ArrayList<>();
        try{
            //From CDSNData
            URL webpage = new URL(requestCDSN);
            URLConnection yc = webpage.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));

            //Read out all of the webpage out into an ArrayList<String>
            boolean moreLines = true;
            while (moreLines) {
                try {
                    String inputLine = in.readLine();
                    if (inputLine != null) {
                        pageData.add(inputLine);
                    } else {
                        moreLines = false;
                    }
                } catch (SocketException e) {
                    //There was an issue with the webpage, so quit out
                    moreLines = false;
                }
            }

            in.close();
            //End CDSNData
        } catch (IOException ex) {
            throw new WaterLocationsException("The was an issue extracting " + database + " station locations from the specified URl: " + requestCDSN + ". " + ex.getMessage());
        }
        
        return pageData;
    }
    
    @Override
    public ArrayList<Station> getStations(String minLat, String maxLat, String minLong, String maxLong, boolean keepHistoricTF) throws WaterLocationsException {
        String requestCDSN = "http://awqms.goldsystems.com/api/MonitoringLocationsVer1?ContentType=xml" + 
                "&MinimumLatitude=" + minLat + "&MaximumLatitude=" + maxLat + 
                "&MinimumLongitude=" + minLong + "&MaximumLongitude=" + maxLong;
//        //Could add this in the future for station metadata, it creates a "ResultSummaries" entry with a "ResultSummary" per water quality parameter (including flow)
//        requestCDSN += "&IncludeResultSummary=TRUE";
        ArrayList<Station> stations = new ArrayList();
        try {
            URL webpage = new URL(requestCDSN);
            URLConnection yc = webpage.openConnection();
            
            //StAX XML Parsing
            XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
            XMLEventReader xmlReader = xmlFactory.createXMLEventReader(yc.getInputStream());
            String huc8 = null;
            String lat = null;
            String lon = null;
            String stationId = null;
            String stationName = null;
            String stationType = null;
            String orgId = null;
            
            while (xmlReader.hasNext()) {
                XMLEvent event = xmlReader.nextEvent();
                if (event.isStartElement()) {   //Event is starting tag
                    StartElement start = event.asStartElement();
                    if (start.getName().getLocalPart().equals("Huc8")) {
                        huc8 = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("Latitude")) {
                        lat = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("Longitude")) {
                        lon = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("MonitoringLocationIdentifier")) {
                        stationId = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("MonitoringLocationName")) {
                        stationName = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("MonitoringLocationType")) {
                        stationType = checkEventText(xmlReader);
                    } else if (start.getName().getLocalPart().equals("OrganizationIdentifier")) {
                        orgId = checkEventText(xmlReader);
                    }
                }
                
                if (event.isEndElement()) { //Event is closing tag
                    EndElement end = event.asEndElement();
                    
                    if (end.getName().getLocalPart().equals("MonitoringLocation")) {
                        Station currentStation = new Station(database + "-" + stationId);
                        currentStation.SetStationId(stationId);
                        currentStation.SetStationName(stationName);
                        currentStation.SetLongitude(lon);
                        currentStation.SetLatitude(lat);
                        currentStation.SetOrgId(orgId);
                        currentStation.SetStationType(stationType);
                        currentStation.SetHUC(huc8);
                        stations.add(currentStation);
                        
                        //Re-initialize the station parameters so that if a station is missing information, the previous data isn't copied over
                        huc8 = null;
                        lat = null;
                        lon = null;
                        stationId = null;
                        stationName = null;
                        stationType = null;
                        orgId = null;
                    }
                }
            }
        } catch (XMLStreamException | IOException ex) {
            throw new WaterLocationsException("The was an issue extracting " + database + " station locations from the specified URl: " + requestCDSN + ". " + ex.getMessage());
        }
        
        return stations;        
    }
    
    private static String checkEventText(XMLEventReader xmlReader) throws XMLStreamException{
        String textString = null;
        XMLEvent event = xmlReader.nextEvent();
        if (event.isCharacters()) {
            textString = event.asCharacters().getData();
        }
        return textString;
    }
}