Revision: 5978
Author: [email protected]
Date: Thu Aug 20 05:44:21 2009
Log: Formalize how default extensions are provided by ClientBundle resource  
types.

Patch by: bobv
Review by: rjrjr
http://code.google.com/p/google-web-toolkit/source/detail?r=5978

Added:
  /trunk/user/src/com/google/gwt/resources/ext/DefaultExtensions.java
Modified:
  /trunk/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
  /trunk/user/src/com/google/gwt/resources/client/CssResource.java
  /trunk/user/src/com/google/gwt/resources/client/ExternalTextResource.java
  /trunk/user/src/com/google/gwt/resources/client/ImageResource.java
  /trunk/user/src/com/google/gwt/resources/client/TextResource.java
  /trunk/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
   
/trunk/user/src/com/google/gwt/resources/rebind/context/AbstractClientBundleGenerator.java
  /trunk/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
   
/trunk/user/src/com/google/gwt/resources/rg/ExternalTextResourceGenerator.java
  /trunk/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
  /trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java

=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/resources/ext/DefaultExtensions.java Thu  
Aug 20 05:44:21 2009
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * 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.google.gwt.resources.ext;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies the default extensions for a resource type. This annotation is
+ * intended to allow external tooling to know which filename extensions the
+ * ClientBundle system will search for if no
+ * {...@link com.google.gwt.resources.client.ClientBundle.Source} annotation  
is
+ * present on an accessor method.
+ */
+...@inherited
+...@retention(RetentionPolicy.RUNTIME)
+...@target(ElementType.TYPE)
+public @interface DefaultExtensions {
+  String[] value();
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java        
 
Wed Apr  1 13:03:34 2009
+++ /trunk/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java        
 
Thu Aug 20 05:44:21 2009
@@ -19,6 +19,9 @@
  import com.google.gwt.dev.util.collect.Sets;

  import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
  import java.util.Map;
  import java.util.Set;

@@ -45,8 +48,8 @@
    }

    /**
-   * Returns <code>true</code> if the rhs array type can be assigned to the
-   * lhs array type.
+   * Returns <code>true</code> if the rhs array type can be assigned to  
the lhs
+   * array type.
     */
    private static boolean areArraysAssignable(JArrayType lhsType,
        JArrayType rhsType) {
@@ -327,8 +330,8 @@
    }

    /**
-   * Cached set of supertypes for this type (including itself).  If null,
-   * the set has not been calculated yet.
+   * Cached set of supertypes for this type (including itself). If null,  
the set
+   * has not been calculated yet.
     */
    private Set<JClassType> flattenedSupertypes;

@@ -357,6 +360,65 @@

      return null;
    }
+
+  /**
+   * Find an annotation on a type or on one of its superclasses or
+   * superinterfaces.
+   * <p>
+   * This provides semantics similar to that of
+   * {...@link java.lang.annotation.Inherited} except that it checks all  
types to
+   * which this type is assignable. {...@code @Inherited} only works on
+   * superclasses, not superinterfaces.
+   * <p>
+   * Annotations present on the superclass chain will be returned  
preferentially
+   * over those found in the superinterface hierarchy. Note that the  
annotation
+   * does not need to be tagged with {...@code @Inherited} in order to be  
returned
+   * from the superclass chain.
+   *
+   * @param annotationType the type of the annotation to look for
+   * @return the desired annotation or <code>null</code> if the annotation  
is
+   *         not present in the type's type hierarchy
+   */
+  public <T extends Annotation> T findAnnotationInTypeHierarchy(
+      Class<T> annotationType) {
+
+    // Remember what we've seen to avoid loops
+    Set<JClassType> seen = new HashSet<JClassType>();
+
+    // Work queue
+    List<JClassType> searchTypes = new LinkedList<JClassType>();
+    searchTypes.add(this);
+
+    T toReturn = null;
+
+    while (!searchTypes.isEmpty()) {
+      JClassType current = searchTypes.remove(0);
+
+      if (!seen.add(current)) {
+        continue;
+      }
+
+      toReturn = current.getAnnotation(annotationType);
+      if (toReturn != null) {
+        /*
+         * First one wins. It might be desirable at some point to have a
+         * variation that can return more than one instance of the  
annotation if
+         * it is present on multiple supertypes.
+         */
+        break;
+      }
+
+      if (current.getSuperclass() != null) {
+        // Add the superclass at the front of the list
+        searchTypes.add(0, current.getSuperclass());
+      }
+
+      // Superinterfaces
+      Collections.addAll(searchTypes, current.getImplementedInterfaces());
+    }
+
+    return toReturn;
+  }

    public abstract JConstructor findConstructor(JType[] paramTypes);

