blob: dfd6c9c93548d6853bac05eb7fe3c55e79836511 [file] [log] [blame]
/*
* Copyright 2000-2014 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.framework.detection.impl;
import com.intellij.framework.detection.DetectedFrameworkDescription;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorIntegerDescriptor;
import com.intellij.util.io.PersistentHashMap;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntIterator;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* @author nik
*/
public class DetectedFrameworksData {
private static final Logger LOG = Logger.getInstance("#com.intellij.framework.detection.impl.DetectedFrameworksData");
private PersistentHashMap<Integer,TIntHashSet> myExistentFrameworkFiles;
private final TIntObjectHashMap<TIntHashSet> myNewFiles;
private final MultiMap<Integer, DetectedFrameworkDescription> myDetectedFrameworks;
public DetectedFrameworksData(Project project) {
myDetectedFrameworks = new MultiMap<Integer, DetectedFrameworkDescription>();
File file = new File(FrameworkDetectorRegistryImpl.getDetectionDirPath() + File.separator + project.getName() + "." + project.getLocationHash() +
File.separator + "files");
myNewFiles = new TIntObjectHashMap<TIntHashSet>();
try {
myExistentFrameworkFiles = new PersistentHashMap<Integer, TIntHashSet>(file, EnumeratorIntegerDescriptor.INSTANCE, new TIntHashSetExternalizer());
}
catch (IOException e) {
LOG.info(e);
PersistentHashMap.deleteFilesStartingWith(file);
try {
myExistentFrameworkFiles = new PersistentHashMap<Integer, TIntHashSet>(file, EnumeratorIntegerDescriptor.INSTANCE, new TIntHashSetExternalizer());
}
catch (IOException e1) {
LOG.error(e1);
}
}
}
public void saveDetected() {
try {
myExistentFrameworkFiles.close();
}
catch (IOException e) {
LOG.info(e);
}
}
public Collection<VirtualFile> retainNewFiles(@NotNull Integer detectorId, @NotNull Collection<VirtualFile> files) {
TIntHashSet oldSet = myNewFiles.get(detectorId);
if (oldSet == null) {
oldSet = new TIntHashSet();
myNewFiles.put(detectorId, oldSet);
}
TIntHashSet existentFilesSet = null;
try {
existentFilesSet = myExistentFrameworkFiles.get(detectorId);
}
catch (IOException e) {
LOG.info(e);
}
final ArrayList<VirtualFile> newFiles = new ArrayList<VirtualFile>();
TIntHashSet newSet = new TIntHashSet();
for (VirtualFile file : files) {
final int fileId = FileBasedIndex.getFileId(file);
if (existentFilesSet == null || !existentFilesSet.contains(fileId)) {
newFiles.add(file);
newSet.add(fileId);
}
}
if (newSet.equals(oldSet)) {
return Collections.emptyList();
}
myNewFiles.put(detectorId, newSet);
return newFiles;
}
public Set<Integer> getDetectorsForDetectedFrameworks() {
return myDetectedFrameworks.keySet();
}
public Collection<? extends DetectedFrameworkDescription> updateFrameworksList(Integer detectorId,
Collection<? extends DetectedFrameworkDescription> frameworks) {
final Collection<DetectedFrameworkDescription> oldFrameworks = myDetectedFrameworks.remove(detectorId);
myDetectedFrameworks.putValues(detectorId, frameworks);
if (oldFrameworks != null) {
frameworks.removeAll(oldFrameworks);
}
return frameworks;
}
public void putExistentFrameworkFiles(Integer id, Collection<? extends VirtualFile> files) {
TIntHashSet set = null;
try {
set = myExistentFrameworkFiles.get(id);
}
catch (IOException e) {
LOG.info(e);
}
if (set == null) {
set = new TIntHashSet();
try {
myExistentFrameworkFiles.put(id, set);
}
catch (IOException e) {
LOG.info(e);
}
}
for (VirtualFile file : files) {
set.add(FileBasedIndex.getFileId(file));
}
}
private static class TIntHashSetExternalizer implements DataExternalizer<TIntHashSet> {
@Override
public void save(@NotNull DataOutput out, TIntHashSet value) throws IOException {
out.writeInt(value.size());
final TIntIterator iterator = value.iterator();
while (iterator.hasNext()) {
out.writeInt(iterator.next());
}
}
@Override
public TIntHashSet read(@NotNull DataInput in) throws IOException {
int size = in.readInt();
final TIntHashSet set = new TIntHashSet(size);
while (size-- > 0) {
set.add(in.readInt());
}
return set;
}
}
}