diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/AbstractGradleDependency.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java similarity index 70% rename from plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/AbstractGradleDependency.java rename to plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java index 1ae0a25b0dde..b8bf9767825f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/AbstractGradleDependency.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleDependency.java @@ -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()); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleEntity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleEntity.java new file mode 100644 index 000000000000..4695978a1830 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractGradleEntity.java @@ -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; + } +} \ No newline at end of file diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractNamedGradleEntity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractNamedGradleEntity.java new file mode 100644 index 000000000000..32d63de45a74 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/AbstractNamedGradleEntity.java @@ -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); + } +} 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 e1dc12382ecb..0ba669c8ea02 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,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> myData = new EnumMap>(SourceType.class); + + private final String myRootPath; + + /** + * Creates new GradleContentRootImpl object. + * + * @param rootPath path to the root directory + */ + public GradleContentRoot(@NotNull String rootPath) { + myRootPath = GradleUtil.toCanonicalPath(rootPath); + for (SourceType type : SourceType.values()) { + Set data = new HashSet(); + myData.put(type, data); + } + } /** * @param type target dir type * @return directories of the target type configured for the current content root */ @NotNull - Collection getPaths(@NotNull SourceType type); + public Collection 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> 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> entry : myData.entrySet()) { + for (String path : entry.getValue()) { + result.storePath(entry.getKey(), path); + } + } + return result; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleDependency.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleDependency.java index 77d9a093e03f..70d60d924bff 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleDependency.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleDependency.java @@ -15,4 +15,6 @@ public interface GradleDependency extends GradleEntity { @NotNull DependencyScope getScope(); + + GradleDependency clone(); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleEntity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleEntity.java index a80ded1300f1..fec73b86486d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleEntity.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleEntity.java @@ -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. + *

+ * 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); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibrary.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibrary.java index 4d4fdb3214e8..2c19ab72332c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibrary.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibrary.java @@ -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 myPaths = new HashMap(); + + 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 entry : myPaths.entrySet()) { + result.addPath(entry.getKey(), entry.getValue()); + } + return result; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibraryDependency.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibraryDependency.java index bbea2a30c271..003146dabe34 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibraryDependency.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleLibraryDependency.java @@ -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; + } } 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 e39e099af41f..0919aacc4dc7 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 @@ -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. - *

