All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.util.dao.orm.CustomSQL Maven / Gradle / Ivy

There is a newer version: 7.4.3.112-ga112
Show newest version
/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package com.liferay.util.dao.orm;

import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.configuration.Configuration;
import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.dao.orm.QueryDefinition;
import com.liferay.portal.kernel.dao.orm.WildcardMode;
import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;

import java.io.IOException;
import java.io.InputStream;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author Brian Wing Shun Chan
 * @author Bruno Farache
 * @author Raymond Augé
 * @see    com.liferay.portal.dao.orm.custom.sql.CustomSQL
 */
public class CustomSQL {

	public static final String DB2_FUNCTION_IS_NOT_NULL =
		"CAST(? AS VARCHAR(32672)) IS NOT NULL";

	public static final String DB2_FUNCTION_IS_NULL =
		"CAST(? AS VARCHAR(32672)) IS NULL";

	public static final String INFORMIX_FUNCTION_IS_NOT_NULL =
		"NOT lportal.isnull(?)";

	public static final String INFORMIX_FUNCTION_IS_NULL = "lportal.isnull(?)";

	public static final String MYSQL_FUNCTION_IS_NOT_NULL =
		"IFNULL(?, '1') = '0'";

	public static final String MYSQL_FUNCTION_IS_NULL = "IFNULL(?, '1') = '1'";

	public static final String SYBASE_FUNCTION_IS_NOT_NULL =
		"CONVERT(VARCHAR,?) IS NOT NULL";

	public static final String SYBASE_FUNCTION_IS_NULL =
		"CONVERT(VARCHAR,?) IS NULL";

	public CustomSQL() throws SQLException {
		reloadCustomSQL();
	}

	public String appendCriteria(String sql, String criteria) {
		if (Validator.isNull(criteria)) {
			return sql;
		}

		if (!criteria.startsWith(StringPool.SPACE)) {
			criteria = StringPool.SPACE.concat(criteria);
		}

		if (!criteria.endsWith(StringPool.SPACE)) {
			criteria = criteria.concat(StringPool.SPACE);
		}

		int pos = sql.indexOf(_GROUP_BY_CLAUSE);

		if (pos != -1) {
			return sql.substring(
				0, pos + 1
			).concat(
				criteria
			).concat(
				sql.substring(pos + 1)
			);
		}

		pos = sql.indexOf(_ORDER_BY_CLAUSE);

		if (pos != -1) {
			return sql.substring(
				0, pos + 1
			).concat(
				criteria
			).concat(
				sql.substring(pos + 1)
			);
		}

		return sql.concat(criteria);
	}

	public String get(String id) {
		return _sqlPool.get(id);
	}

	public String get(String id, QueryDefinition queryDefinition) {
		return get(id, queryDefinition, StringPool.BLANK);
	}

	public String get(
		String id, QueryDefinition queryDefinition, String tableName) {

		String sql = get(id);

		if (!Validator.isBlank(tableName) &&
			!tableName.endsWith(StringPool.PERIOD)) {

			tableName = tableName.concat(StringPool.PERIOD);
		}

		if (queryDefinition.getStatus() == WorkflowConstants.STATUS_ANY) {
			sql = sql.replace(_STATUS_KEYWORD, _STATUS_CONDITION_EMPTY);
		}
		else {
			if (queryDefinition.isExcludeStatus()) {
				sql = sql.replace(
					_STATUS_KEYWORD,
					tableName.concat(_STATUS_CONDITION_INVERSE));
			}
			else {
				sql = sql.replace(
					_STATUS_KEYWORD,
					tableName.concat(_STATUS_CONDITION_DEFAULT));
			}
		}

		if (queryDefinition.getOwnerUserId() > 0) {
			if (queryDefinition.isIncludeOwner()) {
				StringBundler sb = new StringBundler(7);

				sb.append(StringPool.OPEN_PARENTHESIS);
				sb.append(tableName);
				sb.append(_OWNER_USER_ID_CONDITION_DEFAULT);
				sb.append(" AND ");
				sb.append(tableName);
				sb.append(_STATUS_CONDITION_INVERSE);
				sb.append(StringPool.CLOSE_PARENTHESIS);

				sql = sql.replace(_OWNER_USER_ID_KEYWORD, sb.toString());

				sql = sql.replace(_OWNER_USER_ID_AND_OR_CONNECTOR, " OR ");
			}
			else {
				sql = sql.replace(
					_OWNER_USER_ID_KEYWORD,
					tableName.concat(_OWNER_USER_ID_CONDITION_DEFAULT));

				sql = sql.replace(_OWNER_USER_ID_AND_OR_CONNECTOR, " AND ");
			}
		}
		else {
			sql = sql.replace(_OWNER_USER_ID_KEYWORD, StringPool.BLANK);

			sql = sql.replace(
				_OWNER_USER_ID_AND_OR_CONNECTOR, StringPool.BLANK);
		}

		return sql;
	}

