use of org.apache.tapestry5.clojure.Namespace 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.clojure.Namespace in project tapestry-5 by apache.
the class SaxTemplateParser method parameterElement.
/**
* Tapestry 5.1 uses a special namespace (usually mapped to "p:") and the
* name becomes the parameter element.
*/
private void parameterElement(TemplateParserState state) {
ensureParameterWithinComponent(state);
if (tokenStream.getAttributeCount() > 0)
throw new TapestryException("A block parameter element does not allow any additional attributes. The element name defines the parameter name.", getLocation(), null);
tokenAccumulator.add(new ParameterToken(tokenStream.getLocalName(), getLocation()));
processBody(state.insideComponent(false));
}
use of org.apache.tapestry5.clojure.Namespace in project tapestry-5 by apache.
the class AnnotationMapper method mapMethod.
@Override
public Symbol mapMethod(String namespace, Method method) {
FunctionName annotation = method.getAnnotation(FunctionName.class);
if (annotation == null) {
return null;
}
String name = annotation.value();
if (name.contains("/")) {
return Symbol.create(name);
}
return Symbol.create(namespace, name);
}
use of org.apache.tapestry5.clojure.Namespace in project tapestry-5 by apache.
the class ClojureBuilderImpl method build.
@Override
public <T> T build(final Class<T> interfaceType) {
assert interfaceType != null;
assert interfaceType.isInterface();
Namespace annotation = interfaceType.getAnnotation(Namespace.class);
if (annotation == null) {
throw new IllegalArgumentException(String.format("Interface type %s does not have the Namespace annotation.", interfaceType.getName()));
}
final String namespace = annotation.value();
ClassInstantiator<T> instantiator = proxyFactory.createProxy(interfaceType, new PlasticClassTransformer() {
@Override
public void transform(PlasticClass plasticClass) {
for (final Method m : interfaceType.getMethods()) {
bridgeToClojure(plasticClass, m);
}
}
private void bridgeToClojure(final PlasticClass plasticClass, final Method method) {
final MethodDescription desc = new MethodDescription(method);
if (method.getReturnType() == void.class) {
throw new IllegalArgumentException(String.format("Method %s may not be void when bridging to Clojure functions.", desc));
}
final Symbol symbol = mapper.mapMethod(namespace, method);
tracker.run(String.format("Mapping %s method %s to Clojure function %s", interfaceType.getName(), desc.toShortString(), symbol.toString()), new Runnable() {
@Override
public void run() {
Symbol namespaceSymbol = Symbol.create(symbol.getNamespace());
REQUIRE.invoke(namespaceSymbol);
IFn clojureFunction = Clojure.var(symbol);
final PlasticField fnField = plasticClass.introduceField(IFn.class, method.getName() + "IFn").inject(clojureFunction);
plasticClass.introduceMethod(desc).changeImplementation(new InstructionBuilderCallback() {
@Override
public void doBuild(InstructionBuilder builder) {
bridgeToClojure(builder, desc, fnField);
}
});
}
});
}
private void bridgeToClojure(InstructionBuilder builder, MethodDescription description, PlasticField ifnField) {
builder.loadThis().getField(ifnField);
int count = description.argumentTypes.length;
Class[] invokeParameterTypes = new Class[count];
for (int i = 0; i < count; i++) {
invokeParameterTypes[i] = Object.class;
builder.loadArgument(i).boxPrimitive(description.argumentTypes[i]);
}
Method ifnMethod = null;
try {
ifnMethod = IFn.class.getMethod("invoke", invokeParameterTypes);
} catch (NoSuchMethodException ex) {
throw new RuntimeException(String.format("Unable to find correct IFn.invoke() method: %s", ExceptionUtils.toMessage(ex)), ex);
}
builder.invoke(ifnMethod);
builder.castOrUnbox(description.returnType);
builder.returnResult();
}
});
return instantiator.newInstance();
}
use of org.apache.tapestry5.clojure.Namespace in project tapestry-5 by apache.
the class JavaScriptModule method exposeJavaScriptSupportForPartialPageRender.
/**
* Contributes {@link PartialMarkupRendererFilter}s used when rendering a
* partial Ajax response.
* <dl>
* <dt>JavaScriptSupport
* <dd>Provides {@link JavaScriptSupport}</dd>
* </dl>
*/
@Contribute(PartialMarkupRenderer.class)
public void exposeJavaScriptSupportForPartialPageRender(OrderedConfiguration<PartialMarkupRendererFilter> configuration, final JavaScriptStackSource javascriptStackSource, final JavaScriptStackPathConstructor javascriptStackPathConstructor, final Request request) {
final BooleanHook suppressCoreStylesheetsHook = createSuppressCoreStylesheetHook(request);
PartialMarkupRendererFilter javascriptSupport = new PartialMarkupRendererFilter() {
public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer) {
IdAllocator idAllocator;
if (request.getParameter(InternalConstants.SUPPRESS_NAMESPACED_IDS) == null) {
String uid = Long.toHexString(System.nanoTime());
String namespace = "_" + uid;
idAllocator = new IdAllocator(namespace);
} else {
// When suppressed, work just like normal rendering.
idAllocator = new IdAllocator();
}
DocumentLinker linker = environment.peekRequired(DocumentLinker.class);
JavaScriptSupportImpl support = new JavaScriptSupportImpl(linker, javascriptStackSource, javascriptStackPathConstructor, idAllocator, true, suppressCoreStylesheetsHook);
environment.push(JavaScriptSupport.class, support);
renderer.renderMarkup(writer, reply);
environment.pop(JavaScriptSupport.class);
support.commit();
}
};
configuration.add("JavaScriptSupport", javascriptSupport, "after:DocumentLinker");
}
Aggregations