From 7d8713e88c7872b195f7e4d02ac4812536ae196b Mon Sep 17 00:00:00 2001
From: rsanchez <rsanchez@curisit.net>
Date: Tue, 22 Sep 2015 13:53:51 +0000
Subject: [PATCH] #2756 feature - Added lic activation using activationCode

---
 src/main/java/net/curisit/securis/LicenseValidator.java  |   12 +
 src/main/java/net/curisit/securis/beans/LicenseBean.java |    3 
 src/main/java/net/curisit/securis/utils/JsonUtils.java   |   20 ++
 src/main/java/net/curisit/securis/LicenseManager.java    |   75 ++++++--
 src/main/java/net/curisit/securis/ReqGenerator.java      |   13 +
 src/main/java/net/curisit/securis/beans/RequestBean.java |   71 +++++---
 pom.xml                                                  |    2 
 src/main/java/net/curisit/securis/License.java           |  277 +++++++++++++++++-----------------
 8 files changed, 283 insertions(+), 190 deletions(-)

diff --git a/pom.xml b/pom.xml
index b636874..722d682 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>net.curisit</groupId>
 	<artifactId>securis-client</artifactId>
-	<version>1.0.6-SNAPSHOT</version>
+	<version>1.1.0-SNAPSHOT</version>
 	<build>
 		<plugins>
 			<plugin>
