diff options
-rw-r--r-- | client-compiler/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java | 154 | ||||
-rw-r--r-- | client-compiler/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java | 88 |
2 files changed, 228 insertions, 14 deletions
diff --git a/client-compiler/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java b/client-compiler/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java new file mode 100644 index 0000000000..1fa259c06b --- /dev/null +++ b/client-compiler/src/com/vaadin/server/themeutils/SASSAddonImportFileCreator.java @@ -0,0 +1,154 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server.themeutils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URL; +import java.util.Map; + +import com.vaadin.server.widgetsetutils.ClassPathExplorer; +import com.vaadin.server.widgetsetutils.ClassPathExplorer.LocationInfo; + +/** + * Helper class for managing the addon imports and creating an a SCSS file for + * importing all your addon themes. The helper method searches the classpath for + * Vaadin addons and uses the 'Vaadin-Themes' metadata to create the imports. + * + * <p> + * The addons.scss is always overwritten when this tool is invoked. + * </p> + * + * @since 7.1 + */ +public class SASSAddonImportFileCreator { + + private static final String ADDON_IMPORTS_FILE = "addons.scss"; + + private static final String ADDON_IMPORTS_FILE_TEXT = "This file is managed by the Eclipse plug-in and " + + "will be overwritten from time to time. Do not manually edit this file."; + + + /** + * + * @param args + * Theme directory where the addons.scss file should be created + */ + public static void main(String[] args) throws IOException { + if (args.length == 0) { + printUsage(); + } else { + String themeDirectory = args[0]; + updateTheme(themeDirectory); + } + } + + /** + * Updates a themes addons.scss with the addon themes found on the classpath + * + * @param themeDirectory + * The target theme directory + */ + public static void updateTheme(String themeDirectory) throws IOException { + + File addonImports = new File(themeDirectory, ADDON_IMPORTS_FILE); + + if (!addonImports.exists()) { + + // Ensure directory exists + addonImports.getParentFile().mkdirs(); + + // Ensure file exists + addonImports.createNewFile(); + } + + LocationInfo info = ClassPathExplorer.getAvailableWidgetSetsAndStylesheets(); + + try { + PrintStream printStream = new PrintStream(new FileOutputStream( + addonImports)); + + printStream.println("/* " + ADDON_IMPORTS_FILE_TEXT + " */"); + + printStream.println(); + + Map<String, URL> addonThemes = info.getAddonStyles(); + for (String path : addonThemes.keySet()) { + addImport(printStream, path, addonThemes.get(path)); + } + + } catch (FileNotFoundException e) { + // Should not happen since file is checked before this + e.printStackTrace(); + } + } + + private static void addImport(PrintStream stream, String file, URL location) { + + // Add import comment + printImportComment(stream, location); + + if (file.endsWith(".css")) { + stream.print("@import url(\"../" + file + "\");\n"); + } else { + // Assume SASS + stream.print("@import \"../" + file + "\";\n"); + + // Convention is to name the mixing after the stylesheet. Strip + // .scss from filename + String mixin = file.substring(file.lastIndexOf("/") + 1, + file.length() + - ".scss".length()); + + stream.print("@include " + mixin + ";"); + } + + stream.println(); + } + + private static void printImportComment(PrintStream stream, URL location) { + + // file:/absolute/path/to/addon.jar!/ + String path = location.getPath(); + + try { + // Try to parse path for better readability + path = path.substring(path.lastIndexOf(":") + 1, + path.lastIndexOf("!")); + + // Extract jar archive filename + path = path.substring(path.lastIndexOf("/") + 1); + + } catch (Exception e) { + // Parsing failed but no worries, we then use whatever + // location.getPath() returns + } + + stream.println("/* Added by Vaadin Plug-in for Eclipse from " + path + + " */"); + } + + private static void printUsage() { + String className = SASSAddonImportFileCreator.class.getSimpleName(); + PrintStream o = System.out; + o.println(className + " usage:"); + o.println(); + o.println("./" + className + " [Path to target theme folder]"); + } +} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java index 34024f1616..018e19049b 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java @@ -72,6 +72,32 @@ public class ClassPathExplorer { }; /** + * Contains information about widgetsets and themes found on the classpath + * + * @since 7.1 + */ + public static class LocationInfo { + + private final Map<String, URL> widgetsets; + + private final Map<String, URL> addonStyles; + + public LocationInfo(Map<String, URL> widgetsets, Map<String, URL> themes) { + this.widgetsets = widgetsets; + this.addonStyles = themes; + } + + public Map<String, URL> getWidgetsets() { + return widgetsets; + } + + public Map<String, URL> getAddonStyles() { + return addonStyles; + } + + } + + /** * Raw class path entries as given in the java class path string. Only * entries that could include widgets/widgetsets are listed (primarily * directories, Vaadin JARs and add-on JARs). @@ -95,13 +121,26 @@ public class ClassPathExplorer { * Finds the names and locations of widgetsets available on the class path. * * @return map from widgetset classname to widgetset location URL + * @deprecated Use {@link #getAvailableWidgetSetsAndStylesheets()} instead */ + @Deprecated public static Map<String, URL> getAvailableWidgetSets() { + return getAvailableWidgetSetsAndStylesheets().getWidgetsets(); + } + + /** + * Finds the names and locations of widgetsets and themes available on the + * class path. + * + * @return + */ + public static LocationInfo getAvailableWidgetSetsAndStylesheets() { long start = System.currentTimeMillis(); Map<String, URL> widgetsets = new HashMap<String, URL>(); + Map<String, URL> themes = new HashMap<String, URL>(); Set<String> keySet = classpathLocations.keySet(); for (String location : keySet) { - searchForWidgetSets(location, widgetsets); + searchForWidgetSetsAndAddonStyles(location, widgetsets, themes); } long end = System.currentTimeMillis(); @@ -114,14 +153,25 @@ public class ClassPathExplorer { sb.append(widgetsets.get(ws)); sb.append("\n"); } + + sb.append("Addon styles found from classpath:\n"); + for (String theme : themes.keySet()) { + sb.append("\t"); + sb.append(theme); + sb.append(" in "); + sb.append(themes.get(theme)); + sb.append("\n"); + } + final Logger logger = getLogger(); logger.info(sb.toString()); logger.info("Search took " + (end - start) + "ms"); - return widgetsets; + return new LocationInfo(widgetsets, themes); } /** - * Finds all GWT modules / Vaadin widgetsets in a valid location. + * Finds all GWT modules / Vaadin widgetsets and Addon styles in a valid + * location. * * If the location is a directory, all GWT modules (files with the * ".gwt.xml" extension) are added to widgetsets. @@ -136,8 +186,8 @@ public class ClassPathExplorer { * separators) to a URL (see {@link #classpathLocations}) - new * entries are added to this map */ - private static void searchForWidgetSets(String locationString, - Map<String, URL> widgetsets) { + private static void searchForWidgetSetsAndAddonStyles(String locationString, + Map<String, URL> widgetsets, Map<String, URL> addonStyles) { URL location = classpathLocations.get(locationString); File directory = new File(location.getFile()); @@ -197,18 +247,32 @@ public class ClassPathExplorer { // No manifest so this is not a Vaadin Add-on return; } + + // Check for widgetset attribute 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(); + String widgetsetname = widgetsetNames[i].trim(); if (!widgetsetname.equals("")) { widgetsets.put(widgetsetname, location); } } } + + // Check for theme attribute + value = manifest.getMainAttributes().getValue( + "Vaadin-Stylesheets"); + if (value != null) { + String[] stylesheets = value.split(","); + for (int i = 0; i < stylesheets.length; i++) { + String stylesheet = stylesheets[i].trim(); + if (!stylesheet.equals("")) { + addonStyles.put(stylesheet, location); + } + } + } } } catch (IOException e) { getLogger().log(Level.WARNING, "Error parsing jar file", e); @@ -457,14 +521,10 @@ public class ClassPathExplorer { * Test method for helper tool */ public static void main(String[] args) { - getLogger().info("Searching available widgetsets..."); + getLogger().info( + "Searching for available widgetsets and stylesheets..."); - Map<String, URL> availableWidgetSets = ClassPathExplorer - .getAvailableWidgetSets(); - for (String string : availableWidgetSets.keySet()) { - - getLogger().info(string + " in " + availableWidgetSets.get(string)); - } + ClassPathExplorer.getAvailableWidgetSetsAndStylesheets(); } private static final Logger getLogger() { |