1 56 package org.objectstyle.cayenne.conf; 57 58 import java.io.InputStream ; 59 60 import javax.sql.DataSource ; 61 62 import org.apache.log4j.Level; 63 import org.apache.log4j.Logger; 64 import org.objectstyle.cayenne.ConfigurationException; 65 import org.objectstyle.cayenne.access.QueryLogger; 66 import org.objectstyle.cayenne.access.util.ConnectionEventLogger; 67 import org.objectstyle.cayenne.conn.DataSourceInfo; 68 import org.objectstyle.cayenne.conn.PoolManager; 69 import org.objectstyle.cayenne.util.AbstractHandler; 70 import org.objectstyle.cayenne.util.Util; 71 import org.xml.sax.Attributes ; 72 import org.xml.sax.ContentHandler ; 73 import org.xml.sax.InputSource ; 74 import org.xml.sax.SAXException ; 75 import org.xml.sax.XMLReader ; 76 import org.xml.sax.helpers.DefaultHandler ; 77 78 84 public class DriverDataSourceFactory implements DataSourceFactory { 88 89 private static Logger logObj = Logger.getLogger(DriverDataSourceFactory.class); 90 91 protected XMLReader parser; 92 protected DataSourceInfo driverInfo; 93 protected Level logLevel = Level.DEBUG; 94 protected Configuration parentConfiguration; 95 96 99 public DriverDataSourceFactory() throws Exception { 100 this.parser = Util.createXmlReader(); 101 } 102 103 106 public void initializeWithParentConfiguration(Configuration parentConfiguration) { 107 this.parentConfiguration = parentConfiguration; 108 } 109 110 public DataSource getDataSource(String location) throws Exception { 111 return this.getDataSource(location, Level.DEBUG); 112 } 113 114 public DataSource getDataSource(String location, Level logLevel) throws Exception { 115 this.logLevel = logLevel; 116 this.load(location); 117 118 ConnectionEventLogger logger = new ConnectionEventLogger(Level.INFO); 119 120 try { 121 return new PoolManager(driverInfo.getJdbcDriver(), driverInfo 122 .getDataSourceUrl(), driverInfo.getMinConnections(), driverInfo 123 .getMaxConnections(), driverInfo.getUserName(), driverInfo 124 .getPassword(), logger); 125 } 126 catch (Exception ex) { 127 QueryLogger.logConnectFailure(logLevel, ex); 128 throw ex; 129 } 130 } 131 132 135 protected DataSourceInfo getDriverInfo() { 136 return this.driverInfo; 137 } 138 139 protected InputStream getInputStream(String location) { 140 if (this.parentConfiguration == null) { 141 throw new ConfigurationException( 142 "No parent Configuration set - cannot continue."); 143 } 144 145 return this.parentConfiguration.getResourceLocator().findResourceStream(location); 146 } 147 148 152 protected void load(String location) throws Exception { 153 logObj.log(logLevel, "loading driver information from '" + location + "'."); 154 155 InputStream in = this.getInputStream(location); 156 if (in == null) { 157 logObj.log(logLevel, "Error: location '" + location + "' not found."); 158 throw new ConfigurationException( 159 "Can't find DataSource configuration file at " + location); 160 } 161 162 RootHandler handler = new RootHandler(); 163 parser.setContentHandler(handler); 164 parser.setErrorHandler(handler); 165 parser.parse(new InputSource (in)); 166 } 167 168 170 171 private class RootHandler extends DefaultHandler { 172 173 179 public void startElement( 180 String namespaceURI, 181 String localName, 182 String qName, 183 Attributes atts) throws SAXException { 184 if (localName.equals("driver")) { 185 new DriverHandler(parser, this).init(localName, atts); 186 } 187 else { 188 logObj.log(logLevel, "<driver> must be the root element. <" 189 + localName 190 + "> is unexpected."); 191 throw new SAXException ("Config file is not of expected XML type. '" 192 + localName 193 + "' unexpected."); 194 } 195 } 196 } 197 198 199 private class DriverHandler extends AbstractHandler { 200 201 public DriverHandler(XMLReader parser, ContentHandler parentHandler) { 202 super(parser, parentHandler); 203 } 204 205 public void init(String name, Attributes attrs) throws SAXException { 206 String className = attrs.getValue("", "class"); 207 logObj.log(logLevel, "loading driver " + className); 208 driverInfo = new DataSourceInfo(); 209 driverInfo.setJdbcDriver(className); 210 } 211 212 218 public void startElement( 219 String namespaceURI, 220 String localName, 221 String qName, 222 Attributes atts) throws SAXException { 223 if (localName.equals("login")) { 224 new LoginHandler(this.parser, this).init(localName, atts, driverInfo); 225 } 226 else if (localName.equals("url")) { 227 new UrlHandler(this.parser, this).init(localName, atts, driverInfo); 228 } 229 else if (localName.equals("connectionPool")) { 230 new ConnectionHandler(this.parser, this) 231 .init(localName, atts, driverInfo); 232 } 233 else { 234 logObj.log(logLevel, "<login, url, connectionPool> are valid. <" 235 + localName 236 + "> is unexpected."); 237 throw new SAXException ("Config file is not of expected XML type"); 238 } 239 } 240 241 } 242 243 private class UrlHandler extends AbstractHandler { 244 245 251 public UrlHandler(XMLReader parser, ContentHandler parentHandler) { 252 super(parser, parentHandler); 253 } 254 255 public void init(String name, Attributes atts, DataSourceInfo driverInfo) 256 throws SAXException { 257 driverInfo.setDataSourceUrl(atts.getValue("value")); 258 if (driverInfo.getDataSourceUrl() == null) { 259 logObj.log(logLevel, "error: <url> has no 'value'."); 260 throw new SAXException ("'<url value=' attribute is required."); 261 } 262 } 263 } 264 265 private class LoginHandler extends AbstractHandler { 266 267 273 public LoginHandler(XMLReader parser, ContentHandler parentHandler) { 274 super(parser, parentHandler); 275 } 276 277 public void init(String name, Attributes atts, DataSourceInfo driverInfo) 278 throws SAXException { 279 logObj.log(logLevel, "loading user name and password."); 280 driverInfo.setUserName(atts.getValue("userName")); 281 driverInfo.setPassword(atts.getValue("password")); 282 } 283 } 284 285 private class ConnectionHandler extends AbstractHandler { 286 287 293 public ConnectionHandler(XMLReader parser, ContentHandler parentHandler) { 294 super(parser, parentHandler); 295 } 296 297 public void init(String name, Attributes atts, DataSourceInfo driverInfo) 298 throws SAXException { 299 try { 300 String min = atts.getValue("min"); 301 if (min != null) 302 driverInfo.setMinConnections(Integer.parseInt(min)); 303 304 String max = atts.getValue("max"); 305 if (max != null) 306 driverInfo.setMaxConnections(Integer.parseInt(max)); 307 } 308 catch (NumberFormatException nfex) { 309 logObj.log(logLevel, "Error loading numeric attribute", nfex); 310 throw new SAXException ("Error reading numeric attribute.", nfex); 311 } 312 } 313 } 314 } | Popular Tags |