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