/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/expression/RDBMSExpressionFactory.java,v 1.9.2.6 2004/11/24 09:42:27 gcasper Exp $
* $Revision: 1.9.2.6 $
* $Date: 2004/11/24 09:42:27 $
*
* ====================================================================
*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.store.impl.rdbms.expression;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.NodeProperty.NamespaceCache;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.InvalidQueryException;
import org.apache.slide.search.PropertyProvider;
import org.apache.slide.search.basic.BasicExpressionFactory;
import org.apache.slide.search.basic.ComparableResourcesPool;
import org.apache.slide.search.basic.IBasicExpression;
import org.apache.slide.search.basic.IBasicQuery;
import org.apache.slide.search.basic.Literals;
import org.apache.slide.store.impl.rdbms.AbstractRDBMSStore;
import org.apache.slide.store.impl.rdbms.RDBMSComparableResourcesPool;
import org.jdom.Element;
/**
* DASL Basic search expression factory that compiles query expressions
* to native SQL queries.
*/
public class RDBMSExpressionFactory extends BasicExpressionFactory {
private final AbstractRDBMSStore _store;
private final RDBMSQueryContext _context;
public RDBMSExpressionFactory(AbstractRDBMSStore store) {
_store = store;
_context = new RDBMSQueryContext(new RDBMSResultSet(this));
}
public void init(IBasicQuery query, PropertyProvider propertyProvider)
throws BadQueryException {
super.init(query, propertyProvider);
}
public IBasicExpression createMergeExpression(String name, String namespace, Collection members)
throws BadQueryException {
RDBMSExpression result = null;
if (name == null) {
result = new RDBMSNOPExpression(_context);
}
else {
ArrayList otherExpressions = null;
ArrayList rdbmsExpressions = null;
final Iterator iter = members.iterator();
while (iter.hasNext()) {
final IBasicExpression expression = (IBasicExpression) iter.next();
if (expression instanceof RDBMSExpression) {
if (rdbmsExpressions == null) {
rdbmsExpressions = new ArrayList(members.size());
}
rdbmsExpressions.add(expression);
}
else {
if (otherExpressions == null) {
otherExpressions = new ArrayList(members.size());
}
otherExpressions.add(expression);
}
}
result = new RDBMSMergeExpression(name, namespace, _context, rdbmsExpressions, otherExpressions);
}
result.setFactory(this);
return result;
}
IBasicExpression createStandardMergeExpression(String name, String namespace, Collection members)
throws BadQueryException {
return super.createMergeExpression(name, namespace, members);
}
public IBasicExpression createExpression(Element element) throws BadQueryException {
IBasicExpression result = null;
if (element == null) {
result = new RDBMSNOPExpression(_context);
}
else {
final String namespace = element.getNamespace().getURI();
final String name = element.getName();
if (namespace.equals(NamespaceCache.DEFAULT_URI)) {
result = createDAVExpression(element);
}
else if (namespace.equals(NamespaceCache.SLIDE_URI)) {
result = createSlideExpression(element);
}
else {
throw new InvalidQueryException
("operator <" + namespace + ":" + name + "> is an unprocessable entity");
}
}
result.setFactory(this);
return result;
}
protected IBasicExpression createDAVExpression(Element element) throws BadQueryException {
if (isSQLCompilableProperty(element)) {
if (RDBMSCompareExpression.COMPARE_OPERATORS.containsKey(element.getName())) {
return new RDBMSCompareExpression(element, _context);
}
else if (element.getName().equals(Literals.ISDEFINED)) {
return new RDBMSIsDefinedExpression(element, _context);
}
else if (element.getName().equals(Literals.NOT_ISDEFINED)) {
return new RDBMSNotIsDefinedExpression(element, _context);
}
}
else if (element.getName().equals(Literals.ISCOLLECTION)) {
return new RDBMSIsCollectionExpression(element, _context);
}
else if (element.getName().equals(Literals.NOT_ISCOLLECTION)) {
return new RDBMSNotIsCollectionExpression(element, _context);
}
return super.createExpression(element);
}
protected IBasicExpression createSlideExpression(Element element) throws BadQueryException {
if (isSQLCompilableProperty(element)) {
if (element.getName().equals(Literals.PROPCONTAINS)) {
return new RDBMSPropContainsExpression(element, _context);
}
else if (element.getName().equals(Literals.NOT_PROPCONTAINS)) {
return new RDBMSNotPropContainsExpression(element, _context);
}
}
if (element.getName().equals(Literals.ISPRINCIPAL)) {
return new RDBMSIsPrincipalExpression(element, _context);
}
else if (element.getName().equals(Literals.NOT_ISPRINCIPAL)) {
return new RDBMSNotIsPrincipalExpression(element, _context);
}
return super.createExpression(element);
}
protected ComparableResourcesPool getRequestedResourcePool() {
if (requestedResourcePool == null) {
requestedResourcePool = new RDBMSComparableResourcesPool(_store, _context, getQuery());
}
return requestedResourcePool;
}
public boolean isSQLCompilableProperty(Element element) {
Element davProp = element.getChild(Literals.PROP, NamespaceCache.DEFAULT_NAMESPACE);
if (davProp != null) {
Element property = (Element) davProp.getChildren().get(0);
return isSQLCompilableProperty(property.getNamespaceURI(), property.getName());
}
return false;
}
public boolean isSQLCompilableProperty(String namespace, String name) {
if (getPropertyProvider() == null) return false;
try {
final String uri = getQuery().getSearchToken().getSlideContext()
.getSlidePath(getQuery().getScope().getHref());
return !getPropertyProvider().isSupportedProperty(uri, name, namespace);
}
catch (SlideException e) {
e.printStackTrace();
return false;
}
}
/**
* converts a property name to a legal SQL alias.
*/
public static String propertyToAlias(String propertyName) {
// replaceAll occurs in JDK1.4
//return "prop_" + propertyName.replaceAll("-", "_");
StringBuffer buffer = new StringBuffer(propertyName.length() + 5);
buffer.append("prop_");
for (int i = 0, l = propertyName.length(); i < l; i++) {
char c = propertyName.charAt(i);
if (c == '-') c = '_';
buffer.append(c);
}
return buffer.toString();
}
}