You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CvalAddonsChecker.java 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tools;
  17. import static com.vaadin.tools.CvalChecker.LINE;
  18. import static com.vaadin.tools.CvalChecker.computeMajorVersion;
  19. import static com.vaadin.tools.CvalChecker.getErrorMessage;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.net.URL;
  23. import java.util.ArrayList;
  24. import java.util.Enumeration;
  25. import java.util.List;
  26. import java.util.jar.Attributes;
  27. import java.util.jar.JarFile;
  28. import java.util.jar.Manifest;
  29. import com.vaadin.client.metadata.ConnectorBundleLoader.CValUiInfo;
  30. import com.vaadin.tools.CvalChecker.CvalInfo;
  31. import com.vaadin.tools.CvalChecker.CvalServer;
  32. import com.vaadin.tools.CvalChecker.InvalidCvalException;
  33. import com.vaadin.tools.CvalChecker.UnreachableCvalServerException;
  34. /**
  35. * This class is able to visit all MANIFEST.MF files present in the classpath,
  36. * filter by name, and check if the user has a valid license.
  37. *
  38. * Manifest files should have a few attributes indicating the license type of
  39. * the addon:
  40. * <ul>
  41. * <li>Implementation-Version: 4.x.x
  42. * <li>AdVaaName: addon_name
  43. * <li>AdVaaLicen: cval, agpl, empty
  44. * <li>AdVaaPkg: package of the widgets in this addon
  45. * </ul>
  46. *
  47. * The class also have a method to check just one product.
  48. *
  49. * @since 7.3
  50. */
  51. public final class CvalAddonsChecker {
  52. // Manifest attributes
  53. public static final String VAADIN_ADDON_LICENSE = "AdVaaLicen";
  54. public static final String VAADIN_ADDON_NAME = "AdVaaName";
  55. public static final String VAADIN_ADDON_WIDGETSET = "Vaadin-Widgetsets";
  56. public static final String VAADIN_ADDON_VERSION = "Implementation-Version";
  57. public static final String VAADIN_ADDON_TITLE = "Implementation-Title";
  58. // License types
  59. public static final String VAADIN_AGPL = "agpl";
  60. public static final String VAADIN_CVAL = "cval";
  61. private CvalChecker cvalChecker = new CvalChecker();
  62. private String filterPattern;
  63. /**
  64. * The constructor.
  65. */
  66. public CvalAddonsChecker() {
  67. setLicenseProvider(new CvalServer());
  68. setFilter(".*vaadin.*");
  69. }
  70. /**
  71. * Visit all MANIFEST.MF files in the classpath validating licenses.
  72. *
  73. * Return a list of Cval licensed products in order to have enough info to
  74. * generate nag messages in the UI.
  75. */
  76. public List<CValUiInfo> run() throws InvalidCvalException {
  77. List<CValUiInfo> ret = new ArrayList<>();
  78. try {
  79. // Visit all MANIFEST in our classpath
  80. Enumeration<URL> manifests = Thread.currentThread()
  81. .getContextClassLoader()
  82. .getResources(JarFile.MANIFEST_NAME);
  83. while (manifests.hasMoreElements()) {
  84. try {
  85. URL url = manifests.nextElement();
  86. // Discard manifests whose name does not match the filter
  87. // pattern
  88. if (!url.getPath().matches(filterPattern)) {
  89. continue;
  90. }
  91. InputStream is = url.openStream();
  92. // Should never happen, but we don't want a NPE here
  93. if (is == null) {
  94. continue;
  95. }
  96. // Read manifest attributes
  97. Manifest manifest = new Manifest(is);
  98. Attributes attribs = manifest.getMainAttributes();
  99. String license = attribs.getValue(VAADIN_ADDON_LICENSE);
  100. String name = attribs.getValue(VAADIN_ADDON_NAME);
  101. String vers = attribs.getValue(VAADIN_ADDON_VERSION) == null
  102. ? "" : attribs.getValue(VAADIN_ADDON_VERSION);
  103. String title = attribs.getValue(VAADIN_ADDON_TITLE) == null
  104. ? name : attribs.getValue(VAADIN_ADDON_TITLE);
  105. String widgetsets = attribs
  106. .getValue(VAADIN_ADDON_WIDGETSET) == null ? name
  107. : attribs.getValue(VAADIN_ADDON_WIDGETSET);
  108. if (name == null || license == null) {
  109. continue;
  110. }
  111. if (VAADIN_AGPL.equals(license)) {
  112. // For agpl version we print an info message
  113. printAgplLicense(title, vers);
  114. } else if (VAADIN_CVAL.equals(license)) {
  115. // We only check cval licensed products
  116. CvalInfo info;
  117. try {
  118. info = cvalChecker.validateProduct(name, vers,
  119. title);
  120. printValidLicense(info, title, vers);
  121. } catch (UnreachableCvalServerException e) {
  122. info = CvalChecker.parseJson(
  123. "{'product':{'name':'" + name + "'}}");
  124. printServerUnreachable(title, vers);
  125. }
  126. for (String w : widgetsets.split("[, ]+")) {
  127. ret.add(new CValUiInfo(title,
  128. String.valueOf(computeMajorVersion(vers)),
  129. w, info.getType()));
  130. }
  131. }
  132. } catch (IOException ignored) {
  133. }
  134. }
  135. } catch (IOException ignored) {
  136. }
  137. return ret;
  138. }
  139. /**
  140. * Set the filter regexp of .jar names which we have to consider.
  141. *
  142. * default is '.*touchkit.*'
  143. */
  144. public CvalAddonsChecker setFilter(String regexp) {
  145. filterPattern = regexp;
  146. return this;
  147. }
  148. /*
  149. * Change the license provider, only used in tests.
  150. */
  151. protected CvalAddonsChecker setLicenseProvider(CvalServer p) {
  152. cvalChecker.setLicenseProvider(p);
  153. return this;
  154. }
  155. private void printAgplLicense(String name, String version) {
  156. System.out.println(LINE + "\n"
  157. + getErrorMessage("agpl", name, computeMajorVersion(version))
  158. + "\n" + LINE);
  159. }
  160. private void printServerUnreachable(String name, String version) {
  161. System.out.println(LINE + "\n" + getErrorMessage("unreachable", name,
  162. computeMajorVersion(version)) + "\n" + LINE);
  163. }
  164. private void printValidLicense(CvalInfo info, String title,
  165. String version) {
  166. String msg = info.getMessage();
  167. if (msg == null) {
  168. String key = "evaluation".equals(info.getType()) ? "evaluation"
  169. : "valid";
  170. msg = getErrorMessage(key, title, computeMajorVersion(version),
  171. info.getLicensee());
  172. }
  173. System.out.println("\n" + LINE + "\n" + msg + "\n" + LINE + "\n");
  174. }
  175. }