	/**
	 * Returns true if Hibernate is connecting to a DB2 database.
	 *
	 * @return true if Hibernate is connecting to a DB2 database
	 */
	public boolean isVendorDB2() {
		return _vendorDB2;
	}

	/**
	 * Returns true if Hibernate is connecting to a Hypersonic
	 * database.
	 *
	 * @return true if Hibernate is connecting to a Hypersonic
	 *         database
	 */
	public boolean isVendorHSQL() {
		return _vendorHSQL;
	}

	/**
	 * Returns true if Hibernate is connecting to an Informix
	 * database.
	 *
	 * @return true if Hibernate is connecting to an Informix
	 *         database
	 */
	public boolean isVendorInformix() {
		return _vendorInformix;
	}

	/**
	 * Returns true if Hibernate is connecting to a MySQL database.
	 *
	 * @return true if Hibernate is connecting to a MySQL database
	 */
	public boolean isVendorMySQL() {
		return _vendorMySQL;
	}

	/**
	 * Returns true if Hibernate is connecting to an Oracle
	 * database. Oracle has a nasty bug where it treats '' as a
	 * NULL value. See
	 * http://thedailywtf.com/forums/thread/26879.aspx for more information on
	 * this nasty bug.
	 *
	 * @return true if Hibernate is connecting to an Oracle
	 *         database
	 */
	public boolean isVendorOracle() {
		return _vendorOracle;
	}

	/**
	 * Returns true if Hibernate is connecting to a PostgreSQL
	 * database.
	 *
	 * @return true if Hibernate is connecting to a PostgreSQL
	 *         database
	 */
	public boolean isVendorPostgreSQL() {
		return _vendorPostgreSQL;
	}

	/**
	 * Returns true if Hibernate is connecting to a Sybase
	 * database.
	 *
	 * @return true if Hibernate is connecting to a Sybase database
	 */
	public boolean isVendorSybase() {
		return _vendorSybase;
	}

	public String[] keywords(String keywords) {
		return keywords(keywords, true, WildcardMode.SURROUND);
	}

	public String[] keywords(String keywords, boolean lowerCase) {
		return keywords(keywords, lowerCase, WildcardMode.SURROUND);
	}

	public String[] keywords(
		String keywords, boolean lowerCase, WildcardMode wildcardMode) {

		if (Validator.isNull(keywords)) {
			return new String[] {null};
		}

		if (_CUSTOM_SQL_AUTO_ESCAPE_WILDCARDS_ENABLED) {
			keywords = _escapeWildCards(keywords);
		}

		if (lowerCase) {
			keywords = StringUtil.toLowerCase(keywords);
		}

		keywords = keywords.trim();

		List keywordsList = new ArrayList<>();

		for (int i = 0; i < keywords.length(); i++) {
			char c = keywords.charAt(i);

			if (c == CharPool.QUOTE) {
				int pos = i + 1;

				i = keywords.indexOf(CharPool.QUOTE, pos);

				if (i == -1) {
					i = keywords.length();
				}

				if (i > pos) {
					String keyword = keywords.substring(pos, i);

					keywordsList.add(insertWildcard(keyword, wildcardMode));
				}
			}
			else {
				while (Character.isWhitespace(c)) {
					i++;

					c = keywords.charAt(i);
				}

				int pos = i;

				while (!Character.isWhitespace(c)) {
					i++;

					if (i == keywords.length()) {
						break;
					}

					c = keywords.charAt(i);
				}

				String keyword = keywords.substring(pos, i);

				keywordsList.add(insertWildcard(keyword, wildcardMode));
			}
		}

		return keywordsList.toArray(new String[keywordsList.size()]);
	}

	public String[] keywords(String keywords, WildcardMode wildcardMode) {
		return keywords(keywords, true, wildcardMode);
	}

