Java tutorial
package se.berazy.api.client; /** * Berazy Bookkeeping API Client * * @author <a href="mailto:johan@berazy.se">Johan Sall Larsson</a> * @version 1.0.0 * * MIT LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Properties; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import se.berazy.api.utils.EncryptionUtils; import se.berazy.api.utils.XmlUtils; /** * The Bookkeeping API client. * * @author <a href="mailto:johan@berazy.se">Johan Sall Larsson</a> * @since 1.0.0 */ public class PoSInvoiceClient { /** * Logging. */ static Logger log = LoggerFactory.getLogger(PoSInvoiceClient.class); /** * The customer number. */ Integer customerNo; /** * The Authentication token/key. */ String authToken; /** * The IP address. */ String ipAddress; /** * The .properties file name. */ static final String defaultPropertiesFile = "berazy-pos-invoice.properties"; /** * The read properties. */ static Properties properties; /** * Read lock to prevent re-initialization. */ static final Object readLock = new Object(); /** * The endpoint URL. */ static final String createInvoiceEndpointUrl = "https://www.berazy.se/API/createInvoiceBookkeeping"; /** * The endpoint URL. */ static final String creditInvoiceEndpointUrl = "https://www.berazy.se/API/creditInvoice"; /** * Default constructor. */ public PoSInvoiceClient() { } /** * Contructor with params. * * @param customerNo * @param authToken * @param ipAddress */ public PoSInvoiceClient(Integer customerNo, String authToken, String ipAddress) { this.setCustomerNo(customerNo); this.setAuthToken(authToken); this.setIpAddress(ipAddress); } /** * Creates an invoice. * * @param request * @return MethodCallType * @throws ClientProtocolException * @throws IOException */ public se.berazy.api.createinvoicepos.MethodCallType createInvoice( se.berazy.api.createinvoicepos.RequestType request) throws ClientProtocolException, IOException { se.berazy.api.createinvoicepos.ObjectFactory objectFactory = new se.berazy.api.createinvoicepos.ObjectFactory(); se.berazy.api.createinvoicepos.MethodCallType methodCallType = new se.berazy.api.createinvoicepos.MethodCallType(); methodCallType.setMethodName("createInvoice"); methodCallType.setRequest(request); JAXBElement<se.berazy.api.createinvoicepos.MethodCallType> methodCall = objectFactory .createMethodCall(methodCallType); return sendRequest(createInvoiceEndpointUrl, methodCall, se.berazy.api.createinvoicepos.MethodCallType.class); } /** * Credits an invoice. * * @param request * @return List<ResponseType> * @return MethodCallType * @throws ClientProtocolException * @throws IOException */ public se.berazy.api.creditinvoice.MethodCallType creditInvoice( List<se.berazy.api.creditinvoice.RequestType> request) throws ClientProtocolException, IOException { se.berazy.api.creditinvoice.ObjectFactory objectFactory = new se.berazy.api.creditinvoice.ObjectFactory(); se.berazy.api.creditinvoice.MethodCallType methodCallType = new se.berazy.api.creditinvoice.MethodCallType(); methodCallType.setMethodName("creditInvoice"); methodCallType.getRequest().addAll(request); JAXBElement<se.berazy.api.creditinvoice.MethodCallType> methodCall = objectFactory .createMethodCall(methodCallType); return sendRequest(creditInvoiceEndpointUrl, methodCall, se.berazy.api.creditinvoice.MethodCallType.class); } /** * Sends a POST request. * * @param object * @throws ClientProtocolException * @throws IOException */ <TRequest, TResponse> TResponse sendRequest(String url, JAXBElement<TRequest> requestObject, Class<TResponse> responseObject) throws IOException, ClientProtocolException { loadProperties(); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); String key = EncryptionUtils.hash((getIpAddress() + formatter.format(new Date()) + getAuthToken())); httpPost.addHeader("accept", "application/xml"); httpPost.addHeader("customerNo", getCustomerNo().toString()); httpPost.addHeader("key", key); try { String data = XmlUtils.serialize(requestObject); StringEntity stringEntity = new StringEntity(data); stringEntity.setContentType("application/xml"); stringEntity.setContentEncoding("UTF-8"); httpPost.setEntity(stringEntity); log.debug(String.format("XML request: ", data)); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); try { InputStream is = response.getEntity().getContent(); return XmlUtils.deserialize(is, responseObject); } catch (IOException e) { throw e; } catch (RuntimeException e) { httpPost.abort(); throw e; } finally { try { instream.close(); } catch (Exception e) { log.warn("Cannot close response stream.", e); } } } else { throw new ClientProtocolException("Response contains no content"); } } catch (JAXBException e) { throw new ClientProtocolException("Malformed XML", e); } finally { httpClient.getConnectionManager().shutdown(); } } /** * Loads the .properties file and sets authToken, customerNo * and ipAddress. * * @throws IOException */ void loadProperties() throws IOException { if (getCustomerNo() == null || getAuthToken() == null || getIpAddress() == null) { if (properties == null) { synchronized (readLock) { if (properties == null) { log.debug(String.format("Loading properties from %s.", defaultPropertiesFile)); ClassLoader loader = PoSInvoiceClient.class.getClassLoader(); InputStream in = loader.getResourceAsStream(defaultPropertiesFile); properties = new Properties(); properties.load(in); this.setCustomerNo(Integer.parseInt(properties.getProperty("customerNo"))); this.setAuthToken(properties.getProperty("authToken")); this.setIpAddress(properties.getProperty("ipAddress")); } } } } } /** * Returns the customer number. */ public Integer getCustomerNo() { return customerNo; } /** * Sets the customer number. * @param customerNo */ public void setCustomerNo(Integer customerNo) { this.customerNo = customerNo; } /** * Returns the authentication token/key. */ public String getAuthToken() { return authToken; } /** * Sets the authentication token/key. * @param authToken */ public void setAuthToken(String authToken) { this.authToken = authToken; } /** * Returns the IP address. */ public String getIpAddress() { return ipAddress; } /** * Sets the IP address. * @param ipAddress */ public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } }