package fr.adrienbrault.idea.symfony2plugin.util;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.text.VersionComparatorUtil;
import com.jetbrains.php.lang.psi.elements.Field;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
import static org.apache.commons.lang.StringUtils.isBlank;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class SymfonyUtil {
private static final Key<CachedValue<Set<String>>> CACHE = new Key<>("SYMFONY_VERSION_CACHE");
private static boolean compare(@NotNull Project project, @NotNull String version, @NotNull Comparator comparator) {
CachedValue<Set<String>> cache = project.getUserData(CACHE);
if (cache == null) {
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
CachedValueProvider.Result.create(getVersions(project), PsiModificationTracker.MODIFICATION_COUNT),
false
);
project.putUserData(CACHE, cache);
}
for (String s : cache.getValue()) {
if(comparator.accepts(s)) {
return true;
}
}
return false;
}
@NotNull
private static Set<String> getVersions(@NotNull Project project) {
Set<String> versions = new HashSet<>();
for (PhpClass phpClass : PhpElementsUtil.getClassesInterface(project, "Symfony\\Component\\HttpKernel\\Kernel")) {
Field versionField = phpClass.findFieldByName("VERSION", true);
if(versionField == null) {
continue;
}
PsiElement defaultValue = versionField.getDefaultValue();
if(!(defaultValue instanceof StringLiteralExpression)) {
continue;
}
String contents = ((StringLiteralExpression) defaultValue).getContents();
if(isBlank(contents)) {
continue;
}
// 3.2.0-DEV, 3.2.0-RC1
contents = contents.toLowerCase().replaceAll("(.*)-([\\w]+)$", "$1");
versions.add(contents);
}
return versions;
}
public static boolean isVersionGreaterThenEquals(@NotNull Project project, @NotNull String version) {
return compare(project, version, contents -> VersionComparatorUtil.compare(contents, version) >= 0);
}
public static boolean isVersionGreaterThen(@NotNull Project project, @NotNull String version) {
return compare(project, version, contents -> VersionComparatorUtil.compare(contents, version) > 0);
}
public static boolean isVersionLessThenEquals(@NotNull Project project, @NotNull String version) {
return compare(project, version, contents -> VersionComparatorUtil.compare(contents, version) <= 0);
}
public static boolean isVersionLessThen(@NotNull Project project, @NotNull String version) {
return compare(project, version, contents -> VersionComparatorUtil.compare(contents, version) < 0);
}
private interface Comparator {
boolean accepts(@NotNull String contents);
}
}