| /* |
| * 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.incremental.artifacts.instructions; |
| |
| import com.intellij.openapi.diagnostic.Logger; |
| 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.logging.ProjectBuilderLogger; |
| import org.jetbrains.jps.cmdline.ProjectDescriptor; |
| import org.jetbrains.jps.incremental.CompileContext; |
| import org.jetbrains.jps.incremental.ProjectBuildException; |
| import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; |
| import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping; |
| import org.jetbrains.jps.incremental.artifacts.IncArtifactBuilder; |
| import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactPathUtil; |
| |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.Collections; |
| |
| /** |
| * @author nik |
| */ |
| public class FileBasedArtifactRootDescriptor extends ArtifactRootDescriptor { |
| private static final Logger LOG = Logger.getInstance(FileBasedArtifactRootDescriptor.class); |
| private FileCopyingHandler myCopyingHandler; |
| |
| public FileBasedArtifactRootDescriptor(@NotNull File file, |
| @NotNull SourceFileFilter filter, |
| int index, |
| ArtifactBuildTarget target, |
| @NotNull DestinationInfo destinationInfo, FileCopyingHandler copyingHandler) { |
| super(file, createCompositeFilter(filter, copyingHandler.createFileFilter()), index, target, destinationInfo); |
| myCopyingHandler = copyingHandler; |
| } |
| |
| @NotNull |
| private static SourceFileFilter createCompositeFilter(@NotNull final SourceFileFilter baseFilter, @NotNull final FileFilter filter) { |
| if (filter.equals(FileUtilRt.ALL_FILES)) return baseFilter; |
| return new CompositeSourceFileFilter(baseFilter, filter); |
| } |
| |
| @Override |
| protected String getFullPath() { |
| return myRoot.getPath(); |
| } |
| |
| @Override |
| public void writeConfiguration(PrintWriter out) { |
| super.writeConfiguration(out); |
| myCopyingHandler.writeConfiguration(out); |
| } |
| |
| public void copyFromRoot(String filePath, |
| int rootIndex, String outputPath, |
| CompileContext context, BuildOutputConsumer outputConsumer, |
| ArtifactOutputToSourceMapping outSrcMapping) throws IOException, ProjectBuildException { |
| final File file = new File(filePath); |
| if (!file.exists()) return; |
| String targetPath; |
| if (!FileUtil.filesEqual(file, getRootFile())) { |
| final String relativePath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(getRootFile().getPath()), filePath, '/'); |
| if (relativePath == null || relativePath.startsWith("..")) { |
| throw new ProjectBuildException(new AssertionError(filePath + " is not under " + getRootFile().getPath())); |
| } |
| targetPath = JpsArtifactPathUtil.appendToPath(outputPath, relativePath); |
| } |
| else { |
| targetPath = outputPath; |
| } |
| |
| final File targetFile = new File(targetPath); |
| if (FileUtil.filesEqual(file, targetFile)) { |
| //do not process file if should be copied to itself. Otherwise the file will be included to source-to-output mapping and will be deleted by rebuild |
| return; |
| } |
| |
| if (outSrcMapping.getState(targetPath) == null) { |
| ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); |
| if (logger.isEnabled()) { |
| logger.logCompiledFiles(Collections.singletonList(file), IncArtifactBuilder.BUILDER_NAME, "Copying file:"); |
| } |
| myCopyingHandler.copyFile(file, targetFile, context); |
| outputConsumer.registerOutputFile(targetFile, Collections.singletonList(filePath)); |
| } |
| else if (LOG.isDebugEnabled()) { |
| LOG.debug("Target path " + targetPath + " is already registered so " + filePath + " won't be copied"); |
| } |
| outSrcMapping.appendData(targetPath, rootIndex, filePath); |
| } |
| |
| private static class CompositeSourceFileFilter extends SourceFileFilter { |
| private final SourceFileFilter myBaseFilter; |
| private final FileFilter myFilter; |
| |
| public CompositeSourceFileFilter(SourceFileFilter baseFilter, FileFilter filter) { |
| myBaseFilter = baseFilter; |
| myFilter = filter; |
| } |
| |
| @Override |
| public boolean accept(@NotNull String fullFilePath) { |
| return myFilter.accept(new File(fullFilePath)) && myBaseFilter.accept(fullFilePath); |
| } |
| |
| @Override |
| public boolean shouldBeCopied(@NotNull String fullFilePath, ProjectDescriptor projectDescriptor) throws IOException { |
| return myBaseFilter.shouldBeCopied(fullFilePath, projectDescriptor); |
| } |
| } |
| } |