import javax.xml.soap.*;
import java.util.Iterator;
import java.net.URL;
import java.io.*;
      
public class Client {
    
    public static void main(String [] args) {
        try {
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = soapConnectionFactory.createConnection();
            SOAPFactory soapFactory = SOAPFactory.newInstance();
            
            MessageFactory factory = MessageFactory.newInstance();
            SOAPMessage message = factory.createMessage();
            
            SOAPBody body = message.getSOAPBody();
            Name bodyName = soapFactory.createName("getCurrentPredictionStations", "", "urn:CurrentPredictionStations");
            body.addBodyElement(bodyName);
            
            System.out.print("\nPrinting the message that is being sent: \n\n");
            message.writeTo(System.out);
            System.out.println("\n\n");
            
            URL endpoint = new URL ("https://opendap.co-ops.nos.noaa.gov/axis/services/CurrentPredictionStations");
            SOAPMessage response = connection.call(message, endpoint);
            connection.close();
            
            /*
            System.out.println("\nPrinting the respone that was recieved: \n\n" );
            response.writeTo(System.out);
            */  
    
            //Uncoment this part if you want the response to be saved locally in an XML file
            /*
            FileOutputStream fout = new FileOutputStream ("SoapResponse.xml");
            response.writeTo(fout);
            fout.close();
            */
       
            //You can also stores the response as a String
            /*
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.writeTo( out );
            String str = out.toString();  
            */
            
            System.out.println("\n\nIterating through the response object to get the values:\n\n");
            SOAPBody responseBody = response.getSOAPBody();
            
            //Checking for errors
            if (responseBody.hasFault()) {
                SOAPFault newFault = responseBody.getFault();
                System.out.println("SAOP FAULT:\n");
                System.out.println("code = " + newFault.getFaultCodeAsName());
                System.out.println("message = " + newFault.getFaultString());
                System.out.println("actor = " + newFault.getFaultActor());
            } else {
                Iterator iterator = responseBody.getChildElements();
                Iterator iterator2, iterator3, iterator4, iterator5;
                
                String tagName = null;
                SOAPElement se = null;
                Name attributeName = null;
                
                if (iterator.hasNext()) {
                    se = (SOAPElement)iterator.next();  //stations tag
                    iterator2 = se.getChildElements();
                    se = (SOAPElement)iterator2.next();  //station tag
                    iterator2 = se.getChildElements();
                    while (iterator2.hasNext()) {
                        se = (SOAPElement)iterator2.next();
                        tagName = se.getElementName().getLocalName();
                        System.out.println("\n\n******************************************************");
                        if (tagName != null && tagName.equals("station")) {
                            //attributes for a station                            
                            attributeName = soapFactory.createName("ID");
                            System.out.println("Station ID:\t" + se.getAttributeValue(attributeName));  //station ID 
                            attributeName = soapFactory.createName("name");
                            System.out.println("Station Name:\t" + se.getAttributeValue(attributeName));  //station Name  
                        
                            // stationBin & metadata element
                            iterator3 = se.getChildElements();
                            while (iterator3.hasNext()) {
                                se = (SOAPElement)iterator3.next(); // stationBin/metadata 
                                iterator4 = se.getChildElements(); // location and stationType

                                // Get BinNumber/Location
                                se = (SOAPElement)iterator4.next(); // (BinNumber & Depth)/(location & stationType)
                                tagName = se.getElementName().getLocalName();
                                if (tagName != null && tagName.equals("binNumber")) {
                                    System.out.println("Bin Number:\t" + se.getValue());
                                }
                                if (tagName != null && tagName.equals("location")) {
                                    iterator5 = se.getChildElements(); // lat and long
                            	    while (iterator5.hasNext()){
                               	        se = (SOAPElement)iterator5.next();
                                        tagName = se.getElementName().getLocalName();                                        
                                        if (tagName !=null && tagName.equals("lat")) {
                                            System.out.print("Latitude:");
                                        } else if (tagName!= null && tagName.equals("long")) {
                                            System.out.print("Longitude:");
                                        }          
                                        System.out.println("\t" + se.getValue());
                                    }  
                                }    
                                                        	
                                // Get depth/Station Type
                                se = (SOAPElement)iterator4.next();
                                tagName = se.getElementName().getLocalName();
                                if (tagName != null && tagName.equals("depth")) {
                                    System.out.println("Depth(feet):\t" + se.getValue());
                                }
                                if (tagName != null && tagName.equals("stationType")) {
                                    System.out.println("StationType:\t" + se.getValue());
                                } 
                            }
                        }               
                    }                 
                }        
            }
        } catch (SOAPException e) {
            System.err.println("ERROR: ******* " + e.toString());
        } catch (IOException io) {
            System.err.println("ERROR: ******* " + io.toString());
        }
    }
}    
 
/****************************************************
        SAMPLE RUN

>java Client

Sample Output (The entire output is omitted as it is too long)


******************************************************
Station ID:   lc0201
Station Name: Calcasieu Pass, Cameron Fishing Pier
Bin Number:   30
Depth(feet):  15.0
Latitude:     29.7641
Longitude:    -93.3429
StationType:  Harmonic


******************************************************
Station ID:   nb0101
Station Name: Providence River, Fox Point Reach
Bin Number:   8
Depth(feet):  11.0
Latitude:     41.8087
Longitude:    -71.3975
StationType:  Harmonic


******************************************************
Station ID:   nb0101
Station Name: Providence River, Fox Point Reach
Bin Number:   2
Depth(feet):  31.0
Latitude:     41.8087
Longitude:    -71.3975
StationType:  Weak and variable


******************************************************/