From fba69ae5d8cd617424e324c62b14225decf0315e Mon Sep 17 00:00:00 2001 From: Jonatan Kronqvist Date: Tue, 12 Aug 2014 13:52:09 +0300 Subject: [PATCH] Allow for multiple license keys in a single license file #14408 License files can now contain multiple keys to support different versions of a product. The keys are identified by the major version number followed by an equals sign and the key for that version, e.g. 1 = foo-bar-baz 2 = baz-foo-bar The license file can also contain a "default" license key, which is used for all versions except for the explicitly defined ones, e.g. foo-bar-baz 3 = baz-bar-foo 4 = bar-baz-baz Change-Id: Id07d22e9fdc44189c4298b634006cf0df128bfd9 --- .../src/com/vaadin/tools/CvalChecker.java | 20 ++- .../src/com/vaadin/tools/CvalCheckerTest.java | 147 +++++++++++++++++- 2 files changed, 158 insertions(+), 9 deletions(-) diff --git a/client-compiler/src/com/vaadin/tools/CvalChecker.java b/client-compiler/src/com/vaadin/tools/CvalChecker.java index 2de7e10faa..e426c5c4e6 100644 --- a/client-compiler/src/com/vaadin/tools/CvalChecker.java +++ b/client-compiler/src/com/vaadin/tools/CvalChecker.java @@ -26,6 +26,7 @@ import java.net.URLConnection; import java.text.MessageFormat; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import java.util.prefs.Preferences; @@ -465,7 +466,8 @@ public final class CvalChecker { if (url != null) { try { - key = IOUtils.toString(url.openStream()); + key = readKeyFromFile(url, + computeMajorVersion(productVersion)); if (key != null && !(key = key.trim()).isEmpty()) { return key; } @@ -480,6 +482,22 @@ public final class CvalChecker { productTitle, null, null); } + String readKeyFromFile(URL url, int majorVersion) throws IOException { + String majorVersionStr = String.valueOf(majorVersion); + List lines = IOUtils.readLines(url.openStream()); + String defaultKey = null; + for (String line : lines) { + String[] parts = line.split("\\s*=\\s*"); + if (parts.length < 2) { + defaultKey = parts[0].trim(); + } + if (parts[0].equals(majorVersionStr)) { + return parts[1].trim(); + } + } + return defaultKey; + } + static String getErrorMessage(String key, Object... pars) { Locale loc = Locale.getDefault(); ResourceBundle res = ResourceBundle.getBundle( diff --git a/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java b/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java index 51b12f4c7e..2985f61631 100644 --- a/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java +++ b/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java @@ -24,13 +24,17 @@ import static com.vaadin.tools.CvalChecker.GRACE_DAYS_MSECS; import static com.vaadin.tools.CvalChecker.cacheLicenseInfo; import static com.vaadin.tools.CvalChecker.deleteCache; import static com.vaadin.tools.CvalChecker.parseJson; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -147,7 +151,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -158,7 +162,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -169,7 +173,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -180,7 +184,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -207,7 +211,7 @@ public class CvalCheckerTest { } catch (InvalidCvalException expected) { Assert.fail(); } catch (UnreachableCvalServerException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -221,7 +225,7 @@ public class CvalCheckerTest { } catch (InvalidCvalException expected) { Assert.fail(); } catch (UnreachableCvalServerException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -234,7 +238,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); // Check that we use server customized message if it comes Assert.assertTrue(expected.getMessage().contains("Custom")); } @@ -255,7 +259,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertTrue(cacheExists(productNameCval)); } @@ -339,4 +343,131 @@ public class CvalCheckerTest { static void restoreSystemOut() { System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); } + + @Test(expected = FileNotFoundException.class) + public void testReadKeyFromFile_NonexistingLicenseFile() throws Exception { + licenseChecker.readKeyFromFile(new URL("file:///foobar.baz"), 4); + } + + @Test + public void testReadKeyFromFile_LicenseFileEmpty() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + + assertNull(licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasSingleUnidentifiedKey() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasSingleIdentifiedKey() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4=this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasMultipleKeys() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4=this-is-a-license"); + out.println("5=this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasMultipleKeysWithWhitespace() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4 = this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_RequestedVersionMissing() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4 = this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertNull(licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_FallbackToDefaultKey() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_FallbackToDefaultKeyReversed() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("5 = this-is-another-license"); + out.println("this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } } -- 2.39.5