You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/12/01 20:57:20 UTC
svn commit: r600189 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/annotations/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/services/ main/resources/org/apache/tapestry/
site/ site/apt...
Author: hlship
Date: Sat Dec 1 11:57:19 2007
New Revision: 600189
URL: http://svn.apache.org/viewvc?rev=600189&view=rev
Log:
TAPESTRY-1935: Create an annotation to add a CSS stylesheet to the rendered page
Added:
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/internal/services/ComponentResourcesOperation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/css.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/app.css
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MethodPrefixTarget.java
Added: 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=600189&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/IncludeStylesheet.java Sat Dec 1 11:57:19 2007
@@ -0,0 +1,40 @@
+// 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.*;
+
+
+/**
+ * Used to automatically include a CSS stylesheet when rendering the page. The value is an asset reference; relative
+ * paths are relative to the Java class, or a "context:" prefix can be used to reference resources in the web application.
+ * <p/>
+ * This saves the work of injecting the asset into a field and injecting the PageRenderSupport environmental service, and invoking the method.
+ * <p/>
+ * Does not support setting a media type; if that is required. use {@link org.apache.tapestry.PageRenderSupport#addStylesheetLink(org.apache.tapestry.Asset, String)}
+ * directly.
+ *
+ * @see org.apache.tapestry.annotations.Path
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IncludeStylesheet
+{
+ /**
+ * One or more paths to be injected. Symbols in the path will be expanded.
+ */
+ String[] value();
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java Sat Dec 1 11:57:19 2007
@@ -16,6 +16,7 @@
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.AssetSource;
@@ -49,27 +50,21 @@
String expanded = _symbolSource.expandSymbols(path.value());
- String sourceFieldName = transformation.addInjectedField(
- AssetSource.class,
- "assetSource",
- _assetSource);
+ String sourceFieldName = transformation.addInjectedField(AssetSource.class, "assetSource", _assetSource);
+
+ String baseResourceFieldName = transformation.addInjectedField(Resource.class, "baseResource",
+ componentModel.getBaseResource());
+
String resourcesFieldName = transformation.getResourcesFieldName();
- String statement = format(
- "%s = (%s) %s.findAsset(%s.getBaseResource(), \"%s\", %s.getLocale());",
- fieldName,
- fieldType.getName(),
- sourceFieldName,
- resourcesFieldName,
- expanded,
- resourcesFieldName);
+ String statement = format("%s = (%s) %s.findAsset(%s, \"%s\", %s.getLocale());", fieldName, fieldType.getName(),
+ sourceFieldName, baseResourceFieldName, expanded, resourcesFieldName);
transformation.extendConstructor(statement);
transformation.makeReadOnly(fieldName);
return true;
-
}
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java?rev=600189&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java Sat Dec 1 11:57:19 2007
@@ -0,0 +1,31 @@
+// 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.ComponentResources;
+
+/**
+ * A kind of callback that can easily be injected into a transformed class to perform complex work.
+ * <p/>
+ * These callbacks are often injected into a transformed component class via {@link org.apache.tapestry.services.ClassTransformation#addInjectedField(Class, String, Object)}. Bear in mind
+ * that such callbacks must be <em>threadsafe</em>, since every instance of such a class will share a single instance of the operation.
+ */
+public interface ComponentResourcesOperation
+{
+ /**
+ * Perform some operation that requires the components' resources.
+ */
+ void perform(ComponentResources resources);
+}
Added: 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=600189&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IncludeStylesheetWorker.java Sat Dec 1 11:57:19 2007
@@ -0,0 +1,95 @@
+// 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.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
+{
+ private final AssetSource _assetSource;
+
+ private final PageRenderSupport _pageRenderSupport;
+
+ private final SymbolSource _symbolSource;
+
+ public IncludeStylesheetWorker(AssetSource assetSource, PageRenderSupport pageRenderSupport,
+ SymbolSource symbolSource)
+ {
+ _assetSource = assetSource;
+ _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);
+
+ // 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);
+ }
+}
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=600189&r1=600188&r2=600189&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 11:57:19 2007
@@ -245,10 +245,10 @@
* <li>Environment -- allows fields to contain values extracted from the {@link Environment}
* service</li>
* <li>Inject -- used with the {@link Inject} annotation, when a value is supplied</li>
- * <li>InjectResources -- used with the {@link Inject} annotation, when no value is supplied</li>
* <li>InjectPage -- adds code to allow access to other pages via the {@link InjectPage} field
* 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>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
@@ -283,6 +283,8 @@
configuration.add("ApplicationState", new ApplicationStateWorker(applicationStateManager));
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));
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js Sat Dec 1 11:57:19 2007
@@ -455,7 +455,7 @@
// (borders and such). Typically, such a Zone div will initially be invisible.
// The show and update functions apply to the Zone div, not the update div.
- var updates = div.select("DIV.t-zone-update");
+ var updates = this.div.select("DIV.t-zone-update");
this.updatediv = updates.length == 0 ? this.div : updates[0];
},
Added: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/css.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/css.apt?rev=600189&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/css.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/css.apt Sat Dec 1 11:57:19 2007
@@ -0,0 +1,56 @@
+ ---
+ Tapestry CSS Support
+ ---
+
+Tapestry CSS Support
+
+ Cascading Style Sheets (CSS) is an important technology, even with Tapestry. Tapestry works best when the
+ rendered HTML is simple and semantic -- semantic meaning HTML that goes back to its roots, simple, straightforward,
+ with tags used for structure and, as much as possible, details about font, color and layout delegated to CSS.
+
+Default CSS Stylesheet
+
+ Tapestry includes a built-in stylesheet, default.css, is all HTML documents (documents that have an outer
+ \<html\> element and a nested \<head\> element). The default.css stylesheet is always ordered <first> ... any additional stylesheets
+ will come after. This allows Tapestry's default styles to be overridden.
+
+ All the styles in the default stylesheet are prefixed with "t-" (for Tapestry).
+
+Adding your own CSS
+
+ A page or component that is rendering the \<head\> tag can add a stylesheet directly in the markup.
+
++---+
+<head>
+ <link href="/css/myapp.css" rel="stylesheet" type="text/css"/>
+ . . .
++---+
+
+ If you want to leverage Tapestry's localization support, you may want to make use of an expansion and the asset: binding prefix:
+
+
++---+
+<head>
+ <link href="${asset:context:css/myapp.css}" rel="stylesheet" type="text/css"/>
+ . . .
++---+
+
+ The "asset:" prefix means that the remainder of the expansion is a path to a resource. The "context:" part
+ indicates that it should look for the resource in the web application root (src/main/webapp in your workspace). If you
+ left this out, it would look for the file on the classpath, relative to the component's Java class.
+
+Using the IncludeStylesheet Annotation
+
+ Another approach to adding a stylesheet is to include an
+ {{{../../apidocs/org/apache/tapestry/annotations/IncludeStylesheet.html}IncludeStylesheet}} annotation on your component class:
+
++---+
+@IncludeStylesheet("context:css/myapp.css")
+public class MyComponent
+{
+
+}
++---+
+
+ As with {{{ajax.html}included JavaScript libraries}}, the stylesheet will only be added once,
+ regardless of the number of components that include it via the annotation.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml Sat Dec 1 11:57:19 2007
@@ -61,6 +61,7 @@
<item name="Input Validation" href="guide/validation.html"/>
<item name="BeanEditForm Guide" href="guide/beaneditform.html"/>
<item name="Component Events" href="guide/event.html"/>
+ <item name="CSS" href="guide/css.html"/>
<item name="Ajax" href="guide/ajax.html"/>
<item name="Page Lifecycle" href="guide/lifecycle.html"/>
<item name="Component Mixins" href="guide/mixins.html"/>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/app.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/app.css?rev=600189&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/app.css (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/css/app.css Sat Dec 1 11:57:19 2007
@@ -0,0 +1,3 @@
+BODY {
+ font-family: "Trebuchet MS";
+}
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sat Dec 1 11:57:19 2007
@@ -43,6 +43,10 @@
{
start("AssetDemo");
+ // Test for https://issues.apache.org/jira/browse/TAPESTRY-1935
+
+ assertSourcePresent("<link href=\"/css/app.css\" rel=\"stylesheet\" type=\"text/css\">");
+
assertText("//img[@id='icon']/@src", "/images/tapestry_banner.gif");
// doesn't prove that the image shows up in the client browser (it does, but
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java Sat Dec 1 11:57:19 2007
@@ -14,9 +14,12 @@
package org.apache.tapestry.integration.app1.components;
+import org.apache.tapestry.annotations.IncludeStylesheet;
+
/**
* Here's a component with a template, including a t:body element.
*/
+@IncludeStylesheet("context:css/app.css")
public class Border
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java Sat Dec 1 11:57:19 2007
@@ -17,6 +17,7 @@
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.AssetSource;
@@ -57,6 +58,7 @@
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
Path annotation = mockPath();
+ Resource baseResource = mockResource();
String fieldName = "myField";
Class fieldType = Object.class;
@@ -69,6 +71,11 @@
train_expandSymbols(symbolSource, value, expanded);
train_addInjectedField(ct, AssetSource.class, "assetSource", assetSource, "as");
+
+ train_getBaseResource(model, baseResource);
+
+ train_addInjectedField(ct, Resource.class, "baseResource", baseResource, "br");
+
train_getResourcesFieldName(ct, "rez");
// This only tests that the code is generated as expected (which is a bit brittle), it
@@ -76,8 +83,7 @@
// tests for that.
ct
- .extendConstructor(
- "myField = (java.lang.Object) as.findAsset(rez.getBaseResource(), \"foo.gif\", rez.getLocale());");
+ .extendConstructor("myField = (java.lang.Object) as.findAsset(br, \"foo.gif\", rez.getLocale());");
ct.makeReadOnly(fieldName);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MethodPrefixTarget.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MethodPrefixTarget.java?rev=600189&r1=600188&r2=600189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MethodPrefixTarget.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MethodPrefixTarget.java Sat Dec 1 11:57:19 2007
@@ -1,3 +1,17 @@
+// 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;
public class MethodPrefixTarget