View Javadoc

1   /*
2    * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package edu.internet2.middleware.shibboleth.common.config.attribute.resolver.dataConnector;
18  
19  import java.util.List;
20  import java.util.Map;
21  
22  import javax.sql.DataSource;
23  
24  import net.sf.ehcache.Cache;
25  import net.sf.ehcache.CacheManager;
26  
27  import org.opensaml.xml.util.DatatypeHelper;
28  
29  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.RDBMSColumnDescriptor;
30  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.RDBMSDataConnector;
31  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.TemplateEngine;
32  
33  /**
34   * Spring factory bean that produces {@link RDBMSDataConnector}s.
35   */
36  public class RDBMSDataConnectorFactoryBean extends BaseDataConnectorFactoryBean {
37  
38      /** Source of connections to the database. */
39      private DataSource connectionDataSource;
40  
41      /** Template engine used to transform query templates into queries. */
42      private TemplateEngine templateEngine;
43  
44      /** SQL query template. */
45      private String queryTemplate;
46      
47      /** SQL query timeout in milliseconds. */
48      private long queryTimeout;
49  
50      /** Whether the database connections should be read-only. */
51      private boolean readOnlyConnections;
52  
53      /** Whether the SQL query uses stored procedures. */
54      private boolean queryUsesStoredProcedures;
55  
56      /** Whether an empty result set is an error. */
57      private boolean noResultsIsError;
58  
59      /** Result set column descriptors. */
60      private List<RDBMSColumnDescriptor> columnDescriptors;
61      
62      /** Whether results should be cached. */
63      private CacheManager cacheManager;
64  
65      /** Maximum number of queries to keep in the cache. */
66      private int maximumCachedElements;
67  
68      /** Length of time, in milliseconds, elements are cached. */
69      private long cacheElementTtl;
70  
71  
72      /** {@inheritDoc} */
73      public Class getObjectType() {
74          return RDBMSDataConnector.class;
75      }
76  
77      /**
78       * This returns whether this connector will throw an exception if no search results are found. The default is false.
79       * 
80       * @return <code>boolean</code>
81       */
82      public boolean isNoResultIsError() {
83          return noResultsIsError;
84      }
85  
86      /**
87       * This sets whether this connector will throw an exception if no search results are found.
88       * 
89       * @param b <code>boolean</code>
90       */
91      public void setNoResultIsError(boolean b) {
92          noResultsIsError = b;
93      }
94  
95      /**
96       * Gets the result set column descriptors.
97       * 
98       * @return result set column descriptors
99       */
100     public List<RDBMSColumnDescriptor> getColumnDescriptors() {
101         return columnDescriptors;
102     }
103 
104     /**
105      * Sets the result set column descriptors.
106      * 
107      * @param descriptors result set column descriptors
108      */
109     public void setColumnDescriptors(List<RDBMSColumnDescriptor> descriptors) {
110         columnDescriptors = descriptors;
111     }
112 
113     /**
114      * Gets the database connection source.
115      * 
116      * @return database connection source.
117      */
118     public DataSource getConnectionDataSource() {
119         return connectionDataSource;
120     }
121 
122     /**
123      * Sets the database connection source.
124      * 
125      * @param source database connection source
126      */
127     public void setConnectionDataSource(DataSource source) {
128         connectionDataSource = source;
129     }
130 
131     /**
132      * Gets the template engine used to construct the SQL query from the query template.
133      * 
134      * @return template engine used to construct the SQL query from the query template
135      */
136     public TemplateEngine getTemplateEngine() {
137         return templateEngine;
138     }
139 
140     /**
141      * Sets the template engine used to construct the SQL query from the query template.
142      * 
143      * @param engine template engine used to construct the SQL query from the query template
144      */
145     public void setTemplateEngine(TemplateEngine engine) {
146         templateEngine = engine;
147     }
148 
149     /**
150      * Gets the SQL query template.
151      * 
152      * @return SQL query template
153      */
154     public String getQueryTemplate() {
155         return queryTemplate;
156     }
157 
158     /**
159      * Sets the SQL query template.
160      * 
161      * @param template SQL query template
162      */
163     public void setQueryTemplate(String template) {
164         queryTemplate = DatatypeHelper.safeTrimOrNullString(template);
165     }
166     
167     /**
168      * Gets the timeout, in milliseconds, of the SQL query.
169      * 
170      * @return timeout, in milliseconds, of the SQL query.
171      */
172     public long getQueryTimeout() {
173         return queryTimeout;
174     }
175     
176     /**
177      * Sets the timeout, in milliseconds, of the SQL query.
178      * 
179      * @param timeout timeout, in milliseconds, of the SQL query.
180      */
181     public void setQueryTimeout(long timeout) {
182         queryTimeout = timeout;
183     }
184 
185     /**
186      * Gets whether the SQL query uses stored procedures.
187      * 
188      * @return whether the SQL query uses stored procedures
189      */
190     public boolean getQueryUsesStoredProcedures() {
191         return queryUsesStoredProcedures;
192     }
193 
194     /**
195      * Sets whether the SQL query uses stored procedures.
196      * 
197      * @param storedProcedures whether the SQL query uses stored procedures
198      */
199     public void setQueryUsesStoredProcedures(boolean storedProcedures) {
200         queryUsesStoredProcedures = storedProcedures;
201     }
202 
203     /**
204      * Gets the manager for the results cache.
205      * 
206      * @return manager for the results cache
207      */
208     public CacheManager getCacheManager() {
209         return cacheManager;
210     }
211 
212     /**
213      * Sets the manager for the results cache.
214      * 
215      * @param manager manager for the results cache
216      */
217     public void setCacheManager(CacheManager manager) {
218         cacheManager = manager;
219     }
220 
221     /**
222      * Gets the time to live, in milliseconds, for cache elements.
223      * 
224      * @return time to live, in milliseconds, for cache elements
225      */
226     public long getCacheElementTimeToLive() {
227         return cacheElementTtl;
228     }
229 
230     /**
231      * Sets the time to live, in milliseconds, for cache elements.
232      * 
233      * @param ttl time to live, in milliseconds, for cache elements
234      */
235     public void setCacheElementTimeToLive(long ttl) {
236         cacheElementTtl = ttl;
237     }
238 
239     /**
240      * Gets the maximum number of elements that will be cached.
241      * 
242      * @return maximum number of elements that will be cached
243      */
244     public int getMaximumCachedElements() {
245         return maximumCachedElements;
246     }
247 
248     /**
249      * Sets the maximum number of elements that will be cached.
250      * 
251      * @param max maximum number of elements that will be cached
252      */
253     public void setMaximumCachedElements(int max) {
254         maximumCachedElements = max;
255     }
256 
257     /**
258      * Gets whether the database connection is read-only.
259      * 
260      * @return whether the database connection is read-only
261      */
262     public boolean isReadOnlyConnections() {
263         return readOnlyConnections;
264     }
265 
266     /**
267      * Sets whether the database connection is read-only.
268      * 
269      * @param readOnly whether the database connection is read-only
270      */
271     public void setReadOnlyConnections(boolean readOnly) {
272         readOnlyConnections = readOnly;
273     }
274 
275     /** {@inheritDoc} */
276     protected Object createInstance() throws Exception {
277         Cache resultsCache = null;
278         if (cacheManager != null) {
279             resultsCache = cacheManager.getCache(getPluginId());
280             if (resultsCache == null) {
281                 long ttlInSeconds = cacheElementTtl / 1000;
282                 resultsCache = new Cache(
283                     getPluginId(), maximumCachedElements, false, false, ttlInSeconds, ttlInSeconds);
284                 cacheManager.addCache(resultsCache);
285             }
286         }
287 
288         RDBMSDataConnector connector = new RDBMSDataConnector(getConnectionDataSource(), resultsCache);
289         populateDataConnector(connector);
290         connector.registerTemplate(templateEngine, queryTemplate);
291 
292         connector.setQueryTimeout((int) (queryTimeout/1000));
293         connector.setUsesStoredProcedure(getQueryUsesStoredProcedures());
294         connector.setConnectionReadOnly(isReadOnlyConnections());
295         connector.setNoResultIsError(isNoResultIsError());
296 
297         if (getColumnDescriptors() != null) {
298             Map<String, RDBMSColumnDescriptor> columnDecriptors = connector.getColumnDescriptor();
299             for (RDBMSColumnDescriptor descriptor : getColumnDescriptors()) {
300                 columnDecriptors.put(descriptor.getColumnName(), descriptor);
301             }
302         }
303 
304         return connector;
305     }
306 }