diff --git a/src/main/java/net/curisit/securis/License.java b/src/main/java/net/curisit/securis/License.java
index f06a177..08e7781 100644
--- a/src/main/java/net/curisit/securis/License.java
+++ b/src/main/java/net/curisit/securis/License.java
@@ -41,163 +41,166 @@
  */
 public class License {
 
-	private static final Logger LOG = LogManager.getLogger(License.class);
+    private static final Logger LOG = LogManager.getLogger(License.class);
 
-	/**
-	 * Aplication entry point when it used as CLI
-	 * 
-	 * @param args
-	 * @throws URISyntaxException
-	 */
-	public static void main(String[] args) throws URISyntaxException {
+    /**
+     * Aplication entry point when it used as CLI
+     * 
+     * @param args
+     * @throws URISyntaxException
+     */
+    public static void main(String[] args) throws URISyntaxException {
 
-		LOG.debug("SeCuris client tool init ");
+        LOG.debug("SeCuris client tool init ");
 
-		checkConfigFile();
-		CommandLine cmd = getCommandLine(args);
+        checkConfigFile();
+        CommandLine cmd = getCommandLine(args);
 
-		try {
-			if (cmd.hasOption('g')) {
-				String filename = cmd.getOptionValue("rfile");
-				if (filename == null)
-					filename = "./license.req";
-				File file = new File(filename);
-				LicenseManager.getInstance().createRequestFile(file);
-				LOG.info("Request file {} generated OK", file.getAbsolutePath());
-				System.exit(0);
-			}
+        try {
+            if (cmd.hasOption('g')) {
+                String filename = cmd.getOptionValue("rfile");
+                if (filename == null)
+                    filename = "./license.req";
+                File file = new File(filename);
+                LicenseManager.getInstance().createRequestFile(file);
+                LOG.info("Request file {} generated OK", file.getAbsolutePath());
+                System.exit(0);
+            }
 
-			if (cmd.hasOption('l')) {
-				String filename = cmd.getOptionValue("validate");
-				if (filename == null)
-					filename = "./license.lic";
-				File file = new File(filename);
-				if (!file.exists()) {
-					throw new SeCurisException("The license file doesn't exist: " + file.getAbsolutePath());
-				}
-				try {
-					LicenseManager.getInstance().validateLicense(file);
-					LOG.info("License file {} is valid", file.getAbsolutePath());
-				} catch (SeCurisException e) {
-					LOG.info("License file {} is NOT valid", file.getAbsolutePath());
-					LOG.info("Reason: {}", e.toString());
-				}
+            if (cmd.hasOption('l')) {
+                String filename = cmd.getOptionValue("validate");
+                if (filename == null)
+                    filename = "./license.lic";
+                File file = new File(filename);
+                if (!file.exists()) {
+                    throw new SeCurisException("The license file doesn't exist: " + file.getAbsolutePath());
+                }
+                try {
+                    LicenseManager.getInstance().validateLicense(file);
+                    LOG.info("License file {} is valid", file.getAbsolutePath());
+                } catch (SeCurisException e) {
+                    LOG.info("License file {} is NOT valid", file.getAbsolutePath());
+                    LOG.info("Reason: {}", e.toString());
+                }
 
-				System.exit(0);
-			}
+                System.exit(0);
+            }
 
-			if (cmd.hasOption('c')) {
-				// TODO: Change CLI to get name and email in license request
-				SignedLicenseBean lic = LicenseManager.getInstance().requestLicense(null, null);
-				String filename = cmd.getOptionValue("c");
-				if (filename == null) {
-					filename = "./license.lic";
-				}
-				File file = new File(filename);
-				LicenseManager.getInstance().save(lic, file);
-				LOG.info("License file sucessfully saved in file: {}", file.getAbsolutePath());
-				System.exit(0);
-			}
+            if (cmd.hasOption('c')) {
+                // TODO: Change CLI to get name and email in license request
+                SignedLicenseBean lic = LicenseManager.getInstance().requestLicense(null, null);
+                String filename = cmd.getOptionValue("c");
+                if (filename == null) {
+                    filename = "./license.lic";
+                }
+                File file = new File(filename);
+                LicenseManager.getInstance().save(lic, file);
+                LOG.info("License file sucessfully saved in file: {}", file.getAbsolutePath());
+                System.exit(0);
+            }
 
-			if (cmd.hasOption('t')) {
-				LicenseManager.getInstance().testServer();
-				LOG.info("Server is OK, url: {}", Params.get(Params.KEYS.LICENSE_SERVER_URL, Params.DEFAUT_SERVER_URL));
+            if (cmd.hasOption('t')) {
+                LicenseManager.getInstance().testServer();
+                LOG.info("Server is OK, url: {}", Params.get(Params.KEYS.LICENSE_SERVER_URL, Params.DEFAUT_SERVER_URL));
 
-				System.exit(0);
-			}
+                System.exit(0);
+            }
 
-			if (cmd.hasOption('r')) {
-				String licFilename = cmd.getOptionValue("renew");
-				checkMandatoryParameter(licFilename, "renew");
-				File file = new File(licFilename);
-				if (!file.exists()) {
-					throw new SeCurisException("The license file doesn't exist: " + file.getAbsolutePath());
-				}
-				SignedLicenseBean newLic = LicenseManager.getInstance().renew(file);
-				File oldLicFile = new File(file.getAbsoluteFile() + ".old");
-				file.renameTo(oldLicFile);
-				LOG.info("Old license file has been renamed to: {}", oldLicFile.getAbsolutePath());
-				LicenseManager.getInstance().save(newLic, file);
-				LOG.info("New license file saved as: {}", file.getAbsolutePath());
-				System.exit(0);
-			}
+            if (cmd.hasOption('r')) {
+                String licFilename = cmd.getOptionValue("renew");
+                checkMandatoryParameter(licFilename, "renew");
+                File file = new File(licFilename);
+                if (!file.exists()) {
+                    throw new SeCurisException("The license file doesn't exist: " + file.getAbsolutePath());
+                }
+                SignedLicenseBean newLic = LicenseManager.getInstance().renew(file);
+                File oldLicFile = new File(file.getAbsoluteFile() + ".old");
+                file.renameTo(oldLicFile);
+                LOG.info("Old license file has been renamed to: {}", oldLicFile.getAbsolutePath());
+                LicenseManager.getInstance().save(newLic, file);
+                LOG.info("New license file saved as: {}", file.getAbsolutePath());
+                System.exit(0);
+            }
 
-		} catch (SeCurisException e) {
-			LOG.error("The command generated an error: {}", e.toString());
-		}
-	}
+        } catch (SeCurisException e) {
+            LOG.error("The command generated an error: {}", e.toString());
+        }
+    }
 
-	private static void checkMandatoryParameter(String value, String param) {
-		if (value == null) {
-			LOG.error("Parameter {} is mandatory. Use --help to get information about parameters", param);
-			System.exit(-5);
-		}
-	}
+    private static void checkMandatoryParameter(String value, String param) {
+        if (value == null) {
+            LOG.error("Parameter {} is mandatory. Use --help to get information about parameters", param);
+            System.exit(-5);
+        }
+    }
 
-	/**
-	 * Checks that config file exists and contains mandatory parameters
-	 */
-	private static void checkConfigFile() {
-		if (Params.get(Params.KEYS.LIC_TYPE_CODE) == null && Params.get(Params.KEYS.APPLICATION_CODE) == null) {
-			LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.LIC_TYPE_CODE);
-			System.exit(-3);
-		}
-		if (Params.get(Params.KEYS.CUSTOMER_CODE) == null) {
-			LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.CUSTOMER_CODE);
-			System.exit(-4);
-		}
-		if (Params.get(Params.KEYS.PACK_CODE) == null) {
-			LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.PACK_CODE);
-			System.exit(-6);
-		}
-	}
+    /**
+     * Checks that config file exists and contains mandatory parameters
+     */
+    private static void checkConfigFile() {
+        if (Params.get(Params.KEYS.APPLICATION_CODE) == null) {
 
-	private static CommandLine getCommandLine(String[] args) {
-		Options ops = prepareOptionCLI();
-		if (args.length == 0) {
-			printHelp(ops);
-		}
-		CommandLineParser parser = new PosixParser();
-		CommandLine cmd = null;
-		try {
-			cmd = parser.parse(ops, args);
-		} catch (ParseException e) {
-			printHelp(ops);
-		}
+            if (Params.get(Params.KEYS.LIC_TYPE_CODE) == null) {
+                LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.LIC_TYPE_CODE);
+                System.exit(-3);
+            }
+            if (Params.get(Params.KEYS.CUSTOMER_CODE) == null) {
+                LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.CUSTOMER_CODE);
+                System.exit(-4);
+            }
+            if (Params.get(Params.KEYS.PACK_CODE) == null) {
+                LOG.error("Manadatory parameter {} is not set in config file", Params.KEYS.PACK_CODE);
+                System.exit(-6);
+            }
+        } // else: The license will be got using activationCode
+    }
 
