From 332f9252421c0db0d1b0316d44072c4f4f4b85c8 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 25 Oct 2012 00:01:43 +0200 Subject: [PATCH] external build: processing maven resources (initial implementation, no filtering) --- .../compiler/server/BuildManager.java | 7 + .../projectRoot/FacetEditorFacadeImpl.java | 6 +- .../jetbrains/jps/builders/BuildTarget.java | 11 +- .../jetbrains/jps/cmdline/BuildSession.java | 2 +- .../jps/incremental/CompileScopeImpl.java | 26 ++- .../jps/incremental/IncProjectBuilder.java | 23 +-- .../jps/incremental/ModuleBuildTarget.java | 8 +- .../org/jetbrains/jps/incremental/Utils.java | 6 +- .../artifacts/ArtifactBuildTarget.java | 8 +- .../src/com/intellij/facet/Facet.java | 4 - .../builder/AndroidProjectBuildTarget.java | 6 +- ...g.jetbrains.jps.incremental.BuilderService | 1 + .../maven/compiler/MavenBuilderService.java | 43 +++++ .../maven/compiler/MavenResourcesBuilder.java | 82 ++++++++++ .../maven/model/JpsMavenExtensionService.java | 5 + .../maven/model/JpsMavenModuleExtension.java | 6 - .../impl/JpsMavenExtensionServiceImpl.java | 34 ++++ .../JpsMavenModelSerializationExtension.java | 43 ----- .../impl/JpsMavenModuleExtensionImpl.java | 19 +-- .../impl/MavenModuleExtensionProperties.java | 35 ----- .../MavenModuleResourceConfiguration.java | 64 ++++++++ .../model/impl/MavenProjectConfiguration.java | 43 +++++ .../impl/MavenResourceRootDescriptor.java | 148 ++++++++++++++++++ .../model/impl/MavenResourcesTarget.java | 146 +++++++++++++++++ .../model/impl/MavenResourcesTargetType.java | 79 ++++++++++ ...es.java => ResourceRootConfiguration.java} | 9 +- .../maven/importing/MavenProjectImporter.java | 132 ++++++++++++---- .../idea/maven/project/MavenFacet.java | 43 ----- .../project/MavenFacetConfiguration.java | 101 ------------ .../idea/maven/project/MavenFacetType.java | 61 -------- .../src/main/resources/META-INF/plugin.xml | 2 - 31 files changed, 824 insertions(+), 379 deletions(-) create mode 100644 plugins/maven/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenBuilderService.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java delete mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleExtensionProperties.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourceRootDescriptor.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTarget.java create mode 100644 plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTargetType.java rename plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/{ResourceProperties.java => ResourceRootConfiguration.java} (91%) delete mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacet.java delete mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetConfiguration.java delete mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetType.java diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 2b6b378e1ef4..4878e1f0ba99 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -85,6 +85,7 @@ import org.jetbrains.jps.api.GlobalOptions; import org.jetbrains.jps.api.RequestFuture; import org.jetbrains.jps.cmdline.BuildMain; import org.jetbrains.jps.cmdline.ClasspathBootstrap; +import org.jetbrains.jps.incremental.Utils; import javax.tools.*; import java.io.File; @@ -808,6 +809,12 @@ public class BuildManager implements ApplicationComponent{ return new File(mySystemDirectory, SYSTEM_ROOT); } + @Nullable + public File getProjectSystemDirectory(Project project) { + final String projectPath = getProjectPath(project); + return projectPath != null? Utils.getDataStorageRoot(getBuildSystemDirectory(), projectPath) : null; + } + private static int getMinorVersion(String vs) { final int dashIndex = vs.lastIndexOf('_'); if (dashIndex >= 0) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetEditorFacadeImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetEditorFacadeImpl.java index 3cac8e67f16a..5b7c793a1971 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetEditorFacadeImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetEditorFacadeImpl.java @@ -52,10 +52,8 @@ public class FacetEditorFacadeImpl implements FacetEditorFacade { final FacetModel facetModel = getFacetConfigurator().getFacetModel(module); for (Facet facet : facetModel.getSortedFacets()) { - if (!facet.isImplicit()) { - addFacetNode(facet, moduleNode); - facetsExist = true; - } + addFacetNode(facet, moduleNode); + facetsExist = true; } return facetsExist; diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java index a4fd3e2f263f..88db485fcb2b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/BuildTarget.java @@ -6,6 +6,7 @@ import org.jetbrains.jps.builders.storage.BuildDataPaths; import org.jetbrains.jps.indices.IgnoredFileIndex; import org.jetbrains.jps.indices.ModuleExcludeIndex; import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.module.JpsModule; import java.io.File; import java.io.PrintWriter; @@ -45,8 +46,16 @@ public abstract class BuildTarget { @NotNull public abstract String getPresentableName(); + @NotNull + public abstract Collection getOutputDirs(BuildDataPaths paths); + + /** + * @return associated module if applicable + */ @Nullable - public abstract File getOutputDir(BuildDataPaths paths); + public JpsModule getModule() { + return null; + } @Override public String toString() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index e2c8c359be84..866ce41c4d63 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -74,7 +74,7 @@ final class BuildSession implements Runnable, CanceledStatus { myProjectPath = FileUtil.toCanonicalPath(params.getProjectId()); String globalOptionsPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath()); myBuildType = convertCompileType(params.getBuildType()); - List scopes = params.getScopeList(); + List scopes = params.getScopeList(); List filePaths = params.getFilePathList(); Map builderParams = new HashMap(); for (CmdlineRemoteProto.Message.KeyValuePair pair : params.getBuilderParameterList()) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java index b18cf1cf63e3..7dab8c01f03f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java @@ -3,9 +3,13 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.builders.BuildTarget; import org.jetbrains.jps.builders.BuildTargetType; +import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; +import org.jetbrains.jps.model.module.JpsModule; import java.io.File; -import java.util.*; +import java.util.Collection; +import java.util.Map; +import java.util.Set; /** * @author nik @@ -26,12 +30,12 @@ public class CompileScopeImpl extends CompileScope { @Override public boolean isAffected(@NotNull BuildTarget target) { - return myTypes.contains(target.getTargetType()) || myTargets.contains(target) || myFiles.containsKey(target); + return myTypes.contains(target.getTargetType()) || myTargets.contains(target) || myFiles.containsKey(target) || isAffectedByAssociatedModule(target); } @Override public boolean isRecompilationForced(@NotNull BuildTarget target) { - return myForcedCompilation && (myTypes.contains(target.getTargetType()) || myTargets.contains(target)); + return myForcedCompilation && (myTypes.contains(target.getTargetType()) || myTargets.contains(target) || isAffectedByAssociatedModule(target)); } @Override @@ -39,10 +43,24 @@ public class CompileScopeImpl extends CompileScope { if (myFiles.isEmpty()) {//optimization return true; } - if (myTypes.contains(target.getTargetType()) || myTargets.contains(target)) { + if (myTypes.contains(target.getTargetType()) || myTargets.contains(target) || isAffectedByAssociatedModule(target)) { return true; } Set files = myFiles.get(target); return files != null && files.contains(file); } + + private boolean isAffectedByAssociatedModule(BuildTarget target) { + final JpsModule module = target.getModule(); + if (module != null) { + // this target is associated with module + for (JavaModuleBuildTargetType moduleType : JavaModuleBuildTargetType.ALL_TYPES) { + if (myTypes.contains(moduleType) || myTargets.contains(new ModuleBuildTarget(module, moduleType))) { + return true; + } + } + } + return false; + } + } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index b335e4fbd32a..afa4870c24a6 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -315,9 +315,9 @@ public class IncProjectBuilder { ProjectDescriptor projectDescriptor = context.getProjectDescriptor(); for (BuildTarget target : projectDescriptor.getBuildTargetIndex().getAllTargets()) { - File outputDir = target.getOutputDir(projectDescriptor.dataManager.getDataPaths()); - if (outputDir != null) { - rootsToDelete.putValue(outputDir, target); + final Collection outputs = target.getOutputDirs(projectDescriptor.dataManager.getDataPaths()); + for (File file : outputs) { + rootsToDelete.putValue(file, target); } } @@ -1128,23 +1128,28 @@ public class IncProjectBuilder { private final BuildTarget myTarget; private final CompileContext myContext; private FileGeneratedEvent myFileGeneratedEvent; - private File myOutputDir; + private Collection myOutputs; public BuildOutputConsumerImpl(BuildTarget target, CompileContext context) { myTarget = target; myContext = context; myFileGeneratedEvent = new FileGeneratedEvent(); - myOutputDir = myTarget.getOutputDir(myContext.getProjectDescriptor().dataManager.getDataPaths()); + myOutputs = myTarget.getOutputDirs(myContext.getProjectDescriptor().dataManager.getDataPaths()); } @Override public void registerOutputFile(String outputFilePath, Collection sourceFiles) throws IOException { - String relativePath = FileUtil.getRelativePath(myOutputDir, new File(outputFilePath)); - if (myOutputDir != null && relativePath != null) { - myFileGeneratedEvent.add(myOutputDir.getAbsolutePath(), relativePath); + if (myOutputs.size() == 1) { + // todo: multiple outputs case? + final File outputDir = myOutputs.iterator().next(); + final String relativePath = FileUtil.getRelativePath(outputDir, new File(outputFilePath)); + if (relativePath != null) { + myFileGeneratedEvent.add(FileUtil.toSystemIndependentName(outputDir.getPath()), FileUtil.toSystemIndependentName(relativePath)); + } } + final SourceToOutputMapping mapping = myContext.getProjectDescriptor().dataManager.getSourceToOutputMap(myTarget); for (String sourceFile : sourceFiles) { - myContext.getProjectDescriptor().dataManager.getSourceToOutputMap(myTarget).appendOutput(sourceFile, outputFilePath); + mapping.appendOutput(sourceFile, outputFilePath); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java index 816eaed509a2..4dfff29b3e33 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java @@ -48,12 +48,14 @@ public class ModuleBuildTarget extends BuildTarget { return JpsJavaExtensionService.getInstance().getOutputDirectory(myModule, myTargetType.isTests()); } - @Nullable + @NotNull @Override - public File getOutputDir(BuildDataPaths paths) { - return getOutputDir(); + public Collection getOutputDirs(BuildDataPaths paths) { + final File outputDir = getOutputDir(); + return outputDir != null? Collections.singleton(outputDir) : Collections.emptyList(); } + @Override @NotNull public JpsModule getModule() { return myModule; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java index d8d5bc982a1d..5da4265b65d3 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java @@ -39,6 +39,10 @@ public class Utils { @Nullable public static File getDataStorageRoot(String projectPath) { + return getDataStorageRoot(ourSystemRoot, projectPath); + } + + public static File getDataStorageRoot(final File systemRoot, String projectPath) { projectPath = FileUtil.toCanonicalPath(projectPath); if (projectPath == null) { return null; @@ -76,7 +80,7 @@ public class Utils { locationHash = directoryBased.getPath().hashCode(); } - return new File(ourSystemRoot, name.toLowerCase(Locale.US) + "_" + Integer.toHexString(locationHash)); + return new File(systemRoot, name.toLowerCase(Locale.US) + "_" + Integer.toHexString(locationHash)); } private static String getDirectoryBaseProjectName(File dir) throws IOException { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactBuildTarget.java index e4b4d5487548..5a76a1e545cc 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactBuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/ArtifactBuildTarget.java @@ -4,7 +4,6 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.builders.BuildRootDescriptor; import org.jetbrains.jps.builders.BuildRootIndex; import org.jetbrains.jps.builders.BuildTarget; @@ -22,6 +21,7 @@ import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement; import java.io.File; import java.io.PrintWriter; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; @@ -114,10 +114,10 @@ public class ArtifactBuildTarget extends BuildTarget { return "Artifact '" + myArtifact.getName() + "'"; } - @Nullable + @NotNull @Override - public File getOutputDir(BuildDataPaths paths) { + public Collection getOutputDirs(BuildDataPaths paths) { String outputPath = myArtifact.getOutputPath(); - return !StringUtil.isEmpty(outputPath) ? new File(FileUtil.toSystemDependentName(outputPath)) : null; + return outputPath != null && !StringUtil.isEmpty(outputPath) ? Collections.singleton(new File(FileUtil.toSystemDependentName(outputPath))) : Collections.emptyList(); } } diff --git a/platform/lang-api/src/com/intellij/facet/Facet.java b/platform/lang-api/src/com/intellij/facet/Facet.java index db27c7f63ca7..dc8ccd3431d3 100644 --- a/platform/lang-api/src/com/intellij/facet/Facet.java +++ b/platform/lang-api/src/com/intellij/facet/Facet.java @@ -71,10 +71,6 @@ public class Facet extends UserDataHolderBase impl return myModule; } - public boolean isImplicit() { - return false; - } - public boolean isDisposed() { return isDisposed; } diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/builder/AndroidProjectBuildTarget.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/builder/AndroidProjectBuildTarget.java index 3f079a4e6cfd..91b78ac116d2 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/builder/AndroidProjectBuildTarget.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/builder/AndroidProjectBuildTarget.java @@ -107,10 +107,10 @@ public class AndroidProjectBuildTarget extends BuildTarget return "Android " + myKind.name(); } - @Nullable + @NotNull @Override - public File getOutputDir(BuildDataPaths paths) { - return null; + public Collection getOutputDirs(BuildDataPaths paths) { + return Collections.emptyList(); } public static class TargetType extends BuildTargetType { diff --git a/plugins/maven/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService b/plugins/maven/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService new file mode 100644 index 000000000000..5952b4d92af1 --- /dev/null +++ b/plugins/maven/jps-plugin/src/META-INF/services/org.jetbrains.jps.incremental.BuilderService @@ -0,0 +1 @@ +org.jetbrains.jps.maven.compiler.MavenBuilderService \ No newline at end of file diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenBuilderService.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenBuilderService.java new file mode 100644 index 000000000000..32453a735a96 --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenBuilderService.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2012 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.maven.compiler; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.builders.BuildTargetType; +import org.jetbrains.jps.incremental.BuilderService; +import org.jetbrains.jps.incremental.TargetBuilder; +import org.jetbrains.jps.maven.model.impl.MavenResourcesTargetType; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: 10/21/12 + */ +public class MavenBuilderService extends BuilderService{ + @Override + public List> getTargetTypes() { + return Arrays.asList(MavenResourcesTargetType.PRODUCTION, MavenResourcesTargetType.TEST); + } + + @NotNull + @Override + public List> createBuilders() { + return Collections.singletonList(new MavenResourcesBuilder()); + } +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java new file mode 100644 index 000000000000..6e68649916dd --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java @@ -0,0 +1,82 @@ +package org.jetbrains.jps.maven.compiler; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileUtil; +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.incremental.CompileContext; +import org.jetbrains.jps.incremental.ProjectBuildException; +import org.jetbrains.jps.incremental.TargetBuilder; +import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration; +import org.jetbrains.jps.maven.model.impl.MavenResourceRootDescriptor; +import org.jetbrains.jps.maven.model.impl.MavenResourcesTarget; +import org.jetbrains.jps.maven.model.impl.MavenResourcesTargetType; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +/** + * @author Eugene Zhuravlev + * Date: 10/6/11 + */ +public class MavenResourcesBuilder extends TargetBuilder { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.maven.compiler.MavenResourcesBuilder"); + public static final String BUILDER_NAME = "maven-resources"; + + public MavenResourcesBuilder() { + super(Arrays.asList(MavenResourcesTargetType.PRODUCTION, MavenResourcesTargetType.TEST)); + } + + @Override + public String getName() { + return BUILDER_NAME; + } + + @Override + public void build(@NotNull MavenResourcesTarget target, @NotNull final DirtyFilesHolder holder, @NotNull final BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException, IOException { + final MavenModuleResourceConfiguration config = target.getModuleResourcesConfiguration( + context.getProjectDescriptor().dataManager.getDataPaths()); + if (config == null) { + return; + } + final Set filteringExcludedExtensions = config.getFiltetingExcludedExtensions(); + holder.processDirtyFiles(new FileProcessor() { + @Override + public boolean apply(MavenResourcesTarget target, File file, MavenResourceRootDescriptor rd) throws IOException { + final File outputDir = MavenResourcesTarget.getOutputDir(target.getModuleOutputDir(), rd.getConfiguration()); + if (outputDir == null) { + return true; + } + final String relPath = FileUtil.getRelativePath(rd.getRootFile(), file); + if (relPath == null) { + return true; + } + final File outputFile = new File(outputDir, relPath); + final boolean shouldFilter = rd.getConfiguration().isFiltered && !filteringExcludedExtensions.contains(getExtension(file)); + // todo: support filtering + FileUtil.copyContent(file, outputFile); + outputConsumer.registerOutputFile(outputFile.getPath(), Collections.singleton(file.getPath())); + return true; + } + }); + } + + private static String getExtension(File file) { + final String name = file.getName(); + final int dotindex = name.lastIndexOf("."); + if (dotindex < 0) { + return ""; + } + return name.substring(dotindex + 1); + } + + public String getDescription() { + return "Maven Resource Builder"; + } + +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenExtensionService.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenExtensionService.java index c353a47caf39..b4b6e7d7e22c 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenExtensionService.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenExtensionService.java @@ -2,6 +2,8 @@ package org.jetbrains.jps.maven.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.builders.storage.BuildDataPaths; +import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.service.JpsServiceManager; @@ -23,4 +25,7 @@ public abstract class JpsMavenExtensionService { public abstract void setProductionOnTestDependency(@NotNull JpsDependencyElement dependency, boolean value); public abstract boolean isProductionOnTestDependency(@NotNull JpsDependencyElement dependency); + + @NotNull + public abstract MavenProjectConfiguration getMavenProjectConfiguration(BuildDataPaths paths); } diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenModuleExtension.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenModuleExtension.java index 84392092a1f4..8294e18c4833 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenModuleExtension.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/JpsMavenModuleExtension.java @@ -1,15 +1,9 @@ package org.jetbrains.jps.maven.model; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.maven.model.impl.MavenModuleExtensionProperties; import org.jetbrains.jps.model.JpsElement; /** * @author nik */ public interface JpsMavenModuleExtension extends JpsElement { - @NotNull - MavenModuleExtensionProperties getState(); - - void setState(MavenModuleExtensionProperties state); } diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java index 80c8b578ee1c..3029d36cb312 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java @@ -1,7 +1,12 @@ package org.jetbrains.jps.maven.model.impl; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.xmlb.XmlSerializer; +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.incremental.resources.ResourcesBuilder; import org.jetbrains.jps.incremental.resources.StandardResourceBuilderEnabler; import org.jetbrains.jps.maven.model.JpsMavenExtensionService; @@ -13,10 +18,13 @@ 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; + /** * @author nik */ public class JpsMavenExtensionServiceImpl extends JpsMavenExtensionService { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.maven.model.impl.JpsMavenExtensionServiceImpl"); private static final JpsElementChildRole> PRODUCTION_ON_TEST_ROLE = JpsElementChildRoleBase.create("production on test"); public JpsMavenExtensionServiceImpl() { @@ -62,4 +70,30 @@ public class JpsMavenExtensionServiceImpl extends JpsMavenExtensionService { JpsSimpleElement child = dependency.getContainer().getChild(PRODUCTION_ON_TEST_ROLE); return child != null && child.getData(); } + + private volatile MavenProjectConfiguration myConfig; + + @NotNull + @Override + public MavenProjectConfiguration getMavenProjectConfiguration(BuildDataPaths paths) { + MavenProjectConfiguration config = myConfig; + if (config == null) { + synchronized (this) { + config = myConfig; + if (config == null) { + config = new MavenProjectConfiguration(); + try { + final File configFile = new File(paths.getDataStorageRoot(), MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH); + final Document document = JDOMUtil.loadDocument(configFile); + XmlSerializer.deserializeInto(config, document.getRootElement()); + } + catch (Exception e) { + LOG.info(e); + } + myConfig = config; + } + } + } + return config; + } } diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModelSerializationExtension.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModelSerializationExtension.java index 494239b7edaf..ece4d5cecdf4 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModelSerializationExtension.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModelSerializationExtension.java @@ -1,18 +1,11 @@ package org.jetbrains.jps.maven.model.impl; -import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.maven.model.JpsMavenExtensionService; -import org.jetbrains.jps.maven.model.JpsMavenModuleExtension; -import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; -import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer; - -import java.util.Collections; -import java.util.List; /** * @author nik @@ -48,40 +41,4 @@ public class JpsMavenModelSerializationExtension extends JpsModelSerializerExten orderEntry.setAttribute(PRODUCTION_ON_TEST_ATTRIBUTE, ""); } } - - - private final JpsFacetConfigurationSerializer FACET_SERIALIZER = new JpsFacetConfigurationSerializer(JpsMavenModuleExtensionImpl.ROLE, "_maven_", "maven") { - @Override - public JpsMavenModuleExtension loadExtension(Element configurationElement, - String facetName, - JpsModule module, - String baseModulePath, - JpsElement parentFacet) { - final JpsMavenModuleExtension extension = JpsMavenExtensionService.getInstance().getExtension(module); - if (extension != null) { - final MavenModuleExtensionProperties state = XmlSerializer.deserialize(configurationElement, MavenModuleExtensionProperties.class); - if (state != null) { - extension.setState(state); - } - } - return extension; - } - - @Override - protected JpsMavenModuleExtension loadExtension(@NotNull Element facetConfigurationElement, String name, String baseModulePath, JpsElement parent, JpsModule module) { - throw new RuntimeException("Not implemented"); - } - - @Override - protected void saveExtension(JpsMavenModuleExtension extension, Element facetConfigurationTag, JpsModule module) { - final MavenModuleExtensionProperties state = extension.getState(); - XmlSerializer.serializeInto(state, facetConfigurationTag); - } - }; - - @Override - public List> getFacetConfigurationSerializers() { - return Collections.singletonList(FACET_SERIALIZER); - } - } diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModuleExtensionImpl.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModuleExtensionImpl.java index a68001066dc4..8ba02d10a5c5 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModuleExtensionImpl.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenModuleExtensionImpl.java @@ -1,6 +1,5 @@ package org.jetbrains.jps.maven.model.impl; -import com.intellij.util.xmlb.XmlSerializerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.maven.model.JpsMavenModuleExtension; import org.jetbrains.jps.model.JpsElementChildRole; @@ -13,32 +12,16 @@ import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; public class JpsMavenModuleExtensionImpl extends JpsElementBase implements JpsMavenModuleExtension { public static final JpsElementChildRole ROLE = JpsElementChildRoleBase.create("maven"); - private MavenModuleExtensionProperties myState = new MavenModuleExtensionProperties(); - public JpsMavenModuleExtensionImpl() { } - @NotNull - @Override - public MavenModuleExtensionProperties getState() { - return myState; - } - - @Override - public void setState(MavenModuleExtensionProperties state) { - myState = state; - } - @NotNull @Override public JpsMavenModuleExtensionImpl createCopy() { - final JpsMavenModuleExtensionImpl copy = new JpsMavenModuleExtensionImpl(); - XmlSerializerUtil.copyBean(myState, copy.myState); - return copy; + return new JpsMavenModuleExtensionImpl(); } @Override public void applyChanges(@NotNull JpsMavenModuleExtensionImpl modified) { - XmlSerializerUtil.copyBean(modified.myState, myState); } } diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleExtensionProperties.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleExtensionProperties.java deleted file mode 100644 index 4c9828cfcdd8..000000000000 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleExtensionProperties.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2012 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.maven.model.impl; - -import com.intellij.util.xmlb.annotations.AbstractCollection; -import com.intellij.util.xmlb.annotations.Tag; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Eugene Zhuravlev - * Date: 10/20/12 - */ -public class MavenModuleExtensionProperties { - @Tag("resources") - @AbstractCollection(surroundWithTag = false, elementTag = "resource") - public List myResources = new ArrayList(); -} - - - diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java new file mode 100644 index 000000000000..c74095123245 --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2012 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.maven.model.impl; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.MapAnnotation; +import com.intellij.util.xmlb.annotations.OptionTag; +import com.intellij.util.xmlb.annotations.Tag; +import gnu.trove.THashSet; + +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: 10/20/12 + */ +public class MavenModuleResourceConfiguration { + @Tag("properties") + @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) + public Map myProperties = new HashMap(); + + @Tag("filtering-excluded-extensions") + @AbstractCollection(surroundWithTag = false, elementTag = "extension") + public Set myFilteringExcludedExtensions = new THashSet(FileUtil.PATH_HASHING_STRATEGY); + + @OptionTag + public String escapeString = MavenProjectConfiguration.DEFAULT_ESCAPE_STRING; + + @Tag("resources") + @AbstractCollection(surroundWithTag = false, elementTag = "resource") + public List myResources = new ArrayList(); + + @Tag("test-resources") + @AbstractCollection(surroundWithTag = false, elementTag = "resource") + public List myTestResources = new ArrayList(); + + + public Set getFiltetingExcludedExtensions() { + if (myFilteringExcludedExtensions.isEmpty()) { + return MavenProjectConfiguration.DEFAULT_FILTERING_EXCLUDED_EXTENSIONS; + } + final Set result = new THashSet(FileUtil.PATH_HASHING_STRATEGY); + result.addAll(MavenProjectConfiguration.DEFAULT_FILTERING_EXCLUDED_EXTENSIONS); + result.addAll(myFilteringExcludedExtensions); + return Collections.unmodifiableSet(result); + } +} + + + diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java new file mode 100644 index 000000000000..a9d2bdb2f361 --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenProjectConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2012 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.maven.model.impl; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.xmlb.annotations.MapAnnotation; +import com.intellij.util.xmlb.annotations.Tag; +import gnu.trove.THashSet; + +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: 10/24/12 + */ +public class MavenProjectConfiguration { + public static final String CONFIGURATION_FILE_RELATIVE_PATH = "maven/configuration.xml"; + public static final String DEFAULT_ESCAPE_STRING = "\\"; + public static final String DEFAULT_INCLUDE_PATTERN = FileUtil.convertAntToRegexp("**/*"); + public static final Set DEFAULT_FILTERING_EXCLUDED_EXTENSIONS; + static { + final THashSet set = new THashSet(FileUtil.PATH_HASHING_STRATEGY); + set.addAll(Arrays.asList("jpg", "jpeg", "gif", "bmp", "png")); + DEFAULT_FILTERING_EXCLUDED_EXTENSIONS = Collections.unmodifiableSet(set); + } + + @Tag("resource-processing") + @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false, entryTagName = "maven-module", keyAttributeName = "name") + public Map moduleConfigurations = new HashMap(); +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourceRootDescriptor.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourceRootDescriptor.java new file mode 100644 index 000000000000..00a651dfe79d --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourceRootDescriptor.java @@ -0,0 +1,148 @@ +/* + * Copyright 2000-2012 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.maven.model.impl; + +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.builders.BuildRootDescriptor; +import org.jetbrains.jps.indices.IgnoredFileIndex; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * @author Eugene Zhuravlev + * Date: 10/21/12 + */ +public class MavenResourceRootDescriptor extends BuildRootDescriptor { + private final MavenResourcesTarget myTarget; + private final ResourceRootConfiguration myConfig; + private final IgnoredFileIndex myIgnoredFileIndex; + private final File myFile; + private final String myId; + + public MavenResourceRootDescriptor(@NotNull MavenResourcesTarget target, + ResourceRootConfiguration config, + IgnoredFileIndex ignoredFileIndex) { + myTarget = target; + myConfig = config; + myIgnoredFileIndex = ignoredFileIndex; + final String path = FileUtil.toCanonicalPath(config.directory); + myFile = new File(path); + myId = path; + } + + public ResourceRootConfiguration getConfiguration() { + return myConfig; + } + + @Override + public String getRootId() { + return myId; + } + + @Override + public File getRootFile() { + return myFile; + } + + @Override + public MavenResourcesTarget getTarget() { + return myTarget; + } + + @Override + public FileFilter createFileFilter() { + return new MyFileFilter(myFile, myConfig.includes, myConfig.excludes, myIgnoredFileIndex); + } + + private static class MyFileFilter implements FileFilter { + private final List myCompiledIncludes; + private final List myCompiledExcludes; + private final File mySourceRoot; + private final IgnoredFileIndex myIgnoredFileIndex; + + private MyFileFilter(File sourceRoot, final List includes, final List excludes, IgnoredFileIndex ignoredFileIndex) { + mySourceRoot = sourceRoot; + myIgnoredFileIndex = ignoredFileIndex; + myCompiledIncludes = compilePatterns(includes, MavenProjectConfiguration.DEFAULT_INCLUDE_PATTERN); + myCompiledExcludes = compilePatterns(excludes, null); + } + + @Override + public boolean accept(File file) { + if (myIgnoredFileIndex.isIgnored(file.getName())) { + return false; + } + final String relativePath = FileUtil.getRelativePath(mySourceRoot, file); + if (relativePath == null) { + return false; + } + return isIncluded(FileUtil.toSystemIndependentName(relativePath), myCompiledIncludes, myCompiledExcludes); + } + + private static boolean isIncluded(String relativeName, List includes, List excludes) { + boolean isIncluded = false; + for (Pattern each : includes) { + if (each.matcher(relativeName).matches()) { + isIncluded = true; + break; + } + } + if (!isIncluded) { + return false; + } + for (Pattern each : excludes) { + if (each.matcher(relativeName).matches()) { + return false; + } + } + return true; + } + + + @NotNull + private static List compilePatterns(@NotNull List patterns, @Nullable String defaultValue) { + final List result = new ArrayList(); + if (patterns.isEmpty()) { + if (defaultValue == null) { + return Collections.emptyList(); + } + try { + result.add(Pattern.compile(defaultValue)); + } + catch (PatternSyntaxException ignore) { + } + } + + for (String pattern : patterns) { + try { + result.add(Pattern.compile(pattern)); + } + catch (PatternSyntaxException ignore) { + } + } + return result; + } + + } +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTarget.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTarget.java new file mode 100644 index 000000000000..ab48434898ed --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTarget.java @@ -0,0 +1,146 @@ +/* + * Copyright 2000-2012 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.maven.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.BuildRootDescriptor; +import org.jetbrains.jps.builders.BuildRootIndex; +import org.jetbrains.jps.builders.BuildTarget; +import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; +import org.jetbrains.jps.builders.storage.BuildDataPaths; +import org.jetbrains.jps.incremental.ModuleBuildTarget; +import org.jetbrains.jps.indices.IgnoredFileIndex; +import org.jetbrains.jps.indices.ModuleExcludeIndex; +import org.jetbrains.jps.maven.model.JpsMavenExtensionService; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.module.JpsModule; + +import java.io.File; +import java.util.*; + +/** + * @author Eugene Zhuravlev + * Date: 10/21/12 + */ +public class MavenResourcesTarget extends BuildTarget{ + @NotNull + private final JpsModule myModule; + + MavenResourcesTarget(final MavenResourcesTargetType type, @NotNull JpsModule module) { + super(type); + myModule = module; + } + + @NotNull + @Override + public JpsModule getModule() { + return myModule; + } + + @Override + public String getId() { + return myModule.getName(); + } + + @Override + public Collection> computeDependencies() { + final MavenResourcesTargetType type = (MavenResourcesTargetType)getTargetType(); + final JavaModuleBuildTargetType targetType = type.isTests() ? JavaModuleBuildTargetType.TEST : JavaModuleBuildTargetType.PRODUCTION; + return Collections.>singletonList(new ModuleBuildTarget(myModule, targetType)); + } + + @NotNull + @Override + public List computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex, BuildDataPaths dataPaths) { + // todo: should we honor ignored and excluded roots here? + final List result = new ArrayList(); + for (ResourceRootConfiguration resource : getRootConfigurations(dataPaths)) { + result.add(new MavenResourceRootDescriptor(this, resource, ignoredFileIndex)); + } + return result; + } + + private List getRootConfigurations(BuildDataPaths dataPaths) { + final MavenModuleResourceConfiguration moduleConfig = getModuleResourcesConfiguration(dataPaths); + if (moduleConfig != null) { + return isTests() ? moduleConfig.myTestResources : moduleConfig.myResources; + } + return Collections.emptyList(); + } + + public MavenModuleResourceConfiguration getModuleResourcesConfiguration(BuildDataPaths dataPaths) { + final MavenProjectConfiguration projectConfig = JpsMavenExtensionService.getInstance().getMavenProjectConfiguration(dataPaths); + return projectConfig.moduleConfigurations.get(myModule.getName()); + } + + private boolean isTests() { + return ((MavenResourcesTargetType)getTargetType()).isTests(); + } + + @Nullable + @Override + public BuildRootDescriptor findRootDescriptor(String rootId, BuildRootIndex rootIndex) { + for (BuildRootDescriptor 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 getOutputDirs(BuildDataPaths paths) { + final Set result = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + final File moduleOutput = getModuleOutputDir(); + for (ResourceRootConfiguration resConfig : getRootConfigurations(paths)) { + final File output = getOutputDir(moduleOutput, resConfig); + 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) { + if (moduleOutput == null) { + return null; + } + String targetPath = config.targetPath; + if (StringUtil.isEmptyOrSpaces(targetPath)) { + return moduleOutput; + } + final File targetPathFile = new File(targetPath); + return targetPathFile.isAbsolute()? targetPathFile : new File(moduleOutput, targetPath); + } +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTargetType.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTargetType.java new file mode 100644 index 000000000000..a2358c0b5e96 --- /dev/null +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenResourcesTargetType.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2012 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.maven.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.builders.BuildTargetLoader; +import org.jetbrains.jps.builders.BuildTargetType; +import org.jetbrains.jps.maven.model.JpsMavenExtensionService; +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 Eugene Zhuravlev +* Date: 10/24/12 +*/ +public class MavenResourcesTargetType extends BuildTargetType { + public static final MavenResourcesTargetType PRODUCTION = new MavenResourcesTargetType("maven-resources-production", false); + public static final MavenResourcesTargetType TEST = new MavenResourcesTargetType("maven-resources-test", true); + + private final boolean myIsTests; + + private MavenResourcesTargetType(final String typeId, boolean isTests) { + super(typeId); + myIsTests = isTests; + } + + public boolean isTests() { + return myIsTests; + } + + @NotNull + @Override + public List computeAllTargets(@NotNull JpsModel model) { + final List targets = new ArrayList(); + final JpsMavenExtensionService service = JpsMavenExtensionService.getInstance(); + for (JpsModule module : model.getProject().getModules()) { + if (service.getExtension(module) != null) { + targets.add(new MavenResourcesTarget(this, module)); + } + } + return targets; + } + + @NotNull + @Override + public BuildTargetLoader createLoader(@NotNull JpsModel model) { + final Map modules = new HashMap(); + for (JpsModule module : model.getProject().getModules()) { + modules.put(module.getName(), module); + } + return new BuildTargetLoader() { + @Nullable + @Override + public MavenResourcesTarget createTarget(@NotNull String targetId) { + final JpsModule module = modules.get(targetId); + return module != null ? new MavenResourcesTarget(MavenResourcesTargetType.this, module) : null; + } + }; + } +} diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceProperties.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceRootConfiguration.java similarity index 91% rename from plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceProperties.java rename to plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceRootConfiguration.java index 43ce5921629c..96f400dd5c4d 100644 --- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceProperties.java +++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/ResourceRootConfiguration.java @@ -18,6 +18,7 @@ package org.jetbrains.jps.maven.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; @@ -28,12 +29,12 @@ import java.util.List; * Date: 10/20/12 */ @Tag("resource") -public class ResourceProperties { - @Attribute("directory") - @Nullable +public class ResourceRootConfiguration { + @Tag("directory") + @NotNull public String directory; - @Attribute("targetPath") + @Tag("targetPath") @Nullable public String targetPath; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java index e6ab1d48ad4b..793f7a872932 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java @@ -18,7 +18,7 @@ package org.jetbrains.idea.maven.importing; import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerConfigurationImpl; import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration; -import com.intellij.facet.ModifiableFacetModel; +import com.intellij.compiler.server.BuildManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; @@ -30,25 +30,33 @@ import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.Stack; +import com.intellij.util.xmlb.XmlSerializer; import gnu.trove.THashMap; import gnu.trove.THashSet; +import org.jdom.Document; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.model.MavenArtifact; +import org.jetbrains.idea.maven.model.MavenResource; import org.jetbrains.idea.maven.project.*; -import org.jetbrains.idea.maven.utils.MavenLog; -import org.jetbrains.idea.maven.utils.MavenProcessCanceledException; -import org.jetbrains.idea.maven.utils.MavenProgressIndicator; -import org.jetbrains.idea.maven.utils.MavenUtil; +import org.jetbrains.idea.maven.utils.*; +import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration; +import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration; +import org.jetbrains.jps.maven.model.impl.ResourceRootConfiguration; import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.*; @@ -454,46 +462,106 @@ public class MavenProjectImporter { MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { public void run() { MavenProjectsManager.getInstance(myProject).setMavenizedModules(modules, mavenized); - configureMavenFacet(modules, mavenized); + configureExternalBuild(); } }); } - private void configureMavenFacet(Collection modules, boolean modulesMavenized) { - if (modules.isEmpty()) { + private void configureExternalBuild() { + final File projectSystemDir = BuildManager.getInstance().getProjectSystemDirectory(myProject); + if (projectSystemDir == null) { return; } - final Map moduleToProjectMap = new HashMap(); - for (Map.Entry entry : myMavenProjectToModule.entrySet()) { - moduleToProjectMap.put(entry.getValue(), entry.getKey()); - } - final MavenFacetType facetType = MavenFacetType.getInstance(); - for (final Module module : modules) { - final ModifiableFacetModel model = myModelsProvider.getFacetModel(module); - MavenFacet facet = model.getFacetByType(facetType.getId()); - if (!modulesMavenized) { - if (facet != null) { - model.removeFacet(facet); - } + final File mavenConfigFile = new File(projectSystemDir, MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH); + final MavenProjectConfiguration projectConfig = new MavenProjectConfiguration(); + + for (Map.Entry entry : myMavenProjectToModule.entrySet()) { + final Module module = entry.getValue(); + final MavenProject mavenProject = entry.getKey(); + if (module == null || mavenProject == null) { + continue; + } + final MavenModuleResourceConfiguration resourceConfig = new MavenModuleResourceConfiguration(); + addResources(resourceConfig.myResources, mavenProject.getResources()); + addResources(resourceConfig.myTestResources, mavenProject.getTestResources()); + resourceConfig.myFilteringExcludedExtensions.addAll(getFilterExclusions(mavenProject)); + final Properties properties = getFilteringProperties(mavenProject); + for (Map.Entry propEntry : properties.entrySet()) { + resourceConfig.myProperties.put((String)propEntry.getKey(), (String)propEntry.getValue()); + } + resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath( + mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"), "escapeString", "\\" + ); + projectConfig.moduleConfigurations.put(module.getName(), resourceConfig); + } + + try { + final Document document = new Document(new Element("maven-project-configuration")); + XmlSerializer.serializeInto(projectConfig, document.getRootElement()); + FileUtil.createIfDoesntExist(mavenConfigFile); + JDOMUtil.writeDocument(document, mavenConfigFile, "\n"); + } + catch (IOException e) { + e.printStackTrace(); // todo + } + } + + private static void addResources(final List container, Collection resources) { + for (MavenResource resource : resources) { + final String dir = resource.getDirectory(); + if (dir == null) { continue; } - if (facet == null) { - facet = facetType.createFacet(module, facetType.getPresentableName(), facetType.createDefaultConfiguration(), null); - model.addFacet(facet); - } - else { - final MavenFacetConfiguration config = facet.getConfiguration(); - config.clearState(); - } + final ResourceRootConfiguration props = new ResourceRootConfiguration(); + props.directory = FileUtil.toSystemIndependentName(dir); - final MavenProject mavenProject = moduleToProjectMap.get(module); - if (mavenProject != null) { - final MavenFacetConfiguration config = facet.getConfiguration(); - config.addResources(mavenProject.getResources()); + final String target = resource.getTargetPath(); + props.targetPath = target != null? FileUtil.toSystemIndependentName(target) : null; + + props.isFiltered = resource.isFiltered(); + props.includes.clear(); + for (String include : resource.getIncludes()) { + props.includes.add(FileUtil.convertAntToRegexp(include.trim())); + } + props.excludes.clear(); + for (String exclude : resource.getExcludes()) { + props.excludes.add(FileUtil.convertAntToRegexp(exclude.trim())); + } + container.add(props); + } + } + + @NotNull + private static Collection getFilterExclusions(MavenProject mavenProject) { + Element config = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"); + if (config == null) { + return Collections.emptySet(); + } + final List customNonFilteredExtensions = MavenJDOMUtil.findChildrenValuesByPath(config, "nonFilteredFileExtensions", "nonFilteredFileExtension"); + if (customNonFilteredExtensions.isEmpty()) { + return Collections.emptySet(); + } + return Collections.unmodifiableCollection(customNonFilteredExtensions); + } + + private static Properties getFilteringProperties(MavenProject mavenProject) { + final Properties properties = new Properties(mavenProject.getProperties()); + for (String each : mavenProject.getFilters()) { + try { + FileInputStream in = new FileInputStream(each); + try { + properties.load(in); + } + finally { + in.close(); + } + } + catch (IOException ignored) { } } + return properties; } private boolean ensureModuleCreated(MavenProject project) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacet.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacet.java deleted file mode 100644 index 4f6c7ae5cfe2..000000000000 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacet.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2000-2012 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.idea.maven.project; - -import com.intellij.facet.Facet; -import com.intellij.facet.FacetManager; -import com.intellij.facet.FacetType; -import com.intellij.openapi.module.Module; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author Eugene Zhuravlev - * Date: 10/19/12 - */ -public class MavenFacet extends Facet { - MavenFacet(@NotNull FacetType facetType, @NotNull Module module, @NotNull String name, @NotNull MavenFacetConfiguration configuration, @Nullable Facet underlyingFacet) { - super(facetType, module, name, configuration, underlyingFacet); - } - - @Override - public boolean isImplicit() { - return true; - } - - @Nullable - public static MavenFacet getInstance(Module module) { - return FacetManager.getInstance(module).getFacetByType(MavenFacetType.ID); - } -} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetConfiguration.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetConfiguration.java deleted file mode 100644 index f3fe85a1fc14..000000000000 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetConfiguration.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2000-2012 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.idea.maven.project; - -import com.intellij.facet.FacetConfiguration; -import com.intellij.facet.ui.FacetEditorContext; -import com.intellij.facet.ui.FacetEditorTab; -import com.intellij.facet.ui.FacetValidatorsManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jdom.Element; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.maven.model.MavenResource; -import org.jetbrains.jps.maven.model.impl.MavenModuleExtensionProperties; -import org.jetbrains.jps.maven.model.impl.ResourceProperties; - -import java.util.Collection; - -/** - * @author Eugene Zhuravlev - * Date: 10/19/12 - */ -public class MavenFacetConfiguration implements FacetConfiguration, PersistentStateComponent { - private static final FacetEditorTab[] TABS_EMPTY_ARRAY = new FacetEditorTab[0]; - - private final MavenModuleExtensionProperties myState = new MavenModuleExtensionProperties(); - - @Override - public FacetEditorTab[] createEditorTabs(FacetEditorContext editorContext, FacetValidatorsManager validatorsManager) { - return TABS_EMPTY_ARRAY; - } - - @Nullable - @Override - public MavenModuleExtensionProperties getState() { - return myState; - } - - @Override - public void loadState(MavenModuleExtensionProperties state) { - XmlSerializerUtil.copyBean(state, myState); - } - - @Override - public void readExternal(Element element) throws InvalidDataException { - } - - @Override - public void writeExternal(Element element) throws WriteExternalException { - } - - public void clearState() { - myState.myResources.clear(); - } - - public void addResources(Collection resources) { - for (MavenResource resource : resources) { - final ResourceProperties props = new ResourceProperties(); - final String dir = resource.getDirectory(); - props.directory = dir != null? FileUtil.toSystemIndependentName(dir) : null; - - final String target = resource.getTargetPath(); - props.targetPath = target != null? FileUtil.toSystemIndependentName(target) : null; - - props.isFiltered = resource.isFiltered(); - props.includes.clear(); - for (String include : resource.getIncludes()) { - props.includes.add(FileUtil.convertAntToRegexp(include.trim())); - } - props.excludes.clear(); - for (String exclude : resource.getExcludes()) { - props.excludes.add(FileUtil.convertAntToRegexp(exclude.trim())); - } - myState.myResources.add(props); - } - } - - @Nullable - public static MavenFacetConfiguration getInstance(Module module) { - final MavenFacet facet = MavenFacet.getInstance(module); - return facet != null? facet.getConfiguration() : null; - } - -} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetType.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetType.java deleted file mode 100644 index de5d5a7407d1..000000000000 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenFacetType.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2000-2012 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.idea.maven.project; - -import com.intellij.facet.Facet; -import com.intellij.facet.FacetType; -import com.intellij.facet.FacetTypeId; -import com.intellij.openapi.module.JavaModuleType; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author Eugene Zhuravlev - * Date: 10/19/12 - */ -public class MavenFacetType extends FacetType{ - public final static FacetTypeId ID = new FacetTypeId("_maven_"); - - public MavenFacetType() { - super(ID, ID.toString(), "Maven"); - } - - @Override - public MavenFacetConfiguration createDefaultConfiguration() { - return new MavenFacetConfiguration(); - } - - @Override - public MavenFacet createFacet(@NotNull Module module, String name, @NotNull MavenFacetConfiguration configuration, @Nullable Facet underlyingFacet) { - return new MavenFacet(this, module, name, configuration, underlyingFacet); - } - - @Override - public boolean isSuitableModuleType(ModuleType moduleType) { - return moduleType instanceof JavaModuleType; - } - - - public static MavenFacetType getInstance() { - return Holder.ourInstance; - } - - private static class Holder { - static final MavenFacetType ourInstance = FacetType.findInstance(MavenFacetType.class); - } -} diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 2ef7990e9e05..71b36f0bc9c2 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -129,8 +129,6 @@ - -