IDEA-53476 Gradle integration (Maven's level - dependencies, modules, repositories)

1. Removed unnecessary interfaces from the model hierarchy;
2. Copying project settings from gradle model to the wizard context;
This commit is contained in:
Denis.Zhdanov
2011-08-26 09:15:35 +04:00
parent 3735a98211
commit a374143045
25 changed files with 784 additions and 693 deletions
@@ -1,24 +1,21 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
package org.jetbrains.plugins.gradle.importing.model;
import com.intellij.openapi.roots.DependencyScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.importing.model.GradleDependency;
import java.io.Serializable;
/**
* @author Denis Zhdanov
* @since 8/10/11 6:41 PM
*/
public abstract class AbstractGradleDependency implements GradleDependency, Serializable {
public abstract class AbstractGradleDependency extends AbstractGradleEntity implements GradleDependency {
private static final long serialVersionUID = 1L;
private DependencyScope myScope = DependencyScope.COMPILE;
private boolean myExported;
@NotNull
@Override
@NotNull
public DependencyScope getScope() {
return myScope;
}
@@ -60,4 +57,19 @@ public abstract class AbstractGradleDependency implements GradleDependency, Seri
public String toString() {
return "scope: " + getScope() + ", exported: " + isExported();
}
@Override
public GradleDependency clone() {
try {
return (GradleDependency)super.clone();
}
catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
protected void copyTo(@NotNull AbstractGradleDependency that) {
that.setExported(isExported());
that.setScope(getScope());
}
}
@@ -0,0 +1,49 @@
package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* @author Denis Zhdanov
* @since 8/25/11 3:44 PM
*/
public abstract class AbstractGradleEntity implements GradleEntity {
private static final long serialVersionUID = 1L;
private transient PropertyChangeSupport myPropertyChangeSupport;
public AbstractGradleEntity() {
myPropertyChangeSupport = new PropertyChangeSupport(this);
}
@Override
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
myPropertyChangeSupport.addPropertyChangeListener(listener);
}
protected void firePropertyChange(@NotNull String propertyName, @NotNull Object oldValue, @NotNull Object newValue) {
myPropertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
myPropertyChangeSupport = new PropertyChangeSupport(this);
}
@Override
public int hashCode() {
// !!!! Change this implementation if current class has state. !!!
return 1;
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object obj) {
// !!!! Change this implementation if current class has state. !!!
return true;
}
}
@@ -0,0 +1,48 @@
package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 8/25/11 5:38 PM
*/
public abstract class AbstractNamedGradleEntity extends AbstractGradleEntity implements Named {
private static final long serialVersionUID = 1L;
private String myName;
public AbstractNamedGradleEntity(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getName() {
return myName;
}
@Override
public void setName(@NotNull String name) {
String oldName = myName;
myName = name;
firePropertyChange(Named.NAME_PROPERTY, name, oldName);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myName.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
AbstractNamedGradleEntity that = (AbstractNamedGradleEntity)o;
return myName.equals(that.myName);
}
}
@@ -1,24 +1,96 @@
package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.Collection;
import java.util.*;
/**
* Implementations of this interface are expected to be thread-safe.
*
* @author Denis Zhdanov
* @since 8/9/11 6:39 PM
* @since 8/9/11 6:25 PM
*/
public interface GradleContentRoot extends GradleEntity {
public class GradleContentRoot extends AbstractGradleEntity {
@NotNull
String getRootPath();
private static final long serialVersionUID = 1L;
private final Map<SourceType, Collection<String>> myData = new EnumMap<SourceType, Collection<String>>(SourceType.class);
private final String myRootPath;
/**
* Creates new <code>GradleContentRootImpl</code> object.
*
* @param rootPath path to the root directory
*/
public GradleContentRoot(@NotNull String rootPath) {
myRootPath = GradleUtil.toCanonicalPath(rootPath);
for (SourceType type : SourceType.values()) {
Set<String> data = new HashSet<String>();
myData.put(type, data);
}
}
/**
* @param type target dir type
* @return directories of the target type configured for the current content root
*/
@NotNull
Collection<String> getPaths(@NotNull SourceType type);
public Collection<String> getPaths(@NotNull SourceType type) {
return myData.get(type);
}
public void storePath(@NotNull SourceType type, @NotNull String path) {
myData.get(type).add(GradleUtil.toCanonicalPath(path));
}
@NotNull
public String getRootPath() {
return myRootPath;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myData.hashCode();
result = 31 * result + myRootPath.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleContentRoot that = (GradleContentRoot)o;
if (!myData.equals(that.myData)) return false;
if (!myRootPath.equals(that.myRootPath)) return false;
return true;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
for (Map.Entry<SourceType, Collection<String>> entry : myData.entrySet()) {
buffer.append(entry.getKey().toString().toLowerCase()).append(": ").append(entry.getValue()).append("; ");
}
buffer.setLength(buffer.length() - 2);
return buffer.toString();
}
@Override
public GradleContentRoot clone() {
GradleContentRoot result = new GradleContentRoot(getRootPath());
for (Map.Entry<SourceType, Collection<String>> entry : myData.entrySet()) {
for (String path : entry.getValue()) {
result.storePath(entry.getKey(), path);
}
}
return result;
}
}
@@ -15,4 +15,6 @@ public interface GradleDependency extends GradleEntity {
@NotNull
DependencyScope getScope();
GradleDependency clone();
}
@@ -2,13 +2,27 @@ package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
/**
* Stands for the entity from the 'import from gradle' domain.
* <p/>
* It's assumed to be safe to use implementations of this interface at hash-based containers (i.e. they are expected to correctly
* override {@link #equals(Object)} and {@link #hashCode()}.
*
* @author Denis Zhdanov
* @since 8/12/11 12:50 PM
*/
public interface GradleEntity {
public interface GradleEntity extends Cloneable, Serializable {
/**
* Follows contract of {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
*
* @param listener target listener
*/
void addPropertyChangeListener(@NotNull PropertyChangeListener listener);
void invite(@NotNull GradleEntityVisitor visitor);
}
@@ -1,22 +1,67 @@
package org.jetbrains.plugins.gradle.importing.model;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.Map;
/**
* Implementations of this interface are not obliged to be thread-safe.
*
* @author Denis Zhdanov
* @since 8/24/11 4:49 PM
* @since 8/24/11 4:50 PM
*/
public interface GradleLibrary extends Named, GradleEntity {
public class GradleLibrary extends AbstractNamedGradleEntity implements Named {
private static final long serialVersionUID = 1L;
private final Map<LibraryPathType, String> myPaths = new HashMap<LibraryPathType, String>();
public GradleLibrary(@NotNull String name) {
super(name);
}
/**
* Allows to ask for the target path configured for the current library dependency.
*
* @param type target path type
* @return path to the target path configured for the current library dependency
*/
@Nullable
String getPath(@NotNull LibraryPathType type);
public String getPath(@NotNull LibraryPathType type) {
return myPaths.get(type);
}
public void addPath(@NotNull LibraryPathType type, @NotNull String path) {
myPaths.put(type, GradleUtil.toCanonicalPath(path));
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myPaths.hashCode();
result = 31 * result + super.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleLibrary that = (GradleLibrary)o;
return super.equals(that) && myPaths.equals(that.myPaths);
}
@Override
public String toString() {
return "library: " + getName();
}
@Override
protected GradleLibrary clone() {
GradleLibrary result = new GradleLibrary(getName());
for (Map.Entry<LibraryPathType, String> entry : myPaths.entrySet()) {
result.addPath(entry.getKey(), entry.getValue());
}
return result;
}
}
@@ -3,13 +3,53 @@ package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
/**
* Implementations of this interface are not obliged to be thread-safe.
*
* @author Denis Zhdanov
* @since 8/10/11 6:32 PM
* @since 8/10/11 6:46 PM
*/
public interface GradleLibraryDependency extends GradleDependency {
public class GradleLibraryDependency extends AbstractGradleDependency {
private final GradleLibrary myLibrary;
public GradleLibraryDependency(@NotNull GradleLibrary library) {
myLibrary = library;
}
@NotNull
GradleLibrary getLibrary();
public GradleLibrary getLibrary() {
return myLibrary;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myLibrary.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
GradleLibraryDependency that = (GradleLibraryDependency)o;
return myLibrary.equals(that.myLibrary);
}
@Override
public String toString() {
return super.toString() + ", dependency library: " + getLibrary();
}
@Override
public GradleLibraryDependency clone() {
GradleLibraryDependency result = new GradleLibraryDependency(getLibrary().clone());
copyTo(result);
return result;
}
}
@@ -1,36 +1,132 @@
package org.jetbrains.plugins.gradle.importing.model;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.Collection;
import java.util.*;
/**
* Defines IntelliJ module view to the application configured via gradle.
* <p/>
* Implementations of this interface are not obliged to be thread-safe.
*
* @author Denis Zhdanov
* @since 8/8/11 12:10 PM
* @since 8/8/11 12:11 PM
*/
public interface GradleModule extends Named, GradleEntity {
@NotNull
Collection<? extends GradleContentRoot> getContentRoots();
public class GradleModule extends AbstractNamedGradleEntity implements Named {
boolean isInheritProjectCompileOutputPath();
private static final long serialVersionUID = 1L;
private final List<GradleContentRoot> myContentRoots = new ArrayList<GradleContentRoot>();
private final Map<SourceType, String> myCompileOutputPaths = new HashMap<SourceType, String>();
private final Set<GradleDependency> myDependencies = new HashSet<GradleDependency>();
private boolean myInheritProjectCompileOutputPath = true;
public GradleModule(@NotNull String name) {
super(name);
}
@NotNull
public Collection<GradleContentRoot> getContentRoots() {
return myContentRoots;
}
public void addContentRoot(@NotNull GradleContentRoot contentRoot) {
myContentRoots.add(contentRoot);
}
public boolean isInheritProjectCompileOutputPath() {
return myInheritProjectCompileOutputPath;
}
public void setInheritProjectCompileOutputPath(boolean inheritProjectCompileOutputPath) {
myInheritProjectCompileOutputPath = inheritProjectCompileOutputPath;
}
/**
* Allows to get file system path of the compile output of the source of the target type.
*
*
* @param type target source type
* @return file system path to use for compile output for the target source type;
* {@link GradleProject#getCompileOutputPath() project compile output path} should be used if current module
* doesn't provide specific compile output path
*/
@Nullable
String getCompileOutputPath(@NotNull SourceType type);
public String getCompileOutputPath(@NotNull SourceType type) {
return myCompileOutputPaths.get(type);
}
public void setCompileOutputPath(@NotNull SourceType type, @Nullable String path) {
if (path == null) {
myCompileOutputPaths.remove(type);
return;
}
myCompileOutputPaths.put(type, GradleUtil.toCanonicalPath(path));
}
@NotNull
Collection<GradleDependency> getDependencies();
public Collection<GradleDependency> getDependencies() {
return myDependencies;
}
public void addDependency(@NotNull GradleDependency dependency) {
myDependencies.add(dependency);
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myContentRoots.hashCode();
result = 31 * result + myCompileOutputPaths.hashCode();
result = 31 * result + myDependencies.hashCode();
result = 31 * result + myDependencies.hashCode();
result = 31 * result + (myInheritProjectCompileOutputPath ? 1 : 0);
result = 31 * result + super.hashCode();
// We intentionally don't use dependencies here in order to allow module mappings before and after external libraries
// resolving (downloading)
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleModule that = (GradleModule)o;
if (!super.equals(that)) return false;
if (myInheritProjectCompileOutputPath != that.myInheritProjectCompileOutputPath) return false;
if (!myCompileOutputPaths.equals(that.myCompileOutputPaths)) return false;
if (!myContentRoots.equals(that.myContentRoots)) return false;
// We intentionally don't use dependencies here in order to allow module mappings before and after external libraries
// resolving (downloading)
return true;
}
@Override
public String toString() {
return String.format(
"module '%s'. Content roots: %s; inherit compile output path: %b",
getName(), getContentRoots(), isInheritProjectCompileOutputPath()
);
}
@Override
public GradleModule clone() {
GradleModule result = new GradleModule(getName());
for (GradleContentRoot contentRoot : getContentRoots()) {
result.addContentRoot(contentRoot.clone());
}
for (Map.Entry<SourceType, String> entry : myCompileOutputPaths.entrySet()) {
result.setCompileOutputPath(entry.getKey(), entry.getValue());
}
return result;
}
}
@@ -6,17 +6,58 @@ import java.util.Comparator;
/**
* @author Denis Zhdanov
* @since 8/10/11 6:32 PM
* @since 8/10/11 6:40 PM
*/
public interface GradleModuleDependency extends GradleDependency {
public class GradleModuleDependency extends AbstractGradleDependency {
Comparator<GradleModuleDependency> COMPARATOR = new Comparator<GradleModuleDependency>() {
public static final Comparator<GradleModuleDependency> COMPARATOR = new Comparator<GradleModuleDependency>() {
@Override
public int compare(GradleModuleDependency o1, GradleModuleDependency o2) {
return Named.COMPARATOR.compare(o1.getModule(), o2.getModule());
}
};
private static final long serialVersionUID = 1L;
private final GradleModule myModule;
public GradleModuleDependency(@NotNull GradleModule module) {
myModule = module;
}
@NotNull
GradleModule getModule();
public GradleModule getModule() {
return myModule;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
return myModule.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleModuleDependency that = (GradleModuleDependency)o;
return myModule.equals(that.myModule);
}
@Override
public String toString() {
return super.toString() + ", dependency module: " + getModule();
}
@Override
public GradleModuleDependency clone() {
GradleModuleDependency result = new GradleModuleDependency(getModule().clone());
copyTo(result);
return result;
}
}
@@ -1,42 +1,159 @@
package org.jetbrains.plugins.gradle.importing.model;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.HashSet;
import java.util.Set;
/**
* Defines IntelliJ project view to the application configured via gradle.
* <p/>
* Implementations of this interface are not obliged to be thread-safe.
* Not thread-safe.
*
* @author Denis Zhdanov
* @since 8/8/11 12:05 PM
* @since 8/1/11 1:30 PM
*/
public interface GradleProject extends Named, GradleEntity {
public class GradleProject extends AbstractNamedGradleEntity {
private static final long serialVersionUID = 1L;
private static final LanguageLevel DEFAULT_LANGUAGE_LEVEL = LanguageLevel.JDK_1_6;
private static final JavaSdkVersion DEFAULT_JDK_VERSION = JavaSdkVersion.JDK_1_6;
private final Set<GradleModule> myModules = new HashSet<GradleModule>();
private final Set<GradleLibrary> myLibraries = new HashSet<GradleLibrary>();
private JavaSdkVersion myJdkVersion = DEFAULT_JDK_VERSION;
private LanguageLevel myLanguageLevel = DEFAULT_LANGUAGE_LEVEL;
private String myProjectFileDirectoryPath;
private String myCompileOutputPath;
public GradleProject(@NotNull String projectFileDirectoryPath, @NotNull String compileOutputPath) {
super("unnamed");
myProjectFileDirectoryPath = GradleUtil.toCanonicalPath(projectFileDirectoryPath);
myCompileOutputPath = GradleUtil.toCanonicalPath(compileOutputPath);
}
@NotNull
String getCompileOutputPath();
public String getProjectFileDirectoryPath() {
return myProjectFileDirectoryPath;
}
public void setProjectFileDirectoryPath(@NotNull String projectFileDirectoryPath) {
myProjectFileDirectoryPath = GradleUtil.toCanonicalPath(projectFileDirectoryPath);
}
@NotNull
public String getCompileOutputPath() {
return myCompileOutputPath;
}
public void setCompileOutputPath(@NotNull String compileOutputPath) {
myCompileOutputPath = GradleUtil.toCanonicalPath(compileOutputPath);
}
@NotNull
public JavaSdkVersion getJdkVersion() {
return myJdkVersion;
}
public void setJdkVersion(@NotNull JavaSdkVersion jdkVersion) {
myJdkVersion = jdkVersion;
}
public void setJdkVersion(@Nullable String jdk) {
if (jdk == null) {
return;
}
// TODO den implement
}
@NotNull
public LanguageLevel getLanguageLevel() {
return myLanguageLevel;
}
public void setLanguageLevel(@NotNull LanguageLevel level) {
myLanguageLevel = level;
}
public void setLanguageLevel(@Nullable String languageLevel) {
LanguageLevel level = LanguageLevel.parse(languageLevel);
if (level != null) {
myLanguageLevel = level;
}
}
public void addModule(@NotNull GradleModule module) {
myModules.add(module);
}
@NotNull
String getJdkName();
public Set<? extends GradleModule> getModules() {
return myModules;
}
@NotNull
LanguageLevel getLanguageLevel();
void setLanguageLevel(@NotNull LanguageLevel level);
public Set<? extends GradleLibrary> getLibraries() {
return myLibraries;
}
public boolean addLibrary(@NotNull GradleLibrary library) {
return myLibraries.add(library);
}
@NotNull
Set<? extends GradleModule> getModules();
@NotNull
Set<? extends GradleLibrary> getLibraries();
/**
* Offers given library to register for the current project.
*
* @param library library to register
* @return <code>true</code> if no such a library is already registered (given library is stored);
* <code>false</code> if such a library (in terms of {@link Object#equals(Object)}) is already registered
* within the current project (it's not replaced by the given one then)
*/
boolean addLibrary(@NotNull GradleLibrary library);
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myModules.hashCode();
result = 31 * result + myCompileOutputPath.hashCode();
result = 31 * result + myJdkVersion.hashCode();
result = 31 * result + myLanguageLevel.hashCode();
result = 31 * result + super.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleProject that = (GradleProject)o;
if (!super.equals(that)) return false;
if (!myCompileOutputPath.equals(that.myCompileOutputPath)) return false;
if (!myJdkVersion.equals(that.myJdkVersion)) return false;
if (myLanguageLevel != that.myLanguageLevel) return false;
if (!myModules.equals(that.myModules)) return false;
return true;
}
@Override
public String toString() {
return String.format("project '%s'. Jdk: '%s', language level: '%s', modules: %s",
getName(), getJdkVersion(), getLanguageLevel(), getModules());
}
@Override
public GradleProject clone() {
GradleProject result = new GradleProject(getProjectFileDirectoryPath(), getCompileOutputPath());
result.setName(getName());
result.setJdkVersion(getJdkVersion());
result.setLanguageLevel(getLanguageLevel());
for (GradleModule module : getModules()) {
result.addModule(module.clone());
}
for (GradleLibrary library : getLibraries()) {
result.addLibrary(library.clone());
}
return result;
}
}
@@ -2,6 +2,8 @@ package org.jetbrains.plugins.gradle.importing.model;
import org.jetbrains.annotations.NotNull;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Comparator;
/**
@@ -10,6 +12,9 @@ import java.util.Comparator;
*/
public interface Named {
/** Key of the {@link #getName() name} property to use with {@link PropertyChangeListener#propertyChange(PropertyChangeEvent)}. */
String NAME_PROPERTY = "Name";
Comparator<Named> COMPARATOR = new Comparator<Named>() {
@Override
public int compare(Named o1, Named o2) {
@@ -1,89 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.importing.model.GradleContentRoot;
import org.jetbrains.plugins.gradle.importing.model.GradleEntityVisitor;
import org.jetbrains.plugins.gradle.importing.model.SourceType;
import java.io.File;
import java.io.Serializable;
import java.util.*;
/**
* @author Denis Zhdanov
* @since 8/9/11 6:25 PM
*/
public class GradleContentRootImpl implements Serializable, GradleContentRoot {
private static final long serialVersionUID = 1L;
private final Map<SourceType, Collection<String>> myData = new EnumMap<SourceType, Collection<String>>(SourceType.class);
private final Map<SourceType, Collection<String>> myViews = new EnumMap<SourceType, Collection<String>>(SourceType.class);
private final String myRootPath;
/**
* Creates new <code>GradleContentRootImpl</code> object.
*
* @param rootPath path to the root directory
*/
public GradleContentRootImpl(@NotNull String rootPath) {
myRootPath = new File(rootPath).getAbsolutePath();
for (SourceType type : SourceType.values()) {
Set<String> data = new HashSet<String>();
myData.put(type, data);
myViews.put(type, Collections.unmodifiableCollection(data));
}
}
@NotNull
@Override
public Collection<String> getPaths(@NotNull SourceType type) {
return myViews.get(type);
}
public void storePath(@NotNull SourceType type, @NotNull String path) {
myData.get(type).add(new File(path).getAbsolutePath());
}
@NotNull
@Override
public String getRootPath() {
return myRootPath;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myData.hashCode();
result = 31 * result + myRootPath.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleContentRootImpl that = (GradleContentRootImpl)o;
if (!myData.equals(that.myData)) return false;
if (!myRootPath.equals(that.myRootPath)) return false;
return true;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
for (Map.Entry<SourceType, Collection<String>> entry : myData.entrySet()) {
buffer.append(entry.getKey().toString().toLowerCase()).append(": ").append(entry.getValue()).append("; ");
}
buffer.setLength(buffer.length() - 2);
return buffer.toString();
}
}
@@ -1,54 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.importing.model.GradleEntityVisitor;
import org.jetbrains.plugins.gradle.importing.model.GradleLibrary;
import org.jetbrains.plugins.gradle.importing.model.GradleLibraryDependency;
import java.io.Serializable;
/**
* @author Denis Zhdanov
* @since 8/10/11 6:46 PM
*/
public class GradleLibraryDependencyImpl extends AbstractGradleDependency implements GradleLibraryDependency, Serializable {
private final GradleLibrary myLibrary;
public GradleLibraryDependencyImpl(@NotNull GradleLibrary library) {
myLibrary = library;
}
@NotNull
@Override
public GradleLibrary getLibrary() {
return myLibrary;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myLibrary.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
GradleLibraryDependencyImpl that = (GradleLibraryDependencyImpl)o;
return myLibrary.equals(that.myLibrary);
}
@Override
public String toString() {
return super.toString() + ", dependency library: " + getLibrary();
}
}
@@ -1,76 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.importing.model.GradleEntityVisitor;
import org.jetbrains.plugins.gradle.importing.model.GradleLibrary;
import org.jetbrains.plugins.gradle.importing.model.LibraryPathType;
import java.io.File;
import java.io.Serializable;
import java.util.Map;
/**
* @author Denis Zhdanov
* @since 8/24/11 4:50 PM
*/
public class GradleLibraryImpl implements GradleLibrary, Serializable {
private static final long serialVersionUID = 1L;
private final Map<LibraryPathType, String> myPaths = new HashMap<LibraryPathType, String>();
private String myName;
public GradleLibraryImpl(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getName() {
return myName;
}
@Override
public void setName(@NotNull String name) {
myName = name;
}
@Nullable
@Override
public String getPath(@NotNull LibraryPathType type) {
return myPaths.get(type);
}
public void addPath(@NotNull LibraryPathType type, @NotNull String path) {
myPaths.put(type, new File(path).getAbsolutePath());
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myPaths.hashCode();
result = 31 * result + myName.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleLibraryImpl that = (GradleLibraryImpl)o;
return myName.equals(that.myName) && myPaths.equals(that.myPaths);
}
@Override
public String toString() {
return "library: " + getName();
}
}
@@ -1,53 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.importing.model.GradleEntityVisitor;
import org.jetbrains.plugins.gradle.importing.model.GradleModule;
import org.jetbrains.plugins.gradle.importing.model.GradleModuleDependency;
import java.io.Serializable;
/**
* @author Denis Zhdanov
* @since 8/10/11 6:40 PM
*/
public class GradleModuleDependencyImpl extends AbstractGradleDependency implements GradleModuleDependency, Serializable {
private static final long serialVersionUID = 1L;
private final GradleModule myModule;
public GradleModuleDependencyImpl(@NotNull GradleModule module) {
myModule = module;
}
@NotNull
@Override
public GradleModule getModule() {
return myModule;
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
return myModule.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleModuleDependencyImpl that = (GradleModuleDependencyImpl)o;
return myModule.equals(that.myModule);
}
@Override
public String toString() {
return super.toString() + ", dependency module: " + getModule();
}
}
@@ -1,127 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.importing.model.*;
import java.io.File;
import java.io.Serializable;
import java.util.*;
/**
* @author Denis Zhdanov
* @since 8/8/11 12:11 PM
*/
public class GradleModuleImpl implements GradleModule, Serializable {
private static final long serialVersionUID = 1L;
private final List<GradleContentRoot> myContentRoots = new ArrayList<GradleContentRoot>();
private final Map<SourceType, String> myCompileOutputPaths = new HashMap<SourceType, String>();
private final Set<GradleDependency> myDependencies = new HashSet<GradleDependency>();
private final Collection<GradleDependency> myDependenciesView = Collections.unmodifiableCollection(myDependencies);
private boolean myInheritProjectCompileOutputPath = true;
private String myName;
public GradleModuleImpl(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getName() {
return myName;
}
@Override
public void setName(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public Collection<GradleContentRoot> getContentRoots() {
return myContentRoots;
}
public void addContentRoot(@NotNull GradleContentRoot contentRoot) {
myContentRoots.add(contentRoot);
}
@Override
public boolean isInheritProjectCompileOutputPath() {
return myInheritProjectCompileOutputPath;
}
public void setInheritProjectCompileOutputPath(boolean inheritProjectCompileOutputPath) {
myInheritProjectCompileOutputPath = inheritProjectCompileOutputPath;
}
@Nullable
@Override
public String getCompileOutputPath(@NotNull SourceType type) {
return myCompileOutputPaths.get(type);
}
public void setCompileOutputPath(@NotNull SourceType type, @Nullable String path) {
if (path == null) {
myCompileOutputPaths.remove(type);
return;
}
myCompileOutputPaths.put(type, new File(path).getAbsolutePath());
}
@NotNull
@Override
public Collection<GradleDependency> getDependencies() {
return myDependenciesView;
}
public void addDependency(@NotNull GradleDependency dependency) {
myDependencies.add(dependency);
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myContentRoots.hashCode();
result = 31 * result + myCompileOutputPaths.hashCode();
result = 31 * result + myDependencies.hashCode();
result = 31 * result + myDependenciesView.hashCode();
result = 31 * result + (myInheritProjectCompileOutputPath ? 1 : 0);
result = 31 * result + myName.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleModuleImpl that = (GradleModuleImpl)o;
if (myInheritProjectCompileOutputPath != that.myInheritProjectCompileOutputPath) return false;
if (!myCompileOutputPaths.equals(that.myCompileOutputPaths)) return false;
if (!myContentRoots.equals(that.myContentRoots)) return false;
if (!myDependencies.equals(that.myDependencies)) return false;
if (!myDependenciesView.equals(that.myDependenciesView)) return false;
if (!myName.equals(that.myName)) return false;
return true;
}
@Override
public String toString() {
return String.format(
"module '%s'. Content roots: %s; inherit compile output path: %b",
getName(), getContentRoots(), isInheritProjectCompileOutputPath()
);
}
}
@@ -1,145 +0,0 @@
package org.jetbrains.plugins.gradle.importing.model.impl;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.importing.model.GradleEntityVisitor;
import org.jetbrains.plugins.gradle.importing.model.GradleLibrary;
import org.jetbrains.plugins.gradle.importing.model.GradleModule;
import org.jetbrains.plugins.gradle.importing.model.GradleProject;
import java.io.File;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* Not thread-safe.
*
* @author Denis Zhdanov
* @since 8/1/11 1:30 PM
*/
public class GradleProjectImpl implements Serializable, GradleProject {
private static final long serialVersionUID = 1L;
private static final LanguageLevel DEFAULT_LANGUAGE_LEVEL = LanguageLevel.JDK_1_6;
private static final String DEFAULT_JDK = "1.6";
private final Set<GradleModule> myModules = new HashSet<GradleModule>();
private final Set<GradleLibrary> myLibraries = new HashSet<GradleLibrary>();
private final String myCompileOutputPath;
private String myName = "unnamed";
private String myJdk = DEFAULT_JDK;
private LanguageLevel myLanguageLevel = DEFAULT_LANGUAGE_LEVEL;
public GradleProjectImpl(@NotNull String compileOutputPath) {
myCompileOutputPath = new File(compileOutputPath).getAbsolutePath();
}
@NotNull
@Override
public String getName() {
return myName;
}
public void setName(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getCompileOutputPath() {
return myCompileOutputPath;
}
@NotNull
@Override
public String getJdkName() {
return myJdk;
}
public void setJdk(@Nullable String jdk) {
if (jdk != null) {
myJdk = jdk;
}
}
@NotNull
@Override
public LanguageLevel getLanguageLevel() {
return myLanguageLevel;
}
@Override
public void setLanguageLevel(@NotNull LanguageLevel level) {
myLanguageLevel = level;
}
public void setLanguageLevel(@Nullable String languageLevel) {
LanguageLevel level = LanguageLevel.parse(languageLevel);
if (level != null) {
myLanguageLevel = level;
}
}
public void addModule(@NotNull GradleModule module) {
myModules.add(module);
}
@NotNull
@Override
public Set<? extends GradleModule> getModules() {
return myModules;
}
@NotNull
@Override
public Set<? extends GradleLibrary> getLibraries() {
return myLibraries;
}
@Override
public boolean addLibrary(@NotNull GradleLibrary library) {
return myLibraries.add(library);
}
@Override
public void invite(@NotNull GradleEntityVisitor visitor) {
visitor.visit(this);
}
@Override
public int hashCode() {
int result = myModules.hashCode();
result = 31 * result + myCompileOutputPath.hashCode();
result = 31 * result + myName.hashCode();
result = 31 * result + myJdk.hashCode();
result = 31 * result + myLanguageLevel.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GradleProjectImpl that = (GradleProjectImpl)o;
if (!myCompileOutputPath.equals(that.myCompileOutputPath)) return false;
if (!myJdk.equals(that.myJdk)) return false;
if (myLanguageLevel != that.myLanguageLevel) return false;
if (!myModules.equals(that.myModules)) return false;
if (!myName.equals(that.myName)) return false;
return true;
}
@Override
public String toString() {
return String.format("project '%s'. Jdk: '%s', language level: '%s', modules: %s",
getName(), getJdkName(), getLanguageLevel(), getModules());
}
}
@@ -11,11 +11,16 @@ 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.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.packaging.artifacts.ModifiableArtifactModel;
import com.intellij.projectImport.ProjectImportBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.importing.model.GradleEntity;
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;
@@ -26,7 +31,9 @@ import org.jetbrains.plugins.gradle.util.GradleLog;
import javax.swing.*;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* GoF builder for gradle-backed projects.
@@ -39,6 +46,8 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
private static final String GRADLE_IMPORT_ROOT_KEY = "gradle.import.root";
/** @see #setModuleMappings(Map) */
private final Map<GradleModule/*origin*/, GradleModule/*adjusted*/> myModuleMappings = new HashMap<GradleModule, GradleModule>();
private GradleProject myGradleProject;
private File myProjectFile;
@@ -63,13 +72,11 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
}
@Override
public void setList(List<GradleProject> gradleProjects) throws ConfigurationException {
// TODO den implement
public void setList(List<GradleProject> gradleProjects) {
}
@Override
public void setOpenProjectSettingsAfter(boolean on) {
// TODO den implement
}
@Override
@@ -143,7 +150,7 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
GradleApiFacadeManager manager = ServiceManager.getService(getProject(), GradleApiFacadeManager.class);
try {
GradleProjectResolver resolver = manager.getFacade().getResolver();
myGradleProject = resolver.resolveProjectInfo(myProjectFile.getAbsolutePath());
myGradleProject = resolver.resolveProjectInfo(myProjectFile.getAbsolutePath(), false);
}
catch (Exception e) {
// Ignore here because it will be reported on method exit.
@@ -167,4 +174,61 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
public GradleProject getGradleProject() {
return myGradleProject;
}
@Override
public boolean isSuitableSdk(Sdk sdk) {
JavaSdk javaSdk = JavaSdk.getInstance();
if (sdk == null || sdk.getSdkType() != javaSdk) {
return false;
}
if (myGradleProject == null) {
return true;
}
JavaSdkVersion version = javaSdk.getVersion(sdk);
if (version == null) {
return false;
}
return version.getMaxLanguageLevel().isAtLeast(myGradleProject.getLanguageLevel());
}
/**
* Applies gradle-plugin-specific settings like project files location etc to the given context.
*
* @param context storage for the project/module settings.
*/
public void applyProjectSettings(@NotNull WizardContext context) {
if (myGradleProject == null) {
assert false;
return;
}
context.setProjectName(myGradleProject.getName());
context.setProjectFileDirectory(myGradleProject.getProjectFileDirectoryPath());
context.setCompilerOutputDirectory(myGradleProject.getCompileOutputPath());
}
/**
* The whole import sequence looks like below:
* <p/>
* <pre>
* <ol>
* <li>Get project view from the gradle tooling api without resolving dependencies (downloading libraries);</li>
* <li>Allow to adjust project settings before importing;</li>
* <li>Create IJ project and modules;</li>
* <li>Ask gradle tooling api to resolve library dependencies (download the if necessary);</li>
* <li>Configure modules dependencies;</li>
* </ol>
* </pre>
* <p/>
* {@link GradleEntity} guarantees correct {@link #equals(Object)}/{@link #hashCode()} implementation, so, we expect
* to get {@link GradleModule modules} that are the same in terms of {@link #equals(Object)} on subsequent calls. However,
* end-user is allowed to change their settings before the importing (e.g. module name), so, we need to map modules with
* resolved libraries to the modules from project 'view'. That's why end-user adjusts settings of the cloned modules.
* Given collection holds mappings between them.
*
* @param mappings origin-adjusted modules mappings
*/
public void setModuleMappings(@NotNull Map<GradleModule/*origin module*/, GradleModule/*adjusted module*/> mappings) {
myModuleMappings.clear();
myModuleMappings.putAll(mappings);
}
}
@@ -34,11 +34,10 @@ import java.util.List;
public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWizardStep {
private static final String EMPTY_CARD_NAME = "EMPTY";
private final GradleProjectStructureFactory myFactory = GradleProjectStructureFactory.INSTANCE;
private final JPanel myComponent = new JPanel(new GridLayout(1, 2));
private final DefaultTreeModel myTreeModel =
new DefaultTreeModel(new DefaultMutableTreeNode("unnamed"));
private final DefaultTreeModel myTreeModel = new DefaultTreeModel(new DefaultMutableTreeNode("unnamed"));
private final Tree myTree = new Tree(myTreeModel);
private final CardLayout mySettingsCardLayout = new CardLayout();
private final JPanel mySettingsPanel = new JPanel(mySettingsCardLayout);
@@ -151,9 +150,7 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
return;
}
myCards.clear();
mySettingsPanel.removeAll();
mySettingsPanel.add(new JPanel(), EMPTY_CARD_NAME);
clear();
GradleProject project = getBuilder().getGradleProject();
if (project == null) {
@@ -171,8 +168,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
List<GradleModule> modules = new ArrayList<GradleModule>(project.getModules());
Collections.sort(modules, Named.COMPARATOR);
List<MutableTreeNode> moduleNodes = new ArrayList<MutableTreeNode>();
Map<GradleModule, GradleModule> moduleMappings = new HashMap<GradleModule, GradleModule>();
for (GradleModule module : modules) {
GradleModule moduleCopy = module.clone();
moduleMappings.put(module, moduleCopy);
DefaultMutableTreeNode moduleNode = buildNode(module, entity2nodes, counter++);
moduleNodes.add(moduleNode);
Collection<GradleDependency> dependencies = module.getDependencies();
@@ -235,6 +235,8 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
myTree.expandPath(new TreePath(modulesNode.getPath()));
myTree.expandPath(new TreePath(librariesNode.getPath()));
}
getBuilder().setModuleMappings(moduleMappings);
}
private <T extends GradleEntity> DefaultMutableTreeNode buildNode(
@@ -286,10 +288,17 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
return false;
}
}
getBuilder().applyProjectSettings(getContext());
return true;
}
@Override
public void updateDataModel() {
}
private void clear() {
myCards.clear();
mySettingsPanel.removeAll();
mySettingsPanel.add(new JPanel(), EMPTY_CARD_NAME);
}
}
@@ -7,9 +7,8 @@ import org.jetbrains.plugins.gradle.importing.model.*;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
/**
@@ -92,12 +91,14 @@ public class GradleProjectStructureFactory {
entity.invite(new GradleEntityVisitor() {
@Override
public void visit(@NotNull GradleProject project) {
setupController(project, treeModel, treeNodes);
result.set(new GradleProjectSettings(project));
}
@Override
public void visit(@NotNull GradleModule module) {
result.set(new GradleModuleSettings(wrap(GradleModule.class, module, treeModel, treeNodes)));
setupController(module, treeModel, treeNodes);
result.set(new GradleModuleSettings(module));
}
@Override
@@ -108,7 +109,8 @@ public class GradleProjectStructureFactory {
@Override
public void visit(@NotNull GradleLibrary library) {
result.set(new GradleLibrarySettings(wrap(GradleLibrary.class, library, treeModel, treeNodes)));
setupController(library, treeModel, treeNodes);
result.set(new GradleLibrarySettings(library));
}
@Override
@@ -125,42 +127,28 @@ public class GradleProjectStructureFactory {
}
/**
* Wraps target entity into proxy that handles logic of UI update for the corresponding nodes.
* Configures controller that delegates entity state change to all corresponding nodes.
*
* @param interfaceClass target entity business interface
* @param delegate target entity to wrap
* @param entity target entity to wrap
* @param model model of the target tree
* @param treeNodes tree nodes that represent the given entity
* @param <T> target entity business interface
* @return UI-aware proxy of the given entity
*/
@SuppressWarnings("unchecked")
private static <T> T wrap(@NotNull Class<T> interfaceClass, @NotNull final T delegate, @NotNull final DefaultTreeModel model,
@NotNull final Collection<GradleProjectStructureNode> treeNodes)
private static void setupController(@NotNull final GradleEntity entity, @NotNull final DefaultTreeModel model,
@NotNull final Collection<GradleProjectStructureNode> treeNodes)
{
final Method triggerMethod;
try {
triggerMethod = Named.class.getMethod("setName", String.class);
}
catch (NoSuchMethodException e) {
// Never expect to be here.
throw new RuntimeException("Unexpected exception occurred", e);
}
InvocationHandler invocationHandler = new InvocationHandler() {
entity.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(delegate, args);
if (method.equals(triggerMethod)) {
for (GradleProjectStructureNode node : treeNodes) {
node.getDescriptor().setName(args[0].toString());
model.nodeChanged(node);
}
public void propertyChange(PropertyChangeEvent evt) {
if (!Named.NAME_PROPERTY.equals(evt.getPropertyName())) {
return;
}
for (GradleProjectStructureNode node : treeNodes) {
node.getDescriptor().setName(evt.getNewValue().toString());
model.nodeChanged(node);
}
return result;
}
};
ClassLoader classLoader = GradleProjectStructureFactory.class.getClassLoader();
Class<?>[] interfaces = {interfaceClass};
return (T)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
});
}
}
@@ -19,6 +19,7 @@ import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.JdkUtil;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SimpleJavaSdkType;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.text.StringUtil;
@@ -119,6 +120,7 @@ public class GradleApiFacadeManager {
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(LanguageLevel.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(PsiBundle.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(Alarm.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(DependencyScope.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(getClass()), classPath);
for (File library : gradleLibraries) {
classPath.add(library.getAbsolutePath());
@@ -22,11 +22,13 @@ public interface GradleProjectResolver extends Remote {
* command-line switch. So, we want to treat the argument as a target project file name when that is supported.
*
* @param projectPath absolute path to the gradle project file
* @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 IllegalArgumentException if given path doesn't point to directory that contains gradle project
* @throws IllegalStateException if it's not possible to resolve target project info
*/
@NotNull
GradleProject resolveProjectInfo(@NotNull String projectPath) throws RemoteException, IllegalArgumentException, IllegalStateException;
GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries)
throws RemoteException, IllegalArgumentException, IllegalStateException;
}
@@ -4,6 +4,7 @@ import com.intellij.execution.rmi.RemoteObject;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.HashMap;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;
@@ -12,12 +13,14 @@ 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.importing.model.impl.*;
import org.jetbrains.plugins.gradle.importing.model.GradleLibraryDependency;
import org.jetbrains.plugins.gradle.importing.model.GradleProject;
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.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleLog;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.io.File;
import java.rmi.RemoteException;
@@ -40,9 +43,9 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
@NotNull
@Override
public GradleProject resolveProjectInfo(@NotNull String projectPath) throws RemoteException {
public GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) throws RemoteException {
try {
return doResolve(projectPath);
return doResolve(projectPath, downloadLibraries);
}
catch (Throwable e) {
throw new IllegalStateException(GradleBundle.message("gradle.import.text.error.resolve.generic", projectPath), e);
@@ -50,40 +53,39 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
}
@NotNull
private GradleProject doResolve(@NotNull String projectPath) {
private GradleProject doResolve(@NotNull String projectPath, boolean downloadLibraries) {
ProjectConnection connection = getConnection(projectPath);
IdeaProject project = connection.getModel(IdeaProject.class);
// TODO den use OfflineIdeaProject as soon as gradle guys provide support for non-resolved libraries there.
//OfflineIdeaProject project = connection.getModel(OfflineIdeaProject.class);
GradleProjectImpl result = populateProject(project, projectPath);
IdeaProject project = connection.getModel(downloadLibraries ? IdeaProject.class : OfflineIdeaProject.class);
GradleProject result = populateProject(project, projectPath);
// We need two different steps ('create' and 'populate') in order to handle module dependencies, i.e. when one module is
// configured to be dependency for another one, corresponding dependency module object should be available during
// populating dependent module object.
Map<String, Pair<GradleModuleImpl, IdeaModule>> modules = createModules(project, result);
Map<String, Pair<GradleModule, IdeaModule>> modules = createModules(project, result);
populateModules(modules.values(), result);
return result;
}
private static GradleProjectImpl populateProject(@NotNull IdeaProject project, @NotNull String projectPath) {
// TODO den retrieve the value from the gradle api as soon as it's ready
GradleProjectImpl result = new GradleProjectImpl(new File(projectPath).getParentFile().getAbsolutePath() + "/out");
private static GradleProject populateProject(@NotNull IdeaProject project, @NotNull String projectPath) {
String projectDirPath = GradleUtil.toCanonicalPath(PathUtil.getParentPath(projectPath));
// Gradle API doesn't expose project compile output path yet.
GradleProject result = new GradleProject(projectDirPath, projectDirPath + "/out");
result.setName(project.getName());
result.setJdk(project.getJdkName());
result.setJdkVersion(project.getJdkName());
result.setLanguageLevel(project.getLanguageLevel().getLevel());
return result;
}
@NotNull
private static Map<String, Pair<GradleModuleImpl, IdeaModule>> createModules(@NotNull IdeaProject gradleProject,
@NotNull GradleProjectImpl intellijProject)
private static Map<String, Pair<GradleModule, IdeaModule>> createModules(@NotNull IdeaProject gradleProject,
@NotNull GradleProject intellijProject)
throws IllegalStateException
{
DomainObjectSet<? extends IdeaModule> gradleModules = gradleProject.getModules();
if (gradleModules == null || gradleModules.isEmpty()) {
throw new IllegalStateException("No modules found for the target project: " + gradleProject);
}
Map<String, Pair<GradleModuleImpl, IdeaModule>> result = new HashMap<String, Pair<GradleModuleImpl, IdeaModule>>();
Map<String, Pair<GradleModule, IdeaModule>> result = new HashMap<String, Pair<GradleModule, IdeaModule>>();
for (IdeaModule gradleModule : gradleModules) {
if (gradleModule == null) {
continue;
@@ -92,29 +94,29 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
if (moduleName == null) {
throw new IllegalStateException("Module with undefined name detected: " + gradleModule);
}
GradleModuleImpl intellijModule = new GradleModuleImpl(moduleName);
Pair<GradleModuleImpl, IdeaModule> previouslyParsedModule = result.get(moduleName);
GradleModule intellijModule = new GradleModule(moduleName);
Pair<GradleModule, IdeaModule> previouslyParsedModule = result.get(moduleName);
if (previouslyParsedModule != null) {
throw new IllegalStateException(
String.format("Modules with duplicate name (%s) detected: '%s' and '%s'", moduleName, intellijModule, previouslyParsedModule)
);
}
result.put(moduleName, new Pair<GradleModuleImpl, IdeaModule>(intellijModule, gradleModule));
result.put(moduleName, new Pair<GradleModule, IdeaModule>(intellijModule, gradleModule));
intellijProject.addModule(intellijModule);
}
return result;
}
private static void populateModules(@NotNull Iterable<Pair<GradleModuleImpl, IdeaModule>> modules,
private static void populateModules(@NotNull Iterable<Pair<GradleModule, IdeaModule>> modules,
@NotNull GradleProject intellijProject)
throws IllegalStateException
{
for (Pair<GradleModuleImpl, IdeaModule> pair : modules) {
for (Pair<GradleModule, IdeaModule> pair : modules) {
populateModule(pair.second, pair.first, intellijProject);
}
}
private static void populateModule(@NotNull IdeaModule gradleModule, @NotNull GradleModuleImpl intellijModule,
private static void populateModule(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule,
@NotNull GradleProject intellijProject)
throws IllegalStateException
{
@@ -123,7 +125,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
populateDependencies(gradleModule, intellijModule, intellijProject);
}
private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModuleImpl intellijModule) {
private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule) {
DomainObjectSet<? extends IdeaContentRoot> contentRoots = gradleModule.getContentRoots();
if (contentRoots == null) {
return;
@@ -136,7 +138,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
if (rootDirectory == null) {
continue;
}
GradleContentRootImpl intellijContentRoot = new GradleContentRootImpl(rootDirectory.getAbsolutePath());
GradleContentRoot intellijContentRoot = new GradleContentRoot(rootDirectory.getAbsolutePath());
populateContentRoot(intellijContentRoot, SourceType.SOURCE, gradleContentRoot.getSourceDirectories());
populateContentRoot(intellijContentRoot, SourceType.TEST, gradleContentRoot.getTestDirectories());
Set<File> excluded = gradleContentRoot.getExcludeDirectories();
@@ -149,7 +151,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
}
}
private static void populateContentRoot(@NotNull GradleContentRootImpl contentRoot, SourceType type,
private static void populateContentRoot(@NotNull GradleContentRoot contentRoot, SourceType type,
@Nullable Iterable<? extends IdeaSourceDirectory> dirs)
{
if (dirs == null) {
@@ -161,7 +163,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
}
private static void populateCompileOutputSettings(@Nullable IdeaCompilerOutput gradleSettings,
@NotNull GradleModuleImpl intellijModule)
@NotNull GradleModule intellijModule)
{
if (gradleSettings == null) {
return;
@@ -179,7 +181,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
}
}
private static void populateDependencies(@NotNull IdeaModule gradleModule, @NotNull GradleModuleImpl intellijModule,
private static void populateDependencies(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule,
@NotNull GradleProject intellijProject)
{
DomainObjectSet<? extends IdeaDependency> dependencies = gradleModule.getDependencies();
@@ -233,7 +235,7 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
for (GradleModule gradleModule : intellijProject.getModules()) {
registeredModuleNames.add(gradleModule.getName());
if (gradleModule.getName().equals(moduleName)) {
return new GradleModuleDependencyImpl(gradleModule);
return new GradleModuleDependency(gradleModule);
}
}
throw new IllegalStateException(String.format(
@@ -254,8 +256,8 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
));
}
// TODO den use library name from gradle api when it's ready
GradleLibraryImpl library = new GradleLibraryImpl(FileUtil.getNameWithoutExtension(binaryPath));
// Gradle API doesn't provide library name at the moment.
GradleLibrary library = new GradleLibrary(FileUtil.getNameWithoutExtension(binaryPath));
library.addPath(LibraryPathType.BINARY, binaryPath.getAbsolutePath());
File sourcePath = dependency.getSource();
@@ -271,12 +273,12 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
if (!intellijProject.addLibrary(library)) {
for (GradleLibrary registeredLibrary : intellijProject.getLibraries()) {
if (registeredLibrary.equals(library)) {
return new GradleLibraryDependencyImpl(registeredLibrary);
return new GradleLibraryDependency(registeredLibrary);
}
}
}
return new GradleLibraryDependencyImpl(library);
return new GradleLibraryDependency(library);
}
@Nullable
@@ -0,0 +1,27 @@
package org.jetbrains.plugins.gradle.util;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* Holds miscellaneous utility methods.
*
* @author Denis Zhdanov
* @since 8/25/11 1:19 PM
*/
public class GradleUtil {
private GradleUtil() {
}
/**
* @param path target path
* @return absolute path that points to the same location as the given one and that uses only slashes
*/
@NotNull
public static String toCanonicalPath(@NotNull String path) {
return PathUtil.getCanonicalPath(new File(path).getAbsolutePath());
}
}