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 2009/02/13 19:18:53 UTC
svn commit: r744203 [2/3] - in /tapestry/tapestry5/trunk:
tapestry-component-report/src/test/java/org/apache/tapestry/mojo/
tapestry-core/src/main/java/org/apache/tapestry5/annotations/
tapestry-core/src/main/java/org/apache/tapestry5/internal/ tapestr...
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,1015 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.internal.TapestryInternalUtils;
+import org.apache.tapestry5.internal.bindings.LiteralBinding;
+import org.apache.tapestry5.internal.parser.*;
+import org.apache.tapestry5.internal.services.*;
+import org.apache.tapestry5.internal.structure.*;
+import org.apache.tapestry5.ioc.Location;
+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.model.ComponentModel;
+import org.apache.tapestry5.model.EmbeddedComponentModel;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
+import org.apache.tapestry5.services.ComponentClassResolver;
+import org.apache.tapestry5.services.InvalidationListener;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * There's still a lot of room to beef up {@link org.apache.tapestry5.internal.pageload.ComponentAssembler} and {@link
+ * org.apache.tapestry5.internal.pageload.EmbeddedComponentAssembler} to perform more static analysis.
+ */
+public class PageLoaderImpl implements PageLoader, InvalidationListener
+{
+ private static final class Key
+ {
+ private final String className;
+
+ private final Locale locale;
+
+ private Key(String className, Locale locale)
+ {
+ this.className = className;
+ this.locale = locale;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Key key = (Key) o;
+
+ if (!className.equals(key.className))
+ return false;
+
+ return locale.equals(key.locale);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return 31 * className.hashCode() + locale.hashCode();
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("Key[%s, %s]", className, locale);
+ }
+ }
+
+ private static final PageAssemblyAction POP_EMBEDDED_COMPONENT_ACTION = new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.flushComposableRenderCommands();
+
+ pageAssembly.createdElement.pop();
+ pageAssembly.bodyElement.pop();
+ pageAssembly.embeddedAssembler.pop();
+ }
+ };
+
+ private static final RenderCommand END_ELEMENT = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ writer.end();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "End";
+ }
+ };
+
+ private static final PageAssemblyAction END_ELEMENT_ACTION = new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.addRenderCommand(END_ELEMENT);
+ }
+ };
+
+ private static final PageAssemblyAction FLUSH_COMPOSABLE_RENDER_COMMANDS_ACTION = new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.flushComposableRenderCommands();
+ }
+ };
+
+ private final Map<Key, ComponentAssembler> cache = CollectionFactory.newConcurrentMap();
+
+ private final ComponentInstantiatorSource instantiatorSource;
+
+ private final ComponentTemplateSource templateSource;
+
+ private final PageElementFactory elementFactory;
+
+ private final ComponentPageElementResourcesSource resourcesSource;
+
+ private final ComponentClassResolver componentClassResolver;
+
+ private final PersistentFieldManager persistentFieldManager;
+
+ public PageLoaderImpl(ComponentInstantiatorSource instantiatorSource,
+ ComponentTemplateSource templateSource, PageElementFactory elementFactory,
+ ComponentPageElementResourcesSource resourcesSource,
+ ComponentClassResolver componentClassResolver,
+ PersistentFieldManager persistentFieldManager)
+ {
+ this.instantiatorSource = instantiatorSource;
+ this.templateSource = templateSource;
+ this.elementFactory = elementFactory;
+ this.resourcesSource = resourcesSource;
+ this.componentClassResolver = componentClassResolver;
+ this.persistentFieldManager = persistentFieldManager;
+ }
+
+ public void objectWasInvalidated()
+ {
+ cache.clear();
+ }
+
+ public Page loadPage(String logicalPageName, Locale locale)
+ {
+ String pageClassName = componentClassResolver.resolvePageNameToClassName(logicalPageName);
+
+ Page page = new PageImpl(logicalPageName, locale, persistentFieldManager);
+
+ ComponentAssembler assembler = getAssembler(pageClassName, locale);
+
+ ComponentPageElement rootElement = assembler.assembleRootComponent(page);
+
+ page.setRootElement(rootElement);
+
+ // The page is *loaded* before it is attached to the request.
+ // This is to help ensure that no client-specific information leaks
+ // into the page's default state.
+
+ page.loaded();
+
+ return page;
+ }
+
+ private ComponentAssembler getAssembler(String className, Locale locale)
+ {
+ Key key = new Key(className, locale);
+
+ ComponentAssembler result = cache.get(key);
+
+ if (result == null)
+ {
+ result = createAssembler(className, locale);
+ cache.put(key, result);
+ }
+
+ return result;
+ }
+
+ private ComponentAssembler createAssembler(String className, Locale locale)
+ {
+ Instantiator instantiator = instantiatorSource.getInstantiator(className);
+
+ ComponentModel componentModel = instantiator.getModel();
+
+ ComponentTemplate template = templateSource.getTemplate(componentModel, locale);
+
+ ComponentPageElementResources resources = resourcesSource.get(locale);
+
+ ComponentAssembler assembler = new ComponentAssemblerImpl(instantiator, resources);
+
+ // "Program" the assembler by adding actions to it. The actions execute every time a new page instance
+ // is needed.
+
+ programAssembler(assembler, template);
+
+ return assembler;
+ }
+
+ /**
+ * "Programs" the assembler by analyzing the component, its mixins and its embedded components (both in the template
+ * and in the Java class), adding new PageAssemblyActions.
+ */
+ private void programAssembler(ComponentAssembler assembler, ComponentTemplate template)
+ {
+ assembler.validateEmbeddedIds(template);
+
+ // TODO: Optimize for the case of the empty template.
+
+ addImplementationMixins(assembler);
+
+ processTemplate(assembler, template);
+ }
+
+ /**
+ * Add any mixins defined for the component (implementation mixins, rather than instance mixins).
+ */
+
+ private void addImplementationMixins(ComponentAssembler assembler)
+ {
+ final List<String> mixinClassNames = assembler.getModel().getMixinClassNames();
+
+ if (mixinClassNames.isEmpty()) return;
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ ComponentPageElement element = pageAssembly.activeElement.peek();
+
+ for (String className : mixinClassNames)
+ {
+ Instantiator mixinInstantiator = instantiatorSource.getInstantiator(className);
+
+ element.addMixin(InternalUtils.lastTerm(className), mixinInstantiator);
+
+ }
+ }
+ });
+ }
+
+ private void processTemplate(ComponentAssembler assembler, ComponentTemplate template)
+ {
+ if (template.isMissing())
+ {
+ // Pretend the template has a single <t:body> element.
+
+ body(assembler);
+
+ return;
+ }
+
+ TokenStream stream = new TokenStreamImpl(template);
+
+ while (stream.more())
+ {
+ processTemplateToken(assembler, stream);
+ }
+
+ addFlushAction(assembler);
+ }
+
+ private void processTemplateToken(ComponentAssembler assembler, TokenStream stream)
+ {
+ // These tokens can appear at the top level, or at lower levels (this method is invoked
+ // from token-processing loops inside element(), component(), etc.
+
+ switch (stream.peekType())
+ {
+ case TEXT:
+
+ text(assembler, stream.next(TextToken.class));
+ break;
+
+ case EXPANSION:
+ expansion(assembler, stream.next(ExpansionToken.class));
+ break;
+
+ case BODY:
+ stream.next();
+
+ body(assembler);
+ break;
+
+ case START_ELEMENT:
+ // Will consume past matching end token
+ element(assembler, stream);
+ break;
+
+ case START_COMPONENT:
+ // Will consume past matching end token
+ component(assembler, stream);
+ break;
+
+ // ATTRIBUTE and END_ELEMENT can't happen at the top level, they're
+ // handled at a lower level. (inside element(), component(), etc.)
+
+ case COMMENT:
+ comment(assembler, stream.next(CommentToken.class));
+ break;
+
+ case BLOCK:
+ // Will consume past matching end token
+ block(assembler, stream);
+ break;
+
+ case PARAMETER:
+ // Will consume past the matching end token
+ parameter(assembler, stream);
+ break;
+
+ case DTD:
+ dtd(assembler, stream.next(DTDToken.class));
+ break;
+
+ case DEFINE_NAMESPACE_PREFIX:
+
+ defineNamespacePrefix(assembler, stream.next(DefineNamespacePrefixToken.class));
+ break;
+
+ case CDATA:
+ cdata(assembler, stream.next(CDATAToken.class));
+ break;
+
+ default:
+ throw new IllegalStateException("Not yet implemented: " + stream.peekType());
+ }
+ }
+
+ private void cdata(ComponentAssembler assembler, final CDATAToken token)
+ {
+ RenderCommand command = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ writer.cdata(token.getContent());
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("CDATA[%s]", token.getLocation());
+ }
+ };
+
+ addComposableCommand(assembler, command);
+
+ }
+
+ private void defineNamespacePrefix(ComponentAssembler assembler, final DefineNamespacePrefixToken token)
+ {
+ RenderCommand command = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ writer.defineNamespace(token.getNamespaceURI(), token.getNamespacePrefix());
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("DefineNamespace[%s %s]", token.getNamespacePrefix(), token.getNamespaceURI());
+ }
+ };
+
+
+ addComposableCommand(assembler, command);
+ }
+
+ private void dtd(ComponentAssembler assembler, final DTDToken token)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ if (!pageAssembly.checkAndSetFlag("dtd-page-element-added"))
+ {
+ RenderCommand command = new DTDPageElement(token.getName(), token.getPublicId(),
+ token.getSystemId());
+
+ // It doesn't really matter where this ends up in the tree as long as its inside
+ // a portion that always renders.
+
+ pageAssembly.addComposableRenderCommand(command);
+ }
+ }
+ });
+ }
+
+ private void parameter(ComponentAssembler assembler, TokenStream stream)
+ {
+ final ParameterToken token = stream.next(ParameterToken.class);
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ String parameterName = token.getName();
+
+ pageAssembly.flushComposableRenderCommands();
+
+ ComponentPageElement element = pageAssembly.createdElement.peek();
+
+ BlockImpl block = new BlockImpl(token.getLocation(),
+ String.format("Parameter %s of %s",
+ parameterName,
+ element.getCompleteId()));
+
+ Binding binding = new LiteralBinding(token.getLocation(), "block parameter " + parameterName, block);
+
+ EmbeddedComponentAssembler embeddedAssembler = pageAssembly.embeddedAssembler.peek();
+
+ ParameterBinder binder = embeddedAssembler.createBinder(parameterName, binding);
+
+ if (binder == null)
+ {
+ String message = String.format(
+ "Component %s does not include a parameter '%s' (and does not support informal parameters).",
+ element.getCompleteId(),
+ parameterName);
+
+ throw new TapestryException(message, token.getLocation(), null);
+ }
+
+ binder.bind(pageAssembly.activeElement.peek(), element);
+
+ pageAssembly.bodyElement.push(block);
+ }
+ });
+
+ consumeToEndElementAndPopBodyElement(assembler, stream);
+ }
+
+ private void block(ComponentAssembler assembler, TokenStream stream)
+ {
+ final BlockToken token = stream.next(BlockToken.class);
+
+ final String blockId = token.getId();
+
+ // TODO: The description string should be calculatable statically, we just need
+ // to keep yet another stack (of complete component ids).
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ ComponentPageElement element = pageAssembly.activeElement.peek();
+
+ String description = blockId == null
+ ? String.format("Anonymous within %s", element.getCompleteId())
+ : String.format("%s within %s", blockId, element.getCompleteId());
+
+ BlockImpl block = new BlockImpl(token.getLocation(), description);
+
+ if (blockId != null)
+ element.addBlock(blockId, block);
+
+ // Start directing template content into the Block
+ pageAssembly.flushComposableRenderCommands();
+ pageAssembly.bodyElement.push(block);
+ }
+ });
+
+ consumeToEndElementAndPopBodyElement(assembler, stream);
+ }
+
+ private void consumeToEndElementAndPopBodyElement(ComponentAssembler assembler, TokenStream stream)
+ {
+ while (true)
+ {
+ switch (stream.peekType())
+ {
+ case END_ELEMENT:
+
+ stream.next();
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.flushComposableRenderCommands();
+ pageAssembly.bodyElement.pop();
+ }
+ });
+
+ return;
+
+ default:
+ processTemplateToken(assembler, stream);
+ }
+ }
+ }
+
+ private void comment(ComponentAssembler assembler, CommentToken token)
+ {
+ RenderCommand commentElement = new CommentPageElement(token.getComment());
+
+ addComposableCommand(assembler, commentElement);
+ }
+
+ private void component(ComponentAssembler assembler, TokenStream stream)
+ {
+ StartComponentToken token = stream.next(StartComponentToken.class);
+
+ EmbeddedComponentAssembler embeddedAssembler = startComponent(assembler, token);
+
+ while (true)
+ {
+ switch (stream.peekType())
+ {
+ case ATTRIBUTE:
+
+ bindAttributeAsParameter(assembler, embeddedAssembler, stream.next(AttributeToken.class));
+
+ break;
+
+ case END_ELEMENT:
+
+ stream.next();
+
+ assembler.add(POP_EMBEDDED_COMPONENT_ACTION);
+
+ return;
+
+ default:
+ processTemplateToken(assembler, stream);
+ }
+ }
+
+ }
+
+ private void bindAttributeAsParameter(ComponentAssembler assembler, EmbeddedComponentAssembler embeddedAssembler,
+ AttributeToken token)
+ {
+ addParameterBindingAction(assembler, embeddedAssembler, token.getName(), token.getValue(),
+ BindingConstants.LITERAL);
+ }
+
+ private void element(ComponentAssembler assembler, TokenStream stream)
+ {
+ StartElementToken token = stream.next(StartElementToken.class);
+
+ RenderCommand element = new StartElementPageElement(token.getNamespaceURI(), token.getName());
+
+ addComposableCommand(assembler, element);
+
+ while (true)
+ {
+ switch (stream.peekType())
+ {
+ case ATTRIBUTE:
+ attribute(assembler, stream.next(AttributeToken.class));
+ break;
+
+ case END_ELEMENT:
+
+ assembler.add(END_ELEMENT_ACTION);
+
+ stream.next();
+
+ // Pop out a level.
+ return;
+
+ default:
+ processTemplateToken(assembler, stream);
+ }
+ }
+
+ }
+
+ private EmbeddedComponentAssembler startComponent(ComponentAssembler assembler, StartComponentToken token)
+ {
+ String elementName = token.getElementName();
+
+ // Initial guess: the type from the token (but this may be null in many cases).
+ String embeddedType = token.getComponentType();
+
+ // This may be null for an anonymous component.
+ String embeddedId = token.getId();
+
+ String embeddedComponentClassName = null;
+
+ final EmbeddedComponentModel embeddedModel =
+ embeddedId == null
+ ? null
+ : assembler.getModel().getEmbeddedComponentModel(embeddedId);
+
+ if (embeddedId == null)
+ embeddedId = assembler.generateEmbeddedId(embeddedType);
+
+ if (embeddedModel != null)
+ {
+ String modelType = embeddedModel.getComponentType();
+
+ if (InternalUtils.isNonBlank(modelType) && embeddedType != null)
+ {
+ String message = String.format(
+ "Embedded component '%s' provides a type attribute in the template ('%s') " +
+ "as well as in the component class ('%s'). " +
+ "You should not provide a type attribute in the template when defining an embedded component " +
+ "within the component class.",
+ embeddedId, embeddedType, modelType
+ );
+
+ throw new TapestryException(message, token, null);
+ }
+
+ embeddedType = modelType;
+ embeddedComponentClassName = embeddedModel.getComponentClassName();
+ }
+
+ String componentClassName = embeddedComponentClassName;
+
+ // This awkwardness is making me think that the page loader should resolve the component
+ // type before invoking this method (we would then remove the componentType parameter).
+
+ if (InternalUtils.isNonBlank(embeddedType))
+ {
+ // The type actually overrides the specified class name. The class name is defined
+ // by the type of the field. In many scenarios, the field type is a common
+ // interface,
+ // and the type is used to determine the concrete class to instantiate.
+
+ try
+ {
+ componentClassName = componentClassResolver.resolveComponentTypeToClassName(embeddedType);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new TapestryException(ex.getMessage(), token, ex);
+ }
+ }
+
+
+ // OK, now we can record an action to get it instantiated.
+
+ EmbeddedComponentAssembler embeddedAssembler = new EmbeddedComponentAssemblerImpl(instantiatorSource,
+ elementFactory,
+ componentClassName,
+ token.getLocation());
+
+ addActionForEmbeddedComponent(assembler, embeddedAssembler, embeddedId, elementName, componentClassName,
+ token.getLocation());
+
+
+ addMixinActions(assembler, embeddedAssembler, embeddedModel, token.getMixins());
+
+ bindParametersFromEmbeddedModel(assembler, embeddedAssembler, embeddedModel);
+
+
+ if (embeddedModel != null && embeddedModel.getInheritInformalParameters())
+ {
+ // Another two-step: The first "captures" the container and embedded component. The second
+ // occurs at the end of the page setup.
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ final ComponentPageElement container = pageAssembly.activeElement.peek();
+ final ComponentPageElement embedded = pageAssembly.createdElement.peek();
+
+ pageAssembly.deferred.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ copyInformalParameters(container, embedded);
+ }
+ });
+ }
+ });
+
+ }
+
+ return embeddedAssembler;
+
+ }
+
+ private void copyInformalParameters(ComponentPageElement container, ComponentPageElement embedded)
+ {
+ // TODO: Much more, this is an area where we can make things a bit more efficient by tracking
+ // what has and hasn't been bound in the EmbeddedComponentAssembler (and identifying what is
+ // and isn't informal).
+
+ ComponentModel model = embedded.getComponentResources().getComponentModel();
+
+ Map<String, Binding> informals = container.getInformalParameterBindings();
+
+ for (String name : informals.keySet())
+ {
+ if (model.getParameterModel(name) != null) continue;
+
+ Binding binding = informals.get(name);
+
+ embedded.bindParameter(name, binding);
+ }
+ }
+
+ private void bindParametersFromEmbeddedModel(ComponentAssembler assembler,
+ EmbeddedComponentAssembler embeddedAssembler,
+ EmbeddedComponentModel embeddedModel)
+ {
+ if (embeddedModel == null) return;
+
+ for (String name : embeddedModel.getParameterNames())
+ {
+ String parameterValue = embeddedModel.getParameterValue(name);
+
+ addParameterBindingAction(assembler, embeddedAssembler, name, parameterValue, BindingConstants.PROP);
+ }
+ }
+
+ private void addParameterBindingAction(ComponentAssembler assembler,
+ EmbeddedComponentAssembler embeddedAssembler,
+ String parameterName,
+ String parameterValue,
+ String defaultBindingPrefix)
+ {
+ if (embeddedAssembler.isBound(parameterName)) return;
+
+ embeddedAssembler.setBound(parameterName);
+
+ if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX))
+ {
+
+ String containerParameterName = parameterValue.substring(InternalConstants.INHERIT_BINDING_PREFIX.length());
+
+ addInhertedBindingAction(assembler, parameterName, containerParameterName);
+ return;
+ }
+
+
+ final ParameterBinder binder = embeddedAssembler.createBinder(parameterName, parameterValue,
+ defaultBindingPrefix);
+
+ // Null meaning an informal parameter and the component (and mixins) doesn't support informals.
+
+ if (binder != null)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ binder.bind(pageAssembly.activeElement.peek(), pageAssembly.createdElement.peek());
+ }
+ });
+ }
+ }
+
+ /**
+ * Adds a deferred action to the PageAssembly, to handle connecting the embedded components' parameter to the
+ * container component's parameter once everything else has been built.
+ *
+ * @param assembler
+ * @param parameterName
+ * @param containerParameterName
+ */
+ private void addInhertedBindingAction(ComponentAssembler assembler,
+ final String parameterName,
+ final String containerParameterName)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ // At the time this action executes, we'll be able to capture the containing and embedded
+ // component. We can then defer the connection logic until after all other construction.
+
+ final ComponentPageElement container = pageAssembly.activeElement.peek();
+ final ComponentPageElement embedded = pageAssembly.createdElement.peek();
+
+ pageAssembly.deferred.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ connectInheritedParameter(container, embedded, parameterName,
+ containerParameterName);
+ }
+ });
+ }
+ });
+ }
+
+ private void connectInheritedParameter(ComponentPageElement container, ComponentPageElement embedded,
+ String parameterName,
+ String containerParameterName)
+ {
+ // TODO: This assumes that the two parameters are both on the core component and not on
+ // a mixin.
+
+ Binding containerBinding = container.getBinding(containerParameterName);
+
+ if (containerBinding == null) return;
+
+ String description = String.format("InheritedBinding[parameter %s %s(inherited from %s of %s)]",
+ parameterName,
+ embedded.getCompleteId(),
+ containerParameterName,
+ container.getCompleteId());
+
+ // This helps with debugging, and re-orients any thrown exceptions
+ // to the location of the inherited binding, rather than the container component's
+ // binding.
+
+ Binding inherited = new InheritedBinding(description, containerBinding, embedded.getLocation());
+
+ embedded.bindParameter(parameterName, inherited);
+ }
+
+ private ComponentModel getModel(String componentClassName)
+ {
+ return instantiatorSource.getInstantiator(componentClassName).getModel();
+ }
+
+ private void addMixinActions(ComponentAssembler assembler,
+ EmbeddedComponentAssembler embeddedAssembler, EmbeddedComponentModel model,
+ String mixins
+ )
+ {
+ if (model != null)
+ {
+ addMixinActionsFromEmbeddedModel(assembler, embeddedAssembler, model);
+ }
+
+ List<String> classNames = CollectionFactory.newList();
+
+ for (String typeName : TapestryInternalUtils.splitAtCommas(mixins))
+ {
+ classNames.add(componentClassResolver.resolveMixinTypeToClassName(typeName));
+ }
+
+ addMixinActionsForClassNames(assembler, embeddedAssembler, classNames);
+ }
+
+ private void addMixinActionsFromEmbeddedModel(ComponentAssembler assembler,
+ EmbeddedComponentAssembler embeddedAssembler,
+ EmbeddedComponentModel model
+ )
+ {
+ addMixinActionsForClassNames(assembler, embeddedAssembler, model.getMixinClassNames());
+ }
+
+ private void addMixinActionsForClassNames(ComponentAssembler assembler,
+ EmbeddedComponentAssembler embeddedAssembler,
+ final List<String> classNames
+ )
+ {
+ for (String className : classNames)
+ {
+ embeddedAssembler.addInstanceMixin(getModel(className));
+ }
+
+ if (!classNames.isEmpty())
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ ComponentPageElement embedded = pageAssembly.createdElement.peek();
+
+ for (String className : classNames)
+ {
+ Instantiator instantiator = instantiatorSource.getInstantiator(className);
+
+ embedded.addMixin(InternalUtils.lastTerm(className), instantiator);
+ }
+ }
+ });
+ }
+ }
+
+ private void addActionForEmbeddedComponent(ComponentAssembler assembler,
+ final EmbeddedComponentAssembler embeddedAssembler,
+ final String embeddedId,
+ final String elementName,
+ final String componentClassName,
+ final Location location)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.flushComposableRenderCommands();
+
+ Locale locale = pageAssembly.page.getLocale();
+
+ ComponentAssembler assemblerForSubcomponent = getAssembler(componentClassName, locale);
+
+ // Remeber: this pushes onto to the createdElement stack, but does not pop it.
+
+ assemblerForSubcomponent.assembleEmbeddedComponent(pageAssembly, embeddedId, elementName, location);
+
+ // ... which is why we can find it via peek() here. And it's our responsibility
+ // to clean it up.
+
+ ComponentPageElement embeddedElement = pageAssembly.createdElement.peek();
+
+ // Add the new element to the template of its container.
+
+ pageAssembly.addRenderCommand(embeddedElement);
+
+ // And redirect any futher content from this component's template to go into
+ // the body of the embedded element.
+
+ pageAssembly.bodyElement.push(embeddedElement);
+ pageAssembly.embeddedAssembler.push(embeddedAssembler);
+
+ // The means we need to pop the createdElement, bodyElement and embeddedAssembler stacks
+ // when done with this sub-component, which is what POP_EMBEDDED_COMPONENT_ACTION does.
+ }
+ });
+ }
+
+
+ private void attribute(ComponentAssembler assembler, final AttributeToken token)
+ {
+ String value = token.getValue();
+
+ // No expansion makes this easier, more efficient.
+ if (value.indexOf(InternalConstants.EXPANSION_START) < 0)
+ {
+ RenderCommand command = new RenderAttribute(token);
+
+ addComposableCommand(assembler, command);
+
+ return;
+ }
+
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ InternalComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
+
+ RenderCommand command = elementFactory.newAttributeElement(resources, token);
+
+ // Still composable, BTW.
+
+ pageAssembly.addRenderCommand(command);
+ }
+ });
+ }
+
+ private void body(ComponentAssembler assembler)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ ComponentPageElement element = pageAssembly.activeElement.peek();
+
+ pageAssembly.addRenderCommand(new RenderBodyElement(element));
+ }
+ });
+ }
+
+ private void expansion(ComponentAssembler assembler, final ExpansionToken token)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ ComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
+
+ // TODO: Add composably
+
+ RenderCommand command = elementFactory.newExpansionElement(resources, token);
+
+ pageAssembly.addRenderCommand(command);
+ }
+ });
+ }
+
+ private void text(ComponentAssembler assembler, TextToken textToken)
+ {
+ addComposableCommand(assembler, new TextPageElement(textToken.getText()));
+ }
+
+ private void addComposableCommand(ComponentAssembler assembler, final RenderCommand command)
+ {
+ assembler.add(new PageAssemblyAction()
+ {
+ public void execute(PageAssembly pageAssembly)
+ {
+ pageAssembly.addComposableRenderCommand(command);
+ }
+ });
+ }
+
+ private void addFlushAction(ComponentAssembler assembler)
+ {
+ assembler.add(FLUSH_COMPOSABLE_RENDER_COMMANDS_ACTION);
+ }
+
+}
+
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ParameterBinder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ParameterBinder.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ParameterBinder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ParameterBinder.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,25 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
+
+/**
+ * Binds a parameter.
+ */
+interface ParameterBinder
+{
+ void bind(ComponentPageElement container, ComponentPageElement embedded);
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,42 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.internal.parser.AttributeToken;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
+
+class RenderAttribute implements RenderCommand
+{
+ private final AttributeToken token;
+
+ public RenderAttribute(AttributeToken token)
+ {
+ this.token = token;
+ }
+
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ writer.attributeNS(token.getNamespaceURI(), token.getName(), token.getValue());
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("AttributeNS[%s %s \"%s\"]",
+ token.getNamespaceURI(), token.getName(), token.getValue());
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderBodyElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderBodyElement.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderBodyElement.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderBodyElement.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,41 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
+
+class RenderBodyElement implements RenderCommand
+{
+ private final ComponentPageElement component;
+
+ public RenderBodyElement(ComponentPageElement component)
+ {
+ this.component = component;
+ }
+
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ component.enqueueBeforeRenderBody(queue);
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("RenderBody[%s]", component.getNestedId());
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStream.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStream.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStream.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStream.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,44 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.internal.parser.TemplateToken;
+import org.apache.tapestry5.internal.parser.TokenType;
+
+/**
+ * Provides cursor index into a {@link org.apache.tapestry5.internal.parser.ComponentTemplate}.
+ */
+interface TokenStream
+{
+ /**
+ * Returns true if there are more tokens available.
+ */
+ boolean more();
+
+ /**
+ * Peeks at the type of the next token.
+ */
+ TokenType peekType();
+
+ /**
+ * Returns the next token and casts it to the indicated type.
+ */
+ <T extends TemplateToken> T next(Class<T> type);
+
+ /**
+ * Returns the next token.
+ */
+ TemplateToken next();
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStreamImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStreamImpl.java?rev=744203&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStreamImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStreamImpl.java Fri Feb 13 18:18:49 2009
@@ -0,0 +1,63 @@
+// Copyright 2009 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.tapestry5.internal.pageload;
+
+import org.apache.tapestry5.internal.parser.ComponentTemplate;
+import org.apache.tapestry5.internal.parser.TemplateToken;
+import org.apache.tapestry5.internal.parser.TokenType;
+
+import java.util.List;
+
+class TokenStreamImpl implements TokenStream
+{
+ private final List<TemplateToken> tokens;
+
+ private int index = 0;
+
+ public TokenStreamImpl(ComponentTemplate template)
+ {
+ tokens = template.getTokens();
+ }
+
+ public boolean more()
+ {
+ return index < tokens.size();
+ }
+
+ public TokenType peekType()
+ {
+ checkMore();
+
+ return tokens.get(index).getTokenType();
+ }
+
+ private void checkMore()
+ {
+ if (!more())
+ throw new IllegalStateException("No more template tokens.");
+ }
+
+ public <T extends TemplateToken> T next(Class<T> type)
+ {
+ return type.cast(next());
+ }
+
+ public TemplateToken next()
+ {
+ checkMore();
+
+ return tokens.get(index++);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSource.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSource.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -41,7 +41,7 @@
* @param classname FQCN to find (and perhaps transform and load)
* @return an object which can instantiate an instance of the component
*/
- Instantiator findInstantiator(String classname);
+ Instantiator getInstantiator(String classname);
/**
* Adds a controlled package. Only classes within controlled packages are subject to transformation.
@@ -51,7 +51,7 @@
void addPackage(String packageName);
/**
- * Checks to see if a fully qualfied class name exists.
+ * Checks to see if a fully qualfied class name exists. This method appears to exist only for testing.
*
* @param className name of class to check
* @return true if the class exists (there's a ".class" file), false otherwise
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java Fri Feb 13 18:18:49 2009
@@ -101,7 +101,8 @@
}
public ComponentInstantiatorSourceImpl(Logger logger, ClassLoader parent, ComponentClassTransformer transformer,
- InternalRequestGlobals internalRequestGlobals, ClasspathURLConverter classpathURLConverter)
+ InternalRequestGlobals internalRequestGlobals,
+ ClasspathURLConverter classpathURLConverter)
{
this.parent = parent;
this.transformer = transformer;
@@ -262,7 +263,7 @@
{
}
- public synchronized Instantiator findInstantiator(String className)
+ public synchronized Instantiator getInstantiator(String className)
{
Instantiator result = classNameToInstantiator.get(className);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImpl.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -28,6 +28,7 @@
import org.apache.tapestry5.services.InvalidationEventHub;
import org.apache.tapestry5.services.UpdateListener;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -60,7 +61,7 @@
{
public Map<String, Location> getComponentIds()
{
- return null;
+ return Collections.emptyMap();
}
public Resource getResource()
@@ -70,7 +71,7 @@
public List<TemplateToken> getTokens()
{
- return null;
+ return Collections.emptyList();
}
public boolean isMissing()
@@ -79,7 +80,8 @@
}
};
- public ComponentTemplateSourceImpl(TemplateParser parser, PageTemplateLocator locator, ClasspathURLConverter classpathURLConverter)
+ public ComponentTemplateSourceImpl(TemplateParser parser, PageTemplateLocator locator,
+ ClasspathURLConverter classpathURLConverter)
{
this(parser, locator, new URLChangeTracker(classpathURLConverter));
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java Fri Feb 13 18:18:49 2009
@@ -15,6 +15,7 @@
package org.apache.tapestry5.internal.services;
import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.internal.pageload.PageLoaderImpl;
import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSource;
import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSourceImpl;
import org.apache.tapestry5.ioc.ObjectLocator;
@@ -22,11 +23,7 @@
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.*;
import org.apache.tapestry5.ioc.internal.services.CtClassSource;
-import org.apache.tapestry5.ioc.services.Builtin;
-import org.apache.tapestry5.ioc.services.ClassFactory;
-import org.apache.tapestry5.ioc.services.ClasspathURLConverter;
-import org.apache.tapestry5.ioc.services.PerthreadManager;
-import org.apache.tapestry5.ioc.services.PropertyShadowBuilder;
+import org.apache.tapestry5.ioc.services.*;
import org.apache.tapestry5.services.*;
import org.slf4j.Logger;
@@ -43,8 +40,7 @@
private final RequestGlobals requestGlobals;
- public InternalModule(UpdateListenerHub updateListenerHub, ComponentInstantiatorSource componentInstantiatorSource,
- RequestGlobals requestGlobals)
+ public InternalModule(UpdateListenerHub updateListenerHub, RequestGlobals requestGlobals)
{
this.updateListenerHub = updateListenerHub;
this.requestGlobals = requestGlobals;
@@ -74,7 +70,6 @@
binder.bind(InternalRequestGlobals.class, InternalRequestGlobalsImpl.class);
binder.bind(EndOfRequestEventHub.class);
binder.bind(PageActivationContextCollector.class);
- binder.bind(PageLoader.class, PageLoaderImpl.class);
binder.bind(ResponseCompressionAnalyzer.class, ResponseCompressionAnalyzerImpl.class);
binder.bind(LinkFactory.class, LinkFactoryImpl.class);
}
@@ -119,7 +114,7 @@
@Inject
@Symbol(SymbolConstants.APPLICATION_CATALOG)
String appCatalog,
-
+
ClasspathURLConverter classpathURLConverter)
{
ComponentMessagesSourceImpl service = new ComponentMessagesSourceImpl(contextAssetFactory
@@ -137,7 +132,7 @@
Logger logger,
InternalRequestGlobals internalRequestGlobals,
-
+
ClasspathURLConverter classpathURLConverter)
{
ComponentInstantiatorSourceImpl source = new ComponentInstantiatorSourceImpl(logger, classFactory
@@ -156,6 +151,27 @@
return transformer;
}
+ public PageLoader buildPageLoader(@Autobuild PageLoaderImpl service,
+
+ @ComponentClasses
+ InvalidationEventHub classesHub,
+
+ @ComponentTemplates
+ InvalidationEventHub templatesHub,
+
+ @ComponentMessages
+ InvalidationEventHub messagesHub)
+ {
+ // TODO: We could combine these three using chain-of-command.
+
+ classesHub.addInvalidationListener(service);
+ templatesHub.addInvalidationListener(service);
+ messagesHub.addInvalidationListener(service);
+
+ return service;
+ }
+
+
public PagePool buildPagePool(@Autobuild PagePoolImpl service,
@ComponentClasses
@@ -244,4 +260,5 @@
{
return builder.build(componentInstantiatorSource, "classSource", CtClassSource.class);
}
+
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactory.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactory.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -25,8 +25,6 @@
import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.services.BindingSource;
-import java.util.Locale;
-
/**
* Used by the {@link org.apache.tapestry5.internal.services.PageLoader} to create page elements
*/
@@ -69,10 +67,9 @@
*
* @param page the page that will contain the root component
* @param className the fully qualified class name of the root component
- * @param locale the locale for the page
* @return the root page element
*/
- ComponentPageElement newRootComponentElement(Page page, String className, Locale locale);
+ ComponentPageElement newRootComponentElement(Page page, String className);
/**
* Adds a mixin to the element, resolving the mixin type to a mixin class.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java Fri Feb 13 18:18:49 2009
@@ -18,6 +18,7 @@
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.parser.AttributeToken;
import org.apache.tapestry5.internal.parser.ExpansionToken;
import org.apache.tapestry5.internal.structure.*;
@@ -33,7 +34,6 @@
import org.apache.tapestry5.services.ComponentClassResolver;
import java.util.List;
-import java.util.Locale;
public class PageElementFactoryImpl implements PageElementFactory
{
@@ -47,8 +47,6 @@
private final ComponentPageElementResourcesSource componentPageElementResourcesSource;
- private static final String EXPANSION_START = "${";
-
private static class LiteralStringProvider implements StringProvider
{
private final String string;
@@ -106,7 +104,7 @@
while (true)
{
- int expansionx = expression.indexOf(EXPANSION_START, startx);
+ int expansionx = expression.indexOf(InternalConstants.EXPANSION_START, startx);
// No more expansions, add in the rest of the string as a literal.
@@ -204,8 +202,7 @@
try
{
- finalClassName = componentClassResolver
- .resolveComponentTypeToClassName(componentType);
+ finalClassName = componentClassResolver.resolveComponentTypeToClassName(componentType);
}
catch (IllegalArgumentException ex)
{
@@ -213,8 +210,7 @@
}
}
- Instantiator instantiator = componentInstantiatorSource
- .findInstantiator(finalClassName);
+ Instantiator instantiator = componentInstantiatorSource.getInstantiator(finalClassName);
// This is actually a good place to check for recursive templates, here where we've
// resolved
@@ -257,11 +253,12 @@
}
}
- public ComponentPageElement newRootComponentElement(Page page, String componentType, Locale locale)
+ public ComponentPageElement newRootComponentElement(Page page, String componentType)
{
- Instantiator instantiator = componentInstantiatorSource.findInstantiator(componentType);
+ Instantiator instantiator = componentInstantiatorSource.getInstantiator(componentType);
- ComponentPageElementResources componentPageElementResources = componentPageElementResourcesSource.get(locale);
+ ComponentPageElementResources componentPageElementResources = componentPageElementResourcesSource.get(
+ page.getLocale());
ComponentPageElement result = new ComponentPageElementImpl(page, instantiator, componentPageElementResources);
@@ -288,9 +285,11 @@
public void addMixinByClassName(ComponentPageElement component, String mixinClassName)
{
- Instantiator mixinInstantiator = componentInstantiatorSource.findInstantiator(mixinClassName);
+ Instantiator mixinInstantiator = componentInstantiatorSource.getInstantiator(mixinClassName);
+
+ String mixinId = InternalUtils.lastTerm(mixinClassName);
- component.addMixin(mixinInstantiator);
+ component.addMixin(mixinId, mixinInstantiator);
}
public Binding newBinding(String parameterName, ComponentResources loadingComponentResources,
@@ -298,7 +297,7 @@
String expression, Location location)
{
- if (expression.contains(EXPANSION_START))
+ if (expression.contains(InternalConstants.EXPANSION_START))
{
StringProvider provider = parseAttributeExpansionExpression(expression, loadingComponentResources,
location);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElement.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElement.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElement.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -14,6 +14,7 @@
package org.apache.tapestry5.internal.structure;
+import org.apache.tapestry5.Binding;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.ComponentResourcesCommon;
@@ -70,9 +71,18 @@
/**
* Adds a mixin.
*
+ * @param mixinId a unique id for the mixin, the last term of the mixin's class name
* @param instantiator used to instantiate an instance of the mixin
*/
- void addMixin(Instantiator instantiator);
+ void addMixin(String mixinId, Instantiator instantiator);
+
+ /**
+ * @param mixinId id of previously added mixin
+ * @param parameterName simple (unqualified) name of parameter
+ * @param binding binding for parameter
+ * @since 5.1.0.0
+ */
+ void bindMixinParameter(String mixinId, String parameterName, Binding binding);
/**
* Retrieves a component page element by its id. The search is caseless.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java Fri Feb 13 18:18:49 2009
@@ -18,7 +18,6 @@
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.internal.InternalComponentResources;
-import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.internal.services.ComponentEventImpl;
import org.apache.tapestry5.internal.services.EventImpl;
import org.apache.tapestry5.internal.services.Instantiator;
@@ -663,12 +662,14 @@
if (existing != null)
throw new TapestryException(StructureMessages.duplicateChildComponent(this, childId), child,
- new TapestryException(StructureMessages.originalChildComponent(this, childId, existing.getLocation()), existing, null));
+ new TapestryException(StructureMessages.originalChildComponent(this, childId,
+ existing.getLocation()),
+ existing, null));
children.put(childId, child);
}
- public void addMixin(Instantiator instantiator)
+ public void addMixin(String mixinId, Instantiator instantiator)
{
if (mixinIdToComponentResources == null)
{
@@ -676,10 +677,8 @@
components = CollectionFactory.newList();
}
- String mixinClassName = instantiator.getModel().getComponentClassName();
- String mixinName = TapestryInternalUtils.lastTerm(mixinClassName);
- String mixinExtension = "$" + mixinName.toLowerCase();
+ String mixinExtension = "$" + mixinId.toLowerCase();
InternalComponentResourcesImpl resources = new InternalComponentResourcesImpl(page, this, coreResources,
elementResources,
@@ -687,13 +686,31 @@
nestedId + mixinExtension,
instantiator);
- // TODO: Check for name collision?
+ if (mixinIdToComponentResources.containsKey(mixinId))
+ throw new RuntimeException(
+ String.format("Component %s already has a '%s' mixin.", getCompleteId(), mixinId));
- mixinIdToComponentResources.put(mixinName, resources);
+ mixinIdToComponentResources.put(mixinId, resources);
components.add(resources.getComponent());
}
+ public void bindMixinParameter(String mixinId, String parameterName, Binding binding)
+ {
+ InternalComponentResources mixinResources = InternalUtils.get(mixinIdToComponentResources, mixinId);
+
+ if (mixinResources == null)
+ throw new TapestryException(
+ StructureMessages.missingMixinForParameter(completeId, mixinId, parameterName), binding, null);
+
+ mixinResources.bindParameter(parameterName, binding);
+ }
+
+ public Binding getBinding(String parameterName)
+ {
+ return coreResources.getBinding(parameterName);
+ }
+
public void bindParameter(String parameterName, Binding binding)
{
// Maybe should use colon here? Depends on what works best in the template,
@@ -702,15 +719,11 @@
if (dotx > 0)
{
- String mixinName = parameterName.substring(0, dotx);
- InternalComponentResources mixinResources = InternalUtils.get(mixinIdToComponentResources, mixinName);
-
- if (mixinResources == null) throw new TapestryException(
- StructureMessages.missingMixinForParameter(completeId, mixinName, parameterName), binding, null);
-
+ String mixinId = parameterName.substring(0, dotx);
String simpleName = parameterName.substring(dotx + 1);
- mixinResources.bindParameter(simpleName, binding);
+ bindMixinParameter(mixinId, simpleName, binding);
+
return;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java Fri Feb 13 18:18:49 2009
@@ -304,7 +304,7 @@
return getParameterAccess(parameterName).getBoundType();
}
- private Binding getBinding(String parameterName)
+ public Binding getBinding(String parameterName)
{
return InternalUtils.get(bindings, parameterName);
}
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=744203&r1=744202&r2=744203&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 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -21,6 +21,7 @@
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.internal.services.StringLocation;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.MutableComponentModel;
@@ -66,6 +67,14 @@
addParameters(embedded, annotation.parameters());
+
+ String names = annotation.publishParameters();
+ if (InternalUtils.isNonBlank(names))
+ {
+ embedded.setPublishedParameters(CollectionFactory.newList(TapestryInternalUtils.splitAtCommas(names)));
+ }
+
+
transformation.makeReadOnly(fieldName);
String body = String.format("%s = (%s) %s.getEmbeddedComponent(\"%s\");", fieldName, type,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/EmbeddedComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/EmbeddedComponentModel.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/EmbeddedComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/EmbeddedComponentModel.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2009 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.
@@ -60,4 +60,13 @@
* If true, then the component should inherit informal parameters from its container.
*/
boolean getInheritInformalParameters();
+
+ /**
+ * Returns the list of published parameters of this component (usually an empty list).
+ *
+ * @return list of parameter names to publish
+ * @see org.apache.tapestry5.annotations.Component#publishParameters()
+ * @since 5.1.0.0
+ */
+ List<String> getPublishedParameters();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableEmbeddedComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableEmbeddedComponentModel.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableEmbeddedComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableEmbeddedComponentModel.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2009 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.
@@ -14,6 +14,8 @@
package org.apache.tapestry5.model;
+import java.util.List;
+
/**
* A mutable version of {@link org.apache.tapestry5.model.EmbeddedComponentModel} that allows the parameters to be
* incrementally stored.
@@ -26,4 +28,13 @@
* Adds a mixin to the component in terms of its fully qualified class name.
*/
void addMixin(String mixinClassName);
+
+ /**
+ * Sets the list of published parameters for this embedded component.
+ *
+ * @param parameterNames list of names
+ * @see org.apache.tapestry5.annotations.Component#publishParameters()
+ * @since 5.1.0.0
+ */
+ void setPublishedParameters(List<String> parameterNames);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/MarkupUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/MarkupUtilsTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/MarkupUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/MarkupUtilsTest.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 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.
@@ -29,7 +29,7 @@
assertEquals(MarkupUtils.quote(input), expected);
}
- @DataProvider(name = "string_quoting_input")
+ @DataProvider
public Object[][] string_quoting_input()
{
return new Object[][]
@@ -55,7 +55,7 @@
assertEquals(MarkupUtils.join(list), expected);
}
- @DataProvider(name = "join_input")
+ @DataProvider
public Object[][] join_input()
{
return new Object[][]
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/DTDTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/DTDTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/DTDTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/DTDTest.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2009 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.
@@ -28,7 +28,7 @@
private static final String STRICT = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
- @DataProvider(name = "dtd_page_provider")
+ @DataProvider
public Object[][] dtd_page_provider()
{
return new Object[][]
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/TapestryInternalUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/TapestryInternalUtilsTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/TapestryInternalUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/TapestryInternalUtilsTest.java Fri Feb 13 18:18:49 2009
@@ -57,13 +57,13 @@
}
- @Test(dataProvider = "to_user_presentable")
+ @Test(dataProvider = "to_user_presentable_data")
public void to_user_presentable(String input, String expected)
{
assertEquals(TapestryInternalUtils.toUserPresentable(input), expected);
}
- @DataProvider(name = "to_user_presentable")
+ @DataProvider
public Object[][] to_user_presentable_data()
{
return new Object[][] { { "hello", "Hello" }, { "userId", "User Id" }, { "useHTML", "Use HTML" },
@@ -372,14 +372,27 @@
assertEquals(TapestryInternalUtils.toClassAttributeValue(classes), "fred barney wilma");
}
- @Test
- public void split_at_commas()
+ @DataProvider
+ public Object[][] split_at_commas_data()
+ {
+ return new Object[][]
+ {
+ { "foo", new String[] { "foo" } },
+ { "foo, bar", new String[] { "foo", "bar" } },
+ { " foo, \nbar\t\t", new String[] { "foo", "bar" } },
+ { null, new String[0] }
+ };
+ }
+
+
+ @Test(dataProvider = "split_at_commas_data")
+ public void split_at_commas(String input, String[] output)
{
- assertArraysEqual(TapestryInternalUtils.splitAtCommas("foo"), "foo");
- assertArraysEqual(TapestryInternalUtils.splitAtCommas("foo , bar"), "foo", "bar");
+ assertArraysEqual(TapestryInternalUtils.splitAtCommas(input), output);
+
}
- @DataProvider(name = "to_base64_data")
+ @DataProvider
public Object[][] to_base64_data()
{
return new Object[][] {
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/BeanModelUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/BeanModelUtilsTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/BeanModelUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/BeanModelUtilsTest.java Fri Feb 13 18:18:49 2009
@@ -17,9 +17,9 @@
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.beaneditor.PropertyModel;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.easymock.EasyMock;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import org.easymock.EasyMock;
public class BeanModelUtilsTest extends InternalBaseTestCase
{
@@ -35,7 +35,7 @@
{ propertyNames, expected };
}
- @DataProvider(name = "split_inputs")
+ @DataProvider
public Object[][] split_inputs()
{
return new Object[][]
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/PropBindingFactoryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/PropBindingFactoryTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/PropBindingFactoryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/PropBindingFactoryTest.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 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.
@@ -573,33 +573,33 @@
verify();
}
- @DataProvider(name = "values")
+ @DataProvider
public Object[][] values()
{
return new Object[][]
{
- {"true", true,},
- {"True", true,},
- {" true ", true,},
- {"false", false},
- {"null", null},
- {"3", 3l},
- {" 37 ", 37l},
- {" -227", -227l},
- {" 5.", 5d},
- {" -100.", -100d},
- {" -0.0 ", -0d},
- {"+50", 50l},
- {"+7..+20", new IntegerRange(7, 20)},
- {"+5.5", 5.5d},
- {"1..10", new IntegerRange(1, 10)},
- {" -20 .. -30 ", new IntegerRange(-20, -30)},
- {"0.", 0d},
- {" 227.75", 227.75d},
- {" -10123.67", -10123.67d},
- {"'Hello World'", "Hello World"},
- {" 'Whitespace Ignored' ", "Whitespace Ignored"},
- {" ' Inside ' ", " Inside "}
+ { "true", true, },
+ { "True", true, },
+ { " true ", true, },
+ { "false", false },
+ { "null", null },
+ { "3", 3l },
+ { " 37 ", 37l },
+ { " -227", -227l },
+ { " 5.", 5d },
+ { " -100.", -100d },
+ { " -0.0 ", -0d },
+ { "+50", 50l },
+ { "+7..+20", new IntegerRange(7, 20) },
+ { "+5.5", 5.5d },
+ { "1..10", new IntegerRange(1, 10) },
+ { " -20 .. -30 ", new IntegerRange(-20, -30) },
+ { "0.", 0d },
+ { " 227.75", 227.75d },
+ { " -10123.67", -10123.67d },
+ { "'Hello World'", "Hello World" },
+ { " 'Whitespace Ignored' ", "Whitespace Ignored" },
+ { " ' Inside ' ", " Inside " }
};
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommandTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommandTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommandTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommandTest.java Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 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.
@@ -23,7 +23,7 @@
public class CompositeRenderCommandTest extends InternalBaseTestCase
{
- @DataProvider(name = "nyi")
+ @DataProvider
public Object[][] nyi_data()
{
RenderCommand push = new RenderCommand()
@@ -64,7 +64,7 @@
};
}
- @Test(dataProvider = "nyi")
+ @Test(dataProvider = "nyi_data")
public void render_queue_commands_nyi
(RenderCommand
rc)
@@ -74,7 +74,7 @@
try
{
- new CompositeRenderCommand(new RenderCommand[] {rc}).render(writer, queue);
+ new CompositeRenderCommand(new RenderCommand[] { rc }).render(writer, queue);
unreachable();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java Fri Feb 13 18:18:49 2009
@@ -55,7 +55,7 @@
verify();
}
- @DataProvider(name = "to_client_url_data")
+ @DataProvider
public Object[][] to_client_url_data()
{
return new Object[][] { { "foo/bar/Baz.txt", "classpath/1.0/foo/bar/Baz.txt" },
@@ -73,7 +73,7 @@
assertEquals(manager.toResourcePath(clientURL), expectedResourcePath);
}
- @DataProvider(name = "to_resource_path_data")
+ @DataProvider
public Object[][] to_resource_path_data()
{
Object[][] data = to_client_url_data();