KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > source > impl > SimpleJdbcSourceDescriptor


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
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 package org.apache.cocoon.components.source.impl;
17
18 import java.sql.Connection JavaDoc;
19 import java.sql.PreparedStatement JavaDoc;
20 import java.sql.ResultSet JavaDoc;
21 import java.sql.SQLException JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24
25 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
26 import org.apache.avalon.framework.activity.Initializable;
27 import org.apache.avalon.framework.configuration.Configurable;
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.service.ServiceException;
31 import org.apache.avalon.framework.service.ServiceManager;
32 import org.apache.avalon.framework.service.ServiceSelector;
33 import org.apache.avalon.framework.service.Serviceable;
34 import org.apache.avalon.framework.thread.ThreadSafe;
35 import org.apache.cocoon.caching.Cache;
36 import org.apache.cocoon.caching.EventAware;
37 import org.apache.cocoon.caching.validity.EventValidity;
38 import org.apache.cocoon.caching.validity.NameValueEvent;
39 import org.apache.cocoon.components.source.SourceDescriptor;
40 import org.apache.cocoon.components.source.helpers.SourceProperty;
41 import org.apache.excalibur.source.Source;
42 import org.apache.excalibur.source.SourceException;
43 import org.apache.excalibur.source.SourceValidity;
44
45 /**
46  * Simple SourceDescriptor implementation that can stores
47  * properties over JDBC.
48  *
49  * <p>
50  * The descriptor is to be configured with the name of a datasource that
51  * contains a table with the following scheme:
52  * <p>
53  * <code>
54  * CREATE TABLE SOURCEPROPS(<br>
55  * SOURCE VARCHAR NOT NULL,<br>
56  * NAMESPACE VARCHAR NOT NULL,<br>
57  * NAME VARCHAR NOT NULL,<br>
58  * VALUE VARCHAR NOT NULL,<br>
59  * CONSTRAINT SYS_CT_11 UNIQUE(SOURCE,NAMESPACE,NAME))<br>
60  * </code>
61  * </p>
62  * </p>
63  * <p>
64  * The implementation will attempt to connect to the EventAware cache in
65  * order to notify it during changes. If it can't find the EventAware cache
66  * sources that are described by this SourceDescriptor will NOT be cacheable.
67  * </p>
68  *
69  * @version $Id: SimpleJdbcSourceDescriptor.java 30932 2004-07-29 17:35:38Z vgritsenko $
70  */