	public String[] keywords(String[] keywordsArray) {
		return keywords(keywordsArray, true);
	}

	public String[] keywords(String[] keywordsArray, boolean lowerCase) {
		if (ArrayUtil.isEmpty(keywordsArray)) {
			return new String[] {null};
		}

		if (lowerCase) {
			for (int i = 0; i < keywordsArray.length; i++) {
				keywordsArray[i] = StringUtil.lowerCase(keywordsArray[i]);
			}
		}

		return keywordsArray;
	}

	public void reloadCustomSQL() throws SQLException {
		PortalUtil.initCustomSQL();

		Connection con = DataAccess.getConnection();

		String functionIsNull = PortalUtil.getCustomSQLFunctionIsNull();
		String functionIsNotNull = PortalUtil.getCustomSQLFunctionIsNotNull();

		try {
			if (Validator.isNotNull(functionIsNull) &&
				Validator.isNotNull(functionIsNotNull)) {

				_functionIsNull = functionIsNull;
				_functionIsNotNull = functionIsNotNull;

				if (_log.isDebugEnabled()) {
					_log.debug(
						"functionIsNull is manually set to " + functionIsNull);
					_log.debug(
						"functionIsNotNull is manually set to " +
							functionIsNotNull);
				}
			}
			else if (con != null) {
				DatabaseMetaData metaData = con.getMetaData();

				String dbName = GetterUtil.getString(
					metaData.getDatabaseProductName());

				if (_log.isInfoEnabled()) {
					_log.info("Database name " + dbName);
				}

				if (dbName.startsWith("DB2")) {
					_vendorDB2 = true;
					_functionIsNull = DB2_FUNCTION_IS_NULL;
					_functionIsNotNull = DB2_FUNCTION_IS_NOT_NULL;

					if (_log.isInfoEnabled()) {
						_log.info("Detected DB2 with database name " + dbName);
					}
				}
				else if (dbName.startsWith("HSQL")) {
					_vendorHSQL = true;

					if (_log.isInfoEnabled()) {
						_log.info("Detected HSQL with database name " + dbName);
					}
				}
				else if (dbName.startsWith("Informix")) {
					_vendorInformix = true;
					_functionIsNull = INFORMIX_FUNCTION_IS_NULL;
					_functionIsNotNull = INFORMIX_FUNCTION_IS_NOT_NULL;

					if (_log.isInfoEnabled()) {
						_log.info(
							"Detected Informix with database name " + dbName);
					}
				}
				else if (dbName.startsWith("MySQL")) {
					_vendorMySQL = true;
					//_functionIsNull = MYSQL_FUNCTION_IS_NULL;
					//_functionIsNotNull = MYSQL_FUNCTION_IS_NOT_NULL;

					if (_log.isInfoEnabled()) {
						_log.info(
							"Detected MySQL with database name " + dbName);
					}
				}
				else if (dbName.startsWith("Sybase") || dbName.equals("ASE")) {
					_vendorSybase = true;
					_functionIsNull = SYBASE_FUNCTION_IS_NULL;
					_functionIsNotNull = SYBASE_FUNCTION_IS_NOT_NULL;

					if (_log.isInfoEnabled()) {
						_log.info(
							"Detected Sybase with database name " + dbName);
					}
				}
				else if (dbName.startsWith("Oracle")) {
					_vendorOracle = true;

					if (_log.isInfoEnabled()) {
						_log.info(
							"Detected Oracle with database name " + dbName);
					}
				}
				else if (dbName.startsWith("PostgreSQL")) {
					_vendorPostgreSQL = true;

					if (_log.isInfoEnabled()) {
						_log.info(
							"Detected PostgreSQL with database name " + dbName);
					}
				}
				else {
					if (_log.isDebugEnabled()) {
						_log.debug(
							"Unable to detect database with name " + dbName);
					}
				}
			}
		}
		catch (Exception e) {
			_log.error(e, e);
		}
		finally {
			DataAccess.cleanUp(con);
		}

		try {
			Class clazz = getClass();

			ClassLoader classLoader = clazz.getClassLoader();

			String[] configs = getConfigs();

			Map sqlPool = new HashMap<>();

			for (String config : configs) {
				_read(classLoader, config, sqlPool);
			}

			_sqlPool = sqlPool;
		}
		catch (Exception e) {
			_log.error(e, e);
		}
	}

