diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java index 8b082bdd16df..e98026215195 100644 --- a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java +++ b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java @@ -4,11 +4,9 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ThrowableComputable; import com.intellij.util.containers.ConcurrentFactoryMap; import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; +import java.lang.reflect.*; import java.rmi.Remote; import java.util.Map; @@ -137,4 +135,24 @@ public class RemoteUtil { thread.setContextClassLoader(prev); } } + + /** + * There is a possible case that remotely called code throws exception during processing. That exception is wrapped at different + * levels then - {@link InvocationTargetException}, {@link UndeclaredThrowableException} etc. + *

+ * This method tries to extract the 'real exception' from the given potentially wrapped one. + * + * @param e exception to process + * @return extracted 'real exception' if any; given exception otherwise + */ + @NotNull + public static Throwable unwrap(@NotNull Throwable e) { + for (Throwable candidate = e; candidate != null; candidate = candidate.getCause()) { + Class clazz = candidate.getClass(); + if (clazz != InvocationTargetException.class && clazz != UndeclaredThrowableException.class) { + return candidate; + } + } + return e; + } } diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 3c2302c763fb..eda32e58b6b5 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -12,11 +12,14 @@ gradle.import.structure.settings.label.name=Name: gradle.import.structure.settings.label.language.level=Language level: gradle.import.title.error.resolve.generic=Resolve error -gradle.import.text.error.resolve.generic=Can't resolve target gradle project at '{0}' +gradle.import.text.error.resolve.generic.without.reason=Can''t resolve target gradle project at ''{0}'' +gradle.import.text.error.resolve.generic.with.reason=Can''t resolve target gradle project at ''{0}''.\nReason: {1} gradle.import.text.error.project.undefined=No project file is defined gradle.import.text.error.directory.instead.file=Given path points to directory instead of gradle build file gradle.import.text.error.invalid.path=Can't resolve gradle project. Reason: given path ({0}) doesn't point to a file gradle.import.text.error.cannot.parse.project=Can not parse gradle project gradle.import.text.error.undefined.name=Name is undefined +gradle.library.resolve.progress.text=Resolving gradle libraries + gradle.generic.text.error.sdk.undefined=Gradle installation is unknown \ No newline at end of file diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 9b8d29d77563..8372e98727ec 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -1,12 +1,20 @@ package org.jetbrains.plugins.gradle.importing; import com.intellij.openapi.application.*; +import com.intellij.openapi.components.ServiceManager; 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.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.util.Alarm; import com.intellij.util.containers.hash.HashMap; @@ -14,6 +22,9 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.importing.model.*; +import org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager; +import org.jetbrains.plugins.gradle.remote.GradleProjectResolver; +import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleLog; import java.io.File; @@ -42,27 +53,28 @@ public class GradleModulesImporter { /** * Entry point for the whole 'import modules' procedure. * - * @param modules module info containers received from the gradle api - * @param project project that should host the modules - * @param model modules model - * @return mappings between the given gradle modules and newly created intellij modules + * @param modules module info containers received from the gradle api + * @param project project that should host the modules + * @param model modules model + * @param gradleProjectPath file system path to the gradle project file being imported + * @return mappings between the given gradle modules and newly created intellij modules */ @NotNull public Map importModules(@NotNull final Iterable modules, @Nullable final Project project, - @Nullable final ModifiableModuleModel model) + @Nullable final ModifiableModuleModel model, @NotNull String gradleProjectPath) { if (project == null) { return Collections.emptyMap(); } removeExistingModulesSettings(modules); if (!project.isInitialized()) { - myAlarm.addRequest(new ImportModulesTask(project, modules), PROJECT_INITIALISATION_DELAY_MS); + myAlarm.addRequest(new ImportModulesTask(project, modules, gradleProjectPath), PROJECT_INITIALISATION_DELAY_MS); return Collections.emptyMap(); } if (model == null) { return Collections.emptyMap(); } - return importModules(modules, model); + return importModules(modules, model, project, gradleProjectPath); } private static void removeExistingModulesSettings(@NotNull Iterable modules) { @@ -80,7 +92,9 @@ public class GradleModulesImporter { } public Map importModules(@NotNull final Iterable modules, - @NotNull final ModifiableModuleModel model) + @NotNull final ModifiableModuleModel model, + @NotNull final Project intellijProject, + @NotNull final String gradleProjectPath) { final Map result = new HashMap(); UIUtil.invokeAndWaitIfNeeded(new Runnable() { @@ -90,7 +104,13 @@ public class GradleModulesImporter { AccessToken writeLock = application.acquireWriteActionLock(getClass()); try { try { - result.putAll(doImportModules(modules, model)); + Map moduleMappings = doImportModules(modules, model); + result.putAll(moduleMappings); + myAlarm.cancelAllRequests(); + myAlarm.addRequest( + new SetupExternalLibrariesTask(moduleMappings, gradleProjectPath, intellijProject), + PROJECT_INITIALISATION_DELAY_MS + ); } finally { model.commit(); @@ -105,7 +125,7 @@ public class GradleModulesImporter { } /** - * Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel)}. Insists on all arguments to + * Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel, String)}. Insists on all arguments to * be ready to use. * * @param modules modules to import @@ -216,6 +236,156 @@ public class GradleModulesImporter { } } + /** + * Resolves (downloads if necessary) external libraries necessary for the gradle project located at the given path and configures + * them for the corresponding intellij project. + *

