/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.template; import gw.internal.gosu.parser.CompiledGosuClassSymbolTable; import gw.internal.gosu.parser.Symbol; import gw.internal.gosu.parser.TypeLoaderAccess; import gw.lang.parser.ISymbol; import gw.lang.parser.ISymbolTable; import gw.lang.parser.template.ITemplateGenerator; import gw.lang.parser.template.ITemplateHost; import gw.lang.reflect.TypeSystem; import java.io.Reader; import java.io.Writer; import java.util.LinkedList; import java.util.List; /** */ public class SimpleTemplateHost implements ITemplateHost { private static final ThreadLocal g_symTableCtx = new ThreadLocal(); /** */ public SimpleTemplateHost() { } private static ISymbolTable getSymTableCtx() { List list = (List)g_symTableCtx.get(); if( list != null && list.size() > 0 ) { return (ISymbolTable)list.get( 0 ); } return null; } private static void pushSymTableCtx( ISymbolTable ctx ) { List list = (List)g_symTableCtx.get(); if( list == null ) { g_symTableCtx.set( list = new LinkedList() ); } list.add( 0, ctx ); } private static void popSymTableCtx() { List list = (List)g_symTableCtx.get(); list.remove( 0 ); } //---------------------------------------------------------------------------- // -- ITemplateHost methods -- /** * @param readerTemplate * @param writerOut */ public void executeTemplate( Reader readerTemplate, Writer writerOut ) { executeTemplate(readerTemplate, writerOut, false); } /** * @param readerTemplate * @param writerOut */ public void executeTemplate( Reader readerTemplate, Writer writerOut, boolean strict ) { try { TemplateGenerator.generateTemplate( readerTemplate, writerOut, getThreadLocalSymbolTable(), strict ); } catch( Throwable e ) { throw new RuntimeException( e ); } } /** */ public void executeTemplate( ITemplateGenerator precompiledTemplate, Writer writerOut ) { pushSymTableCtx( getSymbolTable() ); try { precompiledTemplate.execute( writerOut, getThreadLocalSymbolTable()); } catch( RuntimeException e ) { throw e; } catch( Throwable e ) { throw new RuntimeException( e ); } finally { popSymTableCtx(); } } /** * @param readerTemplate */ public TemplateGenerator getTemplate( Reader readerTemplate ) { try { return TemplateGenerator.getTemplate( readerTemplate ); } catch( Throwable e ) { throw new RuntimeException( e ); } } public TemplateGenerator getTemplate( Reader readerTemplate, String strFqn ) { try { return TemplateGenerator.getTemplate( readerTemplate, strFqn ); } catch( Throwable e ) { throw new RuntimeException( e ); } } /** * */ public synchronized void pushScope() { getThreadLocalSymbolTable().pushScope(); } /** * */ public synchronized void popScope() { getThreadLocalSymbolTable().popScope(); } /** * @param strName * @param type * @param value */ //## TODO MD: this method needs to take an IType instead of a Class public synchronized void putSymbol( String strName, Class type, Object value ) { if( value != null ) { Class typeValue = value.getClass(); if( !type.isAssignableFrom( typeValue ) && !typeValue.isAssignableFrom( type ) ) { throw new IllegalArgumentException( type.getName() + " is not compatible with " + typeValue.getName() ); } } Symbol root = new Symbol( strName, TypeSystem.get( type ), value ); getThreadLocalSymbolTable().putSymbol( root ); } /** * @param symbol */ public synchronized void putSymbol( ISymbol symbol ) { getThreadLocalSymbolTable().putSymbol( symbol ); } /** * @param strName */ public synchronized void removeSymbol( String strName ) { getThreadLocalSymbolTable().removeSymbol( strName ); } public ISymbolTable getSymbolTable() { return getThreadLocalSymbolTable(); } private static ISymbolTable getThreadLocalSymbolTable() { return CompiledGosuClassSymbolTable.instance(); } }