diff --git a/.idea/modules.xml b/.idea/modules.xml
index ce8d7ca005f3..c7736ee6aa66 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -11,6 +11,7 @@
+
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index 6dc01096ba64..a092e36f46eb 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -366,6 +366,10 @@ public def layoutCommunityPlugins(String home) {
}
jar("android_rt.jar") {module("android-rt")}
+
+ dir("jps") {
+ jar("android-jps-plugin.jar") { module("android-jps-plugin") }
+ }
}
}
}
diff --git a/jps/model/src/org/jetbrains/jps/JavaSdk.groovy b/jps/model/src/org/jetbrains/jps/JavaSdk.groovy
index 2bd8812ce617..17aa8457d59c 100644
--- a/jps/model/src/org/jetbrains/jps/JavaSdk.groovy
+++ b/jps/model/src/org/jetbrains/jps/JavaSdk.groovy
@@ -1,21 +1,11 @@
package org.jetbrains.jps
/**
- * @author nik
+ * @author Eugene.Kudelevsky
*/
-class JavaSdk extends Sdk {
- String jdkPath
+public interface JavaSdk {
- def JavaSdk(Project project, String name, String jdkPath, Closure initializer) {
- super(project, name, initializer)
- this.jdkPath = jdkPath
- }
+ String getJavacExecutable();
- String getJavacExecutable() {
- return jdkPath + File.separator + "bin" + File.separator + "javac";
- }
-
- String getJavaExecutable() {
- return jdkPath + File.separator + "bin" + File.separator + "java";
- }
-}
+ String getJavaExecutable();
+}
\ No newline at end of file
diff --git a/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy b/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy
new file mode 100644
index 000000000000..9caa1092f55d
--- /dev/null
+++ b/jps/model/src/org/jetbrains/jps/JavaSdkImpl.groovy
@@ -0,0 +1,21 @@
+package org.jetbrains.jps
+
+/**
+ * @author nik
+ */
+class JavaSdkImpl extends Sdk implements JavaSdk {
+ String jdkPath
+
+ def JavaSdkImpl(Project project, String name, String jdkPath, Closure initializer) {
+ super(project, name, initializer)
+ this.jdkPath = jdkPath
+ }
+
+ String getJavacExecutable() {
+ return jdkPath + File.separator + "bin" + File.separator + "javac";
+ }
+
+ String getJavaExecutable() {
+ return jdkPath + File.separator + "bin" + File.separator + "java";
+ }
+}
diff --git a/jps/model/src/org/jetbrains/jps/Project.groovy b/jps/model/src/org/jetbrains/jps/Project.groovy
index 60f0fdc74af5..3a89242c5f6a 100644
--- a/jps/model/src/org/jetbrains/jps/Project.groovy
+++ b/jps/model/src/org/jetbrains/jps/Project.groovy
@@ -43,7 +43,7 @@ class Project {
}
def JavaSdk createJavaSdk(String name, String path, Closure initializer) {
- def sdk = new JavaSdk(this, name, path, initializer)
+ def sdk = new JavaSdkImpl(this, name, path, initializer)
sdks[name] = sdk
return sdk
}
diff --git a/jps/model/src/org/jetbrains/jps/idea/JavaSdkType.groovy b/jps/model/src/org/jetbrains/jps/idea/JavaSdkType.groovy
index 6f8f80dc8032..c300e9235363 100644
--- a/jps/model/src/org/jetbrains/jps/idea/JavaSdkType.groovy
+++ b/jps/model/src/org/jetbrains/jps/idea/JavaSdkType.groovy
@@ -1,8 +1,8 @@
package org.jetbrains.jps.idea
+import org.jetbrains.jps.JavaSdkImpl
import org.jetbrains.jps.Project
import org.jetbrains.jps.Sdk
-import org.jetbrains.jps.JavaSdk
/**
* @author nik
@@ -14,6 +14,6 @@ class JavaSdkType extends SdkTypeService {
@Override
Sdk createSdk(Project project, String name, String homePath, Node additionalData) {
- return new JavaSdk(project, name, homePath, {})
+ return new JavaSdkImpl(project, name, homePath, {})
}
}
diff --git a/plugins/android/jps-plugin/android-jps-plugin.iml b/plugins/android/jps-plugin/android-jps-plugin.iml
new file mode 100644
index 000000000000..a2f02ccd0c76
--- /dev/null
+++ b/plugins/android/jps-plugin/android-jps-plugin.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService
new file mode 100644
index 000000000000..a75fa45b2aa4
--- /dev/null
+++ b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService
@@ -0,0 +1 @@
+org.jetbrains.jps.android.AndroidFacetType
\ No newline at end of file
diff --git a/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.SdkTypeService b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.SdkTypeService
new file mode 100644
index 000000000000..f3084a2b366a
--- /dev/null
+++ b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.idea.SdkTypeService
@@ -0,0 +1 @@
+org.jetbrains.jps.android.AndroidSdkType
\ No newline at end of file
diff --git a/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService
new file mode 100644
index 000000000000..59103ac8ba86
--- /dev/null
+++ b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService
@@ -0,0 +1 @@
+org.jetbrains.jps.android.AndroidBuilderService
\ No newline at end of file
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidBuilderService.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidBuilderService.java
new file mode 100644
index 000000000000..81b9e6eba3de
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidBuilderService.java
@@ -0,0 +1,20 @@
+package org.jetbrains.jps.android;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.incremental.BuilderService;
+import org.jetbrains.jps.incremental.ModuleLevelBuilder;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AndroidBuilderService extends BuilderService {
+ @NotNull
+ @Override
+ public List extends ModuleLevelBuilder> createModuleLevelBuilders(ExecutorService executorService) {
+ return Arrays.asList(new AndroidSourceGeneratingBuilder());
+ }
+}
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy
new file mode 100644
index 000000000000..e9530f165ee7
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy
@@ -0,0 +1,46 @@
+package org.jetbrains.jps.android
+
+import com.intellij.openapi.util.io.FileUtil
+import org.jetbrains.jps.Module
+import org.jetbrains.jps.idea.Facet
+
+/**
+ * @author nik
+ */
+class AndroidFacet extends Facet {
+ final Module module
+ final String resFolderRelativePath
+
+ AndroidFacet(Module module, String name, String resFolderRelativePath) {
+ this.module = module
+ this.name = name;
+ this.resFolderRelativePath = resFolderRelativePath
+ }
+
+ File getResourceDir() {
+ return findFileByRelativeModulePath(resFolderRelativePath, true)
+ }
+
+ private File findFileByRelativeModulePath(String relativePath, boolean lookInContentRoot) {
+ if (module.basePath != null) {
+ def absPath = FileUtil.toSystemIndependentName(module.basePath + relativePath)
+ def f = new File(absPath)
+
+ if (f.exists()) {
+ return f
+ }
+ }
+
+ if (lookInContentRoot) {
+ module.contentRoots.each {
+ def absPath = FileUtil.toSystemIndependentName(contentRoot + relativePath)
+ def f = new File(absPath)
+
+ if (f.exists()) {
+ return f
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacetType.groovy b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacetType.groovy
new file mode 100644
index 000000000000..ca555e24e37e
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacetType.groovy
@@ -0,0 +1,22 @@
+package org.jetbrains.jps.android
+
+import org.jetbrains.jps.MacroExpander
+import org.jetbrains.jps.Module
+import org.jetbrains.jps.idea.Facet
+import org.jetbrains.jps.idea.FacetTypeService
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+class AndroidFacetType extends FacetTypeService {
+ public static final String ID = "android"
+
+ AndroidFacetType() {
+ super(ID)
+ }
+
+ @Override
+ Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) {
+ return new AndroidFacet(module, name, "");
+ }
+}
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdk.groovy b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdk.groovy
new file mode 100644
index 000000000000..b4ce00b91c41
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdk.groovy
@@ -0,0 +1,34 @@
+package org.jetbrains.jps.android
+
+import org.jetbrains.jps.JavaSdk
+import org.jetbrains.jps.Project
+import org.jetbrains.jps.Sdk
+import org.jetbrains.jps.JavaSdkImpl
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+class AndroidSdk extends Sdk implements JavaSdk {
+ final String sdkPath;
+ final String buildTargetHashString;
+ final String javaSdkName;
+
+ AndroidSdk(Project project, String name, String sdkPath, String javaSdkName, String buildTargetHashString) {
+ super(project, name, {})
+ this.sdkPath = sdkPath
+ this.buildTargetHashString = buildTargetHashString
+ this.javaSdkName = javaSdkName;
+ }
+
+ @Override
+ String getJavacExecutable() {
+ def javaSdk = project.sdks[javaSdkName]
+ return javaSdk instanceof JavaSdkImpl ? javaSdk.getJavacExecutable() : null
+ }
+
+ @Override
+ String getJavaExecutable() {
+ def javaSdk = project.sdks[javaSdkName]
+ return javaSdk instanceof JavaSdkImpl ? javaSdk.getJavaExecutable() : null
+ }
+}
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdkType.groovy b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdkType.groovy
new file mode 100644
index 000000000000..90d47d29c07c
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSdkType.groovy
@@ -0,0 +1,30 @@
+package org.jetbrains.jps.android
+
+import org.jetbrains.jps.idea.SdkTypeService
+import org.jetbrains.jps.Sdk
+import org.jetbrains.jps.Project
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+class AndroidSdkType extends SdkTypeService {
+ AndroidSdkType() {
+ super("Android SDK");
+ }
+
+ @Override
+ Sdk createSdk(Project project, String name, String homePath, Node additionalData) {
+ def attributes = additionalData.attributes()
+ if (attributes == null) {
+ return null;
+ }
+
+ def buildTargetHashString = (String)attributes.get("sdk")
+ def internalJdkName = (String)attributes.get("jdk")
+
+ if (internalJdkName == null || buildTargetHashString == null) {
+ return null;
+ }
+ return new AndroidSdk(project, name, homePath, internalJdkName, buildTargetHashString)
+ }
+}
diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java
new file mode 100644
index 000000000000..77abb5082d17
--- /dev/null
+++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java
@@ -0,0 +1,498 @@
+package org.jetbrains.jps.android;
+
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.android.compiler.tools.AndroidIdl;
+import org.jetbrains.android.compiler.tools.AndroidRenderscript;
+import org.jetbrains.android.sdk.MessageBuildingSdkLog;
+import org.jetbrains.android.util.AndroidCommonUtils;
+import org.jetbrains.android.util.AndroidCompilerMessageKind;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.*;
+import org.jetbrains.jps.idea.Facet;
+import org.jetbrains.jps.incremental.*;
+import org.jetbrains.jps.incremental.messages.BuildMessage;
+import org.jetbrains.jps.incremental.messages.CompilerMessage;
+import org.jetbrains.jps.incremental.messages.ProgressMessage;
+import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.*;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.android.AndroidSourceGeneratingBuilder");
+
+ @NonNls private static final String BUILDER_NAME = "android-source-generator";
+ @NonNls private static final String AIDL_EXTENSION = "aidl";
+ @NonNls private static final String RENDERSCRIPT_EXTENSION = "rs";
+
+ public AndroidSourceGeneratingBuilder() {
+ super(BuilderCategory.SOURCE_GENERATOR);
+ }
+
+ @Override
+ public String getName() {
+ return BUILDER_NAME;
+ }
+
+ @Override
+ public ModuleLevelBuilder.ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
+ if (context.isCompilingTests()) {
+ return ModuleLevelBuilder.ExitCode.OK;
+ }
+
+ try {
+ return doBuild(context, chunk);
+ }
+ catch (ProjectBuildException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ String message = e.getMessage();
+
+ if (message == null) {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ //noinspection IOResourceOpenedButNotSafelyClosed
+ e.printStackTrace(new PrintStream(out));
+ message = "Internal error: \n" + out.toString();
+ }
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message));
+ throw new ProjectBuildException(message, e);
+ }
+ }
+
+ private static ModuleLevelBuilder.ExitCode doBuild(CompileContext context, ModuleChunk chunk) throws Exception {
+ final Map idlFilesToCompile = new HashMap();
+ final Map rsFilesToCompile = new HashMap();
+ final Set modules = new HashSet();
+
+ context.processFilesToRecompile(chunk, new FileProcessor() {
+ @Override
+ public boolean apply(Module module, File file, String sourceRoot) throws IOException {
+ final AndroidFacet facet = getFacet(module);
+
+ if (facet == null) {
+ return true;
+ }
+ final String ext = FileUtil.getExtension(file.getName());
+
+ if (AIDL_EXTENSION.equals(ext)) {
+ idlFilesToCompile.put(file, facet);
+ modules.add(facet.getModule());
+ }
+ else if (RENDERSCRIPT_EXTENSION.equals(ext)) {
+ rsFilesToCompile.put(file, facet);
+ modules.add(facet.getModule());
+ }
+
+ return true;
+ }
+ });
+
+ final Map moduleDataMap = computeModuleDatas(modules, context);
+
+ if (moduleDataMap == null) {
+ return ExitCode.OK;
+ }
+
+ if (!runAidlCompiler(context, idlFilesToCompile, moduleDataMap)) {
+ return ExitCode.OK;
+ }
+
+ if (!runRenderscriptCompiler(context, rsFilesToCompile, moduleDataMap)) {
+ return ExitCode.OK;
+ }
+
+ return ExitCode.OK;
+ }
+
+ private static boolean runAidlCompiler(@NotNull final CompileContext context,
+ @NotNull Map files,
+ @NotNull Map moduleDataMap) {
+ context.processMessage(new ProgressMessage("Processing AIDL files..."));
+
+ boolean success = true;
+
+ for (Map.Entry entry : files.entrySet()) {
+ final File file = entry.getKey();
+ final Module module = entry.getValue().getModule();
+ final String filePath = file.getPath();
+
+ final MyModuleData moduleData = moduleDataMap.get(module);
+
+ if (!LOG.assertTrue(moduleData != null)) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Internal error"));
+ success = false;
+ continue;
+ }
+ final File outputDirectory = moduleData.getOutputDirectory();
+ final File aidlOutputDirectory = new File(outputDirectory, "generated-aidl");
+ final IAndroidTarget target = moduleData.getAndroidTarget();
+
+ try {
+ final File[] sourceRoots = getSourceRootsForModuleAndDependencies(module);
+ final String[] sourceRootPaths = toPaths(sourceRoots);
+ final String packageName = computePackageForFile(context, file);
+
+ if (packageName == null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot compute package for file",
+ filePath));
+ success = false;
+ continue;
+ }
+
+ final File outputFile = new File(aidlOutputDirectory, packageName.replace('.', File.separatorChar) +
+ File.separator + FileUtil.getNameWithoutExtension(file) + ".java");
+ final String outputFilePath = outputFile.getPath();
+ final Map> messages =
+ AndroidIdl.execute(target, filePath, outputFilePath, sourceRootPaths);
+
+ addMessages(context, messages, filePath);
+
+ if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
+ success = false;
+ continue;
+ }
+
+ final String moduleName = getCannonicalModuleName(module);
+ final SourceToOutputMapping sourceToOutputMap = context.getDataManager().getSourceToOutputMap(moduleName, false);
+ sourceToOutputMap.update(filePath, outputFilePath);
+ }
+ catch (final IOException e) {
+ reportExceptionError(context, filePath, e);
+ success = false;
+ }
+ }
+ return success;
+ }
+
+ private static boolean runRenderscriptCompiler(@NotNull final CompileContext context,
+ @NotNull Map files,
+ @NotNull Map moduleDataMap) {
+ context.processMessage(new ProgressMessage("Processing Renderscript files..."));
+
+ boolean success = true;
+
+ for (Map.Entry entry : files.entrySet()) {
+ final File file = entry.getKey();
+ final Module module = entry.getValue().getModule();
+
+ final MyModuleData moduleData = moduleDataMap.get(module);
+ if (!LOG.assertTrue(moduleData != null)) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Internal error"));
+ success = false;
+ continue;
+ }
+
+ final File outputDirectory = moduleData.getOutputDirectory();
+ final File rsOutputDirectory = new File(outputDirectory, "generated-rs");
+ final File generatedResourcesDir = new File(outputDirectory, "generated-resources");
+
+ final IAndroidTarget target = moduleData.getAndroidTarget();
+ final String sdkLocation = moduleData.getSdkLocation();
+ final String filePath = file.getPath();
+
+ File tmpOutputDirectory = null;
+
+ try {
+ tmpOutputDirectory = FileUtil.createTempDirectory("generated-rs-temp", null);
+ final String depFolderPath = getDependencyFolder(context, file, tmpOutputDirectory);
+ final File rawDir = new File(generatedResourcesDir, "raw");
+
+ final Map> messages =
+ AndroidRenderscript.execute(sdkLocation, target, filePath, tmpOutputDirectory.getPath(), depFolderPath, rawDir.getPath());
+
+ addMessages(context, messages, filePath);
+
+ if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
+ success = false;
+ }
+ else {
+ final List newFiles = new ArrayList();
+ AndroidCommonUtils.moveAllFiles(tmpOutputDirectory, rsOutputDirectory, newFiles);
+
+ final File bcFile = new File(rawDir, FileUtil.getNameWithoutExtension(file) + ".bc");
+ if (bcFile.exists()) {
+ newFiles.add(bcFile);
+ }
+ final List newFilePaths = Arrays.asList(toPaths(newFiles.toArray(new File[newFiles.size()])));
+
+ final String moduleName = getCannonicalModuleName(module);
+ final SourceToOutputMapping sourceToOutputMap = context.getDataManager().getSourceToOutputMap(moduleName, false);
+ sourceToOutputMap.update(filePath, newFilePaths);
+ }
+ }
+ catch (IOException e) {
+ reportExceptionError(context, filePath, e);
+ success = false;
+ }
+ finally {
+ if (tmpOutputDirectory != null) {
+ FileUtil.delete(tmpOutputDirectory);
+ }
+ }
+ }
+ return success;
+ }
+
+ private static void reportExceptionError(@NotNull CompileContext context, @NotNull String filePath, @NotNull Exception exception) {
+ final String message = exception.getMessage();
+
+ if (message != null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message, filePath));
+ LOG.debug(exception);
+ }
+ else {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, exception));
+ }
+ }
+
+ @NotNull
+ private static String getCannonicalModuleName(@NotNull Module module) {
+ return module.getName().toLowerCase(Locale.US);
+ }
+
+ @Nullable
+ private static String getDependencyFolder(@NotNull CompileContext context, @NotNull File sourceFile, @NotNull File genFolder) {
+ final RootDescriptor descriptor = context.getRootsIndex().getModuleAndRoot(sourceFile);
+ if (descriptor == null) {
+ return null;
+ }
+ final File sourceRoot = descriptor.root;
+
+ final File parent = FileUtil.getParentFile(sourceFile);
+ if (parent == null) {
+ return null;
+ }
+
+ if (parent.equals(sourceRoot)) {
+ return genFolder.getPath();
+ }
+ final String relativePath = FileUtil.getRelativePath(sourceRoot, parent);
+ assert relativePath != null;
+ return genFolder.getPath() + '/' + relativePath;
+ }
+
+ @Nullable
+ private static Map computeModuleDatas(@NotNull Collection modules, @NotNull CompileContext context)
+ throws Exception {
+ final Map moduleDataMap = new HashMap();
+
+ boolean success = true;
+
+ for (Module module : modules) {
+
+ final Sdk sdk = module.getSdk();
+ if (!(sdk instanceof AndroidSdk)) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Android SDK is not specified for module " + module.getName()));
+ success = false;
+ continue;
+ }
+ final AndroidSdk androidSdk = (AndroidSdk)sdk;
+
+ final IAndroidTarget target = parseAndroidTarget(androidSdk, context);
+ if (target == null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Android SDK is invalid or not specified for module " + module.getName()));
+ success = false;
+ continue;
+ }
+
+ final File outputDir = context.getProjectPaths().getModuleOutputDir(module, false);
+ if (outputDir == null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Cannot find output directory for module " + module.getName()));
+ success = false;
+ continue;
+ }
+
+ moduleDataMap.put(module, new MyModuleData(outputDir, androidSdk.getSdkPath(), target));
+ }
+
+ return success ? moduleDataMap : null;
+ }
+
+ private static void addMessages(@NotNull CompileContext context,
+ @NotNull Map> messages,
+ @Nullable String sourcePath) {
+ for (Map.Entry> entry : messages.entrySet()) {
+ final AndroidCompilerMessageKind kind = entry.getKey();
+ final BuildMessage.Kind buildMessageKind = toBuildMessageKind(kind);
+
+ if (buildMessageKind == null) {
+ continue;
+ }
+
+ for (String message : entry.getValue()) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, buildMessageKind, message, sourcePath));
+ }
+ }
+ }
+
+ @Nullable
+ private static BuildMessage.Kind toBuildMessageKind(@NotNull AndroidCompilerMessageKind kind) {
+ switch (kind) {
+ case ERROR:
+ return BuildMessage.Kind.ERROR;
+ case INFORMATION:
+ return BuildMessage.Kind.INFO;
+ case WARNING:
+ return BuildMessage.Kind.WARNING;
+ default:
+ LOG.error("unknown AndroidCompilerMessageKind object " + kind);
+ return null;
+ }
+ }
+
+ @Nullable
+ private static String computePackageForFile(@NotNull CompileContext context, @NotNull File file) throws IOException {
+ final RootDescriptor descriptor = context.getRootsIndex().getModuleAndRoot(file);
+ if (descriptor == null) {
+ return null;
+ }
+
+ final String relPath = FileUtil.getRelativePath(descriptor.root, FileUtil.getParentFile(file));
+ if (relPath == null) {
+ return null;
+ }
+
+ return FileUtil.toSystemIndependentName(relPath).replace('/', '.');
+ }
+
+ @Nullable
+ private static IAndroidTarget parseAndroidTarget(@NotNull AndroidSdk sdk, @NotNull CompileContext context) {
+ final String targetHashString = sdk.getBuildTargetHashString();
+ if (targetHashString == null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Cannot parse SDK " + sdk.getName() + ": build target is not specified"));
+ return null;
+ }
+
+ final MessageBuildingSdkLog log = new MessageBuildingSdkLog();
+ final SdkManager manager = AndroidCommonUtils.createSdkManager(sdk.getSdkPath(), log);
+
+ if (manager == null) {
+ final String message = log.getErrorMessage();
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Android SDK is parsed incorrectly." +
+ (message.length() > 0 ? " Parsing log:\n" + message : "")));
+ return null;
+ }
+
+ final IAndroidTarget target = manager.getTargetFromHashString(targetHashString);
+ if (target == null) {
+ context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
+ "Cannot parse SDK '" + sdk.getName() + "': unknown target " + targetHashString));
+ return null;
+ }
+ return target;
+ }
+
+ private static void fillSourceRoots(@NotNull Module module, @NotNull Set visited, @NotNull Set result)
+ throws IOException {
+ visited.add(module);
+ final AndroidFacet facet = getFacet(module);
+ File resDir = null;
+
+ if (facet != null) {
+ resDir = facet.getResourceDir();
+ if (resDir != null) {
+ resDir = resDir.getCanonicalFile();
+ }
+ }
+
+ for (String sourceRootPath : module.getSourceRoots()) {
+ final File sourceRoot = new File(sourceRootPath).getCanonicalFile();
+
+ if (!sourceRoot.equals(resDir)) {
+ result.add(sourceRoot);
+ }
+ }
+
+ for (ClasspathItem classpathItem : module.getClasspath(ClasspathKind.PRODUCTION_COMPILE)) {
+ if (classpathItem instanceof Module) {
+ final Module depModule = (Module)classpathItem;
+
+ if (!visited.contains(depModule)) {
+ fillSourceRoots(depModule, visited, result);
+ }
+ }
+ }
+ }
+
+ @NotNull
+ public static File[] getSourceRootsForModuleAndDependencies(@NotNull Module module) throws IOException {
+ Set result = new HashSet();
+ fillSourceRoots(module, new HashSet(), result);
+ return result.toArray(new File[result.size()]);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Android Builder";
+ }
+
+ @Nullable
+ private static AndroidFacet getFacet(@NotNull Module module) {
+ AndroidFacet androidFacet = null;
+
+ for (Facet facet : module.getFacets().values()) {
+ if (facet instanceof AndroidFacet) {
+ androidFacet = (AndroidFacet)facet;
+ }
+ }
+ return androidFacet;
+ }
+
+ @NotNull
+ private static String[] toPaths(@NotNull File[] files) {
+ final String[] result = new String[files.length];
+
+ for (int i = 0; i < result.length; i++) {
+ result[i] = files[i].getPath();
+ }
+ return result;
+ }
+
+ private static class MyModuleData {
+ private final File myOutputDirectory;
+ private final String mySdkLocation;
+ private final IAndroidTarget myAndroidTarget;
+
+ private MyModuleData(@NotNull File outputDirectory,
+ @NotNull String sdkLocation,
+ @NotNull IAndroidTarget androidTarget) {
+ myOutputDirectory = outputDirectory;
+ mySdkLocation = sdkLocation;
+ myAndroidTarget = androidTarget;
+ }
+
+ @NotNull
+ public File getOutputDirectory() {
+ return myOutputDirectory;
+ }
+
+ @NotNull
+ public IAndroidTarget getAndroidTarget() {
+ return myAndroidTarget;
+ }
+
+ @NotNull
+ public String getSdkLocation() {
+ return mySdkLocation;
+ }
+ }
+}
diff --git a/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidIdl.java b/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidIdl.java
index 16e0bc1a3175..0984f0a8e9aa 100644
--- a/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidIdl.java
+++ b/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidIdl.java
@@ -16,7 +16,9 @@
package org.jetbrains.android.compiler.tools;
import com.android.sdklib.IAndroidTarget;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.android.util.ExecutionUtil;
import org.jetbrains.annotations.NotNull;
@@ -32,6 +34,8 @@ import java.util.Map;
* @author Alexey Efimov
*/
public final class AndroidIdl {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.tools.AndroidIdl");
+
private AndroidIdl() {
}
@@ -51,6 +55,8 @@ public final class AndroidIdl {
}
commands.add(file);
commands.add(outFile);
+
+ LOG.info(AndroidCommonUtils.command2string(commands));
return ExecutionUtil.doExecute(ArrayUtil.toStringArray(commands));
}
diff --git a/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidRenderscript.java b/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidRenderscript.java
new file mode 100644
index 000000000000..0bd16812613e
--- /dev/null
+++ b/plugins/android/rt/src/org/jetbrains/android/compiler/tools/AndroidRenderscript.java
@@ -0,0 +1,58 @@
+package org.jetbrains.android.compiler.tools;
+
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.android.util.AndroidCommonUtils;
+import org.jetbrains.android.util.AndroidCompilerMessageKind;
+import org.jetbrains.android.util.ExecutionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AndroidRenderscript {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.AndroidRenderscriptCompiler");
+
+ public static Map> execute(@NotNull final String sdkLocation,
+ @NotNull IAndroidTarget target,
+ @NotNull String sourceFilePath,
+ @NotNull final String genFolderPath,
+ @Nullable String depFolderPath,
+ @NotNull final String rawDirPath)
+ throws IOException {
+ final List command = new ArrayList();
+ command.add(
+ FileUtil.toSystemDependentName(sdkLocation + '/' + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + SdkConstants.FN_RENDERSCRIPT));
+ command.add("-I");
+ command.add(target.getPath(IAndroidTarget.ANDROID_RS_CLANG));
+ command.add("-I");
+ command.add(target.getPath(IAndroidTarget.ANDROID_RS));
+ command.add("-p");
+ command.add(FileUtil.toSystemDependentName(genFolderPath));
+ command.add("-o");
+ command.add(FileUtil.toSystemDependentName(rawDirPath));
+
+ command.add("-target-api");
+ command.add(Integer.toString(target.getVersion().getApiLevel()));
+
+ if (depFolderPath != null) {
+ command.add("-d");
+ command.add(FileUtil.toSystemDependentName(depFolderPath));
+ }
+
+ command.add("-MD");
+ command.add(FileUtil.toSystemDependentName(sourceFilePath));
+
+ LOG.info(AndroidCommonUtils.command2string(command));
+ return ExecutionUtil.doExecute(ArrayUtil.toStringArray(command));
+ }
+}
diff --git a/plugins/android/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java b/plugins/android/rt/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java
similarity index 91%
rename from plugins/android/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java
rename to plugins/android/rt/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java
index 7c36b181cd6f..49e083d10236 100644
--- a/plugins/android/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java
+++ b/plugins/android/rt/src/org/jetbrains/android/sdk/MessageBuildingSdkLog.java
@@ -21,11 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
/**
- * Created by IntelliJ IDEA.
- * User: Eugene.Kudelevsky
- * Date: Aug 25, 2009
- * Time: 5:54:47 PM
- * To change this template use File | Settings | File Templates.
+ * @author Eugene.Kudelevsky
*/
public class MessageBuildingSdkLog implements ISdkLog {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.sdk.MessageBuildingSdkLog");
diff --git a/plugins/android/rt/src/org/jetbrains/android/util/AndroidCommonUtils.java b/plugins/android/rt/src/org/jetbrains/android/util/AndroidCommonUtils.java
index 450687945d47..3b54dcf9532d 100644
--- a/plugins/android/rt/src/org/jetbrains/android/util/AndroidCommonUtils.java
+++ b/plugins/android/rt/src/org/jetbrains/android/util/AndroidCommonUtils.java
@@ -1,8 +1,15 @@
package org.jetbrains.android.util;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
+import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import java.io.File;
+import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
@@ -11,7 +18,7 @@ import java.util.Iterator;
*/
public class AndroidCommonUtils {
@NonNls public static final Object MANIFEST_JAVA_FILE_NAME = "Manifest.java";
- public static final String R_JAVA_FILENAME = "R.java";
+ @NonNls public static final String R_JAVA_FILENAME = "R.java";
private AndroidCommonUtils() {
}
@@ -29,4 +36,37 @@ public class AndroidCommonUtils {
}
return builder.toString();
}
+
+ @Nullable
+ public static SdkManager createSdkManager(@NotNull String path, @NotNull ISdkLog log) {
+ path = FileUtil.toSystemDependentName(path);
+
+ final File f = new File(path);
+ if (!f.exists() || !f.isDirectory()) {
+ return null;
+ }
+
+ final File platformsDir = new File(f, SdkConstants.FD_PLATFORMS);
+ if (!platformsDir.exists() || !platformsDir.isDirectory()) {
+ return null;
+ }
+
+ return SdkManager.createManager(path + File.separatorChar, log);
+ }
+
+ public static void moveAllFiles(@NotNull File from, @NotNull File to, @NotNull Collection newFiles) throws IOException {
+ if (from.isFile()) {
+ FileUtil.rename(from, to);
+ newFiles.add(to);
+ }
+ else {
+ final File[] children = from.listFiles();
+
+ if (children != null) {
+ for (File child : children) {
+ moveAllFiles(child, new File(to, child.getName()), newFiles);
+ }
+ }
+ }
+ }
}
diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml
index e6e625de60e8..67a616094d46 100644
--- a/plugins/android/src/META-INF/plugin.xml
+++ b/plugins/android/src/META-INF/plugin.xml
@@ -189,6 +189,12 @@
+
+
+
+
+
+
diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java
index 5121f6a31a6f..54802f56a12e 100644
--- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java
+++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java
@@ -20,6 +20,7 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.compiler.tools.AndroidApt;
import org.jetbrains.android.compiler.tools.AndroidIdl;
+import org.jetbrains.android.compiler.tools.AndroidRenderscript;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
@@ -448,13 +449,19 @@ public class AndroidAutogenerator {
try {
tempOutDir = FileUtil.createTempDirectory("android_renderscript_autogeneration", "tmp");
+ final VirtualFile vTempOutDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempOutDir);
- final Map> messages = AndroidRenderscriptCompiler.
- launchRenderscriptCompiler(module.getProject(), item.mySdkLocation, item.myTarget, file, tempOutDir.getPath(), item.myRawDirPath);
+ final String depFolderPath =
+ vTempOutDir != null ? AndroidRenderscriptCompiler.getDependencyFolder(context.getProject(), file, vTempOutDir) : null;
+
+ final Map> messages = AndroidCompileUtil.toCompilerMessageCategoryKeys(
+ AndroidRenderscript
+ .execute(item.mySdkLocation, item.myTarget, file.getPath(), tempOutDir.getPath(), depFolderPath,
+ item.myRawDirPath));
if (messages.get(CompilerMessageCategory.ERROR).size() == 0) {
final List newFiles = new ArrayList();
- moveAllFiles(tempOutDir, new File(item.myGenDirPath), newFiles);
+ AndroidCommonUtils.moveAllFiles(tempOutDir, new File(item.myGenDirPath), newFiles);
for (File newFile : newFiles) {
final VirtualFile newVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(newFile);
@@ -502,22 +509,6 @@ public class AndroidAutogenerator {
}
}
- private static void moveAllFiles(@NotNull File from, @NotNull File to, @NotNull Collection newFiles) throws IOException {
- if (from.isFile()) {
- FileUtil.rename(from, to);
- newFiles.add(to);
- }
- else {
- final File[] children = from.listFiles();
-
- if (children != null) {
- for (File child : children) {
- moveAllFiles(child, new File(to, child.getName()), newFiles);
- }
- }
- }
- }
-
private static boolean ensureFilesWritable(@NotNull final Project project, @NotNull final Collection filesToCheck) {
if (filesToCheck.size() == 0) {
return true;
diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java
index 9dff00c3448f..d6cbc490baad 100644
--- a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java
+++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java
@@ -2,31 +2,26 @@ package org.jetbrains.android.compiler;
import com.android.AndroidConstants;
import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
import com.intellij.facet.FacetManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.compiler.ex.CompileContextEx;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
+import org.jetbrains.android.compiler.tools.AndroidRenderscript;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.fileTypes.AndroidRenderscriptFileType;
import org.jetbrains.android.sdk.AndroidPlatform;
-import org.jetbrains.android.util.AndroidBundle;
-import org.jetbrains.android.util.AndroidCommonUtils;
-import org.jetbrains.android.util.AndroidUtils;
+import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,8 +35,7 @@ import java.util.*;
* @author Eugene.Kudelevsky
*/
public class AndroidRenderscriptCompiler implements SourceGeneratingCompiler {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.AndroidRenderscriptCompiler");
-
+
private static final GenerationItem[] EMPTY_GENERATION_ITEM_ARRAY = {};
@Nullable
@@ -190,13 +184,15 @@ public class AndroidRenderscriptCompiler implements SourceGeneratingCompiler {
}
for (final VirtualFile sourceFile : genItem.myFiles) {
+ final String depFolderOsPath = getDependencyFolder(context.getProject(), sourceFile, outputRootDirectory);
+
try {
- final Map> messages = launchRenderscriptCompiler(context.getProject(),
- genItem.mySdkLocation,
- genItem.myAndroidTarget,
- sourceFile,
- genRootPath,
- genItem.myRawDirPath);
+ final Map> messages = AndroidCompileUtil.toCompilerMessageCategoryKeys(
+ AndroidRenderscript
+ .execute(genItem.mySdkLocation, genItem.myAndroidTarget, sourceFile.getPath(), genRootPath,
+ depFolderOsPath,
+ genItem.myRawDirPath));
+
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
if (context.getProject().isDisposed()) {
@@ -235,47 +231,10 @@ public class AndroidRenderscriptCompiler implements SourceGeneratingCompiler {
}
}
- static Map> launchRenderscriptCompiler(@NotNull Project project,
- @NotNull final String sdkLocation,
- @NotNull IAndroidTarget target,
- @NotNull final VirtualFile sourceFile,
- @NotNull final String genFolderPath,
- @NotNull final String rawDirPath)
- throws IOException {
- final List command = new ArrayList();
- command.add(
- FileUtil.toSystemDependentName(sdkLocation + '/' + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + SdkConstants.FN_RENDERSCRIPT));
- command.add("-I");
- command.add(target.getPath(IAndroidTarget.ANDROID_RS_CLANG));
- command.add("-I");
- command.add(target.getPath(IAndroidTarget.ANDROID_RS));
- command.add("-p");
- command.add(FileUtil.toSystemDependentName(genFolderPath));
- command.add("-o");
- command.add(FileUtil.toSystemDependentName(rawDirPath));
-
- final String sourceFilePath = FileUtil.toSystemDependentName(sourceFile.getPath());
-
- final VirtualFile genFolder = LocalFileSystem.getInstance().refreshAndFindFileByPath(FileUtil.toSystemIndependentName(genFolderPath));
- if (genFolder != null) {
- final String dependencyFolderPath = getDependencyFolder(project, sourceFile, genFolder);
- if (dependencyFolderPath != null) {
- command.add("-d");
- command.add(FileUtil.toSystemDependentName(dependencyFolderPath));
- }
- }
-
- command.add("-MD");
- command.add(sourceFilePath);
-
- LOG.info(AndroidCommonUtils.command2string(command));
- return AndroidCompileUtil.execute(ArrayUtil.toStringArray(command));
- }
-
@Nullable
- private static String getDependencyFolder(@NotNull final Project project,
- @NotNull final VirtualFile sourceFile,
- @NotNull final VirtualFile genFolder) {
+ static String getDependencyFolder(@NotNull final Project project,
+ @NotNull final VirtualFile sourceFile,
+ @NotNull final VirtualFile genFolder) {
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
final VirtualFile sourceRoot = index.getSourceRootForFile(sourceFile);
diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdk.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdk.java
index 877dc802f84c..78cd3fbf1871 100644
--- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdk.java
+++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdk.java
@@ -33,6 +33,7 @@ import com.intellij.reference.SoftReference;
import com.intellij.util.containers.HashMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.android.actions.AndroidEnableDdmsAction;
+import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.BufferingFileWrapper;
import org.jetbrains.annotations.NotNull;
@@ -152,7 +153,7 @@ public class AndroidSdk {
@Nullable
public static AndroidSdk parse(@NotNull String path, @NotNull ISdkLog log) {
- final SdkManager manager = AndroidSdkUtils.createSdkManager(path, log);
+ final SdkManager manager = AndroidCommonUtils.createSdkManager(path, log);
return manager != null ? new AndroidSdk(manager, path) : null;
}
diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java
index 766e05545306..1536eac0a5e8 100644
--- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java
+++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java
@@ -17,9 +17,7 @@
package org.jetbrains.android.sdk;
import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
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.module.Module;
@@ -36,12 +34,12 @@ 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.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.File;
import java.util.*;
/**
@@ -55,7 +53,7 @@ public class AndroidSdkUtils {
}
public static boolean isAndroidSdk(@NotNull String path) {
- return createSdkManager(path, new EmptySdkLog()) != null;
+ return AndroidCommonUtils.createSdkManager(path, new EmptySdkLog()) != null;
}
@Nullable
@@ -370,21 +368,4 @@ public class AndroidSdkUtils {
public static void openModuleDependenciesConfigurable(final Module module) {
ProjectSettingsService.getInstance(module.getProject()).openModuleDependenciesSettings(module, null);
}
-
- @Nullable
- public static SdkManager createSdkManager(@NotNull String path, @NotNull ISdkLog log) {
- path = FileUtil.toSystemDependentName(path);
-
- final File f = new File(path);
- if (!f.exists() || !f.isDirectory()) {
- return null;
- }
-
- final File platformsDir = new File(f, SdkConstants.FD_PLATFORMS);
- if (!platformsDir.exists() || !platformsDir.isDirectory()) {
- return null;
- }
-
- return SdkManager.createManager(path + File.separatorChar, log);
- }
}