}
private EmbeddedComponentAssembler startComponent(AssemblerContext context)
{
StartComponentToken token = context.next(StartComponentToken.class);
ComponentAssembler assembler = context.assembler;
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) { throw new TapestryException(
PageloadMessages.redundantEmbeddedComponentTypes(embeddedId, embeddedType, modelType), 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 (RuntimeException ex)
{
throw new TapestryException(ex.getMessage(), token, ex);
}
}
// OK, now we can record an action to get it instantiated.
EmbeddedComponentAssembler embeddedAssembler = assembler.createEmbeddedAssembler(embeddedId,
componentClassName, embeddedModel, token.getMixins(), token.getLocation());
addActionForEmbeddedComponent(context, embeddedAssembler, embeddedId, elementName, componentClassName);
addParameterBindingActions(context, embeddedAssembler, embeddedModel);