Java tutorial
/* * OpenRemote, the Home of the Digital Home. * Copyright 2008-2016, OpenRemote Inc. * * See the contributors.txt file in the distribution for a * full listing of individual contributors. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.openremote.foxycart.resources; import flexjson.JSONDeserializer; import flexjson.JSONSerializer; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.net.URLCodec; import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataParam; import org.openremote.rest.GenericResourceResultWithErrorMessage; import org.openremote.useraccount.domain.AccountDTO; import org.openremote.useraccount.domain.RoleDTO; import org.openremote.useraccount.domain.UserDTO; import org.restlet.data.ChallengeScheme; import org.restlet.ext.json.JsonRepresentation; import org.restlet.representation.Representation; import org.restlet.resource.ClientResource; import org.restlet.resource.ResourceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.encoding.Md5PasswordEncoder; import org.w3c.dom.Document; import org.xml.sax.InputSource; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.servlet.ServletConfig; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.IOException; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.sql.Timestamp; import java.text.Normalizer; @Path("/datafeed") public class FoxyCartResource { public static final String INIT_PARAM_NAME_FOXYCART_KEY = "foxycart.key"; public static final String INIT_PARAM_NAME_PASSWORD = "uas.admin.password"; private static final String ADMIN_USER = "designer_appl"; private static final String USER_PASSWORD = "gjhsqhghf"; private static final int MAX_NUM_OF_UNIQUE_USER_NAMES = 50; protected final static Logger log = LoggerFactory.getLogger(FoxyCartResource.class); /* @GET() public String getFoxyCart() { return "Hello FoxyCart"; } */ @POST() @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) public Response setCustomer(@FormDataParam("FoxyData") FormDataBodyPart foxyCartBody, @Context ServletConfig servletConfig) { String key = servletConfig.getInitParameter(INIT_PARAM_NAME_FOXYCART_KEY); String password = servletConfig.getInitParameter(INIT_PARAM_NAME_PASSWORD); String foxyDataString = null; foxyDataString = new String(decrypt(decode(foxyCartBody.getValue()), key), StandardCharsets.UTF_8); Document doc = parseXML(foxyDataString); String firstName = evaluateXPath(doc, "/foxydata/transactions/transaction/customer_first_name/text()"); String lastName = evaluateXPath(doc, "/foxydata/transactions/transaction/customer_last_name/text()"); String eMail = evaluateXPath(doc, "/foxydata/transactions/transaction/customer_email/text()"); if (firstName == null) { String msg = "Could not find XML element 'customer_first_name'."; log.error(msg); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } if (lastName == null) { String msg = "Could not find XML element 'customer_last_name'."; log.error(msg); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } if (eMail == null) { String msg = "Could not find XML element 'customer_email'."; log.error(msg); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); throw new WebApplicationException(resp); } int count = 1; while (!createAccount(password, createUniqueUserName(firstName, lastName, count), eMail)) { ++count; if (count > MAX_NUM_OF_UNIQUE_USER_NAMES) { String msg = "Did not create user '" + createUniqueUserName(firstName, lastName, count) + "' because reached max number ('" + MAX_NUM_OF_UNIQUE_USER_NAMES + "') of unique users."; log.error(msg); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg) .build(); throw new WebApplicationException(resp); } } return Response.status(Response.Status.OK).entity("foxy").build(); } private Document parseXML(String data) { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = null; Document doc = null; try { docBuilder = docBuilderFactory.newDocumentBuilder(); doc = docBuilder.parse(new InputSource(new StringReader(data))); } catch (Exception e) { String msg = "Failed to parse XML data."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } return doc; } private String evaluateXPath(Document doc, String xPathExpression) { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); String text = null; try { XPathExpression expr = xpath.compile(xPathExpression); text = (String) expr.evaluate(doc, XPathConstants.STRING); } catch (XPathExpressionException e) { } return text; } private String createUserName(String firstName, String lastName) { firstName = removeDiacritics(firstName.toLowerCase()); lastName = removeDiacritics(lastName.toLowerCase()); String userName = firstName + "." + lastName; userName = userName.replaceAll("\\s+", "."); userName = userName.replaceAll("[-,_]+", "."); StringBuilder builder = new StringBuilder(); for (int i = 0; i < userName.length(); i++) { char c = userName.charAt(i); if ((c >= 'a' && c <= 'z') || c == '.') { builder.append(c); } } userName = builder.toString(); return userName; } private String createUniqueUserName(String firstName, String lastName, int count) { String userName = createUserName(firstName, lastName); if (count == 1) { return userName; } else { return userName + "." + count; } } private byte[] decode(String data) { try { return URLCodec.decodeUrl(data.getBytes()); } catch (DecoderException e) { String msg = "Invalid URL encoded data."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } } private byte[] decrypt(byte[] data, String key) { Cipher rc4 = null; try { rc4 = Cipher.getInstance("RC4"); } catch (GeneralSecurityException e) { String msg = "RC4 decryption algorithm was not found."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } try { rc4.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), "RC4")); } catch (InvalidKeyException e) { String msg = "Invalid key. Key has to be configured in web.xml. In addition make sure " + "Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files have been installed."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } try { return rc4.doFinal(data); } catch (GeneralSecurityException e) { String msg = "Failed to decrypt data with RC4 algorithm because of invalid data. In additon make sure " + "Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files have been installed."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } } private boolean createAccount(String password, String userName, String userEmail) { UserDTO user = new UserDTO(); user.setUsername(userName); user.setPassword(new Md5PasswordEncoder().encodePassword(USER_PASSWORD, userName)); user.setEmail(userEmail); user.setRegisterTime(new Timestamp(System.currentTimeMillis())); user.addRole(new RoleDTO("ROLE_ADMIN", Long.valueOf(3))); user.setAccount(new AccountDTO()); ClientResource cr = new ClientResource("http://designer.openremote.com/uas/rest/user"); cr.setChallengeResponse(ChallengeScheme.HTTP_BASIC, ADMIN_USER, password); Representation rep = new JsonRepresentation(new JSONSerializer().exclude("*.class").deepSerialize(user)); Representation r = null; try { r = cr.post(rep); } catch (ResourceException e) { String msg = "Rest call (POST) 'http://designer.openremote.com/uas/rest/user' failed."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR : " + msg).build(); throw new WebApplicationException(resp); } String str = null; try { str = r.getText(); } catch (IOException e) { String msg = "Failed to deserialize response from rest call (POST) 'http://designer.openremote.com/uas/rest/user'."; log.error(msg, e); Response resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ERROR" + msg).build(); throw new WebApplicationException(resp); } GenericResourceResultWithErrorMessage res = new JSONDeserializer<GenericResourceResultWithErrorMessage>() .use(null, GenericResourceResultWithErrorMessage.class).use("result", Long.class).deserialize(str); if (res.getErrorMessage() != null) { String msg = "Account creation failed (username='" + userName + "', E-Mail='" + userEmail + "') : " + res.getErrorMessage(); System.out.println(msg); log.warn(msg); return false; } else { String msg = "Created user account (username='" + userName + "', E-Mail='" + userEmail + "') oid : " + res.getResult(); System.out.println(msg); log.info(msg); return true; } } private String removeDiacritics(String text) { // characters text = text.replace("\u00E4", "ae"); text = text.replace("\u00F1", "ny"); text = text.replace("\u00F6", "oe"); text = text.replace("\u00FC", "ue"); text = text.replace("\u00FF", "yu"); text = Normalizer.normalize(text, Normalizer.Form.NFD); text = text.replaceAll("\\p{M}", ""); text = text.replace("\u00DF", "ss"); text = text.replace("\u00C6", "AE"); text = text.replace("\u00E6", "ae"); text = text.replace("\u0132", "IJ"); text = text.replace("\u0133", "ij"); text = text.replace("\u0152", "Oe"); text = text.replace("\u0153", "oe"); // ?? text = text.replace("\u00D0", "D"); text = text.replace("\u0110", "D"); text = text.replace("\u00F0", "d"); text = text.replace("\u0111", "d"); text = text.replace("\u0126", "H"); text = text.replace("\u0127", "h"); // ? text = text.replace("\u0131", "i"); text = text.replace("\u0138", "k"); text = text.replace("\u013F", "L"); text = text.replace("\u0141", "L"); text = text.replace("\u0140", "l"); text = text.replace("\u0142", "l"); // text = text.replace("\u014A", "N"); text = text.replace("\u0149", "n"); text = text.replace("\u014B", "n"); text = text.replace("\u00D8", "O"); text = text.replace("\u00F8", "o"); text = text.replace("\u017F", "s"); // text = text.replace("\u00DE", "T"); text = text.replace("\u0166", "T"); text = text.replace("\u00FE", "t"); text = text.replace("\u0167", "t"); return text; } }