Revision: 6480 Author: [email protected] Date: Tue Oct 27 00:00:07 2009 Log: tr...@6479 was merged into this branch This allows multiple source files to be specified for a ui:style svn merge --ignore-ancestry -c 6479 https://google-web-toolkit.googlecode.com/svn/trunk .
http://code.google.com/p/google-web-toolkit/source/detail?r=6480 Added: /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/Menu.css Modified: /releases/2.0/branch-info.txt /releases/2.0/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java /releases/2.0/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java /releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java /releases/2.0/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.css /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml /releases/2.0/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java ======================================= --- /dev/null +++ /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/Menu.css Tue Oct 27 00:00:07 2009 @@ -0,0 +1,4 @@ +.menuBar { + border:solid; + background-color:white; +} ======================================= --- /releases/2.0/branch-info.txt Mon Oct 26 22:07:12 2009 +++ /releases/2.0/branch-info.txt Tue Oct 27 00:00:07 2009 @@ -44,3 +44,7 @@ tr...@6443 was merged into this branch Updates to use the rebased protobuf library svn merge --ignore-ancestry -c 6443 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@6479 was merged into this branch + This allows multiple source files to be specified for a ui:style + svn merge --ignore-ancestry -c 6479 https://google-web-toolkit.googlecode.com/svn/trunk . ======================================= --- /releases/2.0/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java Wed Aug 26 08:44:19 2009 +++ /releases/2.0/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java Tue Oct 27 00:00:07 2009 @@ -202,8 +202,8 @@ public static URL[] findResources(TreeLogger logger, ClassLoader classLoader, ResourceContext context, JMethod method, String[] defaultSuffixes) throws UnableToCompleteException { - return findResources(logger, new ClassLoaderLocator(classLoader), context, - method, defaultSuffixes, true); + return findResources(logger, new Locator[] {new ClassLoaderLocator( + classLoader)}, context, method, defaultSuffixes); } /** @@ -281,34 +281,14 @@ public static URL[] findResources(TreeLogger logger, ResourceContext context, JMethod method, String[] defaultSuffixes) throws UnableToCompleteException { - URL[] toReturn = null; - Locator locator; - - // If we have named files, attempt them first - if (!namedFiles.isEmpty()) { - toReturn = findResources(logger, FileLocator.INSTANCE, context, method, - defaultSuffixes, false); - } - - if (toReturn == null) { - // Try to find the resources with ResourceOracle - locator = new ResourceOracleLocator( - context.getGeneratorContext().getResourcesOracle()); - - // Don't report errors since we have a fallback mechanism - toReturn = findResources(logger, locator, context, method, - defaultSuffixes, false); - } - - if (toReturn == null) { - // Since not all resources were found, try with ClassLoader - locator = new ClassLoaderLocator( - Thread.currentThread().getContextClassLoader()); - - // Do report hard failures - toReturn = findResources(logger, locator, context, method, - defaultSuffixes, true); - } + Locator[] locators = { + FileLocator.INSTANCE, + new ResourceOracleLocator( + context.getGeneratorContext().getResourcesOracle()), + new ClassLoaderLocator(Thread.currentThread().getContextClassLoader())}; + + URL[] toReturn = findResources(logger, locators, context, method, + defaultSuffixes); return toReturn; } @@ -331,14 +311,10 @@ /** * Main implementation of findResources. - * - * @param reportErrors controls whether or not the inability to locate any - * given resource should be a hard error (throw an UnableToComplete) - * or a soft error (return null). */ - private static URL[] findResources(TreeLogger logger, Locator locator, - ResourceContext context, JMethod method, String[] defaultSuffixes, - boolean reportErrors) throws UnableToCompleteException { + private static URL[] findResources(TreeLogger logger, Locator[] locators, + ResourceContext context, JMethod method, String[] defaultSuffixes) + throws UnableToCompleteException { logger = logger.branch(TreeLogger.DEBUG, "Finding resources"); String locale; @@ -360,21 +336,22 @@ if (defaultSuffixes != null) { for (String extension : defaultSuffixes) { logger.log(TreeLogger.SPAM, "Trying default extension " + extension); - URL resourceUrl = tryFindResource(locator, getPathRelativeToPackage( - method.getEnclosingType().getPackage(), method.getName() - + extension), locale); - - if (resourceUrl != null) { - // Early out because we found a hit - return new URL[] {resourceUrl}; + for (Locator locator : locators) { + URL resourceUrl = tryFindResource(locator, + getPathRelativeToPackage( + method.getEnclosingType().getPackage(), method.getName() + + extension), locale); + + if (resourceUrl != null) { + // Take the first match + return new URL[] {resourceUrl}; + } } } } - if (reportErrors) { - logger.log(TreeLogger.ERROR, "No " + Source.class.getName() - + " annotation and no resources found with default extensions"); - } + logger.log(TreeLogger.ERROR, "No " + Source.class.getName() + + " annotation and no resources found with default extensions"); toReturn = null; error = true; @@ -387,26 +364,31 @@ int tagIndex = 0; for (String resource : resources) { // Try to find the resource relative to the package. - URL resourceURL = tryFindResource(locator, getPathRelativeToPackage( - method.getEnclosingType().getPackage(), resource), locale); - - // If we didn't find the resource relative to the package, assume it is - // absolute. - if (resourceURL == null) { - resourceURL = tryFindResource(locator, resource, locale); + URL resourceURL = null; + + for (Locator locator : locators) { + resourceURL = tryFindResource(locator, getPathRelativeToPackage( + method.getEnclosingType().getPackage(), resource), locale); + + /* + * If we didn't find the resource relative to the package, assume it + * is absolute. + */ + if (resourceURL == null) { + resourceURL = tryFindResource(locator, resource, locale); + } + + // If we have found a resource, take the first match + if (resourceURL != null) { + break; + } } if (resourceURL == null) { error = true; - if (reportErrors) { - logger.log(TreeLogger.ERROR, "Resource " + resource - + " not found. Is the name specified as Class.getResource()" - + " would expect?"); - } else { - // Speculative attempts should not emit errors - logger.log(TreeLogger.DEBUG, "Stopping because " + resource - + " not found"); - } + logger.log(TreeLogger.ERROR, "Resource " + resource + + " not found. Is the name specified as Class.getResource()" + + " would expect?"); } toReturn[tagIndex++] = resourceURL; @@ -414,11 +396,7 @@ } if (error) { - if (reportErrors) { - throw new UnableToCompleteException(); - } else { - return null; - } + throw new UnableToCompleteException(); } return toReturn; ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java Tue Oct 13 13:41:12 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java Tue Oct 27 00:00:07 2009 @@ -29,6 +29,7 @@ import com.google.gwt.uibinder.rebind.model.ImplicitDataResource; import com.google.gwt.uibinder.rebind.model.ImplicitImageResource; +import java.util.Collection; import java.util.Set; /** @@ -96,7 +97,7 @@ // Write css methods for (ImplicitCssResource css : bundleClass.getCssMethods()) { - writer.write("@Source(\"%s\")", css.getSource()); + writeCssSource(css); writeCssImports(css); writer.write("%s %s();", css.getClassName(), css.getName()); writer.newline(); @@ -135,6 +136,22 @@ } } } + + private void writeCssSource(ImplicitCssResource css) { + Collection<String> sources = css.getSource(); + if (sources.size() == 1) { + writer.write("@Source(\"%s\")", sources.iterator().next()); + } else { + StringBuffer b = new StringBuffer(); + for (String s : sources) { + if (b.length() > 0) { + b.append(", "); + } + b.append('"').append(s).append('"'); + } + writer.write("@Source({%s})", b); + } + } private void writeImageMethods() { for (ImplicitImageResource image : bundleClass.getImageMethods()) { ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java Tue Oct 13 13:41:12 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java Tue Oct 27 00:00:07 2009 @@ -224,13 +224,12 @@ private void createStyle(XMLElement elem) throws UnableToCompleteException { String body = elem.consumeUnescapedInnerText(); - if (body.length() > 0 && elem.hasAttribute(SOURCE_ATTRIBUTE)) { - writer.die( - "In %s, cannot use both a source attribute and inline css text.", - elem); - } - String source = elem.consumeAttribute(SOURCE_ATTRIBUTE); + + if (0 == body.length() && 0 == source.length()) { + writer.die("%s must have either a src attribute or body text", elem); + } + String name = elem.consumeAttribute(FIELD_ATTRIBUTE, "style"); JClassType publicType = consumeCssResourceType(elem); ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java Tue Oct 13 10:44:52 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java Tue Oct 27 00:00:07 2009 @@ -118,7 +118,7 @@ * was unset. The returned string is not escaped. * * @param name the attribute's full name (including prefix) - * @return the attribute's value, or null + * @return the attribute's value, or "" */ public String consumeAttribute(String name) { String value = elem.getAttribute(name); ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java Tue Oct 13 13:41:12 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java Tue Oct 27 00:00:07 2009 @@ -29,22 +29,34 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; /** * Models a method returning a CssResource on a generated ClientBundle. */ public class ImplicitCssResource { + private static List<String> explodeSource(String source) { + if (source.length() == 0) { + return Collections.emptyList(); + } + return Arrays.asList(source.split("\\s+")); + } + private final String packageName; private final String className; private final String name; - private final String source; + private final List<String> sources; private final JClassType extendedInterface; private final String body; private final MortalLogger logger; private final Set<JClassType> imports; + private File generatedFile; ImplicitCssResource(String packageName, String className, String name, @@ -57,20 +69,7 @@ this.body = body; this.logger = logger; this.imports = Collections.unmodifiableSet(importTypes); - - if (body.length() > 0) { - assert "".equals(source); // Enforced for real by the parser - - /* - * We're going to write the inline body to a temporary File and register - * it with the CssResource world under the name in this.source, via - * ResourceGeneratorUtil.addNamedFile(). When CssResourceGenerator sees - * this name in an @Source annotation it will know to use the registered - * file rather than load a resource. - */ - source = String.format("uibinder:%s.%s.css", packageName, className); - } - this.source = source; + sources = explodeSource(source); } /** @@ -87,20 +86,22 @@ * can't find. */ public Set<String> getCssClassNames() throws UnableToCompleteException { - URL[] urls; - - if (body.length() == 0) { - urls = getExternalCss(); - } else { + List<URL> urls = getExternalCss(); + + final File bodyFile = getGeneratedFile(); + if (bodyFile != null) { try { - urls = new URL[] {getGeneratedFile().toURI().toURL()}; + urls.add(bodyFile.toURI().toURL()); } catch (MalformedURLException e) { throw new RuntimeException(e); } } - - CssStylesheet sheet = GenerateCssAst.exec(logger.getTreeLogger(), urls); - return ExtractClassNamesVisitor.exec(sheet, imports.toArray(new JClassType[imports.size()])); + assert urls.size() > 0; + + CssStylesheet sheet = GenerateCssAst.exec(logger.getTreeLogger(), + urls.toArray(new URL[urls.size()])); + return ExtractClassNamesVisitor.exec(sheet, + imports.toArray(new JClassType[imports.size()])); } /** @@ -133,11 +134,21 @@ /** * @return the name of the .css file(s), separate by white space */ - public String getSource() { - return source; + public Collection<String> getSource() { + if (body.length() == 0) { + return Collections.unmodifiableCollection(sources); + } + + List<String> rtn = new ArrayList<String>(sources); + rtn.add(getBodyFileName()); + return rtn; } - private URL[] getExternalCss() throws UnableToCompleteException { + private String getBodyFileName() { + return String.format("uibinder:%s.%s.css", packageName, className); + } + + private List<URL> getExternalCss() throws UnableToCompleteException { /* * TODO(rjrjr,bobv) refactor ResourceGeneratorUtil.findResources so we can * find them the same way ClientBundle does. For now, just look relative to @@ -147,9 +158,7 @@ ClassLoader classLoader = ImplicitCssResource.class.getClassLoader(); String path = packageName.replace(".", "/"); - String[] sources = source.split(" "); - URL[] urls = new URL[sources.length]; - int i = 0; + List<URL> urls = new ArrayList<URL>(); for (String s : sources) { String resourcePath = path + '/' + s; @@ -157,12 +166,16 @@ if (null == found) { logger.die("Unable to find resource: " + resourcePath); } - urls[i++] = found; + urls.add(found); } return urls; } private File getGeneratedFile() { + if (body.length() == 0) { + return null; + } + if (generatedFile == null) { try { File f = File.createTempFile(String.format("uiBinder_%s_%s", @@ -175,7 +188,7 @@ } catch (IOException e) { throw new RuntimeException(e); } - ResourceGeneratorUtil.addNamedFile(getSource(), generatedFile); + ResourceGeneratorUtil.addNamedFile(getBodyFileName(), generatedFile); } return generatedFile; } ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.css Thu Sep 10 13:35:35 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.css Tue Oct 27 00:00:07 2009 @@ -1,8 +1,3 @@ -.menuBar { - border:solid; - background-color:white; -} - /* * Demonstrates that the ui.xml has access to styles that * do not back any declared CssResource api ======================================= --- /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml Thu Oct 15 18:41:37 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml Tue Oct 27 00:00:07 2009 @@ -71,9 +71,13 @@ <!-- Tests creating a CssResource from an external file. --> -<ui:style field='myStyle' src='WidgetBasedUi.css' - type='com.google.gwt.uibinder.sample.client.WidgetBasedUi.Style'/> - +<ui:style field='myStyle' src='WidgetBasedUi.css Menu.css' + type='com.google.gwt.uibinder.sample.client.WidgetBasedUi.Style'> + .menuBar { + font-family: sans-serif; + } +</ui:style> + <ui:style field='myOtherStyle' type='com.google.gwt.uibinder.sample.client.WidgetBasedUi.Style'> /* because we extend WidgetBasedUi.Style and it's tagged @Shared, we can refine the menubar style defined in other files */ ======================================= --- /releases/2.0/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java Wed Oct 14 18:26:27 2009 +++ /releases/2.0/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java Tue Oct 27 00:00:07 2009 @@ -231,7 +231,7 @@ } interface Bundle extends ClientBundle { - @Source("WidgetBasedUi.css") + @Source({"WidgetBasedUi.css", "Menu.css"}) @NotStrict WidgetBasedUi.Style style(); } --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
