package edu.internet2.middleware.shibboleth.aa.attrresolv.provider;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
import java.security.Principal;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
-
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.log4j.Logger;
+import org.apache.log4j.Priority;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class JDBCDataConnector extends BaseResolutionPlugIn implements DataConnectorPlugIn {
- private static Logger log = Logger.getLogger(JDBCDataConnector.class.getName());
- private Properties props = new Properties();
- private String searchVal = null;
- private String aeClassName = null;
-
- final private static String QueryAtt = "query";
- final private static String AttributeExtractorAtt = "attributeExtractor";
- final private static String DBDriverAtt = "dbDriver";
- final private static String AEInstanceMethodAtt = "instance";
- final private static String URLAtt = "dbURL";
-
- public JDBCDataConnector(Element e) throws ResolutionPlugInException {
-
- super(e);
-
- NodeList propertiesNode = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Property");
- NodeList searchNode = e.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Search");
-
- /**
- * Gets and sets the search parameter and the attribute extractor
- */
- searchVal = ((Element) searchNode.item(0)).getAttribute(QueryAtt);
- aeClassName = ((Element) searchNode.item(0)).getAttribute(AttributeExtractorAtt);
-
- if (searchVal == null || searchVal.equals("")) {
- Node tnode = searchNode.item(0).getFirstChild();
- if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
- searchVal = tnode.getNodeValue();
- }
- if (searchVal == null || searchVal.equals("")) {
- log.error("Search requires a specified query field");
- throw new ResolutionPlugInException("mySQLDataConnection requires a \"Search\" specification");
- }
- }
- else {
- log.debug("Search Query: (" + searchVal + ")");
- }
-
- /**
- * Assigns the property attribute name/value pairs to a hashtable
- */
- for (int i = 0; propertiesNode.getLength() > i; i++) {
- Element property = (Element) propertiesNode.item(i);
- String propertiesName = property.getAttribute("name");
- String propertiesValue = property.getAttribute("value");
-
- if (propertiesName != null
- && !propertiesName.equals("")
- && propertiesValue != null
- && !propertiesValue.equals("")) {
- props.setProperty(propertiesName, propertiesValue);
- log.debug("Property: (" + propertiesName + ")");
- log.debug(" Value: (" + propertiesValue + ")");
- } else {
- log.error("Property is malformed.");
- throw new ResolutionPlugInException("Property is malformed.");
- }
- }
-
- if (props.getProperty(URLAtt) == null) {
- log.error("JDBC connection requires a dbURL property");
- throw new ResolutionPlugInException("JDBCDataConnection requires a \"dbURL\" property");
- }
- }
-
- protected String substitute(String source, String pattern, boolean quote, Dependencies depends) {
- Matcher m=Pattern.compile(pattern).matcher(source);
- while (m.find()) {
- String field = source.substring(m.start()+1, m.end()-1);
- if (field != null && field.length() > 0) {
- StringBuffer buf = new StringBuffer();
-
- //Look for an attribute dependency.
- ResolverAttribute dep = depends.getAttributeResolution(field);
- if (dep != null) {
- Iterator iter=dep.getValues();
- while (iter.hasNext()) {
- if (buf.length() > 0)
- buf = buf.append(',');
- if (quote)
- buf = buf.append("'");
- buf = buf.append(iter.next());
- if (quote)
- buf = buf.append("'");
- }
- }
-
- //If no values found, cycle over the connectors.
- Iterator connDeps = connectorDependencyIds.iterator();
- while (buf.length() == 0 && connDeps.hasNext()) {
- Attributes attrs = depends.getConnectorResolution((String)connDeps.next());
- if (attrs != null) {
- Attribute attr = attrs.get(field);
- if (attr != null) {
- try {
- NamingEnumeration vals = attr.getAll();
- while (vals.hasMore()) {
- if (buf.length() > 0)
- buf = buf.append(',');
- if (quote)
- buf = buf.append("'");
- buf = buf.append(vals.next());
- if (quote)
- buf = buf.append("'");
- }
- }
- catch (NamingException e) {
- // Auto-generated catch block
- }
- }
- }
- }
-
- if (buf.length() == 0) {
- log.warn("Unable to find any values to substitute in query for " + field + ", so using the empty string");
- }
- source = source.replaceAll(m.group(), buf.toString());
- m.reset(source);
- }
- }
- return source;
- }
-
- public Attributes resolve(Principal principal, String requester, Dependencies depends) throws ResolutionPlugInException {
- Connection conn = null;
- ResultSet rs = null;
- JDBCAttributeExtractor aeClassObj = null;
-
- log.debug("Resolving connector: (" + getId() + ")");
- log.debug(getId() + " resolving for principal: (" + principal.getName() + ")");
- log.debug("The query string before inserting substitutions: " + searchVal);
-
- //Replaces %PRINCIPAL% in the query string with its value
- String convertedSearchVal = searchVal.replaceAll("%PRINCIPAL%", principal.getName());
- convertedSearchVal = convertedSearchVal.replaceAll("@PRINCIPAL@", "'" + principal.getName() + "'");
-
- //Find all delimited substitutions and replace with the named attribute value(s).
- convertedSearchVal = substitute(convertedSearchVal,"%.+%",false,depends);
- convertedSearchVal = substitute(convertedSearchVal,"@.+@",true,depends);
-
- //Replace any escaped substitution delimiters.
- convertedSearchVal = convertedSearchVal.replaceAll("\\%","%");
- convertedSearchVal = convertedSearchVal.replaceAll("\\@","@");
-
- log.debug("The query string after inserting substitutions: " + convertedSearchVal);
-
- try {
- //Loads the database driver
- loadDriver((String) props.get(DBDriverAtt));
- } catch (ClassNotFoundException e) {
- log.error("An ClassNotFoundException occured while loading database driver");
- throw new ResolutionPlugInException(
- "An ClassNotFoundException occured while loading database driver: " + e.getMessage());
- } catch (IllegalAccessException e) {
- log.error("An IllegalAccessException occured while loading database driver");
- throw new ResolutionPlugInException(
- "An IllegalAccessException occured while loading database driver: " + e.getMessage());
- } catch (InstantiationException e) {
- log.error("An InstantionException occured while loading database driver");
- throw new ResolutionPlugInException(
- "An InstantiationException occured while loading database driver: " + e.getMessage());
- }
-
- try {
- //Makes the connection to the database
- conn = connect();
- } catch (SQLException e) {
- log.error("An ERROR occured while connecting to database");
- throw new ResolutionPlugInException("An ERROR occured while connecting to the database: " + e.getMessage());
- }
-
- try {
- //Gets the results set for the query
- rs = executeQuery(conn, convertedSearchVal);
- if (!rs.next())
- return new BasicAttributes();
-
- } catch (SQLException e) {
- log.error("An ERROR occured while executing the query");
- throw new ResolutionPlugInException("An ERROR occured while executing the query: " + e.getMessage());
- }
-
- /**
- * If the user has supplied their own class for extracting the attributes from the
- * result set, then their class will be run. A BasicAttributes object is expected as
- * the result of the extraction.
- *
- * If the user has no supplied their own class for extracting the attributes then
- * the default extraction is run, which is specified in DefaultAEAtt.
- */
- if (aeClassName == null || aeClassName.equals("")) {
- aeClassName = DefaultAE.class.getName();
- }
-
- try {
- Class aeClass = Class.forName(aeClassName);
- Method aeMethod = aeClass.getMethod(AEInstanceMethodAtt, null);
-
- //runs the "instance" method returning and instance of the object
- aeClassObj = (JDBCAttributeExtractor) (aeMethod.invoke(null, null));
- log.debug("Supplied attributeExtractor class loaded.");
-
- } catch (ClassNotFoundException e) {
- log.error("The supplied attribute extractor class could not be found");
- throw new ResolutionPlugInException(
- "The supplied attribute extractor class could not be found: " + e.getMessage());
- } catch (NoSuchMethodException e) {
- log.error("The requested method does not exist");
- throw new ResolutionPlugInException("The requested method does not exist: " + e.getMessage());
- } catch (IllegalAccessException e) {
- log.error("Access is not permitted for invoking requested method");
- throw new ResolutionPlugInException(
- "Access is not permitted for invoking requested method: " + e.getMessage());
- } catch (InvocationTargetException e) {
- log.error("An ERROR occured invoking requested method");
- throw new ResolutionPlugInException("An ERROR occured involking requested method: " + e.getMessage());
- }
-
- try {
- return aeClassObj.extractAttributes(rs);
-
- } catch (JDBCAttributeExtractorException e) {
- log.error("An ERROR occured while extracting attributes from result set");
- throw new ResolutionPlugInException(
- "An ERROR occured while extracting attributes from result set: " + e.getMessage());
- } finally {
- try {
- //release result set
- rs.close();
- log.debug("Result set released");
- } catch (SQLException e) {
- log.error("An error occured while closing the result set: " + e);
- throw new ResolutionPlugInException("An error occured while closing the result set: " + e);
- }
-
- try {
- //close the connection
- conn.close();
- log.debug("Connection to database closed");
- } catch (SQLException e) {
- log.error("An error occured while closing the database connection: " + e);
- throw new ResolutionPlugInException("An error occured while closing the database connection: " + e);
- }
- }
- }
-
- /**
- * Loads the driver used to access the database
- * @param driver The driver used to access the database
- * @throws ResolutionPlugInException If there is a failure to load the driver
- */
- public void loadDriver(String driver)
- throws ClassNotFoundException, IllegalAccessException, InstantiationException {
- Class.forName(driver).newInstance();
- log.debug("Loading driver: " + driver);
- }
-
- /**
- * Makes a connection to the database using the property set.
- * @return Connection object
- * @throws SQLException If there is a failure to make a database connection
- */
- public Connection connect()
- throws SQLException {
- String url = props.getProperty(URLAtt);
- log.debug(url);
- Connection conn = DriverManager.getConnection(url,props);
- log.debug("Connection with database established");
-
- return conn;
- }
-
- /**
- * Execute the users query
- * @param query The query the user wishes to execute
- * @return The result of the users <code>query</code>
- * @return null if an error occurs during execution
- * @throws SQLException If an error occurs while executing the query
- */
- public ResultSet executeQuery(Connection conn, String query) throws SQLException {
- log.debug("Users Query: " + query);
- Statement stmt = conn.createStatement();
- return stmt.executeQuery(query);
- }
+ private static Logger log = Logger.getLogger(JDBCDataConnector.class.getName());
+ protected Properties props = new Properties();
+ protected String searchVal;
+ protected DataSource dataSource;
+ protected JDBCAttributeExtractor extractor;
+
+ public JDBCDataConnector(Element element) throws ResolutionPlugInException {
+
+ super(element);
+
+ //Get the query string
+ NodeList searchNode = element.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Search");
+ searchVal = ((Element) searchNode.item(0)).getAttribute("query");
+
+ if (searchVal == null || searchVal.equals("")) {
+ Node tnode = searchNode.item(0).getFirstChild();
+ if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
+ searchVal = tnode.getNodeValue();
+ }
+ if (searchVal == null || searchVal.equals("")) {
+ log.error("Search requires a specified query field");
+ //TODO stinky error message
+ throw new ResolutionPlugInException("mySQLDataConnection requires a \"Search\" specification");
+ }
+ } else {
+ log.debug("Search Query: (" + searchVal + ")");
+ }
+
+ //Instantiate an attribute extractor, using the default if none is specified
+ String aeClassName = ((Element) searchNode.item(0)).getAttribute("attributeExtractor");
+ if (aeClassName == null || aeClassName.equals("")) {
+ aeClassName = DefaultAE.class.getName();
+ }
+ try {
+ Class aeClass = Class.forName(aeClassName);
+ Constructor constructor = aeClass.getConstructor(null);
+ extractor = (JDBCAttributeExtractor) constructor.newInstance(null);
+ log.debug("Supplied attributeExtractor class loaded.");
+
+ } catch (ClassNotFoundException e) {
+ log.error("The supplied Attribute Extractor class could not be found: " + e);
+ throw new ResolutionPlugInException(
+ "The supplied Attribute Extractor class could not be found: " + e.getMessage());
+ } catch (Exception e) {
+ log.error("Unable to instantiate Attribute Extractor implementation: " + e);
+ throw new ResolutionPlugInException(
+ "Unable to instantiate Attribute Extractor implementation: " + e.getMessage());
+ }
+
+ //Grab all other properties
+ NodeList propertiesNode = element.getElementsByTagNameNS(AttributeResolver.resolverNamespace, "Property");
+ for (int i = 0; propertiesNode.getLength() > i; i++) {
+ Element property = (Element) propertiesNode.item(i);
+ String propertiesName = property.getAttribute("name");
+ String propertiesValue = property.getAttribute("value");
+
+ if (propertiesName != null
+ && !propertiesName.equals("")
+ && propertiesValue != null
+ && !propertiesValue.equals("")) {
+ props.setProperty(propertiesName, propertiesValue);
+ log.debug("Property: (" + propertiesName + ")");
+ log.debug(" Value: (" + propertiesValue + ")");
+ } else {
+ log.error("Property is malformed.");
+ throw new ResolutionPlugInException("Property is malformed.");
+ }
+ }
+
+ if (props.getProperty("dbURL") == null) {
+ log.error("JDBC connection requires a dbURL property");
+ throw new ResolutionPlugInException("JDBCDataConnection requires a \"dbURL\" property");
+ }
+
+ //Load the supplied JDBC driver
+ loadDriver((String) props.get("dbDriver"));
+
+ //Setup the Pool
+ GenericObjectPool genericObjectPool = new GenericObjectPool(null);
+
+ try {
+ if (props.getProperty("maxActiveConnections") != null) {
+ genericObjectPool.setMaxActive(Integer.parseInt(props.getProperty("maxActiveConnections")));
+ }
+ if (props.getProperty("maxIdleConnections") != null) {
+ genericObjectPool.setMaxIdle(Integer.parseInt(props.getProperty("maxIdleConnections")));
+ }
+ } catch (NumberFormatException e) {
+ log.error("Malformed pooling configuration settings: using defaults.");
+ }
+ genericObjectPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
+
+ ObjectPool connPool = genericObjectPool;
+ ConnectionFactory connFactory = null;
+ PoolableConnectionFactory poolConnFactory = null;
+
+ try {
+ connFactory = new DriverManagerConnectionFactory(props.getProperty("dbURL"), null);
+ log.debug("Connection factory initialized.");
+ } catch (Exception ex) {
+ log.error(
+ "Connection factory couldn't be initialized, ensure database URL, username and password are correct.");
+ throw new ResolutionPlugInException("Connection facotry couldn't be initialized: " + ex.getMessage());
+ }
+
+ try {
+ poolConnFactory = new PoolableConnectionFactory(connFactory, connPool, null, null, false, true);
+ } catch (Exception ex) {
+ log.debug("Poolable connection factory error");
+ }
+
+ dataSource = new PoolingDataSource(connPool);
+ try {
+ dataSource.setLogWriter(
+ new Log4jPrintWriter(Logger.getLogger(JDBCDataConnector.class.getName() + ".Pool"), Priority.DEBUG));
+ } catch (SQLException e) {
+ log.error("Coudn't setup logger for database connection pool.");
+ }
+ }
+
+ protected String substitute(String source, String pattern, boolean quote, Dependencies depends) {
+ Matcher m = Pattern.compile(pattern).matcher(source);
+ while (m.find()) {
+ String field = source.substring(m.start() + 1, m.end() - 1);
+ if (field != null && field.length() > 0) {
+ StringBuffer buf = new StringBuffer();
+
+ //Look for an attribute dependency.
+ ResolverAttribute dep = depends.getAttributeResolution(field);
+ if (dep != null) {
+ Iterator iter = dep.getValues();
+ while (iter.hasNext()) {
+ if (buf.length() > 0)
+ buf = buf.append(',');
+ if (quote)
+ buf = buf.append("'");
+ buf = buf.append(iter.next());
+ if (quote)
+ buf = buf.append("'");
+ }
+ }
+
+ //If no values found, cycle over the connectors.
+ Iterator connDeps = connectorDependencyIds.iterator();
+ while (buf.length() == 0 && connDeps.hasNext()) {
+ Attributes attrs = depends.getConnectorResolution((String) connDeps.next());
+ if (attrs != null) {
+ Attribute attr = attrs.get(field);
+ if (attr != null) {
+ try {
+ NamingEnumeration vals = attr.getAll();
+ while (vals.hasMore()) {
+ if (buf.length() > 0)
+ buf = buf.append(',');
+ if (quote)
+ buf = buf.append("'");
+ buf = buf.append(vals.next());
+ if (quote)
+ buf = buf.append("'");
+ }
+ } catch (NamingException e) {
+ // Auto-generated catch block
+ }
+ }
+ }
+ }
+
+ if (buf.length() == 0) {
+ log.warn(
+ "Unable to find any values to substitute in query for "
+ + field
+ + ", so using the empty string");
+ }
+ source = source.replaceAll(m.group(), buf.toString());
+ m.reset(source);
+ }
+ }
+ return source;
+ }
+
+ public Attributes resolve(Principal principal, String requester, Dependencies depends)
+ throws ResolutionPlugInException {
+
+ log.debug("Resolving connector: (" + getId() + ")");
+ log.debug(getId() + " resolving for principal: (" + principal.getName() + ")");
+ log.debug("The query string before inserting substitutions: " + searchVal);
+
+ //Replaces %PRINCIPAL% in the query string with its value
+ String convertedSearchVal = searchVal.replaceAll("%PRINCIPAL%", principal.getName());
+ convertedSearchVal = convertedSearchVal.replaceAll("@PRINCIPAL@", "'" + principal.getName() + "'");
+
+ //Find all delimited substitutions and replace with the named attribute value(s).
+ convertedSearchVal = substitute(convertedSearchVal, "%.+%", false, depends);
+ convertedSearchVal = substitute(convertedSearchVal, "@.+@", true, depends);
+
+ //Replace any escaped substitution delimiters.
+ convertedSearchVal = convertedSearchVal.replaceAll("\\%", "%");
+ convertedSearchVal = convertedSearchVal.replaceAll("\\@", "@");
+
+ log.debug("The query string after inserting substitutions: " + convertedSearchVal);
+
+ /**
+ * Retrieves a connection from the connection pool
+ */
+ Connection conn = null;
+ try {
+ conn = dataSource.getConnection();
+ log.debug("Connection retrieved from pool");
+ } catch (Exception e) {
+ log.error("Unable to fetch a connection from the pool");
+ throw new ResolutionPlugInException("Unable to fetch a connection from the pool: " + e.getMessage());
+ }
+ if (conn == null) {
+ log.error("Pool didn't return a propertly initialized connection.");
+ throw new ResolutionPlugInException("Pool didn't return a propertly initialized connection.");
+ }
+
+ ResultSet rs = null;
+ try {
+ //Gets the results set for the query
+ rs = executeQuery(conn, convertedSearchVal);
+ if (!rs.next())
+ return new BasicAttributes();
+
+ } catch (SQLException e) {
+ log.error("An ERROR occured while executing the query");
+ throw new ResolutionPlugInException("An ERROR occured while executing the query: " + e.getMessage());
+ }
+
+ try {
+ return extractor.extractAttributes(rs);
+
+ } catch (JDBCAttributeExtractorException e) {
+ log.error("An ERROR occured while extracting attributes from result set");
+ throw new ResolutionPlugInException(
+ "An ERROR occured while extracting attributes from result set: " + e.getMessage());
+ } finally {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ log.error("An error occured while closing the result set: " + e);
+ throw new ResolutionPlugInException("An error occured while closing the result set: " + e);
+ }
+
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ log.error("An error occured while closing the database connection: " + e);
+ throw new ResolutionPlugInException("An error occured while closing the database connection: " + e);
+ }
+ }
+ }
+
+ /**
+ * Loads the driver used to access the database
+ * @param driver The driver used to access the database
+ * @throws ResolutionPlugInException If there is a failure to load the driver
+ */
+ public void loadDriver(String driver) throws ResolutionPlugInException {
+ try {
+ Class.forName(driver).newInstance();
+ log.debug("Loading JDBC driver: " + driver);
+ } catch (Exception e) {
+ log.error("An error loading database driver: " + e);
+ throw new ResolutionPlugInException(
+ "An IllegalAccessException occured while loading database driver: " + e.getMessage());
+ }
+ log.debug("Driver loaded.");
+ }
+
+ /**
+ * Execute the users query
+ * @param query The query the user wishes to execute
+ * @return The result of the users <code>query</code>
+ * @return null if an error occurs during execution
+ * @throws SQLException If an error occurs while executing the query
+ */
+ public ResultSet executeQuery(Connection conn, String query) throws SQLException {
+ log.debug("Users Query: " + query);
+ Statement stmt = conn.createStatement();
+ return stmt.executeQuery(query);
+ }
+
+ private class Log4jPrintWriter extends PrintWriter {
+
+ private Priority level;
+ private Logger logger;
+ private StringBuffer text = new StringBuffer("");
+
+ private Log4jPrintWriter(Logger logger, org.apache.log4j.Priority level) {
+ super(System.err);
+ this.level = level;
+ this.logger = logger;
+ }
+
+ public void close() {
+ flush();
+ }
+
+ public void flush() {
+ if (!text.toString().equals("")) {
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+ }
+
+ public void print(boolean b) {
+ text.append(b);
+ }
+
+ public void print(char c) {
+ text.append(c);
+ }
+
+ public void print(char[] s) {
+ text.append(s);
+ }
+
+ public void print(double d) {
+ text.append(d);
+ }
+
+ public void print(float f) {
+ text.append(f);
+ }
+
+ public void print(int i) {
+ text.append(i);
+ }
+
+ public void print(long l) {
+ text.append(l);
+ }
+
+ public void print(Object obj) {
+ text.append(obj);
+ }
+
+ public void print(String s) {
+ text.append(s);
+ }
+
+ public void println() {
+ if (!text.toString().equals("")) {
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+ }
+
+ public void println(boolean x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(char x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(char[] x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(double x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(float x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(int x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(long x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(Object x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+
+ public void println(String x) {
+ text.append(x);
+ logger.log(level, text.toString());
+ text.setLength(0);
+ }
+ }
}
/**
*/
class DefaultAE implements JDBCAttributeExtractor {
- private static DefaultAE _instance = null;
- private static Logger log = Logger.getLogger(DefaultAE.class.getName());
-
- // Constructor
- protected DefaultAE() {
- }
-
- // Ensures that only one istance of the class at a time
- public static DefaultAE instance() {
- if (_instance == null)
- return new DefaultAE();
- else
- return _instance;
- }
-
- /**
- * Method of extracting the attributes from the supplied result set.
- *
- * @param ResultSet The result set from the query which contains the attributes
- * @return BasicAttributes as objects containing all the attributes
- * @throws JDBCAttributeExtractorException If there is a complication in retrieving the attributes
- */
- public BasicAttributes extractAttributes(ResultSet rs) throws JDBCAttributeExtractorException {
- BasicAttributes attributes = new BasicAttributes();
-
- log.debug("Using default Attribute Extractor");
-
- try {
- ResultSetMetaData rsmd = rs.getMetaData();
- int numColumns = rsmd.getColumnCount();
- log.debug("Number of returned columns: " + numColumns);
-
- for (int i = 1; i <= numColumns; i++) {
- String columnName = rsmd.getColumnName(i);
- String columnType = rsmd.getColumnTypeName(i);
- Object columnValue = rs.getObject(columnName);
- log.debug(
- "(" + i + ". ColumnType = " + columnType + ") " + columnName + " -> " + (columnValue!=null ? columnValue.toString() : "(null)"));
- attributes.put(new BasicAttribute(columnName, columnValue));
- }
- }
- catch (SQLException e) {
- log.error("An ERROR occured while retrieving result set meta data");
- throw new JDBCAttributeExtractorException(
- "An ERROR occured while retrieving result set meta data: " + e.getMessage());
- }
-
- // Check for multiple rows.
- try {
- if (rs.next())
- throw new JDBCAttributeExtractorException("Query returned more than one row.");
- }
- catch (SQLException e) {
- }
-
- return attributes;
- }
+
+ private static Logger log = Logger.getLogger(DefaultAE.class.getName());
+
+ // Constructor
+ public DefaultAE() {
+ }
+
+ /**
+ * Method of extracting the attributes from the supplied result set.
+ *
+ * @param ResultSet The result set from the query which contains the attributes
+ * @return BasicAttributes as objects containing all the attributes
+ * @throws JDBCAttributeExtractorException If there is a complication in retrieving the attributes
+ */
+ public BasicAttributes extractAttributes(ResultSet rs) throws JDBCAttributeExtractorException {
+ BasicAttributes attributes = new BasicAttributes();
+
+ log.debug("Using default Attribute Extractor");
+
+ try {
+ ResultSetMetaData rsmd = rs.getMetaData();
+ int numColumns = rsmd.getColumnCount();
+ log.debug("Number of returned columns: " + numColumns);
+
+ for (int i = 1; i <= numColumns; i++) {
+ String columnName = rsmd.getColumnName(i);
+ String columnType = rsmd.getColumnTypeName(i);
+ Object columnValue = rs.getObject(columnName);
+ log.debug(
+ "("
+ + i
+ + ". ColumnType = "
+ + columnType
+ + ") "
+ + columnName
+ + " -> "
+ + (columnValue != null ? columnValue.toString() : "(null)"));
+ attributes.put(new BasicAttribute(columnName, columnValue));
+ }
+ } catch (SQLException e) {
+ log.error("An ERROR occured while retrieving result set meta data");
+ throw new JDBCAttributeExtractorException(
+ "An ERROR occured while retrieving result set meta data: " + e.getMessage());
+ }
+
+ // Check for multiple rows.
+ try {
+ if (rs.next())
+ throw new JDBCAttributeExtractorException("Query returned more than one row.");
+ } catch (SQLException e) {
+ //TODO don't squelch this error!!!
+ }
+
+ return attributes;
+ }
}