選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

WidgetSetBuilder.java 8.0KB

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