You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/01/12 21:51:51 UTC
svn commit: r495735 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/ main/java/org/apache/tapestry/annotations/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/internal/structure/ main/java...
Author: hlship
Date: Fri Jan 12 12:51:50 2007
New Revision: 495735
URL: http://svn.apache.org/viewvc?view=rev&rev=495735
Log:
Add support for the <t:block> element in component templates, and the ability to access and inject Block instances into component classes.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/BlockNotFoundException.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BlockDemo.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectAssetWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectAssetWorkerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/BlockNotFoundException.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/BlockNotFoundException.java?view=auto&rev=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/BlockNotFoundException.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/BlockNotFoundException.java Fri Jan 12 12:51:50 2007
@@ -0,0 +1,26 @@
+// 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;
+
+/**
+ * Exception thrown when a a {@link Block} is requested but not found.
+ */
+public class BlockNotFoundException extends RuntimeException
+{
+ public BlockNotFoundException(String message)
+ {
+ super(message);
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Fri Jan 12 12:51:50 2007
@@ -109,4 +109,15 @@
* @return the element name
*/
String getElementName();
+
+ /**
+ * Returns a block from the component's template, referenced by its id.
+ *
+ * @param blockId
+ * the id of the block
+ * @return the identified Block
+ * @throws BlockNotFoundException
+ * if no block with the given id exists
+ */
+ Block getBlock(String blockId);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java Fri Jan 12 12:51:50 2007
@@ -21,8 +21,11 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
+import org.apache.commons.logging.Log;
import org.apache.tapestry.Asset;
+import org.apache.tapestry.Block;
import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Messages;
/**
* Allows injection of various objects into a component class. In certain cases, the type of the
@@ -37,9 +40,21 @@
* </pre>
*
* <p>
- * Finally, for certain specific types (such as {@link ComponentResources}), the value is omitted
- * entirely, and an object appropriate to the component instance is injected.
- *
+ * There is a complex relationship between the type of the field and the interpretation of the
+ * annotation and its value.
+ * <p>
+ * For type {@link Asset}, the value is a relative path to the asset.
+ * <p>
+ * For type {@link Block}, the value is the id of a block in the component's template. When the
+ * value is omitted, it is deduced from the field name.
+ * <p>
+ * Finally, for certain specific types, the value is omitted entirely, and an object appropriate to
+ * the component instance is injected. This includes {@link ComponentResources}, Locale (for the
+ * containing page's locale), {@link Messages} (the component's message catalog), {@link Log} to log
+ * errors or debugging data, and String for the component's complete id.
+ * <p>
+ * And if nothing else matches and the value is omitted, then a search for Tapestry IOC service
+ * implementing the interface defined by the fields type occurs.
* @see org.apache.tapestry.services.InjectionProvider
*/
@Target(FIELD)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectAssetWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectAssetWorker.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectAssetWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectAssetWorker.java Fri Jan 12 12:51:50 2007
@@ -28,7 +28,8 @@
/**
* Supports injection for fields of type {@link Asset}. This worker must be scheduled
- * <em>before</em> {@link InjectNamedWorker}.
+ * <em>before</em> {@link InjectNamedWorker}, because it uses the same annotation, {@link Inject},
+ * but interprets the value as the relative path to the asset.
*
* @see AssetSource
*/
@@ -61,7 +62,7 @@
// If the field has no annotation, or no value for its annotation, that's probably
// a programmer error, but we'll let the later Inject-related workers complain about it.
-
+
if (annotation == null)
continue;
@@ -98,7 +99,7 @@
transformation.makeReadOnly(name);
// Keep InjectNamedWorker from doing anything to it.
-
+
transformation.claimField(name, annotation);
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java?view=auto&rev=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java Fri Jan 12 12:51:50 2007
@@ -0,0 +1,92 @@
+// 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 java.util.List;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Identifies fields of type {@link Block} that have the {@link Inject} annotation and converts them
+ * into read-only fields containing the injected Block from the template. The annotation's value is
+ * the id of the block to inject; if ommitted, the block id is deduced from the field id.
+ * <p>
+ * Must be scheduled before {@link InjectNamedWorker} because it uses the same annotation, Inject,
+ * with a different interpretation.
+ */
+public class InjectBlockWorker implements ComponentClassTransformWorker
+{
+ static final String BLOCK_TYPE_NAME = Block.class.getName();
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ List<String> fieldNames = transformation.findFieldsOfType(BLOCK_TYPE_NAME);
+
+ if (fieldNames.isEmpty())
+ return;
+
+ BodyBuilder builder = new BodyBuilder();
+ builder.begin();
+
+ int count = 0;
+
+ String resourcesFieldName = transformation.getResourcesFieldName();
+
+ for (String fieldName : fieldNames)
+ {
+ Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
+
+ if (annotation == null)
+ continue;
+
+ String blockId = getBlockId(fieldName, annotation);
+
+ builder.addln("%s = %s.getBlock(\"%s\");", fieldName, resourcesFieldName, blockId);
+
+ transformation.makeReadOnly(fieldName);
+ transformation.claimField(fieldName, annotation);
+
+ count++;
+ }
+
+ // Fields yes, but no annotations, so nothing to really do.
+
+ if (count == 0)
+ return;
+
+ builder.end();
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
+ .toString());
+ }
+
+ private String getBlockId(String fieldName, Inject annotation)
+ {
+ String annotationId = annotation.value();
+
+ if (InternalUtils.isNonBlank(annotationId))
+ return annotationId;
+
+ return InternalUtils.stripMemberPrefix(fieldName);
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java Fri Jan 12 12:51:50 2007
@@ -48,6 +48,7 @@
import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.util.MultiKey;
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
import org.apache.tapestry.ioc.internal.util.IdAllocator;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.model.ComponentModel;
@@ -196,6 +197,7 @@
_constructor.append(");\n");
+ // The "}" will be added later, inside
}
private void freeze()
@@ -1166,6 +1168,8 @@
_constructor.append(" ");
_constructor.append(initializer);
+ // This finally matches the "{" added inside the constructor
+
_constructor.append("();\n\n}");
String constructorBody = _constructor.toString();
@@ -1469,4 +1473,14 @@
{
return _log;
}
+
+ public void addToConstructor(String statement)
+ {
+ Defense.notNull(statement, "statement");
+
+ failIfFrozen();
+
+ _constructor.append(statement);
+ }
+
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java Fri Jan 12 12:51:50 2007
@@ -27,6 +27,7 @@
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.internal.InternalConstants;
import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.internal.parser.BlockToken;
import org.apache.tapestry.internal.parser.BodyToken;
import org.apache.tapestry.internal.parser.CommentToken;
import org.apache.tapestry.internal.parser.ComponentTemplate;
@@ -36,6 +37,7 @@
import org.apache.tapestry.internal.parser.StartElementToken;
import org.apache.tapestry.internal.parser.TemplateToken;
import org.apache.tapestry.internal.parser.TextToken;
+import org.apache.tapestry.internal.structure.BlockImpl;
import org.apache.tapestry.internal.structure.BodyPageElement;
import org.apache.tapestry.internal.structure.ComponentPageElement;
import org.apache.tapestry.internal.structure.Page;
@@ -75,7 +77,7 @@
private final LinkedList<Boolean> _discardEndTagStack = newLinkedList();
- private final LinkedList<Runnable> _endElementStack = newLinkedList();
+ private final LinkedList<Runnable> _endElementCommandStack = newLinkedList();
private final IdAllocator _idAllocator = new IdAllocator();
@@ -233,7 +235,7 @@
addToBody(element);
}
- Runnable runnable = _endElementStack.removeFirst();
+ Runnable runnable = _endElementCommandStack.removeFirst();
// Used to return environment to prior state.
@@ -397,6 +399,10 @@
comment((CommentToken) token);
break;
+ case BLOCK:
+ block((BlockToken) token);
+ break;
+
default:
throw new IllegalStateException("Not implemented yet: " + token);
}
@@ -410,6 +416,33 @@
// as the ComponentTemplate is valid.
}
+ private void block(BlockToken token)
+ {
+ // Don't use the page element factory here becauses we need something that is both Block and
+ // BodyPageElement
+ // and don't want to use casts.
+
+ BlockImpl block = new BlockImpl(token.getLocation());
+
+ String id = token.getId();
+
+ if (id != null)
+ _loadingElement.addBlock(id, block);
+
+ _bodyPageElementStack.addFirst(block);
+ _discardEndTagStack.addFirst(true);
+
+ Runnable cleanup = new Runnable()
+ {
+ public void run()
+ {
+ _bodyPageElementStack.removeFirst();
+ }
+ };
+
+ _endElementCommandStack.add(cleanup);
+ }
+
private void startComponent(StartComponentToken token)
{
String elementName = token.getElementName();
@@ -503,7 +536,7 @@
}
};
- _endElementStack.addFirst(cleanup);
+ _endElementCommandStack.addFirst(cleanup);
}
private void startElement(StartElementToken token)
@@ -520,7 +553,7 @@
// Do NOT discard the end tag; add it to the body.
_discardEndTagStack.addFirst(false);
- _endElementStack.addFirst(NO_OP);
+ _endElementCommandStack.addFirst(NO_OP);
}
private void text(TextToken token)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java Fri Jan 12 12:51:50 2007
@@ -14,6 +14,7 @@
package org.apache.tapestry.internal.structure;
+import org.apache.tapestry.Block;
import org.apache.tapestry.ComponentResourcesCommon;
import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.InternalComponentResourcesCommon;
@@ -53,8 +54,14 @@
* ... where a template contains elements that are all components, those components will receive
* portions of the template as their body.
*/
-
void addToTemplate(PageElement element);
+
+ /**
+ * Used during the contruction of a page to add a non-annonymous Block to the component.
+ *
+ * @see ComponentResourcesCommon#getBlock(String)
+ */
+ void addBlock(String blockId, Block block);
/**
* Adds a component to its container. The embedded component's id must be unique within the
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Fri Jan 12 12:51:50 2007
@@ -24,6 +24,8 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.Binding;
+import org.apache.tapestry.Block;
+import org.apache.tapestry.BlockNotFoundException;
import org.apache.tapestry.ComponentEventHandler;
import org.apache.tapestry.Link;
import org.apache.tapestry.MarkupWriter;
@@ -358,6 +360,8 @@
}
};
+ private Map<String, Block> _blocks;
+
private List<PageElement> _body;
private Map<String, ComponentPageElement> _children;
@@ -474,9 +478,10 @@
}
};
- // We know that, at the very least, there will be an element to force the component to render its body,
+ // We know that, at the very least, there will be an element to force the component to render
+ // its body,
// so there's no reason to wait to initialize the list.
-
+
private final List<PageElement> _template = newList();
private final TypeCoercer _typeCoercer;
@@ -939,7 +944,7 @@
{
// TODO: An error if the _render flag is already set (recursive rendering not
// allowed or advisable).
-
+
// Once we start rendering, the page is considered dirty, until we cleanup post render.
_page.incrementDirtyCount();
@@ -1008,6 +1013,26 @@
public void queueRender(RenderQueue queue)
{
queue.push(this);
+ }
+
+ public Block getBlock(String id)
+ {
+ Block result = InternalUtils.get(_blocks, id);
+
+ if (result == null)
+ throw new BlockNotFoundException(StructureMessages.blockNotFound(_completeId, id));
+
+ return result;
+ }
+
+ public void addBlock(String blockId, Block block)
+ {
+ if (_blocks == null)
+ _blocks = newMap();
+
+ // TODO: Check for duplicates.
+
+ _blocks.put(blockId, block);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Fri Jan 12 12:51:50 2007
@@ -21,6 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.Binding;
+import org.apache.tapestry.Block;
import org.apache.tapestry.ComponentEventHandler;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.Link;
@@ -293,4 +294,8 @@
_element.queueRender(queue);
}
+ public Block getBlock(String blockId)
+ {
+ return _element.getBlock(blockId);
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java Fri Jan 12 12:51:50 2007
@@ -70,4 +70,9 @@
{
return MESSAGES.format("wrong-event-result-type", method, expectedType.getName());
}
+
+ static String blockNotFound(String componentId, String blockId)
+ {
+ return MESSAGES.format("block-not-found", componentId, blockId);
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java Fri Jan 12 12:51:50 2007
@@ -267,6 +267,14 @@
void addMethod(MethodSignature signature, String methodBody);
/**
+ * Adds a statement to the constructor.
+ *
+ * @param statement
+ * the statement to add, which should end with a semicolon
+ */
+ void addToConstructor(String statement);
+
+ /**
* Replaces all read-references to the specified field with invocations of the specified method
* name. Replacements do not occur in methods added via
* {@link #addMethod(MethodSignature, String)} or {@link #extendMethod(MethodSignature, String)}.
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Fri Jan 12 12:51:50 2007
@@ -78,6 +78,7 @@
import org.apache.tapestry.internal.services.InfrastructureManagerImpl;
import org.apache.tapestry.internal.services.InjectAnonymousWorker;
import org.apache.tapestry.internal.services.InjectAssetWorker;
+import org.apache.tapestry.internal.services.InjectBlockWorker;
import org.apache.tapestry.internal.services.InjectComponentWorker;
import org.apache.tapestry.internal.services.InjectNamedWorker;
import org.apache.tapestry.internal.services.InjectPageWorker;
@@ -629,6 +630,7 @@
* <li>InjectAnnonymous -- 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>SupportsInformalParameters -- checks for the annotation</li>
* <li>UnclaimedField -- identifies unclaimed fields and resets them to null/0/false at the end
* of the request</li>
@@ -657,12 +659,15 @@
new InjectAnonymousWorker(locator, injectionProvider),
"after:InjectNamed");
configuration.add("InjectAsset", new InjectAssetWorker(assetSource), "before:InjectNamed");
+ configuration.add("InjectBlock", new InjectBlockWorker(), "before:InjectNamed");
+
configuration.add("MixinAfter", new MixinAfterWorker());
configuration.add("Component", new ComponentWorker(resolver));
configuration.add("Environment", new EnvironmentalWorker(environment));
configuration.add("Mixin", new MixinWorker(resolver));
configuration.add("OnEvent", new OnEventWorker());
- configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
+ configuration.add("SupportsInf" +
+ "ormalParameters", new SupportsInformalParametersWorker());
configuration.add("InjectPage", new InjectPageWorker(requestPageCache));
configuration.add("InjectComponent", new InjectComponentWorker());
configuration.add("RenderCommand", new RenderCommandWorker());
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Fri Jan 12 12:51:50 2007
@@ -34,6 +34,7 @@
import org.apache.tapestry.Asset;
import org.apache.tapestry.Binding;
+import org.apache.tapestry.Block;
import org.apache.tapestry.ComponentEventHandler;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.ComponentResourcesCommon;
@@ -643,5 +644,25 @@
protected final Link newLink()
{
return newMock(Link.class);
+ }
+
+ protected final Block newBlock()
+ {
+ return newMock(Block.class);
+ }
+
+ protected final void train_getSupportsInformalParameters(ComponentModel model, boolean supports)
+ {
+ expect(model.getSupportsInformalParameters()).andReturn(supports);
+ }
+
+ protected final Inject newInject()
+ {
+ return newMock(Inject.class);
+ }
+
+ protected final void train_findFieldsOfType(ClassTransformation transformation, String type, String... fieldNames)
+ {
+ expect(transformation.findFieldsOfType(type)).andReturn(Arrays.asList(fieldNames));
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties Fri Jan 12 12:51:50 2007
@@ -22,4 +22,5 @@
wrong-event-result-type=Return value of method %s is not compatible with the expected return type of %s. \
The value has been ignored. \
Further lifecycle methods may be invoked, which is likely to cause incorrect application behavior. \
- You should change the method to return the correct type.
\ No newline at end of file
+ You should change the method to return the correct type.
+block-not-found=Template for component %s does not contain a block with identifier '%s'.
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BlockDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BlockDemo.html?view=auto&rev=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BlockDemo.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BlockDemo.html Fri Jan 12 12:51:50 2007
@@ -0,0 +1,19 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Block Demo</h1>
+
+ <p>
+ This page demonstrates how blocks may be used to contain text and other elements and control when and
+ if they are rendered.
+</p>
+
+ <form t:type="Form">
+ <select t:type="Select" t:id="blockName" model="',fred,barney'" onchange="'this.form.submit();'"/> <label for="blockName">Block to display</label>
+ </form>
+
+ <p>The block: [<t:comp type="Render" value="blockToRender"/>]</p>
+
+<t:block id="fred">Block fred.</t:block>
+<t:block id="barney">Block barney.</t:block>
+
+</html>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html Fri Jan 12 12:51:50 2007
@@ -6,11 +6,11 @@
This page demonstrates how a component may return a component instance from one of its render phase methods to allow that object to render.
</p>
- <t:comp type="NeverRender">
+ <t:block>
<span t:id="optional">
Optional Text
</span>
- </t:comp>
+ </t:block>
<form t:type="Form">
<input t:type="Checkbox" t:id="enabled" onchange="'this.form.submit();'"/> <label for="enabled">Enable optional text</label>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Fri Jan 12 12:51:50 2007
@@ -82,6 +82,9 @@
<li>
<a href="RenderComponentDemo.html">RenderComponentDemo</a> -- components that "nominate" other components to render
</li>
+ <li>
+ <a href="BlockDemo.html">BlockDemo</a> -- use of blocks to control rendering
+ </li>
</ul>
</td>
</tr>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Fri Jan 12 12:51:50 2007
@@ -109,7 +109,7 @@
// This is text passed from Start.html to Output as a parameter
assertTextPresent("we have basic parameters working");
-
+
assertSourcePresent("<!-- my comment -->");
}
@@ -494,6 +494,29 @@
// after all.
assertText("//span[@id='optional']", "Optional Text");
+ }
+
+ /**
+ * Tests the ability to inject a Block, and the ability to use the block to control rendering.
+ */
+ @Test
+ public void block_rendering() throws Exception
+ {
+ _selenium.open(BASE_URL);
+ clickAndWait("link=BlockDemo");
+
+ assertTextPresent("[]");
+
+ _selenium.select("//select[@id='blockName']", "fred");
+ _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+ assertTextPresent("[Block fred.]");
+
+ _selenium.select("//select[@id='blockName']", "barney");
+ _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+ assertTextPresent("[Block barney.]");
+
}
private byte[] readContent(URL url) throws Exception
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java?view=auto&rev=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java Fri Jan 12 12:51:50 2007
@@ -0,0 +1,64 @@
+// 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.integration.app1.pages;
+
+import java.util.Map;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.annotations.Retain;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+@ComponentClass
+public class BlockDemo
+{
+ @Inject
+ private Block _fred;
+
+ @Inject
+ private Block _barney;
+
+ // Blocks not injected until page load, so must lazily initialize the map.
+ @Retain
+ private Map<String, Block> _blocks = null;
+
+ @Persist
+ private String _blockName;
+
+ public Block getBlockToRender()
+ {
+ if (_blocks == null)
+ {
+ _blocks = CollectionFactory.newMap();
+ _blocks.put("fred", _fred);
+ _blocks.put("barney", _barney);
+ }
+
+ return _blocks.get(_blockName);
+ }
+
+ public String getBlockName()
+ {
+ return _blockName;
+ }
+
+ public void setBlockName(String blockName)
+ {
+ _blockName = blockName;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectAssetWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectAssetWorkerTest.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectAssetWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectAssetWorkerTest.java Fri Jan 12 12:51:50 2007
@@ -14,8 +14,6 @@
package org.apache.tapestry.internal.services;
-import java.util.Arrays;
-
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.Resource;
@@ -101,11 +99,5 @@
new InjectAssetWorker(source).transform(ct, model);
verify();
- }
-
- protected final void train_findFieldsOfType(ClassTransformation transformation,
- String typeName, String... names)
- {
- expect(transformation.findFieldsOfType(typeName)).andReturn(Arrays.asList(names));
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java?view=auto&rev=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java Fri Jan 12 12:51:50 2007
@@ -0,0 +1,107 @@
+// 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.annotations.Inject;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.TransformConstants;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * Tests a couple of edge cases where there's nothing to inject.
+ */
+public class InjectBlockWorkerTest extends TapestryTestCase
+{
+ @Test
+ public void no_fields_of_type_block()
+ {
+ ClassTransformation ct = newClassTransformation();
+ MutableComponentModel model = newMutableComponentModel();
+
+ train_findFieldsOfType(ct, InjectBlockWorker.BLOCK_TYPE_NAME);
+
+ replay();
+
+ new InjectBlockWorker().transform(ct, model);
+
+ verify();
+ }
+
+ @Test
+ public void field_missing_annotation()
+ {
+ ClassTransformation ct = newClassTransformation();
+ MutableComponentModel model = newMutableComponentModel();
+
+ train_findFieldsOfType(ct, InjectBlockWorker.BLOCK_TYPE_NAME, "fred");
+
+ train_getResourcesFieldName(ct, "rez");
+
+ train_getFieldAnnotation(ct, "fred", Inject.class, null);
+
+ replay();
+
+ new InjectBlockWorker().transform(ct, model);
+
+ verify();
+ }
+
+ /**
+ * This doesn't prove anything; later there will be integration tests that prove that the
+ * generated code is valid and works.
+ */
+ @Test
+ public void fields_with_annotations()
+ {
+ ClassTransformation ct = newClassTransformation();
+ MutableComponentModel model = newMutableComponentModel();
+ Inject fredAnnotation = newInject();
+ Inject barneyAnnotation = newInject();
+
+ train_findFieldsOfType(ct, InjectBlockWorker.BLOCK_TYPE_NAME, "fred", "_barneyBlock");
+
+ train_getResourcesFieldName(ct, "rez");
+
+ train_getFieldAnnotation(ct, "fred", Inject.class, fredAnnotation);
+
+ train_value(fredAnnotation, "");
+
+ ct.makeReadOnly("fred");
+ ct.claimField("fred", fredAnnotation);
+
+ train_getFieldAnnotation(ct, "_barneyBlock", Inject.class, barneyAnnotation);
+ train_value(barneyAnnotation, "barney");
+
+ ct.makeReadOnly("_barneyBlock");
+ ct.claimField("_barneyBlock", barneyAnnotation);
+
+ train_extendMethod(
+ ct,
+ TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+ "{",
+ "fred = rez.getBlock(\"fred\");",
+ "_barneyBlock = rez.getBlock(\"barney\");",
+ "}");
+
+ replay();
+
+ new InjectBlockWorker().transform(ct, model);
+
+ verify();
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java Fri Jan 12 12:51:50 2007
@@ -675,6 +675,35 @@
}
@Test
+ public void add_to_constructor() throws Exception
+ {
+ InternalComponentResources resources = newInternalComponentResources();
+
+ Log log = newLog();
+
+ replay();
+
+ CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
+
+ InternalClassTransformation ct = new InternalClassTransformationImpl(targetObjectCtClass,
+ _contextClassLoader, log, null);
+
+ ct.addToConstructor("_value = \"from constructor\";");
+
+ ct.finish();
+
+ Class transformed = _classPool.toClass(targetObjectCtClass, _loader);
+
+ Object target = ct.createInstantiator(transformed).newInstance(resources);
+
+ PropertyAccess access = new PropertyAccessImpl();
+
+ assertEquals(access.get(target, "value"), "from constructor");
+
+ verify();
+ }
+
+ @Test
public void inject_field() throws Exception
{
InternalComponentResources resources = newInternalComponentResources();
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java?view=diff&rev=495735&r1=495734&r2=495735
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java Fri Jan 12 12:51:50 2007
@@ -15,6 +15,8 @@
package org.apache.tapestry.internal.structure;
import org.apache.tapestry.Binding;
+import org.apache.tapestry.Block;
+import org.apache.tapestry.BlockNotFoundException;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.services.Instantiator;
@@ -31,6 +33,62 @@
public class ComponentPageElementImplTest extends InternalBaseTestCase
{
@Test
+ public void block_not_found()
+ {
+ Page page = newPage();
+ Component component = newComponent();
+ ComponentModel model = newComponentModel();
+ TypeCoercer coercer = newTypeCoercer();
+
+ Instantiator ins = newInstantiator(component, model);
+
+ replay();
+
+ ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, coercer, null);
+
+ ComponentResources resources = cpe.getComponentResources();
+
+ try
+ {
+ resources.getBlock("notFound");
+ unreachable();
+ }
+ catch (BlockNotFoundException ex)
+ {
+ assertTrue(ex
+ .getMessage()
+ .matches(
+ "Template for component .* does not contain a block with identifier 'notFound'\\."));
+ }
+
+ verify();
+ }
+
+ @Test
+ public void block_found()
+ {
+ Page page = newPage();
+ Component component = newComponent();
+ ComponentModel model = newComponentModel();
+ TypeCoercer coercer = newTypeCoercer();
+ Block block = newBlock();
+
+ Instantiator ins = newInstantiator(component, model);
+
+ replay();
+
+ ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, coercer, null);
+
+ ComponentResources resources = cpe.getComponentResources();
+
+ cpe.addBlock("known", block);
+
+ assertSame(resources.getBlock("known"), block);
+
+ verify();
+ }
+
+ @Test
public void parameter_is_bound()
{
Page page = newPage();
@@ -226,11 +284,6 @@
assertSame(cpe.getComponentResources().readParameter("barney", Long.class), boundValue);
verify();
- }
-
- protected final void train_getSupportsInformalParameters(ComponentModel model, boolean supports)
- {
- expect(model.getSupportsInformalParameters()).andReturn(supports);
}
@Test