1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.core.database;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import javax.naming.NamingException;
22 import javax.sql.DataSource;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.kuali.rice.core.config.Config;
26 import org.kuali.rice.core.config.ConfigContext;
27 import org.kuali.rice.core.config.ConfigurationException;
28 import org.kuali.rice.core.lifecycle.Lifecycle;
29 import org.kuali.rice.core.util.RiceConstants;
30 import org.springframework.beans.factory.config.AbstractFactoryBean;
31 import org.springframework.jndi.JndiTemplate;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class PrimaryDataSourceFactoryBean extends AbstractFactoryBean {
59
60 private static final String DEFAULT_DATASOURCE_PARAM = RiceConstants.DATASOURCE_OBJ;
61 private static final String DEFAULT_SERVER_DATASOURCE_PARAM = RiceConstants.SERVER_DATASOURCE_OBJ;
62 private static final String DEFAULT_NONTRANSACTIONAL_DATASOURCE_PARAM = RiceConstants.NON_TRANSACTIONAL_DATASOURCE_OBJ;
63 private static final String DEFAULT_DATASOURCE_JNDI_PARAM = RiceConstants.DATASOURCE_JNDI;
64 private static final String DEFAULT_SERVER_DATASOURCE_JNDI_PARAM = RiceConstants.SERVER_DATASOURCE_JNDI;
65 private static final String DEFAULT_NONTRANSACTIONAL_DATASOURCE_JNDI_PARAM = RiceConstants.NON_TRANSACTIONAL_DATASOURCE_JNDI;
66
67 private JndiTemplate jndiTemplate;
68 private boolean nonTransactionalDataSource = false;
69 private String defaultDataSourceParam = DEFAULT_DATASOURCE_PARAM;
70 private String defaultNonTransactionalDataSourceParam = DEFAULT_NONTRANSACTIONAL_DATASOURCE_PARAM;
71 private String defaultDataSourceJndiParam = DEFAULT_DATASOURCE_JNDI_PARAM;
72 private String defaultNonTransactionalDataSourceJndiParam = DEFAULT_NONTRANSACTIONAL_DATASOURCE_JNDI_PARAM;
73 private List<String> preferredDataSourceParams = new ArrayList<String>();
74 private List<String> preferredDataSourceJndiParams = new ArrayList<String>();
75 private boolean serverDataSource = false;
76 private boolean nullAllowed = false;
77
78 public PrimaryDataSourceFactoryBean() {
79 setSingleton(true);
80 }
81
82 public Class<DataSource> getObjectType() {
83 return DataSource.class;
84 }
85
86 @Override
87 public void afterPropertiesSet() throws Exception {
88 if (serverDataSource) {
89 getPreferredDataSourceParams().add(DEFAULT_SERVER_DATASOURCE_PARAM);
90 getPreferredDataSourceJndiParams().add(DEFAULT_SERVER_DATASOURCE_JNDI_PARAM);
91 }
92 super.afterPropertiesSet();
93 }
94
95 @Override
96 protected Object createInstance() throws Exception {
97 Config config = ConfigContext.getCurrentContextConfig();
98 DataSource dataSource = createDataSource(config);
99 if (dataSource == null && !isNullAllowed()) {
100 throw new ConfigurationException("Failed to configure the Primary Data Source.");
101 }
102 return dataSource;
103 }
104
105 protected String getDefaultDataSourceParamByType() {
106 return (nonTransactionalDataSource) ? getDefaultNonTransactionalDataSourceParam() : getDefaultDataSourceParam();
107 }
108
109 protected String getDefaultDataSourceJndiParamByType() {
110 return (nonTransactionalDataSource) ? getDefaultNonTransactionalDataSourceJndiParam() : getDefaultDataSourceJndiParam();
111 }
112
113 protected DataSource createDataSource(Config config) throws Exception {
114 DataSource dataSource = loadPreferredDataSourceFromConfig(config);
115 if (dataSource == null) {
116
117 Object dataSourceObject = config.getObject(getDefaultDataSourceParamByType());
118 if (dataSourceObject != null) {
119 validateDataSource(getDefaultDataSourceParamByType(), dataSourceObject);
120 dataSource = (DataSource) dataSourceObject;
121 } else {
122 dataSource = getDataSourceFromJndi(config, getDefaultDataSourceJndiParamByType());
123 }
124 }
125 return dataSource;
126 }
127
128 protected DataSource loadPreferredDataSourceFromConfig(Config config) {
129 for (String dataSourceParam : getPreferredDataSourceParams()) {
130 Object dataSource = config.getObject(dataSourceParam);
131 if (dataSource != null) {
132 validateDataSource(dataSourceParam, dataSource);
133 return (DataSource) dataSource;
134 }
135 }
136 if (this.jndiTemplate == null) {
137 this.jndiTemplate = new JndiTemplate();
138 }
139 for (String dataSourceJndiParam : getPreferredDataSourceJndiParams()) {
140 DataSource dataSource = getDataSourceFromJndi(config, dataSourceJndiParam);
141 if (dataSource != null) {
142 return dataSource;
143 }
144 }
145 return null;
146 }
147
148 protected void validateDataSource(String paramName, Object dataSourceObject) {
149 if (!(dataSourceObject instanceof DataSource)) {
150 throw new ConfigurationException("DataSource configured for parameter '" + paramName + "' was not an instance of DataSource. Was instead " + dataSourceObject.getClass().getName());
151 }
152 }
153
154 protected DataSource getDataSourceFromJndi(Config config, String dataSourceJndiParam) {
155 String jndiName = config.getProperty(dataSourceJndiParam);
156 if (!StringUtils.isBlank(jndiName)) {
157 try {
158 Object dataSource = getJndiTemplate().lookup(jndiName, DataSource.class);
159 if (dataSource != null) {
160 validateDataSource(dataSourceJndiParam, dataSource);
161 return (DataSource) dataSource;
162 }
163 } catch (NamingException e) {
164 throw new ConfigurationException("Could not locate the DataSource at the given JNDI location: '" + jndiName + "'", e);
165 }
166 }
167 return null;
168 }
169
170 protected void destroyInstance(Object instance) throws Exception {
171 if (instance instanceof Lifecycle) {
172 ((Lifecycle) instance).stop();
173 }
174 }
175
176 protected String getStringProperty(Config config, String propertyName) {
177 String data = config.getProperty(propertyName);
178 if (StringUtils.isEmpty(data)) {
179 throw new ConfigurationException("Could not locate a value for the given property '" + propertyName + "'.");
180 }
181 return data;
182 }
183
184 protected int getIntProperty(Config config, String propertyName) {
185 String data = getStringProperty(config, propertyName);
186 try {
187 int intData = Integer.parseInt(data);
188 return intData;
189 } catch (NumberFormatException e) {
190 throw new ConfigurationException("The given property '" + propertyName + "' was not a valid integer. Value was '" + data + "'");
191 }
192 }
193
194 public JndiTemplate getJndiTemplate() {
195 return this.jndiTemplate;
196 }
197
198 public void setJndiTemplate(JndiTemplate jndiTemplate) {
199 this.jndiTemplate = jndiTemplate;
200 }
201
202 public String getDefaultDataSourceJndiParam() {
203 return defaultDataSourceJndiParam;
204 }
205
206 public void setDefaultDataSourceJndiParam(String defaultDataSourceJndiParam) {
207 this.defaultDataSourceJndiParam = defaultDataSourceJndiParam;
208 }
209
210 public String getDefaultNonTransactionalDataSourceJndiParam() {
211 return defaultNonTransactionalDataSourceJndiParam;
212 }
213
214 public void setDefaultNonTransactionalDataSourceJndiParam(String defaultNonTransactionalDataSourceJndiParam) {
215 this.defaultNonTransactionalDataSourceJndiParam = defaultNonTransactionalDataSourceJndiParam;
216 }
217
218 public String getDefaultDataSourceParam() {
219 return defaultDataSourceParam;
220 }
221
222 public void setDefaultDataSourceParam(String defaultDataSourceParam) {
223 this.defaultDataSourceParam = defaultDataSourceParam;
224 }
225
226 public String getDefaultNonTransactionalDataSourceParam() {
227 return defaultNonTransactionalDataSourceParam;
228 }
229
230 public void setDefaultNonTransactionalDataSourceParam(String defaultNonTransactionalDataSourceParam) {
231 this.defaultNonTransactionalDataSourceParam = defaultNonTransactionalDataSourceParam;
232 }
233
234 public List<String> getPreferredDataSourceJndiParams() {
235 return preferredDataSourceJndiParams;
236 }
237
238 public void setPreferredDataSourceJndiParams(List<String> preferredDataSourceJndiParams) {
239 this.preferredDataSourceJndiParams = preferredDataSourceJndiParams;
240 }
241
242 public List<String> getPreferredDataSourceParams() {
243 return preferredDataSourceParams;
244 }
245
246 public void setPreferredDataSourceParams(List<String> preferredDataSourceParams) {
247 this.preferredDataSourceParams = preferredDataSourceParams;
248 }
249
250 public void setNonTransactionalDataSource(boolean nonTransactionalDataSource) {
251 this.nonTransactionalDataSource = nonTransactionalDataSource;
252 }
253
254 public boolean isServerDataSource() {
255 return this.serverDataSource;
256 }
257
258 public void setServerDataSource(boolean serverDataSource) {
259 this.serverDataSource = serverDataSource;
260 }
261
262 public boolean isNullAllowed() {
263 return this.nullAllowed;
264 }
265
266 public void setNullAllowed(boolean nullAllowed) {
267 this.nullAllowed = nullAllowed;
268 }
269
270 }