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.

WidgetSetBuilder.java 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright 2000-2016 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.server.widgetsetutils;
  17. import java.io.BufferedReader;
  18. import java.io.BufferedWriter;
  19. import java.io.File;
  20. import java.io.FileNotFoundException;
  21. import java.io.FileOutputStream;
  22. import java.io.FileReader;
  23. import java.io.IOException;
  24. import java.io.OutputStreamWriter;
  25. import java.io.PrintStream;
  26. import java.io.Reader;
  27. import java.net.URISyntaxException;
  28. import java.net.URL;
  29. import java.util.Collection;
  30. import java.util.HashSet;
  31. import java.util.Iterator;
  32. import java.util.Map;
  33. import java.util.regex.Matcher;
  34. import java.util.regex.Pattern;
  35. /**
  36. * Helper class to update widgetsets GWT module configuration file. Can be used
  37. * command line or via IDE tools.
  38. *
  39. * <p>
  40. * If module definition file contains text "WS Compiler: manually edited", tool
  41. * will skip editing file.
  42. *
  43. */
  44. public class WidgetSetBuilder {
  45. public static void main(String[] args)
  46. throws IOException, URISyntaxException {
  47. if (args.length == 0) {
  48. printUsage();
  49. } else {
  50. String widgetsetname = args[0];
  51. updateWidgetSet(widgetsetname);
  52. }
  53. }
  54. public static void updateWidgetSet(final String widgetset)
  55. throws IOException, FileNotFoundException, URISyntaxException {
  56. boolean changed = false;
  57. Map<String, URL> availableWidgetSets = ClassPathExplorer
  58. .getAvailableWidgetSets();
  59. String widgetsetFileName = widgetset.replace(".", "/") + ".gwt.xml";
  60. URL sourceUrl = availableWidgetSets.get(widgetset);
  61. if (sourceUrl == null) {
  62. // find first/default source directory
  63. sourceUrl = ClassPathExplorer
  64. .getWidgetsetSourceDirectory(widgetsetFileName);
  65. }
  66. File widgetsetFile = new File(new File(sourceUrl.toURI()),
  67. widgetsetFileName);
  68. if (!widgetsetFile.exists()) {
  69. // create empty gwt module file
  70. File parent = widgetsetFile.getParentFile();
  71. if (parent != null && !parent.exists()) {
  72. if (!parent.mkdirs()) {
  73. throw new IOException(
  74. "Could not create directory for the widgetset: "
  75. + parent.getPath());
  76. }
  77. }
  78. widgetsetFile.createNewFile();
  79. try (PrintStream printStream = new PrintStream(
  80. new FileOutputStream(widgetsetFile))) {
  81. printStream.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  82. + "<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN\" \"http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd\">\n");
  83. printStream.print("<module>\n");
  84. printStream.print(" <!--\n"
  85. + " Uncomment the following to compile the widgetset for one browser only.\n\n"
  86. + " Multiple browsers can be specified as a comma separated list. The\n"
  87. + " supported user agents at the moment of writing were:\n"
  88. + " ie8,ie9,gecko1_8,safari,opera\n\n"
  89. + " The value gecko1_8 is used for Firefox and safari is used for webkit\n"
  90. + " based browsers including Google Chrome.\n"
  91. + " -->\n"
  92. + " <!-- <set-property name=\"user.agent\" value=\"safari\"/> -->\n\n"
  93. + " <!--\n"
  94. + " To enable SuperDevMode, uncomment this line.\n\n"
  95. + " See https://vaadin.com/wiki/-/wiki/Main/Using%20SuperDevMode for more\n"
  96. + " information and instructions.\n" + " -->\n"
  97. + " <!-- <set-configuration-property name=\"devModeRedirectEnabled\" value=\"true\" /> -->\n\n");
  98. printStream.print("\n</module>\n");
  99. }
  100. changed = true;
  101. }
  102. String content = readFile(widgetsetFile);
  103. if (isEditable(content)) {
  104. String originalContent = content;
  105. Collection<String> oldInheritedWidgetsets = getCurrentInheritedWidgetsets(
  106. content);
  107. // add widgetsets that do not exist
  108. Iterator<String> i = availableWidgetSets.keySet().iterator();
  109. while (i.hasNext()) {
  110. String ws = i.next();
  111. if (ws.equals(widgetset)) {
  112. // do not inherit the module itself
  113. continue;
  114. }
  115. if (!oldInheritedWidgetsets.contains(ws)) {
  116. content = addWidgetSet(ws, content);
  117. }
  118. }
  119. for (String ws : oldInheritedWidgetsets) {
  120. if (!availableWidgetSets.containsKey(ws)) {
  121. // widgetset not available in classpath
  122. content = removeWidgetSet(ws, content);
  123. }
  124. }
  125. changed = changed || !content.equals(originalContent);
  126. if (changed) {
  127. commitChanges(widgetsetFile, content);
  128. }
  129. } else {
  130. System.out
  131. .println("Widgetset is manually edited. Skipping updates.");
  132. }
  133. }
  134. private static boolean isEditable(String content) {
  135. return !content.contains("WS Compiler: manually edited");
  136. }
  137. private static String removeWidgetSet(String ws, String content) {
  138. return content.replaceFirst("<inherits name=\"" + ws + "\"[^/]*/>", "");
  139. }
  140. private static void commitChanges(File widgetsetFile, String content)
  141. throws IOException {
  142. try (BufferedWriter bufferedWriter = new BufferedWriter(
  143. new OutputStreamWriter(new FileOutputStream(widgetsetFile)))) {
  144. bufferedWriter.write(content);
  145. }
  146. }
  147. private static String addWidgetSet(String ws, String content) {
  148. return content.replace("</module>",
  149. "\n <inherits name=\"" + ws + "\" />" + "\n</module>");
  150. }
  151. private static Collection<String> getCurrentInheritedWidgetsets(
  152. String content) {
  153. HashSet<String> hashSet = new HashSet<>();
  154. Pattern inheritsPattern = Pattern.compile(" name=\"([^\"]*)\"");
  155. Matcher matcher = inheritsPattern.matcher(content);
  156. while (matcher.find()) {
  157. String gwtModule = matcher.group(1);
  158. if (isWidgetset(gwtModule)) {
  159. hashSet.add(gwtModule);
  160. }
  161. }
  162. return hashSet;
  163. }
  164. static boolean isWidgetset(String gwtModuleName) {
  165. return gwtModuleName.toLowerCase().contains("widgetset");
  166. }
  167. private static String readFile(File widgetsetFile) throws IOException {
  168. StringBuilder sb;
  169. try (Reader fi = new FileReader(widgetsetFile)) {
  170. BufferedReader bufferedReader = new BufferedReader(fi);
  171. sb = new StringBuilder();
  172. String line;
  173. while ((line = bufferedReader.readLine()) != null) {
  174. sb.append(line);
  175. sb.append("\n");
  176. }
  177. }
  178. return sb.toString();
  179. }
  180. private static void printUsage() {
  181. PrintStream o = System.out;
  182. o.println(WidgetSetBuilder.class.getSimpleName() + " usage:");
  183. o.println(" 1. Set the same classpath as you will "
  184. + "have for the GWT compiler.");
  185. o.println(" 2. Give the widgetsetname (to be created or updated)"
  186. + " as first parameter");
  187. o.println();
  188. o.println(
  189. "All found vaadin widgetsets will be inherited in given widgetset");
  190. }
  191. }