import java.io.*;
import java.security.*;
import java.text.*;
import java.util.*;

import javax.crypto.*;
import javax.crypto.spec.*;
import javax.xml.soap.*;
import javax.xml.transform.*;

import org.apache.commons.codec.binary.*;

/** 
*/

public class WebServiceTestExample {
  private String publicKey = "[place your public key here]";
  private String privateKey = "[Place your private key here]";
  private String serviceName = "v4";
  private String url = "https://[place your virtual host here].digitalchalk.com/dc/api/v4";

  public static void main(String[] args) {
    WebServiceTestExample example = new WebServiceTestExample();
    try {
      example.getAvailableOfferings("[place your username here]");
    } catch (SOAPException e) {
      e.printStackTrace();
    } catch (TransformerException e) { 
      e.printStackTrace();
    } catch (IOException e) { 
      e.printStackTrace();
    }
  }
  
  public void getAvailableOfferings(String username) throws SOAPException, TransformerException, IOException {
    SOAPMessage msg = MessageFactory.newInstance().createMessage(); 
    SOAPPart p = msg.getSOAPPart();
    SOAPEnvelope env = p.getEnvelope();
    SOAPBody body = env.getBody();
    String prefix="dcAPI";
    String uri = "http://digitalchalk.com/api/v4";

    SOAPBodyElement root = body.addBodyElement(env.createName("getAvailableOfferingsRequest", prefix, uri));
    SOAPElement auth = root.addChildElement(env.createName("auth", prefix, uri)); 
    SOAPElement ak = auth.addChildElement(env.createName("accessKey", prefix, uri)); 
    ak.addTextNode(publicKey);
    SOAPElement ts = auth.addChildElement(env.createName("timestamp", prefix, uri)); 
    Date now = new Date();
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 
    fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    ts.setTextContent(fmt.format(now));
    SOAPElement signature = auth.addChildElement(env.createName("signature", prefix, uri));

    String toSign = serviceName + "getAvailableOfferings" + fmt.format(now); 
    signature.setTextContent(sign(toSign));
    SOAPElement emailElmt = root.addChildElement(env.createName("username", prefix, uri)); 
    emailElmt.setTextContent(username);
    SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance(); 
    SOAPConnection conn = factory.createConnection();

    // You can do something with the result after it is set here SOAPMessage result = conn.call(msg, url);
    result.writeTo(System.out);
  }

  public String sign(String string) {
    SecretKeySpec key = new SecretKeySpec(privateKey.getBytes(), "HmacSHA1");
    Mac mac; 
    
    try {
      mac = Mac.getInstance("HmacSHA1"); 
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException("Could not find sha1 algorithm", e);
    }
    
    try {
      mac.init(key);
    } catch (InvalidKeyException e) { 
      mac = null;
      throw new RuntimeException("Could not initialize the MAC algorithm", e);
    }
    
    byte[] signedBytes = null; 
    
    synchronized (mac) {
      try {
        signedBytes = mac.doFinal(string.getBytes("UTF-8"));
      } catch (UnsupportedEncodingException e) { 
        signedBytes = mac.doFinal(string.getBytes());
      } 
    }
  
    return new String(Base64.encodeBase64(signedBytes));
  } 

}