View Javadoc

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