@@ -446,12 +508,12 @@
        Class<? extends Annotation> annotationClass);

    /**
-   * Returns <code>true</code> if this {...@link JClassType} is assignable  
from
-   * the specified {...@link JClassType} parameter.
+   * Returns <code>true</code> if this {...@link JClassType} is assignable  
from the
+   * specified {...@link JClassType} parameter.
     *
     * @param possibleSubtype possible subtype of this {...@link JClassType}
-   * @return <code>true</code> if this {...@link JClassType} is assignable  
from
-   *         the specified {...@link JClassType} parameter
+   * @return <code>true</code> if this {...@link JClassType} is assignable  
from the
+   *         specified {...@link JClassType} parameter
     *
     * @throws NullPointerException if <code>possibleSubtype</code> is
     *           <code>null</code>
@@ -487,7 +549,7 @@
     * Determines if the class can be constructed using a simple  
<code>new</code>
     * operation. Specifically, the class must
     * <ul>
-   * <li>be a class rather than an interface, </li>
+   * <li>be a class rather than an interface,</li>
     * <li>have either no constructors or a parameterless constructor,  
and</li>
     * <li>be a top-level class or a static nested class.</li>
     * </ul>
=======================================
--- /trunk/user/src/com/google/gwt/resources/client/CssResource.java    Fri  
Jul  3 08:33:45 2009
+++ /trunk/user/src/com/google/gwt/resources/client/CssResource.java    Thu  
Aug 20 05:44:21 2009
@@ -15,6 +15,7 @@
   */
  package com.google.gwt.resources.client;

+import com.google.gwt.resources.ext.DefaultExtensions;
  import com.google.gwt.resources.ext.ResourceGeneratorType;
  import com.google.gwt.resources.rg.CssResourceGenerator;

@@ -32,9 +33,9 @@
   * <li>{...@code String someClassName();} will allow the css class
   * <code>.someClassName</code> to be obfuscated at runtime. The function  
will
   * return the obfuscated class name.</li>
- * <li>{...@code <primitive numeric type or String> someDefName();} will allow
- * access to the values defined by {...@literal @def} rules within the CSS  
file.
- * The defined value must be a raw number, a CSS length, or a percentage  
value
+ * <li>{...@code <primitive numeric type or String> someDefName();} will allow
+ * access to the values defined by {...@literal @def} rules within the CSS  
file.
+ * The defined value must be a raw number, a CSS length, or a percentage  
value
   * if it is to be returned as a numeric type.
   * </ul>
   *
@@ -94,6 +95,7 @@
   * @see <a  
href="http://code.google.com/p/google-web-toolkit/wiki/CssResource";
   *      >CssResource design doc</a>
   */