-		if (cmd.hasOption('h')) {
-			printHelp(ops);
-		}
+    private static CommandLine getCommandLine(String[] args) {
+        Options ops = prepareOptionCLI();
+        if (args.length == 0) {
+            printHelp(ops);
+        }
+        CommandLineParser parser = new PosixParser();
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(ops, args);
+        } catch (ParseException e) {
+            printHelp(ops);
+        }
 
-		return cmd;
-	}
+        if (cmd.hasOption('h')) {
+            printHelp(ops);
+        }
 
-	private static void printHelp(Options ops) {
-		HelpFormatter formatter = new HelpFormatter();
-		formatter.printHelp("securis-client", ops, true);
-		System.exit(-1);
-	}
+        return cmd;
+    }
 
-	@SuppressWarnings("static-access")
-	private static Options prepareOptionCLI() {
-		Options options = new Options();
+    private static void printHelp(Options ops) {
+        HelpFormatter formatter = new HelpFormatter();
+        formatter.printHelp("securis-client", ops, true);
+        System.exit(-1);
+    }
 
-		options.addOption("h", "help", false, "Show help.");
-		options.addOption(OptionBuilder.withArgName("req_file").withLongOpt("rfile")
-				.withDescription("Set request file for its generation or for license requesting.").hasArg(true).create('r'));
-		// options.addOption(OptionBuilder.withArgName("url_license_server").withLongOpt("server").withDescription("License server url.").hasArg(true).create('s'));
-		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("validate").withDescription("Validate lic file.").hasArg(true)
-				.create('l'));
+    @SuppressWarnings("static-access")
+    private static Options prepareOptionCLI() {
+        Options options = new Options();
 
-		options.addOption("g", "gen_request", false,
-				"Generate request file. If --rfile parameter is missing then It is generated in current directory.");
-		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("create").withDescription("Request a license file to server.")
-				.hasArg(true).hasOptionalArg().create('c'));
-		options.addOption("t", "test_lc", false, "Test if License Server (LC) is available. ");
-		options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("renew").withDescription("Synchronize/renew the current license file.")
-				.hasArg(true).create('r'));
+        options.addOption("h", "help", false, "Show help.");
+        options.addOption(OptionBuilder.withArgName("req_file").withLongOpt("rfile")
+                .withDescription("Set request file for its generation or for license requesting.").hasArg(true).create('r'));
+        // options.addOption(OptionBuilder.withArgName("url_license_server").withLongOpt("server").withDescription("License server url.").hasArg(true).create('s'));
+        options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("validate").withDescription("Validate lic file.").hasArg(true)
+                .create('l'));
 
