1 56 package org.objectstyle.cayenne.access.jdbc; 57 58 import java.io.StringReader ; 59 import java.io.StringWriter ; 60 import java.util.ArrayList ; 61 import java.util.HashMap ; 62 import java.util.List ; 63 import java.util.Map ; 64 65 import org.apache.velocity.VelocityContext; 66 import org.apache.velocity.context.InternalContextAdapterImpl; 67 import org.apache.velocity.exception.ParseErrorException; 68 import org.apache.velocity.runtime.RuntimeConstants; 69 import org.apache.velocity.runtime.RuntimeInstance; 70 import org.apache.velocity.runtime.log.NullLogSystem; 71 import org.apache.velocity.runtime.parser.ParseException; 72 import org.apache.velocity.runtime.parser.node.SimpleNode; 73 import org.objectstyle.cayenne.CayenneRuntimeException; 74 75 82 class SQLTemplateProcessor { 83 private static RuntimeInstance sharedRuntime; 84 85 static final String BINDINGS_LIST_KEY = "bindings"; 86 static final String RESULT_COLUMNS_LIST_KEY = "resultColumns"; 87 static final String HELPER_KEY = "helper"; 88 89 private static final SQLTemplateRenderingUtils sharedUtils = 90 new SQLTemplateRenderingUtils(); 91 92 RuntimeInstance velocityRuntime; 93 SQLTemplateRenderingUtils renderingUtils; 94 95 static { 96 initVelocityRuntime(); 97 } 98 99 private static void initVelocityRuntime() { 100 sharedRuntime = new RuntimeInstance(); 102 103 sharedRuntime.addProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new NullLogSystem()); 105 106 sharedRuntime.addProperty( 107 RuntimeConstants.RESOURCE_MANAGER_CLASS, 108 SQLTemplateResourceManager.class.getName()); 109 sharedRuntime.addProperty("userdirective", BindDirective.class.getName()); 110 sharedRuntime.addProperty("userdirective", BindEqualDirective.class.getName()); 111 sharedRuntime.addProperty("userdirective", BindNotEqualDirective.class.getName()); 112 sharedRuntime.addProperty("userdirective", ResultDirective.class.getName()); 113 sharedRuntime.addProperty("userdirective", ChainDirective.class.getName()); 114 sharedRuntime.addProperty("userdirective", ChunkDirective.class.getName()); 115 try { 116 sharedRuntime.init(); 117 } 118 catch (Exception ex) { 119 throw new CayenneRuntimeException( 120 "Error setting up Velocity RuntimeInstance.", 121 ex); 122 } 123 } 124 125 SQLTemplateProcessor() { 126 this.velocityRuntime = sharedRuntime; 127 this.renderingUtils = sharedUtils; 128 } 129 130 SQLTemplateProcessor( 131 RuntimeInstance velocityRuntime, 132 SQLTemplateRenderingUtils renderingUtils) { 133 this.velocityRuntime = velocityRuntime; 134 this.renderingUtils = renderingUtils; 135 } 136 137 143 SQLSelectStatement processSelectTemplate(String template, Map parameters) 144 throws Exception { 145 146 Map internalParameters = 148 (parameters != null && !parameters.isEmpty()) 149 ? new HashMap (parameters) 150 : new HashMap (3); 151 152 List bindings = new ArrayList (); 153 List results = new ArrayList (); 154 internalParameters.put(BINDINGS_LIST_KEY, bindings); 155 internalParameters.put(RESULT_COLUMNS_LIST_KEY, results); 156 internalParameters.put(HELPER_KEY, renderingUtils); 157 158 String sql = 159 buildStatement(new VelocityContext(internalParameters), template, parameters); 160 161 ParameterBinding[] bindingsArray = new ParameterBinding[bindings.size()]; 162 bindings.toArray(bindingsArray); 163 164 ColumnDescriptor[] resultsArray = new ColumnDescriptor[results.size()]; 165 results.toArray(resultsArray); 166 return new SQLSelectStatement(sql, resultsArray, bindingsArray); 167 } 168 169 175 SQLStatement processTemplate(String template, Map parameters) throws Exception { 176 Map internalParameters = 178 (parameters != null && !parameters.isEmpty()) 179 ? new HashMap (parameters) 180 : new HashMap (3); 181 182 List bindings = new ArrayList (); 183 internalParameters.put(BINDINGS_LIST_KEY, bindings); 184 internalParameters.put(HELPER_KEY, renderingUtils); 185 186 String sql = 187 buildStatement(new VelocityContext(internalParameters), template, parameters); 188 189 ParameterBinding[] bindingsArray = new ParameterBinding[bindings.size()]; 190 bindings.toArray(bindingsArray); 191 return new SQLStatement(sql, bindingsArray); 192 } 193 194 String buildStatement(VelocityContext context, String template, Map parameters) 195 throws Exception { 196 199 StringWriter out = new StringWriter (template.length()); 200 SimpleNode nodeTree = null; 201 202 try { 203 nodeTree = velocityRuntime.parse(new StringReader (template), template); 204 } 205 catch (ParseException pex) { 206 throw new ParseErrorException(pex.getMessage()); 207 } 208 209 if (nodeTree == null) { 210 throw new CayenneRuntimeException("Error parsing template " + template); 211 } 212 213 InternalContextAdapterImpl ica = new InternalContextAdapterImpl(context); 215 ica.pushCurrentTemplateName(template); 216 217 try { 218 nodeTree.init(ica, velocityRuntime); 219 nodeTree.render(ica, out); 220 return out.toString(); 221 } 222 finally { 223 ica.popCurrentTemplateName(); 224 } 225 } 226 } 227 | Popular Tags |