	public String removeGroupBy(String sql) {
		int x = sql.indexOf(_GROUP_BY_CLAUSE);

		if (x != -1) {
			int y = sql.indexOf(_ORDER_BY_CLAUSE);

			if (y == -1) {
				sql = sql.substring(0, x);
			}
			else {
				sql = sql.substring(0, x) + sql.substring(y);
			}
		}

		return sql;
	}

	public String removeOrderBy(String sql) {
		int pos = sql.indexOf(_ORDER_BY_CLAUSE);

		if (pos != -1) {
			sql = sql.substring(0, pos);
		}

		return sql;
	}

	public String replaceAndOperator(String sql, boolean andOperator) {
		String andOrConnector = "OR";
		String andOrNullCheck = "AND ? IS NOT NULL";

		if (andOperator) {
			andOrConnector = "AND";
			andOrNullCheck = "OR ? IS NULL";
		}

		sql = StringUtil.replace(
			sql, new String[] {"[$AND_OR_CONNECTOR$]", "[$AND_OR_NULL_CHECK$]"},
			new String[] {andOrConnector, andOrNullCheck});

		if (_vendorPostgreSQL) {
			sql = StringUtil.replace(
				sql,
				new String[] {
					"Date >= ? AND ? IS NOT NULL",
					"Date <= ? AND ? IS NOT NULL", "Date >= ? OR ? IS NULL",
					"Date <= ? OR ? IS NULL"
				},
				new String[] {
					"Date >= ? AND CAST(? AS TIMESTAMP) IS NOT NULL",
					"Date <= ? AND CAST(? AS TIMESTAMP) IS NOT NULL",
					"Date >= ? OR CAST(? AS TIMESTAMP) IS NULL",
					"Date <= ? OR CAST(? AS TIMESTAMP) IS NULL"
				});
		}

		sql = replaceIsNull(sql);

		return sql;
	}

	public String replaceGroupBy(String sql, String groupBy) {
		if (groupBy == null) {
			return sql;
		}

		int x = sql.indexOf(_GROUP_BY_CLAUSE);

		if (x != -1) {
			int y = sql.indexOf(_ORDER_BY_CLAUSE);

			if (y == -1) {
				sql = sql.substring(0, x + _GROUP_BY_CLAUSE.length());

				sql = sql.concat(groupBy);
			}
			else {
				sql = sql.substring(
					0, x + _GROUP_BY_CLAUSE.length()
				).concat(
					groupBy
				).concat(
					sql.substring(y)
				);
			}
		}
		else {
			int y = sql.indexOf(_ORDER_BY_CLAUSE);

			if (y == -1) {
				sql = sql.concat(
					_GROUP_BY_CLAUSE
				).concat(
					groupBy
				);
			}
			else {
				StringBundler sb = new StringBundler(4);

				sb.append(sql.substring(0, y));
				sb.append(_GROUP_BY_CLAUSE);
				sb.append(groupBy);
				sb.append(sql.substring(y));

				sql = sb.toString();
			}
		}

		return sql;
	}

	public String replaceIsNull(String sql) {
		if (Validator.isNotNull(_functionIsNull)) {
			sql = StringUtil.replace(
				sql, new String[] {"? IS NULL", "? IS NOT NULL"},
				new String[] {_functionIsNull, _functionIsNotNull});
		}

		return sql;
	}

