SQLQueryBuilder.java
/*
* Copyright (C) 2003-2008 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.services.wcm.utils;
import java.util.Calendar;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.ISO8601;
/**
* Created by The eXo Platform SAS
* Author : Hoa Pham
* hoa.pham@exoplatform.com
* Oct 7, 2008
*/
/*
* This class is implementation of AbstractQueryBuilder for sql-based query.
* This class help developer create sql query statement easier.
* */
public class SQLQueryBuilder extends AbstractQueryBuilder {
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#isNull(java.lang
* .String, org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void isNull(String propertyName, LOGICAL condition) {
if(condition == LOGICAL.AND)
propertiesClause.append(" AND").append(propertyName).append("IS NULL ");
else if(condition == LOGICAL.OR)
propertiesClause.append(" OR").append(propertyName).append("IS NULL ");
else
propertiesClause.append(propertyName).append("IS NULL ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#isNotNull(java
* .lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void isNotNull(String propertyName, LOGICAL condition) {
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propertyName).append(" IS NOT NULL ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propertyName).append(" IS NOT NULL ");
else
propertiesClause.append(propertyName).append(" IS NOT NULL ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#lessThan(java.
* lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void lessThan(String propertyName, String value, LOGICAL condition) {
comparison(propertyName,value,condition,"<");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#greaterThan(java
* .lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void greaterThan(String propName, String value, LOGICAL condition) {
comparison(propName,value,condition,">");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#lessThanOrEqual
* (java.lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void lessThanOrEqual(String propName, String value, LOGICAL condition) {
comparison(propName,value,condition,"<=");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#greaterOrEqual
* (java.lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void greaterOrEqual(String propName,String value, LOGICAL condition) {
comparison(propName,value,condition,">=");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#equal(java.lang
* .String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void equal(String propName, String value , LOGICAL condition) {
comparison(propName,value,condition,"=");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#notEqual(java.
* lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void notEqual(String propName, String value, LOGICAL condition) {
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propName).append(" <> '").append(value).append("' ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propName).append(" <> '").append(value).append("' ");
else
propertiesClause.append(propName).append(" <> '").append(value).append("' ");
}
/**
* Comparison.
*
* @param propName the prop name
* @param value the value
* @param condition the condition
* @param symbol the symbol
*/
private void comparison(String propName, String value, LOGICAL condition, String symbol) {
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propName).append(" ").append(symbol).append(" '").append(value).append("' ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propName).append(" ").append(symbol).append(" '").append(value).append("' ");
else
propertiesClause.append(propName).append(" ").append(symbol).append(" '").append(value).append("' ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#like(java.lang
* .String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void like(String propName, String value, LOGICAL condition) {
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propName).append(" LIKE '").append(value).append("%' ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propName).append(" LIKE '").append(value).append("%' ");
else
propertiesClause.append(propName).append(" LIKE '").append(value).append("%' ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#reference(java
* .lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void reference(String propName, String value, LOGICAL condition) {
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#beforeDate(java
* .lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void beforeDate(String propName, String comparedDate, LOGICAL condition) {
Calendar calendar = ISO8601.parse(comparedDate);
String time = calendar.getTime().toString();
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propName).append(" <= '").append(time).append("' ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propName).append(" <= '").append(time).append("' ");
else
propertiesClause.append(propName).append(" <= '").append(time).append("' ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#afterDate(java
* .lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void afterDate(String propName, String comparedDate, LOGICAL condition) {
Calendar calendar = ISO8601.parse(comparedDate);
String time = calendar.getTime().toString();
if(condition == LOGICAL.AND)
propertiesClause.append("AND ").append(propName).append(" >= '").append(time).append("' ");
else if(condition == LOGICAL.OR)
propertiesClause.append("OR ").append(propName).append(" >= '").append(time).append("' ");
else
propertiesClause.append(propName).append(" >= '").append(time).append("' ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#betweenDates(java
* .lang.String, java.lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void betweenDates(String propName, String startDate, String endDate, LOGICAL condition) {
String startTime = ISO8601.parse(startDate).getTime().toString();
String endTime = ISO8601.parse(endDate).getTime().toString();
if (condition == LOGICAL.AND)
propertiesClause.append("AND ")
.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
else if (condition == LOGICAL.OR)
propertiesClause.append("OR ")
.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
else
propertiesClause.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
}
public void betweenDates(String propName, Calendar startDate, Calendar endDate, LOGICAL condition) {
String startTime = ISO8601.format(startDate);
String endTime = ISO8601.format(endDate);
if (condition == LOGICAL.AND)
propertiesClause.append("AND ")
.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
else if (condition == LOGICAL.OR)
propertiesClause.append("OR ")
.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
else
propertiesClause.append(propName)
.append(" between TIMESTAMP '")
.append(startTime)
.append("' and TIMESTAMP '")
.append(endTime)
.append("' ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#setQueryPath(java
* .lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.PATH_TYPE)
*/
public void setQueryPath(String path, PATH_TYPE pathtype) {
if(StringUtils.isEmpty(path)) return;
if (PATH_TYPE.EXACT == pathtype) {
if (path.indexOf("[%]") > 0)
pathClause = new StringBuilder().append("jcr:path LIKE '").append(path).append("' ");
else
pathClause = new StringBuilder().append("jcr:path = '").append(path).append("' ");
} else if (PATH_TYPE.CHILDNODES == pathtype) {
pathClause = new StringBuilder().append("jcr:path LIKE '")
.append(path)
.append("/%'")
.append("AND NOT jcr:path like '")
.append(path)
.append("/%/%' ");
} else if (PATH_TYPE.DECENDANTS == pathtype) {
pathClause = new StringBuilder().append("jcr:path LIKE '").append(path).append("/%' ");
} else if (PATH_TYPE.DECENDANTS_OR_SELFT == pathtype) {
pathClause = new StringBuilder().append("jcr:path LIKE '")
.append(path)
.append("'")
.append("OR jcr:path LIKE '")
.append(path)
.append("/%' ");
}
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#contains(java.
* lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void contains(String scope, String term, LOGICAL condition) {
if (scope == null)
scope = ".";
if (LOGICAL.AND == condition)
containsClause.append("AND CONTAINS(").append(scope).append(",'").append(term).append("') ");
else if (LOGICAL.OR == condition)
containsClause.append("OR CONTAINS(").append(scope).append(",'").append(term).append("') ");
else
containsClause.append("CONTAINS(").append(scope).append(",'").append(term).append("') ");
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#notContains(java
* .lang.String, java.lang.String,
* org.exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void notContains(String scope, String term, LOGICAL condition) {
if (scope == null)
scope = ".";
if (LOGICAL.AND == condition)
containsClause.append("AND NOT CONTAINS(")
.append(scope)
.append(",'")
.append(term)
.append("') ");
else if (LOGICAL.OR == condition)
containsClause.append("OR NOT CONTAINS(")
.append(scope)
.append(",'")
.append(term)
.append("') ");
else
containsClause.append("NOT CONTAINS(").append(scope).append(",'").append(term).append("') ");
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#fromNodeTypes(java.lang.String[])
*/
public void fromNodeTypes(String[] nodetypes) {
if(nodetypes == null) {
fromClause = new StringBuilder("FROM nt:base");
return;
}
fromClause = new StringBuilder("FROM ");
for(int i = 0; i<nodetypes.length; i++) {
fromClause.append(nodetypes[i]);
if(i<nodetypes.length-1)
fromClause.append(",");
}
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#selectTypes(java.lang.String[])
*/
public void selectTypes(String[] returnTypes) {
if(returnTypes == null) {
selectClause = new StringBuilder("SELECT * ");
return;
}
selectClause = new StringBuilder("SELECT ");
for(int i = 0; i<returnTypes.length; i++) {
selectClause.append(returnTypes[i]);
if(i<returnTypes.length-1)
selectClause.append(",");
selectClause.append(" ");
}
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#orderBy(java.lang
* .String, org.exoplatform.services.wcm.search.AbstractQueryBuilder.ORDERBY)
*/
public void orderBy(String properyName, ORDERBY orderby) {
if(orderByClause.length()>0)
orderByClause = orderByClause.append(", ");
if(ORDERBY.ASC == orderby)
orderByClause.append(properyName).append(" ASC");
else
orderByClause.append(properyName).append(" DESC");
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#excerpt(boolean)
*/
public void excerpt(boolean enable) {
if(enable)
excerptClause = new StringBuilder("excerpt(.)");
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#spellCheck(java.lang.String)
*/
public void spellCheck(String value) {
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#openGroup(org.
* exoplatform.services.wcm.search.AbstractQueryBuilder.LOGICAL)
*/
public void openGroup(LOGICAL logical) {
if(LOGICAL.AND == logical)
propertiesClause = propertiesClause.append("AND( ");
else if(LOGICAL.OR == logical)
propertiesClause = propertiesClause.append("OR( ");
else if(LOGICAL.AND_NOT == logical)
propertiesClause = propertiesClause.append("AND NOT(");
else if(LOGICAL.OR_NOT == logical)
propertiesClause = propertiesClause.append("OR NOT(");
else
propertiesClause = propertiesClause.append("( ");
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#closeGroup()
*/
public void closeGroup() {
propertiesClause = propertiesClause.append(")");
}
/* (non-Javadoc)
* @see org.exoplatform.services.wcm.search.AbstractQueryBuilder#createQueryStatement()
*/
public String createQueryStatement() {
StringBuffer statement = new StringBuffer();
statement = statement.append(selectClause.toString())
.append(fromClause.toString())
.append(" WHERE ");
if (containsClause.length() > 0) {
statement = statement.append(containsClause.toString());
if (pathClause.length() > 0) {
statement = statement.append("AND ").append(pathClause.toString());
}
} else {
if (pathClause.length() > 0) {
statement = statement.append(pathClause.toString());
}
}
if (propertiesClause.length() > 0) {
String propertiesStr = propertiesClause.toString();
if((propertiesStr.startsWith("AND") || propertiesStr.startsWith(" AND")) &&
statement.toString().endsWith("WHERE "))
propertiesStr = propertiesStr.substring(propertiesStr.lastIndexOf("AND") + 1, propertiesStr.length());
statement = statement.append(propertiesStr);
}
if (orderByClause.length() > 0) {
statement = statement.append("ORDER BY ").append(orderByClause.toString());
}
return statement.toString();
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.services.wcm.search.AbstractQueryBuilder#merge(org.exoplatform
* .services.wcm.search.AbstractQueryBuilder)
*/
public void merge(AbstractQueryBuilder other) {
}
public void queryByNodeName(String rootPath, String nodeName) {
pathClause = new StringBuilder().append(" jcr:path LIKE '")
.append(rootPath)
.append("/%/")
.append(nodeName)
.append("' ")
.append(" or jcr:path like '")
.append(rootPath)
.append("/")
.append(nodeName)
.append("' ");
}
}