aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2009-09-29 13:25:47 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2009-09-29 13:25:47 +0000
commit43467c624d543a25bce4fc3fd7963777851ac657 (patch)
tree511c0ed4e80a12cad15409db784aa3879a818bbb /src
parent83749439ffac694da963fd2196c207fe94616e63 (diff)
downloadvaadin-framework-43467c624d543a25bce4fc3fd7963777851ac657.tar.gz
vaadin-framework-43467c624d543a25bce4fc3fd7963777851ac657.zip
vaadin widget jars now detected by details in manifest file, simple widgetsetbuilder tool + some refactoring
svn changeset:8990/svn branch:2009-09-widget-packaging_3332
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml2
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java (renamed from src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java)149
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java (renamed from src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java)2
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java134
4 files changed, 252 insertions, 35 deletions
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
index 58d692e99f..0c139aabc4 100644
--- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
+++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
@@ -31,7 +31,7 @@
<when-property-is name="user.agent" value="ie6"/>
</replace-with>
- <generate-with class="com.vaadin.terminal.gwt.rebind.WidgetMapGenerator">
+ <generate-with class="com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator">
<when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap"/>
</generate-with>
diff --git a/src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java
index 6c81c368c4..c51e2a2188 100644
--- a/src/com/vaadin/terminal/gwt/rebind/ClassPathExplorer.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java
@@ -1,9 +1,10 @@
-package com.vaadin.terminal.gwt.rebind;
+package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collection;
@@ -12,25 +13,30 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import com.vaadin.terminal.Paintable;
import com.vaadin.ui.ClientWidget;
/**
- * Utility class to find server side widgets with {@link ClientWidget}
- * annotation. Used by WidgetMapGenerator to implement some monkey coding for
+ * Utility class to collect widgetset related information from classpath.
+ * Utility will seek all directories from classpaths, and jar files having
+ * "Vaadin-Widgetsets" key in their manifest file.
+ * <p>
+ * Used by WidgetMapGenerator and ide tools to implement some monkey coding for
* you.
* <p>
- * If you end up reading this comment, I guess you have faced a sluggish
- * performance of widget compilation or unreliable detection of components in
- * your classpaths. The thing you might be able to do is to use annotation
- * processing tool like apt to generate the needed information. Then either use
- * that information in {@link WidgetMapGenerator} or create the appropriate
- * monkey code for gwt directly in annotation processor and get rid of
- * {@link WidgetMapGenerator}. Using annotation processor might be a good idea
- * when dropping Java 1.5 support (integrated to javac in 6).
+ * Developer notice: If you end up reading this comment, I guess you have faced
+ * a sluggish performance of widget compilation or unreliable detection of
+ * components in your classpaths. The thing you might be able to do is to use
+ * annotation processing tool like apt to generate the needed information. Then
+ * either use that information in {@link WidgetMapGenerator} or create the
+ * appropriate monkey code for gwt directly in annotation processor and get rid
+ * of {@link WidgetMapGenerator}. Using annotation processor might be a good
+ * idea when dropping Java 1.5 support (integrated to javac in 6).
*
*/
public class ClassPathExplorer {
@@ -49,6 +55,9 @@ public class ClassPathExplorer {
private ClassPathExplorer() {
}
+ /**
+ * Finds server side widgets with {@link ClientWidget} annotation.
+ */
public static Collection<Class<? extends Paintable>> getPaintablesHavingWidgetAnnotation() {
Collection<Class<? extends Paintable>> paintables = new HashSet<Class<? extends Paintable>>();
Set<URL> keySet = classpathLocations.keySet();
@@ -60,10 +69,74 @@ public class ClassPathExplorer {
}
/**
+ * Finds available widgetset names.
+ *
+ * @return
+ */
+ public static Collection<String> getAvailableWidgetSets() {
+ Collection<String> widgetsets = new HashSet<String>();
+ Set<URL> keySet = classpathLocations.keySet();
+ for (URL url : keySet) {
+ searchForWidgetSets(url, widgetsets);
+ }
+ return widgetsets;
+ }
+
+ private static void searchForWidgetSets(URL location,
+ Collection<String> widgetsets) {
+
+ File directory = new File(location.getFile());
+
+ if (directory.exists() && !directory.isHidden()) {
+ // Get the list of the files contained in the directory
+ String[] files = directory.list();
+ for (int i = 0; i < files.length; i++) {
+ // we are only interested in .gwt.xml files
+ if (files[i].endsWith(".gwt.xml")) {
+ // remove the extension
+ String classname = files[i].substring(0,
+ files[i].length() - 8);
+ classname = classpathLocations.get(location) + "."
+ + classname;
+ widgetsets.add(classname);
+ }
+ }
+ } else {
+
+ try {
+ // check files in jar file, entries will list all directories
+ // and files in jar
+
+ URLConnection openConnection = location.openConnection();
+ if (openConnection instanceof JarURLConnection) {
+ JarURLConnection conn = (JarURLConnection) openConnection;
+
+ JarFile jarFile = conn.getJarFile();
+
+ Manifest manifest = jarFile.getManifest();
+ String value = manifest.getMainAttributes().getValue(
+ "Vaadin-Widgetsets");
+ if (value != null) {
+ String[] widgetsetNames = value.split(",");
+ for (int i = 0; i < widgetsetNames.length; i++) {
+ String widgetsetname = widgetsetNames[i].trim()
+ .intern();
+ widgetsets.add(widgetsetname);
+ }
+ }
+ }
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+
+ }
+ }
+
+ /**
* Determine every URL location defined by the current classpath, and it's
* associated package name.
*/
- public final static Map<URL, String> getClasspathLocations() {
+ private final static Map<URL, String> getClasspathLocations() {
Map<URL, String> locations = new HashMap<URL, String>();
String pathSep = System.getProperty("path.separator");
@@ -92,6 +165,27 @@ public class ClassPathExplorer {
|| classpathEntry.contains(".vaadin.")) {
return true;
} else {
+ URL url;
+ try {
+ url = new URL("file:"
+ + new File(classpathEntry).getCanonicalPath());
+ url = new URL("jar:" + url.toExternalForm() + "!/");
+ JarURLConnection conn = (JarURLConnection) url
+ .openConnection();
+ JarFile jarFile = conn.getJarFile();
+ Manifest manifest = jarFile.getManifest();
+ Attributes mainAttributes = manifest.getMainAttributes();
+ if (mainAttributes.getValue("Vaadin-Widgetsets") != null) {
+ return true;
+ }
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
return false;
}
}
@@ -155,26 +249,6 @@ public class ClassPathExplorer {
}
- private static String packageNameFor(JarEntry entry) {
- if (entry == null) {
- return "";
- }
- String s = entry.getName();
- if (s == null) {
- return "";
- }
- if (s.length() == 0) {
- return s;
- }
- if (s.startsWith("/")) {
- s = s.substring(1, s.length());
- }
- if (s.endsWith("/")) {
- s = s.substring(0, s.length() - 1);
- }
- return s.replace('/', '.');
- }
-
private final static void searchForPaintables(URL location,
String packageName,
Collection<Class<? extends Paintable>> paintables) {
@@ -237,7 +311,7 @@ public class ClassPathExplorer {
Class<?> c = Class.forName(fullclassName);
if (c.getAnnotation(ClientWidget.class) != null) {
paintables.add((Class<? extends Paintable>) c);
- System.out.println("Found paintable " + fullclassName);
+ // System.out.println("Found paintable " + fullclassName);
}
} catch (ExceptionInInitializerError e) {
// e.printStackTrace();
@@ -262,5 +336,14 @@ public class ClassPathExplorer {
for (Class<? extends Paintable> cls : paintables) {
System.out.println(cls.getCanonicalName());
}
+
+ System.out.println();
+ System.out.println("Searching available widgetsets...");
+
+ Collection<String> availableWidgetSets = ClassPathExplorer
+ .getAvailableWidgetSets();
+ for (String string : availableWidgetSets) {
+ System.out.println(string);
+ }
}
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
index ba42f4ebaa..8bd961d925 100644
--- a/src/com/vaadin/terminal/gwt/rebind/WidgetMapGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
@@ -1,4 +1,4 @@
-package com.vaadin.terminal.gwt.rebind;
+package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.PrintWriter;
import java.util.Collection;
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java
new file mode 100644
index 0000000000..c2c888c4bb
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java
@@ -0,0 +1,134 @@
+package com.vaadin.terminal.gwt.widgetsetutils;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Helper class to update widgetsets GWT module configuration file. Can be used
+ * command line or via IDE tools.
+ */
+public class WidgetSetBuilder {
+
+ public static void main(String[] args) throws IOException {
+ if (args.length == 0) {
+ printUsage();
+ } else {
+ String widgetsetname = args[0];
+ String sourcepath = args[1];
+ updateWidgetSet(widgetsetname, sourcepath);
+
+ }
+ }
+
+ public static void updateWidgetSet(final String widgetset, String sourcepath)
+ throws IOException, FileNotFoundException {
+ String widgetsetfilename = sourcepath + "/"
+ + widgetset.replace(".", "/") + ".gwt.xml";
+ File widgetsetFile = new File(widgetsetfilename);
+ if (!widgetsetFile.exists()) {
+ // create empty gwt module file
+ widgetsetFile.createNewFile();
+ PrintStream printStream = new PrintStream(new FileOutputStream(
+ widgetsetFile));
+ printStream.print("<module>\n\n</module>\n");
+ printStream.close();
+ }
+
+ String content = readFile(widgetsetFile);
+
+ Collection<String> oldInheritedWidgetsets = getCurrentWidgetSets(content);
+
+ Collection<String> availableWidgetSets = ClassPathExplorer
+ .getAvailableWidgetSets();
+
+ // add widgetsets that do not exist
+ for (String ws : availableWidgetSets) {
+ if (ws.equals(widgetset)) {
+ // do not inherit the module itself
+ continue;
+ }
+ if (!oldInheritedWidgetsets.contains(ws)) {
+ content = addWidgetSet(ws, content);
+ }
+ }
+
+ for (String ws : oldInheritedWidgetsets) {
+ if (!availableWidgetSets.contains(ws)) {
+ // widgetset not available in classpath
+ content = removeWidgetSet(ws, content);
+ }
+ }
+
+ commitChanges(widgetsetfilename, content);
+ }
+
+ private static String removeWidgetSet(String ws, String content) {
+ return content.replaceFirst("<inherits name=\"" + ws + "\"[^/]*/>", "");
+ }
+
+ private static void commitChanges(String widgetsetfilename, String content)
+ throws IOException {
+ BufferedWriter bufferedWriter = new BufferedWriter(
+ new OutputStreamWriter(new FileOutputStream(widgetsetfilename)));
+ bufferedWriter.write(content);
+ bufferedWriter.close();
+ }
+
+ private static String addWidgetSet(String ws, String content) {
+ return content.replace("</module>", "\n\t<inherits name=\"" + ws
+ + "\" />" + "\n</module>");
+ }
+
+ private static Collection<String> getCurrentWidgetSets(String content) {
+ HashSet<String> hashSet = new HashSet<String>();
+ Pattern inheritsPattern = Pattern.compile(" name=\"([^\"]*)\"");
+
+ Matcher matcher = inheritsPattern.matcher(content);
+
+ while (matcher.find()) {
+ String possibleWidgetSet = matcher.group(1);
+ if (possibleWidgetSet.toLowerCase().contains("widgetset")) {
+ hashSet.add(possibleWidgetSet);
+ }
+ }
+ return hashSet;
+ }
+
+ private static String readFile(File widgetsetFile) throws IOException {
+ Reader fi = new FileReader(widgetsetFile);
+ BufferedReader bufferedReader = new BufferedReader(fi);
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ sb.append(line);
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ private static void printUsage() {
+ PrintStream o = System.out;
+ o.println(WidgetSetBuilder.class.getSimpleName() + " usage:");
+ o.println("\t1. Set the same classpath as you will "
+ + "have for the GWT compiler.");
+ o.println("\t2. Give the widgetsetname (to be created or updated)"
+ + " as first parameter, source path as a second parameter");
+ o.println();
+ o
+ .println("All found vaadin widgetsets will be inherited in given widgetset");
+
+ }
+
+}