	public String replaceKeywords(
		String sql, String field, boolean last, int[] values) {

		if ((values != null) && (values.length == 1)) {
			return sql;
		}

		StringBundler oldSqlSB = new StringBundler(4);

		oldSqlSB.append(StringPool.OPEN_PARENTHESIS);
		oldSqlSB.append(field);
		oldSqlSB.append(" = ?)");

		if (!last) {
			oldSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		if (ArrayUtil.isEmpty(values)) {
			return StringUtil.replace(
				sql, oldSqlSB.toString(), StringPool.BLANK);
		}

		StringBundler newSqlSB = new StringBundler(values.length * 4 + 3);

		newSqlSB.append(StringPool.OPEN_PARENTHESIS);

		for (int i = 0; i < values.length; i++) {
			if (i > 0) {
				newSqlSB.append(" OR ");
			}

			newSqlSB.append(StringPool.OPEN_PARENTHESIS);
			newSqlSB.append(field);
			newSqlSB.append(" = ?)");
		}

		newSqlSB.append(StringPool.CLOSE_PARENTHESIS);

		if (!last) {
			newSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		return StringUtil.replace(
			sql, oldSqlSB.toString(), newSqlSB.toString());
	}

	public String replaceKeywords(
		String sql, String field, boolean last, long[] values) {

		if ((values != null) && (values.length == 1)) {
			return sql;
		}

		StringBundler oldSqlSB = new StringBundler(4);

		oldSqlSB.append(StringPool.OPEN_PARENTHESIS);
		oldSqlSB.append(field);
		oldSqlSB.append(" = ?)");

		if (!last) {
			oldSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		if (ArrayUtil.isEmpty(values)) {
			return StringUtil.replace(
				sql, oldSqlSB.toString(), StringPool.BLANK);
		}

		StringBundler newSqlSB = new StringBundler(values.length * 4 + 3);

		newSqlSB.append(StringPool.OPEN_PARENTHESIS);

		for (int i = 0; i < values.length; i++) {
			if (i > 0) {
				newSqlSB.append(" OR ");
			}

			newSqlSB.append(StringPool.OPEN_PARENTHESIS);
			newSqlSB.append(field);
			newSqlSB.append(" = ?)");
		}

		newSqlSB.append(StringPool.CLOSE_PARENTHESIS);

		if (!last) {
			newSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		return StringUtil.replace(
			sql, oldSqlSB.toString(), newSqlSB.toString());
	}

	public String replaceKeywords(
		String sql, String field, String operator, boolean last,
		String[] values) {

		if ((values != null) && (values.length <= 1)) {
			return sql;
		}

		StringBundler oldSqlSB = new StringBundler(6);

		oldSqlSB.append(StringPool.OPEN_PARENTHESIS);
		oldSqlSB.append(field);
		oldSqlSB.append(" ");
		oldSqlSB.append(operator);
		oldSqlSB.append(" ? [$AND_OR_NULL_CHECK$])");

		if (!last) {
			oldSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		StringBundler newSqlSB = new StringBundler(values.length * 6 + 2);

		newSqlSB.append(StringPool.OPEN_PARENTHESIS);

		for (int i = 0; i < values.length; i++) {
			if (i > 0) {
				newSqlSB.append(" OR ");
			}

			newSqlSB.append(StringPool.OPEN_PARENTHESIS);
			newSqlSB.append(field);
			newSqlSB.append(" ");
			newSqlSB.append(operator);
			newSqlSB.append(" ? [$AND_OR_NULL_CHECK$])");
		}

		newSqlSB.append(StringPool.CLOSE_PARENTHESIS);

		if (!last) {
			newSqlSB.append(" [$AND_OR_CONNECTOR$]");
		}

		return StringUtil.replace(
			sql, oldSqlSB.toString(), newSqlSB.toString());
	}

	public String replaceOrderBy(String sql, OrderByComparator obc) {
		if (obc == null) {
			return sql;
		}

		String orderBy = obc.getOrderBy();

		int pos = sql.indexOf(_ORDER_BY_CLAUSE);

		if ((pos != -1) && (pos < sql.length())) {
			sql = sql.substring(0, pos + _ORDER_BY_CLAUSE.length());

			sql = sql.concat(orderBy);
		}
		else {
			sql = sql.concat(
				_ORDER_BY_CLAUSE
			).concat(
				orderBy
			);
		}

		return sql;
	}

	protected String[] getConfigs() {
		ClassLoader classLoader = CustomSQL.class.getClassLoader();

		if (PortalClassLoaderUtil.isPortalClassLoader(classLoader)) {
			Properties propsUtil = PortalUtil.getPortalProperties();

			return StringUtil.split(
				propsUtil.getProperty("custom.sql.configs"));
		}

		if (classLoader.getResource("portlet.properties") != null) {
			Configuration configuration =
				ConfigurationFactoryUtil.getConfiguration(
					classLoader, "portlet");

			return ArrayUtil.append(
				StringUtil.split(configuration.get("custom.sql.configs")),
				new String[] {
					"custom-sql/default.xml", "META-INF/custom-sql/default.xml"
				});
		}

		return new String[] {
			"custom-sql/default.xml", "META-INF/custom-sql/default.xml"
		};
	}

	protected String insertWildcard(String keyword, WildcardMode wildcardMode) {
		if (wildcardMode == WildcardMode.LEADING) {
			return StringPool.PERCENT.concat(keyword);
		}
		else if (wildcardMode == WildcardMode.SURROUND) {
			return StringUtil.quote(keyword, StringPool.PERCENT);
		}
		else if (wildcardMode == WildcardMode.TRAILING) {
			return keyword.concat(StringPool.PERCENT);
		}
		else {
			throw new IllegalArgumentException(
				"Invalid wildcard mode " + wildcardMode);
		}
	}

	/**
	 * @deprecated As of Judson (7.1.x), replaced by {@link #_read(ClassLoader,
	 *             String, Map)}
	 */
	@Deprecated
	protected void read(ClassLoader classLoader, String source) {
	}

	protected String transform(String sql) {
		sql = PortalUtil.transformCustomSQL(sql);

		StringBundler sb = new StringBundler();

		try (UnsyncBufferedReader unsyncBufferedReader =
				new UnsyncBufferedReader(new UnsyncStringReader(sql))) {

			String line = null;

			while ((line = unsyncBufferedReader.readLine()) != null) {
				line = line.trim();

				if (line.startsWith(StringPool.CLOSE_PARENTHESIS)) {
					sb.setIndex(sb.index() - 1);
				}

				sb.append(line);

				if (!line.endsWith(StringPool.OPEN_PARENTHESIS)) {
					sb.append(StringPool.SPACE);
				}
			}
		}
		catch (IOException ioe) {
			return sql;
		}

		return sb.toString();
	}

	private String _escapeWildCards(String keywords) {
		if (!isVendorMySQL() && !isVendorOracle()) {
			return keywords;
		}

		StringBuilder sb = new StringBuilder(keywords);

		for (int i = 0; i < sb.length(); ++i) {
			char c = sb.charAt(i);

			if (c == CharPool.BACK_SLASH) {
				i++;

				continue;
			}

			if ((c == CharPool.UNDERLINE) || (c == CharPool.PERCENT)) {
				sb.insert(i, CharPool.BACK_SLASH);

				i++;

				continue;
			}
		}

		return sb.toString();
	}

	private void _read(
			ClassLoader classLoader, String source, Map sqlPool)
		throws Exception {

		try (InputStream is = classLoader.getResourceAsStream(source)) {
			if (is == null) {
				return;
			}

			if (_log.isDebugEnabled()) {
				_log.debug("Loading " + source);
			}

			Document document = UnsecureSAXReaderUtil.read(is);

			Element rootElement = document.getRootElement();

			for (Element sqlElement : rootElement.elements("sql")) {
				String file = sqlElement.attributeValue("file");

				if (Validator.isNotNull(file)) {
					_read(classLoader, file, sqlPool);
				}
				else {
					String id = sqlElement.attributeValue("id");

					String content = transform(sqlElement.getText());

					content = replaceIsNull(content);

					sqlPool.put(id, content);
				}
			}
		}
	}

	private static final boolean _CUSTOM_SQL_AUTO_ESCAPE_WILDCARDS_ENABLED =
		GetterUtil.getBoolean(
			PropsUtil.get(PropsKeys.CUSTOM_SQL_AUTO_ESCAPE_WILDCARDS_ENABLED));

	private static final String _GROUP_BY_CLAUSE = " GROUP BY ";

	private static final String _ORDER_BY_CLAUSE = " ORDER BY ";

	private static final String _OWNER_USER_ID_AND_OR_CONNECTOR =
		"[$OWNER_USER_ID_AND_OR_CONNECTOR$]";

	private static final String _OWNER_USER_ID_CONDITION_DEFAULT = "userId = ?";

	private static final String _OWNER_USER_ID_KEYWORD = "[$OWNER_USER_ID$]";

	private static final String _STATUS_CONDITION_DEFAULT = "status = ?";

	private static final String _STATUS_CONDITION_EMPTY =
		WorkflowConstants.STATUS_ANY + " = ?";

	private static final String _STATUS_CONDITION_INVERSE = "status != ?";

	private static final String _STATUS_KEYWORD = "[$STATUS$]";

	private static final Log _log = LogFactoryUtil.getLog(CustomSQL.class);

	private String _functionIsNotNull;
	private String _functionIsNull;
	private volatile Map _sqlPool = Collections.emptyMap();
	private boolean _vendorDB2;
	private boolean _vendorHSQL;
	private boolean _vendorInformix;
	private boolean _vendorMySQL;
	private boolean _vendorOracle;
	private boolean _vendorPostgreSQL;
	private boolean _vendorSybase;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy