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 2010/02/19 19:54:29 UTC
svn commit: r911931 [1/3] - in /tapestry/tapestry5/trunk: src/site/apt/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/
tapestry-core/src/main/java/org/apache/tapestry5/internal/services/
tapestry-core/src/main/java/org/apache/tape...
Author: hlship
Date: Fri Feb 19 18:54:27 2010
New Revision: 911931
URL: http://svn.apache.org/viewvc?rev=911931&view=rev
Log:
Put humpty-dumpty back together again, in terms of getting all the ComponentClassTransformWorkers working together again.
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app2/FortyTwo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app2/PlusOne.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app2/pages/TestPrefixMethod.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app2/pages/TestPrefixMethod2.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/PrefixMethodTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorkerTest.java
Modified:
tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCache.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCacheImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentMethodInvocationBuilder.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResourcesInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderCommandWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/linksubmit.js
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app2/services/LocaleAppModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java
Modified: tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/upgrade.apt?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/upgrade.apt Fri Feb 19 18:54:27 2010
@@ -14,6 +14,24 @@
Release 5.2.0
+* ClassTransformation API changes
+
+ The
+ {{{apidocs/org/apache/tapestry5/services/ClassTransformation.html}ClassTransformation}}
+ API, used to implement component meta-programming,
+ has been rewritten with an eye to making class transformations easier to implement while
+ removing the dependency on the Javassist library. This is of note only to <advanced> users who have implemented
+ {{{apidocs/org/apache/tapestry5/services/ComponentClassTransformWorker.html}ComponentClassTransformWorker}}s, which operate on
+ the
+
+ Much of the existing API has been deprecated and <some> deprecated
+ methods are now non-functional. The deprecated methods will be removed in Tapestry 5.3.
+
+ This represents a shift in how the API operates; previously much of the logic in ComponentClassTransformWorkers
+ was built in terms of Javassist: adding new bytecode to existing methods. The new API switches away from this, and
+ now works in terms of adding new fields, initializing those fields using callbacks, providing callbacks for access
+ to fields, and adding advice to methods.
+
* Asset Security
Tapestry now includes a new mechanism for ensuring the security of server-side assets, addressing a bug
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java Fri Feb 19 18:54:27 2010
@@ -1,10 +1,10 @@
-// Copyright 2008, 2009 The Apache Software Foundation
+// Copyright 2008, 2009, 2010 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
+// 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,
@@ -17,14 +17,16 @@
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.Heartbeat;
import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.javascript.JavascriptSupport;
/**
* Generates a client-side hyperlink that submits the enclosing form. If the link is clicked in the browser, the
- * component will trigger an event ({@linkplain EventConstants#SELECTED selected} by default) , just like {@link
- * Submit}.
+ * component will trigger an event ({@linkplain EventConstants#SELECTED selected} by default) , just like {@link Submit}
+ * .
*/
@SupportsInformalParameters
@IncludeJavaScriptLibrary("linksubmit.js")
@@ -55,7 +57,7 @@
private ComponentResources resources;
@Inject
- private RenderSupport renderSupport;
+ private JavascriptSupport javascriptSupport;
@Environmental
private FormSupport formSupport;
@@ -110,15 +112,15 @@
{
if (!disabled)
{
- clientId = renderSupport.allocateClientId(resources);
+ clientId = javascriptSupport.allocateClientId(resources);
formSupport.store(this, new ProcessSubmission(clientId));
writer.element("a",
- "id", clientId,
+ "id", clientId,
- "href", "#");
+ "href", "#");
if (!request.isXHR())
writer.attributes(MarkupConstants.ONCLICK, MarkupConstants.WAIT_FOR_PAGE);
@@ -133,7 +135,9 @@
{
writer.end();
- renderSupport.addInit("linkSubmit", formSupport.getClientId(), clientId);
+ JSONObject spec = new JSONObject("form", formSupport.getClientId(), "clientId", clientId);
+
+ javascriptSupport.addInitializerCall("linkSubmit", spec);
}
}
@@ -142,4 +146,3 @@
return clientId;
}
}
-
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Select.java Fri Feb 19 18:54:27 2010
@@ -4,7 +4,7 @@
// 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
+// 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,
@@ -47,12 +47,13 @@
* can be overriden by binding the encoder parameter, or extended by contributing a {@link ValueEncoderFactory} into the
* service's configuration.
*/
-@Events({EventConstants.VALIDATE, EventConstants.VALUE_CHANGED + " when 'zone' parameter is bound"})
+@Events(
+{ EventConstants.VALIDATE, EventConstants.VALUE_CHANGED + " when 'zone' parameter is bound" })
public class Select extends AbstractField
{
public static final String FORM_COMPONENTID_PARAMETER = "t:formcomponentid";
public static final String CHANGE_EVENT = "change";
-
+
private class Renderer extends SelectModelRenderer
{
@@ -71,7 +72,7 @@
/**
* Allows a specific implementation of {@link ValueEncoder} to be supplied. This is used to create client-side
* string values for the different options.
- *
+ *
* @see ValueEncoderSource
*/
@Parameter
@@ -93,14 +94,14 @@
/**
* Controls whether an additional blank option is provided. The blank option precedes all other options and is never
- * selected. The value for the blank option is always the empty string, the label may be the blank string; the
+ * selected. The value for the blank option is always the empty string, the label may be the blank string; the
* label is from the blankLabel parameter (and is often also the empty string).
*/
@Parameter(value = "auto", defaultPrefix = BindingConstants.LITERAL)
private BlankOption blankOption;
/**
- * The label to use for the blank option, if rendered. If not specified, the container's message catalog is
+ * The label to use for the blank option, if rendered. If not specified, the container's message catalog is
* searched for a key, <code><em>id</em>-blanklabel</code>.
*/
@Parameter(defaultPrefix = BindingConstants.LITERAL)
@@ -127,9 +128,10 @@
*/
@Parameter(required = true, principal = true, autoconnect = true)
private Object value;
-
+
/**
- * Binding the zone parameter will cause any change of Select's value to be handled as an Ajax request that updates the
+ * Binding the zone parameter will cause any change of Select's value to be handled as an Ajax request that updates
+ * the
* indicated zone. The component will trigger the event {@link EventConstants#VALUE_CHANGED} to inform its
* container that Select's value has changed.
*
@@ -140,7 +142,7 @@
@Inject
private FieldValidationSupport fieldValidationSupport;
-
+
@Environmental
private FormSupport formSupport;
@@ -179,7 +181,8 @@
return TapestryInternalUtils.isEqual(clientValue, selectedClientValue);
}
- @SuppressWarnings({ "unchecked" })
+ @SuppressWarnings(
+ { "unchecked" })
@Override
protected void processSubmission(String elementName)
{
@@ -188,7 +191,7 @@
tracker.recordInput(this, submittedValue);
Object selectedValue = toValue(submittedValue);
-
+
putPropertyNameIntoBeanValidationContext("value");
try
@@ -201,7 +204,7 @@
{
tracker.recordError(this, ex.getMessage());
}
-
+
removePropertyNameFromBeanValidationContext();
}
@@ -213,18 +216,18 @@
void beginRender(MarkupWriter writer)
{
writer.element("select", "name", getControlName(), "id", getClientId());
-
+
putPropertyNameIntoBeanValidationContext("value");
validate.render(writer);
-
+
removePropertyNameFromBeanValidationContext();
resources.renderInformalParameters(writer);
// Disabled is via a mixin
-
- if (this.zone != null)
+
+ if (this.zone != null)
{
final Link link = this.resources.createEventLink(CHANGE_EVENT);
@@ -239,8 +242,8 @@
this.renderSupport.addInit("updateZoneOnEvent", spec);
}
}
-
- Object onChange()
+
+ Object onChange()
{
final String formId = this.request.getParameter(FORM_COMPONENTID_PARAMETER);
@@ -250,9 +253,9 @@
final Holder<Object> holder = Holder.create();
- final ComponentEventCallback callback = new ComponentEventCallback()
+ final ComponentEventCallback callback = new ComponentEventCallback()
{
- public boolean handleResult(final Object result)
+ public boolean handleResult(final Object result)
{
holder.put(result);
@@ -263,20 +266,23 @@
}
};
- this.componentResources.triggerEvent(EventConstants.VALUE_CHANGED, new Object[] { newValue }, callback);
+ this.componentResources.triggerEvent(EventConstants.VALUE_CHANGED, new Object[]
+ { newValue }, callback);
- final PartialMarkupRendererFilter filter = new PartialMarkupRendererFilter()
+ final PartialMarkupRendererFilter filter = new PartialMarkupRendererFilter()
{
- public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
+ public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
{
HiddenFieldPositioner hiddenFieldPositioner = new HiddenFieldPositioner(writer, Select.this.rules);
- final ComponentActionSink actionSink = new ComponentActionSink(Select.this.logger, Select.this.clientDataEncoder);
+ final ComponentActionSink actionSink = new ComponentActionSink(Select.this.logger,
+ Select.this.clientDataEncoder);
final Form form = (Form) Select.this.componentSource.getComponent(formId);
- FormSupport formSupport = form.createRenderTimeFormSupport(form.getClientId(), actionSink, new IdAllocator());
+ FormSupport formSupport = form.createRenderTimeFormSupport(form.getClientId(), actionSink,
+ new IdAllocator());
Select.this.environment.push(FormSupport.class, formSupport);
Select.this.environment.push(ValidationTracker.class, new ValidationTrackerImpl());
@@ -286,8 +292,8 @@
Select.this.environment.pop(ValidationTracker.class);
Select.this.environment.pop(FormSupport.class);
- hiddenFieldPositioner.getElement().attributes("type", "hidden", "name", Form.FORM_DATA,
- "value", actionSink.getClientData());
+ hiddenFieldPositioner.getElement().attributes("type", "hidden", "name", Form.FORM_DATA, "value",
+ actionSink.getClientData());
}
};
@@ -297,7 +303,7 @@
return holder.get();
}
- protected Object toValue(final String submittedValue)
+ protected Object toValue(final String submittedValue)
{
return InternalUtils.isBlank(submittedValue) ? null : this.encoder.toValue(submittedValue);
}
@@ -313,7 +319,8 @@
{
Class valueType = resources.getBoundType("value");
- if (valueType == null) return null;
+ if (valueType == null)
+ return null;
if (Enum.class.isAssignableFrom(valueType))
return new EnumSelectModel(valueType, resources.getContainerMessages());
@@ -335,7 +342,8 @@
String key = resources.getId() + "-blanklabel";
- if (containerMessages.contains(key)) return containerMessages.get(key);
+ if (containerMessages.contains(key))
+ return containerMessages.get(key);
return null;
}
@@ -352,7 +360,8 @@
// Failing that, see if there is a current value (via the value parameter), and
// convert that to a client value for later comparison.
- if (selectedClientValue == null) selectedClientValue = value == null ? null : encoder.toClient(value);
+ if (selectedClientValue == null)
+ selectedClientValue = value == null ? null : encoder.toClient(value);
if (showBlankOption())
{
@@ -361,7 +370,6 @@
writer.end();
}
-
SelectModelVisitor renderer = new Renderer(writer);
model.visit(renderer);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java Fri Feb 19 18:54:27 2010
@@ -17,14 +17,17 @@
import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Id;
+import org.apache.tapestry5.internal.transform.ReadOnlyFieldValueConduit;
import org.apache.tapestry5.ioc.ObjectLocator;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentValueProvider;
import org.apache.tapestry5.services.InjectionProvider;
import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformField;
import org.apache.tapestry5.services.TransformMethod;
/**
@@ -40,32 +43,42 @@
public class BlockInjectionProvider implements InjectionProvider
{
- public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+ public boolean provideInjection(final String fieldName, Class fieldType, ObjectLocator locator,
ClassTransformation transformation, MutableComponentModel componentModel)
{
if (!fieldType.equals(Block.class))
return false;
- Id annotation = transformation.getFieldAnnotation(fieldName, Id.class);
+ TransformField field = transformation.getField(fieldName);
- final String blockId = getBlockId(fieldName, annotation);
+ Id annotation = field.getAnnotation(Id.class);
- ComponentValueProvider<Block> provider = new ComponentValueProvider<Block>()
- {
- public Block get(ComponentResources resources)
- {
- return resources.getBlock(blockId);
- }
- };
+ String blockId = getBlockId(fieldName, annotation);
- TransformMethod method = transformation
- .getMethod(TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE);
+ ComponentValueProvider<FieldValueConduit> provider = cxreateProvider(fieldName, blockId);
- transformation.getField(fieldName).assignIndirect(method, provider);
+ field.replaceAccess(provider);
return true; // claim the field
}
+ private ComponentValueProvider<FieldValueConduit> cxreateProvider(final String fieldName, final String blockId)
+ {
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(final ComponentResources resources)
+ {
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
+ {
+ public Object get()
+ {
+ return resources.getBlock(blockId);
+ }
+ };
+ }
+ };
+ }
+
private String getBlockId(String fieldName, Id annotation)
{
if (annotation != null)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCache.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCache.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCache.java Fri Feb 19 18:54:27 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 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
+// 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,
@@ -15,16 +15,28 @@
package org.apache.tapestry5.internal.services;
/**
- * A cache for converting between class names and component (or other) classes. For component classes, ensures that the
+ * A cache for converting between class names and component (or other) classes. For component classes, ensures that the
* class is the transformed class.
*/
public interface ComponentClassCache
{
/**
* Gets the Class instance for the given fully-qualified class name.
- *
- * @param className fully qualified class name, or a primitive type name, or an array name (in source format)
+ *
+ * @param className
+ * fully qualified class name, or a primitive type name, or an array name (in source format)
* @return the class instance
*/
Class forName(String className);
+
+ /**
+ * Computes the default value for a field of the given type, returns the appropriate
+ * default value. This is typically null, but may be false (for a primitive boolean) or some
+ * version of 0 (for a primitive numeric field). Wrapper types will still be null.
+ *
+ * @param className
+ * type of field
+ * @since 5.2.0
+ */
+ Object defaultValueForType(String className);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCacheImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCacheImpl.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCacheImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentClassCacheImpl.java Fri Feb 19 18:54:27 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 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
+// 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,
@@ -17,6 +17,7 @@
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.ClassFactory;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.ComponentLayer;
import org.apache.tapestry5.services.InvalidationListener;
@@ -28,9 +29,13 @@
private final ClassFactory classFactory;
- public ComponentClassCacheImpl(@ComponentLayer ClassFactory classFactory)
+ private final TypeCoercer typeCoercer;
+
+ public ComponentClassCacheImpl(@ComponentLayer
+ ClassFactory classFactory, TypeCoercer typeCoercer)
{
this.classFactory = classFactory;
+ this.typeCoercer = typeCoercer;
}
public void objectWasInvalidated()
@@ -38,8 +43,20 @@
cache.clear();
}
+ @SuppressWarnings("unchecked")
+ public Object defaultValueForType(String className)
+ {
+ Class clazz = forName(className);
+
+ if (!clazz.isPrimitive())
+ return null;
- public Class forName(final String className)
+ // Remembering that 0 coerces to boolean false, this covers all the primitive
+ // types (boolean, int, short, etc.)
+ return typeCoercer.coerce(0, clazz);
+ }
+
+ public Class forName(String className)
{
Class result = cache.get(className);
@@ -47,7 +64,6 @@
{
result = lookupClassForType(className);
-
cache.put(className, result);
}
@@ -56,7 +72,8 @@
private Class lookupClassForType(String className)
{
- if (className.equals("void")) return void.class;
+ if (className.equals("void"))
+ return void.class;
if (ClassFabUtils.isPrimitiveType(className))
return ClassFabUtils.getPrimitiveType(className);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentMethodInvocationBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentMethodInvocationBuilder.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentMethodInvocationBuilder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentMethodInvocationBuilder.java Fri Feb 19 18:54:27 2010
@@ -158,7 +158,7 @@
builder.end();
/** Replace the original method with the new implementation. */
- transformation.addMethod(advisedMethod, builder.toString());
+ transformation.addNewMethod(advisedMethod, builder.toString());
}
private void implementInvokeAdvisedMethod(String advisedMethodName)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResourcesInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResourcesInjectionProvider.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResourcesInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentResourcesInjectionProvider.java Fri Feb 19 18:54:27 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2010 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
+// 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,
@@ -15,32 +15,50 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.internal.transform.ReadOnlyFieldValueConduit;
import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.ClassTransformation;
+import org.apache.tapestry5.services.ComponentValueProvider;
import org.apache.tapestry5.services.InjectionProvider;
-
-import static java.lang.String.format;
+import org.apache.tapestry5.services.TransformField;
/**
* Allows for the injection of the component's {@link org.apache.tapestry5.ComponentResources}.
*/
public class ComponentResourcesInjectionProvider implements InjectionProvider
{
- public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
- ClassTransformation transformation, MutableComponentModel componentModel)
+
+ public boolean provideInjection(final String fieldName, Class fieldType, ObjectLocator locator,
+ ClassTransformation transformation, MutableComponentModel componentModel)
{
- if (fieldType.equals(ComponentResources.class))
- {
- String body = format("%s = %s;", fieldName, transformation.getResourcesFieldName());
+ if (!fieldType.equals(ComponentResources.class))
+ return false;
- transformation.extendConstructor(body);
+ TransformField field = transformation.getField(fieldName);
- transformation.makeReadOnly(fieldName);
+ ComponentValueProvider<FieldValueConduit> provider = createResourcesFieldConduitProvider(fieldName);
- return true;
- }
+ field.replaceAccess(provider);
- return false;
+ return true;
+ }
+
+ private ComponentValueProvider<FieldValueConduit> createResourcesFieldConduitProvider(final String fieldName)
+ {
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(final ComponentResources resources)
+ {
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
+ {
+ public Object get()
+ {
+ return resources;
+ }
+ };
+ }
+ };
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java Fri Feb 19 18:54:27 2010
@@ -19,6 +19,7 @@
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
+import org.apache.tapestry5.services.TransformMethod;
import org.apache.tapestry5.services.TransformMethodSignature;
import java.util.List;
@@ -30,6 +31,14 @@
public interface InternalClassTransformation extends ClassTransformation
{
/**
+ * Adds a new method to the transformed class, possibly replacing an existing method or
+ * overriding a base-class method.
+ *
+ * @since 5.2.0
+ */
+ TransformMethod addNewMethod(TransformMethodSignature signature, String methodBody);
+
+ /**
* Invoked after all {@link ComponentClassTransformWorker}s have had their chance to work over the class. This
* performs any final operations for the class transformation, which includes coming up with the final constructor
* method for the class.
@@ -60,8 +69,7 @@
*/
String searchForPreviousInjection(InjectionKey key);
- InternalClassTransformation createChildTransformation(CtClass childClass,
- MutableComponentModel childModel);
+ InternalClassTransformation createChildTransformation(CtClass childClass, MutableComponentModel childModel);
/**
* Returns the parent transformation, or null for a root class.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Fri Feb 19 18:54:27 2010
@@ -106,6 +106,12 @@
}
+ @Override
+ public String toString()
+ {
+ return String.format("TransformMethod[%s]", getMethodIdentifier());
+ }
+
public int compareTo(TransformMethod o)
{
return sig.compareTo(o.getSignature());
@@ -139,6 +145,8 @@
builder = createBuilder(sig);
builder.addAdvice(advice);
+
+ formatter.format("add advice %s : %s\n\n", sig.getMediumDescription(), advice);
}
public MethodAccess getAccess()
@@ -304,7 +312,7 @@
builder.end();
- addMethod(accessMethodSignature, builder.toString());
+ addNewMethod(accessMethodSignature, builder.toString());
return methodName;
}
@@ -331,7 +339,6 @@
{
if (identifier == null)
{
-
int lineNumber = method.getMethodInfo2().getLineNumber(0);
CtClass enclosingClass = method.getDeclaringClass();
String sourceFile = enclosingClass.getClassFile2().getSourceFile();
@@ -394,8 +401,6 @@
private Object claimTag;
- boolean removed;
-
String readValueBody, writeValueBody;
private org.apache.tapestry5.services.FieldAccess access;
@@ -419,6 +424,13 @@
primitive = ClassFabUtils.isPrimitiveType(type);
}
+ @Override
+ public String toString()
+ {
+ return String.format("TransformField[%s %s.%s(%s)]", Modifier.toString(field.getModifiers()),
+ getClassName(), name, type);
+ }
+
public int compareTo(TransformField o)
{
return name.compareTo(o.getName());
@@ -461,6 +473,8 @@
getClassName(), claimTag, tag));
claimTag = tag;
+
+ formatter.format("Field %s claimed by %s\n\n", name, tag);
}
public boolean isClaimed()
@@ -600,29 +614,6 @@
return addOrReplaceMethod(signature, String.format("%s = $1;", name), false);
}
- public void remove()
- {
- if (removed)
- throw new RuntimeException(String.format("Field %s.%s has already been marked for removal.", ctClass
- .getName(), name));
-
- removed = true;
-
- formatter.format("remove field %s;\n\n", name);
- }
-
- void doRemove()
- {
- try
- {
- ctClass.removeField(field);
- }
- catch (NotFoundException ex)
- {
- throw new RuntimeException(ex);
- }
- }
-
public void replaceAccess(ComponentValueProvider<FieldValueConduit> conduitProvider)
{
replaceAccess(addIndirectInjectedField(FieldValueConduit.class, name + "$conduit", conduitProvider));
@@ -652,7 +643,7 @@
// this does nothing. but for primitive types, it will unwrap
// the wrapper type back to a primitive.
- addMethod(readSig, String.format("return ($r) ((%s) %s.get());", cast, conduitFieldName));
+ addNewMethod(readSig, String.format("return ($r) ((%s) %s.get());", cast, conduitFieldName));
replaceReadAccess(readMethodName);
@@ -662,42 +653,9 @@
new String[]
{ type }, null);
- addMethod(writeSig, String.format("%s.set(($w) $1);", conduitFieldName));
+ addNewMethod(writeSig, String.format("%s.set(($w) $1);", conduitFieldName));
replaceWriteAccess(writeMethodName);
-
- remove();
- }
-
- public <T> void assignIndirect(TransformMethod method, ComponentValueProvider<T> provider)
- {
- Defense.notNull(method, "method");
- Defense.notNull(provider, "provider");
-
- String providerFieldName = addInjectedField(ComponentValueProvider.class, name + "$provider", provider);
-
- CtClass fieldType = null;
-
- try
- {
- fieldType = field.getType();
- }
- catch (NotFoundException ex)
- {
- throw new RuntimeException(ex);
- }
-
- String body = String.format("%s = (%s) %s.get(%s);", name, fieldType.getName(), providerFieldName,
- resourcesFieldName);
-
- extendMethod(method.getSignature(), body);
-
- makeReadOnly(name);
- }
-
- public <T> void assignIndirect(TransformMethodSignature signature, ComponentValueProvider<T> provider)
- {
- assignIndirect(getMethod(signature), provider);
}
public void inject(Object value)
@@ -717,7 +675,7 @@
String argName = addConstructorArg(providerType, provider);
- extendConstructor(String.format(" %s = (%s) %s.get(%s);", name, type, argName, resourcesFieldName));
+ addToConstructor(String.format(" %s = (%s) %s.get(%s);", name, type, argName, resourcesFieldName));
makeReadOnly(name);
}
@@ -803,7 +761,7 @@
resourcesFieldName = addInjectedFieldUncached(InternalComponentResources.class, "resources", null);
- addMethod(GET_COMPONENT_RESOURCES_SIGNATURE, "return " + resourcesFieldName + ";");
+ addNewMethod(GET_COMPONENT_RESOURCES_SIGNATURE, "return " + resourcesFieldName + ";");
// The "}" will be added later, inside finish().
}
@@ -951,7 +909,7 @@
public <T extends Annotation> T getMethodAnnotation(TransformMethodSignature signature, Class<T> annotationClass)
{
- return getMethod(signature).getAnnotation(annotationClass);
+ return getOrCreateMethod(signature).getAnnotation(annotationClass);
}
/**
@@ -1179,18 +1137,17 @@
public void addMethod(TransformMethodSignature signature, String methodBody)
{
- addOrReplaceMethod(signature, methodBody, true);
+ removed("addMethod(TransformMethodSignature,String)");
}
- public TransformMethod createMethod(TransformMethodSignature signature)
+ public TransformMethod addNewMethod(TransformMethodSignature signature, String methodBody)
{
- failIfFrozen();
-
- if (methods.containsKey(signature))
- throw new RuntimeException(String.format(
- "Unable to create new method %s as it already exists in class %s.", signature, getClassName()));
+ return addOrReplaceMethod(signature, methodBody, true);
+ }
- return addOrReplaceMethod(signature, null, true);
+ public TransformMethod addNewTransformedMethod(TransformMethodSignature signature, String methodBody)
+ {
+ return addOrReplaceMethod(signature, methodBody, false);
}
/**
@@ -1268,53 +1225,7 @@
public void addTransformedMethod(TransformMethodSignature signature, String methodBody)
{
- failIfFrozen();
-
- CtClass returnType = findCtClass(signature.getReturnType());
- CtClass[] parameters = buildCtClassList(signature.getParameterTypes());
- CtClass[] exceptions = buildCtClassList(signature.getExceptionTypes());
-
- try
- {
- CtMethod existing = ctClass.getDeclaredMethod(signature.getMethodName(), parameters);
-
- if (existing != null)
- throw new RuntimeException(ServicesMessages.addNewMethodConflict(signature));
- }
- catch (NotFoundException ex)
- {
- // That's ok. Kind of sloppy to rely on a thrown exception; wish getDeclaredMethod()
- // would return null for
- // that case. Alternately, we could maintain a set of the method signatures of declared
- // or added methods.
- }
-
- try
- {
- CtMethod method = new CtMethod(returnType, signature.getMethodName(), parameters, ctClass);
-
- // TODO: Check for duplicate method add
-
- method.setModifiers(signature.getModifiers());
-
- method.setBody(methodBody);
- method.setExceptionTypes(exceptions);
-
- ctClass.addMethod(method);
-
- recordMethod(method, false);
- }
- catch (CannotCompileException ex)
- {
- throw new MethodCompileException(ServicesMessages.methodCompileError(signature, methodBody, ex),
- methodBody, ex);
- }
- catch (NotFoundException ex)
- {
- throw new RuntimeException(ex);
- }
-
- addMethodToDescription("add transformed", signature, methodBody);
+ removed("addTransformedMethod(TransformMethodSignature,String)");
}
private CtClass[] buildCtClassList(String[] typeNames)
@@ -1341,12 +1252,12 @@
public void extendMethod(TransformMethodSignature methodSignature, String methodBody)
{
- getMethod(methodSignature).extend(methodBody);
+ removed("extendMethod(TransformMethodSignature, String)");
}
public void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody)
{
- extendMethod(methodSignature, methodBody);
+ removed("extendExistingMethod(TransformMethodSignature, String)");
}
public void copyMethod(TransformMethodSignature sourceMethod, int modifiers, String newMethodName)
@@ -1357,7 +1268,7 @@
CtClass[] parameters = buildCtClassList(sourceMethod.getParameterTypes());
CtClass[] exceptions = buildCtClassList(sourceMethod.getExceptionTypes());
- TransformMethodImpl tmi = findOrOverrideMethod(sourceMethod);
+ TransformMethodImpl tmi = locateExistingOrCreateOverrideMethod(sourceMethod);
CtMethod source = tmi.method;
@@ -1393,40 +1304,12 @@
public void addCatch(TransformMethodSignature methodSignature, String exceptionType, String body)
{
- failIfFrozen();
-
- TransformMethodImpl tmi = findOrOverrideMethod(methodSignature);
- CtClass exceptionCtType = findCtClass(exceptionType);
-
- try
- {
- tmi.method.addCatch(body, exceptionCtType);
- }
- catch (CannotCompileException ex)
- {
- throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, body, ex), body, ex);
- }
-
- addMethodToDescription(String.format("catch(%s) in", exceptionType), methodSignature, body);
+ removed("addCatch(TransformMethodSignature, String, String)");
}
public void prefixMethod(TransformMethodSignature methodSignature, String methodBody)
{
- failIfFrozen();
-
- TransformMethodImpl tmi = findOrOverrideMethod(methodSignature);
-
- try
- {
- tmi.method.insertBefore(methodBody);
- }
- catch (CannotCompileException ex)
- {
- throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, methodBody, ex),
- methodBody, ex);
- }
-
- addMethodToDescription("prefix", methodSignature, methodBody);
+ removed("prefixMethod(TransformMethodSignature, String)");
}
private void addMethodToDescription(String operation, TransformMethodSignature methodSignature, String methodBody)
@@ -1462,11 +1345,21 @@
description.append("\n\n");
}
- public TransformMethod getMethod(TransformMethodSignature signature)
+ public TransformMethod getOrCreateMethod(TransformMethodSignature signature)
{
failIfFrozen();
- return findOrOverrideMethod(signature);
+ return findOverrideOrCreateMethod(signature);
+ }
+
+ private TransformMethodImpl findOverrideOrCreateMethod(TransformMethodSignature signature)
+ {
+ TransformMethodImpl result = findOrOverrideMethod(signature);
+
+ if (result != null)
+ return result;
+
+ return addOrReplaceMethod(signature, null, true);
}
private TransformMethodImpl findOrOverrideMethod(TransformMethodSignature signature)
@@ -1476,7 +1369,12 @@
if (result != null)
return result;
- result = addOverrideOfSuperclassMethod(signature);
+ return addOverrideOfSuperclassMethod(signature);
+ }
+
+ private TransformMethodImpl locateExistingOrCreateOverrideMethod(TransformMethodSignature signature)
+ {
+ TransformMethodImpl result = findOrOverrideMethod(signature);
if (result != null)
return result;
@@ -1687,7 +1585,7 @@
{
TransformFieldImpl tmi = (TransformFieldImpl) object;
- return !(tmi.added || tmi.removed || tmi.isClaimed());
+ return !(tmi.added || tmi.isClaimed());
}
});
}
@@ -1793,7 +1691,7 @@
// field type and assign. This will likely not work with
// primitives and arrays, but that's ok for now.
- extendConstructor(String.format(" %s = (%s) %s.get(%s);", field.getName(), type.getName(), argName,
+ addToConstructor(String.format(" %s = (%s) %s.get(%s);", field.getName(), type.getName(), argName,
resourcesFieldName));
return field;
@@ -1844,7 +1742,7 @@
public void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice)
{
- getMethod(methodSignature).addAdvice(advice);
+ getOrCreateMethod(methodSignature).addAdvice(advice);
}
public boolean isMethodOverride(TransformMethodSignature methodSignature)
@@ -1853,7 +1751,7 @@
throw new IllegalArgumentException(String.format("Method %s is not implemented by transformed class %s.",
methodSignature, getClassName()));
- return getMethod(methodSignature).isOverride();
+ return getOrCreateMethod(methodSignature).isOverride();
}
public InternalClassTransformation getParentTransformation()
@@ -1881,7 +1779,7 @@
*/
private void addInjectToConstructor(String fieldName, CtClass fieldType, Object value)
{
- extendConstructor(String.format(" %s = %s;", fieldName, addConstructorArg(fieldType, value)));
+ addToConstructor(String.format(" %s = %s;", fieldName, addConstructorArg(fieldType, value)));
}
public void injectField(String fieldName, Object value)
@@ -2000,19 +1898,8 @@
public Instantiator createInstantiator()
{
- if (Modifier.isAbstract(ctClass.getModifiers())) { return new Instantiator()
- {
- public Component newInstance(InternalComponentResources resources)
- {
- throw new RuntimeException(String.format("Component class %s is abstract and can not be instantiated.",
- ctClass.getName()));
- }
-
- public ComponentModel getModel()
- {
- return componentModel;
- }
- }; }
+ if (Modifier.isAbstract(ctClass.getModifiers()))
+ return createAbstractClassInstantiator();
String componentClassName = getClassName();
@@ -2104,6 +1991,23 @@
}
}
+ private Instantiator createAbstractClassInstantiator()
+ {
+ return new Instantiator()
+ {
+ public Component newInstance(InternalComponentResources resources)
+ {
+ throw new RuntimeException(String.format("Component class %s is abstract and can not be instantiated.",
+ ctClass.getName()));
+ }
+
+ public ComponentModel getModel()
+ {
+ return componentModel;
+ }
+ };
+ }
+
private void failIfFrozen()
{
if (frozen)
@@ -2217,14 +2121,14 @@
String body = String.format("throw new java.lang.RuntimeException(\"%s\");", message);
- addMethod(sig, body);
+ addNewMethod(sig, body);
replaceWriteAccess(fieldName, methodName);
}
public void removeField(String fieldName)
{
- getField(fieldName).remove();
+ removed("removeField(String)");
}
public void replaceReadAccess(String fieldName, String methodName)
@@ -2244,12 +2148,6 @@
if (fieldAccessReplaced)
replaceFieldAccess();
-
- for (TransformFieldImpl tfi : fields.values())
- {
- if (tfi.removed)
- tfi.doRemove();
- }
}
static final int SYNTHETIC = 0x00001000;
@@ -2359,17 +2257,18 @@
public void extendConstructor(String statement)
{
- Defense.notNull(statement, "statement");
-
- failIfFrozen();
+ removed("extendConstructor(String)");
+ }
+ void addToConstructor(String statement)
+ {
constructor.append(statement);
constructor.append("\n");
}
public String getMethodIdentifier(TransformMethodSignature signature)
{
- return getMethod(signature).getMethodIdentifier();
+ return getOrCreateMethod(signature).getMethodIdentifier();
}
public boolean isRootTransformation()
@@ -2421,4 +2320,20 @@
{
return new ComponentMethodInvocationBuilder(this, componentClassCache, signature, classSource);
}
+
+ public boolean isDeclaredMethod(TransformMethodSignature signature)
+ {
+ failIfFrozen();
+
+ Defense.notNull(signature, "signature");
+
+ return methods.containsKey(signature);
+ }
+
+ private void removed(String methodName)
+ {
+ throw new RuntimeException(String.format(
+ "Method ClassTransformation.%s has been deprecated and is no longer functional. "
+ + "Please consult the JavaDoc for a suitable replacement.", methodName));
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java Fri Feb 19 18:54:27 2010
@@ -106,7 +106,7 @@
}
};
- transformation.getMethod(TransformConstants.SETUP_RENDER_SIGNATURE).addAdvice(advice);
+ transformation.getOrCreateMethod(TransformConstants.SETUP_RENDER_SIGNATURE).addAdvice(advice);
model.addRenderPhase(SetupRender.class);
}
@@ -128,7 +128,7 @@
}
};
- transformation.getMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE).addAdvice(advice);
+ transformation.getOrCreateMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE).addAdvice(advice);
}
private List<String> expandSymbolsInPaths(String[] paths)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java Fri Feb 19 18:54:27 2010
@@ -14,6 +14,8 @@
package org.apache.tapestry5.internal.transform;
+import java.lang.reflect.Modifier;
+
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.MixinClasses;
@@ -27,6 +29,7 @@
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.model.MutableEmbeddedComponentModel;
@@ -34,7 +37,6 @@
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
import org.apache.tapestry5.services.ComponentValueProvider;
-import org.apache.tapestry5.services.TransformConstants;
import org.apache.tapestry5.services.TransformField;
/**
@@ -56,47 +58,72 @@
{
for (TransformField field : transformation.matchFieldsWithAnnotation(Component.class))
{
- Component annotation = field.getAnnotation(Component.class);
+ transformField(transformation, model, field);
+ }
+ }
- field.claim(annotation);
+ private void transformField(ClassTransformation transformation, MutableComponentModel model, TransformField field)
+ {
+ Component annotation = field.getAnnotation(Component.class);
- String annotationId = annotation.id();
+ field.claim(annotation);
- String fieldName = field.getName();
+ String annotationId = annotation.id();
- final String id = InternalUtils.isNonBlank(annotationId) ? annotationId : InternalUtils
- .stripMemberName(fieldName);
+ String fieldName = field.getName();
- String type = field.getType();
+ String id = InternalUtils.isNonBlank(annotationId) ? annotationId : InternalUtils.stripMemberName(fieldName);
- Location location = new StringLocation(String.format("%s.%s", transformation
- .getClassName(), fieldName), 0);
+ String type = field.getType();
- MutableEmbeddedComponentModel embedded = model.addEmbeddedComponent(id, annotation
- .type(), type, annotation.inheritInformalParameters(), location);
+ Location location = new StringLocation(String.format("%s.%s", transformation.getClassName(), fieldName), 0);
- addParameters(embedded, annotation.parameters());
+ MutableEmbeddedComponentModel embedded = model.addEmbeddedComponent(id, annotation.type(), type, annotation
+ .inheritInformalParameters(), location);
- String names = annotation.publishParameters();
- if (InternalUtils.isNonBlank(names))
- {
- embedded.setPublishedParameters(CollectionFactory.newList(TapestryInternalUtils
- .splitAtCommas(names)));
- }
+ addParameters(embedded, annotation.parameters());
- ComponentValueProvider<Object> provider = new ComponentValueProvider<Object>()
+ updateModelWithPublishedParameters(embedded, annotation);
+
+ convertAccessToField(transformation, field, id);
+
+ addMixinClasses(field, embedded);
+ addMixinTypes(field, embedded);
+ }
+
+ private void convertAccessToField(ClassTransformation transformation, TransformField field, String id)
+ {
+ String fieldName = field.getName();
+
+ ComponentValueProvider<FieldValueConduit> provider = createProviderForEmbeddedComponentConduit(fieldName, id);
+
+ field.replaceAccess(provider);
+ }
+
+ private ComponentValueProvider<FieldValueConduit> createProviderForEmbeddedComponentConduit(final String fieldName,
+ final String id)
+ {
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(final ComponentResources resources)
{
- public Object get(ComponentResources resources)
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
{
- return resources.getEmbeddedComponent(id);
- }
- };
+ public Object get()
+ {
+ return resources.getEmbeddedComponent(id);
+ }
+ };
+ }
+ };
+ }
- field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, provider);
+ private void updateModelWithPublishedParameters(MutableEmbeddedComponentModel embedded, Component annotation)
+ {
+ String names = annotation.publishParameters();
- addMixinClasses(field, embedded);
- addMixinTypes(field, embedded);
- }
+ if (InternalUtils.isNonBlank(names))
+ embedded.setPublishedParameters(CollectionFactory.newList(TapestryInternalUtils.splitAtCommas(names)));
}
private void addMixinClasses(TransformField field, MutableEmbeddedComponentModel model)
@@ -109,13 +136,13 @@
boolean orderEmpty = annotation.order().length == 0;
if (!orderEmpty && annotation.order().length != annotation.value().length)
- throw new TapestryException(TransformMessages.badMixinConstraintLength(annotation,
- field.getName()), model, null);
+ throw new TapestryException(TransformMessages.badMixinConstraintLength(annotation, field.getName()), model,
+ null);
for (int i = 0; i < annotation.value().length; i++)
{
- String[] constraints = orderEmpty ? InternalConstants.EMPTY_STRING_ARRAY
- : TapestryInternalUtils.splitMixinConstraints(annotation.order()[i]);
+ String[] constraints = orderEmpty ? InternalConstants.EMPTY_STRING_ARRAY : TapestryInternalUtils
+ .splitMixinConstraints(annotation.order()[i]);
model.addMixin(annotation.value()[i].getName(), constraints);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java Fri Feb 19 18:54:27 2010
@@ -17,12 +17,12 @@
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.InjectContainer;
import org.apache.tapestry5.internal.services.ComponentClassCache;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
import org.apache.tapestry5.services.ComponentValueProvider;
-import org.apache.tapestry5.services.TransformConstants;
import org.apache.tapestry5.services.TransformField;
/**
@@ -41,38 +41,57 @@
public void transform(ClassTransformation transformation, MutableComponentModel model)
{
- for (final TransformField field : transformation
- .matchFieldsWithAnnotation(InjectContainer.class))
+ for (final TransformField field : transformation.matchFieldsWithAnnotation(InjectContainer.class))
{
- final String fieldName = field.getName();
+ transformField(model, field);
+ }
+ }
+
+ private void transformField(MutableComponentModel model, TransformField field)
+ {
+ InjectContainer annotation = field.getAnnotation(InjectContainer.class);
+
+ field.claim(annotation);
+
+ ComponentValueProvider<FieldValueConduit> provider = createFieldValueConduitProvider(field);
+
+ field.replaceAccess(provider);
+ }
- final String fieldTypeName = field.getType();
+ private ComponentValueProvider<FieldValueConduit> createFieldValueConduitProvider(TransformField field)
+ {
+
+ final String fieldName = field.getName();
- final String componentClassName = model.getComponentClassName();
+ final String fieldTypeName = field.getType();
- ComponentValueProvider<Object> provider = new ComponentValueProvider<Object>()
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(final ComponentResources resources)
{
- public Object get(ComponentResources resources)
- {
- Component container = resources.getContainer();
+ final Class fieldType = cache.forName(fieldTypeName);
- Class fieldType = cache.forName(fieldTypeName);
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
+ {
- if (!fieldType.isInstance(container))
+ public Object get()
{
- String message = String.format(
- "Component %s is not assignable to field %s.%s (of type %s).",
- container.getComponentResources().getCompleteId(),
- componentClassName, fieldName, fieldTypeName);
+ Component container = resources.getContainer();
- throw new RuntimeException(message);
- }
+ if (!fieldType.isInstance(container))
+ {
+ String message = String.format(
+ "Component %s is not assignable to field %s.%s (of type %s).", container
+ .getComponentResources().getCompleteId(), resources.getComponentModel()
+ .getComponentClassName(), fieldName, fieldTypeName);
- return container;
- }
- };
+ throw new RuntimeException(message);
+ }
- field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, provider);
- }
+ return container;
+ }
+ };
+ }
+ };
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java Fri Feb 19 18:54:27 2010
@@ -49,7 +49,7 @@
if (!transformation.isRootTransformation())
return;
- TransformMethod method = transformation.getMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE);
+ TransformMethod method = transformation.getOrCreateMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE);
method.addAdvice(advice);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java Fri Feb 19 18:54:27 2010
@@ -18,12 +18,12 @@
import org.apache.tapestry5.annotations.Mixin;
import org.apache.tapestry5.internal.InternalComponentResources;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
import org.apache.tapestry5.services.ComponentValueProvider;
-import org.apache.tapestry5.services.TransformConstants;
import org.apache.tapestry5.services.TransformField;
/**
@@ -46,32 +46,54 @@
{
for (TransformField field : transformation.matchFieldsWithAnnotation(Mixin.class))
{
- Mixin annotation = field.getAnnotation(Mixin.class);
+ replaceFieldWithMixin(model, field);
+ }
+ }
- field.claim(annotation);
+ private void replaceFieldWithMixin(MutableComponentModel model, TransformField field)
+ {
+ Mixin annotation = field.getAnnotation(Mixin.class);
- String mixinType = annotation.value();
+ field.claim(annotation);
- String[] order = annotation.order();
+ String mixinType = annotation.value();
- String fieldType = field.getType();
+ String[] order = annotation.order();
- final String mixinClassName = InternalUtils.isBlank(mixinType) ? fieldType : resolver
- .resolveMixinTypeToClassName(mixinType);
+ String fieldType = field.getType();
- model.addMixinClassName(mixinClassName, order);
+ String mixinClassName = InternalUtils.isBlank(mixinType) ? fieldType : resolver
+ .resolveMixinTypeToClassName(mixinType);
- ComponentValueProvider<Object> provider = new ComponentValueProvider<Object>()
- {
- public Object get(ComponentResources resources)
- {
- InternalComponentResources icr = (InternalComponentResources) resources;
+ model.addMixinClassName(mixinClassName, order);
- return icr.getMixinByClassName(mixinClassName);
- }
- };
+ replaceFieldAccessWithMixin(field, mixinClassName);
+ }
- field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, provider);
- }
+ private void replaceFieldAccessWithMixin(TransformField field, String mixinClassName)
+ {
+ ComponentValueProvider<FieldValueConduit> provider = createMixinFieldProvider(field.getName(), mixinClassName);
+
+ field.replaceAccess(provider);
+ }
+
+ private ComponentValueProvider<FieldValueConduit> createMixinFieldProvider(final String fieldName,
+ final String mixinClassName)
+ {
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(ComponentResources resources)
+ {
+ final InternalComponentResources icr = (InternalComponentResources) resources;
+
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
+ {
+ public Object get()
+ {
+ return icr.getMixinByClassName(mixinClassName);
+ }
+ };
+ }
+ };
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java Fri Feb 19 18:54:27 2010
@@ -96,7 +96,7 @@
{
ComponentMethodAdvice advice = createDispatchComponentEventAdvice(invokers);
- transformation.getMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
+ transformation.getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
}
private ComponentMethodAdvice createDispatchComponentEventAdvice(final List<EventHandlerMethodInvoker> invokers)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java Fri Feb 19 18:54:27 2010
@@ -62,7 +62,7 @@
ComponentMethodAdvice advice = createAdvice(field, annotation);
- transformation.getMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
+ transformation.getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
if (annotation.activate())
model.addEventHandler(EventConstants.ACTIVATE);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java Fri Feb 19 18:54:27 2010
@@ -64,7 +64,7 @@
ComponentMethodAdvice advice = createAdviceToInvokeMethod(access);
- transformation.getMethod(lifecycleMethodSignature).addAdvice(advice);
+ transformation.getOrCreateMethod(lifecycleMethodSignature).addAdvice(advice);
}
private ComponentMethodAdvice createAdviceToInvokeMethod(final MethodAccess access)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageResetAnnotationWorker.java Fri Feb 19 18:54:27 2010
@@ -74,12 +74,12 @@
ComponentMethodAdvice advice = createMethodAccessAdvice(methodAccess);
- transformation.getMethod(CONTAINING_PAGE_DID_RESET).addAdvice(advice);
+ transformation.getOrCreateMethod(CONTAINING_PAGE_DID_RESET).addAdvice(advice);
}
private ComponentMethodAdvice createMethodAccessAdvice(final List<MethodAccess> methodAccess)
{
- ComponentMethodAdvice advice = new ComponentMethodAdvice()
+ return new ComponentMethodAdvice()
{
public void advise(ComponentMethodInvocation invocation)
{
@@ -98,7 +98,6 @@
}
}
};
- return advice;
}
private List<MethodAccess> convertToMethodAccess(List<TransformMethod> methods)
@@ -125,7 +124,7 @@
transformation.addImplementedInterface(PageResetListener.class);
- transformation.getMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE).addAdvice(
+ transformation.getOrCreateMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE).addAdvice(
registerAsListenerAdvice);
model.setMeta(META_KEY, "true");