Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2011-07-04 18:29:49 +04:00
32 changed files with 1339 additions and 396 deletions
@@ -328,11 +328,15 @@ public class SourcePathsStep extends AbstractStepWithProgress<List<Trinity<Strin
}
protected List<Trinity<String, String, Collection<String>>> calculate() {
String contentEntryPath = getContentRootPath();
if (contentEntryPath == null) {
return calculateSourceRoots(getContentRootPath());
}
@NotNull
public static List<Trinity<String, String, Collection<String>>> calculateSourceRoots(final String contentRootPath) {
if (contentRootPath == null) {
return EMPTY_STRING_STRING_ARRAY;
}
final File entryFile = new File(contentEntryPath);
final File entryFile = new File(contentRootPath);
if (!entryFile.exists()) {
return EMPTY_STRING_STRING_ARRAY;
}
@@ -40,6 +40,7 @@ import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
@@ -102,7 +103,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
myVariableData = inputVariables;
myHelpId = helpId;
mySignature = new MethodSignatureComponent("", project, JavaFileType.INSTANCE);
mySignature.setPreferredSize(new Dimension(-1, 130));
mySignature.setPreferredSize(new Dimension(450, 100));
setTitle(title);
// Create UI components
@@ -220,7 +221,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
protected JPanel createOptionsPanel() {
final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
optionsPanel.add(new JLabel("Options: "));
//optionsPanel.add(new JLabel("Options: "));
if (myStaticFlag || myCanBeStatic) {
myMakeStatic.setEnabled(!myStaticFlag);
@@ -235,6 +236,8 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
myMakeStatic.setSelected(false);
myMakeStatic.setEnabled(false);
}
final Border emptyBorder = IdeBorderFactory.createEmptyBorder(5, 0, 5, 4);
myMakeStatic.setBorder(emptyBorder);
myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault());
myFoldParameters.setVisible(myVariableData.isFoldable());
@@ -251,6 +254,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
}
});
optionsPanel.add(myFoldParameters);
myFoldParameters.setBorder(emptyBorder);
boolean canBeVarargs = false;
for (ParameterTablePanel.VariableData data : myInputVariables) {
@@ -262,6 +266,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
if (canBeVarargs) {
myMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox"));
myMakeVarargs.setBorder(emptyBorder);
updateVarargsEnabled();
myMakeVarargs.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
@@ -274,6 +279,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog {
if (myCbChainedConstructor != null) {
optionsPanel.add(myCbChainedConstructor);
myCbChainedConstructor.setBorder(emptyBorder);
myCbChainedConstructor.addItemListener(new ItemListener() {
public void itemStateChanged(final ItemEvent e) {
if (myDefaultVisibility) {
@@ -83,7 +83,7 @@ public class LightAdvHighlightingPerformanceTest extends LightDaemonAnalyzerTest
CodeInsightTestFixtureImpl.ensureIndexesUpToDate(getProject());
final List<HighlightInfo> infos = new ArrayList<HighlightInfo>();
PlatformTestUtil.startPerformanceTest(maxMillis, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest(getTestName(false), maxMillis, new ThrowableRunnable() {
@Override
public void run() throws Exception {
infos.clear();
@@ -19,7 +19,7 @@ public class RecursiveVisitorTest extends LightDaemonAnalyzerTestCase{
final PsiElement expression =
JavaPsiFacade.getInstance(getProject()).getElementFactory().createStatementFromText(text.toString(), null);
final int[] n = {0};
PlatformTestUtil.startPerformanceTest(20, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest(getTestName(false), 20, new ThrowableRunnable() {
@Override
public void run() throws Exception {
n[0] = 0;
@@ -46,7 +46,7 @@ public class RecursiveVisitorTest extends LightDaemonAnalyzerTestCase{
final PsiElement expression =
JavaPsiFacade.getInstance(getProject()).getElementFactory().createStatementFromText(text.toString(), null);
final int[] n = {0};
PlatformTestUtil.startPerformanceTest(100, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest(getTestName(false), 100, new ThrowableRunnable() {
@Override
public void run() throws Exception {
n[0] = 0;
@@ -385,7 +385,7 @@ public class VirtualFilePointerTest extends IdeaTestCase {
}
public void testContainerDeletePerformance() throws Exception {
PlatformTestUtil.startPerformanceTest(3000, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest("VF Pointer create/delete",3000, new ThrowableRunnable() {
@Override
public void run() throws Exception {
Disposable parent = Disposer.newDisposable();
@@ -151,7 +151,13 @@ public class PsiConcurrencyStressTest extends PsiTestCase {
super.visitElement(element);
final HighlightInfoHolder infoHolder = new HighlightInfoHolder(myFile, HighlightInfoFilter.EMPTY_ARRAY);
new HighlightVisitorImpl(getProject()).visit(element, infoHolder);
final HighlightVisitorImpl visitor = new HighlightVisitorImpl(getProject());
visitor.analyze(new Runnable() {
@Override
public void run() {
visitor.visit(element, infoHolder);
}
}, false, myFile);
}
});
break;
@@ -478,7 +478,7 @@ public abstract class PassExecutorService implements Disposable {
synchronized (PassExecutorService.class) {
StringBuilder s = new StringBuilder();
for (Object o : info) {
s.append(o.toString());
s.append(o.toString()).append(" ");
}
String message = StringUtil.repeatSymbol(' ', getThreadNum() * 4)
+ " " + pass + " "
@@ -92,15 +92,19 @@ public class HelpManagerImpl extends HelpManager {
for (IdeaPluginDescriptor pluginDescriptor : pluginDescriptors) {
HelpSetPath[] sets = pluginDescriptor.getHelpSets();
for (HelpSetPath hsPath : sets) {
URL hsURL =
new URL("jar:file:///" + pluginDescriptor.getPath().getAbsolutePath() + "/help/" + hsPath.getFile() + "!" + hsPath.getPath());
final String url = "jar:file:///" + pluginDescriptor.getPath().getAbsolutePath() + "/help/" + hsPath.getFile() +
"!" + hsPath.getPath();
try {
URL hsURL = new URL(url);
HelpSet pluginHelpSet = new HelpSet(null, hsURL);
helpSet.add(pluginHelpSet);
}
catch (HelpSetException e) {
LOG.error(e);
}
catch (Exception e) {
LOG.info("Error adding plugin help url " + url, e);
}
}
}
@@ -552,6 +552,13 @@ public class ArrayUtil {
return -1;
}
public static int indexOf(@NotNull Object[] objects, Object object, int start, int end) {
for (int i = start; i < end; i++) {
if (Comparing.equal(objects[i], object)) return i;
}
return -1;
}
public static <T> int indexOf(@NotNull List<T> objects, T object, @NotNull Equality<T> comparator) {
for (int i = 0; i < objects.size(); i++) {
if (comparator.equals(objects.get(i), object)) return i;
@@ -22,7 +22,10 @@ public class Queue<T> {
private Object[] myArray;
private int myFirst;
private int myLast;
private boolean isInverted;
// if true, elements are located at myFirst..myArray.length and 0..myLast
// otherwise, they are at myFirst..myLast
private boolean isWrapped;
public Queue(int initialCapacity) {
myArray = new Object[initialCapacity];
@@ -34,12 +37,12 @@ public class Queue<T> {
myArray = normalize(currentSize * 2);
myFirst = 0;
myLast = currentSize;
isInverted = false;
isWrapped = false;
}
myArray[myLast] = object;
myLast++;
if (myLast == myArray.length) {
isInverted = !isInverted;
isWrapped = !isWrapped;
myLast = 0;
}
}
@@ -49,20 +52,24 @@ public class Queue<T> {
}
public int size() {
return isInverted ? myArray.length - myFirst + myLast : myLast - myFirst;
return isWrapped ? myArray.length - myFirst + myLast : myLast - myFirst;
}
public List<T> toList() {
return Arrays.asList(normalize(size()));
}
public Object[] toArray() {
return normalize(size());
}
public T pullFirst() {
T result = (T)myArray[myFirst];
myArray[myFirst] = null;
myFirst++;
if (myFirst == myArray.length) {
myFirst = 0;
isInverted = !isInverted;
isWrapped = !isWrapped;
}
return result;
}
@@ -79,14 +86,13 @@ public class Queue<T> {
private T[] normalize(int capacity) {
T[] result = (T[])new Object[capacity];
int tailLength;
if (isInverted) {
tailLength = copyFromTo(myFirst, myArray.length, result, 0);
if (isWrapped) {
int tailLength = copyFromTo(myFirst, myArray.length, result, 0);
copyFromTo(0, myLast, result, tailLength);
}
else {
tailLength = 0;
copyFromTo(myFirst, myLast, result, 0);
}
copyFromTo(0, myLast, result, tailLength);
return result;
}
@@ -94,7 +100,7 @@ public class Queue<T> {
for (int i = 0; i < myArray.length; i++) {
myArray[i] = null;
}
isWrapped = false;
myFirst = myLast = 0;
}
}
+1
View File
@@ -44,6 +44,7 @@
</orderEntry>
<orderEntry type="module" module-name="maven" />
<orderEntry type="module" module-name="java-impl" />
<orderEntry type="module" module-name="properties" />
</component>
</module>
@@ -239,4 +239,11 @@ no.jdk.error=You need to create at least one JSDK of versions 1.5 or 1.6
cannot.parse.sdk.error=Cannot parse Android SDK
android.add.sdk.tooltip=Add SDK
android.console.tool.window.title=Android Console
ddms.corrupted.error=Debug info is not available. Please close other application using ADB: DDMS, Eclipse
ddms.corrupted.error=Debug info is not available. Please close other application using ADB: DDMS, Eclipse
android.import.dependencies.error.message.header=Importing finished with errors:
android.import.dependencies.add.module.dependency.task.title=Add dependency {0} --> {1}
android.import.dependencies.new.module.task.title=Create library module {0} in {1}
android.import.dependencies.import.module.task.title=Import library module {0} from {1}
android.import.dependencies.dialog.title=Import Android dependencies from property files
android.import.dependencies.source.roots.dialog.title=Import source roots
android.import.dependencies.source.roots.dialog.label=Choose source roots to add to your project
+1
View File
@@ -63,6 +63,7 @@
</actions>
<depends>JUnit</depends>
<depends>com.intellij.properties</depends>
<depends optional="true" config-file="maven-support.xml">org.jetbrains.idea.maven</depends>
<extensions defaultExtensionNs="com.intellij">
@@ -24,6 +24,7 @@ import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.avd.AvdManager;
import com.intellij.CommonBundle;
import com.intellij.ProjectTopics;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.process.ProcessHandler;
@@ -32,6 +33,9 @@ import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.lang.properties.psi.PropertiesElementFactory;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -39,16 +43,21 @@ import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
@@ -76,10 +85,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import static org.jetbrains.android.util.AndroidUtils.EMULATOR;
import static org.jetbrains.android.util.AndroidUtils.SYSTEM_RESOURCE_PACKAGE;
@@ -370,6 +376,141 @@ public class AndroidFacet extends Facet<AndroidFacetConfiguration> {
});
}
});
getModule().getMessageBus().connect(this).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
private String[] myDependencies;
public void beforeRootsChange(final ModuleRootEvent event) {
}
public void rootsChanged(final ModuleRootEvent event) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (!isDisposed()) {
PsiDocumentManager.getInstance(getModule().getProject()).commitAllDocuments();
final PropertiesFile propertiesFile = AndroidUtils.findPropertyFile(getModule(), SdkConstants.FN_DEFAULT_PROPERTIES);
if (propertiesFile == null) {
return;
}
updateTargetProperty(propertiesFile);
updateLibraryProperty(propertiesFile);
final String[] dependencies = collectDependencies();
if (myDependencies == null || !Comparing.equal(myDependencies, dependencies)) {
updateDependenciesInPropertyFile(propertiesFile, dependencies);
myDependencies = dependencies;
}
}
}
});
}
});
}
private void updateDependenciesInPropertyFile(@NotNull final PropertiesFile propertiesFile, @NotNull final String[] dependencies) {
final VirtualFile vFile = propertiesFile.getVirtualFile();
if (vFile == null) {
return;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (Property property : propertiesFile.getProperties()) {
final String name = property.getName();
if (name != null && name.startsWith(AndroidUtils.ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX)) {
property.delete();
}
}
final VirtualFile baseDir = vFile.getParent();
final String baseDirPath = baseDir.getPath();
final Project project = getModule().getProject();
int index = 1;
for (String dependency : dependencies) {
final String relPath = FileUtil.getRelativePath(baseDirPath, dependency, '/');
final String value = relPath != null ? relPath : dependency;
propertiesFile.addProperty(
PropertiesElementFactory.createProperty(project, AndroidUtils.ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX + index, value));
index++;
}
}
});
}
private String[] collectDependencies() {
final List<String> dependenciesList = new ArrayList<String>();
for (AndroidFacet depFacet : AndroidUtils.getAndroidDependencies(getModule(), true)) {
final Module depModule = depFacet.getModule();
final VirtualFile libDir = getBaseAndroidContentRoot(depModule);
if (libDir != null) {
dependenciesList.add(libDir.getPath());
}
}
final String[] dependencies = ArrayUtil.toStringArray(dependenciesList);
Arrays.sort(dependencies);
return dependencies;
}
@Nullable
private static VirtualFile getBaseAndroidContentRoot(@NotNull Module module) {
final VirtualFile manifestFile = AndroidRootUtil.getManifestFile(module);
final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
if (manifestFile != null) {
for (VirtualFile contentRoot : contentRoots) {
if (VfsUtil.isAncestor(contentRoot, manifestFile, true)) {
return contentRoot;
}
}
}
return contentRoots.length > 0 ? contentRoots[0] : null;
}
private void updateTargetProperty(@NotNull final PropertiesFile propertiesFile) {
final IAndroidTarget androidTarget = getConfiguration().getAndroidTarget();
if (androidTarget != null) {
final String targetPropertyValue = androidTarget.hashString();
final Property property = propertiesFile.findPropertyByKey(AndroidUtils.ANDROID_TARGET_PROPERTY);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
if (property == null) {
final Property newProperty = PropertiesElementFactory.createProperty(propertiesFile.getProject(),
AndroidUtils.ANDROID_TARGET_PROPERTY, targetPropertyValue);
propertiesFile.addProperty(newProperty);
}
else {
property.setValue(targetPropertyValue);
}
}
});
}
}
public void updateLibraryProperty(@NotNull final PropertiesFile propertiesFile) {
final Property property = propertiesFile.findPropertyByKey(AndroidUtils.ANDROID_LIBRARY_PROPERTY);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
if (property != null) {
property.setValue(Boolean.toString(getConfiguration().LIBRARY_PROJECT));
}
else if (getConfiguration().LIBRARY_PROJECT) {
final Property newProperty = PropertiesElementFactory.createProperty(propertiesFile.getProject(),
AndroidUtils.ANDROID_LIBRARY_PROPERTY,
Boolean.TRUE.toString());
propertiesFile.addProperty(newProperty);
}
}
});
}
@Override
@@ -16,29 +16,19 @@
package org.jetbrains.android.facet;
import com.android.sdklib.SdkConstants;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.facet.ui.FacetEditorContext;
import com.intellij.facet.ui.FacetEditorTab;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.GlobalLibrariesConfigurable;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.ComboboxWithBrowseButton;
@@ -63,7 +53,10 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author yole
@@ -106,7 +99,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
public AndroidFacetEditorTab(FacetEditorContext context, AndroidFacetConfiguration androidFacetConfiguration) {
final Project project = context.getProject();
LibraryTable.ModifiableModel model = GlobalLibrariesConfigurable.getInstance(project).getModelProvider().getModifiableModel();
myConfiguration = androidFacetConfiguration;
myContext = context;
@@ -251,16 +243,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
return ArrayUtil.toStringArray(result);
}
private boolean isUnderModuleDir(VirtualFile vFile) {
if (vFile == null) return false;
File file = new File(vFile.getPath());
String moduleDirPath = new File(myContext.getModule().getModuleFilePath()).getParent();
if (moduleDirPath != null) {
moduleDirPath = FileUtil.toSystemIndependentName(moduleDirPath);
}
return moduleDirPath != null && VfsUtil.isAncestor(new File(moduleDirPath), file, true);
}
@Nls
public String getDisplayName() {
return "Android SDK Settings";
@@ -353,29 +335,13 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
return !FileUtil.pathsEqual(pathFromConfig, pathFromTextField);
}
// if library was removed in the same project-structure dialog
@Nullable
private static LibraryOrderEntry findLibraryOrderEntryByName(@NotNull ModifiableRootModel model, @NotNull String name) {
for (OrderEntry entry : model.getOrderEntries()) {
if (entry instanceof LibraryOrderEntry) {
if (name.equals(((LibraryOrderEntry)entry).getLibraryName())) {
return (LibraryOrderEntry)entry;
}
}
}
return null;
}
@Nullable
private String toRelativePath(String absPath) {
absPath = FileUtil.toSystemIndependentName(absPath);
String moduleDirPath = AndroidRootUtil.getModuleDirPath(myContext.getModule());
if (moduleDirPath != null) {
moduleDirPath = FileUtil.toSystemIndependentName(moduleDirPath);
//if (VfsUtil.isAncestor(new File(moduleDirPath), new File(absPath), true)) {
return FileUtil.getRelativePath(moduleDirPath, absPath, '/');
//}
return FileUtil.getRelativePath(moduleDirPath, absPath, '/');
}
return null;
}
@@ -448,16 +414,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
}
myConfiguration.LIBS_FOLDER_RELATIVE_PATH = '/' + getAndCheckRelativePath(absLibsPath, false);
//myConfiguration.ADD_ANDROID_LIBRARY = myAddAndroidLibrary.isSelected();
if (myConfiguration.LIBRARY_PROJECT != myIsLibraryProjectCheckbox.isSelected()) {
// todo: after X release
/*if (myIsLibraryProjectCheckbox.isSelected()) {
excludeAllContentRootsFromCompilation(myContext.getModule());
}
else {
includeAllContentRootsToCompilation(myContext.getModule());
}*/
runApt = true;
}
@@ -529,44 +486,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
}
}
private static void excludeAllContentRootsFromCompilation(@NotNull Module module) {
Project project = module.getProject();
ExcludedEntriesConfiguration configuration =
((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration();
for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) {
configuration.addExcludeEntryDescription(new ExcludeEntryDescription(contentRoot, true, false, project));
}
}
private static void includeAllContentRootsToCompilation(@NotNull Module module) {
Project project = module.getProject();
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
Set<VirtualFile> contentRootSet = new HashSet<VirtualFile>(Arrays.asList(contentRoots));
ExcludedEntriesConfiguration configuration =
((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration();
ExcludeEntryDescription[] descriptions = configuration.getExcludeEntryDescriptions();
configuration.removeAllExcludeEntryDescriptions();
for (ExcludeEntryDescription description : descriptions) {
VirtualFile file = description.getVirtualFile();
if (file != null && !contentRootSet.contains(file)) {
configuration.addExcludeEntryDescription(description);
}
}
}
@NotNull
private String[] getNewResOverlayValue() throws ConfigurationException {
ListModel model = myResOverlayList.getModel();
String[] newResOverlayValue = new String[model.getSize()];
for (int i = 0; i < model.getSize(); i++) {
String element = (String)model.getElementAt(i);
newResOverlayValue[i] = '/' + getAndCheckRelativePath(element, false);
}
return newResOverlayValue;
}
private String getAndCheckRelativePath(String absPath, boolean checkExists) throws ConfigurationException {
if (absPath.indexOf('/') < 0 && absPath.indexOf(File.separatorChar) < 0) {
throw new ConfigurationException(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(absPath)));
@@ -583,8 +502,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
public void reset() {
resetOptions(myConfiguration);
//myAddAndroidLibrary.setSelected(myConfiguration.ADD_ANDROID_LIBRARY);
myIsLibraryProjectCheckbox.setSelected(myConfiguration.LIBRARY_PROJECT);
}
@@ -712,16 +629,8 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
}
}
}
VirtualFile[] files = FileChooser.chooseFiles(myContentPanel, new FileChooserDescriptor(false, true, false, false, false, false) /*{
@Override
public void validateSelectedFiles(VirtualFile[] files) throws Exception {
assert files.length == 1;
VirtualFile file = files[0];
if (!isUnderModuleDir(file)) {
throw new Exception(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(file.getPath())));
}
}
}*/, initialFile);
VirtualFile[] files =
FileChooser.chooseFiles(myContentPanel, new FileChooserDescriptor(false, true, false, false, false, false), initialFile);
if (files.length > 0) {
assert files.length == 1;
myTextField.setText(FileUtil.toSystemDependentName(files[0].getPath()));
@@ -778,15 +687,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
}
return file.isDirectory() || !chooseManifest || SdkConstants.FN_ANDROID_MANIFEST_XML.equals(file.getName());
}
/*@Override
public void validateSelectedFiles(VirtualFile[] files) throws Exception {
for (VirtualFile file : files) {
if (!isUnderModuleDir(file)) {
throw new Exception(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(file.getPath())));
}
}
}*/
}, initialFile);
}
}
@@ -15,50 +15,36 @@
*/
package org.jetbrains.android.facet;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.FacetDetectorRegistry;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.importDependencies.ImportDependenciesUtil;
import org.jetbrains.android.newProject.AndroidModuleType;
import org.jetbrains.android.sdk.*;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
/**
* @author yole
*/
public class AndroidFacetType extends FacetType<AndroidFacet, AndroidFacetConfiguration> {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.facet.AndroidFacetType");
public AndroidFacetType() {
super(AndroidFacet.ID, "android", "Android");
}
@@ -68,26 +54,6 @@ public class AndroidFacetType extends FacetType<AndroidFacet, AndroidFacetConfig
return new AndroidFacetConfiguration();
}
private static boolean tryToSetAndroidPlatform(Module module, Sdk sdk) {
AndroidPlatform platform = AndroidPlatform.parse(sdk);
if (platform != null) {
setSdk(module, sdk);
return true;
}
return false;
}
private static void setSdk(Module module, Sdk sdk) {
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
model.setSdk(sdk);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
model.commit();
}
});
}
public AndroidFacet createFacet(@NotNull Module module,
String name,
@NotNull AndroidFacetConfiguration configuration,
@@ -98,125 +64,6 @@ public class AndroidFacetType extends FacetType<AndroidFacet, AndroidFacetConfig
return new AndroidFacet(module, name, configuration);
}
private static void setupAndroidPlatformInNeccessary(Module module) {
Sdk currentSdk = ModuleRootManager.getInstance(module).getSdk();
if (currentSdk == null || !(currentSdk.getSdkType().equals(AndroidSdkType.getInstance()))) {
setupPlatform(module);
}
}
private static void setupPlatform(@NotNull Module module) {
if (tryToImportFromPropertyFiles(module)) {
return;
}
PropertiesComponent component = PropertiesComponent.getInstance();
if (component.isValueSet(AndroidSdkUtils.DEFAULT_PLATFORM_NAME_PROPERTY)) {
String defaultPlatformName = component.getValue(AndroidSdkUtils.DEFAULT_PLATFORM_NAME_PROPERTY);
Sdk defaultLib = ProjectJdkTable.getInstance().findJdk(defaultPlatformName, AndroidSdkType.getInstance().getName());
if (defaultLib != null && tryToSetAndroidPlatform(module, defaultLib)) {
return;
}
}
for (Sdk sdk : ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance())) {
if (tryToSetAndroidPlatform(module, sdk)) {
component.setValue(AndroidSdkUtils.DEFAULT_PLATFORM_NAME_PROPERTY, sdk.getName());
return;
}
}
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Nullable
private static String getPropertyValue(@NotNull Module module, @NotNull String propertyFileName, @NotNull String propertyKey) {
for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) {
final VirtualFile vFile = contentRoot.findChild(propertyFileName);
if (vFile != null) {
final Properties properties = new Properties();
try {
properties.load(new FileInputStream(new File(vFile.getPath())));
final String value = properties.getProperty(propertyKey);
if (value != null) {
return value;
}
}
catch (IOException e) {
LOG.info(e);
}
}
}
return null;
}
@Nullable
private static Sdk findSuitableAndroidSdk(@NotNull String targetHashString, @Nullable String sdkDir) {
final List<Sdk> androidSdks = ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance());
for (Sdk sdk : androidSdks) {
final AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData();
if (data != null) {
final AndroidPlatform androidPlatform = data.getAndroidPlatform();
if (androidPlatform != null) {
final String baseDir = FileUtil.toSystemIndependentName(androidPlatform.getSdk().getLocation());
if ((sdkDir == null || FileUtil.pathsEqual(baseDir, sdkDir)) &&
targetHashString.equals(androidPlatform.getTarget().hashString())) {
return sdk;
}
}
}
}
return null;
}
private static boolean tryToImportFromPropertyFiles(@NotNull Module module) {
final String targetHashString = getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, "target");
if (targetHashString == null) {
return false;
}
String sdkDir = getPropertyValue(module, SdkConstants.FN_LOCAL_PROPERTIES, "sdk.dir");
if (sdkDir != null) {
sdkDir = FileUtil.toSystemIndependentName(sdkDir);
}
final Sdk sdk = findSuitableAndroidSdk(targetHashString, sdkDir);
if (sdk != null) {
setSdk(module, sdk);
return true;
}
if (sdkDir != null && tryToCreateAndSetAndroidSdk(module, sdkDir, targetHashString)) {
return true;
}
final String androidHomeValue = System.getenv(AndroidSdkUtils.ANDROID_HOME_ENV);
if (androidHomeValue != null &&
tryToCreateAndSetAndroidSdk(module, FileUtil.toSystemIndependentName(androidHomeValue), targetHashString)) {
return true;
}
for (String dir : AndroidSdkUtils.getAndroidSdkPathsFromExistingPlatforms()) {
if (tryToCreateAndSetAndroidSdk(module, dir, targetHashString)) {
return true;
}
}
return false;
}
private static boolean tryToCreateAndSetAndroidSdk(@NotNull Module module, @NotNull String baseDir, @NotNull String targetHashString) {
final AndroidSdk sdkObject = AndroidSdk.parse(baseDir, new EmptySdkLog());
if (sdkObject != null) {
final IAndroidTarget target = sdkObject.findTargetByHashString(targetHashString);
if (target != null) {
final Sdk androidSdk = AndroidSdkUtils.createNewAndroidPlatform(target, sdkObject.getLocation(), true);
if (androidSdk != null) {
setSdk(module, androidSdk);
return true;
}
}
}
return false;
}
public boolean isSuitableModuleType(ModuleType moduleType) {
return moduleType instanceof JavaModuleType || moduleType instanceof AndroidModuleType;
}
@@ -233,15 +80,20 @@ public class AndroidFacetType extends FacetType<AndroidFacet, AndroidFacetConfig
@Override
public void afterFacetAdded(@NotNull final Facet facet) {
if (facet instanceof AndroidFacet) {
final Project project = facet.getModule().getProject();
final Module module = facet.getModule();
final Project project = module.getProject();
ImportDependenciesUtil.importDependencies(module, true);
StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
public void run() {
final Module module = facet.getModule();
setupAndroidPlatformInNeccessary(module);
AndroidSdkUtils.setupAndroidPlatformInNeccessary(module);
final AndroidFacet androidFacet = (AndroidFacet)facet;
final String androidLibraryPropValue = getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, "android.library");
final String androidLibraryPropValue = AndroidUtils
.getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, AndroidUtils.ANDROID_LIBRARY_PROPERTY);
if (androidLibraryPropValue != null && androidLibraryPropValue.equals("true")) {
androidFacet.getConfiguration().LIBRARY_PROJECT = true;
}
@@ -0,0 +1,72 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
class AddModuleDependencyTask extends ImportDependenciesTask {
private final ModuleProvider myModuleProvider;
private final ModuleProvider myDepModuleProvider;
public AddModuleDependencyTask(@NotNull ModuleProvider moduleProvider, @NotNull ModuleProvider depModuleProvider) {
myModuleProvider = moduleProvider;
myDepModuleProvider = depModuleProvider;
}
@Nullable
@Override
public Exception perform() {
final Module module = myModuleProvider.getModule();
final Module depModule = myDepModuleProvider.getModule();
if (module == null || depModule == null) {
return null;
}
final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
if (!rootManager.isDependsOn(depModule)) {
final ModifiableRootModel model = rootManager.getModifiableModel();
model.addModuleOrderEntry(depModule);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
model.commit();
}
});
}
return null;
}
@NotNull
@Override
public String getTitle() {
return AndroidBundle.message("android.import.dependencies.add.module.dependency.task.title", myModuleProvider.getModuleName(),
myDepModuleProvider.getModuleName());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AddModuleDependencyTask that = (AddModuleDependencyTask)o;
if (!myDepModuleProvider.equals(that.myDepModuleProvider)) return false;
if (!myModuleProvider.equals(that.myModuleProvider)) return false;
return true;
}
@Override
public int hashCode() {
int result = myModuleProvider.hashCode();
result = 31 * result + myDepModuleProvider.hashCode();
return result;
}
}
@@ -0,0 +1,88 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.android.newProject.AndroidModuleType;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
class CreateNewModuleTask extends ModuleProvidingTask {
private final Project myProject;
private final VirtualFile myContentRoot;
public CreateNewModuleTask(@NotNull Project project, @NotNull VirtualFile contentRoot) {
myContentRoot = contentRoot;
myProject = project;
}
@Override
public Exception perform() {
final Module depModule = ApplicationManager.getApplication().runWriteAction(new Computable<Module>() {
@Override
public Module compute() {
final Module depModule =
ModuleManager.getInstance(myProject)
.newModule(myContentRoot.getPath() + '/' + myContentRoot.getName() + ".iml", StdModuleTypes.JAVA);
final ModifiableRootModel model = ModuleRootManager.getInstance(depModule).getModifiableModel();
model.addContentEntry(myContentRoot);
model.commit();
return depModule;
}
});
AndroidUtils.addAndroidFacetIfNecessary(depModule, myContentRoot, true);
AndroidSdkUtils.setupAndroidPlatformInNeccessary(depModule);
setDepModule(depModule);
return null;
}
@NotNull
@Override
public String getTitle() {
final String contentRootPath = FileUtil.toSystemDependentName(myContentRoot.getPath());
return AndroidBundle.message("android.import.dependencies.new.module.task.title", getModuleName(), contentRootPath);
}
@Override
public String getModuleName() {
return myContentRoot.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CreateNewModuleTask that = (CreateNewModuleTask)o;
if (!myContentRoot.equals(that.myContentRoot)) return false;
if (!myProject.equals(that.myProject)) return false;
return true;
}
@Override
public int hashCode() {
int result = myProject.hashCode();
result = 31 * result + myContentRoot.hashCode();
return result;
}
@NotNull
public VirtualFile getContentRoot() {
return myContentRoot;
}
}
@@ -0,0 +1,62 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.containers.HashMap;
import org.jetbrains.android.util.AndroidBundle;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Eugene.Kudelevsky
*/
class ImportDependenciesDialog extends DialogWrapper {
private final CheckBoxList myCheckBoxList = new CheckBoxList();
private final List<ImportDependenciesTask> myTasks;
private final Map<ImportDependenciesTask, JCheckBox> myTask2Checkbox = new HashMap<ImportDependenciesTask, JCheckBox>();
protected ImportDependenciesDialog(Project project, List<ImportDependenciesTask> tasks) {
super(project, false);
setTitle(AndroidBundle.message("android.import.dependencies.dialog.title"));
myTasks = tasks;
final JCheckBox[] checkBoxes = new JCheckBox[tasks.size()];
for (int i = 0; i < checkBoxes.length; i++) {
final ImportDependenciesTask task = tasks.get(i);
final JCheckBox checkBox = new JCheckBox(task.getTitle());
checkBox.setSelected(true);
checkBoxes[i] = checkBox;
myTask2Checkbox.put(task, checkBox);
}
myCheckBoxList.setModel(new CollectionListModel(checkBoxes));
init();
}
@Override
protected JComponent createCenterPanel() {
final JBScrollPane pane = new JBScrollPane(myCheckBoxList);
pane.setPreferredSize(new Dimension(500, 200));
return pane;
}
public List<ImportDependenciesTask> getSelectedTasks() {
final List<ImportDependenciesTask> result = new ArrayList<ImportDependenciesTask>();
for (ImportDependenciesTask task : myTasks) {
if (myTask2Checkbox.get(task).isSelected()) {
result.add(task);
}
}
return result;
}
}
@@ -0,0 +1,16 @@
package org.jetbrains.android.importDependencies;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
abstract class ImportDependenciesTask {
@Nullable
public abstract Exception perform();
@NotNull
public abstract String getTitle();
}
@@ -0,0 +1,310 @@
package org.jetbrains.android.importDependencies;
import com.android.sdklib.SdkConstants;
import com.intellij.CommonBundle;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.ide.util.newProjectWizard.SourcePathsStep;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
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.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.*;
import com.intellij.util.containers.HashMap;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.*;
/**
* @author Eugene.Kudelevsky
*/
public class ImportDependenciesUtil {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.importDependencies.ImportDependenciesUtil");
private static final Key<Boolean> WAIT_FOR_IMPORTING_DEPENDENCIES_KEY = new Key<Boolean>("WAIT_FOR_IMPORTING_DEPENDENCIES_KEY");
private static final Object LOCK = new Object();
private ImportDependenciesUtil() {
}
public static void importDependencies(@NotNull Module module,
final boolean updateBackwardDependencies) {
synchronized (LOCK) {
final Project project = module.getProject();
module.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, Boolean.TRUE);
if (project.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) != Boolean.TRUE) {
project.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, Boolean.TRUE);
StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
importDependenciesForMarkedModules(project, updateBackwardDependencies);
}
});
}
});
}
}
}
private static void importDependenciesForMarkedModules(Project project, boolean updateBackwardDependencies) {
if (project.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) != Boolean.TRUE) {
return;
}
project.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, null);
final List<Module> modulesToProcess = new ArrayList<Module>();
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (module.getUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY) == Boolean.TRUE) {
module.putUserData(WAIT_FOR_IMPORTING_DEPENDENCIES_KEY, null);
modulesToProcess.add(module);
}
}
final List<ImportDependenciesTask> tasks = new OrderedSet<ImportDependenciesTask>();
final List<MyUnresolvedDependency> unresolvedDependencies = new ArrayList<MyUnresolvedDependency>();
for (Module module : modulesToProcess) {
importDependencies(module, updateBackwardDependencies, tasks, unresolvedDependencies);
}
final Map<VirtualFile, ModuleProvidingTask> libDir2ModuleProvidingTask = new HashMap<VirtualFile, ModuleProvidingTask>();
for (ImportDependenciesTask task : tasks) {
if (task instanceof ModuleProvidingTask) {
final ModuleProvidingTask moduleProvidingTask = (ModuleProvidingTask)task;
libDir2ModuleProvidingTask.put(moduleProvidingTask.getContentRoot(), moduleProvidingTask);
}
}
for (MyUnresolvedDependency unresolvedDependency : unresolvedDependencies) {
final ModuleProvidingTask taskProvidingDepModule = libDir2ModuleProvidingTask.get(unresolvedDependency.myLibDir);
if (taskProvidingDepModule != null) {
tasks.add(new AddModuleDependencyTask(unresolvedDependency.myModuleProvider,
ModuleProvider.create(taskProvidingDepModule)));
}
}
if (tasks.size() > 0) {
doImportDependencies(project, tasks);
}
}
private static void importDependencies(Module module,
boolean updateBackwardDependencies,
List<ImportDependenciesTask> tasks,
List<MyUnresolvedDependency> unresolvedDependencies) {
importDependencies(module, null, tasks, unresolvedDependencies);
if (updateBackwardDependencies) {
importBackwardDependencies(module, tasks, unresolvedDependencies);
}
}
private static void doImportDependencies(@NotNull Project project, @NotNull List<ImportDependenciesTask> tasks) {
final ImportDependenciesDialog dialog = new ImportDependenciesDialog(project, tasks);
dialog.show();
if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
return;
}
final List<ImportDependenciesTask> selectedTasks = dialog.getSelectedTasks();
final StringBuilder messageBuilder = new StringBuilder();
boolean failed = false;
final List<CreateNewModuleTask> createNewModuleTasks = new ArrayList<CreateNewModuleTask>();
for (ImportDependenciesTask selectedTask : selectedTasks) {
final Exception error = selectedTask.perform();
if (error != null) {
LOG.info(error);
if (messageBuilder.length() > 0) {
messageBuilder.append('\n');
}
messageBuilder.append(error.getMessage());
failed = true;
}
else if (selectedTask instanceof CreateNewModuleTask) {
createNewModuleTasks.add((CreateNewModuleTask)selectedTask);
}
}
if (createNewModuleTasks.size() > 0) {
final List<Trinity<String, String, Collection<String>>> sourceRoots = new ArrayList<Trinity<String, String, Collection<String>>>();
for (CreateNewModuleTask task : createNewModuleTasks) {
final String contentRootPath = task.getContentRoot().getPath();
sourceRoots.addAll(SourcePathsStep.calculateSourceRoots(contentRootPath));
}
if (sourceRoots.size() > 0) {
final ImportSourceRootsDialog sourceRootsDialog = new ImportSourceRootsDialog(project, sourceRoots);
sourceRootsDialog.show();
if (sourceRootsDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
addSourceRoots(project, sourceRootsDialog.getMarkedElements());
}
}
}
if (failed) {
Messages.showErrorDialog(project, AndroidBundle.message("android.import.dependencies.error.message.header") +
"\n" +
messageBuilder.toString(), CommonBundle.getErrorTitle());
}
}
private static void addSourceRoots(final Project project, final Collection<Trinity<String, String, Collection<String>>> sourceRoots) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (Trinity<String, String, Collection<String>> sourceRootTrinity : sourceRoots) {
final VirtualFile sourceRoot = LocalFileSystem.getInstance()
.refreshAndFindFileByPath(FileUtil.toSystemIndependentName(sourceRootTrinity.first));
if (sourceRoot == null) {
LOG.debug(new Exception("Cannot find source root " + sourceRootTrinity.first));
continue;
}
final Module module = ModuleUtil.findModuleForFile(sourceRoot, project);
if (module == null) {
LOG.debug(new Exception("Cannot find module for file " + sourceRoot.getPath()));
continue;
}
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
final ContentEntry[] entries = model.getContentEntries();
if (entries.length > 0) {
entries[0].addSourceFolder(sourceRoot, false, sourceRootTrinity.second);
}
else {
LOG.debug(new Exception("Module " + module.getName() + " has no content entries"));
}
model.commit();
}
}
});
}
@Nullable
private static VirtualFile findModuleFileChild(@NotNull VirtualFile dir) {
for (VirtualFile child : dir.getChildren()) {
if (child.getFileType() instanceof ModuleFileType) {
return child;
}
}
return null;
}
private static class MyUnresolvedDependency {
final ModuleProvider myModuleProvider;
final VirtualFile myLibDir;
private MyUnresolvedDependency(ModuleProvider moduleProvider, VirtualFile libDir) {
myModuleProvider = moduleProvider;
myLibDir = libDir;
}
}
private static void importDependencies(@NotNull Module module,
@Nullable Module allowedDepModule,
@NotNull List<ImportDependenciesTask> tasks,
@NotNull List<MyUnresolvedDependency> unresolvedDependencies) {
final Project project = module.getProject();
final ModuleProvider moduleProvider = ModuleProvider.create(module);
final Pair<Properties, VirtualFile> pair = AndroidUtils.readPropertyFile(module, SdkConstants.FN_DEFAULT_PROPERTIES);
if (pair != null) {
doImportDependencies(module, allowedDepModule, tasks, unresolvedDependencies, project, moduleProvider, pair);
}
}
private static void importDependenciesForNewModule(@NotNull Project project,
@NotNull ModuleProvider newModuleProvider,
@NotNull VirtualFile newModuleContentRoot,
@NotNull List<ImportDependenciesTask> tasks,
@NotNull List<MyUnresolvedDependency> unresolvedDependencies) {
final Pair<Properties, VirtualFile> properties =
AndroidUtils.readPropertyFile(newModuleContentRoot, SdkConstants.FN_DEFAULT_PROPERTIES);
if (properties != null) {
doImportDependencies(null, null, tasks, unresolvedDependencies, project, newModuleProvider, properties);
}
}
private static void doImportDependencies(@Nullable Module module,
@Nullable Module allowedDepModule,
@NotNull List<ImportDependenciesTask> tasks,
@NotNull List<MyUnresolvedDependency> unresolvedDependencies,
@NotNull Project project,
@NotNull ModuleProvider moduleProvider,
@NotNull Pair<Properties, VirtualFile> defaultProperties) {
final VirtualFile baseDir = defaultProperties.second.getParent();
String libDirPath;
int i = 1;
do {
libDirPath = defaultProperties.first.getProperty(AndroidUtils.ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX + i);
if (libDirPath != null) {
final VirtualFile libDir = AndroidUtils.findFileByAbsoluteOrRelativePath(baseDir, FileUtil.toSystemIndependentName(libDirPath));
if (libDir != null) {
final Module depModule = ModuleUtil.findModuleForFile(libDir, project);
if (depModule != null) {
if ((allowedDepModule == null || allowedDepModule == depModule) &&
ArrayUtil.find(ModuleRootManager.getInstance(depModule).getContentRoots(), libDir) >= 0 &&
!(module != null && ModuleRootManager.getInstance(module).isDependsOn(depModule))) {
tasks.add(new AddModuleDependencyTask(moduleProvider, ModuleProvider.create(depModule)));
}
}
else {
final VirtualFile libModuleFile = findModuleFileChild(libDir);
final ModuleProvidingTask task = libModuleFile != null && new File(libModuleFile.getPath()).exists()
? new ImportModuleTask(project, libModuleFile.getPath(), libDir)
: new CreateNewModuleTask(project, libDir);
if (!tasks.contains(task)) {
tasks.add(task);
final ModuleProvider newModuleProvider = ModuleProvider.create(task);
tasks.add(new AddModuleDependencyTask(moduleProvider, newModuleProvider));
importDependenciesForNewModule(project, newModuleProvider, libDir, tasks, unresolvedDependencies);
}
else {
unresolvedDependencies.add(new MyUnresolvedDependency(moduleProvider, libDir));
}
}
}
}
i++;
}
while (libDirPath != null);
}
private static void importBackwardDependencies(@NotNull Module module, @NotNull List<ImportDependenciesTask> tasks,
@NotNull List<MyUnresolvedDependency> unresolvedDependencies) {
for (Module module1 : ModuleManager.getInstance(module.getProject()).getModules()) {
if (module1 != module) {
importDependencies(module1, module, tasks, unresolvedDependencies);
}
}
}
}
@@ -0,0 +1,112 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleWithNameAlreadyExists;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.JDOMException;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
/**
* @author Eugene.Kudelevsky
*/
class ImportModuleTask extends ModuleProvidingTask {
private final Project myProject;
private final String myModuleFilePath;
private final VirtualFile myContentRoot;
public ImportModuleTask(@NotNull Project project,
@NotNull String moduleFilePath,
@NotNull VirtualFile contentRoot) {
myModuleFilePath = moduleFilePath;
myContentRoot = contentRoot;
myProject = project;
}
@Override
public Exception perform() {
final Module[] moduleWrapper = {null};
final Exception exception = ApplicationManager.getApplication().runWriteAction(new Computable<Exception>() {
@Override
public Exception compute() {
try {
moduleWrapper[0] = ModuleManager.getInstance(myProject).loadModule(myModuleFilePath);
}
catch (InvalidDataException e) {
return e;
}
catch (IOException e) {
return e;
}
catch (JDOMException e) {
return e;
}
catch (ModuleWithNameAlreadyExists e) {
return e;
}
return null;
}
});
if (exception != null) {
return exception;
}
assert moduleWrapper[0] != null;
AndroidUtils.addAndroidFacetIfNecessary(moduleWrapper[0], myContentRoot, true);
AndroidSdkUtils.setupAndroidPlatformInNeccessary(moduleWrapper[0]);
setDepModule(moduleWrapper[0]);
return null;
}
@NotNull
@Override
public String getTitle() {
return AndroidBundle
.message("android.import.dependencies.import.module.task.title", getModuleName(), FileUtil.toSystemDependentName(myModuleFilePath));
}
@Override
public String getModuleName() {
return FileUtil.getNameWithoutExtension(new File(myModuleFilePath).getName());
}
@NotNull
@Override
public VirtualFile getContentRoot() {
return myContentRoot;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ImportModuleTask that = (ImportModuleTask)o;
if (!myContentRoot.equals(that.myContentRoot)) return false;
if (!myModuleFilePath.equals(that.myModuleFilePath)) return false;
if (!myProject.equals(that.myProject)) return false;
return true;
}
@Override
public int hashCode() {
int result = myProject.hashCode();
result = 31 * result + myModuleFilePath.hashCode();
result = 31 * result + myContentRoot.hashCode();
return result;
}
}
@@ -0,0 +1,51 @@
package org.jetbrains.android.importDependencies;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Trinity;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
class ImportSourceRootsDialog extends DialogWrapper {
private final ElementsChooser<Trinity<String, String, Collection<String>>> mySourcePathsChooser;
public ImportSourceRootsDialog(@NotNull Project project, @NotNull List<Trinity<String, String, Collection<String>>> sourceRoots) {
super(project, false);
setTitle(AndroidBundle.message("android.import.dependencies.source.roots.dialog.title"));
mySourcePathsChooser = new ElementsChooser<Trinity<String, String, Collection<String>>>(true) {
public String getItemText(@NotNull Trinity<String, String, Collection<String>> sourceRootTrinity) {
return sourceRootTrinity.second.length() > 0
? sourceRootTrinity.first + " (" + sourceRootTrinity.second + ")"
: sourceRootTrinity.first;
}
};
mySourcePathsChooser.setElements(sourceRoots, true);
init();
}
@Override
protected JComponent createCenterPanel() {
final JPanel panel = new JPanel(new VerticalFlowLayout());
panel.setPreferredSize(new Dimension(350, 200));
panel.add(new JLabel(AndroidBundle.message("android.import.dependencies.source.roots.dialog.label")));
panel.add(mySourcePathsChooser);
return panel;
}
public List<Trinity<String, String, Collection<String>>> getMarkedElements() {
return mySourcePathsChooser.getMarkedElements();
}
}
@@ -0,0 +1,100 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
abstract class ModuleProvider {
private ModuleProvider() {
}
@Nullable
public abstract Module getModule();
@NotNull
public abstract String getModuleName();
public static ModuleProvider create(@NotNull final ModuleProvidingTask task) {
return new MyNewModuleProvider(task);
}
public static ModuleProvider create(@NotNull final Module module) {
return new MyExistingModuleProvider(module);
}
private static class MyNewModuleProvider extends ModuleProvider {
private final ModuleProvidingTask myTask;
public MyNewModuleProvider(@NotNull ModuleProvidingTask task) {
myTask = task;
}
@Override
public Module getModule() {
return myTask.getDepModule();
}
@NotNull
@Override
public String getModuleName() {
return myTask.getModuleName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyNewModuleProvider that = (MyNewModuleProvider)o;
if (!myTask.equals(that.myTask)) return false;
return true;
}
@Override
public int hashCode() {
return myTask.hashCode();
}
}
private static class MyExistingModuleProvider extends ModuleProvider {
private final Module myModule;
public MyExistingModuleProvider(Module module) {
myModule = module;
}
@Override
public Module getModule() {
return myModule;
}
@NotNull
@Override
public String getModuleName() {
return myModule.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyExistingModuleProvider that = (MyExistingModuleProvider)o;
if (!myModule.equals(that.myModule)) return false;
return true;
}
@Override
public int hashCode() {
return myModule.hashCode();
}
}
}
@@ -0,0 +1,25 @@
package org.jetbrains.android.importDependencies;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
abstract class ModuleProvidingTask extends ImportDependenciesTask {
private Module myDepModule;
public Module getDepModule() {
return myDepModule;
}
protected void setDepModule(Module depModule) {
myDepModule = depModule;
}
public abstract String getModuleName();
@NotNull
public abstract VirtualFile getContentRoot();
}
@@ -124,7 +124,7 @@ public class AndroidLogcatUtil {
return super.ready();
}
catch (IOException e) {
LOG.info(e);
LOG.debug(e);
return false;
}
}
@@ -23,8 +23,6 @@ import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
import com.intellij.openapi.application.ApplicationManager;
@@ -54,8 +52,8 @@ import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.dom.resources.ResourceElement;
import org.jetbrains.android.dom.resources.ResourceValue;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidFacetConfiguration;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.importDependencies.ImportDependenciesUtil;
import org.jetbrains.android.resourceManagers.LocalResourceManager;
import org.jetbrains.android.run.testing.AndroidTestRunConfiguration;
import org.jetbrains.android.run.testing.AndroidTestRunConfigurationType;
@@ -75,11 +73,7 @@ import static com.android.sdklib.SdkConstants.FN_DEFAULT_PROPERTIES;
import static org.jetbrains.android.util.AndroidUtils.createChildDirectoryIfNotExist;
/**
* Created by IntelliJ IDEA.
* User: Eugene.Kudelevsky
* Date: Jun 26, 2009
* Time: 7:32:27 PM
* To change this template use File | Settings | File Templates.
* @author Eugene.Kudelevsky
*/
public class AndroidModuleBuilder extends JavaModuleBuilder {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.newProject.AndroidModuleBuilder");
@@ -99,9 +93,10 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
VirtualFile[] files = rootModel.getContentRoots();
if (files.length > 0) {
final VirtualFile contentRoot = files[0];
final AndroidFacet facet = addAndroidFacet(rootModel, contentRoot);
final AndroidFacet facet = AndroidUtils.addAndroidFacet(rootModel, contentRoot, myProjectType == ProjectType.LIBRARY);
if (myProjectType == null) {
ImportDependenciesUtil.importDependencies(rootModel.getModule(), true);
return;
}
@@ -135,12 +130,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
createDirectoryStructure(contentRoot, sourceRoot, facet);
}
else {
// todo: after X release
/*if (myProjectType == ProjectType.LIBRARY) {
ExcludedEntriesConfiguration configuration =
((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration();
configuration.addExcludeEntryDescription(new ExcludeEntryDescription(contentRoot, true, false, project));
}*/
createProjectByAndroidTool(contentRoot, sourceRoot, facet);
}
}
@@ -346,7 +335,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
}
Properties properties = FileTemplateManager.getInstance().getDefaultProperties();
properties.setProperty("TARGET", "android-" + platform.getTarget().getVersion().getApiString());
properties.setProperty("TARGET", platform.getTarget().hashString());
AndroidFileTemplateProvider.createFromTemplate(project, contentRoot, "default.properties", FN_DEFAULT_PROPERTIES, properties);
}
catch (Exception e) {
@@ -446,26 +435,6 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
}
}
@NotNull
private AndroidFacet addAndroidFacet(ModifiableRootModel rootModel, VirtualFile contentRoot) {
Module module = rootModel.getModule();
final FacetManager facetManager = FacetManager.getInstance(module);
ModifiableFacetModel model = facetManager.createModifiableModel();
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
AndroidFacetConfiguration configuration = facet.getConfiguration();
configuration.init(module, contentRoot);
if (myProjectType == ProjectType.LIBRARY) {
configuration.LIBRARY_PROJECT = true;
}
model.addFacet(facet);
/*if (configuration.ADD_ANDROID_LIBRARY) {
LibraryOrderEntry libraryEntry = rootModel.addLibraryEntry(myPlatform.getLibrary());
libraryEntry.setScope(DependencyScope.PROVIDED);
}*/
model.commit();
return facet;
}
private void createResourcesAndLibs(final Project project, final VirtualFile rootDir) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
@@ -47,7 +47,7 @@ import static com.intellij.openapi.util.text.StringUtil.capitalize;
* Time: 6:02:59 PM
* To change this template use File | Settings | File Templates.
*/
public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.IDeviceChangeListener {
public class DeviceChooser extends DialogWrapper {
public static final IDevice[] EMPTY_DEVICE_ARRAY = new IDevice[0];
private final AndroidFacet myFacet;
@@ -95,16 +95,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I
if (selectedSerials != null) {
resetSelection(selectedSerials);
}
/*try {
AdbManager.run(new Runnable() {
public void run() {
AndroidDebugBridge.addDeviceChangeListener(DeviceChooser.this);
}
}, false);
}
catch (AdbNotRespondingException e) {
Messages.showErrorDialog(facet.getModule().getProject(), e.getMessage(), CommonBundle.getErrorTitle());
}*/
}
private void resetSelection(@NotNull String[] selectedSerials) {
@@ -160,12 +150,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I
return state != null ? capitalize(state.name().toLowerCase()) : "";
}
@Override
protected void dispose() {
super.dispose();
AndroidDebugBridge.removeDeviceChangeListener(this);
}
@Override
protected void doOKAction() {
mySelectedRows = myDeviceTable.getSelectedRows();
@@ -233,32 +217,6 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I
}
}
public void deviceConnected(IDevice device) {
/*ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
updateTable();
}
});*/
}
public void deviceDisconnected(IDevice device) {
/*ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
updateTable();
}
});*/
}
public void deviceChanged(IDevice device, int changeMask) {
/*if ((changeMask & (IDevice.CHANGE_STATE | IDevice.CHANGE_BUILD_INFO)) != 0) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
updateTable();
}
});
}*/
}
private class MyDeviceTableModel extends AbstractTableModel {
private final IDevice[] myDevices;
@@ -19,18 +19,23 @@ package org.jetbrains.android.sdk;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.OrderRoot;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -81,15 +86,6 @@ public class AndroidSdkUtils {
return platformDir;
}
public static VirtualFile[] chooseAndroidSdkPath(@NotNull Component parent) {
return FileChooser.chooseFiles(parent, new FileChooserDescriptor(false, true, false, false, false, false) {
@Override
public boolean isFileSelectable(VirtualFile file) {
return super.isFileSelectable(file) && isAndroidSdk(file.getPath()) || isAndroidPlatform(file);
}
});
}
public static List<OrderRoot> getLibraryRootsForTarget(@NotNull IAndroidTarget target, @Nullable String sdkPath) {
List<OrderRoot> result = new ArrayList<OrderRoot>();
VirtualFile platformDir = getPlatformDir(target);
@@ -259,4 +255,121 @@ public class AndroidSdkUtils {
return result;
}
private static boolean tryToSetAndroidPlatform(Module module, Sdk sdk) {
AndroidPlatform platform = AndroidPlatform.parse(sdk);
if (platform != null) {
setSdk(module, sdk);
return true;
}
return false;
}
private static void setSdk(Module module, Sdk sdk) {
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
model.setSdk(sdk);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
model.commit();
}
});
}
private static void setupPlatform(@NotNull Module module) {
if (tryToImportFromPropertyFiles(module)) {
return;
}
PropertiesComponent component = PropertiesComponent.getInstance();
if (component.isValueSet(DEFAULT_PLATFORM_NAME_PROPERTY)) {
String defaultPlatformName = component.getValue(DEFAULT_PLATFORM_NAME_PROPERTY);
Sdk defaultLib = ProjectJdkTable.getInstance().findJdk(defaultPlatformName, AndroidSdkType.getInstance().getName());
if (defaultLib != null && tryToSetAndroidPlatform(module, defaultLib)) {
return;
}
}
for (Sdk sdk : ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance())) {
if (tryToSetAndroidPlatform(module, sdk)) {
component.setValue(DEFAULT_PLATFORM_NAME_PROPERTY, sdk.getName());
return;
}
}
}
@Nullable
private static Sdk findSuitableAndroidSdk(@NotNull String targetHashString, @Nullable String sdkDir) {
final List<Sdk> androidSdks = ProjectJdkTable.getInstance().getSdksOfType(AndroidSdkType.getInstance());
for (Sdk sdk : androidSdks) {
final AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData();
if (data != null) {
final AndroidPlatform androidPlatform = data.getAndroidPlatform();
if (androidPlatform != null) {
final String baseDir = FileUtil.toSystemIndependentName(androidPlatform.getSdk().getLocation());
if ((sdkDir == null || FileUtil.pathsEqual(baseDir, sdkDir)) &&
targetHashString.equals(androidPlatform.getTarget().hashString())) {
return sdk;
}
}
}
}
return null;
}
private static boolean tryToImportFromPropertyFiles(@NotNull Module module) {
final String targetHashString = AndroidUtils.getPropertyValue(module, SdkConstants.FN_DEFAULT_PROPERTIES, "target");
if (targetHashString == null) {
return false;
}
String sdkDir = AndroidUtils.getPropertyValue(module, SdkConstants.FN_LOCAL_PROPERTIES, "sdk.dir");
if (sdkDir != null) {
sdkDir = FileUtil.toSystemIndependentName(sdkDir);
}
final Sdk sdk = findSuitableAndroidSdk(targetHashString, sdkDir);
if (sdk != null) {
setSdk(module, sdk);
return true;
}
if (sdkDir != null && tryToCreateAndSetAndroidSdk(module, sdkDir, targetHashString)) {
return true;
}
final String androidHomeValue = System.getenv(ANDROID_HOME_ENV);
if (androidHomeValue != null &&
tryToCreateAndSetAndroidSdk(module, FileUtil.toSystemIndependentName(androidHomeValue), targetHashString)) {
return true;
}
for (String dir : getAndroidSdkPathsFromExistingPlatforms()) {
if (tryToCreateAndSetAndroidSdk(module, dir, targetHashString)) {
return true;
}
}
return false;
}
private static boolean tryToCreateAndSetAndroidSdk(@NotNull Module module, @NotNull String baseDir, @NotNull String targetHashString) {
final AndroidSdk sdkObject = AndroidSdk.parse(baseDir, new EmptySdkLog());
if (sdkObject != null) {
final IAndroidTarget target = sdkObject.findTargetByHashString(targetHashString);
if (target != null) {
final Sdk androidSdk = createNewAndroidPlatform(target, sdkObject.getLocation(), true);
if (androidSdk != null) {
setSdk(module, androidSdk);
return true;
}
}
}
return false;
}
public static void setupAndroidPlatformInNeccessary(Module module) {
Sdk currentSdk = ModuleRootManager.getInstance(module).getSdk();
if (currentSdk == null || !(currentSdk.getSdkType().equals(AndroidSdkType.getInstance()))) {
setupPlatform(module);
}
}
}
@@ -30,8 +30,11 @@ import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.process.*;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.facet.ProjectFacetManager;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -40,19 +43,14 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
@@ -79,6 +77,7 @@ import org.jetbrains.android.dom.manifest.Application;
import org.jetbrains.android.dom.manifest.IntentFilter;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidFacetConfiguration;
import org.jetbrains.android.run.AndroidRunConfiguration;
import org.jetbrains.android.run.AndroidRunConfigurationType;
import org.jetbrains.android.sdk.AndroidSdk;
@@ -91,6 +90,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;
@@ -135,6 +136,10 @@ public class AndroidUtils {
private static final Key<ConsoleView> CONSOLE_VIEW_KEY = new Key<ConsoleView>("AndroidConsoleView");
@NonNls public static final String ANDROID_LIBRARY_PROPERTY = "android.library";
@NonNls public static final String ANDROID_TARGET_PROPERTY = "target";
@NonNls public static final String ANDROID_LIBRARY_REFERENCE_PROPERTY_PREFIX = "android.library.reference.";
private AndroidUtils() {
}
@@ -712,4 +717,114 @@ public class AndroidUtils {
}
return false;
}
public static void addAndroidFacetIfNecessary(@NotNull final Module module,
@NotNull final VirtualFile contentRoot,
final boolean library) {
if (AndroidFacet.getInstance(module) == null) {
addAndroidFacet(module, contentRoot, library);
}
}
@NotNull
public static AndroidFacet addAndroidFacet(@NotNull final Module module, @NotNull final VirtualFile contentRoot, final boolean library) {
return ApplicationManager.getApplication().runWriteAction(new Computable<AndroidFacet>() {
@Override
public AndroidFacet compute() {
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
final AndroidFacet facet = addAndroidFacet(model, contentRoot, library);
model.commit();
return facet;
}
});
}
@NotNull
public static AndroidFacet addAndroidFacet(ModifiableRootModel rootModel, VirtualFile contentRoot, boolean library) {
Module module = rootModel.getModule();
final FacetManager facetManager = FacetManager.getInstance(module);
ModifiableFacetModel model = facetManager.createModifiableModel();
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
AndroidFacetConfiguration configuration = facet.getConfiguration();
configuration.init(module, contentRoot);
if (library) {
configuration.LIBRARY_PROJECT = true;
}
model.addFacet(facet);
model.commit();
return facet;
}
@Nullable
public static PropertiesFile findPropertyFile(@NotNull final Module module, @NotNull String propertyFileName) {
for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) {
final VirtualFile vFile = contentRoot.findChild(propertyFileName);
if (vFile != null) {
final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
@Override
public PsiFile compute() {
return PsiManager.getInstance(module.getProject()).findFile(vFile);
}
});
if (psiFile instanceof PropertiesFile) {
return (PropertiesFile)psiFile;
}
}
}
return null;
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Nullable
public static Pair<Properties, VirtualFile> readPropertyFile(@NotNull Module module, @NotNull String propertyFileName) {
for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) {
final Pair<Properties, VirtualFile> result = readPropertyFile(contentRoot, propertyFileName);
if (result != null) {
return result;
}
}
return null;
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Nullable
public static Pair<Properties, VirtualFile> readPropertyFile(@NotNull VirtualFile contentRoot, @NotNull String propertyFileName) {
final VirtualFile vFile = contentRoot.findChild(propertyFileName);
if (vFile != null) {
final Properties properties = new Properties();
try {
properties.load(new FileInputStream(new File(vFile.getPath())));
return new Pair<Properties, VirtualFile>(properties, vFile);
}
catch (IOException e) {
LOG.info(e);
}
}
return null;
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Nullable
public static String getPropertyValue(@NotNull Module module, @NotNull String propertyFileName, @NotNull String propertyKey) {
final Pair<Properties, VirtualFile> pair = readPropertyFile(module, propertyFileName);
if (pair != null) {
final String value = pair.first.getProperty(propertyKey);
if (value != null) {
return value;
}
}
return null;
}
@Nullable
public static VirtualFile findFileByAbsoluteOrRelativePath(@Nullable VirtualFile baseDir, @NotNull String path) {
VirtualFile libDir = LocalFileSystem.getInstance().findFileByPath(path);
if (libDir != null) {
return libDir;
}
else if (baseDir != null) {
return LocalFileSystem.getInstance().findFileByPath(baseDir.getPath() + '/' + path);
}
return null;
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.spellchecker.compress.CompressedDictionary;
@@ -115,12 +116,13 @@ public class BaseSpellChecker implements SpellCheckerEngine {
}
private void _doLoadDictionaryAsync(final Loader loader, final Consumer<Dictionary> consumer) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
final Runnable runnable = new Runnable() {
@Override
public void run() {
if (myProject.isDisposed()) return;
LOG.debug("Loading " + loader.getName());
ProgressManager.getInstance()
.run(new Task.Backgroundable(myProject,"Loading spellchecker dictionary...", false,
.run(new Task.Backgroundable(myProject, "Loading spellchecker dictionary...", false,
new PerformInBackgroundOption() {
@Override
public boolean shouldStartInBackground() {
@@ -163,7 +165,22 @@ public class BaseSpellChecker implements SpellCheckerEngine {
}
});
}
});
};
if (!myProject.isInitialized()) {
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(
new Runnable() {
@Override
public void run() {
UIUtil.invokeLaterIfNeeded(runnable);
}
}
);
} else {
UIUtil.invokeLaterIfNeeded(runnable);
}
}
private void queueDictionaryLoad(final Loader loader, final Consumer<Dictionary> consumer) {
@@ -63,7 +63,7 @@ public class DictionaryTest extends TestCase {
public void loadDictionaryTest(@NotNull final String name, int wordCount) throws IOException {
final Transformation transform = new Transformation();
PlatformTestUtil.startPerformanceTest(times.get(name), new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest("load dictionary", times.get(name), new ThrowableRunnable() {
@Override
public void run() throws Exception {
dictionary = CompressedDictionary
@@ -72,7 +72,7 @@ public class DictionaryTest extends TestCase {
}).cpuBound().assertTiming();
final Set<String> wordsToStoreAndCheck = createWordSets(name, 50000, 1).getFirst();
PlatformTestUtil.startPerformanceTest(2000, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest("words contain",2000, new ThrowableRunnable() {
@Override
public void run() throws Exception {
for (String s : wordsToStoreAndCheck) {