This little post explains how to perform "Content Validation" of a Java Fragment TBB as part of the Tridion Java Mediator I am currently working on. If you want more information about the "Yet Another Java Mediator" for Tridion templating, have a look at my previous post.
Content validation for TBBs, or in Tridion terms, a Template Content Handler, is a piece of code that runs when a TBB is read (open) or written (saved) and it serves two purposes:
On the Java side, I am simply intercepting the messages coming from the Compiler API and, in case of an error, throw an exception with the compiler message formatted a bit. I do some formatting on the line numbers only, so that the line number reported is actually relative to the Java Fragment that is shown in Tridion and not the line number relative to the entire compilation unit. The thrown exception is propagated all the way back into .NET and eventually ends up being displayed in the CME.
Content validation for TBBs, or in Tridion terms, a Template Content Handler, is a piece of code that runs when a TBB is read (open) or written (saved) and it serves two purposes:
- perform any validation of the TBB content;
- replace any references to other Tridion items (either by TCM URI or WebDAV URL, or some kind of reference) with some kind of substitution;
I have not implemented any replacement logic yet (it is to come in the near future when I'll write the logic to upload JARs and execute classes from it). So far my goal was to perform a compile of the TBB Java source fragment at the moment of saving the TBB, and in case of errors, show the errors in the GUI and prevent saving. This is the same behaviour the C# Fragment TBBs have in OOTB Tridion.
In .NET things are simple -- all I had to do was create a class that extends abstract Tridion.ContentManager.Templating.AbstractTemplateContentHandler and implement method PerformValidateContent. From this method I called the Java Fragment compile logic (written in Java, over JNI proxy, as described in my previous post).
C#:
public class JavaFragmentContentHandler : AbstractTemplateContentHandler {
public override
void PerformValidateContent() {
JavaTemplateHandler
handler = new JavaTemplateHandler();
handler.compile(base.Content);
}
Java:
public class JavaTemplateHandler {
public void compile(String javaFragmentSource) {
String javaSource
= String.format(JAVA_FRAGMENT_SKELETON_SOURCE, javaFragmentSource);
SourceStringCompiler
compiler = new SourceStringCompiler(CLASSES_DIR);
compiler.compile(JAVA_FRAGMENT_SKELETON_CLASS_NAME, javaSource);
}
On the Java side, I am simply intercepting the messages coming from the Compiler API and, in case of an error, throw an exception with the compiler message formatted a bit. I do some formatting on the line numbers only, so that the line number reported is actually relative to the Java Fragment that is shown in Tridion and not the line number relative to the entire compilation unit. The thrown exception is propagated all the way back into .NET and eventually ends up being displayed in the CME.
I hit a few roadblocks, of course:
- Content handlers need to be registered in the GAC. This is unfortunately inconsistent with the mechanism of registering mediators, where you can specify the actual assembly path. As a Java head, I really dislike the GAC -- it is the root of all evil. This meant I had to sign all my referenced DLLs (including Tom.Java, jni4net). This meant a lot of trouble with the JAR loading mechanism from jni4net etc). In the end I opted for reflection, just to keep the 'referenced' DLLs out of GAC and unsigned;
- 32bit vs 64bit trouble -- some parts of Tridion CM run as 32bit applications and some as 64bit. This poses a huge problem to jni4net Bridge, which has to use the appropriate 32 vs 64 bit Java Development Kit based on the calling .NET CLR it runs it;
So far I have the entire Java Fragment TBB done, including validation/compilation. Next, I I'll focus on the JSP/JSTL TBBs that I intend to use as replacement of Dreamweaver TBBs.
Comments