- * 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 getContentRoots(); +public class GradleModule extends AbstractNamedGradleEntity implements Named { - boolean isInheritProjectCompileOutputPath(); + private static final long serialVersionUID = 1L; + + private final List myContentRoots = new ArrayList(); + private final Map myCompileOutputPaths = new HashMap(); + private final Set myDependencies = new HashSet(); + + private boolean myInheritProjectCompileOutputPath = true; + + public GradleModule(@NotNull String name) { + super(name); + } + + @NotNull + public Collection 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 getDependencies(); + public Collection 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 entry : myCompileOutputPaths.entrySet()) { + result.setCompileOutputPath(entry.getKey(), entry.getValue()); + } + return result; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModuleDependency.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModuleDependency.java index 16d934d56eed..e42b02a7e7de 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModuleDependency.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleModuleDependency.java @@ -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 COMPARATOR = new Comparator() { + public static final Comparator COMPARATOR = new Comparator() { @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; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleProject.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleProject.java index 20efcc82c032..e5ccdf241ff8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleProject.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/GradleProject.java @@ -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. - *

- * 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 myModules = new HashSet(); + private final Set myLibraries = new HashSet(); + + 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 getModules() { + return myModules; + } + @NotNull - LanguageLevel getLanguageLevel(); - void setLanguageLevel(@NotNull LanguageLevel level); + public Set getLibraries() { + return myLibraries; + } + + public boolean addLibrary(@NotNull GradleLibrary library) { + return myLibraries.add(library); + } - @NotNull - Set getModules(); - - @NotNull - Set getLibraries(); - /** - * Offers given library to register for the current project. - * - * @param library library to register - * @return true if no such a library is already registered (given library is stored); - * false 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; + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/Named.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/Named.java index 6e336eb95e12..84c64ab8a003 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/Named.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/Named.java @@ -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 COMPARATOR = new Comparator() { @Override public int compare(Named o1, Named o2) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleContentRootImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleContentRootImpl.java deleted file mode 100644 index b107ef294948..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleContentRootImpl.java +++ /dev/null @@ -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> myData = new EnumMap>(SourceType.class); - private final Map> myViews = new EnumMap>(SourceType.class); - - private final String myRootPath; - - /** - * Creates new GradleContentRootImpl object. - * - * @param rootPath path to the root directory - */ - public GradleContentRootImpl(@NotNull String rootPath) { - myRootPath = new File(rootPath).getAbsolutePath(); - for (SourceType type : SourceType.values()) { - Set data = new HashSet(); - myData.put(type, data); - myViews.put(type, Collections.unmodifiableCollection(data)); - } - } - - @NotNull - @Override - public Collection 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> entry : myData.entrySet()) { - buffer.append(entry.getKey().toString().toLowerCase()).append(": ").append(entry.getValue()).append("; "); - } - buffer.setLength(buffer.length() - 2); - return buffer.toString(); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryDependencyImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryDependencyImpl.java deleted file mode 100644 index e77450a9f0fe..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryDependencyImpl.java +++ /dev/null @@ -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(); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryImpl.java deleted file mode 100644 index c6b059e436e6..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleLibraryImpl.java +++ /dev/null @@ -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 myPaths = new HashMap(); - - 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(); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleDependencyImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleDependencyImpl.java deleted file mode 100644 index d3beb5317ebd..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleDependencyImpl.java +++ /dev/null @@ -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(); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleImpl.java deleted file mode 100644 index a926d15df7d9..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleModuleImpl.java +++ /dev/null @@ -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 myContentRoots = new ArrayList(); - private final Map myCompileOutputPaths = new HashMap(); - private final Set myDependencies = new HashSet(); - private final Collection 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 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 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() - ); - } -} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleProjectImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleProjectImpl.java deleted file mode 100644 index 6d0452f24af4..000000000000 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/model/impl/GradleProjectImpl.java +++ /dev/null @@ -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 myModules = new HashSet(); - private final Set myLibraries = new HashSet(); - - 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 getModules() { - return myModules; - } - - @NotNull - @Override - public Set 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()); - } -} 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 970b59b0d898..6c8a5b89f200 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 @@ -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 myModuleMappings = new HashMap(); private GradleProject myGradleProject; private File myProjectFile; @@ -63,13 +72,11 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder gradleProjects) throws ConfigurationException { - // TODO den implement + public void setList(List gradleProjects) { } @Override public void setOpenProjectSettingsAfter(boolean on) { - // TODO den implement } @Override @@ -143,7 +150,7 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder + *

+   * 
    + *
  1. Get project view from the gradle tooling api without resolving dependencies (downloading libraries);
  2. + *
  3. Allow to adjust project settings before importing;
  4. + *
  5. Create IJ project and modules;
  6. + *
  7. Ask gradle tooling api to resolve library dependencies (download the if necessary);
  8. + *
  9. Configure modules dependencies;
  10. + *
+ *
+ *

+ * {@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 mappings) { + myModuleMappings.clear(); + myModuleMappings.putAll(mappings); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java index 7afa317ca75c..15b2d7242547 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java @@ -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 modules = new ArrayList(project.getModules()); Collections.sort(modules, Named.COMPARATOR); List moduleNodes = new ArrayList(); + Map moduleMappings = new HashMap(); for (GradleModule module : modules) { + GradleModule moduleCopy = module.clone(); + moduleMappings.put(module, moduleCopy); DefaultMutableTreeNode moduleNode = buildNode(module, entity2nodes, counter++); moduleNodes.add(moduleNode); Collection 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 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); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleProjectStructureFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleProjectStructureFactory.java index 92c5ba44be88..70aae71fde31 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleProjectStructureFactory.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleProjectStructureFactory.java @@ -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 target entity business interface - * @return UI-aware proxy of the given entity */ @SuppressWarnings("unchecked") - private static T wrap(@NotNull Class interfaceClass, @NotNull final T delegate, @NotNull final DefaultTreeModel model, - @NotNull final Collection treeNodes) + private static void setupController(@NotNull final GradleEntity entity, @NotNull final DefaultTreeModel model, + @NotNull final Collection 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); + }); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java index fe06bd3bb657..5abe5a925316 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java @@ -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()); 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 bc34e487f7f3..722f275325d8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleProjectResolver.java @@ -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; } 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 a1eef03c2ef9..229e2d5db54c 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 @@ -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> modules = createModules(project, result); + Map> 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> createModules(@NotNull IdeaProject gradleProject, - @NotNull GradleProjectImpl intellijProject) + private static Map> createModules(@NotNull IdeaProject gradleProject, + @NotNull GradleProject intellijProject) throws IllegalStateException { DomainObjectSet gradleModules = gradleProject.getModules(); if (gradleModules == null || gradleModules.isEmpty()) { throw new IllegalStateException("No modules found for the target project: " + gradleProject); } - Map> result = new HashMap>(); + Map> result = new HashMap>(); 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 previouslyParsedModule = result.get(moduleName); + GradleModule intellijModule = new GradleModule(moduleName); + Pair 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(intellijModule, gradleModule)); + result.put(moduleName, new Pair(intellijModule, gradleModule)); intellijProject.addModule(intellijModule); } return result; } - private static void populateModules(@NotNull Iterable> modules, + private static void populateModules(@NotNull Iterable> modules, @NotNull GradleProject intellijProject) throws IllegalStateException { - for (Pair pair : modules) { + for (Pair 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 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 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 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 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 diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java new file mode 100644 index 000000000000..24ae6f7dd426 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -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()); + } +}