-		return options;
-	}
+        options.addOption("g", "gen_request", false,
+                "Generate request file. If --rfile parameter is missing then It is generated in current directory.");
+        options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("create").withDescription("Request a license file to server.")
+                .hasArg(true).hasOptionalArg().create('c'));
+        options.addOption("t", "test_lc", false, "Test if License Server (LC) is available. ");
+        options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("renew").withDescription("Synchronize/renew the current license file.")
+                .hasArg(true).create('r'));
+
+        return options;
+    }
 
 }
diff --git a/src/main/java/net/curisit/securis/LicenseManager.java b/src/main/java/net/curisit/securis/LicenseManager.java
index 49fb807..01625fc 100644
--- a/src/main/java/net/curisit/securis/LicenseManager.java
+++ b/src/main/java/net/curisit/securis/LicenseManager.java
@@ -38,7 +38,8 @@
 	public static final String HEADER_LICENSE_NAME_OR_REFERENCE = "X-SECURIS-LIC-NAMEREF";
 	public static final String HEADER_LICENSE_EMAIL = "X-SECURIS-LIC-EMAIL";
 
-	private LicenseManager() {}
+	private LicenseManager() {
+	}
 
 	public static LicenseManager getInstance() {
 		return singleton;
@@ -62,7 +63,8 @@
 	}
 
 	/**
-	 * Validates the license stored in {@code licFile} and get the corresponding LicenseBean
+	 * Validates the license stored in {@code licFile} and get the corresponding
+	 * LicenseBean
 	 * <p>
 	 * The validation includes:
 	 * <ul>
@@ -82,7 +84,8 @@
 	}
 
 	/**
-	 * Validates the license stored in {@code licFile} and get the corresponding LicenseBean. The License date is not validated
+	 * Validates the license stored in {@code licFile} and get the corresponding
+	 * LicenseBean. The License date is not validated
 	 * <p>
 	 * The validation includes:
 	 * <ul>
@@ -99,7 +102,12 @@
 	public LicenseBean validateLicense(File licFile, boolean excludeDateValidation) throws SeCurisException {
 		LicenseBean licBean = load(licFile);
 		SignatureHelper.getInstance().validateSignature(licBean);
-		LicenseValidator.getInstance().validateHW(licBean, Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
+		if (licBean.getActivationCode() != null) {
+			LicenseValidator.getInstance().validateHW(licBean, Params.get(Params.KEYS.APPLICATION_CODE), licBean.getActivationCode());
+		} else {
+			LicenseValidator.getInstance().validateHW(licBean, Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)),
+					Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
+		}
 		LicenseValidator.getInstance().validateLogo(licBean);
 
 		if (!excludeDateValidation) {
@@ -118,7 +126,21 @@
 	 * @throws SeCurisException
 	 */
 	public SignedLicenseBean requestLicense(String nameOrReference, String email) throws SeCurisException {
-		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
+		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)),
+				Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
+
+		SignedLicenseBean lic = requestLicenseToServer(req, nameOrReference, email);
+		return lic;
+	}
+
+	/**
+	 * Request to server for a valid license
+	 * 
+	 * @return The license bean returned by the server
+	 * @throws SeCurisException
+	 */
+	public SignedLicenseBean requestLicense(String nameOrReference, String email, String activationCode) throws SeCurisException {
+		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.APPLICATION_CODE), activationCode);
 
 		SignedLicenseBean lic = requestLicenseToServer(req, nameOrReference, email);
 		return lic;
@@ -170,7 +192,8 @@
 	}
 
 	/**
-	 * Creates a new request file with current hardware in the File passed as parameter
+	 * Creates a new request file with current hardware in the File passed as
+	 * parameter
 	 * 
 	 * @param outputRequestFile
 	 *            File where the request data will be saved
@@ -178,7 +201,8 @@
 	 * @throws SeCurisException
 	 */
 	public RequestBean createRequestFile(File outputRequestFile) throws SeCurisException {
-		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)), Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
+		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.LIC_TYPE_CODE, Params.get(Params.KEYS.APPLICATION_CODE)),
+				Params.get(Params.KEYS.CUSTOMER_CODE), Params.get(Params.KEYS.PACK_CODE));
 
 		ReqGenerator.getInstance().save(req, outputRequestFile);
 
