/** * 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.portal.dao.orm.hibernate; import com.liferay.portal.kernel.cache.PortalCache; import com.liferay.portal.kernel.cache.SingleVMPoolUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.StringUtil; import java.util.HashSet; import java.util.Set; /** * @author Shuyang Zhou */ public class SQLQueryTableNamesUtil { public static String[] getTableNames(String sql) { String[] tableNames = _portalCache.get(sql); if (tableNames != null) { return tableNames; } String lowerCaseSQL = StringUtil.toLowerCase(sql); Set<String> tableNameSet = new HashSet<>(); // Find table name from the "from" clause int index = 0; while ((index = lowerCaseSQL.indexOf(" from ", index)) != -1) { index += 6; int[] indexes = _getTableNameIndexes(lowerCaseSQL, index); if (indexes != null) { tableNameSet.add(sql.substring(indexes[0], indexes[1])); } } // Find table name from the "join" clause index = 0; while ((index = lowerCaseSQL.indexOf(" join ", index)) != -1) { index += 6; int[] indexes = _getTableNameIndexes(lowerCaseSQL, index); if (indexes != null) { tableNameSet.add(sql.substring(indexes[0], indexes[1])); } } tableNames = tableNameSet.toArray(new String[tableNameSet.size()]); _portalCache.put(sql, tableNames); return tableNames; } private static int[] _getTableNameIndexes(String sql, int index) { int start = -1; int end = sql.length(); for (int i = index; i < sql.length(); i++) { char c = sql.charAt(i); if (c == CharPool.OPEN_PARENTHESIS) { // There is a subquery in the current clause, so no need to // parse for a table name break; } else if ((c == CharPool.SPACE) || (c == CharPool.CLOSE_PARENTHESIS)) { if (start != -1) { end = i; break; } } else if (start == -1) { start = i; } } if (start == -1) { return null; } return new int[] {start, end}; } private static final PortalCache<String, String[]> _portalCache = SingleVMPoolUtil.getPortalCache(SQLQueryTableNamesUtil.class.getName()); }