summaryrefslogtreecommitdiff
path: root/plugins/gradle/jps-plugin/src/org/jetbrains/jps
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gradle/jps-plugin/src/org/jetbrains/jps')
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/ChainingFilterTransformer.java111
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleBuilderService.java44
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourceFileProcessor.java94
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourcesBuilder.java128
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleExtensionService.java49
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleModuleExtension.java25
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/FilePattern.java38
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleModuleResourceConfiguration.java81
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleProjectConfiguration.java35
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceFileFilter.java81
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceRootDescriptor.java88
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTarget.java161
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTargetType.java78
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleDependenciesEnumerationHandler.java57
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleExtensionServiceImpl.java136
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModelSerializationExtension.java59
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModuleExtensionImpl.java43
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ModuleVersion.java64
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootConfiguration.java59
-rw-r--r--plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootFilter.java75
20 files changed, 1506 insertions, 0 deletions
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/ChainingFilterTransformer.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/ChainingFilterTransformer.java
new file mode 100644
index 000000000000..c717fe16c792
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/ChainingFilterTransformer.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleBuilderService.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleBuilderService.java
new file mode 100644
index 000000000000..5219a2ccad7b
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleBuilderService.java
@@ -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());
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourceFileProcessor.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourceFileProcessor.java
new file mode 100644
index 000000000000..dadfa21906a0
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourceFileProcessor.java
@@ -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)));
+ }
+} \ No newline at end of file
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourcesBuilder.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourcesBuilder.java
new file mode 100644
index 000000000000..295c8bab8133
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/compiler/GradleResourcesBuilder.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleExtensionService.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleExtensionService.java
new file mode 100644
index 000000000000..126cf5758ac1
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleExtensionService.java
@@ -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);
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleModuleExtension.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleModuleExtension.java
new file mode 100644
index 000000000000..c673e4c0d27c
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/JpsGradleModuleExtension.java
@@ -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 {
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/FilePattern.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/FilePattern.java
new file mode 100644
index 000000000000..98938f596d05
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/FilePattern.java
@@ -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>();
+
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleModuleResourceConfiguration.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleModuleResourceConfiguration.java
new file mode 100644
index 000000000000..9b6732a6d5d5
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleModuleResourceConfiguration.java
@@ -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;
+ }
+}
+
+
+
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleProjectConfiguration.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleProjectConfiguration.java
new file mode 100644
index 000000000000..083bba570d8a
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleProjectConfiguration.java
@@ -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>();
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceFileFilter.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceFileFilter.java
new file mode 100644
index 000000000000..60e7fd295daa
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceFileFilter.java
@@ -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);
+ }
+} \ No newline at end of file
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceRootDescriptor.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceRootDescriptor.java
new file mode 100644
index 000000000000..e8ae0d701200
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourceRootDescriptor.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTarget.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTarget.java
new file mode 100644
index 000000000000..344c83080186
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTarget.java
@@ -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())));
+ }
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTargetType.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTargetType.java
new file mode 100644
index 000000000000..bd399a164d31
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/GradleResourcesTargetType.java
@@ -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;
+ }
+ };
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleDependenciesEnumerationHandler.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleDependenciesEnumerationHandler.java
new file mode 100644
index 000000000000..af0fd08fb6cf
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleDependenciesEnumerationHandler.java
@@ -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;
+ }
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleExtensionServiceImpl.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleExtensionServiceImpl.java
new file mode 100644
index 000000000000..81ed9076f13e
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleExtensionServiceImpl.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModelSerializationExtension.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModelSerializationExtension.java
new file mode 100644
index 000000000000..cebd00878b19
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModelSerializationExtension.java
@@ -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, "");
+ }
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModuleExtensionImpl.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModuleExtensionImpl.java
new file mode 100644
index 000000000000..ecdd04fce10e
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/JpsGradleModuleExtensionImpl.java
@@ -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) {
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ModuleVersion.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ModuleVersion.java
new file mode 100644
index 000000000000..dbb696d8c33c
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ModuleVersion.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootConfiguration.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootConfiguration.java
new file mode 100644
index 000000000000..efd419175dc3
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootConfiguration.java
@@ -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;
+ }
+}
diff --git a/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootFilter.java b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootFilter.java
new file mode 100644
index 000000000000..e8c39e32417e
--- /dev/null
+++ b/plugins/gradle/jps-plugin/src/org/jetbrains/jps/gradle/model/impl/ResourceRootFilter.java
@@ -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;
+ }
+}