/** * 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.source.formatter.parser.comparator; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.NaturalOrderStringComparator; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.source.formatter.parser.JavaClass; import com.liferay.source.formatter.parser.JavaConstructor; import com.liferay.source.formatter.parser.JavaMethod; import com.liferay.source.formatter.parser.JavaParameter; import com.liferay.source.formatter.parser.JavaSignature; import com.liferay.source.formatter.parser.JavaStaticBlock; import com.liferay.source.formatter.parser.JavaTerm; import com.liferay.source.formatter.parser.JavaVariable; import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Hugo Huijser */ public class JavaTermComparator implements Comparator<JavaTerm> { public JavaTermComparator(String customSQLContent) { _customSQLContent = customSQLContent; } @Override public int compare(JavaTerm javaTerm1, JavaTerm javaTerm2) { int type1 = _getType(javaTerm1); int type2 = _getType(javaTerm2); if ((type1 == -1) || (type2 == -1)) { return 0; } if (type1 != type2) { return type1 - type2; } String name1 = javaTerm1.getName(); String name2 = javaTerm2.getName(); if (javaTerm1 instanceof JavaVariable) { if (StringUtil.isUpperCase(name1) && !StringUtil.isLowerCase(name1) && !StringUtil.isUpperCase(name2)) { return -1; } if (!StringUtil.isUpperCase(name1) && StringUtil.isUpperCase(name2) && !StringUtil.isLowerCase(name2)) { return 1; } if (javaTerm1.isStatic()) { String accessModifier = javaTerm1.getAccessModifier(); if (accessModifier.equals(JavaTerm.ACCESS_MODIFIER_PRIVATE)) { if (name2.equals("_log") || name2.equals("_logger")) { return 1; } if (name1.equals("_instance") || name1.equals("_log") || name1.equals("_logger")) { return -1; } if (name2.equals("_instance")) { return 1; } } } } if (Validator.isNotNull(_customSQLContent) && (name1.compareToIgnoreCase(name2) != 0)) { int value = _compareFinderJavaTerms(javaTerm1, javaTerm2); if (value != 0) { return value; } } if (name1.compareToIgnoreCase(name2) != 0) { NaturalOrderStringComparator naturalOrderStringComparator = new NaturalOrderStringComparator(true, false); return naturalOrderStringComparator.compare(name1, name2); } if (name1.compareTo(name2) != 0) { NaturalOrderStringComparator naturalOrderStringComparator = new NaturalOrderStringComparator(true, true); return -naturalOrderStringComparator.compare(name1, name2); } return _compareParameterTypes(javaTerm1, javaTerm2); } private int _compareFinderJavaTerms( JavaTerm javaTerm1, JavaTerm javaTerm2) { Matcher matcher1 = _finderPattern.matcher(javaTerm1.getName()); if (!matcher1.find()) { return 0; } Matcher matcher2 = _finderPattern.matcher(javaTerm2.getName()); if (!matcher2.find()) { return 0; } String namePart1 = matcher1.group(1); String namePart2 = matcher2.group(1); if (!namePart1.equals(namePart2)) { return 0; } String customSQLKey1 = _getCustomSQLKey(javaTerm1); String customSQLKey2 = _getCustomSQLKey(javaTerm2); if ((customSQLKey1 == null) || (customSQLKey2 == null)) { return 0; } int startsWithWeight = StringUtil.startsWithWeight( customSQLKey1, customSQLKey2); if (startsWithWeight != 0) { String startKey = customSQLKey1.substring(0, startsWithWeight); if (!startKey.contains("By")) { NaturalOrderStringComparator comparator = new NaturalOrderStringComparator(); return comparator.compare(customSQLKey1, customSQLKey2); } } int pos1 = _customSQLContent.indexOf(customSQLKey1); int pos2 = _customSQLContent.indexOf(customSQLKey2); if ((pos1 != -1) && (pos2 != -1)) { return pos1 - pos2; } int columnCount1 = StringUtil.count( javaTerm1.getName(), CharPool.UNDERLINE); int columnCount2 = StringUtil.count( javaTerm2.getName(), CharPool.UNDERLINE); return columnCount1 - columnCount2; } private int _compareParameterTypes(JavaTerm javaTerm1, JavaTerm javaTerm2) { JavaSignature javaSignature1 = javaTerm1.getSignature(); JavaSignature javaSignature2 = javaTerm2.getSignature(); if ((javaSignature1 == null) || (javaSignature1 == null)) { return 0; } List<JavaParameter> parameters1 = javaSignature1.getParameters(); List<JavaParameter> parameters2 = javaSignature2.getParameters(); if (parameters2.isEmpty()) { if (parameters1.isEmpty()) { return 0; } return 1; } if (parameters1.isEmpty()) { return -1; } for (int i = 0; i < parameters1.size(); i++) { if (parameters2.size() < (i + 1)) { return 1; } JavaParameter parameter1 = parameters1.get(i); JavaParameter parameter2 = parameters2.get(i); String parameterType1 = parameter1.getParameterType(); String parameterType2 = parameter2.getParameterType(); if ((parameters1.size() != parameters2.size()) && (parameterType1.equals(parameterType2.concat("...")) || parameterType2.equals(parameterType1.concat("...")))) { continue; } if (parameterType1.compareToIgnoreCase(parameterType2) != 0) { return parameterType1.compareToIgnoreCase(parameterType2); } if (parameterType1.compareTo(parameterType2) != 0) { return -parameterType1.compareTo(parameterType2); } } if (parameters1.size() == parameters2.size()) { return 0; } return -1; } private String _getCustomSQLKey(JavaTerm javaTerm) { JavaClass javaClass = javaTerm.getParentJavaClass(); String javaClassName = javaClass.getName(); String objectName = StringUtil.replaceLast( javaClassName, "Impl", StringPool.BLANK); String javaTermName = javaTerm.getName(); if (javaTermName.matches("(COUNT|FIND|JOIN)_.*")) { Matcher matcher = _sqlKeyPattern.matcher(javaTerm.getContent()); if (matcher.find()) { return objectName + StringPool.PERIOD + matcher.group(1); } return null; } String sqlKey = javaTermName.replaceFirst( "^(do|filter)", StringPool.BLANK); sqlKey = StringUtil.toLowerCase(sqlKey.substring(0, 1)) + sqlKey.substring(1); return objectName + StringPool.PERIOD + sqlKey; } private int _getType(JavaTerm javaTerm) { if (javaTerm instanceof JavaStaticBlock) { return -1; } String accessModifier = javaTerm.getAccessModifier(); if (accessModifier.equals(JavaTerm.ACCESS_MODIFIER_PUBLIC)) { if (javaTerm.isStatic()) { if (javaTerm instanceof JavaVariable) { return 1; } if (javaTerm instanceof JavaMethod) { return 2; } if (javaTerm instanceof JavaClass) { return 6; } } else { if (javaTerm instanceof JavaConstructor) { return 3; } if (javaTerm instanceof JavaMethod) { return 4; } if (javaTerm instanceof JavaVariable) { return 5; } if (javaTerm instanceof JavaClass) { return 7; } } } if (accessModifier.equals(JavaTerm.ACCESS_MODIFIER_PROTECTED)) { if (javaTerm.isStatic()) { if (javaTerm instanceof JavaMethod) { return 8; } if (javaTerm instanceof JavaVariable) { return 11; } if (javaTerm instanceof JavaClass) { return 13; } } else { if (javaTerm instanceof JavaConstructor) { return 9; } if (javaTerm instanceof JavaMethod) { return 10; } if (javaTerm instanceof JavaVariable) { return 12; } if (javaTerm instanceof JavaClass) { return 14; } } } if (accessModifier.equals(JavaTerm.ACCESS_MODIFIER_PRIVATE)) { if (javaTerm.isStatic()) { if (javaTerm instanceof JavaMethod) { return 15; } if (javaTerm instanceof JavaVariable) { return 18; } if (javaTerm instanceof JavaClass) { return 20; } } else { if (javaTerm instanceof JavaConstructor) { return 16; } if (javaTerm instanceof JavaMethod) { return 17; } if (javaTerm instanceof JavaVariable) { return 19; } if (javaTerm instanceof JavaClass) { return 21; } } } return -1; } private final String _customSQLContent; private final Pattern _finderPattern = Pattern.compile( "((COUNT|FIND|JOIN)_|(do|filter)?([Cc]ount|[Ff]ind)).*"); private final Pattern _sqlKeyPattern = Pattern.compile( "\"\\.([^\"]+)\";\n"); }