Skip to main content

Syntax Validation for Java Fragment TBB

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:
  • 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;
Finally, everything worked and the validation looks something like that:
Notice the variable "a" declared without a type and the Date class not being resolvable.

A detail error message looks like this, if expanded:
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

Popular posts from this blog

Running sp_updatestats on AWS RDS database

Part of the maintenance tasks that I perform on a MSSQL Content Manager database is to run stored procedure sp_updatestats . exec sp_updatestats However, that is not supported on an AWS RDS instance. The error message below indicates that only the sa  account can perform this: Msg 15247 , Level 16 , State 1 , Procedure sp_updatestats, Line 15 [Batch Start Line 0 ] User does not have permission to perform this action. Instead there are several posts that suggest using UPDATE STATISTICS instead: https://dba.stackexchange.com/questions/145982/sp-updatestats-vs-update-statistics I stumbled upon the following post from 2008 (!!!), https://social.msdn.microsoft.com/Forums/sqlserver/en-US/186e3db0-fe37-4c31-b017-8e7c24d19697/spupdatestats-fails-to-run-with-permission-error-under-dbopriveleged-user , which describes a way to wrap the call to sp_updatestats and execute it under a different user: create procedure dbo.sp_updstats with execute as 'dbo' as

I Have Gone Dark

Maybe it's the Holidays, but my mood has gone pretty dark. That is, regarding the look and feel of my computer and Tridion CME, of course. What I did was to dim the lights on the operating system, so I installed Placebo themes for Windows 7 . I went for the Ashtray look -- great name :) My VM looks now like this: But, once you change the theme on Windows, you should 'match' the theme of your applications. Some skin easily, some not. The Office suite has an in-built scheme, which can be set to Black , but it doesn't actually dim the ribbon tool bars -- it looks quite weird. Yahoo Messenger is skinnable, but you can't change the big white panels where you actually 'chat'. Skype is not skinnable at all. For Chrome, there are plenty of grey themes. Now i'm using Pro Grey . But then I got into changing the theme of websites. While very few offer skinnable interfaces (as GMail does), I had to find a way to darken the websites... Enter Stylish -- a pl

REL Standard Tag Library

The RSTL is a library of REL tags providing standard functionality such as iterating collections, conditionals, imports, assignments, XML XSLT transformations, formatting dates, etc. RSTL distributable is available on my Google Code page under  REL Standard Tag Library . Always use the latest JAR . This post describes each RSTL tag in the library explaining its functionality, attributes and providing examples. For understanding the way expressions are evaluated, please read my post about the  Expression Language used by REL Standard Tag Library . <c:choose> / <c:when> / <c:otherwise> Syntax:     <c:choose>         <c:when test="expr1">             Do something         </c:when>         <c:when test="expr2">             Do something else         </c:when>         <c:otherwise>             Do something otherwise         </c:otherwise>     </c:choose> Att