+...@defaultextensions(value = {".css"})
  @ResourceGeneratorType(CssResourceGenerator.class)
  public interface CssResource extends ResourcePrototype {
    /**
=======================================
---  
/trunk/user/src/com/google/gwt/resources/client/ExternalTextResource.java       
 
Wed Mar 11 17:58:41 2009
+++  
/trunk/user/src/com/google/gwt/resources/client/ExternalTextResource.java       
 
Thu Aug 20 05:44:21 2009
@@ -15,6 +15,7 @@
   */
  package com.google.gwt.resources.client;

+import com.google.gwt.resources.ext.DefaultExtensions;
  import com.google.gwt.resources.ext.ResourceGeneratorType;
  import com.google.gwt.resources.rg.ExternalTextResourceGenerator;

@@ -23,6 +24,7 @@
   * not inlined into the compiled output. This is suitable for resources  
that are
   * not required as part of program initialization.
   */
+...@defaultextensions(value = {".txt"})
  @ResourceGeneratorType(ExternalTextResourceGenerator.class)
  public interface ExternalTextResource extends ResourcePrototype {
    void getText(ResourceCallback<TextResource> callback)
=======================================
--- /trunk/user/src/com/google/gwt/resources/client/ImageResource.java  Thu  
Jul 30 11:19:40 2009
+++ /trunk/user/src/com/google/gwt/resources/client/ImageResource.java  Thu  
Aug 20 05:44:21 2009
@@ -15,6 +15,7 @@
   */
  package com.google.gwt.resources.client;

+import com.google.gwt.resources.ext.DefaultExtensions;
  import com.google.gwt.resources.ext.ResourceGeneratorType;
  import com.google.gwt.resources.rg.ImageResourceGenerator;

@@ -25,6 +26,7 @@
  /**
   * Provides access to image resources at runtime.
   */
+...@defaultextensions(value = {".png", ".jpg", ".gif", ".bmp"})
  @ResourceGeneratorType(ImageResourceGenerator.class)
  public interface ImageResource extends ResourcePrototype {

=======================================
--- /trunk/user/src/com/google/gwt/resources/client/TextResource.java   Wed  
Mar 11 17:58:41 2009
+++ /trunk/user/src/com/google/gwt/resources/client/TextResource.java   Thu  
Aug 20 05:44:21 2009
@@ -15,6 +15,7 @@
   */
  package com.google.gwt.resources.client;

+import com.google.gwt.resources.ext.DefaultExtensions;
  import com.google.gwt.resources.ext.ResourceGeneratorType;
  import com.google.gwt.resources.rg.TextResourceGenerator;

@@ -22,6 +23,7 @@
   * A resource that contains text that should be incorporated into the  
compiled
   * output.
   */
+...@defaultextensions(value = {".txt"})
  @ResourceGeneratorType(TextResourceGenerator.class)
  public interface TextResource extends ResourcePrototype {
    String getText();
=======================================
--- /trunk/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java     
 
Wed Jun 17 13:49:44 2009
+++ /trunk/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java     
 
Thu Aug 20 05:44:21 2009
@@ -20,6 +20,7 @@
  import com.google.gwt.core.ext.SelectionProperty;
  import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
  import com.google.gwt.core.ext.typeinfo.JMethod;
  import com.google.gwt.core.ext.typeinfo.JPackage;
  import com.google.gwt.dev.resource.Resource;
@@ -171,6 +172,10 @@
     * will fall back to using the current thread's context ClassLoader. If  
it is
     * necessary to alter the way in which resources are located, use the  
overload
     * that accepts a ClassLoader.
+   * <p>
+   * If the method's return type declares the {...@link DefaultExtensions}
+   * annotation, the value of this annotation will be used to find matching
+   * resource names if the method lacks an {...@link Source} annotation.
     *
     * @param logger a TreeLogger that will be used to report errors or  
warnings
     * @param context the ResourceContext in which the ResourceGenerator is
@@ -184,7 +189,16 @@
     */
    public static URL[] findResources(TreeLogger logger, ResourceContext  
context,
        JMethod method) throws UnableToCompleteException {
-    return findResources(logger, context, method, new String[0]);
+    JClassType returnType = method.getReturnType().isClassOrInterface();
+    assert returnType != null;
+    DefaultExtensions annotation =  
returnType.findAnnotationInTypeHierarchy(DefaultExtensions.class);
+    String[] extensions;
+    if (annotation != null) {
+      extensions = annotation.value();
+    } else {
+      extensions = new String[0];
+    }
+    return findResources(logger, context, method, extensions);
    }

    /**
=======================================
---  
/trunk/user/src/com/google/gwt/resources/rebind/context/AbstractClientBundleGenerator.java
       
Mon Jun 22 07:10:10 2009
+++  
/trunk/user/src/com/google/gwt/resources/rebind/context/AbstractClientBundleGenerator.java
       
Thu Aug 20 05:44:21 2009
@@ -418,40 +418,18 @@
    private Class<? extends ResourceGenerator> findResourceGenerator(
        TreeLogger logger, TypeOracle typeOracle, JMethod method)
        throws UnableToCompleteException {
-
      JClassType resourceType = method.getReturnType().isClassOrInterface();
      assert resourceType != null;

-    List<JClassType> searchTypes = new ArrayList<JClassType>();
-    searchTypes.add(resourceType);
-
-    ResourceGeneratorType generatorType = null;
-
-    while (!searchTypes.isEmpty()) {
-      JClassType current = searchTypes.remove(0);
-      generatorType = current.getAnnotation(ResourceGeneratorType.class);
-      if (generatorType != null) {
-        break;
-      }
-
-      if (current.getSuperclass() != null) {
-        searchTypes.add(current.getSuperclass());
-      }
-
-      for (JClassType t : current.getImplementedInterfaces()) {
-        searchTypes.add(t);
-      }
-    }
-
-    if (generatorType == null) {
+    ResourceGeneratorType annotation =  
resourceType.findAnnotationInTypeHierarchy(ResourceGeneratorType.class);
+    if (annotation == null) {
        logger.log(TreeLogger.ERROR, "No @"
-          + ResourceGeneratorType.class.getName()
-          + " was specifed for resource type "
+          + ResourceGeneratorType.class.getName() + " was specifed for  
type "
            + resourceType.getQualifiedSourceName() + " or its supertypes");
        throw new UnableToCompleteException();
      }

-    return generatorType.value();
+    return annotation.value();
    }

    /**
=======================================
--- /trunk/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java       
 
Mon Jul  6 08:09:11 2009
+++ /trunk/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java       
 
Thu Aug 20 05:44:21 2009
@@ -1002,8 +1002,6 @@
     */
    private static final int CONCAT_EXPRESSION_LIMIT = 20;

-  private static final String[] DEFAULT_EXTENSIONS = new String[] {".css"};
-
    /**
     * These constants are used to cache obfuscated class names.
     */
@@ -1377,7 +1375,7 @@
      }

      URL[] resources = ResourceGeneratorUtil.findResources(logger, context,
-        method, DEFAULT_EXTENSIONS);
+        method);

      if (resources.length == 0) {
        logger.log(TreeLogger.ERROR, "At least one source must be  
specified");
=======================================
---  
/trunk/user/src/com/google/gwt/resources/rg/ExternalTextResourceGenerator.java  
 
Thu Mar 12 11:16:43 2009
+++  
/trunk/user/src/com/google/gwt/resources/rg/ExternalTextResourceGenerator.java  
 
Thu Aug 20 05:44:21 2009
@@ -41,7 +41,6 @@
   */
  public final class ExternalTextResourceGenerator extends
      AbstractResourceGenerator {
-  private static final String[] DEFAULT_EXTENSIONS = new String[] {".txt"};
    private StringBuffer data;
    private boolean first;
    private String urlExpression;
@@ -112,8 +111,7 @@
        ClientBundleRequirements requirements, JMethod method)
        throws UnableToCompleteException {

-    URL[] urls = ResourceGeneratorUtil.findResources(logger, context,  
method,
-        DEFAULT_EXTENSIONS);
+    URL[] urls = ResourceGeneratorUtil.findResources(logger, context,  
method);

      if (urls.length != 1) {
        logger.log(TreeLogger.ERROR, "Exactly one resource must be  
specified",
=======================================
--- /trunk/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java     
 
Thu Jul 30 11:19:40 2009
+++ /trunk/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java     
 
Thu Aug 20 05:44:21 2009
@@ -45,8 +45,6 @@
   * Builds an image strip for all ImageResources defined within an  
ClientBundle.
   */
  public final class ImageResourceGenerator extends  
AbstractResourceGenerator {
-  private static final String[] DEFAULT_EXTENSIONS = new String[] {
-      ".png", ".jpg", ".gif", ".bmp"};
    private Map<String, ImageRect> imageRectsByName;
    private Map<ImageRect, ImageBundleBuilder> buildersByImageRect;
    private Map<RepeatStyle, ImageBundleBuilder> buildersByRepeatStyle;
@@ -199,7 +197,7 @@
        ClientBundleRequirements requirements, JMethod method)
        throws UnableToCompleteException {
      URL[] resources = ResourceGeneratorUtil.findResources(logger, context,
-        method, DEFAULT_EXTENSIONS);
+        method);

      if (resources.length != 1) {
        logger.log(TreeLogger.ERROR, "Exactly one image may be specified",  
null);
=======================================
--- /trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java      
 
Thu Mar 12 11:16:43 2009
+++ /trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java      
 
Thu Aug 20 05:44:21 2009
@@ -33,13 +33,11 @@
   */
  public final class TextResourceGenerator extends AbstractResourceGenerator  
{

-  private static final String[] DEFAULT_EXTENSIONS = new String[] {".txt"};
-
    @Override
    public String createAssignment(TreeLogger logger, ResourceContext  
context,
        JMethod method) throws UnableToCompleteException {
      URL[] resources = ResourceGeneratorUtil.findResources(logger, context,
-        method, DEFAULT_EXTENSIONS);
+        method);

      if (resources.length != 1) {
        logger.log(TreeLogger.ERROR, "Exactly one resource must be  
specified",

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to