private void addMixinsToComponent( ComponentPageElement component, EmbeddedComponentModel model, String mixins) { if (model != null) { for (String mixinClassName : model.getMixinClassNames()) pageElementFactory.addMixinByClassName(component, mixinClassName); } if (mixins != null) { for (String type : COMMA_PATTERN.split(mixins)) pageElementFactory.addMixinByTypeName(component, type); } }
private void loadRootComponent(String className) { ComponentPageElement rootComponent = pageElementFactory.newRootComponentElement(page, className, locale); page.setRootElement(rootComponent); componentQueue.push(rootComponent); }
private void attribute(AttributeToken token) { // This kind of bookkeeping is ugly, we probably should have distinct (if very similar) // tokens for attributes and for parameter bindings. if (addAttributesAsComponentBindings) { ComponentPageElement activeElement = activeElementStack.peek(); bindParameterFromTemplate(activeElement, token); return; } PageElement element = pageElementFactory.newAttributeElement(loadingElement.getComponentResources(), token); addToBody(element); }
/** * Creates a new binding, or returns an existing binding (or null) for the "inherit:" binding prefix. Mostly a * wrapper around {@link BindingSource#newBinding(String, ComponentResources, ComponentResources, String, String, * Location) * * @return the new binding, or an existing binding (if inherited), or null (if inherited, and the containing * parameter is not bound) */ private Binding findBinding( ComponentPageElement loadingComponent, ComponentPageElement component, String name, String value, String defaultBindingPrefix, Location location) { if (value.startsWith(INHERIT_PREFIX)) { String loadingParameterName = value.substring(INHERIT_PREFIX.length()); Map<String, Binding> loadingComponentBindingMap = componentIdToBindingMap.get(loadingComponent.getCompleteId()); // This may return null if the parameter is not bound in the loading component. Binding existing = loadingComponentBindingMap.get(loadingParameterName); if (existing == null) return null; String description = String.format( "InheritedBinding[parameter %s %s(inherited from %s of %s)]", name, component.getCompleteId(), loadingParameterName, loadingComponent.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. return new InheritedBinding(description, existing, location); } return pageElementFactory.newBinding( name, loadingComponent.getComponentResources(), component.getComponentResources(), defaultBindingPrefix, value, location); }
private void startComponent(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 : loadingComponentModel.getEmbeddedComponentModel(embeddedId); // We know that if embeddedId is null, embeddedType is not. if (embeddedId == null) embeddedId = generateEmbeddedId(embeddedType, idAllocator); if (embeddedModel != null) { String modelType = embeddedModel.getComponentType(); if (InternalUtils.isNonBlank(modelType) && embeddedType != null) throw new TapestryException( ServicesMessages.compTypeConflict(embeddedId, embeddedType, modelType), token, null); embeddedType = modelType; embeddedComponentClassName = embeddedModel.getComponentClassName(); } // We only have the embeddedModel if the embeddedId was specified. If embeddedType was ommitted // and if (InternalUtils.isBlank(embeddedType) && embeddedModel == null) throw new TapestryException( ServicesMessages.noTypeForEmbeddedComponent( embeddedId, loadingComponentModel.getComponentClassName()), token, null); final ComponentPageElement newComponent = pageElementFactory.newComponentElement( page, loadingElement, embeddedId, embeddedType, embeddedComponentClassName, elementName, token.getLocation()); addMixinsToComponent(newComponent, embeddedModel, token.getMixins()); final Map<String, Binding> newComponentBindings = CollectionFactory.newMap(); componentIdToBindingMap.put(newComponent.getCompleteId(), newComponentBindings); if (embeddedModel != null) bindParametersFromModel(embeddedModel, loadingElement, newComponent, newComponentBindings); addToBody(newComponent); // Remember to load the template for this new component componentQueue.push(newComponent); // Any attribute tokens that immediately follow should be // used to bind parameters. addAttributesAsComponentBindings = true; // Any attributes (including component parameters) that come up belong on this component. activeElementStack.push(newComponent); // Set things up so that content inside the component is added to the component's body. bodyPageElementStack.push(newComponent); // And clean that up when the end element is reached. final ComponentModel newComponentModel = newComponent.getComponentResources().getComponentModel(); // If the component was from an embedded @Component annotation, and it is inheritting informal // parameters, // and the component in question supports informal parameters, than get those inheritted // informal parameters ... // but later (this helps ensure that <t:parameter> elements that may provide informal parameters // are // visible when the informal parameters are copied to the child component). if (embeddedModel != null && embeddedModel.getInheritInformalParameters() && newComponentModel.getSupportsInformalParameters()) { final ComponentPageElement loadingElement = this.loadingElement; Runnable finalizer = new Runnable() { public void run() { handleInformalParameters( loadingElement, embeddedModel, newComponent, newComponentModel, newComponentBindings); } }; finalization.add(finalizer); } Runnable cleanup = new Runnable() { public void run() { // May need a separate queue for this, to execute at the very end of page loading. activeElementStack.pop(); bodyPageElementStack.pop(); } }; // The start tag is not added to the body of the component, so neither should // the end tag. configureEnd(true, cleanup); }
private void expansion(ExpansionToken token) { PageElement element = pageElementFactory.newExpansionElement(loadingElement.getComponentResources(), token); addToBody(element); }