From 9e88933413bd540b08b411191f3e128ee7253961 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 21 Oct 2011 12:38:50 +0400 Subject: [PATCH] GRADLE-1856 Tooling API: Make it possible to get IntelliJ IDEA view to the gradle project Improved gradle api exceptions reporting --- .../wizard/GradleProjectImportBuilder.java | 15 +++- .../gradle/remote/GradleApiException.java | 85 +++++++++++++++++++ .../gradle/remote/GradleProjectResolver.java | 3 +- .../impl/GradleProjectResolverImpl.java | 70 ++++----------- 4 files changed, 117 insertions(+), 56 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiException.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java index c6214087d1ac..048babe7168c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/GradleProjectImportBuilder.java @@ -17,6 +17,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.ProjectImportBuilder; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,7 @@ import org.jetbrains.plugins.gradle.importing.model.GradleModule; import org.jetbrains.plugins.gradle.importing.model.GradleProject; import org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager; import org.jetbrains.plugins.gradle.remote.GradleProjectResolver; +import org.jetbrains.plugins.gradle.remote.GradleApiException; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleIcons; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -157,14 +159,21 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder + * This class allows to extract textual description of the target problem and deliver it for further processing without risking to + * get the problems mentioned above. I.e. it doesn't require anything specific can be safely delivered to IJ process then. + * + * @author Denis Zhdanov + * @since 10/21/11 11:42 AM + */ +public class GradleApiException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private final String myOriginalReason; + + public GradleApiException() { + this(null, null); + } + + public GradleApiException(@Nullable String message) { + this(message, null); + } + + public GradleApiException(@Nullable Throwable cause) { + this("", cause); + } + + public GradleApiException(@Nullable String message, @Nullable Throwable cause) { + super(extractMessage(message, cause)); + if (cause == null) { + myOriginalReason = ""; + return; + } + + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + try { + cause.printStackTrace(printWriter); + } + finally { + printWriter.close(); + } + myOriginalReason = stringWriter.toString(); + } + + /** + * @return textual description of the wrapped exception (if any); empty string otherwise + */ + @NotNull + public String getOriginalReason() { + return myOriginalReason; + } + + @Override + public void printStackTrace(PrintWriter s) { + super.printStackTrace(s); + s.println(myOriginalReason); + } + + @Override + public void printStackTrace(PrintStream s) { + super.printStackTrace(s); + s.println(myOriginalReason); + } + + @Nullable + private static String extractMessage(@Nullable String message, @Nullable Throwable cause) { + if (message != null) { + return message; + } + return cause == null ? "" : cause.getMessage(); + } + +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java index ecb0a6324858..4c70a26380e7 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java @@ -25,11 +25,12 @@ public interface GradleProjectResolver extends Remote { * @param downloadLibraries flag that specifies if third-party libraries that are not available locally should be resolved (downloaded) * @return object-level representation of the target gradle project * @throws RemoteException in case of unexpected exception during remote communications + * @throws GradleApiException in case of unexpected exception thrown from Gradle API * @throws IllegalArgumentException if given path doesn't point to directory that contains gradle project or if gradle api * returns invalid data * @throws IllegalStateException if it's not possible to resolve target project info */ @NotNull GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) - throws RemoteException, IllegalArgumentException, IllegalStateException; + throws RemoteException, GradleApiException, IllegalArgumentException, IllegalStateException; } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java index 17dad9759b35..8b5ef5b420b2 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java @@ -13,16 +13,13 @@ import org.gradle.tooling.model.idea.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.importing.model.*; -import org.jetbrains.plugins.gradle.remote.GradleProjectResolver; -import org.jetbrains.plugins.gradle.remote.RemoteGradleProcessSettings; -import org.jetbrains.plugins.gradle.remote.RemoteGradleService; +import org.jetbrains.plugins.gradle.remote.*; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleLog; import org.jetbrains.plugins.gradle.util.GradleUtil; import java.io.File; import java.rmi.RemoteException; -import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -37,16 +34,25 @@ import java.util.concurrent.atomic.AtomicReference; */ public class GradleProjectResolverImpl extends RemoteObject implements GradleProjectResolver, RemoteGradleService { - private static final Set NON_UNIQUE_PATH_ENTRIES = new HashSet(Arrays.asList( - "src", "main", "java", "test", "resources" - )); - - private final BlockingQueue myConnections = new LinkedBlockingQueue(); - private final AtomicReference mySettings = new AtomicReference(); - + private final BlockingQueue myConnections = new LinkedBlockingQueue(); + private final AtomicReference mySettings = new AtomicReference(); + private final GradleLibraryNamesMixer myLibraryNamesMixer = new GradleLibraryNamesMixer(); + @NotNull @Override public GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) + throws RemoteException, GradleApiException, IllegalArgumentException, IllegalStateException + { + try { + return doResolveProjectInfo(projectPath, downloadLibraries); + } + catch (Throwable e) { + throw new GradleApiException(e); + } + } + + @NotNull + private GradleProject doResolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) throws RemoteException, IllegalArgumentException, IllegalStateException { ProjectConnection connection = getConnection(projectPath); @@ -58,7 +64,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro // populating dependent module object. Map> modules = createModules(project, result); populateModules(modules.values(), result); - diversifyLibraryNamesIfNecessary(result); + myLibraryNamesMixer.mixNames(result.getLibraries()); return result; } @@ -315,46 +321,6 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro return null; } - /** - * Gradle API doesn't provide library names at the moment, so, we deduce them from the path. However, it's possible to have identical - * names then. - *

- * This method solves that by diversifying duplicate library names. - * - * @param project target project which library names should be diversified if necessary - */ - private static void diversifyLibraryNamesIfNecessary(@NotNull GradleProject project) { - Map libraries = new HashMap(); - for (GradleLibrary library : project.getLibraries()) { - GradleLibrary previous = libraries.remove(library.getName()); - if (previous == null) { - libraries.put(library.getName(), library); - continue; - } - previous.setName(generateName(previous)); - libraries.put(previous.getName(), previous); - library.setName(generateName(library)); - libraries.put(library.getName(), library); - } - } - - @NotNull - private static String generateName(@NotNull GradleLibrary library) { - for (LibraryPathType pathType : LibraryPathType.values()) { - String path = library.getPath(pathType); - if (path == null) { - continue; - } - File file = new File(path).getParentFile(); - for (; file != null; file = file.getParentFile()) { - if (!NON_UNIQUE_PATH_ENTRIES.contains(file.getName())) { - return file.getName() + "-" + library.getName(); - } - } - } - return library.getName(); - } - /** * Allows to retrieve gradle api connection to use for the given project. *