use of org.apache.tapestry5.annotations.Parameter in project tapestry-5 by apache.
the class SaxTemplateParser method element.
/**
* Processes an element through to its matching end tag.
*
* An element can be:
*
* a Tapestry component via <t:type>
*
* a Tapestry component via t:type="type" and/or t:id="id"
*
* a Tapestry component via a library namespace
*
* A parameter element via <t:parameter>
*
* A parameter element via <p:name>
*
* A <t:remove> element (in the 5.1 schema)
*
* A <t:content> element (in the 5.1 schema)
*
* A <t:block> element
*
* The body <t:body>
*
* An ordinary element
*/
void element(TemplateParserState initialState) {
TemplateParserState state = setupForElement(initialState);
String uri = tokenStream.getNamespaceURI();
String name = tokenStream.getLocalName();
Version version = NAMESPACE_URI_TO_VERSION.get(uri);
if (T_5_1.sameOrEarlier(version)) {
if (name.equalsIgnoreCase("remove")) {
removeContent();
return;
}
if (name.equalsIgnoreCase("content")) {
limitContent(state);
return;
}
if (name.equalsIgnoreCase("extension-point")) {
extensionPoint(state);
return;
}
if (name.equalsIgnoreCase("replace")) {
throw new RuntimeException("The <replace> element may only appear directly within an extend element.");
}
if (MUST_BE_ROOT.contains(name))
mustBeRoot(name);
}
if (version != null) {
if (name.equalsIgnoreCase("body")) {
body();
return;
}
if (name.equalsIgnoreCase("container")) {
mustBeRoot(name);
}
if (name.equalsIgnoreCase("block")) {
block(state);
return;
}
if (name.equalsIgnoreCase("parameter")) {
if (T_5_3.sameOrEarlier(version)) {
throw new RuntimeException(String.format("The <parameter> element has been deprecated in Tapestry 5.3 in favour of '%s' namespace.", TAPESTRY_PARAMETERS_URI));
}
classicParameter(state);
return;
}
possibleTapestryComponent(state, null, tokenStream.getLocalName().replace('.', '/'));
return;
}
if (uri != null && uri.startsWith(LIB_NAMESPACE_URI_PREFIX)) {
libraryNamespaceComponent(state);
return;
}
if (TAPESTRY_PARAMETERS_URI.equals(uri)) {
parameterElement(state);
return;
}
// Just an ordinary element ... unless it has t:id or t:type
possibleTapestryComponent(state, tokenStream.getLocalName(), null);
}
use of org.apache.tapestry5.annotations.Parameter in project tapestry-5 by apache.
the class SaxTemplateParser method possibleTapestryComponent.
/**
* @param elementName
* @param identifiedType
* the type of the element, usually null, but may be the
* component type derived from element
*/
private void possibleTapestryComponent(TemplateParserState state, String elementName, String identifiedType) {
String id = null;
String type = identifiedType;
String mixins = null;
int count = tokenStream.getAttributeCount();
Location location = getLocation();
List<TemplateToken> attributeTokens = CollectionFactory.newList();
for (int i = 0; i < count; i++) {
QName qname = tokenStream.getAttributeName(i);
if (isXMLSpaceAttribute(qname))
continue;
// The name will be blank for an xmlns: attribute
String localName = qname.getLocalPart();
if (InternalUtils.isBlank(localName))
continue;
String uri = qname.getNamespaceURI();
String value = tokenStream.getAttributeValue(i);
Version version = NAMESPACE_URI_TO_VERSION.get(uri);
if (version != null) {
if (T_5_4.sameOrEarlier(version)) {
strictMixinParameters = true;
}
if (localName.equalsIgnoreCase(ID_ATTRIBUTE_NAME)) {
id = nullForBlank(value);
validateId(id, "Component id '%s' is not valid; component ids must be valid Java identifiers: start with a letter, and consist of letters, numbers and underscores.");
continue;
}
if (type == null && localName.equalsIgnoreCase(TYPE_ATTRIBUTE_NAME)) {
type = nullForBlank(value);
continue;
}
if (localName.equalsIgnoreCase(MIXINS_ATTRIBUTE_NAME)) {
mixins = nullForBlank(value);
continue;
}
// Anything else is the name of a Tapestry component parameter
// that is simply
// not part of the template's doctype for the element being
// instrumented.
}
attributeTokens.add(new AttributeToken(uri, localName, value, location));
}
boolean isComponent = (id != null || type != null);
if (mixins != null && !isComponent)
throw new TapestryException(String.format("You may not specify mixins for element <%s> because it does not represent a component (which requires either an id attribute or a type attribute).", elementName), location, null);
if (isComponent) {
tokenAccumulator.add(new StartComponentToken(elementName, id, type, mixins, location));
} else {
tokenAccumulator.add(new StartElementToken(tokenStream.getNamespaceURI(), elementName, location));
}
addDefineNamespaceTokens();
tokenAccumulator.addAll(attributeTokens);
if (id != null)
componentIds.put(id, location);
processBody(state.insideComponent(isComponent));
}
use of org.apache.tapestry5.annotations.Parameter in project tapestry-5 by apache.
the class MutableComponentModelImplTest method add_duplicate_parameters_to_embedded.
@Test
public void add_duplicate_parameters_to_embedded() {
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null, false, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false, null);
fred.addParameter("city", "bedrock");
try {
fred.addParameter("city", "slateville");
unreachable();
} catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "A value for parameter 'city' of embedded component fred (of component class org.example.components.Foo) has already been provided.");
}
verify();
}
use of org.apache.tapestry5.annotations.Parameter in project tapestry-5 by apache.
the class BindingSourceImpl method newBinding.
public Binding newBinding(String description, ComponentResources container, ComponentResources component, String defaultPrefix, String expression, Location location) {
assert InternalUtils.isNonBlank(description);
assert container != null;
assert InternalUtils.isNonBlank(defaultPrefix);
assert component != null;
// TAP5-845: The expression may be the empty string. This is ok, if it's compatible with
// the default prefix (the empty string is not a valid property expression, but is valid
// as a literal string, perhaps as an informal parameter).
// Location might be null
String subexpression = expression;
int colonx = expression.indexOf(':');
BindingFactory factory = null;
if (colonx > 0) {
String prefix = expression.substring(0, colonx);
factory = factories.get(prefix);
if (factory != null)
subexpression = expression.substring(colonx + 1);
}
if (factory == null)
factory = factories.get(defaultPrefix);
try {
return factory.newBinding(interner.intern(description), container, component, subexpression, location);
} catch (Exception ex) {
throw new TapestryException(String.format("Could not convert '%s' into a component parameter binding: %s", expression, ExceptionUtils.toMessage(ex)), location, ex);
}
}
use of org.apache.tapestry5.annotations.Parameter in project tapestry-5 by apache.
the class PageLoaderImpl method addParameterBindingAction.
private void addParameterBindingAction(AssemblerContext context, final EmbeddedComponentAssembler embeddedAssembler, final String parameterName, final String parameterValue, final String metaDefaultBindingPrefix, final Location location, final boolean ignoreUnmatchedFormal) {
if (embeddedAssembler.isBound(parameterName))
return;
embeddedAssembler.setBound(parameterName);
if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX)) {
String containerParameterName = parameterValue.substring(InternalConstants.INHERIT_BINDING_PREFIX.length());
addInheritedBindingAction(context, parameterName, containerParameterName);
return;
}
context.add(new PageAssemblyAction() {
public void execute(PageAssembly pageAssembly) {
// Because of published parameters, we have to wait until page assembly time to throw out
// informal parameters bound to components that don't support informal parameters ...
// otherwise we'd throw out (sometimes!) published parameters.
final ParameterBinder binder = embeddedAssembler.createParameterBinder(parameterName);
if (binder == null) {
if (ignoreUnmatchedFormal) {
return;
}
throw new UnknownValueException(String.format("Component %s does not include a formal parameter '%s' (and does not support informal parameters).", pageAssembly.createdElement.peek().getCompleteId(), parameterName), null, null, new AvailableValues("Formal parameters", embeddedAssembler.getFormalParameterNames()));
}
final String defaultBindingPrefix = binder.getDefaultBindingPrefix(metaDefaultBindingPrefix);
InternalComponentResources containerResources = pageAssembly.activeElement.peek().getComponentResources();
ComponentPageElement embeddedElement = pageAssembly.createdElement.peek();
InternalComponentResources embeddedResources = embeddedElement.getComponentResources();
Binding binding = elementFactory.newBinding(parameterName, containerResources, embeddedResources, defaultBindingPrefix, parameterValue, location);
binder.bind(embeddedElement, binding);
}
});
}
Aggregations