@@ -186,11 +210,30 @@
 	}
 
 	/**
-	 * Send the current license file to server, which is previously validated, to get a renewed one if it is prepared in server side.
+	 * Creates a new request file with current hardware in the File passed as
+	 * parameter
+	 * 
+	 * @param outputRequestFile
+	 *            File where the request data will be saved
+	 * @return The generated request bean
+	 * @throws SeCurisException
+	 */
+	public RequestBean createRequestFile(File outputRequestFile, String activationCode) throws SeCurisException {
+		RequestBean req = ReqGenerator.getInstance().createRequest(Params.get(Params.KEYS.APPLICATION_CODE), activationCode);
+
+		ReqGenerator.getInstance().save(req, outputRequestFile);
+
+		return req;
+	}
+
+	/**
+	 * Send the current license file to server, which is previously validated,
+	 * to get a renewed one if it is prepared in server side.
 	 * 
 	 * @param licenseFile
 	 *            Current and valid License file
-	 * @return New license bean if server creates a new one, otherwise the same current License bean will be returned
+	 * @return New license bean if server creates a new one, otherwise the same
+	 *         current License bean will be returned
 	 * @throws SeCurisException
 	 */
 	public SignedLicenseBean renew(File licenseFile) throws SeCurisException {
@@ -220,18 +263,4 @@
 		}
 	}
 
-	public static void main(String[] args) throws SeCurisException {
-		String filename  = "/Users/rob/.doxr/doxr.lic";
-
-		if (filename == null)
-			filename = "./license.req";
-		File file = new File(filename);
-		LicenseManager.getInstance().validateLicense(file);
-		LOG.info("Validation Ok");
-		String r = "{\"licenseTypeCode\":\"DX01\",\"packCode\":\"DEVDX01\",\"arch\":\"x86_64\",\"osName\":\"darwin\",\"customerCode\":\"CIT\",\"macAddresses\":[\"60:c5:47:03:cf:c8\",\"b2:00:12:b6:88:e0\"]}";
-		RequestBean rb = JsonUtils.json2object(r, RequestBean.class);
-		System.out.println(rb);
-		LOG.info("Request file {} generated OK", file.getAbsolutePath());
-
-	}
 }
diff --git a/src/main/java/net/curisit/securis/LicenseValidator.java b/src/main/java/net/curisit/securis/LicenseValidator.java
index c5d7e93..0a31755 100644
--- a/src/main/java/net/curisit/securis/LicenseValidator.java
+++ b/src/main/java/net/curisit/securis/LicenseValidator.java
@@ -61,8 +61,16 @@
     public void validateHW(RequestBean reqBean, String licTypeCode, String customerCode, String packCode) throws SeCurisException {
         RequestBean currentHW = ReqGenerator.getInstance().createRequest(licTypeCode, customerCode, packCode);
         if (!currentHW.match(reqBean)) {
-            throw new SeCurisException("Current System info mismatch the License System info:\n Licensed: \n" + JsonUtils.toPrettyJSON(reqBean)
-                    + "\n Expected: \n" + JsonUtils.toPrettyJSON(currentHW));
+            throw new SeCurisException("Current System info mismatch the License System info:\n Licensed: \n"
+                    + JsonUtils.toPrettyJSON(reqBean, RequestBean.class) + "\n Expected: \n" + JsonUtils.toPrettyJSON(currentHW));
+        }
+    }
+
+    public void validateHW(RequestBean reqBean, String appCode, String activationCode) throws SeCurisException {
+        RequestBean currentHW = ReqGenerator.getInstance().createRequest(appCode, activationCode);
+        if (!currentHW.match(reqBean)) {
+            throw new SeCurisException("Current System info mismatch the License System info:\n Licensed: \n"
+                    + JsonUtils.toPrettyJSON(reqBean, RequestBean.class) + "\n Expected: \n" + JsonUtils.toPrettyJSON(currentHW));
         }
     }
 
diff --git a/src/main/java/net/curisit/securis/ReqGenerator.java b/src/main/java/net/curisit/securis/ReqGenerator.java
index 4614a3b..d7565c9 100644
--- a/src/main/java/net/curisit/securis/ReqGenerator.java
+++ b/src/main/java/net/curisit/securis/ReqGenerator.java
@@ -44,6 +44,19 @@
         return req;
     }
 
