package rewards.ws.client; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import org.springframework.util.xml.DomUtils; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import rewards.AccountContribution; import rewards.Dining; import rewards.RewardConfirmation; import rewards.RewardNetwork; import rewards.AccountContribution.Distribution; import common.money.MonetaryAmount; import common.money.Percentage; public class SoapRewardNetwork extends WebServiceGatewaySupport implements RewardNetwork { private static final String NAMESPACE_URI = "http://www.springsource.com/reward-network"; public RewardConfirmation rewardAccountFor(Dining dining) { Element requestElement = prepareRequest(dining); DOMSource source = new DOMSource(requestElement); DOMResult result = new DOMResult(); getWebServiceTemplate().sendSourceAndReceiveToResult(source, result); return processResponse(result.getNode()); } private Element prepareRequest(Dining dining) { Document document = getDocument(); Element requestElement = document.createElementNS(NAMESPACE_URI, "rewardAccountForDiningRequest"); requestElement.appendChild(mapDining(document, dining)); return requestElement; } private Element mapDining(Document document, Dining dining) { Element diningElement = document.createElementNS(NAMESPACE_URI, "dining"); diningElement.setAttribute("amount", dining.getAmount().toString()); diningElement.setAttribute("creditCardNumber", dining.getCreditCardNumber()); diningElement.setAttribute("merchantNumber", dining.getMerchantNumber()); return diningElement; } private Document getDocument() { try { return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } } private RewardConfirmation processResponse(Node node) { Element responseElement = (Element) node.getFirstChild(); return mapRewardConfirmation(DomUtils.getChildElementByTagName(responseElement, "rewardConfirmation")); } private RewardConfirmation mapRewardConfirmation(Element confirmationElement) { String confirmationNumber = confirmationElement.getAttribute("confirmationNumber"); String accountNumber = confirmationElement.getAttribute("accountNumber"); String amount = confirmationElement.getAttribute("amount"); List<Element> distributionElements = DomUtils.getChildElementsByTagName(confirmationElement, "distribution"); AccountContribution contribution = new AccountContribution(accountNumber, MonetaryAmount.valueOf(amount), mapDistributions(distributionElements)); return new RewardConfirmation(confirmationNumber, contribution); } private Set<Distribution> mapDistributions(List<Element> distributionElements) { Set<Distribution> distributions = new HashSet<Distribution>(distributionElements.size()); for (Element element : distributionElements) { String beneficiary = element.getAttribute("beneficiary"); String amount = element.getAttribute("amount"); String percentage = element.getAttribute("percentage"); String totalSavings = element.getAttribute("totalSavings"); Distribution distribution = new Distribution(beneficiary, MonetaryAmount.valueOf(amount), Percentage .valueOf(percentage), MonetaryAmount.valueOf(totalSavings)); distributions.add(distribution); } return distributions; } }