1 16 package org.apache.cocoon.components.source.impl; 17 18 import java.sql.Connection ; 19 import java.sql.PreparedStatement ; 20 import java.sql.ResultSet ; 21 import java.sql.SQLException ; 22 import java.util.ArrayList ; 23 import java.util.List ; 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 71 public class SimpleJdbcSourceDescriptor 72 extends AbstractConfigurableSourceDescriptor 73 implements SourceDescriptor, Serviceable, Configurable, Initializable, ThreadSafe { 74 75 76 private static final String STMT_SELECT_SINGLE = 77 "SELECT value FROM sourceprops WHERE source=? AND namespace=? AND name=?;"; 78 79 private static final String STMT_SELECT_ALL = 80 "SELECT namespace, name, value FROM sourceprops WHERE source=?;"; 81 82 private static final String STMT_INSERT = 83 "INSERT INTO sourceprops (source,namespace,name,value) VALUES (?,?,?,?);"; 84 85 private static final String 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 m_datasourceName; 93 private String m_eventName; 94 95 96 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 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 { 126 ServiceSelector datasources = (ServiceSelector) m_manager.lookup( 127 DataSourceComponent.ROLE + "Selector"); 128 m_datasource = (DataSourceComponent) datasources.select(m_datasourceName); 129 } 130 131 133 public SourceProperty[] getSourceProperties(Source source) 134 throws SourceException { 135 136 Connection connection = null; 137 PreparedStatement stmt = null; 138 try { 139 connection = m_datasource.getConnection(); 140 stmt = connection.prepareStatement(STMT_SELECT_ALL); 141 stmt.setString(1,source.getURI()); 142 ResultSet result = stmt.executeQuery(); 143 List properties = new ArrayList (); 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 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 e) {} 165 } 166 } 167 } 168 169 public SourceProperty doGetSourceProperty( 170 Source source, 171 String namespace, 172 String name) 173 throws SourceException { 174 175 Connection connection = null; 176 PreparedStatement 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 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 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 e) {} 204 } 205 } 206 } 207 208 public void doSetSourceProperty(Source source, SourceProperty property) 209 throws SourceException { 210 211 Connection connection = null; 212 PreparedStatement 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 e) { 238 throw new SourceException("Error setting property",e); 239 } 240 finally { 241 if (connection != null) { 242 try { 243 connection.close(); 244 } catch (SQLException e) {} 245 } 246 } 247 } 248 249 public void doRemoveSourceProperty( 250 Source source, 251 String namespace, 252 String name) 253 throws SourceException { 254 255 Connection connection = null; 256 PreparedStatement 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 e) { 274 throw new SourceException("Error removing propery",e); 275 } 276 finally { 277 if (connection != null) { 278 try { 279 connection.close(); 280 } catch (SQLException 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 getEventName() { 293 if (m_eventName == null) { 294 Connection connection = null; 295 try { 296 connection = m_datasource.getConnection(); 297 String catalogName = connection.getCatalog(); 298 m_eventName = (catalogName != null) 299 ? catalogName + "/sourceprops" 300 : "sourceprops"; 301 } 302 catch (SQLException 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 e) {} 311 } 312 } 313 } 314 return m_eventName; 315 } 316 } 317 | Popular Tags |