You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/12/01 23:22:20 UTC
svn commit: r600203 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/annotations/
main/java/org/apache/tapestry/corelib/components/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/services/ ...
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
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+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 {@link SelectModel} will be rendered, but are not supported by the many
* browsers, and are not fully handled on the client side.
*/
+@IncludeJavaScriptLibrary("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, {@link #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 {@link 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 {@link org.apache.tapestry.annotations.IncludeStylesheet} annotation</li>
+ * <li>IncludeJavaScriptLibrary -- supports the {@link 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:
+
++---+
+@InjectJavaScriptLibrary("${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