1 23 package org.apache.slide.store.impl.rdbms; 24 25 import java.lang.reflect.Constructor ; 26 import java.sql.Connection ; 27 import java.sql.PreparedStatement ; 28 import java.sql.ResultSet ; 29 import java.sql.SQLException ; 30 import java.util.ArrayList ; 31 import java.util.Collections ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.Set ; 37 38 import org.apache.slide.common.PropertyName; 39 import org.apache.slide.common.RequestedProperties; 40 import org.apache.slide.common.RequestedProperty; 41 import org.apache.slide.common.RequestedPropertyImpl; 42 import org.apache.slide.common.ServiceAccessException; 43 import org.apache.slide.common.SlideException; 44 import org.apache.slide.common.SlideRuntimeException; 45 import org.apache.slide.content.NodeProperty; 46 import org.apache.slide.search.BadQueryException; 47 import org.apache.slide.search.PropertyProvider; 48 import org.apache.slide.search.QueryScope; 49 import org.apache.slide.search.SearchQuery; 50 import org.apache.slide.search.SearchToken; 51 import org.apache.slide.search.basic.ComparableResourceImpl; 52 import org.apache.slide.search.basic.ComparableResourcesPool; 53 import org.apache.slide.search.basic.IBasicQuery; 54 import org.apache.slide.security.AccessDeniedException; 55 import org.apache.slide.store.impl.rdbms.expression.RDBMSExpressionFactory; 56 import org.apache.slide.store.impl.rdbms.expression.RDBMSQueryContext; 57 import org.apache.slide.structure.ObjectNode; 58 import org.apache.slide.util.logger.Logger; 59 60 62 public class RDBMSComparableResourcesPool implements ComparableResourcesPool { 63 64 private final AbstractRDBMSStore _store; 65 private final RDBMSQueryContext _context; 66 private final IBasicQuery _query; 67 private final SearchToken _token; 68 private final QueryScope _scope; 69 private final Map _selectProperties; 70 private final PropertyProvider _provider; 71 72 private Set _pool; 73 74 public RDBMSComparableResourcesPool(AbstractRDBMSStore store, 75 RDBMSQueryContext context, 76 IBasicQuery query) { 77 _store = store; 78 _context = context; 79 _query = query; 80 _token = _query.getSearchToken(); 81 _scope = _query.getScope(); 82 _selectProperties = new HashMap (); 83 _provider = new RDBMSPropertyProvider(_query.getPropertyProvider(), _selectProperties); 84 85 if (_query instanceof SearchQuery) { 86 final RequestedProperties props = ((SearchQuery) _query).requestedProperties(); 87 if (!props.isAllProp()) { 88 final Iterator iter = props.getRequestedProperties(); 89 while (iter.hasNext()) { 90 final RequestedProperty property = (RequestedProperty) iter.next(); 91 final String selectKey = property.getNamespace() + property.getName(); 92 if (_context.selects().containsKey(selectKey)) { 93 _selectProperties.put(property, new HashMap ()); 94 } 95 } 96 } 97 } 98 } 99 100 public Iterator resourceIterator() { 101 try { 102 return getPool().iterator(); 103 } 104 catch (BadQueryException e) { 105 throw new SlideRuntimeException(e.toString()); 106 } 107 } 108 109 public Set getPool() throws BadQueryException { 110 if (_pool == null) { 111 try { 112 ObjectNode[] objects = retrieveObjects(); 113 _pool = new HashSet (objects.length); 114 for (int i = 0; i < objects.length; i++) { 115 try { 116 _pool.add(new ComparableResourceImpl(objects[i], _token, _scope, _provider)); 117 } 118 catch (AccessDeniedException e) { 119 } 121 } 122 } 123 catch (ServiceAccessException e) { 124 throw new BadQueryException(e); 125 } 126 catch (SlideException e) { 127 throw new BadQueryException(e); 128 } 129 } 130 return _pool; 131 } 132 133 public boolean partialResult() { 134 return false; 135 } 136 137 public QueryScope getScope() { 138 return _scope; 139 } 140 141 private ObjectNode[] retrieveObjects() throws ServiceAccessException, BadQueryException { 142 if (_store.getCurrentlyActiveTransactionalResource() == null) { 143 Connection connection = null; 144 try { 145 connection = _store.getNewConnection(); 146 return retrieveObjects(connection); 147 } catch (SQLException e) { 148 throw new ServiceAccessException(_store, e); 149 } finally { 150 if (connection != null) { 151 try { 152 connection.close(); 153 } catch (SQLException e) { 154 _store.getLogger().log(e, AbstractRDBMSStore.LOG_CHANNEL, Logger.WARNING); 155 } 156 } 157 } 158 } else { 159 return retrieveObjects(_store.getCurrentConnection()); 160 } 161 } 162 163 private ObjectNode[] retrieveObjects(Connection connection) throws ServiceAccessException, BadQueryException { 164 PreparedStatement statement = null; 165 ResultSet result = null; 166 ArrayList classNames = new ArrayList (); 167 ArrayList uris = new ArrayList (); 168 try { 169 final String sql = compileSQL(); 170 if (_store.getLogger().isEnabled(Logger.INFO)) { 171 _store.getLogger().log("executing: " + sql, AbstractRDBMSStore.LOG_CHANNEL, Logger.INFO); 172 } 173 statement = connection.prepareStatement(sql); 174 result = statement.executeQuery(); 175 while (result.next()) { 176 final String uri = result.getString(1); 177 final String className = result.getString(2); 178 uris.add(uri); 179 classNames.add(className); 180 Iterator iter = _selectProperties.keySet().iterator(); 181 while (iter.hasNext()) { 182 final RequestedProperty requested = (RequestedProperty) iter.next(); 183 final String name = requested.getName(); 184 final String namespace = requested.getNamespace(); 185 final String alias = RDBMSExpressionFactory.propertyToAlias(requested.getName()); 186 final String value = result.getString(alias); 187 final NodeProperty property = new NodeProperty(name, value, namespace); 188 final Map properties = (Map ) _selectProperties.get(requested); 189 properties.put(uri, property); 190 } 191 } 192 } 193 catch (SQLException e) { 194 throw new ServiceAccessException(_store, e); 195 } 196 finally { 197 if (result != null) { 198 try { 199 result.close(); 200 } 201 catch (SQLException e) { 202 _store.getLogger().log(e, AbstractRDBMSStore.LOG_CHANNEL, Logger.WARNING); 203 } 204 } 205 if (statement != null) { 206 try { 207 statement.close(); 208 } 209 catch (SQLException e) { 210 _store.getLogger().log(e, AbstractRDBMSStore.LOG_CHANNEL, Logger.WARNING); 211 } 212 } 213 } 214 int size = uris.size(); 215 ObjectNode[] objects = new ObjectNode[size]; 216 for (int i = 0; i < size; i++) { 217 try { 218 Class objclass = Class.forName((String ) classNames.get(i)); 219 Class argClasses[] = { String .class }; 220 Object arguments[] = { uris.get(i) }; 221 Constructor constructor = objclass.getConstructor(argClasses); 222 objects[i] = (ObjectNode) constructor.newInstance(arguments); 223 objects[i].setUri(objects[i].getUuri()); 224 } catch (Exception e) { 225 throw new ServiceAccessException(_store, e); 226 } 227 } 228 return objects; 229 } 230 231 private String compileSQL() throws BadQueryException { 232 String uri = _token.getSlideContext().getSlidePath(_scope.getHref()); 233 if (uri.endsWith("/")) { 234 uri = uri.substring(0, uri.length()-1); 235 } 236 String query = "select " + compileSelect() + 237 " from " + compileJoins() + 238 " where " + compileScope(uri); 239 final String criteria = compileCriteria(); 240 query = (criteria != null && criteria.length() > 0) ? query + " AND " + criteria : query; 241 return query; 242 } 243 244 private String compileSelect() { 245 String select = "u.URI_STRING, o.CLASS_NAME"; 246 final Iterator iter = _selectProperties.keySet().iterator(); 247 while (iter.hasNext()) { 248 final RequestedProperty property = (RequestedProperty) iter.next(); 249 final String selectKey = property.getNamespace() + property.getName(); 250 String propSelect = (String ) _context.selects().get(selectKey); 251 if (propSelect != null) { 252 select += ", " + propSelect; 253 } 254 } 255 return select; 256 } 257 258 private String compileScope(String uri) { 259 switch (_scope.getDepth()) { 260 case QueryScope.DEPTH_0: { 261 return " u.URI_STRING = '" + uri + "'"; 262 } 263 case QueryScope.DEPTH_1: { 264 return " (u.URI_STRING = '" + uri + "'" + 265 " OR (u.URI_STRING LIKE '" + uri + "/%'" + 266 " AND u.URI_STRING NOT LIKE '" + uri + "/%/%'))"; 267 } 268 case QueryScope.DEPTH_INFINITY: 269 default: { 270 return " (u.URI_STRING = '" + uri + "'" + 271 " OR u.URI_STRING LIKE '" + uri + "/%')"; 272 } 273 } 274 } 275 276 private String compileCriteria() { 277 String result = null; 278 if (_context.criteria().size() > 0) { 279 result = ""; 280 Iterator iter = _context.criteria().iterator(); 281 while (iter.hasNext()) { 282 result += iter.next(); 283 } 284 } 285 return result; 286 } 287 288 private String compileJoins() { 289 String joins = "((OBJECT o " + 290 "inner join URI u on u.URI_ID = o.URI_ID) " + 291 "inner join VERSION_HISTORY vh on vh.URI_ID = u.URI_ID) "; 292 Iterator iter = _context.joins().iterator(); 293 while (iter.hasNext()) { 294 joins = "(" + joins + " " + iter.next() + ") "; 295 } 296 return joins; 297 } 298 299 private static class RDBMSPropertyProvider implements PropertyProvider { 300 301 private final PropertyProvider _propertyProvider; 302 private final Map _selectProperties; 303 304 private RDBMSPropertyProvider(PropertyProvider propertyProvider, Map selectProperties) { 305 _propertyProvider = propertyProvider; 306 _selectProperties = selectProperties; 307 } 308 309 public boolean isSupportedProperty(String resourceUri, String propertyName, String propertyNamespace) throws SlideException { 310 if (_selectProperties.containsKey(new RequestedPropertyImpl(propertyName, propertyNamespace))) { 311 return true; 312 } 313 else if (_propertyProvider != null) { 314 return _propertyProvider.isSupportedProperty(resourceUri, propertyName, propertyNamespace); 315 } 316 return false; 317 } 318 319 public Iterator getSupportedPropertiesNames(String resourceUri) throws SlideException { 320 Iterator selected = _selectProperties.keySet().iterator(); 321 Iterator provided = null; 322 if (_propertyProvider != null) { 323 provided = _propertyProvider.getSupportedPropertiesNames(resourceUri); 324 } 325 return new PropertyNamesIterator(selected, provided); 326 } 327 328 public NodeProperty getProperty(String resourceUri, String propertyName, String propertyNamespace) throws SlideException { 329 Map properties = (Map ) _selectProperties.get(new RequestedPropertyImpl(propertyName, propertyNamespace)); 330 if (properties != null) { 331 return (NodeProperty) properties.get(resourceUri); 332 } 333 else if (_propertyProvider != null) { 334 return _propertyProvider.getProperty(resourceUri, propertyName, propertyNamespace); 335 } 336 return null; 337 } 338 339 public Iterator getSupportedProperties(String resourceUri) throws SlideException { 340 Iterator selected = _selectProperties.values().iterator(); 341 Iterator provided = null; 342 if (_propertyProvider != null) { 343 provided = _propertyProvider.getSupportedProperties(resourceUri); 344 } 345 return new NodePropertiesIterator(resourceUri, selected, provided); 346 } 347 348 private static class PropertyNamesIterator implements Iterator { 349 350 private final Iterator _selectedProperties; 351 private final Iterator _providedProperties; 352 353 private PropertyNamesIterator(Iterator selectedProperties, Iterator providedProperties) { 354 _selectedProperties = selectedProperties; 355 if (providedProperties != null) { 356 _providedProperties = providedProperties; 357 } 358 else { 359 _providedProperties = Collections.EMPTY_LIST.iterator(); 360 } 361 } 362 363 public void remove() { 364 throw new UnsupportedOperationException (); 365 } 366 367 public boolean hasNext() { 368 return _selectedProperties.hasNext() || _providedProperties.hasNext(); 369 } 370 371 public Object next() { 372 if (_selectedProperties.hasNext()) { 373 RequestedProperty property = (RequestedProperty) _selectedProperties.next(); 374 return new PropertyName(property.getName(), property.getNamespace()); 375 } 376 return _providedProperties.next(); 377 } 378 379 } 380 381 private static class NodePropertiesIterator implements Iterator { 382 383 private String _resourceUri; 384 private Iterator _selectedProperties; 385 private Iterator _providedProperties; 386 387 private NodePropertiesIterator(String resourceUri, Iterator selectedProperties, Iterator providedProperties) { 388 _resourceUri = resourceUri; 389 _selectedProperties = selectedProperties; 390 if (providedProperties != null) { 391 _providedProperties = providedProperties; 392 } 393 else { 394 _providedProperties = Collections.EMPTY_LIST.iterator(); 395 } 396 } 397 398 public void remove() { 399 throw new UnsupportedOperationException (); 400 } 401 402 public boolean hasNext() { 403 return _selectedProperties.hasNext() || _providedProperties.hasNext(); 404 } 405 406 public Object next() { 407 if (_selectedProperties.hasNext()) { 408 Map properties = (Map ) _selectedProperties.next(); 409 return (NodeProperty) properties.get(_resourceUri); 410 } 411 return _providedProperties.next(); 412 } 413 414 } 415 416 } 417 418 } 419 | Popular Tags |