+    public RequestBean createRequest(String appCode, String activationCode) throws SeCurisException {
+        RequestBean req = new RequestBean();
+
+        req.setAppCode(appCode);
+        req.setActivationCode(activationCode);
+        req.setArch(HWInfo.getArch());
+        req.setCrcLogo(getCrcLogo());
+        req.setMacAddresses(HWInfo.getMACAddress());
+        req.setOsName(HWInfo.getOsName());
+
+        return req;
+    }
+
     public RequestBean loadRequest(File requestFile) throws SeCurisException {
         try {
             String json = new String(Files.readAllBytes(Paths.get(requestFile.toURI())), "utf-8");
diff --git a/src/main/java/net/curisit/securis/beans/LicenseBean.java b/src/main/java/net/curisit/securis/beans/LicenseBean.java
index 8a40399..406e7aa 100644
--- a/src/main/java/net/curisit/securis/beans/LicenseBean.java
+++ b/src/main/java/net/curisit/securis/beans/LicenseBean.java
@@ -11,7 +11,8 @@
 
 @JsonAutoDetect
 @JsonPropertyOrder({
-        "appName", "licenseCode", "licenseTypeCode", "expirationDate", "arch", "osName", "customerCode", "macAddresses", "crcLogo", "metadata", "packCode"
+        "appCode", "appName", "licenseCode", "activationCode", "licenseTypeCode", "expirationDate", "arch", "osName", "customerCode", "macAddresses",
+        "crcLogo", "metadata", "packCode"
 })
 public class LicenseBean extends RequestBean {
     private Date expirationDate;
diff --git a/src/main/java/net/curisit/securis/beans/RequestBean.java b/src/main/java/net/curisit/securis/beans/RequestBean.java
index 369a355..3b206dd 100644
--- a/src/main/java/net/curisit/securis/beans/RequestBean.java
+++ b/src/main/java/net/curisit/securis/beans/RequestBean.java
@@ -2,9 +2,7 @@
 
 import java.util.Collections;
 import java.util.List;
-
-import net.curisit.securis.SeCurisException;
-import net.curisit.securis.utils.JsonUtils;
+import java.util.Objects;
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonInclude;
@@ -14,9 +12,11 @@
 @JsonAutoDetect
 @JsonInclude(Include.NON_NULL)
 @JsonPropertyOrder({
-        "licenseTypeCode", "packCode", "arch", "osName", "customerCode", "macAddresses", "crcLogo"
+        "appCode", "activationCode", "licenseTypeCode", "packCode", "arch", "osName", "customerCode", "macAddresses", "crcLogo"
 })
 public class RequestBean {
+    private String appCode;
+    private String activationCode;
     private String customerCode;
     private String crcLogo;
     private String licenseTypeCode;
@@ -24,6 +24,14 @@
     private List<String> macAddresses;
     private String osName;
     private String arch;
+
+    public String getActivationCode() {
+        return activationCode;
+    }
+
+    public void setActivationCode(String activationCode) {
+        this.activationCode = activationCode;
+    }
 
     public String getCustomerCode() {
         return customerCode;
@@ -48,9 +56,9 @@
     public void setMacAddresses(List<String> macAddresses) {
         // We need to be sure that the same mac addresses are always shown in
         // the same order, to generate a valid hash
-    	if (macAddresses != null) {
-    		Collections.<String> sort(macAddresses);
-    	}
+        if (macAddresses != null) {
+            Collections.<String> sort(macAddresses);
+        }
         this.macAddresses = macAddresses;
     }
 
@@ -71,13 +79,21 @@
     }
 
     public boolean match(RequestBean rb) {
+        boolean result = true;
+        if (activationCode != null) {
+            result = result && activationCode.equals(rb.activationCode);
+            // appCode is optional
+            result = result && (appCode == null || appCode.equals(rb.appCode));
+        } else {
+            // If activationCode exists then we ignore other license identifiers
+            result = result && licenseTypeCode != null && licenseTypeCode.equals(rb.licenseTypeCode);
+            result = result && (customerCode != null && customerCode.equals(rb.customerCode));
+            result = result && (packCode != null && packCode.equals(rb.packCode));
+        }
 
-        boolean result = licenseTypeCode != null && licenseTypeCode.equals(rb.licenseTypeCode);
-        result = result && (packCode != null && packCode.equals(rb.packCode));
         result = result && (arch != null && arch.equals(rb.arch));
         // CRC Logo validation is optional, only if request file contains it
         result = result && (crcLogo == null || crcLogo.equals(rb.crcLogo));
-        result = result && (customerCode != null && customerCode.equals(rb.customerCode));
         result = result && (osName != null && osName.equals(rb.osName));
         result = result && (macAddresses != null && rb.macAddresses != null) && anyMacIsIncluded(rb.getMacAddresses());
 
@@ -95,6 +111,8 @@
     @Override
     public int hashCode() {
         int code = 0;
+        code += appCode != null ? appCode.hashCode() : 0;
+        code += activationCode != null ? activationCode.hashCode() : 0;
         code += licenseTypeCode != null ? licenseTypeCode.hashCode() : 0;
         code += arch != null ? arch.hashCode() : 0;
         code += crcLogo != null ? crcLogo.hashCode() : 0;
@@ -111,14 +129,17 @@
         if (!(obj instanceof RequestBean))
             return false;
         RequestBean rb = (RequestBean) obj;
-        boolean result = (rb.licenseTypeCode == null && licenseTypeCode == null)
-                || (licenseTypeCode != null && licenseTypeCode.equals(rb.licenseTypeCode));
-        result = result && ((rb.packCode == null && packCode == null) || (packCode != null && packCode.equals(rb.arch)));
-        result = result && ((rb.arch == null && arch == null) || (arch != null && arch.equals(rb.arch)));
-        result = result && ((rb.crcLogo == null && crcLogo == null) || (crcLogo != null && crcLogo.equals(rb.crcLogo)));
-        result = result && ((rb.customerCode == null && customerCode == null) || (customerCode != null && customerCode.equals(rb.customerCode)));
-        result = result && ((rb.osName == null && osName == null) || (osName != null && osName.equals(rb.osName)));
-        result = result && ((rb.macAddresses == null && macAddresses == null) || (macAddresses != null && macAddresses.equals(rb.macAddresses)));
+
+        boolean result = true;
+        result = result && Objects.equals(appCode, rb.appCode);
+        result = result && Objects.equals(activationCode, rb.activationCode);
+        result = result && Objects.equals(licenseTypeCode, rb.licenseTypeCode);
+        result = result && Objects.equals(packCode, rb.packCode);
+        result = result && Objects.equals(arch, rb.arch);
+        result = result && Objects.equals(crcLogo, rb.crcLogo);
+        result = result && Objects.equals(customerCode, rb.customerCode);
+        result = result && Objects.equals(osName, rb.osName);
+        result = result && Objects.equals(macAddresses, rb.macAddresses);
         return result;
     }
 
@@ -138,13 +159,11 @@
         this.licenseTypeCode = licenseTypeCode;
     }
 
-    public static void main(String[] args) {
-        String requestData = "{\n    \"licenseTypeCode\": \"CI01\",\n    \"packCode\": \"CIBP01\",\n    \"arch\": \"amd64\",\n    \"osName\": \"Windows Server 2012\",\n    \"customerCode\": \"BP01\",\n    \"macAddresses\": [\n        \"02-71-1A-0E-5D-7C\"\n    ],\n    \"crcLogo\": \"153e09683eaa26d23c951f6605af5f874b533a917f73681e3e0a1f175aae3981\"\n}";
-        try {
-            JsonUtils.json2object(requestData, RequestBean.class);
-        } catch (SeCurisException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
+    public String getAppCode() {
+        return appCode;
+    }
+
+    public void setAppCode(String appCode) {
+        this.appCode = appCode;
     }
 }
diff --git a/src/main/java/net/curisit/securis/utils/JsonUtils.java b/src/main/java/net/curisit/securis/utils/JsonUtils.java
index c71301d..7658d87 100644
--- a/src/main/java/net/curisit/securis/utils/JsonUtils.java
+++ b/src/main/java/net/curisit/securis/utils/JsonUtils.java
@@ -135,6 +135,26 @@
     }
 
     /**
+     * Create a JSON string from a object compatible or annotated with Jackson,
+     * i.e: <code>
+     * {"f1":2345,"f2":"Test de valor"}
+     * 
+     * @param obj
+     * @return JSON string representation from object
+     */
+    public static String toPrettyJSON(Object obj, Class<?> klass) throws SeCurisException {
+        // and could also do other configuration...
+        try {
+            if (obj == null)
+                return null;
+            return MAPPER_PRETTY.writerWithType(klass).writeValueAsString(obj);
+        } catch (IOException e) {
+            LOG.error("Error formating JSON from object: {}", obj, e);
+            throw new SeCurisException("Error formating JSON from object: " + obj, e);
+        }
+    }
+
+    /**
      * Create a Map from a json string, i.e: <code>
      * {"f1":2345,"f2":"Test de valor"}
      * </code>

--
Gitblit v1.3.2