IDEA-127046 Gradle: processing resources

This commit is contained in:
Vladislav.Soroka
2014-07-31 17:05:20 +04:00
parent 6859788abf
commit 8ffd435983
74 changed files with 4484 additions and 118 deletions
+5
View File
@@ -336,6 +336,10 @@ public def layoutCommunityPlugins(String home) {
}
layoutPlugin("gradle") {
jar("gradle-jps-plugin.jar") {
module("gradle-jps-plugin")
}
jar("gradle-tooling-extension-api.jar") {
module("gradle-tooling-extension-api")
}
@@ -753,6 +757,7 @@ def layoutJps(String home, String targetDir, String buildNumber, Closure additio
jar("maven-jps-plugin.jar") { module("maven-jps-plugin") }
jar("gradle-jps-plugin.jar") { module("gradle-jps-plugin") }
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/lib") {include(name: "plexus-utils-*.jar")}
jar("eclipse-jps-plugin.jar") {
@@ -68,6 +68,18 @@ public class DataNode<T> implements Serializable {
return result;
}
@NotNull
public <T> DataNode<T> createOrReplaceChild(@NotNull Key<T> key, @NotNull T data) {
for (Iterator<DataNode<?>> iterator = myChildren.iterator(); iterator.hasNext(); ) {
DataNode<?> child = iterator.next();
if (child.getKey().equals(key)) {
iterator.remove();
break;
}
}
return createChild(key, data);
}
@NotNull
public Key<T> getKey() {
return myKey;
@@ -0,0 +1,62 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 7/22/2014
*/
public class DefaultExternalFilter implements ExternalFilter {
private static final long serialVersionUID = 1L;
@NotNull
private String myFilterType;
@NotNull
private String myPropertiesAsJsonMap;
public DefaultExternalFilter() {
myPropertiesAsJsonMap = "";
myFilterType = "";
}
public DefaultExternalFilter(ExternalFilter filter) {
myPropertiesAsJsonMap = filter.getPropertiesAsJsonMap();
myFilterType = filter.getFilterType();
}
@NotNull
@Override
public String getFilterType() {
return myFilterType;
}
public void setFilterType(@NotNull String filterType) {
myFilterType = filterType;
}
@Override
@NotNull
public String getPropertiesAsJsonMap() {
return myPropertiesAsJsonMap;
}
public void setPropertiesAsJsonMap(@NotNull String propertiesAsJsonMap) {
myPropertiesAsJsonMap = propertiesAsJsonMap;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 7/16/2014
*/
public class DefaultExternalPlugin implements ExternalPlugin {
private static final long serialVersionUID = 1L;
@NotNull
private String myId;
public DefaultExternalPlugin() {
}
public DefaultExternalPlugin(ExternalPlugin plugin) {
myId = plugin.getId();
}
@NotNull
@Override
public String getId() {
return myId;
}
public void setId(@NotNull String id) {
myId = id;
}
}
@@ -0,0 +1,243 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public class DefaultExternalProject implements ExternalProject {
private static final long serialVersionUID = 1L;
@NotNull
private String myName;
@NotNull
private String myQName;
@Nullable
private String myDescription;
@NotNull
private String myGroup;
@NotNull
private String myVersion;
@NotNull
private Map<String, ExternalProject> myChildProjects;
@NotNull
private File myProjectDir;
@NotNull
private File myBuildDir;
@Nullable
private File myBuildFile;
@NotNull
private Map<String, ExternalTask> myTasks;
@NotNull
private Map<String, ?> myProperties;
@NotNull
private Map<String, ExternalSourceSet> mySourceSets;
@NotNull
private String myExternalSystemId;
@NotNull
private Map<String, ExternalPlugin> myPlugins;
public DefaultExternalProject() {
myChildProjects = new HashMap<String, ExternalProject>();
myTasks = new HashMap<String, ExternalTask>();
myProperties = new HashMap<String, Object>();
mySourceSets = new HashMap<String, ExternalSourceSet>();
myPlugins = new HashMap<String, ExternalPlugin>();
}
public DefaultExternalProject(@NotNull ExternalProject externalProject) {
this();
myName = externalProject.getName();
myQName = externalProject.getQName();
myVersion = externalProject.getVersion();
myGroup = externalProject.getGroup();
myDescription = externalProject.getDescription();
myProjectDir = externalProject.getProjectDir();
myBuildDir = externalProject.getBuildDir();
myBuildFile = externalProject.getBuildFile();
myExternalSystemId = externalProject.getExternalSystemId();
for (Map.Entry<String, ExternalProject> entry : externalProject.getChildProjects().entrySet()) {
myChildProjects.put(entry.getKey(), new DefaultExternalProject(entry.getValue()));
}
for (Map.Entry<String, ExternalTask> entry : externalProject.getTasks().entrySet()) {
myTasks.put(entry.getKey(), new DefaultExternalTask(entry.getValue()));
}
for (Map.Entry<String, ExternalSourceSet> entry : externalProject.getSourceSets().entrySet()) {
mySourceSets.put(entry.getKey(), new DefaultExternalSourceSet(entry.getValue()));
}
for (Map.Entry<String, ExternalPlugin> entry : externalProject.getPlugins().entrySet()) {
myPlugins.put(entry.getKey(), new DefaultExternalPlugin(entry.getValue()));
}
}
@NotNull
@Override
public String getExternalSystemId() {
return myExternalSystemId;
}
public void setExternalSystemId(@NotNull String externalSystemId) {
myExternalSystemId = externalSystemId;
}
@NotNull
@Override
public String getName() {
return myName;
}
public void setName(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getQName() {
return myQName;
}
public void setQName(@NotNull String QName) {
myQName = QName;
}
@Nullable
@Override
public String getDescription() {
return myDescription;
}
public void setDescription(@Nullable String description) {
myDescription = description;
}
@NotNull
@Override
public String getGroup() {
return myGroup;
}
public void setGroup(@NotNull String group) {
myGroup = group;
}
@NotNull
@Override
public String getVersion() {
return myVersion;
}
public void setVersion(@NotNull String version) {
myVersion = version;
}
@NotNull
@Override
public Map<String, ExternalProject> getChildProjects() {
return myChildProjects;
}
public void setChildProjects(@NotNull Map<String, ExternalProject> childProjects) {
myChildProjects = childProjects;
}
@NotNull
@Override
public File getProjectDir() {
return myProjectDir;
}
public void setProjectDir(@NotNull File projectDir) {
myProjectDir = projectDir;
}
@NotNull
@Override
public File getBuildDir() {
return myBuildDir;
}
public void setBuildDir(@NotNull File buildDir) {
myBuildDir = buildDir;
}
@Nullable
@Override
public File getBuildFile() {
return myBuildFile;
}
public void setBuildFile(@Nullable File buildFile) {
myBuildFile = buildFile;
}
@NotNull
@Override
public Map<String, ExternalTask> getTasks() {
return myTasks;
}
public void setTasks(@NotNull Map<String, ExternalTask> tasks) {
myTasks = tasks;
}
@NotNull
@Override
public Map<String, ExternalPlugin> getPlugins() {
return myPlugins;
}
public void setPlugins(@NotNull Map<String, ExternalPlugin> plugins) {
myPlugins = plugins;
}
@NotNull
@Override
public Map<String, ?> getProperties() {
return myProperties;
}
public void setProperties(@NotNull Map<String, ?> properties) {
myProperties = properties;
}
@Nullable
@Override
public Object getProperty(String name) {
return myProperties.get(name);
}
@NotNull
@Override
public Map<String, ExternalSourceSet> getSourceSets() {
return mySourceSets;
}
public void setSourceSets(@NotNull Map<String, ExternalSourceSet> sourceSets) {
mySourceSets = sourceSets;
}
}
@@ -0,0 +1,124 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public class DefaultExternalSourceDirectorySet implements ExternalSourceDirectorySet {
private static final long serialVersionUID = 1L;
@NotNull
private String myName;
@NotNull
private Set<File> mySrcDirs;
@NotNull
private File myOutputDir;
@NotNull
private Set<String> myExcludes;
@NotNull
private Set<String> myIncludes;
@NotNull
private List<ExternalFilter> myFilters;
public DefaultExternalSourceDirectorySet() {
mySrcDirs = new HashSet<File>();
myExcludes = new HashSet<String>();
myIncludes = new HashSet<String>();
myFilters = new ArrayList<ExternalFilter>();
}
public DefaultExternalSourceDirectorySet(ExternalSourceDirectorySet sourceDirectorySet) {
this();
myName = sourceDirectorySet.getName();
mySrcDirs = new HashSet<File>(sourceDirectorySet.getSrcDirs());
myOutputDir = sourceDirectorySet.getOutputDir();
myExcludes = new HashSet<String>(sourceDirectorySet.getExcludes());
myIncludes = new HashSet<String>(sourceDirectorySet.getIncludes());
for (ExternalFilter filter : sourceDirectorySet.getFilters()) {
myFilters.add(new DefaultExternalFilter(filter));
}
}
@NotNull
@Override
public String getName() {
return myName;
}
public void setName(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public Set<File> getSrcDirs() {
return mySrcDirs;
}
public void setSrcDirs(@NotNull Set<File> srcDirs) {
mySrcDirs = srcDirs;
}
@NotNull
@Override
public File getOutputDir() {
return myOutputDir;
}
@NotNull
@Override
public Set<String> getIncludes() {
return myIncludes;
}
public void setIncludes(@NotNull Set<String> includes) {
myIncludes = includes;
}
@NotNull
@Override
public Set<String> getExcludes() {
return myExcludes;
}
public void setExcludes(@NotNull Set<String> excludes) {
myExcludes = excludes;
}
@NotNull
@Override
public List<ExternalFilter> getFilters() {
return myFilters;
}
public void setFilters(@NotNull List<ExternalFilter> filters) {
myFilters = filters;
}
public void setOutputDir(@NotNull File outputDir) {
myOutputDir = outputDir;
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
import com.intellij.openapi.externalSystem.model.project.IExternalSystemSourceType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public class DefaultExternalSourceSet implements ExternalSourceSet {
private static final long serialVersionUID = 1L;
private String myName;
private Map<IExternalSystemSourceType, ExternalSourceDirectorySet> mySources;
public DefaultExternalSourceSet() {
mySources = new HashMap<IExternalSystemSourceType, ExternalSourceDirectorySet>();
}
public DefaultExternalSourceSet(ExternalSourceSet sourceSet) {
this();
myName = sourceSet.getName();
for (Map.Entry<IExternalSystemSourceType, ExternalSourceDirectorySet> entry : sourceSet.getSources().entrySet()) {
mySources.put(ExternalSystemSourceType.from(entry.getKey()), new DefaultExternalSourceDirectorySet(entry.getValue()));
}
}
@NotNull
@Override
public String getName() {
return myName;
}
public void setName(String name) {
myName = name;
}
@NotNull
@Override
public Map<IExternalSystemSourceType, ExternalSourceDirectorySet> getSources() {
return mySources;
}
public void setSources(Map<IExternalSystemSourceType, ExternalSourceDirectorySet> sources) {
mySources = sources;
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public class DefaultExternalTask implements ExternalTask {
private static final long serialVersionUID = 1L;
@NotNull
private String myName;
@NotNull
private String myQName;
@Nullable
private String myDescription;
@Nullable
private String myGroup;
public DefaultExternalTask() {
}
public DefaultExternalTask(ExternalTask externalTask) {
myName = externalTask.getName();
myQName = externalTask.getQName();
myDescription = externalTask.getDescription();
myGroup = externalTask.getGroup();
}
@NotNull
@Override
public String getName() {
return myName;
}
public void setName(@NotNull String name) {
myName = name;
}
@NotNull
@Override
public String getQName() {
return myQName;
}
public void setQName(@NotNull String QName) {
myQName = QName;
}
@Nullable
@Override
public String getDescription() {
return myDescription;
}
public void setDescription(@Nullable String description) {
myDescription = description;
}
@Nullable
@Override
public String getGroup() {
return myGroup;
}
public void setGroup(@Nullable String group) {
myGroup = group;
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalFilter extends Serializable {
@NotNull
String getFilterType();
@NotNull
String getPropertiesAsJsonMap();
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalPlugin extends Serializable {
@NotNull
String getId();
}
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.Serializable;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalProject extends Serializable {
@NotNull
String getExternalSystemId();
@NotNull
String getName();
@NotNull
String getQName();
@Nullable
String getDescription();
@NotNull
String getGroup();
@NotNull
String getVersion();
@NotNull
Map<String, ExternalProject> getChildProjects();
@NotNull
File getProjectDir();
@NotNull
File getBuildDir();
@Nullable
File getBuildFile();
@NotNull
Map<String, ExternalTask> getTasks();
//@NotNull
//Map<String, ExternalConfiguration> getConfigurations();
//@NotNull
//List<ExternalRepository> getRepositories();
//@NotNull
//List<ExternalDependency> getDependencies();
@NotNull
Map<String, ExternalPlugin> getPlugins();
//@NotNull
//ExternalProjectBuild getBuild();
@NotNull
Map<String, ?> getProperties();
@Nullable
Object getProperty(String name);
@NotNull
Map<String, ExternalSourceSet> getSourceSets();
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalSourceDirectorySet extends Serializable {
@NotNull
String getName();
@NotNull
Set<File> getSrcDirs();
@NotNull
File getOutputDir();
@NotNull
Set<String> getExcludes();
@NotNull
Set<String> getIncludes();
@NotNull
List<ExternalFilter> getFilters();
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import com.intellij.openapi.externalSystem.model.project.IExternalSystemSourceType;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalSourceSet extends Serializable {
@NotNull
String getName();
//@NotNull
//ClasspathContainer getCompileClasspath();
//@NotNull
//ClasspathContainer getRuntimeClasspath();
@NotNull
Map<IExternalSystemSourceType, ExternalSourceDirectorySet> getSources();
}
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
/**
* @author Vladislav.Soroka
* @since 7/14/2014
*/
public interface ExternalTask extends Serializable {
@NotNull
String getName();
@NotNull
String getQName();
@Nullable
String getDescription();
@Nullable
String getGroup();
}
@@ -1,52 +1,62 @@
package com.intellij.openapi.externalSystem.model.project;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
/**
* Enumerates module source types.
*
* @author Denis Zhdanov
* @since 8/10/11 5:21 PM
*/
public class ExternalSystemSourceType implements Serializable {
public enum ExternalSystemSourceType implements IExternalSystemSourceType {
@NotNull public static final ExternalSystemSourceType SOURCE = new ExternalSystemSourceType("SOURCE");
@NotNull public static final ExternalSystemSourceType TEST = new ExternalSystemSourceType("TEST");
@NotNull public static final ExternalSystemSourceType EXCLUDED = new ExternalSystemSourceType("EXCLUDED");
@NotNull public static final ExternalSystemSourceType SOURCE_GENERATED = new ExternalSystemSourceType("SOURCE_GENERATED");
@NotNull public static final ExternalSystemSourceType TEST_GENERATED = new ExternalSystemSourceType("TEST_GENERATED");
@NotNull public static final ExternalSystemSourceType RESOURCE = new ExternalSystemSourceType("RESOURCE");
@NotNull public static final ExternalSystemSourceType TEST_RESOURCE = new ExternalSystemSourceType("TEST_RESOURCE");
private static final long serialVersionUID = 1L;
SOURCE(false, false, false, false),
TEST(true, false, false, false),
EXCLUDED(false, false, false, true),
SOURCE_GENERATED(true, true, false, false),
TEST_GENERATED(true, true, false, false),
RESOURCE(false, false, true, false),
TEST_RESOURCE(true, false, true, false);
@NotNull private final String myId;
private final boolean isTest;
private final boolean isGenerated;
private final boolean isResource;
private final boolean isExcluded;
public ExternalSystemSourceType(@NotNull String id) {
myId = id;
ExternalSystemSourceType(boolean test, boolean generated, boolean resource, boolean excluded) {
isTest = test;
isGenerated = generated;
isResource = resource;
isExcluded = excluded;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExternalSystemSourceType type = (ExternalSystemSourceType)o;
if (!myId.equals(type.myId)) return false;
return true;
public boolean isTest() {
return isTest;
}
@Override
public int hashCode() {
return myId.hashCode();
public boolean isGenerated() {
return isGenerated;
}
@Override
public String toString() {
return myId;
public boolean isResource() {
return isResource;
}
@Override
public boolean isExcluded() {
return isExcluded;
}
public static ExternalSystemSourceType from(IExternalSystemSourceType sourceType) {
for (ExternalSystemSourceType systemSourceType : ExternalSystemSourceType.values()) {
if (systemSourceType.isGenerated == sourceType.isGenerated() &&
systemSourceType.isResource == sourceType.isResource() &&
systemSourceType.isTest == sourceType.isTest() &&
systemSourceType.isExcluded == sourceType.isExcluded()) {
return systemSourceType;
}
}
throw new IllegalArgumentException("Invalid source type: " + sourceType);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.model.project;
import java.io.Serializable;
/**
* @author Vladislav.Soroka
* @since 7/17/2014
*/
public interface IExternalSystemSourceType extends Serializable {
boolean isTest();
boolean isGenerated();
boolean isResource();
boolean isExcluded();
}
@@ -681,4 +681,9 @@ public class ExternalSystemApiUtil {
public static String getExternalProjectPath(@Nullable Module module) {
return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : null;
}
@Nullable
public static String getExternalProjectId(@Nullable Module module) {
return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_ID_KEY) : null;
}
}
@@ -27,6 +27,7 @@ public class ExternalSystemConstants {
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_ID_KEY = "external.system.id";
@NonNls @NotNull public static final String LINKED_PROJECT_PATH_KEY = "external.linked.project.path";
@NonNls @NotNull public static final String ROOT_PROJECT_PATH_KEY = "external.root.project.path";
@NonNls @NotNull public static final String LINKED_PROJECT_ID_KEY = "external.linked.project.id";
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_MODULE_GROUP_KEY = "external.system.module.group";
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_MODULE_VERSION_KEY = "external.system.module.version";
@@ -24,6 +24,8 @@
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="library" name="Kryo" level="project" />
<orderEntry type="module" module-name="compiler-impl" scope="TEST" />
</component>
</module>
@@ -1,42 +0,0 @@
package com.intellij.openapi.externalSystem.service.project;
import org.jetbrains.annotations.NotNull;
/**
* Facades all services necessary for the 'sync project changes' processing.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since 2/14/12 1:26 PM
*/
public class ProjectStructureServices {
@NotNull private final ProjectStructureHelper myProjectStructureHelper;
@NotNull private final PlatformFacade myPlatformFacade;
@NotNull private final ExternalLibraryPathTypeMapper myLibraryPathTypeMapper;
public ProjectStructureServices(@NotNull ProjectStructureHelper projectStructureHelper,
@NotNull PlatformFacade platformFacade,
@NotNull ExternalLibraryPathTypeMapper mapper)
{
myProjectStructureHelper = projectStructureHelper;
myPlatformFacade = platformFacade;
myLibraryPathTypeMapper = mapper;
}
@NotNull
public ProjectStructureHelper getProjectStructureHelper() {
return myProjectStructureHelper;
}
@NotNull
public PlatformFacade getPlatformFacade() {
return myPlatformFacade;
}
@NotNull
public ExternalLibraryPathTypeMapper getLibraryPathTypeMapper() {
return myLibraryPathTypeMapper;
}
}
@@ -274,6 +274,7 @@ public class ModuleDataService implements ProjectDataService<ModuleData, Module>
module.putUserData(MODULE_DATA_KEY, moduleData);
module.setOption(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, moduleData.getOwner().toString());
module.setOption(ExternalSystemConstants.LINKED_PROJECT_ID_KEY, moduleData.getId());
module.setOption(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY, moduleData.getLinkedExternalProjectPath());
final ProjectData projectData = moduleDataNode.getData(ProjectKeys.PROJECT);
module.setOption(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY, projectData != null ? projectData.getLinkedExternalProjectPath() : "");
@@ -25,6 +25,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
@@ -40,8 +41,10 @@ public class ProjectDataManager {
private static final Logger LOG = Logger.getInstance("#" + ProjectDataManager.class.getName());
@NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices =
new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
@NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices;
public ProjectDataManager() {
myServices = new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
@NotNull
@Override
protected Map<Key<?>, List<ProjectDataService<?, ?>>> compute() {
@@ -57,10 +60,22 @@ public class ProjectDataManager {
for (List<ProjectDataService<?, ?>> services : result.values()) {
ExternalSystemApiUtil.orderAwareSort(services);
}
return result;
}
};
}
@Nullable
public List<ProjectDataService<?, ?>> getDataServices(Key<?> key) {
return myServices.getValue().get(key);
}
@Nullable
public ProjectDataService<?, ?> getDataService(Key<?> key) {
final List<ProjectDataService<?, ?>> dataServices = myServices.getValue().get(key);
assert dataServices == null || dataServices.isEmpty() || dataServices.size() == 1;
return ContainerUtil.getFirstItem(dataServices);
}
@SuppressWarnings("unchecked")
public <T> void importData(@NotNull Collection<DataNode<?>> nodes, @NotNull Project project, boolean synchronous) {
@@ -0,0 +1,262 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.externalSystem.util;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.CollectionSerializer;
import com.esotericsoftware.kryo.serializers.DefaultSerializers;
import com.esotericsoftware.kryo.serializers.FieldSerializer;
import com.esotericsoftware.kryo.serializers.MapSerializer;
import com.esotericsoftware.minlog.Log;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.*;
/**
* @author Vladislav.Soroka
* @since 7/15/2014
*/
public class ExternalProjectSerializer {
private static final Logger LOG = Logger.getInstance(ExternalProjectSerializer.class);
private final Kryo myKryo;
public ExternalProjectSerializer() {
myKryo = new Kryo() {
@Override
public <T> T newInstance(Class<T> type) {
LOG.error("Serializing default type: " + type);
return super.newInstance(type);
}
};
configureKryo();
}
private void configureKryo() {
myKryo.setAutoReset(true);
myKryo.setRegistrationRequired(true);
Log.set(Log.LEVEL_WARN);
myKryo.register(ArrayList.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new ArrayList();
}
});
myKryo.register(HashMap.class, new MapSerializer() {
@Override
protected Map create(Kryo kryo, Input input, Class<Map> type) {
return new HashMap();
}
});
myKryo.register(HashSet.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new HashSet();
}
});
myKryo.register(File.class, new FileSerializer());
myKryo.register(DefaultExternalProject.class, new FieldSerializer<DefaultExternalProject>(myKryo, DefaultExternalProject.class) {
@Override
protected DefaultExternalProject create(Kryo kryo, Input input, Class<DefaultExternalProject> type) {
return new DefaultExternalProject();
}
});
myKryo.register(DefaultExternalTask.class, new FieldSerializer<DefaultExternalTask>(myKryo, DefaultExternalTask.class) {
@Override
protected DefaultExternalTask create(Kryo kryo, Input input, Class<DefaultExternalTask> type) {
return new DefaultExternalTask();
}
});
myKryo.register(DefaultExternalPlugin.class, new FieldSerializer<DefaultExternalPlugin>(myKryo, DefaultExternalPlugin.class) {
@Override
protected DefaultExternalPlugin create(Kryo kryo, Input input, Class<DefaultExternalPlugin> type) {
return new DefaultExternalPlugin();
}
});
myKryo.register(DefaultExternalSourceSet.class, new FieldSerializer<DefaultExternalSourceSet>(myKryo, DefaultExternalSourceSet.class) {
@Override
protected DefaultExternalSourceSet create(Kryo kryo, Input input, Class<DefaultExternalSourceSet> type) {
return new DefaultExternalSourceSet();
}
});
myKryo.register(
DefaultExternalSourceDirectorySet.class,
new FieldSerializer<DefaultExternalSourceDirectorySet>(myKryo, DefaultExternalSourceDirectorySet.class) {
@Override
protected DefaultExternalSourceDirectorySet create(Kryo kryo, Input input, Class<DefaultExternalSourceDirectorySet> type) {
return new DefaultExternalSourceDirectorySet();
}
}
);
myKryo.register(DefaultExternalFilter.class, new FieldSerializer<DefaultExternalFilter>(myKryo, DefaultExternalFilter.class) {
@Override
protected DefaultExternalFilter create(Kryo kryo, Input input, Class<DefaultExternalFilter> type) {
return new DefaultExternalFilter();
}
});
myKryo.register(ExternalSystemSourceType.class, new DefaultSerializers.EnumSerializer(ExternalSystemSourceType.class));
myKryo.register(LinkedHashSet.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new LinkedHashSet();
}
});
myKryo.register(HashSet.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new HashSet();
}
});
myKryo.register(THashSet.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new THashSet();
}
});
myKryo.register(Set.class, new CollectionSerializer() {
@Override
protected Collection create(Kryo kryo, Input input, Class<Collection> type) {
return new HashSet();
}
});
myKryo.register(THashMap.class, new MapSerializer() {
@Override
protected Map create(Kryo kryo, Input input, Class<Map> type) {
return new THashMap();
}
});
}
public void save(@NotNull ExternalProject externalProject) {
Output output = null;
try {
final String externalProjectPath = externalProject.getProjectDir().getPath();
final File configurationFile =
getProjectConfigurationFile(new ProjectSystemId(externalProject.getExternalSystemId()), externalProjectPath);
if (!FileUtil.createParentDirs(configurationFile)) return;
output = new Output(new FileOutputStream(configurationFile));
myKryo.writeObject(output, externalProject);
}
catch (FileNotFoundException e) {
LOG.error(e);
}
finally {
StreamUtil.closeStream(output);
}
}
@Nullable
public ExternalProject load(@NotNull ProjectSystemId externalSystemId, File externalProjectPath) {
Input input = null;
try {
final File configurationFile = getProjectConfigurationFile(externalSystemId, externalProjectPath.getPath());
if (!configurationFile.isFile()) return null;
input = new Input(new FileInputStream(configurationFile));
return myKryo.readObject(input, DefaultExternalProject.class);
}
catch (Exception e) {
LOG.error(e);
}
finally {
StreamUtil.closeStream(input);
}
return null;
}
private static File getProjectConfigurationFile(ProjectSystemId externalSystemId, String externalProjectPath) {
return new File(getProjectConfigurationDir(externalSystemId), Integer.toHexString(externalProjectPath.hashCode()) + "/project.dat");
}
private static File getProjectConfigurationDir(ProjectSystemId externalSystemId) {
return getPluginSystemDir(externalSystemId, "Projects");
}
private static File getPluginSystemDir(ProjectSystemId externalSystemId, String folder) {
return new File(PathManager.getSystemPath(), externalSystemId.getId().toLowerCase() + "/" + folder).getAbsoluteFile();
}
private static class FileSerializer extends Serializer<File> {
private final Kryo myStdKryo;
public FileSerializer() {
myStdKryo = new Kryo();
myStdKryo.register(File.class);
myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
}
@Override
public void write(Kryo kryo, Output output, File object) {
myStdKryo.writeObject(output, object);
}
@Override
public File read(Kryo kryo, Input input, Class<File> type) {
File file = myStdKryo.readObject(input, File.class);
return new File(file.getPath());
}
}
private static class StdSerializer<T> extends Serializer<T> {
private final Kryo myStdKryo;
public StdSerializer(Class<T> clazz) {
myStdKryo = new Kryo();
myStdKryo.register(clazz);
myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
}
@Override
public void write(Kryo kryo, Output output, T object) {
myStdKryo.writeObject(output, object);
}
@Override
public T read(Kryo kryo, Input input, Class<T> type) {
return myStdKryo.readObject(input, type);
}
}
}
@@ -15,24 +15,41 @@
*/
package com.intellij.openapi.externalSystem.test;
import com.intellij.compiler.CompilerTestUtil;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.artifacts.ArtifactsTestUtil;
import com.intellij.compiler.impl.ModuleCompileScope;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompileStatusNotification;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.io.TestFileSystemItem;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -40,6 +57,7 @@ import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
@@ -129,11 +147,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
@Override
public void tearDown() throws Exception {
try {
myProject = null;
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
edt(new Runnable() {
@Override
public void run() {
try {
CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
catch (Exception e) {
@@ -141,6 +159,7 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
}
}
});
myProject = null;
if (!FileUtil.delete(myTestDir) && myTestDir.exists()) {
System.err.println("Cannot delete " + myTestDir);
//printDirectoryContent(myDir);
@@ -319,7 +338,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
File f = new File(getProjectPath(), relativePath);
FileUtil.ensureExists(f.getParentFile());
f.createNewFile();
FileUtil.ensureCanCreateFile(f);
final boolean created = f.createNewFile();
if(!created) {
throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
}
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
@@ -329,6 +352,114 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
return file;
}
protected void compileModules(final String... moduleNames) {
compile(createModulesCompileScope(moduleNames));
}
protected void buildArtifacts(String... artifactNames) {
compile(createArtifactsScope(artifactNames));
}
private void compile(final CompileScope scope) {
edt(new Runnable() {
@Override
public void run() {
for (Module module : scope.getAffectedModules()) {
setupJdkForModule(module.getName());
}
}
});
CompilerWorkspaceConfiguration.getInstance(myProject).CLEAR_OUTPUT_DIRECTORY = true;
final Semaphore semaphore = new Semaphore();
semaphore.down();
edt(new Runnable() {
@Override
public void run() {
CompilerTestUtil.enableExternalCompiler();
CompilerManager.getInstance(myProject).make(scope, new CompileStatusNotification() {
@Override
public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
//assertFalse(aborted);
//assertEquals(collectMessages(compileContext, CompilerMessageCategory.ERROR), 0, errors);
//assertEquals(collectMessages(compileContext, CompilerMessageCategory.WARNING), 0, warnings);
semaphore.up();
}
});
}
});
while (!semaphore.waitFor(100)) {
if (SwingUtilities.isEventDispatchThread()) {
UIUtil.dispatchAllInvocationEvents();
}
}
if (SwingUtilities.isEventDispatchThread()) {
UIUtil.dispatchAllInvocationEvents();
}
}
private CompileScope createModulesCompileScope(final String[] moduleNames) {
final List<Module> modules = new ArrayList<Module>();
for (String name : moduleNames) {
modules.add(getModule(name));
}
return new ModuleCompileScope(myProject, modules.toArray(new Module[modules.size()]), false);
}
private CompileScope createArtifactsScope(String[] artifactNames) {
List<Artifact> artifacts = new ArrayList<Artifact>();
for (String name : artifactNames) {
artifacts.add(ArtifactsTestUtil.findArtifact(myProject, name));
}
return ArtifactCompileScope.createArtifactsScope(myProject, artifacts);
}
protected Sdk setupJdkForModule(final String moduleName) {
final Sdk sdk = true ? JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk() : createJdk("Java 1.5");
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
return sdk;
}
protected static Sdk createJdk(String versionName) {
return IdeaTestUtil.getMockJdk17(versionName);
}
protected Module getModule(final String name) {
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
try {
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
assertNotNull("Module " + name + " not found", m);
return m;
}
finally {
accessToken.finish();
}
}
protected void assertExplodedLayout(String artifactName, String expected) {
assertJarLayout(artifactName + " exploded", expected);
}
protected void assertJarLayout(String artifactName, String expected) {
ArtifactsTestUtil.assertLayout(myProject, artifactName, expected);
}
protected void assertArtifactOutputPath(final String artifactName, final String expected) {
ArtifactsTestUtil.assertOutputPath(myProject, artifactName, expected);
}
protected void assertArtifactOutputFileName(final String artifactName, final String expected) {
ArtifactsTestUtil.assertOutputFileName(myProject, artifactName, expected);
}
protected void assertArtifactOutput(String artifactName, TestFileSystemItem fs) {
final String outputPath = ArtifactsTestUtil.findArtifact(myProject, artifactName).getOutputPath();
assert outputPath != null;
fs.assertDirectoryEqual(new File(outputPath));
}
private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
new WriteAction<VirtualFile>() {
@Override
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -65,4 +66,12 @@ public abstract class OrderEnumerationHandler {
@NotNull Collection<String> urls) {
return false;
}
public boolean addCustomModuleRoots(@NotNull OrderRootType type,
@NotNull ModuleRootModel rootModel,
@NotNull Collection<String> result,
boolean includeProduction,
boolean includeTests) {
return false;
}
}
@@ -356,6 +356,38 @@ abstract class OrderEnumeratorBase extends OrderEnumerator implements OrderEnume
return false;
}
boolean addCustomRootsForModule(OrderRootType type,
ModuleRootModel rootModel,
Collection<VirtualFile> result,
boolean includeProduction,
boolean includeTests) {
for (OrderEnumerationHandler handler : myCustomHandlers) {
final List<String> urls = new ArrayList<String>();
final boolean added = handler.addCustomModuleRoots(type, rootModel, urls, includeProduction, includeTests);
for (String url : urls) {
ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), result);
}
if (added) return true;
}
return false;
}
boolean addCustomRootUrlsForModule(OrderRootType type,
ModuleRootModel rootModel,
Collection<String> result,
boolean includeProduction,
boolean includeTests) {
for (OrderEnumerationHandler handler : myCustomHandlers) {
final List<String> urls = new ArrayList<String>();
final boolean added = handler.addCustomModuleRoots(type, rootModel, urls, includeProduction, includeTests);
result.addAll(urls);
if (added) return true;
}
return false;
}
@Override
public boolean isRuntimeOnly() {
return myRuntimeOnly;
@@ -240,6 +240,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
}
}
}
myOrderEnumerator.addCustomRootsForModule(type, rootModel, result, includeProduction, includeTests);
}
private void collectModuleRootsUrls(OrderRootType type,
+3
View File
@@ -14,6 +14,7 @@
<orderEntry type="module" module-name="external-system-impl" exported="" />
<orderEntry type="module" module-name="gradle-tooling-extension-api" exported="" />
<orderEntry type="module" module-name="gradle-tooling-extension-impl" />
<orderEntry type="module" module-name="gradle-jps-plugin" />
<orderEntry type="module" module-name="idea-ui" />
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="compiler-openapi" />
@@ -105,6 +106,8 @@
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="junit" />
<orderEntry type="module" module-name="smRunner" />
<orderEntry type="library" name="Ant" level="project" />
<orderEntry type="library" name="gson" level="project" />
</component>
</module>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="jps-builders" />
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="jps-model-api" />
<orderEntry type="module" module-name="jps-model-serialization" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-core-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-messaging-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-base-services-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-base-services-groovy-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-native-2.0.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-resources-2.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/tooling-api/src/main/java" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/core/src/main/groovy" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/messaging/src/main/java" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/wrapper/src/main/java" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services/src/main/java" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services-groovy/src/main/groovy" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/native/src/main/java" />
<root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/resources/src/main/java" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="library" exported="" name="Ant" level="project" />
<orderEntry type="library" name="gson" level="project" />
</component>
</module>
@@ -0,0 +1,16 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.jetbrains.jps.gradle.model.impl.JpsGradleExtensionServiceImpl
@@ -0,0 +1,16 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.jetbrains.jps.gradle.compiler.GradleBuilderService
@@ -0,0 +1,16 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.jetbrains.jps.gradle.model.impl.JpsGradleDependenciesEnumerationHandler$GradleFactory
@@ -0,0 +1,16 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
org.jetbrains.jps.gradle.model.impl.JpsGradleModelSerializationExtension
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.compiler;
import com.intellij.openapi.util.Ref;
import org.gradle.api.Transformer;
import org.gradle.util.ConfigureUtil;
import org.jetbrains.jps.gradle.model.impl.ResourceRootFilter;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import java.io.File;
import java.io.FilterReader;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.regex.Matcher;
/**
* @author Vladislav.Soroka
* @since 7/24/2014
*/
public class ChainingFilterTransformer implements Transformer<Reader, Reader> {
private final Collection<ResourceRootFilter> myFilters = new ArrayList<ResourceRootFilter>();
private final CompileContext myContext;
private final Ref<File> myOutputFileRef;
public ChainingFilterTransformer(CompileContext context, Collection<ResourceRootFilter> filters, Ref<File> outputFileRef) {
myContext = context;
myOutputFileRef = outputFileRef;
myFilters.addAll(filters);
}
public ChainingFilterTransformer(CompileContext context, Collection<ResourceRootFilter> filters) {
this(context, filters, null);
}
public void addAll(Collection<ResourceRootFilter> filters) {
myFilters.addAll(filters);
}
public void add(ResourceRootFilter... filters) {
Collections.addAll(myFilters, filters);
}
@Override
public Reader transform(Reader original) {
Reader value = original;
for (ResourceRootFilter filter : myFilters) {
value = doTransform(filter, value);
}
return value;
}
private Reader doTransform(ResourceRootFilter filter, Reader original) {
if ("RenamingCopyFilter" .equals(filter.filterType)) {
final Matcher matcher = (Matcher)filter.getProperties().get("matcher");
final String replacement = (String)filter.getProperties().get("replacement");
if (matcher == null || replacement == null) return original;
matcher.reset(myOutputFileRef.get().getName());
if (matcher.find()) {
final String newFileName = matcher.replaceFirst(replacement);
myOutputFileRef.set(new File(myOutputFileRef.get().getParentFile(), newFileName));
}
return original;
}
try {
Class<?> clazz = Class.forName(filter.filterType);
if (!FilterReader.class.isAssignableFrom(clazz)) {
myContext.processMessage(
new CompilerMessage(
GradleResourcesBuilder.BUILDER_NAME, BuildMessage.Kind.WARNING,
String.format("Error - Invalid filter specification for %s. It should extend java.io.FilterReader.", filter.filterType), null)
);
}
Constructor constructor = clazz.getConstructor(Reader.class);
FilterReader result = (FilterReader)constructor.newInstance(original);
final Map<Object, Object> properties = filter.getProperties();
if (!properties.isEmpty()) {
ConfigureUtil.configureByMap(properties, result);
}
return result;
}
catch (Throwable th) {
myContext.processMessage(new CompilerMessage(
GradleResourcesBuilder.BUILDER_NAME, BuildMessage.Kind.WARNING,
String.format("Error - Failed to apply filter(%s): %s", filter.filterType, th.getMessage()), null)
);
}
return original;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.compiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.gradle.model.impl.GradleResourcesTargetType;
import org.jetbrains.jps.incremental.BuilderService;
import org.jetbrains.jps.incremental.TargetBuilder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleBuilderService extends BuilderService {
@NotNull
@Override
public List<? extends BuildTargetType<?>> getTargetTypes() {
return Arrays.asList(GradleResourcesTargetType.PRODUCTION, GradleResourcesTargetType.TEST);
}
@NotNull
@Override
public List<? extends TargetBuilder<?, ?>> createBuilders() {
return Collections.singletonList(new GradleResourcesBuilder());
}
}
@@ -0,0 +1,94 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.compiler;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import org.apache.tools.ant.util.ReaderInputStream;
import org.jetbrains.jps.gradle.model.impl.GradleModuleResourceConfiguration;
import org.jetbrains.jps.gradle.model.impl.GradleProjectConfiguration;
import org.jetbrains.jps.gradle.model.impl.ResourceRootConfiguration;
import org.jetbrains.jps.gradle.model.impl.ResourceRootFilter;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.model.JpsEncodingConfigurationService;
import org.jetbrains.jps.model.JpsEncodingProjectConfiguration;
import org.jetbrains.jps.model.JpsProject;
import java.io.*;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourceFileProcessor {
private static final int FILTERING_SIZE_LIMIT = 10 * 1024 * 1024 /*10 mb*/;
protected final JpsEncodingProjectConfiguration myEncodingConfig;
protected final GradleProjectConfiguration myProjectConfig;
protected final GradleModuleResourceConfiguration myModuleConfiguration;
public GradleResourceFileProcessor(GradleProjectConfiguration projectConfiguration, JpsProject project,
GradleModuleResourceConfiguration moduleConfiguration) {
myProjectConfig = projectConfiguration;
myEncodingConfig = JpsEncodingConfigurationService.getInstance().getEncodingConfiguration(project);
myModuleConfiguration = moduleConfiguration;
}
public void copyFile(File file, Ref<File> targetFileRef, ResourceRootConfiguration rootConfiguration, CompileContext context,
FileFilter filteringFilter) throws IOException {
boolean shouldFilter = rootConfiguration.isFiltered && !rootConfiguration.filters.isEmpty() && filteringFilter.accept(file);
if (shouldFilter && file.length() > FILTERING_SIZE_LIMIT) {
context.processMessage(new CompilerMessage(
GradleResourcesBuilder.BUILDER_NAME, BuildMessage.Kind.WARNING,
"File is too big to be filtered. Most likely it is a binary file and should be excluded from filtering", file.getPath())
);
shouldFilter = false;
}
if (shouldFilter) {
copyWithFiltering(file, targetFileRef, rootConfiguration.filters, context);
}
else {
FileUtil.copyContent(file, targetFileRef.get());
}
}
private static void copyWithFiltering(File file, Ref<File> outputFileRef, List<ResourceRootFilter> filters, CompileContext context)
throws IOException {
final FileInputStream originalInputStream = new FileInputStream(file);
try {
final InputStream inputStream = transform(filters, originalInputStream, outputFileRef, context);
FileUtil.createIfDoesntExist(outputFileRef.get());
FileOutputStream outputStream = new FileOutputStream(outputFileRef.get());
try {
FileUtil.copy(inputStream, outputStream);
}
finally {
StreamUtil.closeStream(inputStream);
StreamUtil.closeStream(outputStream);
}
}
finally {
StreamUtil.closeStream(originalInputStream);
}
}
private static InputStream transform(List<ResourceRootFilter> filters, FileInputStream original, Ref<File> outputFileRef, CompileContext context) {
return new ReaderInputStream(new ChainingFilterTransformer(context, filters, outputFileRef).transform(new InputStreamReader(original)));
}
}
@@ -0,0 +1,128 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.compiler;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.gradle.model.impl.*;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ProjectBuildException;
import org.jetbrains.jps.incremental.TargetBuilder;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourcesBuilder extends TargetBuilder<GradleResourceRootDescriptor, GradleResourcesTarget> {
public static final String BUILDER_NAME = "Gradle Resources Compiler";
public GradleResourcesBuilder() {
super(Arrays.asList(GradleResourcesTargetType.PRODUCTION, GradleResourcesTargetType.TEST));
}
@Override
public void build(@NotNull final GradleResourcesTarget target,
@NotNull final DirtyFilesHolder<GradleResourceRootDescriptor, GradleResourcesTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull final CompileContext context) throws ProjectBuildException, IOException {
final BuildDataPaths dataPaths = context.getProjectDescriptor().dataManager.getDataPaths();
final GradleProjectConfiguration projectConfig = JpsGradleExtensionService.getInstance().getGradleProjectConfiguration(dataPaths);
final GradleModuleResourceConfiguration config = target.getModuleResourcesConfiguration(dataPaths);
if (config == null) return;
final Map<GradleResourceRootDescriptor, List<File>> files = new HashMap<GradleResourceRootDescriptor, List<File>>();
holder.processDirtyFiles(new FileProcessor<GradleResourceRootDescriptor, GradleResourcesTarget>() {
@Override
public boolean apply(GradleResourcesTarget t, File file, GradleResourceRootDescriptor rd) throws IOException {
assert target == t;
List<File> fileList = files.get(rd);
if (fileList == null) {
fileList = new ArrayList<File>();
files.put(rd, fileList);
}
fileList.add(file);
return true;
}
});
GradleResourceRootDescriptor[] roots = files.keySet().toArray(new GradleResourceRootDescriptor[files.keySet().size()]);
Arrays.sort(roots, new Comparator<GradleResourceRootDescriptor>() {
@Override
public int compare(GradleResourceRootDescriptor r1, GradleResourceRootDescriptor r2) {
int res = r1.getIndexInPom() - r2.getIndexInPom();
if (r1.isOverwrite()) {
assert r2.isOverwrite();
return res;
}
if (r1.getConfiguration().isFiltered && !r2.getConfiguration().isFiltered) return 1;
if (!r1.getConfiguration().isFiltered && r2.getConfiguration().isFiltered) return -1;
if (!r1.getConfiguration().isFiltered) {
res = -res;
}
return res;
}
});
GradleResourceFileProcessor fileProcessor = new GradleResourceFileProcessor(projectConfig, target.getModule().getProject(), config);
for (GradleResourceRootDescriptor rd : roots) {
for (File file : files.get(rd)) {
String relPath = FileUtil.getRelativePath(rd.getRootFile(), file);
if (relPath == null) continue;
final File outputDir =
GradleResourcesTarget.getOutputDir(target.getModuleOutputDir(), rd.getConfiguration(), config.outputDirectory);
if (outputDir == null) continue;
context.processMessage(new ProgressMessage("Copying resources... [" + target.getModule().getName() + "]"));
final Ref<File> fileRef = Ref.create(new File(outputDir, relPath));
fileProcessor.copyFile(file, fileRef, rd.getConfiguration(), context, FileUtilRt.ALL_FILES);
outputConsumer.registerOutputFile(fileRef.get(), Collections.singleton(file.getPath()));
if (context.getCancelStatus().isCanceled()) return;
}
}
context.checkCanceled();
context.processMessage(new ProgressMessage(""));
}
@NotNull
public String getPresentableName() {
return BUILDER_NAME;
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.gradle.model.impl.GradleProjectConfiguration;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.service.JpsServiceManager;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public abstract class JpsGradleExtensionService {
public static JpsGradleExtensionService getInstance() {
return JpsServiceManager.getInstance().getService(JpsGradleExtensionService.class);
}
@Nullable
public abstract JpsGradleModuleExtension getExtension(@NotNull JpsModule module);
@NotNull
public abstract JpsGradleModuleExtension getOrCreateExtension(@NotNull JpsModule module);
public abstract void setProductionOnTestDependency(@NotNull JpsDependencyElement dependency, boolean value);
public abstract boolean isProductionOnTestDependency(@NotNull JpsDependencyElement dependency);
public abstract boolean hasGradleProjectConfiguration(@NotNull BuildDataPaths paths);
@NotNull
public abstract GradleProjectConfiguration getGradleProjectConfiguration(BuildDataPaths paths);
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model;
import org.jetbrains.jps.model.JpsElement;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public interface JpsGradleModuleExtension extends JpsElement {
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Tag;
import java.util.HashSet;
import java.util.Set;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class FilePattern {
@Tag("includes")
@AbstractCollection(surroundWithTag = false, elementTag = "pattern")
public Set<String> includes = new HashSet<String>();
@Tag("excludes")
@AbstractCollection(surroundWithTag = false, elementTag = "pattern")
public Set<String> excludes = new HashSet<String>();
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.OptionTag;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleModuleResourceConfiguration {
@NotNull
@Tag("id")
public ModuleVersion id;
@Nullable
@Tag("parentId")
public ModuleVersion parentId;
@NotNull
@Tag("directory")
public String directory;
@OptionTag
public boolean overwrite;
@OptionTag
public String outputDirectory = null;
@Tag("resources")
@AbstractCollection(surroundWithTag = false, elementTag = "resource")
public List<ResourceRootConfiguration> resources = new ArrayList<ResourceRootConfiguration>();
@Tag("test-resources")
@AbstractCollection(surroundWithTag = false, elementTag = "resource")
public List<ResourceRootConfiguration> testResources = new ArrayList<ResourceRootConfiguration>();
public int computeConfigurationHash(boolean forTestResources) {
int result = computeModuleConfigurationHash();
final List<ResourceRootConfiguration> _resources = forTestResources ? testResources : resources;
result = 31 * result;
for (ResourceRootConfiguration resource : _resources) {
result += resource.computeConfigurationHash();
}
return result;
}
public int computeModuleConfigurationHash() {
int result = id.hashCode();
result = 31 * result + (parentId != null ? parentId.hashCode() : 0);
result = 31 * result + directory.hashCode();
result = 31 * result + (outputDirectory != null ? outputDirectory.hashCode() : 0);
result = 31 * result + (overwrite ? 1 : 0);
return result;
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Tag;
import gnu.trove.THashMap;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleProjectConfiguration {
public static final String CONFIGURATION_FILE_RELATIVE_PATH = "gradle/configuration.xml";
@Tag("resource-processing")
@MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false, entryTagName = "gradle-module",
keyAttributeName = "name")
public Map<String, GradleModuleResourceConfiguration> moduleConfigurations = new THashMap<String, GradleModuleResourceConfiguration>();
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.openapi.util.io.FileUtil;
import org.gradle.api.file.RelativePath;
import org.gradle.api.internal.file.pattern.PatternMatcherFactory;
import org.gradle.api.specs.Spec;
import org.gradle.api.specs.Specs;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.regex.Pattern;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourceFileFilter implements FileFilter {
private FilePattern myFilePattern;
private File myRoot;
private final Spec<RelativePath> myFileFilterSpec;
public GradleResourceFileFilter(@NotNull File rootFile, @NotNull FilePattern filePattern) {
myFilePattern = filePattern;
myRoot = rootFile;
myFileFilterSpec = getAsSpec();
}
@Override
public boolean accept(@NotNull File file) {
final String relPath = FileUtil.getRelativePath(myRoot, file);
return relPath != null && isIncluded(relPath);
}
private boolean isIncluded(@NotNull String relativePath) {
RelativePath path = new RelativePath(true, relativePath.split(Pattern.quote(File.separator)));
return myFileFilterSpec.isSatisfiedBy(path);
}
private Spec<RelativePath> getAsSpec() {
return Specs.and(getAsIncludeSpec(true), Specs.not(getAsExcludeSpec(true)));
}
private Spec<RelativePath> getAsExcludeSpec(boolean caseSensitive) {
Collection<String> allExcludes = new LinkedHashSet<String>(myFilePattern.excludes);
List<Spec<RelativePath>> matchers = new ArrayList<Spec<RelativePath>>();
for (String exclude : allExcludes) {
Spec<RelativePath> patternMatcher = PatternMatcherFactory.getPatternMatcher(false, caseSensitive, exclude);
matchers.add(patternMatcher);
}
return Specs.or(false, matchers);
}
private Spec<RelativePath> getAsIncludeSpec(boolean caseSensitive) {
List<Spec<RelativePath>> matchers = new ArrayList<Spec<RelativePath>>();
for (String include : myFilePattern.includes) {
Spec<RelativePath> patternMatcher = PatternMatcherFactory.getPatternMatcher(true, caseSensitive, include);
matchers.add(patternMatcher);
}
return Specs.or(true, matchers);
}
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import java.io.File;
import java.io.FileFilter;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourceRootDescriptor extends BuildRootDescriptor {
private final GradleResourcesTarget myTarget;
private final ResourceRootConfiguration myConfig;
private final File myFile;
private final String myId;
private final boolean myOverwrite;
private final int myIndexInPom;
public GradleResourceRootDescriptor(@NotNull GradleResourcesTarget target,
ResourceRootConfiguration config,
int indexInPom,
boolean overwrite) {
myTarget = target;
myConfig = config;
final String path = FileUtil.toCanonicalPath(config.directory);
myFile = new File(path);
myId = path;
myIndexInPom = indexInPom;
myOverwrite = overwrite;
}
public ResourceRootConfiguration getConfiguration() {
return myConfig;
}
@Override
public String getRootId() {
return myId;
}
@Override
public File getRootFile() {
return myFile;
}
@Override
public GradleResourcesTarget getTarget() {
return myTarget;
}
@NotNull
@Override
public FileFilter createFileFilter() {
return new GradleResourceFileFilter(myFile, myConfig);
}
@Override
public boolean canUseFileCache() {
return true;
}
public int getIndexInPom() {
return myIndexInPom;
}
public boolean isOverwrite() {
return myOverwrite;
}
}
@@ -0,0 +1,161 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.indices.IgnoredFileIndex;
import org.jetbrains.jps.indices.ModuleExcludeIndex;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
import java.io.PrintWriter;
import java.util.*;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourcesTarget extends ModuleBasedTarget<GradleResourceRootDescriptor> {
GradleResourcesTarget(final GradleResourcesTargetType type, @NotNull JpsModule module) {
super(type, module);
}
@Override
public String getId() {
return myModule.getName();
}
@Override
public Collection<BuildTarget<?>> computeDependencies(BuildTargetRegistry targetRegistry, TargetOutputIndex outputIndex) {
return Collections.emptyList();
}
@Override
public boolean isCompiledBeforeModuleLevelBuilders() {
return true;
}
@NotNull
@Override
public List<GradleResourceRootDescriptor> computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex, BuildDataPaths dataPaths) {
final List<GradleResourceRootDescriptor> result = new ArrayList<GradleResourceRootDescriptor>();
GradleProjectConfiguration projectConfig = JpsGradleExtensionService.getInstance().getGradleProjectConfiguration(dataPaths);
GradleModuleResourceConfiguration moduleConfig = projectConfig.moduleConfigurations.get(myModule.getName());
if (moduleConfig == null) return Collections.emptyList();
int i = 0;
for (ResourceRootConfiguration resource : getRootConfigurations(moduleConfig)) {
result.add(new GradleResourceRootDescriptor(this, resource, i++, moduleConfig.overwrite));
}
return result;
}
private Collection<ResourceRootConfiguration> getRootConfigurations(@Nullable GradleModuleResourceConfiguration moduleConfig) {
if (moduleConfig != null) {
return isTests() ? moduleConfig.testResources : moduleConfig.resources;
}
return Collections.emptyList();
}
public GradleModuleResourceConfiguration getModuleResourcesConfiguration(BuildDataPaths dataPaths) {
final GradleProjectConfiguration projectConfig = JpsGradleExtensionService.getInstance().getGradleProjectConfiguration(dataPaths);
return projectConfig.moduleConfigurations.get(myModule.getName());
}
public boolean isTests() {
return ((GradleResourcesTargetType)getTargetType()).isTests();
}
@Nullable
@Override
public GradleResourceRootDescriptor findRootDescriptor(String rootId, BuildRootIndex rootIndex) {
for (GradleResourceRootDescriptor descriptor : rootIndex.getTargetRoots(this, null)) {
if (descriptor.getRootId().equals(rootId)) {
return descriptor;
}
}
return null;
}
@NotNull
@Override
public String getPresentableName() {
return getTargetType().getTypeId() + ":" + myModule.getName();
}
@NotNull
@Override
public Collection<File> getOutputRoots(CompileContext context) {
GradleModuleResourceConfiguration configuration =
getModuleResourcesConfiguration(context.getProjectDescriptor().dataManager.getDataPaths());
final Set<File> result = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
final File moduleOutput = getModuleOutputDir();
for (ResourceRootConfiguration resConfig : getRootConfigurations(configuration)) {
final File output = getOutputDir(moduleOutput, resConfig, configuration.outputDirectory);
if (output != null) {
result.add(output);
}
}
return result;
}
@Nullable
public File getModuleOutputDir() {
return JpsJavaExtensionService.getInstance().getOutputDirectory(myModule, isTests());
}
@Nullable
public static File getOutputDir(@Nullable File moduleOutput, ResourceRootConfiguration config, @Nullable String outputDirectory) {
if(outputDirectory != null) {
moduleOutput = JpsPathUtil.urlToFile(outputDirectory);
}
if (moduleOutput == null) {
return null;
}
String targetPath = config.targetPath;
if (StringUtil.isEmptyOrSpaces(targetPath)) {
return moduleOutput;
}
final File targetPathFile = new File(targetPath);
final File outputFile = targetPathFile.isAbsolute() ? targetPathFile : new File(moduleOutput, targetPath);
return new File(FileUtil.toCanonicalPath(outputFile.getPath()));
}
@Override
public void writeConfiguration(ProjectDescriptor pd, PrintWriter out) {
final BuildDataPaths dataPaths = pd.getTargetsState().getDataPaths();
final GradleModuleResourceConfiguration configuration = getModuleResourcesConfiguration(dataPaths);
if (configuration != null) {
out.write(Integer.toHexString(configuration.computeConfigurationHash(isTests())));
}
}
}
@@ -0,0 +1,78 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTargetLoader;
import org.jetbrains.jps.builders.ModuleBasedBuildTargetType;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.module.JpsModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourcesTargetType extends ModuleBasedBuildTargetType<GradleResourcesTarget> {
public static final GradleResourcesTargetType PRODUCTION = new GradleResourcesTargetType("gradle-resources-production", false);
public static final GradleResourcesTargetType TEST = new GradleResourcesTargetType("gradle-resources-test", true);
private final boolean myIsTests;
private GradleResourcesTargetType(final String typeId, boolean isTests) {
super(typeId);
myIsTests = isTests;
}
public boolean isTests() {
return myIsTests;
}
@NotNull
@Override
public List<GradleResourcesTarget> computeAllTargets(@NotNull JpsModel model) {
final List<GradleResourcesTarget> targets = new ArrayList<GradleResourcesTarget>();
for (JpsModule module : model.getProject().getModules()) {
if (JpsGradleExtensionService.getInstance().getExtension(module) != null) {
targets.add(new GradleResourcesTarget(this, module));
}
}
return targets;
}
@NotNull
@Override
public BuildTargetLoader<GradleResourcesTarget> createLoader(@NotNull JpsModel model) {
final Map<String, JpsModule> modules = new HashMap<String, JpsModule>();
for (JpsModule module : model.getProject().getModules()) {
modules.put(module.getName(), module);
}
return new BuildTargetLoader<GradleResourcesTarget>() {
@Nullable
@Override
public GradleResourcesTarget createTarget(@NotNull String targetId) {
final JpsModule module = modules.get(targetId);
return module != null ? new GradleResourcesTarget(GradleResourcesTargetType.this, module) : null;
}
};
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.model.java.impl.JpsJavaDependenciesEnumerationHandler;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import java.util.Collection;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class JpsGradleDependenciesEnumerationHandler extends JpsJavaDependenciesEnumerationHandler {
private static final JpsGradleDependenciesEnumerationHandler INSTANCE = new JpsGradleDependenciesEnumerationHandler();
@Override
public boolean shouldAddRuntimeDependenciesToTestCompilationClasspath() {
return true;
}
@Override
public boolean isProductionOnTestsDependency(JpsDependencyElement element) {
return JpsGradleExtensionService.getInstance().isProductionOnTestDependency(element);
}
public static class GradleFactory extends Factory {
@Nullable
@Override
public JpsJavaDependenciesEnumerationHandler createHandler(@NotNull Collection<JpsModule> modules) {
JpsGradleExtensionService service = JpsGradleExtensionService.getInstance();
for (JpsModule module : modules) {
if (service.getExtension(module) != null) {
return INSTANCE;
}
}
return null;
}
}
}
@@ -0,0 +1,136 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.xmlb.XmlSerializer;
import gnu.trove.THashMap;
import org.jdom.Document;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.gradle.model.JpsGradleModuleExtension;
import org.jetbrains.jps.incremental.resources.ResourcesBuilder;
import org.jetbrains.jps.incremental.resources.StandardResourceBuilderEnabler;
import org.jetbrains.jps.model.JpsElementChildRole;
import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.File;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class JpsGradleExtensionServiceImpl extends JpsGradleExtensionService {
private static final Logger LOG = Logger.getInstance(JpsGradleExtensionServiceImpl.class);
private static final JpsElementChildRole<JpsSimpleElement<Boolean>> PRODUCTION_ON_TEST_ROLE = JpsElementChildRoleBase.create("production on test");
private final Map<File, GradleProjectConfiguration> myLoadedConfigs =
new THashMap<File, GradleProjectConfiguration>(FileUtil.FILE_HASHING_STRATEGY);
private final FactoryMap<File, Boolean> myConfigFileExists = new ConcurrentFactoryMap<File, Boolean>() {
@Nullable
@Override
protected Boolean create(File key) {
return key.exists();
}
};
public JpsGradleExtensionServiceImpl() {
ResourcesBuilder.registerEnabler(new StandardResourceBuilderEnabler() {
@Override
public boolean isResourceProcessingEnabled(JpsModule module) {
// enable standard resource processing only if this is not a gradle module
// for gradle modules use gradle-aware resource builder
return getExtension(module) == null;
}
});
}
@Nullable
@Override
public JpsGradleModuleExtension getExtension(@NotNull JpsModule module) {
return module.getContainer().getChild(JpsGradleModuleExtensionImpl.ROLE);
}
@NotNull
@Override
public JpsGradleModuleExtension getOrCreateExtension(@NotNull JpsModule module) {
JpsGradleModuleExtension extension = module.getContainer().getChild(JpsGradleModuleExtensionImpl.ROLE);
if (extension == null) {
extension = new JpsGradleModuleExtensionImpl();
module.getContainer().setChild(JpsGradleModuleExtensionImpl.ROLE, extension);
}
return extension;
}
@Override
public void setProductionOnTestDependency(@NotNull JpsDependencyElement dependency, boolean value) {
if (value) {
dependency.getContainer().setChild(PRODUCTION_ON_TEST_ROLE, JpsElementFactory.getInstance().createSimpleElement(true));
}
else {
dependency.getContainer().removeChild(PRODUCTION_ON_TEST_ROLE);
}
}
@Override
public boolean isProductionOnTestDependency(@NotNull JpsDependencyElement dependency) {
JpsSimpleElement<Boolean> child = dependency.getContainer().getChild(PRODUCTION_ON_TEST_ROLE);
return child != null && child.getData();
}
@Override
public boolean hasGradleProjectConfiguration(@NotNull BuildDataPaths paths) {
return myConfigFileExists.get(new File(paths.getDataStorageRoot(), GradleProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH));
}
@NotNull
@Override
public GradleProjectConfiguration getGradleProjectConfiguration(BuildDataPaths paths) {
final File dataStorageRoot = paths.getDataStorageRoot();
return getGradleProjectConfiguration(dataStorageRoot);
}
@NotNull
public GradleProjectConfiguration getGradleProjectConfiguration(@NotNull File dataStorageRoot) {
final File configFile = new File(dataStorageRoot, GradleProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH);
GradleProjectConfiguration config;
synchronized (myLoadedConfigs) {
config = myLoadedConfigs.get(configFile);
if (config == null) {
config = new GradleProjectConfiguration();
try {
final Document document = JDOMUtil.loadDocument(configFile);
XmlSerializer.deserializeInto(config, document.getRootElement());
}
catch (Exception e) {
LOG.info(e);
}
myLoadedConfigs.put(configFile, config);
}
}
return config;
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.gradle.model.JpsGradleExtensionService;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class JpsGradleModelSerializationExtension extends JpsModelSerializerExtension {
private static final String PRODUCTION_ON_TEST_ATTRIBUTE = "production-on-test";
@Override
public void loadModuleOptions(@NotNull JpsModule module, @NotNull Element rootElement) {
if ("GRADLE".equals(rootElement.getAttributeValue("external.system.id"))) {
JpsGradleExtensionService.getInstance().getOrCreateExtension(module);
}
}
@Override
public void saveModuleOptions(@NotNull JpsModule module, @NotNull Element rootElement) {
if (JpsGradleExtensionService.getInstance().getExtension(module) != null) {
rootElement.setAttribute("external.system.id", "GRADLE");
}
}
@Override
public void loadModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) {
if (orderEntry.getAttributeValue(PRODUCTION_ON_TEST_ATTRIBUTE) != null) {
JpsGradleExtensionService.getInstance().setProductionOnTestDependency(dependency, true);
}
}
@Override
public void saveModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) {
if (JpsGradleExtensionService.getInstance().isProductionOnTestDependency(dependency)) {
orderEntry.setAttribute(PRODUCTION_ON_TEST_ATTRIBUTE, "");
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.gradle.model.JpsGradleModuleExtension;
import org.jetbrains.jps.model.JpsElementChildRole;
import org.jetbrains.jps.model.ex.JpsElementBase;
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class JpsGradleModuleExtensionImpl extends JpsElementBase<JpsGradleModuleExtensionImpl> implements JpsGradleModuleExtension {
public static final JpsElementChildRole<JpsGradleModuleExtension> ROLE = JpsElementChildRoleBase.create("gradle");
public JpsGradleModuleExtensionImpl() {
}
@NotNull
@Override
public JpsGradleModuleExtensionImpl createCopy() {
return new JpsGradleModuleExtensionImpl();
}
@Override
public void applyChanges(@NotNull JpsGradleModuleExtensionImpl modified) {
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.util.xmlb.annotations.Tag;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class ModuleVersion {
@Tag("groupId")
public String groupId;
@Tag("artifactId")
public String artifactId;
@Tag("version")
public String version;
public ModuleVersion() {
}
public ModuleVersion(String groupId, String artifactId, String version) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ModuleVersion bean = (ModuleVersion)o;
if (artifactId != null ? !artifactId.equals(bean.artifactId) : bean.artifactId != null) return false;
if (groupId != null ? !groupId.equals(bean.groupId) : bean.groupId != null) return false;
if (version != null ? !version.equals(bean.version) : bean.version != null) return false;
return true;
}
@Override
public int hashCode() {
int result = groupId != null ? groupId.hashCode() : 0;
result = 31 * result + (artifactId != null ? artifactId.hashCode() : 0);
result = 31 * result + (version != null ? version.hashCode() : 0);
return result;
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
@Tag("resource")
public class ResourceRootConfiguration extends FilePattern {
@Tag("directory")
@NotNull
public String directory;
@Tag("targetPath")
@Nullable
public String targetPath;
@Attribute("filtered")
public boolean isFiltered;
@Tag("filters")
@AbstractCollection(surroundWithTag = false, elementTag = "filter")
public List<ResourceRootFilter> filters = new ArrayList<ResourceRootFilter>();
public int computeConfigurationHash() {
int result = directory.hashCode();
result = 31 * result + (targetPath != null ? targetPath.hashCode() : 0);
result = 31 * result + (isFiltered ? 1 : 0);
result = 31 * result + includes.hashCode();
result = 31 * result + excludes.hashCode();
for (ResourceRootFilter filter : filters) {
result = 31 * result + filter.computeConfigurationHash();
}
return result;
}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.gradle.model.impl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Vladislav.Soroka
* @since 7/22/2014
*/
@Tag("filter")
public class ResourceRootFilter {
@Tag("filterType")
@NotNull
public String filterType;
@Tag("properties")
@NotNull
public String properties;
private transient Map<Object, Object> propertiesMap;
public int computeConfigurationHash() {
int result = filterType.hashCode();
result = 31 * result + properties.hashCode();
return result;
}
@NotNull
public Map<Object, Object> getProperties() {
if (propertiesMap == null) {
try {
Gson gson = new GsonBuilder().create();
propertiesMap = gson.fromJson(
properties,
new TypeToken<Map<Object, Object>>() {
}.getType());
if("RenamingCopyFilter".equals(filterType)) {
final Object pattern = propertiesMap.get("pattern");
final Matcher matcher = Pattern.compile(pattern instanceof String ? (String)pattern : "").matcher("");
propertiesMap.put("matcher", matcher);
}
}
catch (JsonSyntaxException e) {
throw new RuntimeException("Unsupported filter: " + properties , e);
} catch (JsonParseException e) {
throw new RuntimeException("Unsupported filter: " + properties , e);
}
}
return propertiesMap;
}
}
@@ -21,7 +21,6 @@
<postStartupActivity implementation="org.jetbrains.plugins.gradle.integrations.maven.GradleProjectStartupActivity"/>
<externalSystemTaskNotificationListener
implementation="org.jetbrains.plugins.gradle.integrations.maven.GradleMavenProjectImportNotificationListener"/>
<externalProjectDataService implementation="com.intellij.openapi.externalSystem.service.project.manage.ModuleDataService"/>
<completion.contributor language="Groovy" order="first"
implementationClass="org.jetbrains.plugins.gradle.integrations.maven.codeInsight.completion.MavenDependenciesGradleCompletionContributor"/>
</extensions>
+6
View File
@@ -67,6 +67,11 @@
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="org.jetbrains.plugins.gradle.service.project.GradleStartupActivity"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler$FactoryImpl"/>
<compileServer.plugin classpath="gradle-jps-plugin.jar"/>
<buildProcess.parametersProvider implementation="org.jetbrains.plugins.gradle.compiler.GradleBuildProcessParametersProvider"/>
<resolveScopeEnlarger implementation="org.jetbrains.plugins.gradle.config.GradleBuildClasspathResolveScopeEnlarger"/>
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
@@ -95,6 +100,7 @@
<externalSystemConfigLocator implementation="org.jetbrains.plugins.gradle.service.settings.GradleConfigLocator"/>
<externalSystemManager implementation="org.jetbrains.plugins.gradle.GradleManager"/>
<externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.BuildClasspathModuleGradleDataService"/>
<externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService"/>
<externalSystemNotificationExtension implementation="org.jetbrains.plugins.gradle.service.notification.GradleNotificationExtension" order="last"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.plugins.gradle.service.project.GradleProjectImportNotificationListener"/>
@@ -0,0 +1,93 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.compiler;
import com.google.gson.Gson;
import com.intellij.compiler.server.BuildProcessParametersProvider;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import groovy.lang.GroovyObject;
import org.apache.tools.ant.taskdefs.Ant;
import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.io.File;
import java.util.List;
/**
* Adds Gradle build dependencies to the project build process' classpath if it has at least one gradle module.
*
* @author Vladislav.Soroka
* @since 7/22/2014
*/
public class GradleBuildProcessParametersProvider extends BuildProcessParametersProvider {
@NotNull private final Project myProject;
private List<String> myClasspath;
public GradleBuildProcessParametersProvider(@NotNull Project project) {
myProject = project;
}
@Override
@NotNull
public List<String> getClassPath() {
if (myClasspath == null) {
final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
for (Module module : moduleManager.getModules()) {
if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) {
myClasspath = ContainerUtil.newArrayList();
addGradleClassPath(myClasspath);
addOtherClassPath(myClasspath);
break;
}
}
}
return myClasspath;
}
private static void addGradleClassPath(@NotNull final List<String> classpath) {
String gradleLibDirPath = null;
String gradleToolingApiJarPath = PathUtil.getJarPathForClass(ProjectConnection.class);
if (!StringUtil.isEmpty(gradleToolingApiJarPath)) {
gradleLibDirPath = PathUtil.getParentPath(gradleToolingApiJarPath);
}
if (gradleLibDirPath == null || gradleLibDirPath.isEmpty()) return;
File gradleLibDir = new File(gradleLibDirPath);
if (!gradleLibDir.isDirectory()) return;
File[] children = FileUtil.notNullize(gradleLibDir.listFiles());
for (File child : children) {
if (child.isFile() && child.getName().endsWith(".jar")) {
classpath.add(child.getAbsolutePath());
}
}
}
private static void addOtherClassPath(@NotNull final List<String> classpath) {
classpath.add(PathUtil.getJarPathForClass(Ant.class));
classpath.add(PathUtil.getJarPathForClass(GroovyObject.class));
classpath.add(PathUtil.getJarPathForClass(Gson.class));
}
}
@@ -0,0 +1,186 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.config;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ExternalFilter;
import com.intellij.openapi.externalSystem.model.ExternalProject;
import com.intellij.openapi.externalSystem.model.ExternalSourceDirectorySet;
import com.intellij.openapi.externalSystem.model.ExternalSourceSet;
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Document;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.gradle.model.impl.*;
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/10/2014
*/
public class GradleResourceCompilerConfigurationGenerator {
private static Logger LOG = Logger.getInstance(GradleResourceCompilerConfigurationGenerator.class);
@NotNull private final Project myProject;
@NotNull private final CompileContext myContext;
@NotNull private final Map<String, ExternalProject> myExternalProjectMap;
private final ExternalProjectDataService myExternalProjectDataService;
public GradleResourceCompilerConfigurationGenerator(@NotNull final Project project, @NotNull final CompileContext context) {
myProject = project;
myContext = context;
myExternalProjectDataService =
(ExternalProjectDataService)ServiceManager.getService(ProjectDataManager.class).getDataService(ExternalProjectDataService.KEY);
assert myExternalProjectDataService != null;
myExternalProjectMap = new FactoryMap<String, ExternalProject>() {
@Nullable
@Override
protected ExternalProject create(String gradleProjectPath) {
return myExternalProjectDataService.getOrImportRootExternalProject(project, GradleConstants.SYSTEM_ID, new File(gradleProjectPath));
}
};
}
public void generateBuildConfiguration() {
if (!hasGradleModules()) return;
final BuildManager buildManager = BuildManager.getInstance();
final File projectSystemDir = buildManager.getProjectSystemDirectory(myProject);
if (projectSystemDir == null) return;
final File gradleConfigFile = new File(projectSystemDir, GradleProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH);
GradleProjectConfiguration projectConfig = new GradleProjectConfiguration();
for (Module module : myContext.getCompileScope().getAffectedModules()) {
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) continue;
final String gradleProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
assert gradleProjectPath != null;
final ExternalProject externalRootProject = myExternalProjectMap.get(gradleProjectPath);
if (externalRootProject == null) {
myContext.addMessage(CompilerMessageCategory.ERROR,
String.format("Unable to make the module: %s, related gradle module configuration was not imported",
module.getName()),
VfsUtilCore.pathToUrl(gradleProjectPath), -1, -1);
continue;
}
ExternalProject externalProject = myExternalProjectDataService.findExternalProject(externalRootProject, module);
if (externalProject == null) {
LOG.warn("Unable to find config for module: " + module.getName());
continue;
}
final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
assert compilerModuleExtension != null;
GradleModuleResourceConfiguration resourceConfig = new GradleModuleResourceConfiguration();
resourceConfig.id = new ModuleVersion(externalProject.getGroup(), externalProject.getName(), externalProject.getVersion());
resourceConfig.directory = FileUtil.toSystemIndependentName(externalProject.getProjectDir().getPath());
final ExternalSourceSet mainSourcesSet = externalProject.getSourceSets().get("main");
addResources(resourceConfig.resources, mainSourcesSet, ExternalSystemSourceType.RESOURCE);
final ExternalSourceSet testSourcesSet = externalProject.getSourceSets().get("test");
addResources(resourceConfig.testResources, testSourcesSet, ExternalSystemSourceType.TEST_RESOURCE);
projectConfig.moduleConfigurations.put(module.getName(), resourceConfig);
}
final Document document = new Document(new Element("gradle-project-configuration"));
XmlSerializer.serializeInto(projectConfig, document.getRootElement());
buildManager.runCommand(new Runnable() {
@Override
public void run() {
buildManager.clearState(myProject);
FileUtil.createIfDoesntExist(gradleConfigFile);
try {
JDOMUtil.writeDocument(document, gradleConfigFile, "\n");
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
private boolean hasGradleModules() {
for (Module module : myContext.getCompileScope().getAffectedModules()) {
if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return true;
}
return false;
}
private static void addResources(@NotNull List<ResourceRootConfiguration> container,
@Nullable ExternalSourceSet externalSourceSet,
@NotNull ExternalSystemSourceType sourceType) {
if (externalSourceSet == null) return;
final ExternalSourceDirectorySet directorySet = externalSourceSet.getSources().get(sourceType);
if (directorySet == null) return;
for (File file : directorySet.getSrcDirs()) {
final String dir = file.getPath();
final ResourceRootConfiguration rootConfiguration = new ResourceRootConfiguration();
rootConfiguration.directory = FileUtil.toSystemIndependentName(dir);
final String target = directorySet.getOutputDir().getPath();
rootConfiguration.targetPath = FileUtil.toSystemIndependentName(target);
rootConfiguration.includes.clear();
for (String include : directorySet.getIncludes()) {
rootConfiguration.includes.add(include.trim());
}
rootConfiguration.excludes.clear();
for (String exclude : directorySet.getExcludes()) {
rootConfiguration.excludes.add(exclude.trim());
}
rootConfiguration.isFiltered = !directorySet.getFilters().isEmpty();
rootConfiguration.filters.clear();
for (ExternalFilter filter : directorySet.getFilters()) {
final ResourceRootFilter resourceRootFilter = new ResourceRootFilter();
resourceRootFilter.filterType = filter.getFilterType();
resourceRootFilter.properties = filter.getPropertiesAsJsonMap();
rootConfiguration.filters.add(resourceRootFilter);
}
container.add(rootConfiguration);
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.execution;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ExternalProject;
import com.intellij.openapi.externalSystem.model.ExternalSourceDirectorySet;
import com.intellij.openapi.externalSystem.model.ExternalSourceSet;
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.OrderEnumerationHandler;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.vfs.VfsUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.io.File;
import java.util.Collection;
public class GradleOrderEnumeratorHandler extends OrderEnumerationHandler {
private static final Logger LOG = Logger.getInstance(GradleOrderEnumeratorHandler.class);
public static class FactoryImpl extends Factory {
@Override
public boolean isApplicable(@NotNull Project project) {
return true;
}
@Override
public boolean isApplicable(@NotNull Module module) {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module);
}
@Override
public OrderEnumerationHandler createHandler(@Nullable Module module) {
return INSTANCE;
}
}
private static final GradleOrderEnumeratorHandler INSTANCE = new GradleOrderEnumeratorHandler();
@Override
public boolean addCustomModuleRoots(@NotNull OrderRootType type,
@NotNull ModuleRootModel rootModel,
@NotNull Collection<String> result,
boolean includeProduction,
boolean includeTests) {
if (!type.equals(OrderRootType.CLASSES)) return false;
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.getModule())) return false;
final String gradleProjectPath = rootModel.getModule().getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
if (gradleProjectPath == null) {
LOG.error("Root project path of the Gradle project not found for " + rootModel.getModule());
return false;
}
final ExternalProjectDataService externalProjectDataService =
(ExternalProjectDataService)ServiceManager.getService(ProjectDataManager.class).getDataService(ExternalProjectDataService.KEY);
assert externalProjectDataService != null;
final ExternalProject externalRootProject =
externalProjectDataService.getRootExternalProject(GradleConstants.SYSTEM_ID, new File(gradleProjectPath));
if (externalRootProject == null) {
LOG.debug("Root external project was not yep imported for the project path: " + gradleProjectPath);
return false;
}
ExternalProject externalProject = externalProjectDataService.findExternalProject(externalRootProject, rootModel.getModule());
if (externalProject == null) return false;
if (includeProduction) {
addSourceRoots(externalProject.getSourceSets().get("main"), ExternalSystemSourceType.RESOURCE, result);
}
if (includeTests) {
addSourceRoots(externalProject.getSourceSets().get("test"), ExternalSystemSourceType.TEST_RESOURCE, result);
}
return true;
}
private static void addSourceRoots(@Nullable ExternalSourceSet externalSourceSet,
@NotNull ExternalSystemSourceType sourceType,
@NotNull Collection<String> result) {
if (externalSourceSet == null) return;
final ExternalSourceDirectorySet directorySet = externalSourceSet.getSources().get(sourceType);
if (directorySet == null) return;
for (File file : directorySet.getSrcDirs()) {
result.add(VfsUtilCore.pathToUrl(file.getAbsolutePath()));
}
}
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.util.KeyValue;
import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -80,6 +81,11 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
return nextResolver.createJavaProjectData();
}
@Override
public void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject) {
nextResolver.populateProjectExtraModels(gradleProject, ideProject);
}
@NotNull
@Override
public ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData) {
@@ -15,14 +15,13 @@
*/
package org.jetbrains.plugins.gradle.service.project;
import com.google.gson.GsonBuilder;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.externalSystem.JavaProjectData;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -56,6 +55,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
import org.jetbrains.plugins.gradle.tooling.internal.init.Init;
import org.jetbrains.plugins.gradle.util.GradleBundle;
@@ -79,6 +79,8 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
private static final Logger LOG = Logger.getInstance("#" + BaseGradleProjectResolverExtension.class.getName());
@NotNull @NonNls private static final String UNRESOLVED_DEPENDENCY_PREFIX = "unresolved dependency - ";
private static final String MAIN_SOURCE_SET = "main";
private static final String TEST_SOURCE_SET = "test";
@NotNull private ProjectResolverContext resolverCtx;
@NotNull private final BaseProjectImportErrorHandler myErrorHandler = new BaseProjectImportErrorHandler();
@@ -120,6 +122,14 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
return javaProjectData;
}
@Override
public void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject) {
final ExternalProject externalProject = resolverCtx.getExtraProject(ExternalProject.class);
if (externalProject != null) {
ideProject.createChild(ExternalProjectDataService.KEY, externalProject);
}
}
@NotNull
@Override
public ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData) {
@@ -220,6 +230,8 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
File sourceCompileOutputPath = null;
File testCompileOutputPath = null;
File resourceCompileOutputPath;
File testResourceCompileOutputPath;
boolean inheritOutputDirs = false;
ModuleData moduleData = ideModule.getData();
@@ -229,30 +241,71 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
inheritOutputDirs = moduleCompilerOutput.getInheritOutputDirs();
}
ExternalProject externalProject = resolverCtx.getExtraProject(gradleModule, ExternalProject.class);
if (externalProject != null) {
externalProject = new DefaultExternalProject(externalProject);
}
if (!inheritOutputDirs && (sourceCompileOutputPath == null || testCompileOutputPath == null)) {
ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
if (moduleExtendedModel != null) {
ExtIdeaCompilerOutput output = moduleExtendedModel.getCompilerOutput();
if (output != null) {
if (sourceCompileOutputPath == null) {
sourceCompileOutputPath = output.getMainClassesDir();
}
if (testCompileOutputPath == null) {
testCompileOutputPath = output.getTestClassesDir();
sourceCompileOutputPath = getCompileOutputPath(externalProject, MAIN_SOURCE_SET, ExternalSystemSourceType.SOURCE);
resourceCompileOutputPath = getCompileOutputPath(externalProject, MAIN_SOURCE_SET, ExternalSystemSourceType.RESOURCE);
testCompileOutputPath = getCompileOutputPath(externalProject, TEST_SOURCE_SET, ExternalSystemSourceType.TEST);
testResourceCompileOutputPath = getCompileOutputPath(externalProject, TEST_SOURCE_SET, ExternalSystemSourceType.TEST_RESOURCE);
}
else {
resourceCompileOutputPath = sourceCompileOutputPath;
testResourceCompileOutputPath = testCompileOutputPath;
if (externalProject != null) {
final ExternalSourceSet mainSourceSet = externalProject.getSourceSets().get(MAIN_SOURCE_SET);
if (mainSourceSet != null) {
final ExternalSourceDirectorySet resourceDirectories = mainSourceSet.getSources().get(ExternalSystemSourceType.RESOURCE);
if (resourceDirectories instanceof DefaultExternalSourceDirectorySet) {
((DefaultExternalSourceDirectorySet)resourceDirectories).setOutputDir(sourceCompileOutputPath);
}
}
final ExternalSourceSet testSourceSet = externalProject.getSourceSets().get(TEST_SOURCE_SET);
if (testSourceSet != null) {
final ExternalSourceDirectorySet testResourceDirectories = testSourceSet.getSources().get(ExternalSystemSourceType.TEST_RESOURCE);
if (testResourceDirectories instanceof DefaultExternalSourceDirectorySet) {
((DefaultExternalSourceDirectorySet)testResourceDirectories).setOutputDir(testCompileOutputPath);
}
}
final DataNode<ProjectData> projectDataNode = ExternalSystemApiUtil.findParent(ideModule, ProjectKeys.PROJECT);
assert projectDataNode != null;
projectDataNode.createOrReplaceChild(ExternalProjectDataService.KEY, externalProject);
}
}
if (sourceCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.SOURCE, sourceCompileOutputPath.getAbsolutePath());
}
if (resourceCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.RESOURCE, resourceCompileOutputPath.getAbsolutePath());
}
if (testCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.TEST, testCompileOutputPath.getAbsolutePath());
}
if (testResourceCompileOutputPath != null) {
moduleData.setCompileOutputPath(ExternalSystemSourceType.TEST_RESOURCE, testResourceCompileOutputPath.getAbsolutePath());
}
moduleData.setInheritProjectCompileOutputPath(inheritOutputDirs || sourceCompileOutputPath == null);
}
@Nullable
private static File getCompileOutputPath(@Nullable ExternalProject externalProject,
@NotNull String sourceSetName,
@NotNull ExternalSystemSourceType sourceType) {
if (externalProject == null) return null;
final ExternalSourceSet sourceSet = externalProject.getSourceSets().get(sourceSetName);
if(sourceSet == null) return null;
final ExternalSourceDirectorySet directorySet = sourceSet.getSources().get(sourceType);
return directorySet != null ? directorySet.getOutputDir() : null;
}
@Override
public void populateModuleDependencies(@NotNull IdeaModule gradleModule,
@NotNull DataNode<ModuleData> ideModule,
@@ -319,17 +372,19 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
@Override
public Set<Class> getExtraProjectModelClasses() {
return ContainerUtil.<Class>set(
GradleBuild.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
GradleBuild.class, ExternalProject.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
}
@NotNull
@Override
public Set<Class> getToolingExtensionsClasses() {
return ContainerUtil.<Class>set(
ExternalProject.class,
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class
ModelBuildScriptClasspathBuilderImpl.class,
GsonBuilder.class
);
}
@@ -199,6 +199,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectDataNode.createChild(JavaProjectData.KEY, javaProjectData);
IdeaProject ideaProject = resolverCtx.getModels().getIdeaProject();
projectResolverChain.populateProjectExtraModels(ideaProject, projectDataNode);
DomainObjectSet<? extends IdeaModule> gradleModules = ideaProject.getModules();
if (gradleModules == null || gradleModules.isEmpty()) {
throw new IllegalStateException("No modules found for the target project: " + ideaProject);
@@ -27,6 +27,7 @@ import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
import com.intellij.openapi.util.KeyValue;
import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.GradleManager;
@@ -62,6 +63,8 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
@NotNull
JavaProjectData createJavaProjectData();
void populateProjectExtraModels(@NotNull IdeaProject gradleProject, @NotNull DataNode<ProjectData> ideProject);
@NotNull
ModuleData createModule(@NotNull IdeaModule gradleModule, @NotNull ProjectData projectData);
@@ -21,6 +21,11 @@ import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileTask;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
@@ -30,6 +35,8 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.project.MavenResourceCompilerConfigurationGenerator;
import org.jetbrains.plugins.gradle.config.GradleResourceCompilerConfigurationGenerator;
import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder;
import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider;
@@ -52,9 +59,22 @@ public class GradleStartupActivity implements StartupActivity {
private static final String DO_NOT_SHOW_EVENT_DESCRIPTION = "do.not.show";
@Override
public void runActivity(@NotNull Project project) {
public void runActivity(@NotNull final Project project) {
configureBuildClasspath(project);
showNotificationForUnlinkedGradleProject(project);
CompilerManager.getInstance(project).addBeforeTask(new CompileTask() {
@Override
public boolean execute(CompileContext context) {
AccessToken token = ReadAction.start();
try {
new GradleResourceCompilerConfigurationGenerator(project, context).generateBuildConfiguration();
}
finally {
token.finish();
}
return true;
}
});
}
private static void configureBuildClasspath(@NotNull final Project project) {
@@ -19,6 +19,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
@@ -93,7 +94,12 @@ public class ProjectResolverContext {
}
@Nullable
public <T> T getExtraProject(@NotNull IdeaModule module, Class<T> modelClazz) {
public <T> T getExtraProject(Class<T> modelClazz) {
return myModels.getExtraProject(null, modelClazz);
}
@Nullable
public <T> T getExtraProject(@Nullable IdeaModule module, Class<T> modelClazz) {
return myModels.getExtraProject(module, modelClazz);
}
@@ -0,0 +1,233 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.service.project.data;
import com.intellij.CommonBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.*;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask;
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager;
import com.intellij.openapi.externalSystem.service.notification.NotificationSource;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Collection;
import java.util.Map;
/**
* @author Vladislav.Soroka
* @since 7/17/2014
*/
@Order(ExternalSystemConstants.BUILTIN_SERVICE_ORDER)
public class ExternalProjectDataService implements ProjectDataService<ExternalProject, Project> {
private static final Logger LOG = Logger.getInstance(ExternalProjectDataService.class);
@NotNull public static final Key<ExternalProject> KEY = Key.create(ExternalProject.class, ProjectKeys.TASK.getProcessingWeight() + 1);
@NotNull private final Map<Pair<ProjectSystemId, File>, ExternalProject> myExternalRootProjects;
@NotNull private ProjectDataManager myProjectDataManager;
public ExternalProjectDataService(@NotNull ProjectDataManager projectDataManager) {
myProjectDataManager = projectDataManager;
myExternalRootProjects = new ConcurrentFactoryMap<Pair<ProjectSystemId, File>, ExternalProject>() {
@Nullable
@Override
protected ExternalProject create(Pair<ProjectSystemId, File> key) {
return new ExternalProjectSerializer().load(key.first, key.second);
}
@Override
public ExternalProject put(Pair<ProjectSystemId, File> key, ExternalProject value) {
new ExternalProjectSerializer().save(value);
return super.put(key, value);
}
};
}
@NotNull
@Override
public Key<ExternalProject> getTargetDataKey() {
return KEY;
}
public void importData(@NotNull final Collection<DataNode<ExternalProject>> toImport,
@NotNull final Project project,
final boolean synchronous) {
if (toImport.size() != 1) {
throw new IllegalArgumentException(
String.format("Expected to get a single external project but got %d: %s", toImport.size(), toImport));
}
saveExternalProject(toImport.iterator().next().getData());
}
@Override
public void removeData(@NotNull final Collection<? extends Project> modules, @NotNull Project project, boolean synchronous) {
}
@Nullable
public ExternalProject getOrImportRootExternalProject(@NotNull Project project,
@NotNull ProjectSystemId systemId,
@NotNull File projectRootDir) {
final ExternalProject externalProject = getRootExternalProject(systemId, projectRootDir);
return externalProject != null ? externalProject : importExternalProject(project, systemId, projectRootDir);
}
@Nullable
private ExternalProject importExternalProject(@NotNull final Project project,
@NotNull final ProjectSystemId projectSystemId,
@NotNull final File projectRootDir) {
final Boolean result = UIUtil.invokeAndWaitIfNeeded(new Computable<Boolean>() {
@Override
public Boolean compute() {
final Ref<Boolean> result = new Ref<Boolean>(false);
if (project.isDisposed()) return false;
final String linkedProjectPath = FileUtil.toCanonicalPath(projectRootDir.getPath());
final ExternalProjectSettings projectSettings =
ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectSettings(linkedProjectPath);
if (projectSettings == null) {
LOG.warn("Unable to get project settings for project path: " + linkedProjectPath);
if (LOG.isDebugEnabled()) {
LOG.debug("Available projects paths: " + ContainerUtil.map(
ExternalSystemApiUtil.getSettings(project, projectSystemId).getLinkedProjectsSettings(),
new Function<ExternalProjectSettings, String>() {
@Override
public String fun(ExternalProjectSettings settings) {
return settings.getExternalProjectPath();
}
}));
}
return false;
}
final File projectFile = new File(linkedProjectPath);
final String projectName;
if (projectFile.isFile()) {
projectName = projectFile.getParentFile().getName();
}
else {
projectName = projectFile.getName();
}
// ask a user for the project import if auto-import is disabled
if (!projectSettings.isUseAutoImport()) {
String message = String.format("Project '%s' require synchronization with %s configuration. \nImport the project?",
projectName, projectSystemId.getReadableName());
int returnValue = Messages.showOkCancelDialog(
message, "Import Project", CommonBundle.getOkButtonText(), CommonBundle.getCancelButtonText(), Messages.getQuestionIcon()
);
if (returnValue != Messages.OK) return false;
}
final String title = ExternalSystemBundle.message("progress.import.text", linkedProjectPath, projectSystemId.getReadableName());
new Task.Modal(project, title, false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
if (project.isDisposed()) return;
ExternalSystemNotificationManager.getInstance(project)
.clearNotifications(null, NotificationSource.PROJECT_SYNC, projectSystemId);
ExternalSystemResolveProjectTask task =
new ExternalSystemResolveProjectTask(projectSystemId, project, linkedProjectPath, false);
task.execute(indicator, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions());
if (project.isDisposed()) return;
final Throwable error = task.getError();
if (error != null) {
ExternalSystemNotificationManager.getInstance(project)
.processExternalProjectRefreshError(error, projectName, projectSystemId);
return;
}
final DataNode<ProjectData> projectDataDataNode = task.getExternalProject();
if (projectDataDataNode == null) return;
final Collection<DataNode<ExternalProject>> nodes = ExternalSystemApiUtil.findAll(projectDataDataNode, KEY);
if (nodes.size() != 1) {
throw new IllegalArgumentException(
String.format("Expected to get a single external project but got %d: %s", nodes.size(), nodes));
}
ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
myProjectDataManager.importData(KEY, nodes, project, true);
}
});
result.set(true);
}
}.queue();
return result.get();
}
});
return result ? getRootExternalProject(projectSystemId, projectRootDir) : null;
}
@Nullable
public ExternalProject getRootExternalProject(@NotNull ProjectSystemId systemId, @NotNull File projectRootDir) {
return myExternalRootProjects.get(Pair.create(systemId, projectRootDir));
}
public void saveExternalProject(@NotNull ExternalProject externalProject) {
myExternalRootProjects.put(
Pair.create(new ProjectSystemId(externalProject.getExternalSystemId()), externalProject.getProjectDir()),
new DefaultExternalProject(externalProject)
);
}
@Nullable
public ExternalProject findExternalProject(@NotNull ExternalProject parentProject, @NotNull Module module) {
String externalProjectId = ExternalSystemApiUtil.getExternalProjectId(module);
return externalProjectId != null ? findExternalProject(parentProject, externalProjectId) : null;
}
@Nullable
private static ExternalProject findExternalProject(@NotNull ExternalProject parentProject, @NotNull String externalProjectId) {
if (parentProject.getQName().equals(externalProjectId)) return parentProject;
if (parentProject.getChildProjects().containsKey(externalProjectId)) {
return parentProject.getChildProjects().get(externalProjectId);
}
for (ExternalProject externalProject : parentProject.getChildProjects().values()) {
final ExternalProject project = findExternalProject(externalProject, externalProjectId);
if (project != null) return project;
}
return null;
}
}
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.compiler;
import com.intellij.compiler.artifacts.ArtifactsTestUtil;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileTask;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.util.io.TestFileSystemItem;
import org.jetbrains.plugins.gradle.config.GradleResourceCompilerConfigurationGenerator;
import org.jetbrains.plugins.gradle.importing.GradleImportingTestCase;
import java.io.File;
/**
* @author Vladislav.Soroka
* @since 7/21/2014
*/
public abstract class GradleCompilingTestCase extends GradleImportingTestCase {
@Override
protected void setUpInWriteAction() throws Exception {
super.setUpInWriteAction();
CompilerManager.getInstance(myProject).addBeforeTask(new CompileTask() {
@Override
public boolean execute(CompileContext context) {
AccessToken token = ReadAction.start();
try {
new GradleResourceCompilerConfigurationGenerator(myProject, context).generateBuildConfiguration();
}
finally {
token.finish();
}
return true;
}
});
}
protected void assertCopied(String path) {
assertTrue(new File(myProjectConfig.getParent().getPath(), path).exists());
}
protected void assertCopied(String path, String content) {
assertCopied(path);
assertSameLinesWithFile(new File(myProjectConfig.getParent().getPath(), path).getPath(), content);
}
protected void assertNotCopied(String path) {
assertFalse(new File(myProjectConfig.getParent().getPath(), path).exists());
}
@Override
protected void assertArtifactOutputPath(String artifactName, String expected) {
final String defaultArtifactOutputPath = ArtifactUtil.getDefaultArtifactOutputPath(artifactName, myProject);
assert defaultArtifactOutputPath != null;
final String basePath = FileUtil.toSystemIndependentName(new File(defaultArtifactOutputPath).getParent());
super.assertArtifactOutputPath(artifactName, basePath + expected);
}
protected void assertArtifactOutputFile(String artifactName, String path, String content) {
final String defaultArtifactOutputPath = ArtifactUtil.getDefaultArtifactOutputPath(artifactName, myProject);
assert defaultArtifactOutputPath != null;
final String basePath = FileUtil.toSystemIndependentName(new File(defaultArtifactOutputPath).getParent());
assertSameLinesWithFile(basePath + path, content);
}
protected void assertArtifactOutputFile(String artifactName, String path) {
final String defaultArtifactOutputPath = ArtifactUtil.getDefaultArtifactOutputPath(artifactName, myProject);
assert defaultArtifactOutputPath != null;
final String basePath = FileUtil.toSystemIndependentName(new File(defaultArtifactOutputPath).getParent());
assertExists(new File(basePath + path));
}
}
@@ -0,0 +1,132 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.compiler;
import org.junit.Test;
/**
* @author Vladislav.Soroka
* @since 7/21/2014
*/
@SuppressWarnings("JUnit4AnnotatedMethodInJUnit3TestCase")
public class GradleResourceFilteringTest extends GradleCompilingTestCase {
@Test
public void testHeadFilter() throws Exception {
createProjectSubFile(
"src/main/resources/dir/file.txt", "1 Header\n" +
"2\n" +
"3 another text\n" +
"4\n" +
"5 another text \n" +
"6 another text @token@ another text\n" +
"7\n" +
"8 Footer");
importProject(
"apply plugin: 'java'\n" +
"\n" +
"import org.apache.tools.ant.filters.*\n" +
"processResources {\n" +
" filter(HeadFilter, lines:3, skip:2)\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopied("build/resources/main/dir/file.txt", "3 another text\n" +
"4\n" +
"5 another text \n");
}
@Test
public void testReplaceTokensFilter() throws Exception {
createProjectSubFile(
"src/main/resources/dir/file.txt", "1 Header\n" +
"2\n" +
"3 #token1#another text\n" +
"4\n" +
"5 another text \n" +
"6 another text #token2# another text\n" +
"7\n" +
"8 Footer");
importProject(
"apply plugin: 'java'\n" +
"\n" +
"import org.apache.tools.ant.filters.*\n" +
"processResources {\n" +
" filter(ReplaceTokens, tokens:[token1:'<11111>', token2:'<2222>'], beginToken: '#', endToken: '#')\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopied("build/resources/main/dir/file.txt", "1 Header\n" +
"2\n" +
"3 <11111>another text\n" +
"4\n" +
"5 another text \n" +
"6 another text <2222> another text\n" +
"7\n" +
"8 Footer");
}
@Test
public void testRenameFilter() throws Exception {
createProjectSubFile("src/main/resources/dir/file.txt");
importProject(
"apply plugin: 'java'\n" +
"\n" +
"import org.apache.tools.ant.filters.*\n" +
"processResources {\n" +
" rename 'file.txt', 'file001.txt'\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopied("build/resources/main/dir/file001.txt");
}
@Test
public void testFiltersChain() throws Exception {
createProjectSubFile(
"src/main/resources/dir/file.txt", "1 Header\n" +
"2\n" +
"3 another text@token1@\n" +
"4\n" +
"5 another text \n" +
"6 another text @token2@ another text\n" +
"7\n" +
"8 Footer");
importProject(
"apply plugin: 'java'\n" +
"\n" +
"import org.apache.tools.ant.filters.*\n" +
"processResources {\n" +
" filter(HeadFilter, lines:4, skip:2)\n" +
" filter(ReplaceTokens, tokens:[token1:'<11111>', token2:'<2222>'])\n" +
" rename 'file.txt', 'file001.txt'\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopied("build/resources/main/dir/file001.txt", "3 another text<11111>\n" +
"4\n" +
"5 another text \n" +
"6 another text <2222> another text");
}
}
@@ -0,0 +1,176 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.compiler;
import org.junit.Test;
import java.io.IOException;
/**
* @author Vladislav.Soroka
* @since 7/21/2014
*/
@SuppressWarnings("JUnit4AnnotatedMethodInJUnit3TestCase")
public class GradleResourceProcessingTest extends GradleCompilingTestCase {
@Test
public void testBasicResourceCopying() throws Exception {
createProjectSubFile("src/main/resources/dir/file.properties");
createProjectSubFile("src/test/resources/dir/file-test.properties");
importProject(
"apply plugin: 'java'"
);
assertModules("project");
compileModules("project");
assertCopied("build/resources/main/dir/file.properties");
assertCopied("build/resources/test/dir/file-test.properties");
}
@Test
public void testResourceProcessingWithIdeaGradlePluginCustomization() throws Exception {
createProjectSubFile("src/main/resources/dir/file.properties");
createProjectSubFile("src/test/resources/dir/file-test.properties");
importProject(
"apply plugin: 'java'\n" +
"apply plugin: 'idea'\n" +
"idea {\n" +
" module {\n" +
" inheritOutputDirs = false\n" +
" outputDir = file('muchBetterOutputDir')\n" +
" testOutputDir = file('muchBetterTestOutputDir')\n" +
" }\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopied("muchBetterOutputDir/dir/file.properties");
assertCopied("muchBetterTestOutputDir/dir/file-test.properties");
}
@Test
public void testIncludesAndExcludesInSourceSets() throws Exception {
createFilesForIncludesAndExcludesTest();
importProject(
"apply plugin: 'java'\n" +
"\n" +
"sourceSets {\n" +
" main {\n" +
" resources {\n" +
" include '**/*.yyy'\n" +
" include '**/*.xxx'\n" +
" exclude 'dir/*.yyy'\n" +
" exclude '*.xxx'\n" +
" }\n" +
" }\n" +
" test {\n" +
" resources {\n" +
" include '**/*.yyy'\n" +
" include '**/*.xxx'\n" +
" exclude 'dir/*.yyy'\n" +
" exclude '*.xxx'\n" +
" }\n" +
" }\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopiedResources();
}
@Test
public void testIncludesAndExcludesInAllSourceSets() throws Exception {
createFilesForIncludesAndExcludesTest();
importProject(
"apply plugin: 'java'\n" +
"\n" +
"sourceSets.all {\n" +
" resources {\n" +
" include '**/*.yyy'\n" +
" include '**/*.xxx'\n" +
" exclude 'dir/*.yyy'\n" +
" exclude '*.xxx'\n" +
" }\n" +
"}"
);
assertModules("project");
compileModules("project");
assertCopiedResources();
}
@Test
public void testIncludesAndExcludesInResourcesTask() throws Exception {
createFilesForIncludesAndExcludesTest();
importProject(
"apply plugin: 'java'\n" +
"\n" +
"processResources {\n" +
" include '**/*.yyy'\n" +
" include '**/*.xxx'\n" +
" exclude 'dir/*.yyy'\n" +
" exclude '*.xxx'\n" +
"}\n" +
"\n" +
"processTestResources {\n" +
" include '**/*.yyy'\n" +
" include '**/*.xxx'\n" +
" exclude 'dir/*.yyy'\n" +
" exclude '*.xxx'\n" +
"}\n"
);
assertModules("project");
compileModules("project");
assertCopiedResources();
}
private void createFilesForIncludesAndExcludesTest() throws IOException {
createProjectSubFile("src/main/resources/dir/file.xxx");
createProjectSubFile("src/main/resources/dir/file.yyy");
createProjectSubFile("src/main/resources/file.xxx");
createProjectSubFile("src/main/resources/file.yyy");
createProjectSubFile("src/main/resources/file.zzz");
createProjectSubFile("src/test/resources/dir/file.xxx");
createProjectSubFile("src/test/resources/dir/file.yyy");
createProjectSubFile("src/test/resources/file.xxx");
createProjectSubFile("src/test/resources/file.yyy");
createProjectSubFile("src/test/resources/file.zzz");
}
private void assertCopiedResources() {
// assert production resources
assertCopied("build/resources/main/dir/file.xxx");
assertCopied("build/resources/main/file.yyy");
assertNotCopied("build/resources/main/dir/file.yyy");
assertNotCopied("build/resources/main/file.xxx");
assertNotCopied("build/resources/main/file.zzz");
// assert test resources
assertCopied("build/resources/test/dir/file.xxx");
assertCopied("build/resources/test/file.yyy");
assertNotCopied("build/resources/test/dir/file.yyy");
assertNotCopied("build/resources/test/file.xxx");
assertNotCopied("build/resources/test/file.zzz");
}
}
@@ -22,9 +22,12 @@ import java.io.Serializable;
import java.util.List;
/**
* @deprecated Use {@link com.intellij.openapi.externalSystem.model.ExternalProject} model instead.
*
* @author Vladislav.Soroka
* @since 11/5/13
*/
@Deprecated()
public interface ModuleExtendedModel extends Serializable {
/**
* The group of the module.
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.gradle.model;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import org.gradle.tooling.BuildAction;
import org.gradle.tooling.BuildController;
import org.gradle.tooling.model.Model;
import org.gradle.tooling.model.build.BuildEnvironment;
import org.gradle.tooling.model.idea.BasicIdeaProject;
import org.gradle.tooling.model.idea.IdeaModule;
@@ -48,8 +49,7 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
@Nullable
@Override
public AllModels execute(final BuildController controller) {
Class<? extends IdeaProject> aClass1 = myIsPreviewMode ? BasicIdeaProject.class : IdeaProject.class;
final IdeaProject ideaProject = controller.getModel(aClass1);
final IdeaProject ideaProject = controller.getModel(myIsPreviewMode ? BasicIdeaProject.class : IdeaProject.class);
if (ideaProject == null || ideaProject.getModules().isEmpty()) {
return null;
}
@@ -59,25 +59,30 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
// TODO ask gradle guys why there is always null got for BuildEnvironment model
//allModels.setBuildEnvironment(controller.findModel(BuildEnvironment.class));
addExtraProject(controller, allModels, null);
for (IdeaModule module : ideaProject.getModules()) {
for (Class aClass : myExtraProjectModelClasses) {
try {
Object extraProject = controller.findModel(module, aClass);
if (extraProject == null) continue;
allModels.addExtraProject(extraProject, aClass, module);
}
catch (Exception e) {
// do not fail project import in a preview mode
if (!myIsPreviewMode) {
throw new ExternalSystemException(e);
}
}
}
addExtraProject(controller, allModels, module);
}
return allModels;
}
private void addExtraProject(@NotNull BuildController controller, @NotNull AllModels allModels, @Nullable IdeaModule model) {
for (Class aClass : myExtraProjectModelClasses) {
try {
Object extraProject = controller.findModel(model, aClass);
if (extraProject == null) continue;
allModels.addExtraProject(extraProject, aClass, model);
}
catch (Exception e) {
// do not fail project import in a preview mode
if (!myIsPreviewMode) {
throw new ExternalSystemException(e);
}
}
}
}
public static class AllModels implements Serializable {
@NotNull private final Map<String, Object> projectsByPath = new HashMap<String, Object>();
@NotNull private final IdeaProject myIdeaProject;
@@ -101,9 +106,13 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
myBuildEnvironment = buildEnvironment;
}
@Nullable
public <T> T getExtraProject(Class<T> modelClazz) {
return getExtraProject(null, modelClazz);
}
@Nullable
public <T> T getExtraProject(@NotNull IdeaModule module, Class<T> modelClazz) {
public <T> T getExtraProject(@Nullable IdeaModule module, Class<T> modelClazz) {
Object extraProject = projectsByPath.get(extractMapKey(modelClazz, module));
if (modelClazz.isInstance(extraProject)) {
//noinspection unchecked
@@ -129,13 +138,17 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
return modules;
}
public void addExtraProject(@NotNull Object project, @NotNull Class modelClazz, @NotNull IdeaModule module) {
public void addExtraProject(@NotNull Object project, @NotNull Class modelClazz) {
projectsByPath.put(extractMapKey(modelClazz, null), project);
}
public void addExtraProject(@NotNull Object project, @NotNull Class modelClazz, @Nullable IdeaModule module) {
projectsByPath.put(extractMapKey(modelClazz, module), project);
}
@NotNull
private static String extractMapKey(Class modelClazz, @NotNull IdeaModule module) {
return modelClazz.getName() + '@' + module.getGradleProject().getPath();
private String extractMapKey(Class modelClazz, @Nullable IdeaModule module) {
return modelClazz.getName() + '@' + (module != null ? module.getGradleProject().getPath() : "root" + myIdeaProject.getName().hashCode());
}
@NotNull
@@ -31,17 +31,21 @@ public class ErrorMessageBuilder {
public static final String EOL_TAG = "<eol>";
@NotNull private final Project myProject;
@NotNull private final Exception myException;
@Nullable private final Exception myException;
@NotNull private final String myGroup;
@Nullable private String myDescription;
private ErrorMessageBuilder(@NotNull Project project, @NotNull Exception exception, @NotNull String group) {
private ErrorMessageBuilder(@NotNull Project project, @Nullable Exception exception, @NotNull String group) {
myProject = project;
myException = exception;
myGroup = group;
}
public static ErrorMessageBuilder create(@NotNull Project project, @NotNull Exception exception, @NotNull String group) {
public static ErrorMessageBuilder create(@NotNull Project project, @NotNull String group) {
return new ErrorMessageBuilder(project, null, group);
}
public static ErrorMessageBuilder create(@NotNull Project project, @Nullable Exception exception, @NotNull String group) {
return new ErrorMessageBuilder(project, exception, group);
}
@@ -59,7 +63,7 @@ public class ErrorMessageBuilder {
(
"<i>" +
"<b>" + myProject + ((myDescription != null) ? ": " + myDescription : "") + "</b>" +
"\nDetails: " + getErrorMessage(myException) +
(myException != null ? "\nDetails: " + getErrorMessage(myException) : "") +
"</i>"
).replaceAll("\r\n|\n\r|\n|\r", EOL_TAG)
);
@@ -67,6 +67,7 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="gson" level="project" />
</component>
</module>
@@ -17,3 +17,4 @@ org.jetbrains.plugins.gradle.tooling.builder.WarModelBuilderImpl
org.jetbrains.plugins.gradle.tooling.builder.ModuleExtendedModelBuilderImpl
org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl
org.jetbrains.plugins.gradle.tooling.builder.ScalaModelBuilderImpl
org.jetbrains.plugins.gradle.tooling.builder.ExternalProjectBuilderImpl
@@ -0,0 +1,231 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.gradle.tooling.builder
import com.google.gson.GsonBuilder
import com.intellij.openapi.externalSystem.model.*
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.ContentFilterable
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.util.PatternFilterable
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
import java.util.concurrent.ConcurrentHashMap
/**
* @author Vladislav.Soroka
* @since 12/20/13
*/
class ExternalProjectBuilderImpl implements ModelBuilderService {
private final cache = new ConcurrentHashMap<String, ExternalProject>()
@Override
public boolean canBuild(String modelName) {
return ExternalProject.name.equals(modelName)
}
@Nullable
@Override
public Object buildAll(final String modelName, final Project project) {
ExternalProject externalProject = cache[project.path]
if (externalProject != null) return externalProject
DefaultExternalProject defaultExternalProject = new DefaultExternalProject()
defaultExternalProject.externalSystemId = "GRADLE"
defaultExternalProject.name = project.name
defaultExternalProject.QName = ":".equals(project.path) ? project.name : project.path
defaultExternalProject.version = wrap(project.version)
defaultExternalProject.description = project.description
defaultExternalProject.buildDir = project.buildDir
defaultExternalProject.buildFile = project.buildFile
defaultExternalProject.group = wrap(project.group)
defaultExternalProject.projectDir = project.projectDir
defaultExternalProject.sourceSets = getSourceSets(project)
defaultExternalProject.tasks = getTasks(project)
defaultExternalProject.plugins = getPlugins(project)
//defaultExternalProject.setProperties(project.getProperties())
final Map<String, ExternalProject> childProjects = new HashMap<String, ExternalProject>(project.getChildProjects().size())
for (Map.Entry<String, Project> projectEntry : project.getChildProjects().entrySet()) {
final Object externalProjectChild = buildAll(modelName, projectEntry.getValue())
if (externalProjectChild instanceof ExternalProject) {
childProjects.put(projectEntry.getKey(), (ExternalProject)externalProjectChild)
}
}
defaultExternalProject.setChildProjects(childProjects)
cache.put(project.getPath(), defaultExternalProject)
defaultExternalProject
}
static Map<String, ExternalPlugin> getPlugins(Project project) {
def result = [:] as Map<String, ExternalPlugin>
project.convention.plugins.each { key, value ->
ExternalPlugin externalPlugin = new DefaultExternalPlugin()
externalPlugin.id = key
result.put(key, externalPlugin)
}
result
}
static Map<String, ExternalTask> getTasks(Project project) {
def result = [:] as Map<String, ExternalTask>
project.tasks.all { Task task ->
ExternalTask externalTask = new DefaultExternalTask()
externalTask.name = task.name
externalTask.description = task.description
externalTask.group = task.group
externalTask.QName = task.path
result.put(externalTask.QName, externalTask)
}
result
}
static Map<String, ExternalSourceSet> getSourceSets(Project project) {
def result = [:] as Map<String, ExternalSourceSet>
if (!project.hasProperty("sourceSets") || !(project.sourceSets instanceof SourceSetContainer)) {
return result
}
def sourceSets = project.sourceSets as SourceSetContainer
def (resourcesIncludes, resourcesExcludes, filterReaders) = getFilters(project, 'processResources')
def (testResourcesIncludes, testResourcesExcludes, testFilterReaders) = getFilters(project, 'processTestResources')
//def (javaIncludes,javaExcludes) = getFilters(project,'compileJava')
sourceSets.all { SourceSet sourceSet ->
ExternalSourceSet externalSourceSet = new DefaultExternalSourceSet()
externalSourceSet.name = sourceSet.name
def sources = [:] as Map<ExternalSystemSourceType, ExternalSourceDirectorySet>
ExternalSourceDirectorySet resourcesDirectorySet = new DefaultExternalSourceDirectorySet()
resourcesDirectorySet.name = sourceSet.resources.name
resourcesDirectorySet.srcDirs = sourceSet.resources.srcDirs
resourcesDirectorySet.outputDir = sourceSet.output.resourcesDir
ExternalSourceDirectorySet javaDirectorySet = new DefaultExternalSourceDirectorySet()
javaDirectorySet.name = sourceSet.allJava.name
javaDirectorySet.srcDirs = sourceSet.allJava.srcDirs
javaDirectorySet.outputDir = sourceSet.output.classesDir
// javaDirectorySet.excludes = javaExcludes + sourceSet.java.excludes;
// javaDirectorySet.includes = javaIncludes + sourceSet.java.includes;
if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.name)) {
resourcesDirectorySet.excludes = testResourcesExcludes + sourceSet.resources.excludes;
resourcesDirectorySet.includes = testResourcesIncludes + sourceSet.resources.includes;
resourcesDirectorySet.filters = testFilterReaders
sources.put(ExternalSystemSourceType.TEST, javaDirectorySet)
sources.put(ExternalSystemSourceType.TEST_RESOURCE, resourcesDirectorySet)
}
else {
resourcesDirectorySet.excludes = resourcesExcludes + sourceSet.resources.excludes;
resourcesDirectorySet.includes = resourcesIncludes + sourceSet.resources.includes;
resourcesDirectorySet.filters = filterReaders
sources.put(ExternalSystemSourceType.SOURCE, javaDirectorySet)
sources.put(ExternalSystemSourceType.RESOURCE, resourcesDirectorySet)
}
externalSourceSet.sources = sources
result[sourceSet.name] = externalSourceSet
}
result
}
static getFilters(Project project, String taskName) {
def includes = []
def excludes = []
def filterReaders = [] as List<ExternalFilter>
def filterableTask = project.tasks.findByName(taskName)
if (filterableTask instanceof PatternFilterable) {
includes += filterableTask.includes
excludes += filterableTask.excludes
}
if(System.getProperty('idea.disable.gradle.resource.filtering', 'false').toBoolean()) {
return [includes, excludes, filterReaders]
}
try {
if (filterableTask instanceof ContentFilterable && filterableTask.metaClass.respondsTo(filterableTask, "getMainSpec")) {
def properties = filterableTask.getMainSpec().properties
def copyActions = properties?.allCopyActions ?: properties?.copyActions
if(copyActions) {
copyActions.each { Action<? super FileCopyDetails> action ->
if (action.hasProperty('val$filterType') && action.hasProperty('val$properties')) {
def filterType = (action?.val$filterType as Class).name
def filter = [filterType: filterType] as DefaultExternalFilter
def props = action?.val$properties
if (props) {
filter.propertiesAsJsonMap = new GsonBuilder().create().toJson(props);
}
filterReaders << filter
}
else if (action.class.simpleName.equals('RenamingCopyAction') && action.hasProperty('transformer')) {
if (action.transformer.hasProperty('matcher') && action?.transformer.hasProperty('replacement')) {
String pattern = action?.transformer?.matcher.pattern().pattern
String replacement = action?.transformer?.replacement
def filter = [filterType: 'RenamingCopyFilter'] as DefaultExternalFilter
if(pattern && replacement){
filter.propertiesAsJsonMap = new GsonBuilder().create().toJson([pattern: pattern, replacement: replacement]);
filterReaders << filter
}
}
}
// else {
// project.logger.error(
// ErrorMessageBuilder.create(project, "Resource configuration errors")
// .withDescription("Unsupported copy action found: " + action.class.name).build())
// }
}
}
}
}
catch (Exception ignore) {
// project.logger.error(
// ErrorMessageBuilder.create(project, e, "Resource configuration errors")
// .withDescription("Unable to resolve resources filtering configuration").build())
}
return [includes, excludes, filterReaders]
}
private static String wrap(Object o) {
return o instanceof CharSequence ? o.toString() : ""
}
@NotNull
@Override
public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
return ErrorMessageBuilder.create(
project, e, "Project resolve errors"
).withDescription("Unable to resolve additional project configuration.")
}
}