import java.io.InputStream ;
import java.io.IOException ;
import java.lang.System ;
import java.net.URL ;
import java.net.HttpURLConnection ;
import javax.xml.parsers.DocumentBuilder ;
import javax.xml.parsers.DocumentBuilderFactory ;
import javax.xml.xpath.XPath ;
import javax.xml.xpath.XPathConstants ;
import javax.xml.xpath.XPathFactory ;
import org.w3c.dom.Document ;
import org.w3c.dom.Node ;
import org.w3c.dom.NodeList ;

/**
 * A tutorial example of using XPath to parse XML resource on the Doxpop Court Api.
 * For more information on XPath, see the w3schools tutorial at 
 * http://www.w3schools.com/xpath/
 */
public class XMLClient {

  private static String contextUrl = "https://demo-api.doxpop.com" ;
  // userPass is base64-encoded user:password
  private static String userPass = "ZGVtbzpkZW1v" ; 

  public static InputStream getPage( URL url ) throws IOException
  {
    HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;
    conn.setRequestProperty("Authorization", "Basic " + userPass) ;
    conn.connect() ;
    return (InputStream) conn.getContent() ;
  }

  public static void main( String[] args ) throws Exception
  {
    URL context = new URL( contextUrl ) ;

    URL queryUrl = new URL( context, "/actors_cases.xml?fullname=rifkind,+david" ) ;
    XPath xpath = XPathFactory.newInstance().newXPath() ;
    String expression = "/response/actor_case" ;
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance() ;
    DocumentBuilder docbuilder = dbFactory.newDocumentBuilder() ;
    Document doc = docbuilder.parse( getPage( queryUrl ) ) ;
    NodeList nodes = (NodeList) xpath.evaluate(expression, doc, 
        XPathConstants.NODESET) ;
    for ( int i=0; i < nodes.getLength(); i++ ) 
    {
      Node node = nodes.item(i) ;
      System.out.println( xpath.evaluate( "assigned_case_role", node ) ) ;

      // Some actor information
      Node actor = (Node) xpath.evaluate( "actor", node, XPathConstants.NODE ) ;
      System.out.println( xpath.evaluate( "actor_full_name", actor ) ) ;
      System.out.println( xpath.evaluate( "actor_person_date_of_birth", actor ) ) ;

      // Some address information
      NodeList addresses = (NodeList) xpath.evaluate( "addresses/address", 
          actor, XPathConstants.NODESET ) ;
      for ( int j=0; j < addresses.getLength(); j++ )
      {
        Node address = addresses.item(j) ;
        System.out.println( xpath.evaluate( "address_line1", address ) ) ;
        System.out.println( xpath.evaluate( "address_city", address ) ) ;
        System.out.println( xpath.evaluate( "address_state_province_code", address ) ) ;
        System.out.println( xpath.evaluate( "address_postal_code", address ) ) ;
      }

      // Some case information
      Node caseNode = (Node) xpath.evaluate( "case", node, XPathConstants.NODE ) ;
      System.out.println( xpath.evaluate( "case_caption", caseNode ) ) ;
      System.out.println( xpath.evaluate( "case_global_disposition_code", caseNode ) ) ;
      System.out.println( xpath.evaluate( "case_disposition_date", caseNode ) ) ;

      // Extract and use the charges URI.
      String chargesUri = xpath.evaluate( "charges_uri", caseNode ) ;
      System.out.println( chargesUri ) ;
      URL chargesUrl = new URL( context, chargesUri + ".xml" ) ;
      Document chargesDoc = docbuilder.parse( getPage( chargesUrl ) ) ;
      NodeList charges = (NodeList) xpath.evaluate("/response/charge", chargesDoc,
          XPathConstants.NODESET) ;
      for ( int k=0; k < charges.getLength(); k++ )
      {
        Node chargeNode = charges.item(k) ;
        System.out.println( xpath.evaluate( "charge_desc", chargeNode ) ) ;
      }
    }
  }
}
