2988afab6d8097eae85f7106d86a7ecde000644b
[fedora-idea.git] / plugins / eclipse / src / org / jetbrains / idea / eclipse / importWizard / EclipseImportBuilder.java
blob2988afab6d8097eae85f7106d86a7ecde000644b
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.jetbrains.idea.eclipse.importWizard;
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.application.ex.ApplicationInfoEx;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.fileChooser.FileChooser;
22 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
23 import com.intellij.openapi.module.ModifiableModuleModel;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.module.ModuleManager;
26 import com.intellij.openapi.module.StdModuleTypes;
27 import com.intellij.openapi.progress.ProgressIndicator;
28 import com.intellij.openapi.progress.ProgressManager;
29 import com.intellij.openapi.progress.Task;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.project.impl.ProjectMacrosUtil;
32 import com.intellij.openapi.roots.ModifiableRootModel;
33 import com.intellij.openapi.roots.ModuleRootManager;
34 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
35 import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
36 import com.intellij.openapi.roots.libraries.Library;
37 import com.intellij.openapi.roots.libraries.LibraryTable;
38 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
39 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
40 import com.intellij.openapi.ui.DialogWrapper;
41 import com.intellij.openapi.ui.Messages;
42 import com.intellij.openapi.util.Comparing;
43 import com.intellij.openapi.util.IconLoader;
44 import com.intellij.openapi.util.JDOMUtil;
45 import com.intellij.openapi.util.Ref;
46 import com.intellij.openapi.util.io.FileUtil;
47 import com.intellij.openapi.util.text.StringUtil;
48 import com.intellij.openapi.vfs.LocalFileSystem;
49 import com.intellij.openapi.vfs.VirtualFile;
50 import com.intellij.packaging.artifacts.ModifiableArtifactModel;
51 import com.intellij.projectImport.ProjectImportBuilder;
52 import com.intellij.util.Function;
53 import org.jdom.Element;
54 import org.jdom.JDOMException;
55 import org.jetbrains.annotations.NotNull;
56 import org.jetbrains.annotations.Nullable;
57 import org.jetbrains.idea.eclipse.EclipseBundle;
58 import org.jetbrains.idea.eclipse.EclipseXml;
59 import org.jetbrains.idea.eclipse.IdeaXml;
60 import org.jetbrains.idea.eclipse.config.EclipseClasspathStorageProvider;
61 import org.jetbrains.idea.eclipse.conversion.EclipseClasspathReader;
62 import org.jetbrains.idea.eclipse.conversion.EclipseUserLibrariesHelper;
64 import javax.swing.*;
65 import java.io.File;
66 import java.io.IOException;
67 import java.util.*;
69 public class EclipseImportBuilder extends ProjectImportBuilder<String> implements EclipseProjectWizardContext {
70 private static final Icon eclipseIcon = IconLoader.getIcon("/images/eclipse.gif");
71 private static final Logger LOG = Logger.getInstance("#" + EclipseImportBuilder.class.getName());
73 public static class Parameters {
74 public String root;
75 public List<String> workspace;
76 public boolean linkConverted;
77 public List<String> projectsToConvert = new ArrayList<String>();
78 public boolean openModuleSettings;
79 public Options converterOptions = new Options();
80 public Set<String> existingModuleNames;
83 private Parameters parameters;
86 public String getName() {
87 return EclipseBundle.message("eclipse.name");
90 public Icon getIcon() {
91 return eclipseIcon;
94 @Nullable
95 public String getRootDirectory() {
96 return getParameters().root;
99 public boolean setRootDirectory(final String path) {
100 ProgressManager.getInstance().run(new Task.Modal(getCurrentProject(), EclipseBundle.message("eclipse.import.scanning"), true) {
101 public void run(@NotNull ProgressIndicator indicator) {
102 final ArrayList<String> roots = new ArrayList<String>();
103 EclipseProjectFinder.findModuleRoots(roots, path);
104 getParameters().workspace = roots;
105 getParameters().root = path;
108 public void onCancel() {
109 getParameters().workspace = null;
110 getParameters().root = null;
114 return getParameters().workspace != null;
117 public List<String> getList() {
118 return getParameters().workspace;
121 public boolean isMarked(final String element) {
122 if (getParameters().projectsToConvert != null) {
123 return getParameters().projectsToConvert.contains(element);
125 return !getParameters().existingModuleNames.contains(EclipseProjectFinder.findProjectName(element));
128 public void setList(List<String> list) {
129 getParameters().projectsToConvert = list;
132 public boolean isOpenProjectSettingsAfter() {
133 return getParameters().openModuleSettings;
136 public void setOpenProjectSettingsAfter(boolean on) {
137 getParameters().openModuleSettings = on;
140 public void cleanup() {
141 super.cleanup();
142 parameters = null;
145 public boolean validate(final Project currentProject, final Project dstProject) {
146 final Ref<Exception> refEx = new Ref<Exception>();
147 final HashSet<String> variables = new HashSet<String>();
148 ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
149 public void run() {
150 try {
151 for (String path : getParameters().projectsToConvert) {
152 final File classpathfile = new File(path, EclipseXml.DOT_CLASSPATH_EXT);
153 if (classpathfile.exists()) {
154 final Element classpathElement = JDOMUtil.loadDocument(classpathfile).getRootElement();
155 EclipseClasspathReader.collectVariables(variables, classpathElement);
159 catch (IOException e) {
160 refEx.set(e);
162 catch (JDOMException e) {
163 refEx.set(e);
166 }, EclipseBundle.message("eclipse.import.converting"), false, currentProject);
168 if (!refEx.isNull()) {
169 Messages.showErrorDialog(dstProject, refEx.get().getMessage(), getTitle());
170 return false;
173 if (!ProjectMacrosUtil.checkMacros(dstProject, variables)) {
174 return false;
177 return true;
180 @Override
181 public List<Module> commit(final Project project, ModifiableModuleModel model, ModulesProvider modulesProvider,
182 ModifiableArtifactModel artifactModel) {
184 final Collection<String> unknownLibraries = new TreeSet<String>();
185 final Collection<String> unknownJdks = new TreeSet<String>();
186 final Set<String> refsToModules = new HashSet<String>();
187 final List<Module> result = new ArrayList<Module>();
189 try {
190 final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();
191 final ModifiableRootModel[] rootModels = new ModifiableRootModel[getParameters().projectsToConvert.size()];
192 final Set<File> files = new HashSet<File>();
193 for (String path : getParameters().projectsToConvert) {
194 String modulesDirectory = getParameters().converterOptions.commonModulesDirectory;
195 if (modulesDirectory == null) {
196 modulesDirectory = path;
198 final String moduleName = EclipseProjectFinder.findProjectName(path);
199 final File imlFile = new File(modulesDirectory + File.separator + moduleName + IdeaXml.IML_EXT);
200 if (imlFile.isFile()) {
201 files.add(imlFile);
203 final File emlFile = new File(modulesDirectory + File.separator + moduleName + EclipseXml.IDEA_SETTINGS_POSTFIX);
204 if (emlFile.isFile()) {
205 files.add(emlFile);
208 if (!files.isEmpty()) {
209 final int resultCode = Messages.showYesNoCancelDialog(ApplicationInfoEx.getInstanceEx().getFullApplicationName() +
210 " module files found:\n" +
211 StringUtil.join(files,new Function<File, String>() {
212 public String fun(File file) {
213 return file.getPath();
215 }, "\n") +
216 ".\n Would you like to reuse them?", "Module files found",
217 Messages.getQuestionIcon());
218 if (resultCode != DialogWrapper.OK_EXIT_CODE) {
219 if (resultCode == DialogWrapper.CANCEL_EXIT_CODE) {
220 final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
221 for (File file : files) {
222 final VirtualFile virtualFile = localFileSystem.findFileByIoFile(file);
223 if (virtualFile != null) {
224 final IOException[] ex = new IOException[1];
225 ApplicationManager.getApplication().runWriteAction(new Runnable() {
226 public void run() {
227 try {
228 virtualFile.delete(this);
230 catch (IOException e) {
231 ex[0] = e;
235 if (ex[0] != null) {
236 throw ex[0];
239 else {
240 FileUtil.delete(file);
243 } else {
244 return result;
248 int idx = 0;
249 final Set<String> usedVariables = new HashSet<String>();
250 for (String path : getParameters().projectsToConvert) {
251 String modulesDirectory = getParameters().converterOptions.commonModulesDirectory;
252 if (modulesDirectory == null) {
253 modulesDirectory = path;
255 final Module module = moduleModel.newModule(modulesDirectory + "/" + EclipseProjectFinder.findProjectName(path) + IdeaXml.IML_EXT, StdModuleTypes.JAVA);
256 result.add(module);
257 final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
258 rootModels[idx++] = rootModel;
260 final File classpathFile = new File(path, EclipseXml.DOT_CLASSPATH_EXT);
261 final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert);
262 classpathReader.init(rootModel);
263 if (classpathFile.exists()) {
264 final Element classpathElement = JDOMUtil.loadDocument(classpathFile).getRootElement();
265 classpathReader.readClasspath(rootModel, unknownLibraries, unknownJdks, usedVariables, refsToModules,
266 getParameters().converterOptions.testPattern, classpathElement);
267 } else {
268 EclipseClasspathReader.setupOutput(rootModel, path + "/bin");
270 ClasspathStorage.setStorageType(rootModel,
271 getParameters().linkConverted ? EclipseClasspathStorageProvider.ID : ClasspathStorage.DEFAULT_STORAGE);
272 if (model != null) {
273 ApplicationManager.getApplication().runWriteAction(new Runnable() {
274 public void run() {
275 rootModel.commit();
280 if (model == null) {
281 ApplicationManager.getApplication().runWriteAction(new Runnable() {
282 public void run(){
283 ProjectRootManagerEx.getInstanceEx(project).multiCommit(moduleModel, rootModels);
289 catch (Exception e) {
290 LOG.error(e);
293 createEclipseLibrary(project, unknownLibraries, IdeaXml.ECLIPSE_LIBRARY);
295 StringBuffer message = new StringBuffer();
296 refsToModules.removeAll(getParameters().existingModuleNames);
297 for (String path : getParameters().projectsToConvert) {
298 final String projectName = EclipseClasspathReader.getLastPathComponent(FileUtil.toSystemIndependentName(path));
299 if (projectName != null) {
300 refsToModules.remove(projectName);
301 getParameters().existingModuleNames.add(projectName);
304 if (!refsToModules.isEmpty()) {
306 message.append("Unknown modules detected");
307 for (String module : refsToModules) {
308 message.append("\n").append(module);
311 if (!unknownJdks.isEmpty()) {
312 if (message.length() > 0){
313 message.append("\nand jdks");
314 } else {
315 message.append("Imported project refers to unknown jdks");
317 for (String unknownJdk : unknownJdks) {
318 message.append("\n").append(unknownJdk);
321 if (!unknownLibraries.isEmpty()) {
322 final StringBuffer buf = new StringBuffer();
323 buf.append("<html><body>");
324 buf.append(EclipseBundle.message("eclipse.import.warning.undefinded.libraries"));
325 for (String name : unknownLibraries) {
326 buf.append("<br>").append(name);
328 if (model == null) {
329 buf.append("<br><b>Please export Eclipse user libraries and import them now from resulted .userlibraries file</b>");
330 buf.append("</body></html>");
331 final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
332 @Override
333 public boolean isFileSelectable(VirtualFile file) {
334 return super.isFileSelectable(file) && Comparing.strEqual(file.getExtension(), "userlibraries");
337 descriptor.setDescription(buf.toString());
338 descriptor.setTitle(getTitle());
339 final VirtualFile[] selectedFiles = FileChooser.chooseFiles(project, descriptor, project.getBaseDir());
340 if (selectedFiles.length == 1) {
341 ApplicationManager.getApplication().runWriteAction(new Runnable() {
342 public void run() {
343 try {
344 EclipseUserLibrariesHelper.readProjectLibrariesContent(new File(selectedFiles[0].getPath()), project, unknownLibraries);
346 catch (Exception e) {
347 LOG.error(e);
355 if (message.length() > 0) {
356 Messages.showErrorDialog(project, message.toString(), getTitle());
359 return result;
362 private static void createEclipseLibrary(final Project project, final Collection<String> libraries, final String libraryName) {
363 if (libraries.contains(libraryName)) {
364 final FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false) {
365 public Icon getOpenIcon(final VirtualFile virtualFile) {
366 return looksLikeEclipse(virtualFile) ? eclipseIcon : super.getOpenIcon(virtualFile);
369 public Icon getClosedIcon(final VirtualFile virtualFile) {
370 return looksLikeEclipse(virtualFile) ? eclipseIcon : super.getClosedIcon(virtualFile);
373 private boolean looksLikeEclipse(final VirtualFile virtualFile) {
374 return virtualFile.findChild(".eclipseproduct") != null;
377 fileChooserDescriptor.setTitle(EclipseBundle.message("eclipse.create.library.title"));
378 fileChooserDescriptor.setDescription(EclipseBundle.message("eclipse.create.library.description", libraryName));
379 final VirtualFile[] files = FileChooser.chooseFiles(project, fileChooserDescriptor);
380 if (files.length == 1) {
381 final VirtualFile pluginsDir = files[0].findChild("plugins");
382 if (pluginsDir != null) {
383 ApplicationManager.getApplication().runWriteAction(new Runnable() {
384 public void run() {
385 final LibraryTable table =
386 LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(LibraryTablesRegistrar.APPLICATION_LEVEL, project);
387 assert table != null;
388 final LibraryTable.ModifiableModel tableModel = table.getModifiableModel();
389 final Library library = tableModel.createLibrary(libraryName);
390 final Library.ModifiableModel libraryModel = library.getModifiableModel();
391 libraryModel.addJarDirectory(pluginsDir, true);
392 libraryModel.commit();
393 tableModel.commit();
396 libraries.remove(libraryName);
402 public Parameters getParameters() {
403 if (parameters == null) {
404 parameters = new Parameters();
405 parameters.existingModuleNames = new HashSet<String>();
406 if (isUpdate()) {
407 for (Module module : ModuleManager.getInstance(getCurrentProject()).getModules()) {
408 parameters.existingModuleNames.add(module.getName());
412 return parameters;