1 17 18 package org.apache.james.util; 19 20 import org.apache.oro.text.perl.MalformedPerl5PatternException; 21 import org.apache.oro.text.perl.Perl5Util; 22 import org.w3c.dom.*; 23 24 import javax.xml.parsers.DocumentBuilder ; 25 import javax.xml.parsers.DocumentBuilderFactory ; 26 import java.io.File ; 27 import java.sql.Connection ; 28 import java.sql.SQLException ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.Map ; 32 33 34 42 public class SqlResources 43 { 44 47 private Map m_sql = new HashMap (); 48 49 52 private Map m_dbOptions = new HashMap (); 53 54 57 static private Map stringTable = java.util.Collections.synchronizedMap(new HashMap ()); 58 59 62 private Perl5Util m_perl5Util = new Perl5Util(); 63 64 81 public void init(File sqlFile, String sqlDefsSection, 82 Connection conn, Map configParameters) 83 throws Exception 84 { 85 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 87 DocumentBuilder builder = factory.newDocumentBuilder(); 88 Document sqlDoc = builder.parse(sqlFile); 89 90 Element dbMatcherElement = 93 (Element)(sqlDoc.getElementsByTagName("dbMatchers").item(0)); 94 String dbProduct = null; 95 if ( dbMatcherElement != null ) { 96 dbProduct = matchDbConnection(conn, dbMatcherElement); 97 m_perl5Util = null; } 99 100 Element dbOptionsElement = 102 (Element)(sqlDoc.getElementsByTagName("dbOptions").item(0)); 103 if ( dbOptionsElement != null ) { 104 populateDbOptions("", dbOptionsElement, m_dbOptions); 106 if ( dbProduct != null ) { 108 populateDbOptions(dbProduct, dbOptionsElement, m_dbOptions); 109 } 110 } 111 112 113 NodeList sections = sqlDoc.getElementsByTagName("sqlDefs"); 115 int sectionsCount = sections.getLength(); 116 Element sectionElement = null; 117 for (int i = 0; i < sectionsCount; i++ ) { 118 sectionElement = (Element)(sections.item(i)); 119 String sectionName = sectionElement.getAttribute("name"); 120 if ( sectionName != null && sectionName.equals(sqlDefsSection) ) { 121 break; 122 } 123 124 } 125 if ( sectionElement == null ) { 126 StringBuffer exceptionBuffer = 127 new StringBuffer (64) 128 .append("Error loading sql definition file. ") 129 .append("The element named \'") 130 .append(sqlDefsSection) 131 .append("\' does not exist."); 132 throw new RuntimeException (exceptionBuffer.toString()); 133 } 134 135 Map parameters = new HashMap (); 138 Element parametersElement = 140 (Element)(sectionElement.getElementsByTagName("parameters").item(0)); 141 if ( parametersElement != null ) { 142 NamedNodeMap params = parametersElement.getAttributes(); 143 int paramCount = params.getLength(); 144 for (int i = 0; i < paramCount; i++ ) { 145 Attr param = (Attr)params.item(i); 146 String paramName = param.getName(); 147 String paramValue = param.getValue(); 148 parameters.put(paramName, paramValue); 149 } 150 } 151 parameters.putAll(configParameters); 153 154 Map defaultSqlStatements = new HashMap (); 158 Map dbProductSqlStatements = new HashMap (); 159 160 NodeList sqlDefs = sectionElement.getElementsByTagName("sql"); 163 int sqlCount = sqlDefs.getLength(); 164 for ( int i = 0; i < sqlCount; i++ ) { 165 Element sqlElement = (Element)(sqlDefs.item(i)); 167 String sqlDb = sqlElement.getAttribute("db"); 168 Map sqlMap; 169 if ( sqlDb.equals("")) { 170 sqlMap = defaultSqlStatements; 172 } 173 else if (sqlDb.equals(dbProduct) ) { 174 sqlMap = dbProductSqlStatements; 176 } 177 else { 178 continue; 180 } 181 182 String sqlKey = sqlElement.getAttribute("name"); 184 if ( sqlKey == null ) { 185 continue; 187 } 188 String sqlString = sqlElement.getFirstChild().getNodeValue(); 189 190 Iterator paramNames = parameters.keySet().iterator(); 192 while ( paramNames.hasNext() ) { 193 String paramName = (String )paramNames.next(); 194 String paramValue = (String )parameters.get(paramName); 195 196 StringBuffer replaceBuffer = 197 new StringBuffer (64) 198 .append("${") 199 .append(paramName) 200 .append("}"); 201 sqlString = substituteSubString(sqlString, replaceBuffer.toString(), paramValue); 202 } 203 204 String shared = (String ) stringTable.get(sqlString); 206 if (shared == null) { 208 stringTable.put(sqlString, sqlString); 209 } else { 210 sqlString = shared; 211 } 212 213 sqlMap.put(sqlKey, sqlString); 215 } 216 217 m_sql.putAll(defaultSqlStatements); 219 m_sql.putAll(dbProductSqlStatements); 220 } 221 222 235 private String matchDbConnection(Connection conn, 236 Element dbMatchersElement) 237 throws MalformedPerl5PatternException, SQLException 238 { 239 String dbProductName = conn.getMetaData().getDatabaseProductName(); 240 241 NodeList dbMatchers = 242 dbMatchersElement.getElementsByTagName("dbMatcher"); 243 for ( int i = 0; i < dbMatchers.getLength(); i++ ) { 244 Element dbMatcher = (Element)dbMatchers.item(i); 246 String dbMatchName = dbMatcher.getAttribute("db"); 247 StringBuffer dbProductPatternBuffer = 248 new StringBuffer (64) 249 .append("/") 250 .append(dbMatcher.getAttribute("databaseProductName")) 251 .append("/i"); 252 253 if ( m_perl5Util.match(dbProductPatternBuffer.toString(), dbProductName) ) { 256 return dbMatchName; 257 } 258 } 259 return null; 260 } 261 262 271 private void populateDbOptions(String dbProduct, Element dbOptionsElement, Map dbOptionsMap) 272 { 273 NodeList dbOptions = 274 dbOptionsElement.getElementsByTagName("dbOption"); 275 for ( int i = 0; i < dbOptions.getLength(); i++ ) { 276 Element dbOption = (Element)dbOptions.item(i); 278 if (!dbProduct.equalsIgnoreCase(dbOption.getAttribute("db"))) { 281 continue; 282 } 283 dbOptionsMap.put(dbOption.getAttribute("name"), dbOption.getAttribute("value")); 285 } 286 } 287 288 295 private String substituteSubString( String input, 296 String find, 297 String replace ) 298 { 299 int find_length = find.length(); 300 int replace_length = replace.length(); 301 302 StringBuffer output = new StringBuffer (input); 303 int index = input.indexOf(find); 304 int outputOffset = 0; 305 306 while ( index > -1 ) { 307 output.replace(index + outputOffset, index + outputOffset + find_length, replace); 308 outputOffset = outputOffset + (replace_length - find_length); 309 310 index = input.indexOf(find, index + find_length); 311 } 312 313 String result = output.toString(); 314 return result; 315 } 316 317 324 public String getSqlString(String name) 325 { 326 return (String )m_sql.get(name); 327 } 328 329 339 public String getSqlString(String name, boolean required) 340 { 341 String sql = getSqlString(name); 342 343 if (sql == null && required) { 344 StringBuffer exceptionBuffer = 345 new StringBuffer (64) 346 .append("Required SQL resource: '") 347 .append(name) 348 .append("' was not found."); 349 throw new RuntimeException (exceptionBuffer.toString()); 350 } 351 return sql; 352 } 353 354 360 public String getDbOption(String name) 361 { 362 return (String )m_dbOptions.get(name); 363 } 364 365 } 366 | Popular Tags |