new framework detection: obsolete code removed

This commit is contained in:
nik
2011-08-08 13:18:54 +04:00
parent 97dabbe2f5
commit b0f7a89a29
32 changed files with 0 additions and 4296 deletions
@@ -1,29 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.openapi.module.Module;
import com.intellij.facet.FacetType;
/**
* @author nik
*/
public interface AutodetectionFilter {
boolean isAutodetectionEnabled(Module module, FacetType facetType, final String url);
}
@@ -1,65 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
/**
* @author nik
*/
public class DefaultDetectedFacetPresentation extends DetectedFacetPresentation {
public static final DefaultDetectedFacetPresentation INSTANCE = new DefaultDetectedFacetPresentation();
@Nullable
public String getDetectedFacetDescription(final VirtualFile root, final VirtualFile[] files) {
VirtualFile file = files[0];
if (root == null) return file.getPresentableUrl();
String path = VfsUtil.getRelativePath(file, root, File.separatorChar);
return path != null ? path : file.getPresentableUrl();
}
public String getAutodetectionPopupText(@NotNull final Module module, @NotNull final FacetType facetType, @NotNull final String facetName,
@NotNull final VirtualFile[] files) {
String fileUrl = getRelativeFileUrl(files[0], module.getProject());
return ProjectBundle.message("facet.autodetected.popup.default.text", fileUrl, module.getName(), facetType.getPresentableName(), facetName);
}
private static String getRelativeFileUrl(final @NotNull VirtualFile file, final Project project) {
String fileUrl = file.getPresentableUrl();
VirtualFile baseDir = project.getBaseDir();
if (baseDir == null) {
return fileUrl;
}
String prefix = baseDir.getPresentableUrl() + File.separator;
if (fileUrl.startsWith(prefix)) {
return fileUrl.substring(prefix.length());
}
return fileUrl;
}
}
@@ -1,435 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.ProjectTopics;
import com.intellij.facet.*;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.impl.autodetecting.facetsTree.DetectedFacetsDialog;
import com.intellij.facet.impl.autodetecting.model.*;
import com.intellij.ide.caches.FileContent;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.HyperlinkEvent;
import java.util.*;
/**
* @author nik
*/
public class DetectedFacetManager implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.DetectedFacetManager");
@NonNls private static final String NOTIFICATION_ID = "Facet Detector";
private static final int NOTIFICATION_DELAY = 200;
private final Project myProject;
private final FacetAutodetectingManagerImpl myAutodetectingManager;
private final ProjectWideFacetListenersRegistry myProjectWideFacetListenersRegistry;
private boolean myUIInitialized;
private final Set<DetectedFacetInfo<Module>> myPendingNewFacets = new HashSet<DetectedFacetInfo<Module>>();
private final Alarm myNotificationAlarm = new Alarm();
private final ProjectFacetInfoSet myDetectedFacetSet;
private final List<FacetDetectedNotification> myNotifications = new ArrayList<FacetDetectedNotification>();
public DetectedFacetManager(final Project project, final FacetAutodetectingManagerImpl autodetectingManager,
final ProjectFacetInfoSet detectedFacetSet) {
myDetectedFacetSet = detectedFacetSet;
myProjectWideFacetListenersRegistry = ProjectWideFacetListenersRegistry.getInstance(project);
myProject = project;
myAutodetectingManager = autodetectingManager;
myDetectedFacetSet.addListener(new ProjectFacetInfoSet.DetectedFacetListener() {
public void facetDetected(final DetectedFacetInfo<Module> info) {
onDetectedFacetChanged(Collections.singletonList(info), Collections.<DetectedFacetInfo<Module>>emptyList());
}
public void facetRemoved(final DetectedFacetInfo<Module> info) {
myAutodetectingManager.getFileIndex().removeFromIndex(info);
onDetectedFacetChanged(Collections.<DetectedFacetInfo<Module>>emptyList(), Collections.singletonList(info));
}
});
Disposer.register(myProject, this);
myProject.getMessageBus().connect().subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
@Override
public void moduleRemoved(final Project project, final Module module) {
myDetectedFacetSet.removeDetectedFacets(module);
}
});
}
public <F extends Facet<C>, C extends FacetConfiguration> void registerListeners(final FacetType<F, C> type) {
myProjectWideFacetListenersRegistry.registerListener(type.getId(), new MyProjectWideFacetListener<F, C>(), this);
}
public Project getProject() {
return myProject;
}
public void onDetectedFacetChanged(@NotNull final Collection<DetectedFacetInfo<Module>> added, @NotNull final Collection<DetectedFacetInfo<Module>> removed) {
if (!myUIInitialized) return;
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
Runnable runnable = new Runnable() {
public void run() {
if (isDisposed()) return;
myPendingNewFacets.addAll(added);
for (FacetDetectedNotification notification : myNotifications) {
for (DetectedFacetInfo<Module> facetInfo : removed) {
notification.processFacetRemoved(facetInfo);
}
}
queueNotificationPopup();
}
};
ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL);
}
}
private void queueNotificationPopup() {
myNotificationAlarm.cancelAllRequests();
myNotificationAlarm.addRequest(new Runnable() {
public void run() {
firePendingNotifications();
}
}, NOTIFICATION_DELAY);
}
public boolean isDisposed() {
return myProject.isDisposed() || !myUIInitialized;
}
private void firePendingNotifications() {
if (myPendingNewFacets.isEmpty() || myProject.isDisposed()) return;
List<DetectedFacetInfo<Module>> newFacets = new ArrayList<DetectedFacetInfo<Module>>();
for (DetectedFacetInfo<Module> newFacet : myPendingNewFacets) {
newFacets.add(newFacet);
}
myPendingNewFacets.clear();
//fireNotification(newFacets);
}
private void fireNotification(final List<DetectedFacetInfo<Module>> newFacets) {
if (newFacets.isEmpty()) {
return;
}
boolean showNotification = true;//todo[nik] may be we shouldn't show notification if "Facets Detected" dialog is opened
HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> filesMap = getFilesMap(newFacets);
if (!filesMap.isEmpty() && showNotification) {
final Set<DetectedFacetInfo<Module>> detectedFacetInfos = filesMap.keySet();
final FacetDetectedNotification notification;
if (filesMap.size() == 1) {
final DetectedFacetInfo<Module> facetInfo = detectedFacetInfos.iterator().next();
final List<VirtualFile> files = filesMap.get(facetInfo);
notification = createSingleFacetDetectedNotification(facetInfo, VfsUtil.toVirtualFileArray(files));
}
else {
notification = createSeveralFacetsDetectedNotification(filesMap.keySet());
}
myNotifications.add(notification);
Notifications.Bus.notify(notification, myProject);
}
else {
myPendingNewFacets.addAll(newFacets);
}
}
public void dispose() {
}
public void initUI() {
myUIInitialized = true;
onDetectedFacetChanged(myDetectedFacetSet.getAllDetectedFacets(), Collections.<DetectedFacetInfo<Module>>emptyList());
}
public void disposeUI() {
if (!myUIInitialized) return;
myNotificationAlarm.cancelAllRequests();
}
public void disableDetectionInFile(final DetectedFacetInfo<Module> detectedFacet) {
Collection<String> urls = myAutodetectingManager.getFileIndex().getFiles(detectedFacet.getId());
if (urls != null && !urls.isEmpty()) {
myAutodetectingManager.disableAutodetectionInFiles(detectedFacet.getFacetType(), detectedFacet.getModule(), ArrayUtil.toStringArray(urls));
}
myAutodetectingManager.getDetectedFacetSet().removeFacetInfo(detectedFacet);
}
public void disableDetectionInModule(final DetectedFacetInfo<Module> detectedFacetInfo) {
disableDetectionInModule(detectedFacetInfo.getFacetType(), detectedFacetInfo.getModule());
}
public void disableDetectionInModule(final FacetType type, final Module module) {
myAutodetectingManager.disableAutodetectionInModule(type, module);
myAutodetectingManager.getDetectedFacetSet().removeDetectedFacets(type.getId(), module);
}
public boolean showDetectedFacetsDialog() {
List<DetectedFacetInfo<Module>> detectedFacets = new ArrayList<DetectedFacetInfo<Module>>(myDetectedFacetSet.getAllDetectedFacets());
HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> filesMap = getFilesMap(detectedFacets);
if (detectedFacets.isEmpty()) {
removeAllNotifications();
return false;
}
DetectedFacetsDialog dialog = new DetectedFacetsDialog(myProject, this, detectedFacets, filesMap);
dialog.show();
final boolean processed = dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE;
if (processed) {
removeAllNotifications();
}
return processed;
}
private HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> getFilesMap(final List<DetectedFacetInfo<Module>> detectedFacets) {
MultiValuesMap<DetectedFacetInfo<Module>, DetectedFacetInfo<Module>> facet2Children = new MultiValuesMap<DetectedFacetInfo<Module>, DetectedFacetInfo<Module>>();
for (DetectedFacetInfo<Module> detected : detectedFacets) {
FacetInfo2<Module> underlying = detected.getUnderlyingFacetInfo();
if (underlying instanceof DetectedFacetInfo) {
facet2Children.put((DetectedFacetInfo<Module>)underlying, detected);
}
}
HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> filesMap = new HashMap<DetectedFacetInfo<Module>, List<VirtualFile>>();
Set<DetectedFacetInfo<Module>> toRemove = new HashSet<DetectedFacetInfo<Module>>();
for (DetectedFacetInfo<Module> detected : detectedFacets) {
Set<String> urls = myAutodetectingManager.getFileIndex().getFiles(detected.getId());
List<VirtualFile> files = new ArrayList<VirtualFile>();
if (urls != null) {
for (String url : urls) {
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
files.add(file);
}
}
}
if (!files.isEmpty()) {
filesMap.put(detected, files);
}
else {
addWithChildren(detected, facet2Children, toRemove);
}
}
detectedFacets.removeAll(toRemove);
return filesMap;
}
private static void addWithChildren(final DetectedFacetInfo<Module> detected,
final MultiValuesMap<DetectedFacetInfo<Module>, DetectedFacetInfo<Module>> facet2Children,
final Set<DetectedFacetInfo<Module>> result) {
if (result.add(detected)) {
Collection<DetectedFacetInfo<Module>> children = facet2Children.get(detected);
if (children != null) {
for (DetectedFacetInfo<Module> info : children) {
addWithChildren(info, facet2Children, result);
}
}
}
}
public Facet createFacet(final DetectedFacetInfo<Module> info, final Facet underlyingFacet) {
final Module module = info.getModule();
FacetType<?, ?> type = info.getFacetType();
final Facet facet = createFacet(info, module, underlyingFacet, type);
ModifiableFacetModel model = FacetManager.getInstance(module).createModifiableModel();
ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
final FacetDetector detector = myAutodetectingManager.findDetector(info.getDetectorId());
if (detector != null) {
detector.beforeFacetAdded(facet, model, rootModel);
}
model.addFacet(facet);
if (rootModel.isChanged()) {
rootModel.commit();
}
else {
rootModel.dispose();
}
model.commit();
myAutodetectingManager.getFileIndex().updateIndexEntryForCreatedFacet(info, facet);
myAutodetectingManager.getDetectedFacetSet().removeFacetInfo(info);
if (detector != null) {
detector.afterFacetAdded(facet);
}
return facet;
}
private static <C extends FacetConfiguration, F extends Facet> Facet createFacet(final DetectedFacetInfo<Module> info, final Module module, final Facet underlyingFacet,
final FacetType<F, C> facetType) {
return FacetManager.getInstance(module).createFacet(facetType, info.getFacetName(), (C)info.getConfiguration(), underlyingFacet);
}
private FacetDetectedNotification createSingleFacetDetectedNotification(final DetectedFacetInfo<Module> detectedFacetInfo, final VirtualFile[] files) {
@SuppressWarnings({"RedundantCast"}) DetectedFacetPresentation presentation = FacetDetectorRegistryEx.getDetectedFacetPresentation((FacetType<?,? extends FacetConfiguration>)detectedFacetInfo.getFacetType());
String text = presentation.getAutodetectionPopupText(detectedFacetInfo.getModule(), detectedFacetInfo.getFacetType(),
detectedFacetInfo.getFacetName(), files);
if (text == null) {
text = DefaultDetectedFacetPresentation.INSTANCE.getAutodetectionPopupText(detectedFacetInfo.getModule(), detectedFacetInfo.getFacetType(),
detectedFacetInfo.getFacetName(), files);
}
final String description = ProjectBundle.message("facet.autodetected.info.text", detectedFacetInfo.getFacetType().getPresentableName(), text,
detectedFacetInfo.getFacetName());
final String title = ProjectBundle.message("notification.name.0.facet.detected", detectedFacetInfo.getFacetType().getPresentableName());
return new FacetDetectedNotification(title, description, new NotificationListener() {
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
notification.expire();
if (isDisposed()) {
return;
}
String link = event.getDescription();
if ("create".equals(link)) {
new WriteAction() {
protected void run(final Result result) {
createFacetWithUnderlyingFacets(detectedFacetInfo);
}
}.execute();
}
else if ("disable".equals(link)) {
disableDetectionInModule(detectedFacetInfo);
}
else {
LOG.error(link);
}
}
}
}, Collections.singletonList(detectedFacetInfo));
}
private Facet createFacetWithUnderlyingFacets(DetectedFacetInfo<Module> detectedFacetInfo) {
FacetInfo2<Module> underlyingInfo = detectedFacetInfo.getUnderlyingFacetInfo();
final Facet underlyingFacet;
if (underlyingInfo instanceof FacetInfoBackedByFacet) {
underlyingFacet = ((FacetInfoBackedByFacet)underlyingInfo).getFacet();
}
else if (underlyingInfo instanceof DetectedFacetInfo) {
underlyingFacet = createFacetWithUnderlyingFacets((DetectedFacetInfo<Module>)underlyingInfo);
}
else {
underlyingFacet = null;
}
return createFacet(detectedFacetInfo, underlyingFacet);
}
private FacetDetectedNotification createSeveralFacetsDetectedNotification(final Set<DetectedFacetInfo<Module>> facets) {
final String title = ProjectBundle.message("notification.name.0.facets.detected", facets.size());
final String content = ProjectBundle.message("facet.autodetection.several.facets.detected.text", facets.size());
return new FacetDetectedNotification(title, content, new NotificationListener() {
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (isDisposed()) {
return;
}
if ("more".equals(event.getDescription())) {
showDetectedFacetsDialog();
}
}
}
}, facets);
}
private void removeAllNotifications() {
for (Notification notification : myNotifications) {
if (!notification.isExpired()) {
notification.expire();
}
}
myNotifications.clear();
}
private class MyProjectWideFacetListener<F extends Facet<C>, C extends FacetConfiguration> extends ProjectWideFacetAdapter<F> {
@Override
public void facetAdded(final F facet) {
Map<C, FacetInfo2<Module>> map = myDetectedFacetSet.getConfigurations((FacetTypeId<F>)facet.getTypeId(), facet.getModule());
Collection<FacetInfo2<Module>> infos = map.values();
Set<VirtualFile> files = new HashSet<VirtualFile>();
for (FacetInfo2<Module> info : infos) {
if (info instanceof DetectedFacetInfo) {
Set<String> urls = myAutodetectingManager.getFileIndex().getFiles(((DetectedFacetInfo)info).getId());
if (urls != null) {
for (String url : urls) {
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
files.add(file);
}
}
}
}
}
for (VirtualFile file : files) {
myAutodetectingManager.processFile(new FileContent(file));
}
}
@Override
public void beforeFacetRemoved(final F facet) {
Set<String> files = myAutodetectingManager.getFiles(facet);
if (files != null) {
myAutodetectingManager.disableAutodetectionInFiles(facet.getType(), facet.getModule(), ArrayUtil.toStringArray(files));
}
myAutodetectingManager.removeFacetFromCache(facet);
}
}
private static class FacetDetectedNotification extends Notification {
private final List<DetectedFacetInfo<Module>> myFacets = new ArrayList<DetectedFacetInfo<Module>>();
private FacetDetectedNotification(@NotNull String title, @NotNull String content, NotificationListener listener, Collection<DetectedFacetInfo<Module>> facets) {
super(NOTIFICATION_ID, title, content, NotificationType.INFORMATION, listener);
myFacets.addAll(facets);
}
public void processFacetRemoved(DetectedFacetInfo<Module> facetInfo) {
myFacets.remove(facetInfo);
if (myFacets.isEmpty() && !isExpired()) {
expire();
}
}
}
}
@@ -1,173 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetType;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionByTypeElement;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionInModuleElement;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
/**
* @author nik
*/
public class EnableAutodetectionWorker {
private final MultiValuesMap<FacetType<?,?>, Module> myModulesToProcess = new MultiValuesMap<FacetType<?,?>, Module>();
private final MultiValuesMap<FacetType<?,?>, VirtualFile> myFilesToProcess = new MultiValuesMap<FacetType<?,?>, VirtualFile>();
private final Project myProject;
private final FacetAutodetectingManagerImpl myFacetAutodetectingManager;
public EnableAutodetectionWorker(@NotNull Project project, final FacetAutodetectingManagerImpl facetAutodetectingManager) {
myProject = project;
myFacetAutodetectingManager = facetAutodetectingManager;
}
public void addFile(@NotNull FacetType<?, ?> type, @NotNull String url) {
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
myFilesToProcess.put(type, file);
}
}
public void queueChanges(final @NotNull FacetType<?, ?> facetType, final @Nullable DisabledAutodetectionByTypeElement oldElement,
final @Nullable DisabledAutodetectionByTypeElement newElement) {
if (oldElement == null || newElement != null && newElement.getModuleElements().isEmpty()) return;
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
List<Module> modulesToProcess = new ArrayList<Module>();
List<DisabledAutodetectionInModuleElement> moduleElements = oldElement.getModuleElements();
for (DisabledAutodetectionInModuleElement moduleElement : moduleElements) {
if (moduleElement.isDisableInWholeModule()) {
Module module = moduleManager.findModuleByName(moduleElement.getModuleName());
if (module != null) {
modulesToProcess.add(module);
}
}
else {
for (String url : moduleElement.getFiles()) {
if (newElement == null || !newElement.isDisabled(moduleElement.getModuleName(), url)) {
addFile(facetType, url);
}
}
for (String directoryUrl : moduleElement.getDirectories()) {
if (newElement == null || !newElement.isDisabled(moduleElement.getModuleName(), directoryUrl)) {
addFile(facetType, directoryUrl);
}
}
}
}
if (moduleElements.isEmpty()) {
ContainerUtil.addAll(modulesToProcess, moduleManager.getModules());
}
if (newElement != null) {
Set<String> toRemove = new THashSet<String>();
for (DisabledAutodetectionInModuleElement moduleElement : newElement.getModuleElements()) {
if (moduleElement.isDisableInWholeModule()) {
toRemove.add(moduleElement.getModuleName());
}
}
Iterator<Module> iterator = modulesToProcess.iterator();
while (iterator.hasNext()) {
Module module = iterator.next();
if (toRemove.contains(module.getName())) {
iterator.remove();
}
}
}
if (!modulesToProcess.isEmpty()) {
myModulesToProcess.putAll(facetType, modulesToProcess);
}
}
public void redetectFacets() {
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
for (FacetType<?, ?> type : myModulesToProcess.keySet()) {
detectFacetsInModules(type, myModulesToProcess.get(type));
}
myModulesToProcess.clear();
for (FacetType<?, ?> type : myFilesToProcess.keySet()) {
detectFacetsInFiles(type, myFilesToProcess.get(type));
}
myFilesToProcess.clear();
}
}, ProjectBundle.message("progress.text.detecting.facets"), false, myProject);
myFacetAutodetectingManager.getDetectedFacetManager().showDetectedFacetsDialog();
}
private void detectFacetsInModules(final FacetType<?, ?> type, final Collection<Module> modules) {
for (Module module : modules) {
ModuleRootManager.getInstance(module).getFileIndex().iterateContent(new ContentIterator() {
public boolean processFile(final VirtualFile file) {
detectFacetsInFile(type, file);
return true;
}
});
}
}
private void detectFacetsInFile(final FacetType<?, ?> type, final VirtualFile file) {
//todo[nik] detect only facets of specified type
if (file.isDirectory()) {
for (VirtualFile child : file.getChildren()) {
detectFacetsInFile(type, child);
}
}
else {
myFacetAutodetectingManager.processFile(new FileContent(file));
}
}
private void detectFacetsInFiles(final FacetType<?, ?> type, final Collection<VirtualFile> virtualFiles) {
for (VirtualFile file : virtualFiles) {
detectFacetsInFile(type, file);
}
}
@TestOnly
@Nullable
public Collection<Module> getModulesToProcess(FacetType<?, ?> facetType) {
return myModulesToProcess.get(facetType);
}
@TestOnly
@Nullable
public Collection<VirtualFile> getFilesToProcess(FacetType<?, ?> facetType) {
return myFilesToProcess.get(facetType);
}
}
@@ -1,35 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class FacetAutodetectingManager {
public static FacetAutodetectingManager getInstance(Project project) {
return project.getComponent(FacetAutodetectingManager.class);
}
public abstract void disableAutodetectionInFiles(@NotNull FacetType type, @NotNull Module module, @NotNull String... fileUrls);
public abstract void disableAutodetectionInModule(FacetType type, Module module);
}
@@ -1,377 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionByTypeElement;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionInfo;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.util.SmartList;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
/**
* @author nik
*/
public class FacetAutodetectingManagerImpl extends FacetAutodetectingManager implements AutodetectionFilter, ProjectComponent {
private final MultiValuesMap<FileType, FacetDetectorWrapper> myDetectors = new MultiValuesMap<FileType, FacetDetectorWrapper>();
private final Map<String, FacetDetector<?,?>> myId2Detector = new HashMap<String, FacetDetector<?,?>>();
private final Project myProject;
private final PsiManager myPsiManager;
private final FacetPointersManager myFacetPointersManager;
private FacetDetectionIndex myFileIndex;
private MergingUpdateQueue myMergingUpdateQueue;
private final ProjectFacetInfoSet myDetectedFacetSet;
private DetectedFacetManager myDetectedFacetManager;
private DisabledAutodetectionInfo myDisabledAutodetectionInfo = new DisabledAutodetectionInfo();
private boolean myDetectionInProgress;
private final Set<FacetType<?,?>> myFacetTypesWithDetectors = new THashSet<FacetType<?,?>>();
private final EnableAutodetectionWorker myEnableAutodetectionWorker;
private final Object myLock = new Object();
public FacetAutodetectingManagerImpl(final Project project, PsiManager psiManager, FacetPointersManager facetPointersManager) {
myProject = project;
myPsiManager = psiManager;
myFacetPointersManager = facetPointersManager;
myDetectedFacetSet = new ProjectFacetInfoSet(project, project);
myEnableAutodetectionWorker = new EnableAutodetectionWorker(project, this);
}
public void projectOpened() {
if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment()) return;
myDetectedFacetSet.loadDetectedFacets(FacetDetectionIndex.getDetectedFacetsFile(myProject));
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
myDetectedFacetManager.initUI();
}
});
}
public void projectClosed() {
if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment()) return;
myDetectedFacetSet.saveDetectedFacets(FacetDetectionIndex.getDetectedFacetsFile(myProject));
if (myDetectedFacetManager != null) {
myDetectedFacetManager.disposeUI();
}
}
@NonNls
@NotNull
public String getComponentName() {
return "OldFacetAutodetectingManagerImpl";
}
public void initComponent() {
boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
if (!unitTestMode && !myProject.isDefault()) {
initialize();
}
}
public void initialize() {
myDetectedFacetManager = new DetectedFacetManager(myProject, this, myDetectedFacetSet);
FacetType[] types = FacetTypeRegistry.getInstance().getFacetTypes();
for (FacetType<?,?> type : types) {
registerDetectors(type);
}
myFileIndex = new FacetDetectionIndex(myProject, this, myDetectors.keySet());
myFileIndex.initialize();
MyPsiTreeChangeListener psiTreeChangeListener = new MyPsiTreeChangeListener();
myPsiManager.addPsiTreeChangeListener(psiTreeChangeListener, myProject);
myMergingUpdateQueue = new MergingUpdateQueue("FacetAutodetectionQueue", 500, true, null, myProject);
}
private <F extends Facet<C>, C extends FacetConfiguration> void registerDetectors(final FacetType<F, C> type) {
FacetOnTheFlyDetectorRegistryImpl<C, F> detectorRegistry = new FacetOnTheFlyDetectorRegistryImpl<C, F>(type);
type.registerDetectors(new FacetDetectorRegistryEx<C>(null, detectorRegistry));
if (detectorRegistry.hasDetectors()) {
myFacetTypesWithDetectors.add(type);
myDetectedFacetManager.registerListeners(type);
}
}
@Nullable
public DisabledAutodetectionByTypeElement getDisabledAutodetectionState(@NotNull FacetType<?,?> type) {
return myDisabledAutodetectionInfo.findElement(type.getStringId());
}
public void processFile(FileContent fileContent) {
final VirtualFile file = fileContent.getVirtualFile();
if (!file.isValid() || file.isDirectory() || myProject.isDisposed()
|| !file.exists() || !myFileIndex.getProjectFileIndex().isInContent(file)) return;
FileType fileType = file.getFileType();
Collection<FacetDetectorWrapper> detectors = myDetectors.get(fileType);
if (detectors == null) return;
synchronized (myLock) {
List<FacetInfo2<Module>> facets = null;
for (FacetDetectorWrapper<?,?,?,?> detector : detectors) {
facets = process(file, fileContent, detector, facets);
}
String url = file.getUrl();
FacetDetectionIndexEntry indexEntry = myFileIndex.getIndexEntry(url);
if (indexEntry == null) {
indexEntry = new FacetDetectionIndexEntry(file.getTimeStamp());
}
Collection<Integer> removed = indexEntry.update(myFacetPointersManager, facets);
myFileIndex.putIndexEntry(url, indexEntry);
if (removed != null) {
removeObsoleteFacets(removed);
}
}
}
public void removeObsoleteFacets(final Collection<Integer> ids) {
for (Integer id : ids) {
Set<String> urls = myFileIndex.getFiles(id);
if (urls == null || urls.isEmpty()) {
myDetectedFacetSet.removeDetectedFacetWithSubFacets(id);
}
}
}
public ProjectFacetInfoSet getDetectedFacetSet() {
return myDetectedFacetSet;
}
private List<FacetInfo2<Module>> process(final VirtualFile virtualFile,
FileContent fileContent,
final FacetDetectorWrapper<?, ?, ?, ?> detector,
List<FacetInfo2<Module>> facets) {
if (!myDetectionInProgress && detector.getFileContentPattern().accepts(fileContent)) {
try {
myDetectionInProgress = true;
FacetInfo2<Module> facet = detector.detectFacet(virtualFile, myPsiManager);
if (facet != null) {
if (facets == null) {
facets = new SmartList<FacetInfo2<Module>>();
}
facets.add(facet);
}
}
finally {
myDetectionInProgress = false;
}
}
return facets;
}
public void disposeComponent() {
if (!ApplicationManager.getApplication().isUnitTestMode() && !myProject.isDefault()) {
dispose();
}
}
public void dispose() {
if (myFileIndex != null) {
myFileIndex.dispose();
}
}
public void redetectFacets() {
myEnableAutodetectionWorker.redetectFacets();
}
@TestOnly
public EnableAutodetectionWorker getEnableAutodetectionWorker() {
return myEnableAutodetectionWorker;
}
public boolean isAutodetectionEnabled(final Module module, final FacetType facetType, final String url) {
return !myDisabledAutodetectionInfo.isDisabled(facetType.getStringId(), module.getName(), url);
}
private void queueUpdate(final PsiFile psiFile) {
if (!myDetectors.keySet().contains(psiFile.getFileType())) return;
VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
queueUpdate(virtualFile);
}
}
public void queueUpdate(final VirtualFile file) {
Update update = new Update("file:" + file.getUrl()) {
public void run() {
processFile(new FileContent(file));
}
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
update.run();
}
else {
myMergingUpdateQueue.queue(update);
}
}
@Nullable
public Set<String> getFiles(final Facet facet) {
return myFileIndex.getFiles(facet);
}
public void removeFacetFromCache(final Facet facet) {
myFileIndex.removeFacetFromCache(myFacetPointersManager.create(facet));
}
public Set<FileType> getFileTypes(final Set<FacetType> facetTypes) {
THashSet<FileType> fileTypes = new THashSet<FileType>();
for (FileType type : myDetectors.keySet()) {
Collection<FacetDetectorWrapper> detectorWrappers = myDetectors.get(type);
if (detectorWrappers != null) {
for (FacetDetectorWrapper detectorWrapper : detectorWrappers) {
if (facetTypes.contains(detectorWrapper.getFacetType())) {
fileTypes.add(type);
break;
}
}
}
}
return fileTypes;
}
public void disableAutodetectionInModule(final FacetType type, final Module module) {
myDisabledAutodetectionInfo.addDisabled(type.getStringId(), module.getName());
}
public void disableAutodetectionInFiles(@NotNull final FacetType type, @NotNull final Module module, @NotNull final String... fileUrls) {
myDisabledAutodetectionInfo.addDisabled(type.getStringId(), module.getName(), fileUrls);
}
public void setDisabledAutodetectionState(final @NotNull FacetType<?, ?> facetType, final @Nullable DisabledAutodetectionByTypeElement element) {
String id = facetType.getStringId();
DisabledAutodetectionByTypeElement oldElement = myDisabledAutodetectionInfo.findElement(id);
myEnableAutodetectionWorker.queueChanges(facetType, oldElement, element);
myDisabledAutodetectionInfo.replaceElement(id, element);
}
public DetectedFacetManager getDetectedFacetManager() {
return myDetectedFacetManager;
}
@Nullable
public FacetDetector<?,?> findDetector(final String detectorId) {
return myId2Detector.get(detectorId);
}
public FacetDetectionIndex getFileIndex() {
return myFileIndex;
}
private class FacetOnTheFlyDetectorRegistryImpl<C extends FacetConfiguration, F extends Facet<C>> implements FacetOnTheFlyDetectorRegistry<C> {
private final FacetType<F, C> myType;
private boolean myHasDetectors;
public FacetOnTheFlyDetectorRegistryImpl(final FacetType<F, C> type) {
myType = type;
}
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final OldFileContentPattern fileContentFilter,
@NotNull final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myHasDetectors = true;
myId2Detector.put(facetDetector.getId(), facetDetector);
myDetectors.put(fileType, new FacetByVirtualFileDetectorWrapper<C, F, U>(myDetectedFacetSet, myType,
FacetAutodetectingManagerImpl.this, fileContentFilter,
facetDetector, selector));
}
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final OldFileContentPattern fileContentFilter,
@NotNull final Condition<PsiFile> psiFileFilter, @NotNull final FacetDetector<PsiFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myHasDetectors = true;
myId2Detector.put(facetDetector.getId(), facetDetector);
myDetectors.put(fileType, new FacetByPsiFileDetectorWrapper<C, F, U>(myDetectedFacetSet, myType, FacetAutodetectingManagerImpl.this,
fileContentFilter, facetDetector, psiFileFilter, selector));
}
public boolean hasDetectors() {
return myHasDetectors;
}
}
private class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
public void childAdded(final PsiTreeChangeEvent event) {
PsiElement child = event.getChild();
if (child instanceof PsiFile) {
queueUpdate((PsiFile)child);
}
else {
processChangedElement(event);
}
}
private void processChangedElement(final PsiTreeChangeEvent event) {
PsiFile psiFile = event.getFile();
if (psiFile != null) {
queueUpdate(psiFile);
}
}
public void childRemoved(final PsiTreeChangeEvent event) {
PsiElement child = event.getChild();
if (child instanceof PsiFile) {
VirtualFile virtualFile = ((PsiFile)child).getVirtualFile();
if (virtualFile != null) {
myFileIndex.removeIndexEntry(virtualFile);
}
}
else {
processChangedElement(event);
}
}
public void childReplaced(final PsiTreeChangeEvent event) {
processChangedElement(event);
}
public void childMoved(final PsiTreeChangeEvent event) {
processChangedElement(event);
}
}
}
@@ -1,58 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
/**
* @author nik
*/
public class FacetByPsiFileDetectorWrapper<C extends FacetConfiguration, F extends Facet<C>, U extends FacetConfiguration> extends FacetDetectorWrapper<PsiFile, C, F, U> {
private final Condition<PsiFile> myPsiFileFilter;
public FacetByPsiFileDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType,
final AutodetectionFilter autodetectionFilter, final OldFileContentPattern fileContentPattern,
final FacetDetector<PsiFile, C> facetDetector,
Condition<PsiFile> psiFileFilter, final UnderlyingFacetSelector<VirtualFile, U> selector) {
super(projectFacetSet, facetType, autodetectionFilter, fileContentPattern, facetDetector, selector);
myPsiFileFilter = psiFileFilter;
}
public FacetInfo2<Module> detectFacet(final VirtualFile virtualFile, final PsiManager psiManager) {
PsiFile psiFile = psiManager.findFile(virtualFile);
if (psiFile == null || !myPsiFileFilter.value(psiFile)) {
return null;
}
Module module = ModuleUtil.findModuleForFile(virtualFile, psiManager.getProject());
if (module == null) return null;
return detectFacet(module, virtualFile, psiFile);
}
}
@@ -1,51 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public class FacetByVirtualFileDetectorWrapper<C extends FacetConfiguration, F extends Facet<C>, U extends FacetConfiguration> extends FacetDetectorWrapper<VirtualFile, C, F, U> {
public FacetByVirtualFileDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType,
final AutodetectionFilter autodetectionFilter, final OldFileContentPattern fileContentPattern,
final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
super(projectFacetSet, facetType, autodetectionFilter, fileContentPattern, facetDetector, selector);
}
@Nullable
public FacetInfo2<Module> detectFacet(final VirtualFile virtualFile, final PsiManager psiManager) {
Module module = ModuleUtil.findModuleForFile(virtualFile, psiManager.getProject());
if (module == null) {
return null;
}
return detectFacet(module, virtualFile, virtualFile);
}
}
@@ -1,223 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.facet.pointers.FacetPointer;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.BidirectionalMultiMap;
import com.intellij.util.fileIndex.AbstractFileIndex;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* @author nik
*/
public class FacetDetectionIndex extends AbstractFileIndex<FacetDetectionIndexEntry> {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.FacetDetectionIndex");
private static final byte CURRENT_VERSION = 1;
@NonNls private static final String CACHE_DIRECTORY_NAME = "facets";
private final FileTypeManager myFileTypeManager;
private final Set<FileType> myFileTypes;
private final Set<FacetType> myNewFacetTypes = new THashSet<FacetType>();
private final FacetPointersManager myFacetPointersManager;
private final FacetAutodetectingManagerImpl myAutodetectingManager;
private final BidirectionalMultiMap<String, FacetPointer> myFacets;
private final BidirectionalMultiMap<String, Integer> myDetectedFacetIds;
public FacetDetectionIndex(final Project project, final FacetAutodetectingManagerImpl autodetectingManager, Set<FileType> fileTypes) {
super(project);
myAutodetectingManager = autodetectingManager;
myFileTypes = new THashSet<FileType>(fileTypes);
myFileTypeManager = FileTypeManager.getInstance();
myFacetPointersManager = FacetPointersManager.getInstance(project);
myFacets = new BidirectionalMultiMap<String, FacetPointer>();
myDetectedFacetIds = new BidirectionalMultiMap<String, Integer>();
}
protected FacetDetectionIndexEntry createIndexEntry(final DataInputStream input) throws IOException {
return new FacetDetectionIndexEntry(input, myFacetPointersManager);
}
public boolean belongs(final VirtualFile file) {
FileType fileType = myFileTypeManager.getFileTypeByFile(file);
return myFileTypes.contains(fileType);
}
protected String getLoadingIndicesMessage() {
return ProjectBundle.message("progress.text.loading.facet.detection.indices");
}
public byte getCurrentVersion() {
return CURRENT_VERSION;
}
public String getCachesDirName() {
return CACHE_DIRECTORY_NAME;
}
public static File getDetectedFacetsFile(@NotNull Project project) {
return new File(PathManager.getSystemPath() + File.separator + CACHE_DIRECTORY_NAME + File.separator + project.getName() + ".detected." + project.getLocationHash());
}
protected void readHeader(final DataInputStream input) throws IOException {
int size = input.readInt();
Set<String> facetTypesInCache = new THashSet<String>();
while (size-- > 0) {
facetTypesInCache.add(input.readUTF());
}
Set<String> unknownTypes = new THashSet<String>(facetTypesInCache);
for (FacetType type : FacetTypeRegistry.getInstance().getFacetTypes()) {
unknownTypes.remove(type.getStringId());
if (!facetTypesInCache.contains(type.getStringId())) {
myNewFacetTypes.add(type);
}
}
if (!unknownTypes.isEmpty()) {
LOG.info("Unknown facet types in cache: " + new HashSet<String>(unknownTypes));
}
}
@Nullable
protected Set<FileType> getFileTypesToRefresh() {
if (myNewFacetTypes.isEmpty()) {
return null;
}
return myAutodetectingManager.getFileTypes(myNewFacetTypes);
}
protected void writeHeader(final DataOutputStream output) throws IOException {
FacetType[] types = FacetTypeRegistry.getInstance().getFacetTypes();
output.writeInt(types.length);
for (FacetType type : types) {
output.writeUTF(type.getStringId());
}
}
public void queueEntryUpdate(final VirtualFile file) {
myAutodetectingManager.queueUpdate(file);
}
protected void doUpdateIndexEntry(final FileContent fileContent) {
myAutodetectingManager.processFile(fileContent);
}
@Nullable
public Set<String> getFiles(Integer id) {
return myDetectedFacetIds.getKeys(id);
}
@Nullable
public Set<String> getFiles(final Facet facet) {
return myFacets.getKeys(myFacetPointersManager.create(facet));
}
protected void onEntryAdded(final String url, final FacetDetectionIndexEntry entry) {
myFacets.removeKey(url);
SmartList<FacetPointer> detectedFacets = entry.getFacets();
if (detectedFacets != null) {
for (FacetPointer detectedFacet : detectedFacets) {
myFacets.put(url, detectedFacet);
}
}
myDetectedFacetIds.removeKey(url);
SmartList<Integer> facetIds = entry.getDetectedFacetIds();
if (facetIds != null) {
for (Integer id : facetIds) {
myDetectedFacetIds.put(url, id);
}
}
}
protected void onEntryRemoved(final String url, final FacetDetectionIndexEntry entry) {
Set<Integer> ids = myDetectedFacetIds.getValues(url);
myDetectedFacetIds.removeKey(url);
if (ids != null && !ids.isEmpty()) {
myAutodetectingManager.removeObsoleteFacets(ids);
}
}
public void removeFacetFromCache(final FacetPointer<Facet> facetPointer) {
Set<String> urls = myFacets.getKeys(facetPointer);
if (urls != null) {
for (String url : urls) {
FacetDetectionIndexEntry indexEntry = getIndexEntry(url);
if (indexEntry != null) {
indexEntry.remove(facetPointer);
}
}
}
myFacets.removeValue(facetPointer);
}
public void updateIndexEntryForCreatedFacet(final DetectedFacetInfo<Module> info, final Facet facet) {
FacetPointer<Facet> pointer = FacetPointersManager.getInstance(facet.getModule().getProject()).create(facet);
Set<String> urls = myDetectedFacetIds.getKeys(info.getId());
if (urls != null) {
String[] urlsArray = ArrayUtil.toStringArray(urls);
for (String url : urlsArray) {
myDetectedFacetIds.remove(url, info.getId());
myFacets.put(url, pointer);
FacetDetectionIndexEntry indexEntry = getIndexEntry(url);
indexEntry.remove(info.getId());
indexEntry.add(pointer);
}
}
}
public boolean isEmpty() {
return myDetectedFacetIds.isEmpty() && myFacets.isEmpty();
}
public void removeFromIndex(final DetectedFacetInfo<Module> info) {
int id = info.getId();
Set<String> urls = myDetectedFacetIds.getKeys(id);
if (urls != null) {
for (String url : urls) {
FacetDetectionIndexEntry entry = getIndexEntry(url);
if (entry != null) {
entry.remove(id);
}
}
}
myDetectedFacetIds.removeValue(id);
}
}
@@ -1,157 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.FacetInfoBackedByFacet;
import com.intellij.facet.pointers.FacetPointer;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.SmartList;
import com.intellij.util.fileIndex.FileIndexEntry;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author nik
*/
public class FacetDetectionIndexEntry extends FileIndexEntry {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.FacetDetectionIndexEntry");
private SmartList<FacetPointer> myFacets;
private SmartList<Integer> myDetectedFacetIds;
public FacetDetectionIndexEntry(final long timestamp) {
super(timestamp);
}
public FacetDetectionIndexEntry(final DataInputStream stream, final FacetPointersManager facetPointersManager) throws IOException {
super(stream);
int size = stream.readInt();
if (size > 0) {
while (size-- > 0) {
String id = stream.readUTF();
if (id.startsWith("/")) {
if (myDetectedFacetIds == null) {
myDetectedFacetIds = new SmartList<Integer>();
}
myDetectedFacetIds.add(Integer.parseInt(id.substring(1)));
}
else {
if (myFacets == null) {
myFacets = new SmartList<FacetPointer>();
}
myFacets.add(facetPointersManager.create(id));
}
}
}
}
@Nullable
public SmartList<FacetPointer> getFacets() {
return myFacets;
}
@Nullable
public SmartList<Integer> getDetectedFacetIds() {
return myDetectedFacetIds;
}
public void write(final DataOutputStream stream) throws IOException {
super.write(stream);
int number = (myFacets != null ? myFacets.size() : 0) + (myDetectedFacetIds != null ? myDetectedFacetIds.size() : 0);
stream.writeInt(number);
if (myFacets != null) {
for (FacetPointer facetPointer : myFacets) {
stream.writeUTF(facetPointer.getId());
}
}
if (myDetectedFacetIds != null) {
for (Integer id : myDetectedFacetIds) {
stream.writeUTF("/" + id);
}
}
}
@Nullable
public Collection<Integer> update(final FacetPointersManager facetPointersManager, final @Nullable List<FacetInfo2<Module>> detectedFacets) {
if (detectedFacets == null || detectedFacets.isEmpty()) {
SmartList<Integer> old = myDetectedFacetIds;
myFacets = null;
myDetectedFacetIds = null;
return old;
}
if (myFacets == null) {
myFacets = new SmartList<FacetPointer>();
}
else {
myFacets.clear();
}
if (myDetectedFacetIds == null) {
myDetectedFacetIds = new SmartList<Integer>();
}
Set<Integer> toRemove = new HashSet<Integer>(myDetectedFacetIds);
for (FacetInfo2<Module> info : detectedFacets) {
if (info instanceof FacetInfoBackedByFacet) {
FacetPointer<Facet> pointer = facetPointersManager.create(((FacetInfoBackedByFacet)info).getFacet());
LOG.assertTrue(pointer.getModuleName().length() > 0);//IDEADEV-34200
myFacets.add(pointer);
}
else {
Integer id = ((DetectedFacetInfo)info).getId();
boolean removed = toRemove.remove(id);
if (!removed) {
myDetectedFacetIds.add(id);
}
}
}
myDetectedFacetIds.removeAll(toRemove);
return toRemove;
}
public void remove(final FacetPointer facetPointer) {
if (myFacets != null) {
myFacets.remove(facetPointer);
}
}
public void remove(final Integer id) {
if (myDetectedFacetIds != null) {
myDetectedFacetIds.remove(id);
}
}
public void add(final FacetPointer<Facet> pointer) {
if (myFacets == null) {
myFacets = new SmartList<FacetPointer>();
}
LOG.assertTrue(pointer.getModuleName().length() > 0);//IDEADEV-34200
myFacets.add(pointer);
}
}
@@ -1,33 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public interface FacetDetectorForWizardRegistry<C extends FacetConfiguration> {
<U extends FacetConfiguration> void register(final FileType fileType, @NotNull final OldFileContentPattern fileContentPattern,
final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector);
}
@@ -1,168 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.FacetDetectorRegistry;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.VirtualFilePattern;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements FacetDetectorRegistry<C> {
private final @Nullable FacetDetectorForWizardRegistry<C> myForWizardDelegate;
private final @Nullable FacetOnTheFlyDetectorRegistry<C> myOnTheFlyDelegate;
private DetectedFacetPresentation myPresentation;
public FacetDetectorRegistryEx(final @Nullable FacetDetectorForWizardRegistry<C> forWizardDelegate, final @Nullable FacetOnTheFlyDetectorRegistry<C> onTheFlyDelegate) {
myForWizardDelegate = forWizardDelegate;
myOnTheFlyDelegate = onTheFlyDelegate;
}
public void customizeDetectedFacetPresentation(@NotNull final DetectedFacetPresentation presentation) {
myPresentation = presentation;
}
public void registerUniversalDetectorByRootTag(@NotNull final String rootTag, @NotNull final FacetDetector<VirtualFile, C> detector) {
registerUniversalDetector(StdFileTypes.XML, OldFileContentPattern.fileContent().xmlWithRootTag(rootTag), detector, null);
}
public <U extends FacetConfiguration> void registerUniversalDetectorByFileNameAndRootTag(@NotNull @NonNls String fileName,
@NotNull @NonNls String rootTag,
@NotNull final FacetDetector<VirtualFile, C> detector,
@Nullable UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
registerUniversalDetector(StdFileTypes.XML, OldFileContentPattern.fileContent().withName(fileName).xmlWithRootTag(rootTag), detector, underlyingFacetSelector);
}
public void registerDetectorForWizard(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter, @NotNull final FacetDetector<VirtualFile, C> facetDetector) {
if (myForWizardDelegate != null) {
myForWizardDelegate.register(fileType, OldFileContentPattern.byFilter(virtualFileFilter), facetDetector, null);
}
}
public void registerDetectorForWizard(@NotNull final FileType fileType, @NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final FacetDetector<VirtualFile, C> facetDetector) {
if (myForWizardDelegate != null) {
myForWizardDelegate.register(fileType, OldFileContentPattern.byFilePattern(virtualFilePattern), facetDetector, null);
}
}
public <U extends FacetConfiguration> void registerSubFacetDetectorForWizard(@NotNull final FileType fileType, @NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final FacetDetector<VirtualFile, C> facetDetector,
@NotNull final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
if (myForWizardDelegate != null) {
myForWizardDelegate.register(fileType, OldFileContentPattern.byFilePattern(virtualFilePattern), facetDetector, underlyingFacetSelector);
}
}
private <U extends FacetConfiguration> void registerOnTheFlyDetector(@NotNull final FileType fileType,
@NotNull final VirtualFileFilter virtualFileFilter,
@NotNull final Condition<PsiFile> psiFileFilter,
@NotNull final FacetDetector<PsiFile, C> facetDetector,
@Nullable UnderlyingFacetSelector<VirtualFile, U> selector) {
if (myOnTheFlyDelegate != null) {
myOnTheFlyDelegate.register(fileType, OldFileContentPattern.byFilter(virtualFileFilter), psiFileFilter, facetDetector, selector);
}
}
public <U extends FacetConfiguration> void registerOnTheFlySubFacetDetector(@NotNull final FileType fileType,
@NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final ElementPattern<? extends PsiFile> psiFilePattern,
@NotNull final FacetDetector<PsiFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
registerOnTheFlyDetector(fileType, new MyPatternFilter(virtualFilePattern), new Condition<PsiFile>() {
public boolean value(final PsiFile psiFile) {
return psiFilePattern.accepts(psiFile);
}
}, facetDetector, selector);
}
public void registerOnTheFlyDetector(@NotNull final FileType fileType, @NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final ElementPattern<? extends PsiFile> psiFilePattern,
@NotNull final FacetDetector<PsiFile, C> facetDetector) {
registerOnTheFlySubFacetDetector(fileType, virtualFilePattern, psiFilePattern, facetDetector, null);
}
public void registerOnTheFlyDetector(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter, @NotNull final Condition<PsiFile> psiFileFilter,
@NotNull final FacetDetector<PsiFile, C> facetDetector) {
registerOnTheFlyDetector(fileType, virtualFileFilter, psiFileFilter, facetDetector, null);
}
public void registerUniversalDetector(@NotNull final FileType fileType, @NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final FacetDetector<VirtualFile, C> facetDetector) {
registerUniversalDetector(fileType, new MyPatternFilter(virtualFilePattern), facetDetector);
}
public void registerUniversalDetector(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter, @NotNull final FacetDetector<VirtualFile, C> facetDetector) {
registerUniversalDetector(fileType, OldFileContentPattern.byFilter(virtualFileFilter), facetDetector, null);
}
public <U extends FacetConfiguration> void registerUniversalDetector(@NotNull final FileType fileType,
@NotNull final OldFileContentPattern fileContentFilter,
@NotNull final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
if (myForWizardDelegate != null) {
myForWizardDelegate.register(fileType, fileContentFilter, facetDetector, underlyingFacetSelector);
}
if (myOnTheFlyDelegate != null) {
myOnTheFlyDelegate.register(fileType, fileContentFilter, facetDetector, underlyingFacetSelector);
}
}
public <U extends FacetConfiguration> void registerUniversalSubFacetDetector(@NotNull final FileType fileType, @NotNull final VirtualFilePattern virtualFilePattern,
@NotNull final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
registerUniversalDetector(fileType, OldFileContentPattern.byFilePattern(virtualFilePattern), facetDetector, underlyingFacetSelector);
}
private static class MyPatternFilter implements VirtualFileFilter {
private final VirtualFilePattern myVirtualFilePattern;
public MyPatternFilter(final VirtualFilePattern virtualFilePattern) {
myVirtualFilePattern = virtualFilePattern;
}
public boolean accept(final VirtualFile file) {
return myVirtualFilePattern.accepts(file);
}
}
@NotNull
public static <C extends FacetConfiguration> DetectedFacetPresentation getDetectedFacetPresentation(@NotNull FacetType<?,C> facetType) {
FacetDetectorRegistryEx<C> registry = new FacetDetectorRegistryEx<C>(null, null);
facetType.registerDetectors(registry);
DetectedFacetPresentation presentation = registry.myPresentation;
return presentation != null ? presentation : DefaultDetectedFacetPresentation.INSTANCE;
}
}
@@ -1,117 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
/**
* @author nik
*/
public abstract class FacetDetectorWrapper<S, C extends FacetConfiguration, F extends Facet<C>, U extends FacetConfiguration> {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.FacetDetectorWrapper");
private final AutodetectionFilter myAutodetectionFilter;
private final OldFileContentPattern myFileContentPattern;
private final FacetDetector<S,C> myFacetDetector;
private final UnderlyingFacetSelector<VirtualFile, U> myUnderlyingFacetSelector;
private final ProjectFacetInfoSet myDetectedFacetSet;
private final FacetType<F,C> myFacetType;
protected FacetDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType, final AutodetectionFilter autodetectionFilter, final OldFileContentPattern fileContentPattern,
final FacetDetector<S, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myDetectedFacetSet = projectFacetSet;
myFacetType = facetType;
myAutodetectionFilter = autodetectionFilter;
myFileContentPattern = fileContentPattern;
myFacetDetector = facetDetector;
myUnderlyingFacetSelector = selector;
}
public OldFileContentPattern getFileContentPattern() {
return myFileContentPattern;
}
public FacetType<?, C> getFacetType() {
return myFacetType;
}
@Nullable
protected FacetInfo2<Module> detectFacet(@NotNull final Module module, VirtualFile virtualFile, S source) {
if (!myFacetType.isSuitableModuleType(module.getModuleType())) return null;
String url = virtualFile.getUrl();
if (!myAutodetectionFilter.isAutodetectionEnabled(module, myFacetType, url)) {
LOG.debug("Autodetection disabled for " + myFacetType.getPresentableName() + " facets in module " + module.getName());
return null;
}
FacetInfo2<Module> underlyingFacet = null;
FacetTypeId underlyingFacetType = myFacetType.getUnderlyingFacetType();
if (underlyingFacetType != null) {
if (myUnderlyingFacetSelector != null) {
Map<U, FacetInfo2<Module>> underlyingFacets = myDetectedFacetSet.getConfigurations(underlyingFacetType, module);
FacetConfiguration undelyingConfiguration =
myUnderlyingFacetSelector.selectUnderlyingFacet(virtualFile, Collections.unmodifiableSet(underlyingFacets.keySet()));
underlyingFacet = underlyingFacets.get(undelyingConfiguration);
}
if (underlyingFacet == null) {
LOG.debug("Underlying " + underlyingFacetType + " facet not found for " + url);
return null;
}
}
Map<C, FacetInfo2<Module>> configurations = myDetectedFacetSet.getConfigurations(myFacetType.getId(), module);
final C detectedConfiguration = myFacetDetector.detectFacet(source, Collections.unmodifiableSet(configurations.keySet()));
if (detectedConfiguration == null) {
return null;
}
if (configurations.containsKey(detectedConfiguration)) {
return configurations.get(detectedConfiguration);
}
final String name = myDetectedFacetSet.generateName(module, myFacetType);
FacetInfo2<Module> detected = myDetectedFacetSet.createInfo(module, url, underlyingFacet, detectedConfiguration, name, myFacetType, myFacetDetector.getId());
myDetectedFacetSet.addFacetInfo(detected);
return detected;
}
@Override
public String toString() {
return myFacetType.getStringId() + ": " + myFacetDetector.getId();
}
@Nullable
public abstract FacetInfo2<Module> detectFacet(final VirtualFile virtualFile, final PsiManager psiManager);
}
@@ -1,40 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public interface FacetOnTheFlyDetectorRegistry<C extends FacetConfiguration> {
<U extends FacetConfiguration>
void register(@NotNull FileType fileType, @NotNull OldFileContentPattern fileContentPattern,
@NotNull FacetDetector<VirtualFile, C> detector, UnderlyingFacetSelector<VirtualFile, U> selector);
<U extends FacetConfiguration>
void register(@NotNull FileType fileType, @NotNull OldFileContentPattern fileContentPattern,
@NotNull Condition<PsiFile> psiFileFilter, @NotNull FacetDetector<PsiFile, C> detector,
UnderlyingFacetSelector<VirtualFile, U> selector);
}
@@ -1,125 +0,0 @@
/*
* Copyright 2000-2010 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.facet.impl.autodetecting;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.patterns.*;
import com.intellij.psi.impl.cache.impl.CacheUtil;
import com.intellij.util.ProcessingContext;
import com.intellij.util.text.CharSequenceReader;
import com.intellij.util.xml.NanoXmlUtil;
import com.intellij.util.xml.XmlFileHeader;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
/**
* @author nik
*/
public class OldFileContentPattern extends ObjectPattern<FileContent, OldFileContentPattern> {
public OldFileContentPattern() {
super(FileContent.class);
}
public static OldFileContentPattern fileContent() {
return new OldFileContentPattern();
}
public OldFileContentPattern withName(@NotNull final String name) {
return with(new PatternCondition<FileContent>("withName") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
return name.equals(fileContent.getVirtualFile().getName());
}
});
}
public OldFileContentPattern withName(final StringPattern namePattern) {
return with(new PatternCondition<FileContent>("withName") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
return namePattern.accepts(fileContent.getVirtualFile().getName());
}
});
}
public OldFileContentPattern inDirectory(final @NotNull String name) {
return with(new PatternCondition<FileContent>("inDirectory") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
return name.equals(fileContent.getVirtualFile().getParent().getName());
}
});
}
public OldFileContentPattern xmlWithRootTag(@NotNull final String rootTag) {
return with(new PatternCondition<FileContent>("withRootTag") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
try {
return rootTag.equals(parseHeaderWithException(fileContent).getRootTagLocalName());
}
catch (IOException e) {
return false;
}
}
});
}
public OldFileContentPattern xmlWithRootTagNamespace(final String namespace) {
return xmlWithRootTagNamespace(StandardPatterns.string().equalTo(namespace));
}
public OldFileContentPattern xmlWithRootTagNamespace(final ElementPattern<String> namespacePattern) {
return with(new PatternCondition<FileContent>("xmlWithRootTagNamespace") {
public boolean accepts(@NotNull final FileContent fileContent, final ProcessingContext context) {
try {
String rootTagNamespace = parseHeaderWithException(fileContent).getRootTagNamespace();
return rootTagNamespace != null && namespacePattern.getCondition().accepts(rootTagNamespace, context);
}
catch (IOException e) {
return false;
}
}
});
}
public static OldFileContentPattern byFilter(@NotNull final VirtualFileFilter filter) {
return fileContent().with(new PatternCondition<FileContent>("withFileFilter") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
return filter.accept(fileContent.getVirtualFile());
}
});
}
public static OldFileContentPattern byFilePattern(@NotNull final VirtualFilePattern pattern) {
return fileContent().with(new PatternCondition<FileContent>("withFilePattern") {
@Override
public boolean accepts(@NotNull FileContent fileContent, ProcessingContext context) {
return pattern.accepts(fileContent.getVirtualFile());
}
});
}
@NotNull
private static XmlFileHeader parseHeaderWithException(FileContent fileContent) throws IOException {
final CharSequence contentText = CacheUtil.getContentText(fileContent);
//noinspection IOResourceOpenedButNotSafelyClosed
return NanoXmlUtil.parseHeaderWithException(new CharSequenceReader(contentText));
}
}
@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.facet.impl.autodetecting.facetsTree.DetectedFacetsDialog">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="543" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="f60f4" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ProjectBundle" key="label.text.the.following.facets.are.detected.on.the.fly"/>
</properties>
</component>
<scrollpane class="com.intellij.ui.components.JBScrollPane" id="41e3d">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="f167b" binding="myTreePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints/>
<properties/>
<border type="none"/>
<children/>
</grid>
</children>
</scrollpane>
</children>
</grid>
</form>
@@ -1,83 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.facetsTree;
import com.intellij.facet.impl.autodetecting.DetectedFacetManager;
import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.help.HelpManager;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* @author nik
*/
public class DetectedFacetsDialog extends DialogWrapper {
private final ImplicitFacetsTreeComponent myFacetsTreeComponent;
private JPanel myMainPanel;
private JPanel myTreePanel;
public DetectedFacetsDialog(final Project project, final DetectedFacetManager detectedFacetsManager, final Collection<DetectedFacetInfo<Module>> detectedFacets,
final HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> files) {
super(project, true);
setTitle(ProjectBundle.message("dialog.title.facets.detected"));
myFacetsTreeComponent = new ImplicitFacetsTreeComponent(detectedFacetsManager, detectedFacets, files);
DetectedFacetsTree tree = myFacetsTreeComponent.getTree();
TreeUtil.expandAll(tree);
myTreePanel.add(tree, BorderLayout.CENTER);
setOKButtonText(ProjectBundle.message("button.text.accept.detected.facets"));
setCancelButtonText(ProjectBundle.message("button.text.postpone.detected.facets"));
init();
}
@Nullable
protected JComponent createCenterPanel() {
return myMainPanel;
}
@Override
protected Action[] createActions() {
return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
}
@Override
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp("procedures.workingwithmodules.facet");
}
protected void doOKAction() {
new WriteAction() {
protected void run(final Result result) {
myFacetsTreeComponent.createFacets();
}
}.execute();
super.doOKAction();
}
}
@@ -1,175 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.facetsTree;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.facet.impl.autodetecting.FacetDetectorRegistryEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CheckboxTreeBase;
import com.intellij.ui.CheckedTreeNode;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author nik
*/
public class DetectedFacetsTree extends CheckboxTreeBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.facetsTree.DetectedFacetsTree");
private static final Icon MODULE_ICON = IconLoader.getIcon("/nodes/ModuleClosed.png");
public DetectedFacetsTree(final Collection<? extends CheckedTreeNode> roots) {
super(new FacetsCheckboxTreeCellRenderer(), createRoot(roots), new CheckPolicy(true, true, true, false));
}
private static CheckedTreeNode createRoot(final Collection<? extends CheckedTreeNode> nodes) {
CheckedTreeNode root = new CheckedTreeNode(null);
for (CheckedTreeNode node : nodes) {
if (!(node instanceof FacetTypeNode) && !(node instanceof ModuleNode) && !(node instanceof FacetNode)) {
LOG.error("incorrect node class: " + node.getClass().getName());
}
root.add(node);
}
return root;
}
private static class FacetsCheckboxTreeCellRenderer extends CheckboxTreeCellRendererBase {
public void customizeRenderer(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) {
ColoredTreeCellRenderer renderer = getTextRenderer();
if (value instanceof ModuleNode) {
ModuleNode moduleNode = (ModuleNode)value;
renderer.setIcon(MODULE_ICON);
renderer.append(moduleNode.getModuleName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
renderer.append(moduleNode.getModuleDescription(), SimpleTextAttributes.GRAY_ATTRIBUTES);
}
else if (value instanceof FacetNode) {
final FacetNode node = (FacetNode)value;
FacetType type = node.getFacetType();
renderer.setIcon(type.getIcon());
renderer.append(node.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
String description = node.getDescription();
if (description != null) {
renderer.append(" (" + description + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
else if (value instanceof FacetTypeNode) {
FacetType type = ((FacetTypeNode)value).getFacetType();
renderer.setIcon(type.getIcon());
renderer.append(ProjectBundle.message("detected.facet.type.node", type.getPresentableName()), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
}
public static abstract class ModuleNode extends CheckedTreeNode{
private final List<FacetNode> myRootFacets = new ArrayList<FacetNode>();
public ModuleNode(Object userObject) {
super(userObject);
}
public abstract String getModuleName();
public abstract String getModuleDescription();
public void addRootFacet(FacetNode facetInfo) {
myRootFacets.add(facetInfo);
add(facetInfo);
}
public List<FacetNode> getRootFacets() {
return myRootFacets;
}
}
public static class FacetTypeNode extends CheckedTreeNode {
private final FacetType myFacetType;
private final List<ModuleNode> myModuleNodes = new ArrayList<ModuleNode>();
public FacetTypeNode(final FacetType facetType) {
super(facetType);
myFacetType = facetType;
}
public FacetType getFacetType() {
return myFacetType;
}
public void addModuleNode(ModuleNode moduleNode) {
myModuleNodes.add(moduleNode);
add(moduleNode);
}
public List<ModuleNode> getModuleNodes() {
return myModuleNodes;
}
}
public static class FacetNode extends CheckedTreeNode {
private final VirtualFile[] myFiles;
private final FacetType<?,?> myFacetType;
private final VirtualFile myProjectRoot;
private final List<FacetNode> myChildren = new ArrayList<FacetNode>();
public FacetNode(Object userObject, FacetType facetType, VirtualFile projectRoot, final VirtualFile[] files, @Nullable FacetNode parent) {
super(userObject);
myFacetType = facetType;
myProjectRoot = projectRoot;
myFiles = files;
if (parent != null) {
parent.myChildren.add(this);
parent.add(this);
}
}
public String getName() {
return myFacetType.getPresentableName();
}
public VirtualFile[] getFiles() {
return myFiles;
}
public List<FacetNode> getChildren() {
return myChildren;
}
public FacetType getFacetType() {
return myFacetType;
}
@Nullable
public String getDescription() {
DetectedFacetPresentation presentation = FacetDetectorRegistryEx.getDetectedFacetPresentation(myFacetType);
return presentation.getDetectedFacetDescription(myProjectRoot, myFiles);
}
}
}
@@ -1,167 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.facetsTree;
import com.intellij.facet.*;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.impl.autodetecting.FacetAutodetectingManager;
import com.intellij.facet.impl.ui.FacetDetectionProcessor;
import com.intellij.ide.util.importProject.ModuleDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CheckboxTreeBase;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
/**
* @author nik
*/
public class DetectedFacetsTreeComponent {
private final JPanel myMainPanel;
private final List<ModuleDescriptorNode> myModuleNodes = new ArrayList<ModuleDescriptorNode>();
public DetectedFacetsTreeComponent() {
myMainPanel = new JPanel(new BorderLayout());
}
public JPanel getMainPanel() {
return myMainPanel;
}
public void addFacets(ModuleDescriptor moduleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>> root2Facets) {
for (File root : root2Facets.keySet()) {
ModuleDescriptorNode moduleNode = new ModuleDescriptorNode(moduleDescriptor, root);
Map<FacetInfo, DetectedFacetsTree.FacetNode> facetInfos = new HashMap<FacetInfo, DetectedFacetsTree.FacetNode>();
for (FacetDetectionProcessor.DetectedInWizardFacetInfo detectedFacetInfo : root2Facets.get(root)) {
DetectedFacetsTree.FacetNode parent = null;
FacetInfo underlyingFacet = detectedFacetInfo.getFacetInfo().getUnderlyingFacet();
if (underlyingFacet != null) {
parent = facetInfos.get(underlyingFacet);
}
VirtualFile virtualRoot = LocalFileSystem.getInstance().findFileByIoFile(root);
DetectedFacetsTree.FacetNode detectedFacet = new FacetInfoNode(detectedFacetInfo, virtualRoot, parent);
facetInfos.put(detectedFacetInfo.getFacetInfo(), detectedFacet);
if (parent == null) {
moduleNode.addRootFacet(detectedFacet);
}
}
myModuleNodes.add(moduleNode);
}
}
public void createTree() {
final CheckboxTreeBase tree = new DetectedFacetsTree(myModuleNodes);
TreeUtil.expandAll(tree);
myMainPanel.add(tree, BorderLayout.CENTER);
}
public void clear() {
myMainPanel.removeAll();
myModuleNodes.clear();
}
public void createFacets(final ModuleDescriptor descriptor, final Module module, final ModifiableRootModel rootModel) {
List<Pair<FacetDetector, Facet>> createdFacets = new ArrayList<Pair<FacetDetector, Facet>>();
ModifiableFacetModel modifiableModel = FacetManager.getInstance(module).createModifiableModel();
for (ModuleDescriptorNode moduleNode : myModuleNodes) {
if (moduleNode.myModuleDescriptor.equals(descriptor)) {
processFacetsInfos(moduleNode.getRootFacets(), module, rootModel, modifiableModel, null, createdFacets, moduleNode.isChecked());
}
}
modifiableModel.commit();
for (Pair<FacetDetector, Facet> createdFacet : createdFacets) {
createdFacet.getFirst().afterFacetAdded(createdFacet.getSecond());
}
}
private static void processFacetsInfos(final List<DetectedFacetsTree.FacetNode> facets, final Module module, final ModifiableRootModel rootModel,
final ModifiableFacetModel facetModel, Facet underlyingFacet,
final List<Pair<FacetDetector, Facet>> createdFacets, boolean createFacets) {
for (DetectedFacetsTree.FacetNode facetNode : facets) {
boolean createFacet = createFacets && facetNode.isChecked();
FacetDetectionProcessor.DetectedInWizardFacetInfo detectedFacetInfo = ((FacetInfoNode)facetNode).getDetectedFacetInfo();
FacetInfo facetInfo = detectedFacetInfo.getFacetInfo();
FacetType type = facetInfo.getFacetType();
Facet facet = null;
if (createFacet) {
//noinspection unchecked
facet = FacetManager.getInstance(module).createFacet(type, facetInfo.getName(), facetInfo.getConfiguration(), underlyingFacet);
FacetDetector facetDetector = detectedFacetInfo.getFacetDetector();
facetDetector.beforeFacetAdded(facet, facetModel, rootModel);
facetModel.addFacet(facet);
createdFacets.add(Pair.create(facetDetector, facet));
}
else {
VirtualFile[] files = facetNode.getFiles();
String[] urls = new String[files.length];
for (int i = 0; i < files.length; i++) {
urls[i] = files[i].getUrl();
}
FacetAutodetectingManager.getInstance(module.getProject()).disableAutodetectionInFiles(type, module, urls);
}
processFacetsInfos(facetNode.getChildren(), module, rootModel, facetModel, facet, createdFacets, createFacet);
}
}
private static class FacetInfoNode extends DetectedFacetsTree.FacetNode {
private final FacetDetectionProcessor.DetectedInWizardFacetInfo myDetectedFacetInfo;
private FacetInfoNode(final FacetDetectionProcessor.DetectedInWizardFacetInfo detectedFacetInfo, final VirtualFile root, @Nullable final DetectedFacetsTree.FacetNode parent) {
super(detectedFacetInfo.getFacetInfo(), detectedFacetInfo.getFacetInfo().getFacetType(), root, new VirtualFile[]{detectedFacetInfo.getFile()}, parent);
myDetectedFacetInfo = detectedFacetInfo;
}
public FacetDetectionProcessor.DetectedInWizardFacetInfo getDetectedFacetInfo() {
return myDetectedFacetInfo;
}
}
private static class ModuleDescriptorNode extends DetectedFacetsTree.ModuleNode {
private final ModuleDescriptor myModuleDescriptor;
private final File myRoot;
private ModuleDescriptorNode(ModuleDescriptor moduleDescriptor, final File root) {
super(moduleDescriptor);
myModuleDescriptor = moduleDescriptor;
myRoot = root;
}
public String getModuleName() {
return myModuleDescriptor.getName();
}
public String getModuleDescription() {
return " (" + myRoot.getPath() + ")";
}
}
}
@@ -1,199 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.facetsTree;
import com.intellij.facet.FacetType;
import com.intellij.facet.Facet;
import com.intellij.facet.impl.autodetecting.DetectedFacetManager;
import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.FacetInfoBackedByFacet;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* @author nik
*/
public class ImplicitFacetsTreeComponent {
private final DetectedFacetsTree myTree;
private final DetectedFacetManager myDetectedFacetManager;
private final Collection<DetectedFacetsTree.FacetTypeNode> myFacetTypeNodes;
public ImplicitFacetsTreeComponent(DetectedFacetManager detectedFacetManager, Collection<DetectedFacetInfo<Module>> detectedFacets, HashMap<DetectedFacetInfo<Module>, List<VirtualFile>> files) {
myDetectedFacetManager = detectedFacetManager;
Map<FacetType, DetectedFacetsTree.FacetTypeNode> facetTypeNodes = new HashMap<FacetType, DetectedFacetsTree.FacetTypeNode>();
Collection<FacetInfo2<Module>> sortedFacets = new LinkedHashSet<FacetInfo2<Module>>();
for (FacetInfo2<Module> facet : detectedFacets) {
addUnderlying(facet, sortedFacets);
}
Map<FacetInfo2<Module>, DetectedFacetsTree.FacetNode> facetNodes = new HashMap<FacetInfo2<Module>, DetectedFacetsTree.FacetNode>();
for (FacetInfo2<Module> facetInfo : sortedFacets) {
FacetType facetType = getRootFacetType(facetInfo);
DetectedFacetsTree.FacetTypeNode facetTypeNode = facetTypeNodes.get(facetType);
if (facetTypeNode == null) {
facetTypeNode = new DetectedFacetsTree.FacetTypeNode(facetType);
facetTypeNodes.put(facetType, facetTypeNode);
}
Module module = facetInfo.getModule();
ModuleNodeImpl moduleNode = findOrCreateModuleNode(facetTypeNode, module);
DetectedFacetsTree.FacetNode parentNode = null;
FacetInfo2<Module> underlyingFacet = facetInfo.getUnderlyingFacetInfo();
if (underlyingFacet != null) {
parentNode = facetNodes.get(underlyingFacet);
}
VirtualFile projectRoot = facetInfo.getModule().getProject().getBaseDir();
DetectedFacetsTree.FacetNode facetNode;
if (facetInfo instanceof DetectedFacetInfo) {
facetNode = new FacetNodeImpl((DetectedFacetInfo<Module>)facetInfo, projectRoot, parentNode, files.get(facetInfo));
}
else {
facetNode = new RealFacetNode((FacetInfoBackedByFacet)facetInfo, projectRoot, parentNode);
}
facetNodes.put(facetInfo, facetNode);
if (parentNode == null) {
moduleNode.addRootFacet(facetNode);
}
}
myFacetTypeNodes = facetTypeNodes.values();
myTree = new DetectedFacetsTree(myFacetTypeNodes);
}
public void createFacets() {
for (DetectedFacetsTree.FacetTypeNode facetTypeNode : myFacetTypeNodes) {
for (DetectedFacetsTree.ModuleNode moduleNode : facetTypeNode.getModuleNodes()) {
boolean accept = facetTypeNode.isChecked() && moduleNode.isChecked();
processFacetNodes(moduleNode.getRootFacets(), accept, null);
}
}
}
private void processFacetNodes(final List<DetectedFacetsTree.FacetNode> facetNodes, final boolean accept, final Facet underlyingFacet) {
for (DetectedFacetsTree.FacetNode facetNode : facetNodes) {
Facet facet = null;
if (facetNode instanceof FacetNodeImpl) {
DetectedFacetInfo<Module> detectedFacetInfo = ((FacetNodeImpl)facetNode).getDetectedFacetInfo();
if (accept && facetNode.isChecked()) {
facet = myDetectedFacetManager.createFacet(detectedFacetInfo, underlyingFacet);
}
else {
myDetectedFacetManager.disableDetectionInFile(detectedFacetInfo);
}
}
else {
facet = ((RealFacetNode)facetNode).myFacetInfo.getFacet();
}
processFacetNodes(facetNode.getChildren(), accept && facetNode.isChecked(), facet);
}
}
private static void addUnderlying(final FacetInfo2<Module> facet, final Collection<FacetInfo2<Module>> sortedFacets) {
FacetInfo2<Module> underlying = facet.getUnderlyingFacetInfo();
if (underlying != null && !sortedFacets.contains(underlying)) {
addUnderlying(underlying, sortedFacets);
}
sortedFacets.add(facet);
}
private static ModuleNodeImpl findOrCreateModuleNode(final DetectedFacetsTree.FacetTypeNode facetTypeNode, final Module module) {
for (DetectedFacetsTree.ModuleNode node : facetTypeNode.getModuleNodes()) {
ModuleNodeImpl moduleNode = (ModuleNodeImpl)node;
if (moduleNode.myModule.equals(module)) {
return moduleNode;
}
}
ModuleNodeImpl moduleNode = new ModuleNodeImpl(module);
facetTypeNode.addModuleNode(moduleNode);
return moduleNode;
}
private static FacetType getRootFacetType(final FacetInfo2<?> detectedFacet) {
FacetInfo2<?> facet = detectedFacet;
FacetInfo2<?> underlyingFacet;
while ((underlyingFacet = facet.getUnderlyingFacetInfo()) != null) {
facet = underlyingFacet;
}
return facet.getFacetType();
}
public DetectedFacetsTree getTree() {
return myTree;
}
private static class FacetNodeImpl extends DetectedFacetsTree.FacetNode {
private final DetectedFacetInfo<Module> myDetectedFacetInfo;
private FacetNodeImpl(@NotNull DetectedFacetInfo<Module> detectedFacet, VirtualFile projectRoot, @Nullable final DetectedFacetsTree.FacetNode parent,
final @NotNull List<VirtualFile> files) {
super(detectedFacet, detectedFacet.getFacetType(), projectRoot, VfsUtil.toVirtualFileArray(files), parent);
myDetectedFacetInfo = detectedFacet;
}
public DetectedFacetInfo<Module> getDetectedFacetInfo() {
return myDetectedFacetInfo;
}
public String getName() {
return myDetectedFacetInfo.getFacetName();
}
}
private static class RealFacetNode extends DetectedFacetsTree.FacetNode {
private final FacetInfoBackedByFacet myFacetInfo;
private RealFacetNode(final FacetInfoBackedByFacet facetInfo, final VirtualFile projectRoot, @Nullable final DetectedFacetsTree.FacetNode parent) {
super(facetInfo, facetInfo.getFacetType(), projectRoot, VirtualFile.EMPTY_ARRAY, parent);
myFacetInfo = facetInfo;
}
public String getDescription() {
return "";
}
public String getName() {
return myFacetInfo.getFacetName();
}
}
private static class ModuleNodeImpl extends DetectedFacetsTree.ModuleNode {
private final Module myModule;
private ModuleNodeImpl(final Module module) {
super(module);
myModule = module;
}
public String getModuleName() {
return myModule.getName();
}
public String getModuleDescription() {
return "";
}
}
}
@@ -1,26 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
/**
* @author nik
*/
public interface DetectedFacetInfo<M> extends FacetInfo2<M> {
int getId();
String getDetectorId();
}
@@ -1,87 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author nik
*/
public class DetectedFacetInfoImpl<M> implements DetectedFacetInfo<M> {
private final String myFacetName;
private final FacetConfiguration myConfiguration;
private final FacetType<?,?> myFacetType;
private final FacetInfo2<M> myUnderlyingFacetInfo;
private final M myModule;
private final Collection<String> myUrls;
private final int myId;
private final String myDetectorId;
public DetectedFacetInfoImpl(final @NotNull String facetName, final @NotNull FacetConfiguration configuration, final @NotNull FacetType<?, ?> facetType,
final @NotNull M module,
final @Nullable FacetInfo2<M> underlyingFacetInfo,
final String url,
final int id,
final String detectorId) {
myFacetName = facetName;
myConfiguration = configuration;
myFacetType = facetType;
myModule = module;
myUnderlyingFacetInfo = underlyingFacetInfo;
myId = id;
myDetectorId = detectorId;
myUrls = new ArrayList<String>();
myUrls.add(url);
}
@NotNull
public String getFacetName() {
return myFacetName;
}
@NotNull
public FacetConfiguration getConfiguration() {
return myConfiguration;
}
@NotNull
public FacetType<?,?> getFacetType() {
return myFacetType;
}
public FacetInfo2<M> getUnderlyingFacetInfo() {
return myUnderlyingFacetInfo;
}
@NotNull
public M getModule() {
return myModule;
}
public int getId() {
return myId;
}
public String getDetectorId() {
return myDetectorId;
}
}
@@ -1,42 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public interface FacetInfo2<M> {
@NotNull
String getFacetName();
@NotNull
FacetConfiguration getConfiguration();
@NotNull
FacetType<?,?> getFacetType();
@Nullable
FacetInfo2<M> getUnderlyingFacetInfo();
@NotNull
M getModule();
}
@@ -1,64 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class FacetInfoBackedByFacet implements FacetInfo2<Module> {
private final Facet myFacet;
private final ProjectFacetInfoSet myProjectFacetSet;
FacetInfoBackedByFacet(@NotNull Facet facet, final ProjectFacetInfoSet projectFacetSet) {
myFacet = facet;
myProjectFacetSet = projectFacetSet;
}
@NotNull
public String getFacetName() {
return myFacet.getName();
}
@NotNull
public FacetConfiguration getConfiguration() {
return myFacet.getConfiguration();
}
@NotNull
public FacetType getFacetType() {
return myFacet.getType();
}
public FacetInfo2<Module> getUnderlyingFacetInfo() {
Facet underlying = myFacet.getUnderlyingFacet();
return underlying != null ? myProjectFacetSet.getOrCreateInfo(underlying) : null;
}
@NotNull
public Module getModule() {
return myFacet.getModule();
}
public Facet getFacet() {
return myFacet;
}
}
@@ -1,168 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.util.containers.FactoryMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author nik
*/
public class FacetInfoSet<M> {
private final Map<FacetConfiguration, FacetInfo2<M>> myFacetInfos = new HashMap<FacetConfiguration, FacetInfo2<M>>();
private final Map<FacetTypeId, MultiValuesMap<M, FacetInfo2<M>>> myInfosByType = new FactoryMap<FacetTypeId, MultiValuesMap<M, FacetInfo2<M>>>() {
protected MultiValuesMap<M, FacetInfo2<M>> create(final FacetTypeId key) {
return new MultiValuesMap<M, FacetInfo2<M>>();
}
};
private final Map<Integer, DetectedFacetInfo<M>> myDetectedById = new HashMap<Integer, DetectedFacetInfo<M>>();
public void addFacetInfo(@NotNull FacetInfo2<M> facetInfo) {
myFacetInfos.put(facetInfo.getConfiguration(), facetInfo);
myInfosByType.get(facetInfo.getFacetType().getId()).put(facetInfo.getModule(), facetInfo);
if (facetInfo instanceof DetectedFacetInfo) {
DetectedFacetInfo<M> detected = (DetectedFacetInfo<M>)facetInfo;
myDetectedById.put(detected.getId(), detected);
}
}
public void removeFacetInfo(@NotNull FacetInfo2<M> facetInfo) {
myFacetInfos.remove(facetInfo.getConfiguration());
myInfosByType.get(facetInfo.getFacetType().getId()).remove(facetInfo.getModule(), facetInfo);
if (facetInfo instanceof DetectedFacetInfo) {
final DetectedFacetInfo<M> detected = (DetectedFacetInfo<M>)facetInfo;
myDetectedById.remove(detected.getId());
}
}
public void removeDetectedFacets(final FacetTypeId<?> type, final M module) {
Collection<FacetInfo2<M>> facets = myInfosByType.get(type).get(module);
if (facets != null) {
List<FacetInfo2<M>> infos = new ArrayList<FacetInfo2<M>>(facets);
for (FacetInfo2<M> info : infos) {
if (info instanceof DetectedFacetInfo) {
removeFacetInfo(info);
}
}
}
}
public void removeDetectedFacets(FacetTypeId<?> type) {
List<FacetInfo2<M>> infos = new ArrayList<FacetInfo2<M>>(myInfosByType.get(type).values());
for (FacetInfo2<M> info : infos) {
if (info instanceof DetectedFacetInfo) {
removeFacetInfo(info);
}
}
}
@Nullable
public FacetInfo2 findFacet(final @NotNull FacetTypeId<?> typeId, @NotNull M module, final @NotNull String name) {
Collection<FacetInfo2<M>> detectedFacets = myInfosByType.get(typeId).get(module);
if (detectedFacets != null) {
for (FacetInfo2 detected : detectedFacets) {
if (detected.getFacetName().equals(name)) {
return detected;
}
}
}
return null;
}
public <C extends FacetConfiguration, F extends Facet<C>> Map<C, FacetInfo2<M>> getConfigurations(final FacetTypeId<F> typeId, final M module) {
//todo[nik] cache?
Map<C, FacetInfo2<M>> configurations = new LinkedHashMap<C, FacetInfo2<M>>();
Collection<FacetInfo2<M>> detectedFacets = myInfosByType.get(typeId).get(module);
if (detectedFacets != null) {
for (FacetInfo2 detected : detectedFacets) {
if (detected instanceof FacetInfoBackedByFacet) {
//noinspection unchecked
configurations.put((C)detected.getConfiguration(), detected);
}
}
for (FacetInfo2 detected : detectedFacets) {
if (!(detected instanceof FacetInfoBackedByFacet)) {
//noinspection unchecked
configurations.put((C)detected.getConfiguration(), detected);
}
}
}
return configurations;
}
public String generateName(final M module, final FacetType<?, ?> facetType) {
String baseName = facetType.getDefaultFacetName();
int i = 2;
String name = baseName;
while (findFacet(facetType.getId(), module, name) != null) {
name = baseName + i;
i++;
}
return name;
}
@Nullable
public FacetInfo2<M> findById(int id) {
return myDetectedById.get(id);
}
public void removeDetectedFacetWithSubFacets(final Integer id) {
FacetInfo2<M> detected = myDetectedById.get(id);
if (detected != null) {
Set<FacetInfo2<M>> set = collectSubFacets(detected);
for (FacetInfo2<M> info : set) {
removeFacetInfo(info);
}
}
}
public void removeDetectedFacets(@NotNull M module) {
List<FacetTypeId> typeIds = new ArrayList<FacetTypeId>(myInfosByType.keySet());
for (FacetTypeId typeId : typeIds) {
removeDetectedFacets(typeId, module);
}
}
private Set<FacetInfo2<M>> collectSubFacets(final FacetInfo2<M> facetInfo) {
final Set<FacetInfo2<M>> set = new HashSet<FacetInfo2<M>>();
set.add(facetInfo);
boolean setChanged = true;
while (setChanged) {
setChanged = false;
for (FacetInfo2<M> info : myFacetInfos.values()) {
FacetInfo2<M> underlying = info.getUnderlyingFacetInfo();
if (underlying != null && set.contains(underlying) && !set.contains(info)) {
set.add(info);
setChanged = true;
}
}
}
return set;
}
public Collection<DetectedFacetInfo<M>> getAllDetectedFacets() {
return Collections.unmodifiableCollection(myDetectedById.values());
}
}
@@ -1,270 +0,0 @@
/*
* 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 com.intellij.facet.impl.autodetecting.model;
import com.intellij.facet.*;
import com.intellij.facet.impl.FacetUtil;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.SystemProperties;
import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import org.jdom.Document;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* @author nik
*/
public class ProjectFacetInfoSet extends FacetInfoSet<Module> {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet");
private final Map<Facet, FacetInfoBackedByFacet> myFacetInfos = new HashMap<Facet, FacetInfoBackedByFacet>();
private final EventDispatcher<DetectedFacetListener> myDispatcher = EventDispatcher.create(DetectedFacetListener.class);
private int myNextId;
private final Project myProject;
public ProjectFacetInfoSet(Project project, Disposable parentDisposable) {
myProject = project;
ProjectWideFacetListenersRegistry.getInstance(project).registerListener(new MyProjectWideFacetAdapter(), parentDisposable);
}
public FacetInfoBackedByFacet getOrCreateInfo(@NotNull Facet facet) {
FacetInfoBackedByFacet info = myFacetInfos.get(facet);
if (info == null) {
info = new FacetInfoBackedByFacet(facet, this);
myFacetInfos.put(facet, info);
}
return info;
}
public void addFacetInfo(@NotNull final FacetInfo2<Module> facetInfo) {
super.addFacetInfo(facetInfo);
if (facetInfo instanceof DetectedFacetInfo) {
myDispatcher.getMulticaster().facetDetected((DetectedFacetInfo<Module>)facetInfo);
}
}
public void removeFacetInfo(@NotNull final FacetInfo2<Module> facetInfo) {
super.removeFacetInfo(facetInfo);
if (facetInfo instanceof DetectedFacetInfo) {
myDispatcher.getMulticaster().facetRemoved((DetectedFacetInfo<Module>)facetInfo);
}
}
public void loadDetectedFacets(@NotNull File file) {
if (!file.exists()) return;
FacetTypeRegistry facetTypeRegistry = FacetTypeRegistry.getInstance();
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
Document document;
try {
document = JDOMUtil.loadDocument(file);
}
catch (Exception e) {
LOG.info(e);
return;
}
DetectedFacetsBean detectedFacetsBean = XmlSerializer.deserialize(document, DetectedFacetsBean.class);
if (detectedFacetsBean == null) return;
for (DetectedFacetBean facetBean : detectedFacetsBean.myFacets) {
FacetType type = facetTypeRegistry.findFacetType(facetBean.myTypeId);
if (type == null) {
LOG.info("facet type '" + facetBean.myTypeId + " not found");
continue;
}
Module module = moduleManager.findModuleByName(facetBean.myModuleName);
if (module == null) {
LOG.info("module '" + facetBean.myModuleName + "' not found");
continue;
}
FacetInfo2<Module> underlyingFacet = null;
String underlyingId = facetBean.myUnderlyingId;
if (underlyingId != null) {
if (underlyingId.startsWith("/")) {
underlyingFacet = findById(Integer.parseInt(underlyingId.substring(1)));
}
else {
Facet facet = FacetPointersManager.getInstance(myProject).create(underlyingId).getFacet();
underlyingFacet = facet != null ? getOrCreateInfo(facet) : null;
}
}
FacetConfiguration configuration = type.createDefaultConfiguration();
try {
FacetUtil.loadFacetConfiguration(configuration, facetBean.myConfiguration);
}
catch (InvalidDataException e) {
LOG.info(e);
continue;
}
int id = facetBean.myId;
myNextId = Math.max(myNextId, id + 1);
addFacetInfo(new DetectedFacetInfoImpl<Module>(facetBean.myFacetName, configuration, type, module, underlyingFacet, null, id,
facetBean.myDetectorId));
}
}
public void saveDetectedFacets(File file) {
DetectedFacetsBean facetsBean = new DetectedFacetsBean();
Collection<DetectedFacetInfo<Module>> facets = getAllDetectedFacets();
Set<DetectedFacetInfo<Module>> added = new HashSet<DetectedFacetInfo<Module>>();
for (DetectedFacetInfo<Module> facet : facets) {
addFacetBean(facet, facetsBean, added);
}
Element element = XmlSerializer.serialize(facetsBean, new SkipDefaultValuesSerializationFilters());
try {
FileUtil.delete(file);
FileUtil.createParentDirs(file);
JDOMUtil.writeDocument(new Document(element), file, SystemProperties.getLineSeparator());
}
catch (IOException e) {
LOG.info(e);
}
}
private static boolean addFacetBean(final DetectedFacetInfo<Module> facet, final DetectedFacetsBean facetsBean,
final Set<DetectedFacetInfo<Module>> added) {
if (!added.add(facet)) {
return true;
}
FacetInfo2<Module> underlyingInfo = facet.getUnderlyingFacetInfo();
if (underlyingInfo instanceof DetectedFacetInfo && !addFacetBean((DetectedFacetInfo<Module>)underlyingInfo, facetsBean, added)) {
return false;
}
try {
final Element configuration = FacetUtil.saveFacetConfiguration(facet.getConfiguration());
final String underlyingId;
if (underlyingInfo instanceof FacetInfoBackedByFacet) {
underlyingId = FacetPointersManager.constructId(((FacetInfoBackedByFacet)underlyingInfo).getFacet());
}
else {
underlyingId = underlyingInfo != null ? "/" + ((DetectedFacetInfo)underlyingInfo).getId() : null;
}
DetectedFacetBean facetBean = new DetectedFacetBean(facet.getId(), facet.getFacetName(), facet.getModule().getName(), configuration,
facet.getFacetType().getStringId(), underlyingId, facet.getDetectorId());
facetsBean.myFacets.add(facetBean);
return true;
}
catch (WriteExternalException e) {
LOG.info(e);
return false;
}
}
public void addListener(@NotNull DetectedFacetListener listener) {
myDispatcher.addListener(listener);
}
public <C extends FacetConfiguration, F extends Facet<C>> DetectedFacetInfo<Module> createInfo(final Module module,
final String url, final FacetInfo2<Module> underlyingFacet,
final C detectedConfiguration,
final String name,
final FacetType<F, C> facetType,
final String detectorId) {
return new DetectedFacetInfoImpl<Module>(name, detectedConfiguration, facetType, module, underlyingFacet, url,
generateId(), detectorId);
}
private int generateId() {
return myNextId++;
}
private class MyProjectWideFacetAdapter extends ProjectWideFacetAdapter<Facet> {
public void facetAdded(final Facet facet) {
addFacetInfo(getOrCreateInfo(facet));
}
public void facetRemoved(final Facet facet) {
FacetInfoBackedByFacet detected = myFacetInfos.remove(facet);
if (detected != null) {
removeFacetInfo(detected);
}
}
}
public static interface DetectedFacetListener extends EventListener {
void facetDetected(final DetectedFacetInfo<Module> info);
void facetRemoved(DetectedFacetInfo<Module> info);
}
public static class DetectedFacetsBean {
@Tag("facets")
@AbstractCollection(surroundWithTag = false)
public List<DetectedFacetBean> myFacets = new ArrayList<DetectedFacetBean>();
}
@Tag("facet")
public static class DetectedFacetBean {
@Attribute("type")
public String myTypeId;
@Attribute("facet-name")
public String myFacetName;
@Attribute("id")
public int myId;
@Tag("configuration")
public Element myConfiguration;
@Attribute("underlying-id")
public String myUnderlyingId;
@Attribute("module-name")
public String myModuleName;
@Attribute("detector-id")
public String myDetectorId;
public DetectedFacetBean() {
}
public DetectedFacetBean(final int id, final String facetName, final String moduleName, final Element configuration,
final String typeId, final String underlyingId, String detectorId) {
myId = id;
myFacetName = facetName;
myConfiguration = configuration;
myTypeId = typeId;
myModuleName = moduleName;
myUnderlyingId = underlyingId;
myDetectorId = detectorId;
}
}
}
@@ -1,273 +0,0 @@
/*
* 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 com.intellij.facet.impl.ui;
import com.intellij.facet.*;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.FacetDetectorForWizardRegistry;
import com.intellij.facet.impl.autodetecting.FacetDetectorRegistryEx;
import com.intellij.facet.impl.autodetecting.OldFileContentPattern;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.*;
/**
* @author nik
*/
public class FacetDetectionProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.ui.FacetDetectionProcessor");
private final Map<FacetConfiguration, DetectedInWizardFacetInfo> myDetectedFacets = new LinkedHashMap<FacetConfiguration, DetectedInWizardFacetInfo>();
private final Map<FacetTypeId, List<FacetConfiguration>> myDetectedConfigurations = new HashMap<FacetTypeId, List<FacetConfiguration>>();
private final ProgressIndicator myProgressIndicator;
private final FileTypeManager myFileTypeManager;
private final List<MultiValuesMap<FileType, MyFacetDetectorWrapper>> myDetectors = new ArrayList<MultiValuesMap<FileType, MyFacetDetectorWrapper>>();
public FacetDetectionProcessor(final ProgressIndicator progressIndicator, final ModuleType moduleType) {
myProgressIndicator = progressIndicator;
myFileTypeManager = FileTypeManager.getInstance();
FacetType[] types = FacetTypeRegistry.getInstance().getFacetTypes();
for (FacetType<?,?> type : types) {
if (type.isSuitableModuleType(moduleType)) {
registerDetectors(type);
myDetectedConfigurations.put(type.getId(), new ArrayList<FacetConfiguration>());
}
}
}
private <C extends FacetConfiguration> void registerDetectors(final FacetType<?, C> type) {
type.registerDetectors(new FacetDetectorRegistryEx<C>(new MyFacetDetectorRegistry<C>(type), null));
}
public void process(final File root) {
final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root);
if (virtualFile == null) return;
for (int i = 0; i < myDetectors.size(); i++) {
MultiValuesMap<FileType, MyFacetDetectorWrapper> map = myDetectors.get(i);
if (i > 0) {
List<MyFacetDetectorWrapper> toRemove = new ArrayList<MyFacetDetectorWrapper>();
for (MyFacetDetectorWrapper detector : map.values()) {
FacetTypeId typeId = detector.getFacetType().getUnderlyingFacetType();
LOG.assertTrue(typeId != null);
List<FacetConfiguration> list = myDetectedConfigurations.get(typeId);
if (list == null || list.isEmpty()) {
toRemove.add(detector);
}
}
for (MyFacetDetectorWrapper detectorWrapper : toRemove) {
map.remove(detectorWrapper.getFileType(), detectorWrapper);
}
}
if (map.isEmpty()) break;
process(virtualFile, map);
}
}
private void process(final VirtualFile file, MultiValuesMap<FileType, MyFacetDetectorWrapper> detectorsMap) {
if (myProgressIndicator.isCanceled()) return;
if (file.isDirectory()) {
file.getChildren();//initialize myChildren field to ensure that refresh will be really performed
file.refresh(false, false);
VirtualFile[] children = file.getChildren();
for (VirtualFile child : children) {
process(child, detectorsMap);
}
return;
}
myProgressIndicator.setText2(file.getPresentableUrl());
FileType fileType = myFileTypeManager.getFileTypeByFile(file);
Collection<MyFacetDetectorWrapper> detectors = detectorsMap.get(fileType);
if (detectors == null) return;
final FileContent content = new FileContent(file);
for (MyFacetDetectorWrapper detector : detectors) {
detector.detectFacet(content);
}
}
public List<DetectedInWizardFacetInfo> getDetectedFacetsInfos() {
return new ArrayList<DetectedInWizardFacetInfo>(myDetectedFacets.values());
}
public List<FacetInfo> getDetectedFacets() {
List<FacetInfo> list = new ArrayList<FacetInfo>();
for (DetectedInWizardFacetInfo info : myDetectedFacets.values()) {
list.add(info.getFacetInfo());
}
return list;
}
private class MyFacetDetectorWrapper<C extends FacetConfiguration, U extends FacetConfiguration> {
private final FacetType<?, C> myFacetType;
private final FileType myFileType;
private final OldFileContentPattern myFileContentPattern;
private final FacetDetector<VirtualFile, C> myDetector;
private final UnderlyingFacetSelector<VirtualFile, U> myUnderlyingFacetSelector;
public MyFacetDetectorWrapper(final FacetType<?, C> facetType, final FileType fileType, final OldFileContentPattern fileContentFilter, final FacetDetector<VirtualFile, C> detector,
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
myUnderlyingFacetSelector = underlyingFacetSelector;
myFacetType = facetType;
myFileType = fileType;
myFileContentPattern = fileContentFilter;
myDetector = detector;
}
public FileType getFileType() {
return myFileType;
}
public FacetType<?, C> getFacetType() {
return myFacetType;
}
public void detectFacet(final FileContent fileContent) {
if (!myFileContentPattern.accepts(fileContent)) return;
final VirtualFile file = fileContent.getVirtualFile();
FacetInfo underlyingFacet = null;
if (myUnderlyingFacetSelector != null) {
List<U> list = (List<U>)myDetectedConfigurations.get(myFacetType.getUnderlyingFacetType());
U underlying = myUnderlyingFacetSelector.selectUnderlyingFacet(file, list);
if (underlying == null) {
return;
}
underlyingFacet = myDetectedFacets.get(underlying).getFacetInfo();
}
List<C> configurations = (List<C>)myDetectedConfigurations.get(myFacetType.getId());
C newConfiguration = myDetector.detectFacet(file, configurations);
if (newConfiguration == null || configurations.contains(newConfiguration)) {
return;
}
FacetInfo facetInfo = new FacetInfo(myFacetType, generateFacetName(), newConfiguration, underlyingFacet);
configurations.add(newConfiguration);
myDetectedFacets.put(newConfiguration, new DetectedInWizardFacetInfo(facetInfo, file, myDetector));
}
private String generateFacetName() {
String baseName = myFacetType.getDefaultFacetName();
String name = baseName;
int i = 2;
while (isUsed(name)) {
name = baseName + i;
i++;
}
return name;
}
private boolean isUsed(final String name) {
List<FacetConfiguration> configurations = myDetectedConfigurations.get(myFacetType.getId());
if (configurations != null) {
for (FacetConfiguration configuration : configurations) {
if (name.equals(myDetectedFacets.get(configuration).getFacetInfo().getName())) {
return true;
}
}
}
return false;
}
}
private class MyFacetDetectorRegistry<C extends FacetConfiguration> implements FacetDetectorForWizardRegistry<C> {
private final FacetType<?, C> myFacetType;
private final int myLevel;
public MyFacetDetectorRegistry(final FacetType<?, C> facetType) {
myFacetType = facetType;
int level = 0;
FacetTypeId<?> typeId = facetType.getUnderlyingFacetType();
Set<FacetTypeId> parentTypes = new HashSet<FacetTypeId>();
parentTypes.add(facetType.getId());
while (typeId != null) {
level++;
FacetType<?,?> underlying = FacetTypeRegistry.getInstance().findFacetType(typeId);
LOG.assertTrue(underlying != null, "Cannot find underlying facet type by id: " + typeId + " (for facet " + facetType.getId() + ")");
typeId = underlying.getUnderlyingFacetType();
if (!parentTypes.add(typeId)) {
LOG.error("Circular dependency between facets: " + parentTypes);
break;
}
}
myLevel=level;
}
public <U extends FacetConfiguration> void register(final FileType fileType, @NotNull final OldFileContentPattern fileContentPattern, final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
if (myFacetType.getUnderlyingFacetType() != null) {
LOG.assertTrue(underlyingFacetSelector != null, "UnderlyingFacetSelector must be specified for " + myFacetType.getPresentableName() + " detector");
}
else {
LOG.assertTrue(underlyingFacetSelector == null, "UnderlyingFacetSelector must not be specified for " + myFacetType.getPresentableName() + " detector");
}
MyFacetDetectorWrapper<C, U> detector = new MyFacetDetectorWrapper<C, U>(myFacetType, fileType, fileContentPattern,
facetDetector, underlyingFacetSelector);
getDetectorsMap().put(fileType, detector);
}
private MultiValuesMap<FileType, MyFacetDetectorWrapper> getDetectorsMap() {
while (myLevel >= myDetectors.size()) {
myDetectors.add(new MultiValuesMap<FileType, MyFacetDetectorWrapper>());
}
return myDetectors.get(myLevel);
}
}
//todo[nik] use DetectedFacetInfo instead
public static class DetectedInWizardFacetInfo {
private final FacetInfo myFacetInfo;
private final VirtualFile myFile;
private final FacetDetector myFacetDetector;
public DetectedInWizardFacetInfo(final FacetInfo facetInfo, final VirtualFile file, final FacetDetector facetDetector) {
myFacetInfo = facetInfo;
myFile = file;
myFacetDetector = facetDetector;
}
public FacetInfo getFacetInfo() {
return myFacetInfo;
}
public VirtualFile getFile() {
return myFile;
}
public FacetDetector getFacetDetector() {
return myFacetDetector;
}
}
}
@@ -1,174 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.facet.impl.ui.facetType.FacetAutodetectionConfigurable">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="850" height="308"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3eb01" class="javax.swing.JCheckBox" binding="myEnableAutoDetectionCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text resource-bundle="messages/ProjectBundle" key="checkbox.text.enable.auto.detection"/>
</properties>
</component>
<vspacer id="cbc45">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="cb574" binding="mySettingsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="1" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="e56d7">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="284de" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactorySimpleWithoutIndent"/>
</clientProperties>
<border type="etched" title-resource-bundle="messages/ProjectBundle" title-key="label.text.autodetection.skip.modules"/>
<children>
<grid id="24018" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="c5815">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="c8e69" class="javax.swing.JButton" binding="myRemoveModuleButton">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ProjectBundle" key="button.remove"/>
</properties>
</component>
<component id="7a5d0" class="javax.swing.JButton" binding="myAddModuleButton">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ProjectBundle" key="button.add"/>
</properties>
</component>
</children>
</grid>
<grid id="fbaab" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="180" height="-1"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="c575b" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="250" height="120"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d3735" class="com.intellij.ui.components.JBList" binding="myModulesList">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
</children>
</grid>
<grid id="1567f" binding="mySkipFilesListPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactorySimpleWithoutIndent"/>
</clientProperties>
<border type="etched" title-resource-bundle="messages/ProjectBundle" title-key="label.text.autodetection.skip.files"/>
<children>
<grid id="4807d" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="77903" class="javax.swing.JButton" binding="myRemoveFileButton">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ProjectBundle" key="button.text.autodetection.remove.file"/>
</properties>
</component>
<vspacer id="cdbb2">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
<grid id="65e12" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="4fa3" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="350" height="120"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="96c82" class="com.intellij.ui.components.JBList" binding="myFilesList">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>
@@ -1,393 +0,0 @@
/*
* 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 com.intellij.facet.impl.ui.facetType;
import com.intellij.facet.FacetType;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionByTypeElement;
import com.intellij.framework.detection.impl.exclude.old.DisabledAutodetectionInModuleElement;
import com.intellij.facet.impl.autodetecting.FacetAutodetectingManager;
import com.intellij.facet.impl.autodetecting.FacetAutodetectingManagerImpl;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.ListUtil;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.BidirectionalMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.*;
/**
* @author nik
*/
public class FacetAutodetectionConfigurable implements Configurable {
private final Project myProject;
private final StructureConfigurableContext myContext;
private final FacetType<?, ?> myFacetType;
private JPanel myMainPanel;
private JCheckBox myEnableAutoDetectionCheckBox;
private JList myModulesList;
private JButton myAddModuleButton;
private JButton myRemoveModuleButton;
private JList myFilesList;
private JButton myRemoveFileButton;
private JPanel mySettingsPanel;
private JPanel mySkipFilesListPanel;
private final DefaultListModel myModulesListModel;
private final DefaultListModel myFilesListModel;
private final BidirectionalMap<String, String> myFile2Module = new BidirectionalMap<String, String>();
private final Set<String> myRemovedModules = new HashSet<String>();
private final Set<String> myAddedModules = new HashSet<String>();
private final Set<String> myRemovedFiles = new HashSet<String>();
private boolean myAutodetectionWasEnabled;
public FacetAutodetectionConfigurable(@NotNull Project project, final StructureConfigurableContext context, final @NotNull FacetType<?, ?> facetType) {
myProject = project;
myContext = context;
myFacetType = facetType;
myModulesList.setCellRenderer(new ModulesListCellRenderer());
myModulesListModel = new DefaultListModel();
myModulesList.setModel(myModulesListModel);
myFilesList.setCellRenderer(new FilesListCellRenderer());
myFilesListModel = new DefaultListModel();
myFilesList.setModel(myFilesListModel);
myAddModuleButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
String description = ProjectBundle.message("choose.description.facet.auto.detection.will.be.disabled.in.the.selected.modules",
myFacetType.getPresentableName());
String title = ProjectBundle.message("choose.modules.dialog.title");
ChooseModulesDialog dialog = new ChooseModulesDialog(myProject, getEnabledModules(), title, description);
dialog.show();
List<Module> chosenElements = dialog.getChosenElements();
if (dialog.isOK() && !chosenElements.isEmpty()) {
for (Module module : chosenElements) {
String moduleName = module.getName();
myModulesListModel.addElement(moduleName);
if (!myRemovedModules.remove(moduleName)) {
myAddedModules.add(moduleName);
}
}
updateButtons();
myModulesList.repaint();
}
}
});
UIUtil.addKeyboardShortcut(myModulesList, myAddModuleButton, CommonShortcuts.getInsertKeystroke());
myRemoveModuleButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
//noinspection unchecked
List<String> removed = ListUtil.removeSelectedItems(myModulesList);
for (String moduleName : removed) {
if (!myAddedModules.remove(moduleName)) {
myRemovedModules.add(moduleName);
}
}
updateButtons();
}
});
KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
UIUtil.addKeyboardShortcut(myModulesList, myRemoveModuleButton, delete);
myRemoveFileButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
//noinspection unchecked
List<String> removed = ListUtil.removeSelectedItems(myFilesList);
myRemovedFiles.addAll(removed);
updateButtons();
}
});
UIUtil.addKeyboardShortcut(myFilesList, myRemoveFileButton, delete);
myEnableAutoDetectionCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
updateButtons();
}
});
ListSelectionListener selectionListener = new ListSelectionListener() {
public void valueChanged(final ListSelectionEvent e) {
updateRemoveButtons();
}
};
myFilesList.addListSelectionListener(selectionListener);
myModulesList.addListSelectionListener(selectionListener);
}
private List<Module> getEnabledModules() {
List<Module> modules = new ArrayList<Module>(Arrays.asList(getAllModules()));
Iterator<Module> iterator = modules.iterator();
Set<String> disabled = getDisabledModules();
while (iterator.hasNext()) {
Module module = iterator.next();
if (disabled.contains(module.getName())) {
iterator.remove();
}
}
return modules;
}
protected Module[] getAllModules() {
return myContext.getModules();
}
private Set<String> getDisabledModules() {
Set<String> disabled = new LinkedHashSet<String>();
for (int i = 0; i < myModulesListModel.getSize(); i++) {
disabled.add((String)myModulesListModel.getElementAt(i));
}
return disabled;
}
public String getDisplayName() {
return ProjectBundle.message("auto.detection.configurable.display.name");
}
public Icon getIcon() {
return null;
}
public String getHelpTopic() {
return "reference.settingsdialog.project.structure.facet";
}
public JComponent createComponent() {
return myMainPanel;
}
public boolean isModified() {
return myAutodetectionWasEnabled != myEnableAutoDetectionCheckBox.isSelected()
|| !myRemovedFiles.isEmpty() || !myAddedModules.isEmpty() || !myRemovedModules.isEmpty();
}
public void apply() throws ConfigurationException {
DisabledAutodetectionByTypeElement state = getAutodetectingManager().getDisabledAutodetectionState(myFacetType);
DisabledAutodetectionByTypeElement newState = modifyState(state);
getAutodetectingManager().setDisabledAutodetectionState(myFacetType, newState);
}
@Nullable
private DisabledAutodetectionByTypeElement modifyState(final DisabledAutodetectionByTypeElement state) {
if (!myEnableAutoDetectionCheckBox.isSelected()) {
return new DisabledAutodetectionByTypeElement(myFacetType.getStringId());
}
if (state == null) {
if (myAddedModules.isEmpty()) {
return null;
}
DisabledAutodetectionByTypeElement newState = new DisabledAutodetectionByTypeElement(myFacetType.getStringId());
for (String moduleName : myAddedModules) {
newState.getModuleElements().add(new DisabledAutodetectionInModuleElement(moduleName));
}
return newState;
}
DisabledAutodetectionByTypeElement newState = copyState(state);
boolean someModuleRemoved = false;
for (String url : myRemovedFiles) {
String moduleName = myFile2Module.get(url);
DisabledAutodetectionInModuleElement element = newState.findElement(moduleName);
if (element != null) {
boolean removed = element.getFiles().remove(url) | element.getDirectories().remove(url);
if (removed && element.isDisableInWholeModule()) {
newState.removeDisabled(moduleName);
someModuleRemoved = true;
}
}
}
for (String moduleName : myAddedModules) {
newState.getModuleElements().add(new DisabledAutodetectionInModuleElement(moduleName));
}
for (String moduleName : myRemovedModules) {
someModuleRemoved |= newState.findElement(moduleName) != null;
newState.removeDisabled(moduleName);
}
if ((someModuleRemoved || !myAutodetectionWasEnabled) && newState.getModuleElements().isEmpty()) {
return null;
}
return newState;
}
private DisabledAutodetectionByTypeElement copyState(final DisabledAutodetectionByTypeElement state) {
DisabledAutodetectionByTypeElement newState = new DisabledAutodetectionByTypeElement(myFacetType.getStringId());
for (DisabledAutodetectionInModuleElement moduleElement : state.getModuleElements()) {
DisabledAutodetectionInModuleElement newModuleElement = new DisabledAutodetectionInModuleElement(moduleElement.getModuleName());
newModuleElement.getFiles().addAll(moduleElement.getFiles());
newModuleElement.getDirectories().addAll(moduleElement.getDirectories());
newState.getModuleElements().add(newModuleElement);
}
return newState;
}
public void reset() {
DisabledAutodetectionByTypeElement autodetectionInfo = getAutodetectingManager().getDisabledAutodetectionState(myFacetType);
myModulesListModel.removeAllElements();
myFilesListModel.removeAllElements();
myFile2Module.clear();
myRemovedModules.clear();
myAddedModules.clear();
myRemovedFiles.clear();
myEnableAutoDetectionCheckBox.setSelected(true);
if (autodetectionInfo != null) {
List<DisabledAutodetectionInModuleElement> moduleElements = autodetectionInfo.getModuleElements();
if (moduleElements.isEmpty()) {
myEnableAutoDetectionCheckBox.setSelected(false);
}
else {
List<String> modules = new ArrayList<String>();
List<String> urls = new ArrayList<String>();
for (DisabledAutodetectionInModuleElement moduleElement : moduleElements) {
String moduleName = moduleElement.getModuleName();
if (moduleElement.isDisableInWholeModule()) {
modules.add(moduleName);
}
else {
for (String url : moduleElement.getFiles()) {
myFile2Module.put(url, moduleName);
urls.add(url);
}
for (String url : moduleElement.getDirectories()) {
myFile2Module.put(url, moduleName);
urls.add(url);
}
}
}
Collections.sort(urls);
Collections.sort(modules);
for (String url : urls) {
myFilesListModel.addElement(url);
}
for (String moduleName : modules) {
myModulesListModel.addElement(moduleName);
}
}
}
myAutodetectionWasEnabled = myEnableAutoDetectionCheckBox.isSelected();
mySkipFilesListPanel.setVisible(!myFilesListModel.isEmpty());
updateButtons();
}
@TestOnly
public Set<String> getRemovedModules() {
return myRemovedModules;
}
@TestOnly
public Set<String> getAddedModules() {
return myAddedModules;
}
@TestOnly
public Set<String> getRemovedFiles() {
return myRemovedFiles;
}
@TestOnly
public JCheckBox getEnableAutoDetectionCheckBox() {
return myEnableAutoDetectionCheckBox;
}
private void updateButtons() {
if (!myEnableAutoDetectionCheckBox.isSelected()) {
UIUtil.setEnabled(mySettingsPanel, false, true);
return;
}
UIUtil.setEnabled(mySettingsPanel, true, true);
myAddModuleButton.setEnabled(!getEnabledModules().isEmpty());
updateRemoveButtons();
}
private void updateRemoveButtons() {
myRemoveModuleButton.setEnabled(myEnableAutoDetectionCheckBox.isSelected() && myModulesList.getSelectedIndices().length > 0);
myRemoveFileButton.setEnabled(myEnableAutoDetectionCheckBox.isSelected() && myFilesList.getSelectedIndices().length > 0);
}
private FacetAutodetectingManagerImpl getAutodetectingManager() {
return (FacetAutodetectingManagerImpl)FacetAutodetectingManager.getInstance(myProject);
}
public void disposeUIResources() {
}
private static class FilesListCellRenderer extends ColoredListCellRenderer {
protected void customizeCellRenderer(final JList list,
final Object value,
final int index,
final boolean selected,
final boolean hasFocus) {
String url = (String)value;
String path = VfsUtil.urlToPath(url);
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null) {
append(path, SimpleTextAttributes.REGULAR_ATTRIBUTES);
setIcon(file.isDirectory() ? PlatformIcons.FOLDER_ICON : file.getIcon());
}
else {
append(path, SimpleTextAttributes.ERROR_ATTRIBUTES);
setIcon(null);
}
}
}
private class ModulesListCellRenderer extends ColoredListCellRenderer {
protected void customizeCellRenderer(final JList list,
final Object value,
final int index,
final boolean selected,
final boolean hasFocus) {
String moduleName = (String)value;
Module module = myContext.myModulesConfigurator.getModule(moduleName);
if (module != null) {
append(moduleName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
setIcon(module.getModuleType().getNodeIcon(false));
}
else {
append(moduleName, SimpleTextAttributes.ERROR_ATTRIBUTES);
setIcon(null);
}
}
}
}
@@ -19,8 +19,6 @@ import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.impl.autodetecting.FacetAutodetectingManager;
import com.intellij.facet.impl.autodetecting.FacetAutodetectingManagerImpl;
import com.intellij.facet.impl.invalid.InvalidFacetManager;
import com.intellij.facet.impl.invalid.InvalidFacetType;
import com.intellij.facet.impl.ui.facetType.FacetTypeEditor;
@@ -150,9 +148,6 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
for (FacetTypeEditor editor : myFacetTypeEditors.values()) {
editor.apply();
}
if (!myProject.isDefault()) {
((FacetAutodetectingManagerImpl)FacetAutodetectingManager.getInstance(myProject)).redetectFacets();
}
}
public boolean isModified() {
@@ -46,32 +46,13 @@ project.import.jbuilder.home=JBuilder &Home:
project.import.jbuilder.home.title=Set JBuilder Home Location
project.import.jbuilder.home.prompt=Choose directory with JBuilder installation
progress.text.loading.facet.detection.indices=Loading facet detection indices...
progress.text.detecting.facets=Detecting facets...
framework.detected.info.text={0} {1, choice, 1#framework is|2#frameworks are} detected in the project <a href="configure">Configure</a>
facet.autodetected.info.text=<html><body><font face="verdana"> \
<font size="3">{1}<br> \
<a href="create">Create {0} Facet</a><br> \
<a href="disable">Don''t detect {0} Facets in module</a>\
</font></font></body></html>
facet.autodetected.popup.default.text=<b>{0}</b><br> \
from module <b>{1}</b> appears to be a <b>{2} Facet</b> descriptor
notification.name.0.facets.detected={0} facets detected
notification.name.0.facet.detected={0} facet detected
facet.autodetection.several.facets.detected.text=<html><body><font face="verdana">{0} facets detected. <a href="more">More...</a></font></body></html>
progress.text.searching.frameworks=Searching for frameworks. Please wait.
message.text.stop.searching.for.frameworks={0} is currently searching for frameworks. Would you like to stop the search?
label.text.the.following.frameworks.are.detected=<html><body>Several frameworks are detected in the project. Please review the following items and exclude mistakenly detected.</body></html>
label.text.no.frameworks.detected=No frameworks detected.
dialog.title.facets.detected=New Facets Detected
label.text.the.following.facets.are.detected.on.the.fly=<html><body>Several facets are detected in the project. Please review the following facets and exclude mistakenly detected.</body></html>
detected.facet.type.node={0} Facets
button.text.accept.detected.facets=&Accept
button.text.postpone.detected.facets=&Postpone
sdk.java.name=JSDK
sdk.java.unknown.name=Unknown
sdk.java.corrupt.error=Probably SDK installed in ''{0}'' is corrupt
@@ -374,36 +355,11 @@ project.roots.external.annotations.description=Manage external annotations attac
add.external.annotations.path.title=Add path to external annotations
add.external.annotations.path.description=Select path in which external annotations for module sources is located
node.text.packaging.included.from.0=from {0}
node.text.packaging.compile.output=(compile output)
node.text.packed.0.compile.output=(''{0}'' compile output)
node.text.library.of.module=(library from ''{0}'' module)
button.text.packaging.tree.add=Add...
button.text.packaging.tree.edit=Edit...
message.text.packaging.selected.item.belongs.to.0.do.you.want.to.exlude.1.from.2=Selected item belongs to {0}.\nDo you want to exlude {1} from {2}?
message.text.packaging.do.you.want.to.exlude.0.from.1=Do you want to exlude {0} from {1}?
message.text.individial.files.cannot.be.removed.from.packaging.do.you.want.to.remove.the.whole.libraries=An individial files cannot be removed from packaging. \nDo you want to remove the whole {0} {1, choice, 1#library|2#libraries}?
dialog.title.packaging.remove.included=Remove
action.name.packaging.add.library=Add Library...
dialog.title.packaging.choose.library=Choose Library
action.name.packaging.add.module=Add Module...
dialog.title.packaging.choose.module=Choose Module
dialog.title.packaging.edit.properties=Edit Properties
label.text.packaging.method=&Packaging method:
label.text.output.relative.path=&Output relative path:
checkbox.text.show.content.of.included.facets=Show content of &included facets
checkbox.text.show.library.files=Show &library files
text.module.link.description.0.module=''{0}'' module
element.description.0.items={0} items
project.facets.display.name=Facets
facet.type.banner.text=''{0}'' Facets
auto.detection.configurable.display.name=Auto-detection
choose.description.facet.auto.detection.will.be.disabled.in.the.selected.modules=<html><body>{0} facet auto-detection will be disabled in the selected modules</body></html>
checkbox.text.enable.auto.detection=&Enable auto-detection
label.text.autodetection.skip.modules=Skip modules
label.text.autodetection.skip.files=Skip files
button.text.autodetection.remove.file=Rem&ove
facet.defaults.display.name=Defaults
multiple.facets.banner.0.1.facets={0} {1} facets
tab.name.all.facets=All Facets
@@ -17,10 +17,6 @@
</application-components>
<project-components>
<component>
<interface-class>com.intellij.facet.impl.autodetecting.FacetAutodetectingManager</interface-class>
<implementation-class>com.intellij.facet.impl.autodetecting.FacetAutodetectingManagerImpl</implementation-class>
</component>
<component>
<implementation-class>com.intellij.framework.detection.impl.FrameworkDetectionManager</implementation-class>
</component>