| /* |
| * 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; |
| } |
| } |
| } |