71 public class SimpleJdbcSourceDescriptor
72 extends AbstractConfigurableSourceDescriptor
73 implements SourceDescriptor, Serviceable, Configurable, Initializable, ThreadSafe {
74     
75     
76     private static final String JavaDoc STMT_SELECT_SINGLE =
77         "SELECT value FROM sourceprops WHERE source=? AND namespace=? AND name=?;";
78     
79     private static final String JavaDoc STMT_SELECT_ALL =
80         "SELECT namespace, name, value FROM sourceprops WHERE source=?;";
81     
82     private static final String JavaDoc STMT_INSERT =
83         "INSERT INTO sourceprops (source,namespace,name,value) VALUES (?,?,?,?);";
84     
85     private static final String JavaDoc STMT_DELETE =
86         "DELETE FROM sourceprops WHERE source=? AND namespace=? AND name=?;";
87     
88     private ServiceManager m_manager;
89     private EventAware m_cache;
90     private DataSourceComponent m_datasource;
91     
92     private String JavaDoc m_datasourceName;
93     private String JavaDoc m_eventName;
94     
95     
96     // ---------------------------------------------------- Lifecycle
97

98     public SimpleJdbcSourceDescriptor() {
99     }
100     
101     public void service(ServiceManager manager) throws ServiceException {
102         m_manager = manager;
103         if (manager.hasService(Cache.ROLE + "/EventAware")) {
104             m_cache = (EventAware) manager.lookup(Cache.ROLE + "/EventAware");
105         } else {
106             getLogger().warn("EventAware cache was not found: sources won't be cacheable.");
107         }
108     }
109     
110     /**
111      * Configuration options:
112      *
113      * <ul>
114      * <li>element <code>property</code> (multiple,required)
115      * - define a property that this store should handle.</li>
116      * <li>element <code>datasource</code> (single,optional,[cocoondb])
117      * - the name of the excalibur datasource to use.</li>
118      * </ul>
119      */

120     public void configure(final Configuration configuration) throws ConfigurationException {
121         super.configure(configuration);
122         m_datasourceName = configuration.getChild("datasource",true).getValue("cocoondb");
123     }
124     
125     public void initialize() throws Exception JavaDoc {
126         ServiceSelector datasources = (ServiceSelector) m_manager.lookup(
127             DataSourceComponent.ROLE + "Selector");
128         m_datasource = (DataSourceComponent) datasources.select(m_datasourceName);
129     }
130     
131     // ---------------------------------------------------- SourceInspection
132

133     public SourceProperty[] getSourceProperties(Source source)
134         throws SourceException {
135
136         Connection JavaDoc connection = null;
137         PreparedStatement JavaDoc stmt = null;
138         try {
139             connection = m_datasource.getConnection();
140             stmt = connection.prepareStatement(STMT_SELECT_ALL);
141             stmt.setString(1,source.getURI());
142             ResultSet JavaDoc result = stmt.executeQuery();
143             List JavaDoc properties = new ArrayList JavaDoc();
144             while (result.next()) {
145                 SourceProperty property = new SourceProperty(
146                     result.getString(1),result.getString(2),result.getString(3));
147                 if (handlesProperty(property.getNamespace(),property.getName())) {
148                     properties.add(property);
149                 }
150             }
151             result.close();
152             stmt.close();
153             return (SourceProperty[]) properties.toArray(
154                 new SourceProperty[properties.size()]);
155         }
156         catch (SQLException JavaDoc e) {
157             throw new SourceException("Error retrieving properties from database",e);
158         }
159         finally {
160             if (connection != null) {
161                 try {
162                     connection.close();
163                 }
164                 catch (SQLException JavaDoc e) {}
165             }
166         }
167     }
168     
169     public SourceProperty doGetSourceProperty(
170         Source source,
171         String JavaDoc namespace,
172         String JavaDoc name)
173         throws SourceException {
174         
175         Connection JavaDoc connection = null;
176         PreparedStatement JavaDoc stmt = null;
177         try {
178             connection = m_datasource.getConnection();
179             stmt = connection.prepareStatement(STMT_SELECT_SINGLE);
180             stmt.setString(1,source.getURI());
181             stmt.setString(2,namespace);
182             stmt.setString(3,name);
183             ResultSet JavaDoc result = stmt.executeQuery();
184             SourceProperty property = null;
185             if (result.next()) {
186                 property = new SourceProperty(
187                     namespace,
188                     name,
189                     result.getString(1));
190             }
191             result.close();
192             stmt.close();
193             return property;
194         }
195         catch (SQLException JavaDoc e) {
196             throw new SourceException("Error retrieving property from database",e);
197         }
198         finally {
199             if (connection != null) {
200                 try {
201                     connection.close();
202                 }
203                 catch (SQLException JavaDoc e) {}
204             }
205         }
206     }
207         
208     public void doSetSourceProperty(Source source, SourceProperty property)
209         throws SourceException {
210         
211         Connection JavaDoc connection = null;
212         PreparedStatement JavaDoc stmt = null;
213         
214         try {
215             connection = m_datasource.getConnection();
216             stmt = connection.prepareStatement(STMT_DELETE);
217             stmt.setString(1,source.getURI());
218             stmt.setString(2,property.getNamespace());
219             stmt.setString(3,property.getName());
220             int count = stmt.executeUpdate();
221             stmt.close();
222             
223             stmt = connection.prepareStatement(STMT_INSERT);
224             stmt.setString(1,source.getURI());
225             stmt.setString(2,property.getNamespace());
226             stmt.setString(3,property.getName());
227             stmt.setString(4,property.getValueAsString());
228             
229             count += stmt.executeUpdate();
230             stmt.close();
231             connection.commit();
232             
233             if (m_cache != null && count > 0) {
234                 m_cache.processEvent(new NameValueEvent(m_eventName,source.getURI()));
235             }
236         }
237         catch (SQLException JavaDoc e) {
238             throw new SourceException("Error setting property",e);
239         }
240         finally {
241             if (connection != null) {
242                 try {
243                     connection.close();
244                 } catch (SQLException JavaDoc e) {}
245             }
246         }
247     }
248     
249     public void doRemoveSourceProperty(
250         Source source,
251         String JavaDoc namespace,
252         String JavaDoc name)
253         throws SourceException {
254         
255         Connection JavaDoc connection = null;
256         PreparedStatement JavaDoc stmt = null;
257         
258         try {
259             connection = m_datasource.getConnection();
260             stmt = connection.prepareStatement(STMT_DELETE);
261             stmt.setString(1,source.getURI());
262             stmt.setString(2,namespace);
263             stmt.setString(3,name);
264             
265             int count = stmt.executeUpdate();
266             stmt.close();
267             connection.commit();
268             
269             if (m_cache != null && count > 0) {
270                 m_cache.processEvent(new NameValueEvent(m_eventName,source.getURI()));
271             }
272         }
273         catch (SQLException JavaDoc e) {
274             throw new SourceException("Error removing propery",e);
275         }
276         finally {
277             if (connection != null) {
278                 try {
279                     connection.close();
280                 } catch (SQLException JavaDoc e) {}
281             }
282         }
283     }
284     
285     public SourceValidity getValidity(Source source) {
286         if (m_cache != null) {
287             return new EventValidity(new NameValueEvent(getEventName(),source.getURI()));
288         }
289         return null;
290     }
291
292     private final String JavaDoc getEventName() {
293         if (m_eventName == null) {
294             Connection JavaDoc connection = null;
295             try {
296                 connection = m_datasource.getConnection();
297                 String JavaDoc catalogName = connection.getCatalog();
298                 m_eventName = (catalogName != null)
299                     ? catalogName + "/sourceprops"
300                     : "sourceprops";
301             }
302             catch (SQLException JavaDoc e) {
303                 getLogger().warn("Error getting catalog name from jdbc connection.",e);
304                 m_eventName = "sourceprops";
305             }
306             finally {
307                 if (connection != null) {
308                     try {
309                         connection.close();
310                     } catch (SQLException JavaDoc e) {}
311                 }
312             }
313         }
314         return m_eventName;
315     }
316 }
317
Popular Tags