}
}
for (final Map.Entry<String, Attribute> param : params.entrySet()) {
final String name = param.getKey();
final FormalParameter parameter = callee.getParameter(name);
Attribute attr = param.getValue();
if (parameter == null) {
alertSink.add(new BadParameterError(attr.getValue(), callee, name));
continue;
}
// TODO(harryh): maybe better to use a DefaultingExpressionVisitor
// here?
if (attr.getValue() instanceof ObjectConstant) {
ObjectConstant oc = (ObjectConstant) attr.getValue();
// TODO(harryh): maybe this should be in Validator?
if (!parameter.regexMatches(oc)) {
alertSink.add(new InvalidParameterFailedRegexError(
calleeName, name, parameter.getRegex(), oc));
}
attr = parameter.hasConstructor()
? attr.withValue(new ConstructedConstant(oc, oc.getValue(), callee, parameter))
: attr.withValue(parameter.getType().parseObjectConstant(name, oc, alertSink));
}
attr = attr.withValue(prepareExpressionAsParameterValue(parameter, attr.getValue()));
final Attribute updatedAttr = visitAttribute(attr);
parameter.getType().acceptTypeVisitor(new DefaultingTypeVisitor<Void>() {
protected Void defaultVisitType(Type type) {
newAttrBuilder.put(name, updatedAttr);
return null;
}
public Void visitBundleType(BundleType type) {
final AttributeValidator validator = type.getValidator(name);
String innerContentTypeString = validator.getContentType();
if (innerContentTypeString != null) {
Schema innerSchema = schemaFactory.fromContentTypeName(innerContentTypeString);
attrBundles.get(parameter.getPrimaryName()).put(validator,
updatedAttr.withInnerSchema(innerSchema));
} else {
attrBundles.get(parameter.getPrimaryName()).put(validator, updatedAttr);
}
return null;
}
});
}
// go through the attrBundleMap and turn each entry into an
// AttrBundleParam and put this into the builder map.
for (Map.Entry<String, Map<AttributeValidator, Attribute>> attrBundle :
attrBundles.entrySet()) {
FormalParameter parameter = callee.getParameterByPrimary(attrBundle.getKey());
BundleType bt = (BundleType) parameter.getType();
// special case for the (common case) of a single bundle on the
// callee side. In this case there is no mixing of attributes
// between bundles so the GxpAttrBundleBuilder does not need to
// include only some attributes from passed in bundles. See the
// empty constructor in j/c/g/gxp/base/GxpAttrBundleBuilder.java
Set<String> includeAttrs = (attrBundles.size() == 1)
? Collections.<String>emptySet() : bt.getAttrMap().keySet();
AttrBundleParam newBundle =
new AttrBundleParam(call, callee.getSchema(), includeAttrs,
attrBundle.getValue(), call.getAttrBundles());
newAttrBuilder.put(attrBundle.getKey(),
new Attribute(call, attrBundle.getKey(),
newBundle, null));
}
// Handle content parameter
FormalParameter contentParam = callee.getContentConsumingParameter();
Expression content = prepareExpressionAsParameterValue(contentParam,
apply(call.getContent()));
boolean contentIgnorable = content.alwaysOnlyWhitespace();
if (contentParam == null) {
if (!contentIgnorable) {
alertSink.add(new BadNodePlacementError(content, call));
}
} else {
String paramName = contentParam.getPrimaryName();
if (!contentIgnorable && params.containsKey(paramName)) {
alertSink.add(new MultiValueAttributeError(call, params.get(paramName)));
} else if (!contentIgnorable
|| (!contentParam.hasDefault() && !params.containsKey(paramName))) {
newAttrBuilder.put(contentParam.getPrimaryName(),
new Attribute(call, paramName, content, null));
}
}
requirements.add(callee);