blob: 4ffac2cb8eb9c2f8c3e326355b127e0928ee13b3 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.platform;
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
import com.intellij.projectImport.ProjectAttachProcessor;
import com.intellij.projectImport.ProjectOpenProcessor;
import com.intellij.projectImport.ProjectOpenedCallback;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
/**
* @author max
*/
public class PlatformProjectOpenProcessor extends ProjectOpenProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.platform.PlatformProjectOpenProcessor");
public static PlatformProjectOpenProcessor getInstance() {
PlatformProjectOpenProcessor projectOpenProcessor = getInstanceIfItExists();
assert projectOpenProcessor != null;
return projectOpenProcessor;
}
@Nullable
public static PlatformProjectOpenProcessor getInstanceIfItExists() {
ProjectOpenProcessor[] processors = Extensions.getExtensions(EXTENSION_POINT_NAME);
for(ProjectOpenProcessor processor: processors) {
if (processor instanceof PlatformProjectOpenProcessor) {
return (PlatformProjectOpenProcessor) processor;
}
}
return null;
}
public boolean canOpenProject(final VirtualFile file) {
return file.isDirectory();
}
@Override
public boolean isProjectFile(VirtualFile file) {
return false;
}
@Override
public boolean lookForProjectsInDirectory() {
return false;
}
@Nullable
public Project doOpenProject(@NotNull final VirtualFile virtualFile, @Nullable final Project projectToClose, final boolean forceOpenInNewFrame) {
return doOpenProject(virtualFile, projectToClose, forceOpenInNewFrame, -1, null, false);
}
@Nullable
public static Project doOpenProject(@NotNull final VirtualFile virtualFile,
Project projectToClose,
final boolean forceOpenInNewFrame,
final int line,
@Nullable ProjectOpenedCallback callback,
final boolean isReopen) {
VirtualFile baseDir = virtualFile;
boolean dummyProject = false;
String dummyProjectName = null;
if (!baseDir.isDirectory()) {
baseDir = virtualFile.getParent();
while (baseDir != null) {
if (new File(FileUtil.toSystemDependentName(baseDir.getPath()), Project.DIRECTORY_STORE_FOLDER).exists()) {
break;
}
baseDir = baseDir.getParent();
}
if (baseDir == null) { // no reasonable directory -> create new temp one or use parent
if (Registry.is("ide.open.file.in.temp.project.dir")) {
try {
dummyProjectName = virtualFile.getName();
File directory = FileUtil.createTempDirectory(dummyProjectName, null, true);
baseDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(directory);
dummyProject = true;
} catch (IOException ex) {
LOG.error(ex);
}
}
if (baseDir == null) baseDir = virtualFile.getParent();
}
}
final File projectDir = new File(FileUtil.toSystemDependentName(baseDir.getPath()), Project.DIRECTORY_STORE_FOLDER);
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (!forceOpenInNewFrame && openProjects.length > 0) {
if (projectToClose == null) {
projectToClose = openProjects[openProjects.length - 1];
}
if (ProjectAttachProcessor.canAttachToProject()) {
final OpenOrAttachDialog dialog = new OpenOrAttachDialog(projectToClose, isReopen, isReopen ? "Reopen Project" : "Open Project");
dialog.show();
if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
return null;
}
if (dialog.isReplace()) {
if (!ProjectUtil.closeAndDispose(projectToClose)) return null;
}
else if (dialog.isAttach()) {
if (attachToProject(projectToClose, projectDir, callback)) return null;
}
}
else {
int exitCode = ProjectUtil.confirmOpenNewProject(false);
if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) {
if (!ProjectUtil.closeAndDispose(projectToClose)) return null;
}
else if (exitCode != GeneralSettings.OPEN_PROJECT_NEW_WINDOW) { // not in a new window
return null;
}
}
}
boolean runConfigurators = true;
final ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx();
Project project = null;
if (projectDir.exists()) {
try {
for (ProjectOpenProcessor processor : ProjectOpenProcessor.EXTENSION_POINT_NAME.getExtensions()) {
processor.refreshProjectFiles(projectDir);
}
project = projectManager.convertAndLoadProject(baseDir.getPath());
if (project == null) {
WelcomeFrame.showIfNoProjectOpened();
return null;
}
final Module[] modules = ModuleManager.getInstance(project).getModules();
if (modules.length > 0) {
runConfigurators = false;
}
}
catch (Exception e) {
// ignore
}
}
else {
projectDir.mkdirs();
}
if (project == null) {
String projectName = dummyProject ? dummyProjectName : projectDir.getParentFile().getName();
project = projectManager.newProject(projectName, projectDir.getParent(), true, dummyProject);
}
if (project == null) return null;
ProjectBaseDirectory.getInstance(project).setBaseDir(baseDir);
final Module module = runConfigurators ? runDirectoryProjectConfigurators(baseDir, project) : ModuleManager.getInstance(project).getModules()[0];
if (runConfigurators && dummyProject) { // add content root for chosen (single) file
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
ContentEntry[] entries = model.getContentEntries();
if (entries.length == 1) model.removeContentEntry(entries[0]); // remove custom content entry created for temp directory
model.addContentEntry(virtualFile);
model.commit();
}
});
}
openFileFromCommandLine(project, virtualFile, line);
if (!projectManager.openProject(project)) {
WelcomeFrame.showIfNoProjectOpened();
final Project finalProject = project;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Disposer.dispose(finalProject);
}
});
return project;
}
if (callback != null) {
callback.projectOpened(project, module);
}
return project;
}
public static Module runDirectoryProjectConfigurators(VirtualFile baseDir, Project project) {
final Ref<Module> moduleRef = new Ref<Module>();
for (DirectoryProjectConfigurator configurator: Extensions.getExtensions(DirectoryProjectConfigurator.EP_NAME)) {
try {
configurator.configureProject(project, baseDir, moduleRef);
}
catch (Exception e) {
LOG.error(e);
}
}
return moduleRef.get();
}
private static boolean attachToProject(Project project, File projectDir, ProjectOpenedCallback callback) {
final ProjectAttachProcessor[] extensions = Extensions.getExtensions(ProjectAttachProcessor.EP_NAME);
for (ProjectAttachProcessor processor : extensions) {
if (processor.attachToProject(project, projectDir, callback)) {
return true;
}
}
return false;
}
private static void openFileFromCommandLine(final Project project, final VirtualFile virtualFile, final int line) {
StartupManager.getInstance(project).registerPostStartupActivity(new DumbAwareRunnable() {
public void run() {
ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
public void run() {
ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
public void run() {
if (!virtualFile.isDirectory()) {
if (line > 0) {
new OpenFileDescriptor(project, virtualFile, line-1, 0).navigate(true);
}
else {
new OpenFileDescriptor(project, virtualFile).navigate(true);
}
}
}
});
}
});
}
});
}
@Nullable
public Icon getIcon() {
return null;
}
public String getName() {
return "text editor";
}
}