View Javadoc

1   package org.naftulin.configmgr.parsers;
2   
3   import java.net.URL;
4   import java.sql.Connection;
5   import java.sql.PreparedStatement;
6   import java.sql.ResultSet;
7   import java.sql.SQLException;
8   import java.util.HashMap;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Properties;
12  
13  import javax.naming.InitialContext;
14  import javax.naming.NamingException;
15  import javax.sql.DataSource;
16  
17  import org.apache.log4j.Logger;
18  import org.naftulin.configmgr.ConfigurationManagementEntry;
19  import org.naftulin.configmgr.ConfigurationManagementEntryImpl;
20  import org.naftulin.configmgr.ConfigurationManagerException;
21  import org.naftulin.configmgr.ConfigurationType;
22  import org.naftulin.configmgr.content.NameValuePairImpl;
23  
24  /*
25   * 
26   */
27  public class DbJndiParserImpl extends AbstractJndiParser implements ConfigEntryParser {
28  	private static final Logger log = Logger.getLogger(DbJndiParserImpl.class);
29  	
30  	private static final long serialVersionUID = 1L;
31  	private final String sql;
32  	private final String keyColumnName;
33  	private final String valueColumnName;
34  	
35  	 
36  
37  	public DbJndiParserImpl(final String jndiName, final String initialContextFactory, final String sql, 
38  			final String keyColumnName, final String valueColumnName, final List<NameValuePairImpl> nameValuePairs) {
39  		super(jndiName, initialContextFactory, nameValuePairs);
40  		this.sql = sql;
41  		this.keyColumnName = keyColumnName;
42  		this.valueColumnName = valueColumnName;
43  	}
44  	
45  	/***
46  	 * Returns configuratoin management entry that contains a Map with key-value pairs read from the database based on the sql specified.
47  	 * The steps are: first database connection is established by looking up the database connection in JNDI based on JNDI name,
48  	 * JNDI Context factory if provided and other parameters as provided in cofiguration description. 
49  	 * Second sql provided is executed against the database connection and lastly the results are read based on the columns provided in the
50  	 * configuration.
51  	 * @param key configuration management key
52  	 * @param fileUrl file url is null, since database configuration is not file URL based.
53  	 * @return Configuration management entry.
54  	 */
55  	public ConfigurationManagementEntry getConfigurationManagementEntry(
56  			final String key, final URL fileUrl) throws ConfigurationManagerException {
57  		ConfigurationManagementEntry entry = null;
58  		// at this point connect to the database, and get the info
59  		validateParameters(key);
60  		
61  		
62  		final Properties jndiProperties = new Properties();
63  		prepareJndiProperties(jndiProperties);
64  		
65  		Connection c = null;
66  		PreparedStatement stmt = null;
67  		ResultSet rs = null;
68  		try {
69  			InitialContext context = null;
70  			context = getJndiContext(key, jndiProperties, context);
71  			log.info("Initial context created for JNDI name " + jndiName);
72  			
73  			c = getJdbcConnection(key, context);
74  			log.info("Connected to the database by JNDI name " + jndiName + " and sql " + sql);
75  			
76  			stmt = c.prepareStatement(sql);
77  			log.debug("Statment perpared " + sql + " for database jndi name " + jndiName);
78  			
79  			rs = stmt.executeQuery();
80  			log.debug("Received result set for sql " + sql);
81  			
82  			entry = createEntryBasedOnNameValuePairs(key, rs);
83  			log.info("configuration management entry created for key " + key + " with sql " + sql);
84  		} catch (SQLException e) {
85  			log.error("Could not connect to the database using jndi name: " + jndiName + " sql " + sql + " and other parameters from configuration " + key, e);
86  			throw new ConfigurationManagerException("Could not connect to the database using jndiName: " + jndiName + " sql " + sql + " and other parameters from configuration " + key, e);
87  		} finally {
88  			DBUtils.closeResultSet(rs);
89  			DBUtils.closeStatement(stmt);
90  			DBUtils.closeConnection(c);
91  		}
92  		
93  		return entry;
94  	}
95  
96  	private ConfigurationManagementEntry createEntryBasedOnNameValuePairs(
97  			final String key, final ResultSet rs) throws SQLException {
98  		ConfigurationManagementEntry entry;
99  		final Map<String, String> configuration = new HashMap<String, String>();
100 		String mapKey = null;
101 		String mapValue = null;
102 		while(rs.next()) {
103 			mapKey = rs.getString(keyColumnName);
104 			mapValue = rs.getString(valueColumnName);
105 			log.debug("getting key " + mapKey + " value " + mapValue + " for sql " + sql);
106 			configuration.put(mapKey, mapValue);
107 		}
108 		final String fileName = "jndiName : " + jndiName +  " sql " + sql;
109 		//construct the configuration entry
110 		entry = new ConfigurationManagementEntryImpl(key, fileName, configuration, this, ConfigurationType.DB_JNDI);
111 		return entry;
112 	}
113 
114 	private Connection getJdbcConnection(final String key, final InitialContext context) throws SQLException, ConfigurationManagerException {
115 		Connection c = null;
116 		try {
117 			final DataSource dc = (DataSource) context.lookup(jndiName);
118 			c = dc.getConnection();
119 		} catch (NamingException e) {
120 			log.error("Could not lookup jndi name: " + jndiName + " sql " + sql + " and other parameters from configuration " + key, e);
121 			throw new ConfigurationManagerException("Could not lookup jndi name: " + jndiName + " sql " + sql + " and other parameters from configuration " + key, e);
122 		}
123 		return c;
124 	}
125 
126 	/***
127 	 * Validates that key, jndi name, sql, etc are not null parameters 
128 	 * @param key
129 	 * @throws ConfigurationManagerException
130 	 */
131 	protected void validateParameters(final String key) throws ConfigurationManagerException {
132 		super.validateParameters(key);
133 		if (sql == null) {
134 			throw new ConfigurationManagerException("sql is null, please provide sql in you master configuraton file for external cofiguraton with key =" + key);
135 		}
136 		if (keyColumnName == null) {
137 			throw new ConfigurationManagerException("keyColumnName is null, please provide key column name in you master configuraton file for external cofiguraton with key =" + key);
138 		}
139 		if (valueColumnName == null) {
140 			throw new ConfigurationManagerException("valueColumnName is null, please provide valueColumnName in you master configuraton file for external cofiguraton with key =" + key);
141 		}
142 	}
143 
144 
145 
146 }