package com.intellij.jps.flex.build;
import com.intellij.flex.FlexCommonUtils;
import com.intellij.flex.build.FlexResourceBuildTarget;
import com.intellij.flex.build.FlexResourceBuildTargetType;
import com.intellij.flex.model.bc.JpsFlexBuildConfiguration;
import com.intellij.flex.model.bc.JpsFlexCompilerOptions;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.PathUtilRt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildOutputConsumer;
import org.jetbrains.jps.builders.BuildRootDescriptor;
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.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.java.compiler.JpsCompilerExcludes;
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
public class FlexResourceBuilder extends TargetBuilder<BuildRootDescriptor, FlexResourceBuildTarget> {
private static final @NonNls String BUILDER_NAME = "Flash Resource Builder";
protected FlexResourceBuilder() {
super(Arrays.asList(FlexResourceBuildTargetType.PRODUCTION, FlexResourceBuildTargetType.TEST));
}
@NotNull
public String getPresentableName() {
return BUILDER_NAME;
}
public void build(@NotNull final FlexResourceBuildTarget target,
@NotNull final DirtyFilesHolder<BuildRootDescriptor, FlexResourceBuildTarget> holder,
@NotNull final BuildOutputConsumer outputConsumer,
@NotNull final CompileContext context) throws ProjectBuildException, IOException {
final JpsJavaCompilerConfiguration configuration =
JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(target.getModule().getProject());
final JpsCompilerExcludes excludes = configuration.getCompilerExcludes();
try {
holder.processDirtyFiles(new FileProcessor<BuildRootDescriptor, FlexResourceBuildTarget>() {
public boolean apply(final FlexResourceBuildTarget target, final File file, final BuildRootDescriptor root) throws IOException {
if (excludes.isExcluded(file)) return true;
final String relativePath = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(root.getRootFile(), file));
if (target.isTests()) {
if (!FlexCommonUtils.isSourceFile(file.getName())) {
final String outputRootUrl = JpsJavaExtensionService.getInstance().getOutputUrl(target.getModule(), target.isTests());
if (outputRootUrl == null) return true;
final String targetPath = JpsPathUtil.urlToPath(outputRootUrl) + '/' + relativePath;
context.processMessage(new ProgressMessage("Copying " + file.getPath()));
copyResource(context, file, Collections.singleton(targetPath), outputConsumer);
}
}
else {
final Collection<String> targetPaths = new ArrayList<>();
for (JpsFlexBuildConfiguration bc : target.getModule().getProperties().getBuildConfigurations()) {
if (bc.isSkipCompile() || !FlexCommonUtils.canHaveResourceFiles(bc.getNature()) ||
bc.getCompilerOptions().getResourceFilesMode() == JpsFlexCompilerOptions.ResourceFilesMode.None) {
continue;
}
final JpsFlexCompilerOptions.ResourceFilesMode mode = bc.getCompilerOptions().getResourceFilesMode();
if (mode == JpsFlexCompilerOptions.ResourceFilesMode.All && !FlexCommonUtils.isSourceFile(file.getName()) ||
mode == JpsFlexCompilerOptions.ResourceFilesMode.ResourcePatterns && configuration.isResourceFile(file, root.getRootFile())) {
final String outputFolder = PathUtilRt.getParentPath(bc.getActualOutputFilePath());
targetPaths.add(outputFolder + "/" + relativePath);
}
}
if (!targetPaths.isEmpty()) {
context.processMessage(new ProgressMessage("Copying " + file.getPath()));
copyResource(context, file, targetPaths, outputConsumer);
}
}
return true;
}
});
}
catch (Exception e) {
throw new ProjectBuildException(e.getMessage(), e);
}
}
private static void copyResource(final CompileContext context,
final File file,
final Collection<String> targetPaths,
final BuildOutputConsumer outputConsumer) {
try {
for (String targetPath : targetPaths) {
final File targetFile = new File(targetPath);
FileUtil.copyContent(file, targetFile);
outputConsumer.registerOutputFile(targetFile, Collections.singletonList(file.getPath()));
}
}
catch (IOException e) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, e.getMessage(),
FileUtil.toSystemIndependentName(file.getPath())));
}
}
}