+ * Note: is assumed to be executed under write action. + * + * @param moduleMappings gradle-intellij module mappings + * @param intellijProject intellij project for the target gradle project + * @param gradleProjectPath file system path to the target gradle project + */ + private static void setupLibraries(@NotNull final Map moduleMappings, + @NotNull final Project intellijProject, + @NotNull final String gradleProjectPath) + { + final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class); + + Runnable edtAction = new Runnable() { + @Override + public void run() { + final Ref gradleProjectRef = new Ref(); + //ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + ProgressManager.getInstance().run( + new Task.Backgroundable(intellijProject, GradleBundle.message("gradle.library.resolve.progress.text"), false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + indicator.setIndeterminate(true); + try { + GradleProjectResolver resolver = manager.getFacade().getResolver(); + gradleProjectRef.set(resolver.resolveProjectInfo(gradleProjectPath, true)); + } + catch (Exception e) { + GradleLog.LOG.warn("Can't resolve external dependencies of the target gradle project (" + gradleProjectPath + ")", e); + } + } + }); + + final GradleProject gradleProject = gradleProjectRef.get(); + if (gradleProject == null) { + return; + } + + Application application = ApplicationManager.getApplication(); + AccessToken writeLock = application.acquireWriteActionLock(getClass()); + try { + doSetupLibraries(moduleMappings, gradleProject, intellijProject); + } + finally { + writeLock.finish(); + } + } + }; + UIUtil.invokeLaterIfNeeded(edtAction); + } + + private static void doSetupLibraries(@NotNull Map moduleMappings, + @NotNull GradleProject gradleProject, + @NotNull Project intellijProject) + { + Application application = ApplicationManager.getApplication(); + application.assertWriteAccessAllowed(); + + Map libraryMappings = registerProjectLibraries(gradleProject, intellijProject); + if (libraryMappings == null) { + return; + } + + configureModulesLibraryDependencies(moduleMappings, libraryMappings, gradleProject); + } + + /** + * Registers {@link GradleProject#getLibraries() libraries} of the given gradle project at the intellij project. + * + * @param gradleProject target gradle project being imported + * @param intellijProject intellij representation of the given gradle project + * @return mapping between libraries of the given gradle and intellij projects + */ + @Nullable + private static Map registerProjectLibraries(GradleProject gradleProject, Project intellijProject) { + LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(intellijProject); + if (projectLibraryTable == null) { + GradleLog.LOG.warn( + "Can't resolve external dependencies of the target gradle project (" + intellijProject + "). Reason: project " + + "library table is undefined" + ); + return null; + } + Map libraryMappings = new HashMap(); + for (GradleLibrary gradleLibrary : gradleProject.getLibraries()) { + Library intellijLibrary = projectLibraryTable.createLibrary(gradleLibrary.getName()); + libraryMappings.put(gradleLibrary, intellijLibrary); + Library.ModifiableModel model = intellijLibrary.getModifiableModel(); + try { + registerPath(gradleLibrary, model); + } + finally { + model.commit(); + } + } + return libraryMappings; + } + + private static void configureModulesLibraryDependencies(@NotNull Map moduleMappings, + @NotNull final Map libraryMappings, + @NotNull GradleProject gradleProject) { + for (GradleModule gradleModule : gradleProject.getModules()) { + Module intellijModule = moduleMappings.get(gradleModule); + if (intellijModule == null) { + GradleLog.LOG.warn(String.format( + "Can't find intellij module for the gradle module '%s'. Registered mappings: %s", gradleModule, moduleMappings + )); + continue; + } + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule); + final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); + GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() { + @Override + public void visit(@NotNull GradleLibraryDependency dependency) { + GradleLibrary gradleLibrary = dependency.getLibrary(); + Library intellijLibrary = libraryMappings.get(gradleLibrary); + if (intellijLibrary == null) { + GradleLog.LOG.warn(String.format( + "Can't find registered intellij library for gradle library '%s'. Registered mappings: %s", gradleLibrary, libraryMappings + )); + return; + } + LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(intellijLibrary); + orderEntry.setExported(dependency.isExported()); + orderEntry.setScope(dependency.getScope()); + } + }; + try { + for (GradleDependency dependency : gradleModule.getDependencies()) { + dependency.invite(visitor); + } + } + finally { + moduleRootModel.commit(); + } + } + } + + private static void registerPath(@NotNull GradleLibrary gradleLibrary, @NotNull Library.ModifiableModel model) { + for (LibraryPathType pathType : LibraryPathType.values()) { + String path = gradleLibrary.getPath(pathType); + if (path != null) { + model.addRoot(toVfsUrl(path), pathType.getRootType()); + } + } + } + private static String toVfsUrl(@NotNull String path) { return LocalFileSystem.PROTOCOL_PREFIX + path; } @@ -224,17 +394,19 @@ public class GradleModulesImporter { private final Project myProject; private final Iterable myModules; + private final String myGradleProjectPath; - private ImportModulesTask(@NotNull Project project, @NotNull Iterable modules) { + private ImportModulesTask(@NotNull Project project, @NotNull Iterable modules, @NotNull String gradleProjectPath) { myProject = project; myModules = modules; + myGradleProjectPath = gradleProjectPath; } @Override public void run() { myAlarm.cancelAllRequests(); if (!myProject.isInitialized()) { - myAlarm.addRequest(new ImportModulesTask(myProject, myModules), PROJECT_INITIALISATION_DELAY_MS); + myAlarm.addRequest(new ImportModulesTask(myProject, myModules, myGradleProjectPath), PROJECT_INITIALISATION_DELAY_MS); return; } @@ -243,8 +415,26 @@ public class GradleModulesImporter { result.setResult(ModuleManager.getInstance(myProject).getModifiableModel()); } }.execute().getResultObject(); + + importModules(myModules, model, myProject, myGradleProjectPath); + } + } + + private static class SetupExternalLibrariesTask implements Runnable { - importModules(myModules, model); + private final Map myModules; + private final String myGradleProjectPath; + private final Project myIntellijProject; + + SetupExternalLibrariesTask(@NotNull Map modules, @NotNull String gradleProjectPath, Project intellijProject) { + myModules = modules; + myGradleProjectPath = gradleProjectPath; + myIntellijProject = intellijProject; + } + + @Override + public void run() { + setupLibraries(myModules, myIntellijProject, myGradleProjectPath); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleContentRoot.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleContentRoot.java index 0ba669c8ea02..d22170d9b4c8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleContentRoot.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleContentRoot.java @@ -1,8 +1,10 @@ package org.jetbrains.plugins.gradle.importing.model; +import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.util.GradleUtil; +import java.io.File; import java.util.*; /** @@ -39,7 +41,21 @@ public class GradleContentRoot extends AbstractGradleEntity { return myData.get(type); } - public void storePath(@NotNull SourceType type, @NotNull String path) { + /** + * Ask to remember that directory at the given path contains sources of the given type. + * + * @param type target sources type + * @param path target source directory path + * @throws IllegalArgumentException if given path points to the directory that is not located + * under the {@link #getRootPath() content root} + */ + public void storePath(@NotNull SourceType type, @NotNull String path) throws IllegalArgumentException { + if (!FileUtil.isAncestor(new File(getRootPath()), new File(path), false)) { + throw new IllegalArgumentException(String.format( + "Can't register given path of type '%s' because it's out of content root.%nContent root: '%s'%nGiven path: '%s'", + type, getRootPath(), new File(path).getAbsolutePath() + )); + } myData.get(type).add(GradleUtil.toCanonicalPath(path)); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModule.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModule.java index d951bad3aa98..172dc2bce629 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModule.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModule.java @@ -138,6 +138,7 @@ public class GradleModule extends AbstractNamedGradleEntity implements Named { @Override public GradleModule clone() { GradleModule result = new GradleModule(getName(), new File(getModuleFilePath()).getParent()); + result.setInheritProjectCompileOutputPath(isInheritProjectCompileOutputPath()); for (GradleContentRoot contentRoot : getContentRoots()) { result.addContentRoot(contentRoot.clone()); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/LibraryPathType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/LibraryPathType.java index b90a3d910691..d08c06f3bc87 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/LibraryPathType.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/LibraryPathType.java @@ -1,8 +1,27 @@ package org.jetbrains.plugins.gradle.importing.model; +import com.intellij.openapi.roots.OrderRootType; +import org.jetbrains.annotations.NotNull; + /** + * Note that current enum duplicates {@link OrderRootType}. We can't use the later directly because it's not properly setup + * for serialization/deserialization. + * * @author Denis Zhdanov * @since 8/10/11 6:37 PM */ public enum LibraryPathType { - BINARY, SOURCE, JAVADOC} + + BINARY(OrderRootType.CLASSES), SOURCE(OrderRootType.SOURCES), JAVADOC(OrderRootType.DOCUMENTATION); + + private final transient OrderRootType myRootType; + + LibraryPathType(@NotNull OrderRootType rootType) { + myRootType = rootType; + } + + @NotNull + public OrderRootType getRootType() { + return myRootType; + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/AbstractImportFromGradleWizardStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/AbstractImportFromGradleWizardStep.java index 14b1c32b8076..6cf44f974d77 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/AbstractImportFromGradleWizardStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/AbstractImportFromGradleWizardStep.java @@ -1,7 +1,7 @@ package org.jetbrains.plugins.gradle.importing.wizard; -import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.projectImport.ProjectImportWizardStep; import org.jetbrains.annotations.NotNull; /** @@ -10,21 +10,20 @@ import org.jetbrains.annotations.NotNull; * @author Denis Zhdanov * @since 8/2/11 3:22 PM */ -public abstract class AbstractImportFromGradleWizardStep extends ModuleWizardStep { +public abstract class AbstractImportFromGradleWizardStep extends ProjectImportWizardStep { - private final WizardContext myContext; - protected AbstractImportFromGradleWizardStep(@NotNull WizardContext context) { - myContext = context; + super(context); } - @NotNull - public WizardContext getContext() { - return myContext; + @Override + public WizardContext getWizardContext() { + return super.getWizardContext(); } + @Override @NotNull protected GradleProjectImportBuilder getBuilder() { - return (GradleProjectImportBuilder)myContext.getProjectBuilder(); + return (GradleProjectImportBuilder)getWizardContext().getProjectBuilder(); } } 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 5018c5b77333..48f1de807626 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 @@ -1,5 +1,6 @@ package org.jetbrains.plugins.gradle.importing.wizard; +import com.intellij.execution.rmi.RemoteUtil; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.components.ServiceManager; @@ -15,6 +16,7 @@ import com.intellij.openapi.projectRoots.JavaSdk; 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.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.ProjectImportBuilder; import org.jetbrains.annotations.NotNull; @@ -84,7 +86,7 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder mappings = importer.importModules(myModuleMappings.values(), project, model); + Map mappings = importer.importModules(myModuleMappings.values(), project, model, myProjectFile.getAbsolutePath()); return new ArrayList(mappings.values()); } @@ -139,19 +141,22 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder errorReason = new Ref(); try { // TODO den derive target project for 'import module from gradle' (for 'add module' functionality). Project project = ProjectManager.getInstance().getDefaultProject(); ProgressManager.getInstance().run(new Task.Modal(project, GradleBundle.message("gradle.import.progress.text"), true) { + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") @Override public void run(@NotNull ProgressIndicator indicator) { indicator.setIndeterminate(true); - GradleApiFacadeManager manager = ServiceManager.getService(getProject(), GradleApiFacadeManager.class); + GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class); try { GradleProjectResolver resolver = manager.getFacade().getResolver(); myGradleProject = resolver.resolveProjectInfo(myProjectFile.getAbsolutePath(), false); } catch (Exception e) { + errorReason.set(RemoteUtil.unwrap(e).getLocalizedMessage()); // Ignore here because it will be reported on method exit. GradleLog.LOG.warn("Can't resolve gradle project", e); } @@ -162,10 +167,12 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder> modules, + private static void populateModules(@NotNull Iterable> modules, @NotNull GradleProject intellijProject) - throws IllegalStateException + throws IllegalArgumentException, IllegalStateException { for (Pair pair : modules) { populateModule(pair.second, pair.first, intellijProject); } } - private static void populateModule(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule, + private static void populateModule(@NotNull IdeaModule gradleModule, + @NotNull GradleModule intellijModule, @NotNull GradleProject intellijProject) - throws IllegalStateException + throws IllegalArgumentException, IllegalStateException { populateContentRoots(gradleModule, intellijModule); populateCompileOutputSettings(gradleModule.getCompilerOutput(), intellijModule); populateDependencies(gradleModule, intellijModule, intellijProject); } - private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule) { + /** + * Populates {@link GradleModule#getContentRoots() content roots} of the given intellij module on the basis of the information + * contained at the given gradle module. + * + * @param gradleModule holder of the module information received from the gradle tooling api + * @param intellijModule corresponding module from intellij gradle plugin domain + * @throws IllegalArgumentException if given gradle module contains invalid data + */ + private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule) + throws IllegalArgumentException + { DomainObjectSet contentRoots = gradleModule.getContentRoots(); if (contentRoots == null) { return; @@ -150,9 +153,19 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro intellijModule.addContentRoot(intellijContentRoot); } } - - private static void populateContentRoot(@NotNull GradleContentRoot contentRoot, SourceType type, + + /** + * Stores information about given directories at the given content root + * + * @param contentRoot target paths info holder + * @param type type of data located at the given directories + * @param dirs directories which paths should be stored at the given content root + * @throws IllegalArgumentException if specified by {@link GradleContentRoot#storePath(SourceType, String)} + */ + private static void populateContentRoot(@NotNull GradleContentRoot contentRoot, + @NotNull SourceType type, @Nullable Iterable dirs) + throws IllegalArgumentException { if (dirs == null) { return; diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/model/GradleContentRootTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/model/GradleContentRootTest.java new file mode 100644 index 000000000000..72af9c93be0b --- /dev/null +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/model/GradleContentRootTest.java @@ -0,0 +1,16 @@ +package org.jetbrains.plugins.gradle.importing.model; + +import org.junit.Test; + +/** + * @author Denis Zhdanov + * @since 8/31/11 1:33 PM + */ +public class GradleContentRootTest { + + @Test(expected = IllegalArgumentException.class) + public void pathOutOfContentRoot() { + GradleContentRoot contentRoot = new GradleContentRoot("./my-content-root"); + contentRoot.storePath(SourceType.SOURCE, "./my-dir-out-of-content-root"); + } +}