blob: 84ab4ffc247e756949acfe77baf9309b2d6549f0 [file] [log] [blame]
/*
* Copyright 2000-2012 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.project.model.impl.module.content;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ContentFolder;
import com.intellij.openapi.roots.ExcludeFolder;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.roots.impl.DirectoryIndexExcludePolicy;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.project.model.impl.module.JpsRootModel;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author nik
*/
public class JpsContentEntry implements ContentEntry, Disposable {
private final VirtualFilePointer myRoot;
private final JpsModule myModule;
private final JpsRootModel myRootModel;
private final List<JpsSourceFolder> mySourceFolders;
private final List<JpsExcludeFolder> myExcludeFolders;
public JpsContentEntry(JpsModule module, JpsRootModel rootModel, String rootUrl) {
myModule = module;
myRootModel = rootModel;
myRoot = VirtualFilePointerManager.getInstance().create(rootUrl, this, null);
mySourceFolders = new ArrayList<JpsSourceFolder>();
String rootPath = VfsUtilCore.urlToPath(getUrl());
for (JpsModuleSourceRoot root : myModule.getSourceRoots()) {
if (FileUtil.isAncestor(rootPath, VfsUtilCore.urlToPath(root.getUrl()), false)) {
mySourceFolders.add(new JpsSourceFolder(root, this));
}
}
myExcludeFolders = new ArrayList<JpsExcludeFolder>();
for (String excludedUrl : myModule.getExcludeRootsList().getUrls()) {
if (FileUtil.isAncestor(rootPath, VfsUtilCore.urlToPath(excludedUrl), false)) {
myExcludeFolders.add(new JpsExcludeFolder(excludedUrl, this));
}
}
}
@Override
public VirtualFile getFile() {
return myRoot.getFile();
}
@NotNull
@Override
public String getUrl() {
return myRoot.getUrl();
}
@NotNull
@Override
public SourceFolder[] getSourceFolders() {
return mySourceFolders.toArray(new SourceFolder[mySourceFolders.size()]);
}
@NotNull
@Override
public List<SourceFolder> getSourceFolders(@NotNull JpsModuleSourceRootType<?> rootType) {
return getSourceFolders(Collections.singleton(rootType));
}
@NotNull
@Override
public List<SourceFolder> getSourceFolders(@NotNull Set<? extends JpsModuleSourceRootType<?>> rootTypes) {
List<SourceFolder> folders = new SmartList<SourceFolder>();
for (JpsSourceFolder folder : mySourceFolders) {
if (rootTypes.contains(folder.getRootType())) {
folders.add(folder);
}
}
return folders;
}
@NotNull
@Override
public VirtualFile[] getSourceFolderFiles() {
return getFiles(getSourceFolders());
}
private static VirtualFile[] getFiles(ContentFolder[] sourceFolders) {
ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(sourceFolders.length);
for (ContentFolder sourceFolder : sourceFolders) {
final VirtualFile file = sourceFolder.getFile();
if (file != null) {
result.add(file);
}
}
return VfsUtilCore.toVirtualFileArray(result);
}
@NotNull
@Override
public ExcludeFolder[] getExcludeFolders() {
return myExcludeFolders.toArray(new ExcludeFolder[myExcludeFolders.size()]);
}
@NotNull
@Override
public List<String> getExcludeFolderUrls() {
List<String> excluded = new ArrayList<String>();
for (JpsExcludeFolder folder : myExcludeFolders) {
excluded.add(folder.getUrl());
}
for (DirectoryIndexExcludePolicy excludePolicy : Extensions
.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, myRootModel.getProject())) {
for (VirtualFilePointer pointer : excludePolicy.getExcludeRootsForModule(myRootModel)) {
excluded.add(pointer.getUrl());
}
}
return excluded;
}
@NotNull
@Override
public VirtualFile[] getExcludeFolderFiles() {
List<VirtualFile> excluded = new ArrayList<VirtualFile>();
for (JpsExcludeFolder folder : myExcludeFolders) {
ContainerUtil.addIfNotNull(excluded, folder.getFile());
}
for (DirectoryIndexExcludePolicy excludePolicy : Extensions.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, myRootModel.getProject())) {
for (VirtualFilePointer pointer : excludePolicy.getExcludeRootsForModule(myRootModel)) {
ContainerUtil.addIfNotNull(excluded, pointer.getFile());
}
}
return VfsUtilCore.toVirtualFileArray(excluded);
}
@NotNull
@Override
public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource) {
return addSourceFolder(file, isTestSource, "");
}
@NotNull
@Override
public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix) {
return addSourceFolder(file.getUrl(), isTestSource, packagePrefix);
}
@NotNull
@Override
public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull VirtualFile file,
@NotNull JpsModuleSourceRootType<P> type,
@NotNull P properties) {
final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(file.getUrl(), type, properties);
final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
mySourceFolders.add(sourceFolder);
return sourceFolder;
}
@NotNull
@Override
public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull VirtualFile file, @NotNull JpsModuleSourceRootType<P> type) {
return addSourceFolder(file, type, type.createDefaultProperties());
}
private SourceFolder addSourceFolder(final String url, boolean isTestSource, String packagePrefix) {
final JavaSourceRootType rootType = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
JavaSourceRootProperties properties = JpsJavaExtensionService.getInstance().createSourceRootProperties(packagePrefix);
return addSourceFolder(url, rootType, properties);
}
@NotNull
@Override
public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
return addSourceFolder(url, isTestSource, "");
}
@NotNull
@Override
public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type) {
return addSourceFolder(url, type, type.createDefaultProperties());
}
@NotNull
public <P extends JpsElement> SourceFolder addSourceFolder(@NotNull String url, @NotNull JpsModuleSourceRootType<P> type, @NotNull P properties) {
final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(url, type, properties);
final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this);
mySourceFolders.add(sourceFolder);
return sourceFolder;
}
@Override
public void removeSourceFolder(@NotNull SourceFolder sourceFolder) {
final JpsSourceFolder folder = (JpsSourceFolder)sourceFolder;
mySourceFolders.remove(folder);
myModule.removeSourceRoot(folder.getSourceRoot().getUrl(), folder.getSourceRoot().getRootType());
Disposer.dispose(folder);
}
@Override
public void clearSourceFolders() {
List<JpsModuleSourceRoot> toRemove = new ArrayList<JpsModuleSourceRoot>();
for (JpsSourceFolder folder : mySourceFolders) {
toRemove.add(folder.getSourceRoot());
Disposer.dispose(folder);
}
mySourceFolders.clear();
for (JpsModuleSourceRoot root : toRemove) {
myModule.removeSourceRoot(root.getUrl(), root.getRootType());
}
}
@Override
public ExcludeFolder addExcludeFolder(@NotNull VirtualFile file) {
return addExcludeFolder(file.getUrl());
}
@Override
public ExcludeFolder addExcludeFolder(@NotNull String url) {
final JpsExcludeFolder folder = new JpsExcludeFolder(url, this);
myModule.getExcludeRootsList().addUrl(url);
myExcludeFolders.add(folder);
return folder;
}
@Override
public void removeExcludeFolder(@NotNull ExcludeFolder excludeFolder) {
JpsExcludeFolder folder = (JpsExcludeFolder)excludeFolder;
myExcludeFolders.remove(folder);
myModule.getExcludeRootsList().removeUrl(folder.getUrl());
Disposer.dispose(folder);
}
@Override
public boolean removeExcludeFolder(@NotNull String url) {
for (JpsExcludeFolder folder : myExcludeFolders) {
if (folder.getUrl().equals(url)) {
myExcludeFolders.remove(folder);
myModule.getExcludeRootsList().removeUrl(url);
Disposer.dispose(folder);
return true;
}
}
return false;
}
@Override
public void clearExcludeFolders() {
List<String> toRemove = new ArrayList<String>();
for (JpsExcludeFolder folder : myExcludeFolders) {
toRemove.add(folder.getUrl());
Disposer.dispose(folder);
}
myExcludeFolders.clear();
for (String url : toRemove) {
myModule.getExcludeRootsList().removeUrl(url);
}
}
@Override
public boolean isSynthetic() {
return false;
}
@Override
public void dispose() {
for (JpsSourceFolder folder : mySourceFolders) {
Disposer.dispose(folder);
}
for (JpsExcludeFolder folder : myExcludeFolders) {
Disposer.dispose(folder);
}
}
}