blob: d2db31c4728e01a48f3635996b9250ee41a7082c [file] [log] [blame]
/*
* Copyright 2000-2009 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 org.jetbrains.idea.maven.indices;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import gnu.trove.THashSet;
import org.apache.lucene.search.Query;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectChanges;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.project.MavenProjectsTree;
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
import org.jetbrains.idea.maven.utils.MavenMergingUpdateQueue;
import org.jetbrains.idea.maven.utils.MavenSimpleProjectComponent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class MavenProjectIndicesManager extends MavenSimpleProjectComponent {
private volatile List<MavenIndex> myProjectIndices = new ArrayList<MavenIndex>();
private final MergingUpdateQueue myUpdateQueue;
public static MavenProjectIndicesManager getInstance(Project p) {
return p.getComponent(MavenProjectIndicesManager.class);
}
public MavenProjectIndicesManager(Project project) {
super(project);
myUpdateQueue = new MavenMergingUpdateQueue(getClass().getSimpleName(), 1000, true, project);
}
@Override
public void initComponent() {
if (!isNormalProject()) return;
doInit();
}
public void doInit() {
if (ApplicationManager.getApplication().isUnitTestMode()) {
scheduleUpdateIndicesList();
}
getMavenProjectManager().addManagerListener(new MavenProjectsManager.Listener() {
public void activated() {
scheduleUpdateIndicesList();
}
public void projectsScheduled() {
}
@Override
public void importAndResolveScheduled() {
}
});
getMavenProjectManager().addProjectsTreeListener(new MavenProjectsTree.ListenerAdapter() {
@Override
public void projectsUpdated(List<Pair<MavenProject, MavenProjectChanges>> updated, List<MavenProject> deleted) {
scheduleUpdateIndicesList();
}
@Override
public void projectResolved(Pair<MavenProject, MavenProjectChanges> projectWithChanges,
NativeMavenProjectHolder nativeMavenProject) {
scheduleUpdateIndicesList();
}
});
}
private void scheduleUpdateIndicesList() {
scheduleUpdateIndicesList(null);
}
public void scheduleUpdateIndicesList(@Nullable final Consumer<List<MavenIndex>> consumer) {
myUpdateQueue.queue(new Update(MavenProjectIndicesManager.this) {
public void run() {
Set<Pair<String, String>> remoteRepositoriesIdsAndUrls;
File localRepository;
AccessToken accessToken = ReadAction.start();
try {
if (myProject.isDisposed()) return;
remoteRepositoriesIdsAndUrls = collectRemoteRepositoriesIdsAndUrls();
localRepository = getLocalRepository();
}
finally {
accessToken.finish();
}
myProjectIndices = MavenIndicesManager.getInstance().ensureIndicesExist(myProject, localRepository, remoteRepositoriesIdsAndUrls);
if(consumer != null) {
consumer.consume(myProjectIndices);
}
}
});
}
private File getLocalRepository() {
return MavenProjectsManager.getInstance(myProject).getLocalRepository();
}
private Set<Pair<String, String>> collectRemoteRepositoriesIdsAndUrls() {
Set<Pair<String, String>> result = new THashSet<Pair<String, String>>();
Set<MavenRemoteRepository> remoteRepositories = ContainerUtil.newHashSet(getMavenProjectManager().getRemoteRepositories());
for (MavenRepositoryProvider repositoryProvider : MavenRepositoryProvider.EP_NAME.getExtensions()) {
ContainerUtil.addAll(remoteRepositories, repositoryProvider.getRemoteRepositories(myProject));
}
for (MavenRemoteRepository each : remoteRepositories) {
String id = each.getId();
String url = each.getUrl();
result.add(Pair.create(id, url));
}
return result;
}
public List<MavenIndex> getIndices() {
return new ArrayList<MavenIndex>(myProjectIndices);
}
public void scheduleUpdateAll() {
MavenIndicesManager.getInstance().scheduleUpdate(myProject, myProjectIndices);
}
public void scheduleUpdate(List<MavenIndex> indices) {
MavenIndicesManager.getInstance().scheduleUpdate(myProject, indices);
}
public MavenIndicesManager.IndexUpdatingState getUpdatingState(MavenIndex index) {
return MavenIndicesManager.getInstance().getUpdatingState(index);
}
private MavenProjectsManager getMavenProjectManager() {
return MavenProjectsManager.getInstance(myProject);
}
public Set<String> getGroupIds() {
Set<String> result = getProjectGroupIds();
for (MavenIndex each : myProjectIndices) {
result.addAll(each.getGroupIds());
}
return result;
}
public Set<String> getArtifactIds(String groupId) {
Set<String> result = getProjectArtifactIds(groupId);
for (MavenIndex each : myProjectIndices) {
result.addAll(each.getArtifactIds(groupId));
}
return result;
}
public Set<String> getVersions(String groupId, String artifactId) {
Set<String> result = getProjectVersions(groupId, artifactId);
for (MavenIndex each : myProjectIndices) {
result.addAll(each.getVersions(groupId, artifactId));
}
return result;
}
public boolean hasGroupId(String groupId) {
if (hasProjectGroupId(groupId)) return true;
for (MavenIndex each : myProjectIndices) {
if (each.hasGroupId(groupId)) return true;
}
return checkLocalRepository(groupId, null, null);
}
private boolean checkLocalRepository(String groupId, String artifactId, String version) {
if (StringUtil.isEmpty(groupId)) return false;
String relPath = groupId.replace('.', '/');
if (artifactId != null) {
relPath += "/" + artifactId;
if (version != null) {
relPath += "/" + version + "/" + artifactId + "-" + version + ".pom";
}
}
File file = new File(getLocalRepository(), relPath);
return file.exists();
}
public boolean hasArtifactId(String groupId, String artifactId) {
if (hasProjectArtifactId(groupId, artifactId)) return true;
for (MavenIndex each : myProjectIndices) {
if (each.hasArtifactId(groupId, artifactId)) return true;
}
return checkLocalRepository(groupId, artifactId, null);
}
public boolean hasVersion(String groupId, String artifactId, String version) {
if (hasProjectVersion(groupId, artifactId, version)) return true;
for (MavenIndex each : myProjectIndices) {
if (each.hasVersion(groupId, artifactId, version)) return true;
}
return checkLocalRepository(groupId, artifactId, version);
}
public Set<MavenArtifactInfo> search(Query query, int maxResult) {
Set<MavenArtifactInfo> result = new THashSet<MavenArtifactInfo>();
for (MavenIndex each : myProjectIndices) {
int remained = maxResult - result.size();
if (remained <= 0) break;
result.addAll(each.search(query, remained));
}
return result;
}
private Set<String> getProjectGroupIds() {
Set<String> result = new THashSet<String>();
for (MavenId each : getProjectsIds()) {
result.add(each.getGroupId());
}
return result;
}
private Set<String> getProjectArtifactIds(String groupId) {
Set<String> result = new THashSet<String>();
for (MavenId each : getProjectsIds()) {
if (groupId.equals(each.getGroupId())) {
result.add(each.getArtifactId());
}
}
return result;
}
private Set<String> getProjectVersions(String groupId, String artifactId) {
Set<String> result = new THashSet<String>();
for (MavenId each : getProjectsIds()) {
if (groupId.equals(each.getGroupId()) && artifactId.equals(each.getArtifactId())) {
result.add(each.getVersion());
}
}
return result;
}
private boolean hasProjectGroupId(String groupId) {
return getProjectGroupIds().contains(groupId);
}
private boolean hasProjectArtifactId(String groupId, String artifactId) {
return getProjectArtifactIds(groupId).contains(artifactId);
}
private boolean hasProjectVersion(String groupId, String artifactId, String version) {
return getProjectVersions(groupId, artifactId).contains(version);
}
private Set<MavenId> getProjectsIds() {
Set<MavenId> result = new THashSet<MavenId>();
for (MavenProject each : MavenProjectsManager.getInstance(myProject).getProjects()) {
result.add(each.getMavenId());
}
return result;
}
}