blob: cc1d2bac30ef077d02675672b433152c7b776f19 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.classFilesIndex.api.index;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.io.PersistentHashMap;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.classFilesIndex.indexer.api.IndexState;
import org.jetbrains.jps.classFilesIndex.indexer.api.storage.ClassFilesIndexStorageBase;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import java.io.File;
import java.io.IOException;
/**
* @author Dmitry Batkovich
*/
public abstract class ClassFilesIndexReaderBase<K, V> {
public static final String VERSION_FILE_NAME = "version";
private final static Logger LOG = Logger.getInstance(ClassFilesIndexReaderBase.class);
@Nullable
protected final ClassFilesIndexStorageReader<K, V> myIndex;
@Nullable
protected final Mappings myMappings;
public static boolean checkIndexAndRecreateIfNeed(final Project project, final int currentVersion, final String canonicalIndexName) {
final File projectBuildSystemDirectory = BuildManager.getInstance().getProjectSystemDirectory(project);
assert projectBuildSystemDirectory != null;
final File versionFile = new File(ClassFilesIndexStorageBase.getIndexDir(canonicalIndexName, projectBuildSystemDirectory), VERSION_FILE_NAME);
final File indexDir = ClassFilesIndexStorageBase.getIndexDir(canonicalIndexName, projectBuildSystemDirectory);
if (versionFile.exists() &&
!versionDiffers(projectBuildSystemDirectory, canonicalIndexName, currentVersion) &&
IndexState.load(indexDir) == IndexState.EXIST) {
return true;
}
else {
recreateIndex(canonicalIndexName, currentVersion, projectBuildSystemDirectory, indexDir);
return false;
}
}
@SuppressWarnings("ConstantConditions")
protected ClassFilesIndexReaderBase(final KeyDescriptor<K> keyDescriptor,
final DataExternalizer<V> valueExternalizer,
final String canonicalIndexName,
final int indexVersion,
final Project project) {
if (checkIndexAndRecreateIfNeed(project, indexVersion, canonicalIndexName)) {
ClassFilesIndexStorageReader<K, V> index = null;
IOException exception = null;
final File projectBuildSystemDirectory = BuildManager.getInstance().getProjectSystemDirectory(project);
final File indexDir = ClassFilesIndexStorageBase.getIndexDir(canonicalIndexName, projectBuildSystemDirectory);
try {
index = new ClassFilesIndexStorageReader<K, V>(indexDir, keyDescriptor, valueExternalizer);
}
catch (final IOException e) {
exception = e;
PersistentHashMap.deleteFilesStartingWith(ClassFilesIndexStorageBase.getIndexFile(indexDir));
}
if (exception != null) {
recreateIndex(canonicalIndexName, indexVersion, projectBuildSystemDirectory, indexDir);
myIndex = null;
myMappings = null;
}
else {
myIndex = index;
try {
myMappings = new Mappings(BuildDataManager.getMappingsRoot(projectBuildSystemDirectory),false);
}
catch (final IOException e) {
throw new RuntimeException(e);
}
}
}
else {
myIndex = null;
myMappings = null;
}
}
private static void recreateIndex(final String canonicalIndexName,
final int indexVersion,
final File projectBuildSystemDirectory,
final File indexDir) {
if (indexDir.exists()) {
FileUtil.delete(indexDir);
}
try {
FileUtil.writeToFile(new File(ClassFilesIndexStorageBase.getIndexDir(canonicalIndexName, projectBuildSystemDirectory), VERSION_FILE_NAME),
String.valueOf(indexVersion));
}
catch (final IOException e) {
throw new RuntimeException(e);
}
IndexState.NOT_EXIST.save(indexDir);
}
public boolean isEmpty() {
return myIndex == null;
}
public final void close() {
if (myIndex != null) {
try {
myIndex.close();
}
catch (final IOException e) {
throw new RuntimeException(e);
}
}
}
public final void delete() {
try {
if (myIndex != null) {
myIndex.delete();
}
}
catch (final IOException e) {
throw new RuntimeException(e);
}
}
private static File getVersionFile(final File projectBuildSystemDirectory, final String canonicalIndexName) {
return new File(ClassFilesIndexStorageBase.getIndexDir(canonicalIndexName, projectBuildSystemDirectory), VERSION_FILE_NAME);
}
private static boolean versionDiffers(final File projectBuildSystemDirectory, final String canonicalIndexName, final int currentVersion) {
final File versionFile = getVersionFile(projectBuildSystemDirectory, canonicalIndexName);
if (!versionFile.exists()) {
return true;
}
try {
return Integer.parseInt(FileUtil.loadFile(versionFile)) != currentVersion;
}
catch (final IOException e) {
LOG.error("error while reading version file " + versionFile.getAbsolutePath());
return true;
}
}
}