Author: hlship
Date: Sat Dec  1 14:22:18 2007
New Revision: 600203

URL: http://svn.apache.org/viewvc?rev=600203&view=rev
Log:
TAPESTRY-1509: Create an annotation to add a static JavaScript library to the 
rendered page

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractIncludeAssetWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeJavaScriptLibraryWorker.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.java?rev=600203&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.java
 Sat Dec  1 14:22:18 2007
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.annotations;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Allows for the inclusion of one or more JavaScript libraries.  The 
libraries are assets, usually
+ * (but not always) stored on the classpath with the component.
+ *
+ * @see org.apache.tapestry.annotations.IncludeStylesheet
+ * @see org.apache.tapestry.annotations.Path
+ */
[EMAIL PROTECTED]({ElementType.TYPE})
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]
+public @interface IncludeJavaScriptLibrary
+{
+    /**
+     * The paths to the JavaScript library assets.  Symbols in the paths are 
expanded.  The library may be localized.
+     */
+    String[] value();
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java
 Sat Dec  1 14:22:18 2007
@@ -27,6 +27,7 @@
  * directly.
  *
  * @see org.apache.tapestry.annotations.Path
+ * @see org.apache.tapestry.annotations.IncludeJavaScriptLibrary
  */
 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
@@ -34,7 +35,7 @@
 public @interface IncludeStylesheet
 {
     /**
-     * One or more paths to be injected. Symbols in the path will be expanded.
+     * One or more paths to be injected. Symbols in the path will be expanded. 
The stylesheets may be localized.
      */
     String[] value();
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
 Sat Dec  1 14:22:18 2007
@@ -16,8 +16,8 @@
 
 import org.apache.tapestry.*;
 import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.IncludeJavaScriptLibrary;
 import org.apache.tapestry.annotations.Parameter;
-import org.apache.tapestry.annotations.Path;
 import org.apache.tapestry.corelib.base.AbstractField;
 import org.apache.tapestry.internal.util.SelectModelRenderer;
 import org.apache.tapestry.ioc.annotations.Inject;
@@ -65,6 +65,7 @@
  * Option groups within the [EMAIL PROTECTED] SelectModel} will be rendered, 
but are not supported by the many
  * browsers, and are not fully handled on the client side.
  */
[EMAIL PROTECTED]("palette.js")
 public class Palette extends AbstractField
 {
     // These all started as anonymous inner classes, and were refactored out 
to here.
@@ -186,10 +187,6 @@
     @Parameter(value = "asset:move_up.png")
     private Asset _moveUp;
 
-    @Inject
-    @Path("palette.js")
-    private Asset _paletteLibrary;
-
     /**
      * Used to include scripting code in the rendered page.
      */
@@ -334,8 +331,6 @@
         }
 
         String clientId = getClientId();
-
-        _renderSupport.addScriptLink(_paletteLibrary);
 
         _renderSupport.addScript("new Tapestry.Palette('%s', %s, %s);", 
clientId, _reorder, naturalOrder);
 

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractIncludeAssetWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractIncludeAssetWorker.java?rev=600203&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractIncludeAssetWorker.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractIncludeAssetWorker.java
 Sat Dec  1 14:22:18 2007
@@ -0,0 +1,103 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+import java.util.List;
+import java.util.Locale;
+
+public abstract class AbstractIncludeAssetWorker implements 
ComponentClassTransformWorker
+{
+    private final AssetSource _assetSource;
+    private final SymbolSource _symbolSource;
+
+    public AbstractIncludeAssetWorker(AssetSource assetSource, SymbolSource 
symbolSource)
+    {
+        _assetSource = assetSource;
+        _symbolSource = symbolSource;
+    }
+
+    /**
+     * Expands symbols in the path, then adds an operation into the setup 
render phase of the component.
+     * Ultimately, [EMAIL PROTECTED] #handleAsset(org.apache.tapestry.Asset)} 
will be invoked for each
+     * asset (dervied from assetPaths).
+     *
+     * @param transformation transformation process for component
+     * @param model          component model for component
+     * @param assetPaths     raw paths to be converted to assets
+     */
+    protected final void addOperationForAssetPaths(ClassTransformation 
transformation,
+                                                   final MutableComponentModel 
model, String[] assetPaths)
+    {
+        final List<String> paths = CollectionFactory.newList();
+
+        for (String value : assetPaths)
+        {
+            String expanded = _symbolSource.expandSymbols(value);
+
+            paths.add(expanded);
+        }
+
+        ComponentResourcesOperation op = new ComponentResourcesOperation()
+        {
+            // Remember that ONE instances of this op will be injected into 
EVERY instance
+            // of the component ... that means that we can't do any aggresive 
caching
+            // inside the operation (the operation must be threadsafe).
+
+            public void perform(ComponentResources resources)
+            {
+                Locale locale = resources.getLocale();
+
+                for (String assetPath : paths)
+                {
+                    Asset asset = 
_assetSource.findAsset(model.getBaseResource(), assetPath, locale);
+
+                    handleAsset(asset);
+                }
+            }
+        };
+
+        String opFieldName = 
transformation.addInjectedField(ComponentResourcesOperation.class, "operation", 
op);
+
+        String resourcesName = transformation.getResourcesFieldName();
+
+        String body = String.format("%s.perform(%s);", opFieldName, 
resourcesName);
+
+        // This is what I like about this approach; the injected body is tiny. 
 The downside is that
+        // the object that gets injected is hard to test, hard enough that 
we'll just concentrate on
+        // the integration test, thank you.
+
+        transformation.extendMethod(TransformConstants.SETUP_RENDER_SIGNATURE, 
body);
+    }
+
+    /**
+     * Invoked, from the component's setup render phase, for each asset. This 
method must be
+     * threadsafe.  Most implementation pass the asset to a particular method
+     * of [EMAIL PROTECTED] PageRenderSupport}.
+     *
+     * @param asset to be processed
+     */
+    protected abstract void handleAsset(Asset asset);
+}

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeJavaScriptLibraryWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeJavaScriptLibraryWorker.java?rev=600203&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeJavaScriptLibraryWorker.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeJavaScriptLibraryWorker.java
 Sat Dec  1 14:22:18 2007
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.annotations.IncludeJavaScriptLibrary;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+
+public class IncludeJavaScriptLibraryWorker extends AbstractIncludeAssetWorker
+{
+
+    private final PageRenderSupport _pageRenderSupport;
+
+    public IncludeJavaScriptLibraryWorker(AssetSource assetSource, 
PageRenderSupport pageRenderSupport,
+                                          SymbolSource symbolSource)
+    {
+        super(assetSource, symbolSource);
+
+        _pageRenderSupport = pageRenderSupport;
+    }
+
+    public void transform(ClassTransformation transformation, final 
MutableComponentModel model)
+    {
+        IncludeJavaScriptLibrary annotation = 
transformation.getAnnotation(IncludeJavaScriptLibrary.class);
+
+        if (annotation != null) addOperationForAssetPaths(transformation, 
model, annotation.value());
+    }
+
+    protected void handleAsset(Asset asset)
+    {
+        _pageRenderSupport.addScriptLink(asset);
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java
 Sat Dec  1 14:22:18 2007
@@ -15,81 +15,36 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.Asset;
-import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.PageRenderSupport;
 import org.apache.tapestry.annotations.IncludeStylesheet;
-import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.services.SymbolSource;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.services.AssetSource;
 import org.apache.tapestry.services.ClassTransformation;
-import org.apache.tapestry.services.ComponentClassTransformWorker;
-import org.apache.tapestry.services.TransformConstants;
 
-import java.util.List;
-import java.util.Locale;
-
-public class IncludeStylesheetWorker implements ComponentClassTransformWorker
+public class IncludeStylesheetWorker extends AbstractIncludeAssetWorker
 {
-    private final AssetSource _assetSource;
 
     private final PageRenderSupport _pageRenderSupport;
 
-    private final SymbolSource _symbolSource;
-
     public IncludeStylesheetWorker(AssetSource assetSource, PageRenderSupport 
pageRenderSupport,
                                    SymbolSource symbolSource)
     {
-        _assetSource = assetSource;
+        super(assetSource, symbolSource);
+
         _pageRenderSupport = pageRenderSupport;
-        _symbolSource = symbolSource;
     }
 
     public void transform(ClassTransformation transformation, final 
MutableComponentModel model)
     {
         IncludeStylesheet annotation = 
transformation.getAnnotation(IncludeStylesheet.class);
 
-        if (annotation == null) return;
-
-        final List<String> paths = CollectionFactory.newList();
-
-        for (String value : annotation.value())
-        {
-            String expanded = _symbolSource.expandSymbols(value);
-
-            paths.add(expanded);
-        }
-
-        ComponentResourcesOperation op = new ComponentResourcesOperation()
-        {
-            // Remember that ONE instances of this op will be injected into 
EVERY instance
-            // of the component ... that means that we can't do any aggresive 
caching
-            // inside the operation (the operation must be threadsafe).
-
-            public void perform(ComponentResources resources)
-            {
-                Locale locale = resources.getLocale();
-
-                for (String assetPath : paths)
-                {
-                    Asset asset = 
_assetSource.findAsset(model.getBaseResource(), assetPath, locale);
-
-                    _pageRenderSupport.addStylesheetLink(asset, null);
-                }
-            }
-        };
-
-        String opFieldName = 
transformation.addInjectedField(ComponentResourcesOperation.class, 
"includeCSSOperation",
-                                                             op);
-
-        String resourcesName = transformation.getResourcesFieldName();
-
-        String body = String.format("%s.perform(%s);", opFieldName, 
resourcesName);
+        if (annotation != null) addOperationForAssetPaths(transformation, 
model, annotation.value());
+    }
 
-        // This is what I like about this approach; the injected body is tiny. 
 The downside is that
-        // the object that gets injected is hard to test, hard enough that 
we'll just concentrate on
-        // the integration test, thank you.
 
-        transformation.extendMethod(TransformConstants.SETUP_RENDER_SIGNATURE, 
body);
+    protected void handleAsset(Asset asset)
+    {
+        _pageRenderSupport.addStylesheetLink(asset, null);
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
 Sat Dec  1 14:22:18 2007
@@ -1406,12 +1406,16 @@
             @Override
             public void edit(FieldAccess access) throws CannotCompileException
             {
+                CtBehavior where = access.where();
+
+                if (where instanceof CtConstructor) return;
+
                 boolean isRead = access.isReader();
                 String fieldName = access.getFieldName();
-                CtBehavior where = access.where();
+                CtMethod method = (CtMethod) where;
 
-                _formatter.format("Checking field %s %s in %s: ", isRead ? 
"read" : "write", fieldName,
-                                  where.getLongName());
+                _formatter.format("Checking field %s %s in method %s(): ", 
isRead ? "read" : "write", fieldName,
+                                  method.getName());
 
                 // Ignore any methods to were added as part of the 
transformation.
                 // If we reference the field there, we really mean the field.

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
 Sat Dec  1 14:22:18 2007
@@ -249,6 +249,7 @@
      * annotation</li>
      * <li>InjectBlock -- allows a block from the template to be injected into 
a field</li>
      * <li>IncludeStylesheet -- supports the [EMAIL PROTECTED] 
org.apache.tapestry.annotations.IncludeStylesheet} annotation</li>
+     * <li>IncludeJavaScriptLibrary -- supports the [EMAIL PROTECTED] 
org.apache.tapestry.annotations.IncludeJavaScriptLibrary} annotation</li>
      * <li>SupportsInformalParameters -- checks for the annotation</li>
      * <li>Meta -- checks for meta data and adds it to the component model
      * <li>ApplicationState -- converts fields that reference application 
state objects
@@ -284,7 +285,6 @@
 
         configuration.add("Inject", new InjectWorker(locator, 
injectionProvider));
 
-        configuration.add("IncludeStylesheet", 
locator.autobuild(IncludeStylesheetWorker.class));
 
         configuration.add("MixinAfter", new MixinAfterWorker());
         configuration.add("Component", new ComponentWorker(resolver));
@@ -325,6 +325,10 @@
 
         configuration.add("Retain", new RetainWorker());
         configuration.add("Persist", new PersistWorker());
+
+        configuration.add("IncludeStylesheet", 
locator.autobuild(IncludeStylesheetWorker.class), "after:SetupRender");
+        configuration.add("IncludeJavaScriptLibrary", 
locator.autobuild(IncludeJavaScriptLibraryWorker.class),
+                          "after:SetupRender");
 
         // This one is always last. Any additional private fields that aren't 
annotated will
         // be converted to clear out at the end of the request.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt?rev=600203&r1=600202&r2=600203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt 
(original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt Sat Dec  
1 14:22:18 2007
@@ -132,6 +132,25 @@
   Inside a component, you should use Environmental, to highlight the fact that 
PageRenderSupport (like most
   environmental objects) is only available during rendering, not during action 
requests.
 
+IncludeJavaScriptLibrary Annotation
+
+  The
+  
{{{../../apidocs/org/apache/tapestry/annotations/IncludeJavaScriptLibrary.html}IncludeJavaScriptLibrary}}
 annotation
+  is the easy way to include one or more JavaScript libraries.
+
+  The previous example could be re-written as:
+
++---+
[EMAIL PROTECTED]("${tapestry.scriptaculous}/dragdrop.js")
+public class MyComponent
+{
+ . . .
+}
++---+
+
+  This saves you the effort of injecting the asset and making the call to 
PageRenderSupport.
+  Chances are you will <still> inject PageRenderSupport so as to add some 
initialization JavaScript.
+
 Ajax Components and Mixins
 
 * Autocomplete Mixin


Reply via email to