old packaging compiler removed

This commit is contained in:
nik
2009-11-02 15:36:24 +03:00
parent 6e52b45cdc
commit 84f3745d38
49 changed files with 191 additions and 3373 deletions
@@ -18,7 +18,6 @@ package com.intellij.compiler;
import com.intellij.compiler.impl.*;
import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
import com.intellij.compiler.impl.javaCompiler.JavaCompiler;
import com.intellij.compiler.impl.packagingCompiler.IncrementalPackagingCompiler;
import com.intellij.compiler.impl.resourceCompiler.ResourceCompiler;
import com.intellij.compiler.impl.rmiCompiler.RmicCompiler;
import com.intellij.openapi.compiler.*;
@@ -69,7 +68,6 @@ public class CompilerManagerImpl extends CompilerManager {
addCompiler(new AnnotationProcessingCompiler(project));
addCompiler(new ResourceCompiler(project, compilerConfiguration));
addCompiler(new RmicCompiler());
addCompiler(new IncrementalPackagingCompiler());
addCompiler(new IncrementalArtifactsCompiler());
for(Compiler compiler: Extensions.getExtensions(Compiler.EP_NAME, myProject)) {
@@ -1,64 +0,0 @@
/*
* Copyright 2000-2009 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.
*/
/**
* @author cdr
*/
package com.intellij.compiler.ant.j2ee;
import com.intellij.compiler.ant.ExplodedAndJarTargetParameters;
import com.intellij.compiler.ant.Tag;
import com.intellij.compiler.ant.taskdefs.Target;
import com.intellij.compiler.make.ExplodedAndJarBuildGenerator;
import com.intellij.openapi.compiler.make.BuildInstruction;
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.extensions.Extensions;
public class BuildExplodedTarget extends Target {
public BuildExplodedTarget(final ExplodedAndJarTargetParameters parameters,
final BuildRecipe buildRecipe,
final String description) {
super(parameters.getBuildExplodedTargetName(), null, description, null);
final ExplodedAndJarBuildGenerator[] generators = Extensions.getExtensions(DefaultExplodedAndJarBuildGenerator.EP_NAME);
// reverse order to get overwriting instructions later
buildRecipe.visitInstructions(new BuildInstructionVisitor() {
private int myInstructionCount;
public boolean visitInstruction(final BuildInstruction instruction) throws Exception {
for (final ExplodedAndJarBuildGenerator generator : generators) {
final Tag[] tags = generator.generateTagsForExplodedTarget(instruction, parameters, myInstructionCount);
if (tags != null) {
for (final Tag tag : tags) {
add(tag);
}
return true;
}
}
for (final Tag tag : DefaultExplodedAndJarBuildGenerator.INSTANCE.generateTagsForExplodedTarget(instruction, parameters,
myInstructionCount)) {
add(tag);
}
myInstructionCount++;
return super.visitInstruction(instruction);
}
}, true);
}
}
@@ -1,81 +0,0 @@
/*
* Copyright 2000-2009 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.
*/
/*
* User: anna
* Date: 19-Dec-2006
*/
package com.intellij.compiler.ant.j2ee;
import com.intellij.compiler.ant.BuildProperties;
import com.intellij.compiler.ant.CompositeGenerator;
import com.intellij.compiler.ant.ExplodedAndJarTargetParameters;
import com.intellij.compiler.ant.GenerationUtils;
import com.intellij.compiler.ant.taskdefs.AntCall;
import com.intellij.compiler.ant.taskdefs.Param;
import com.intellij.compiler.ant.taskdefs.Property;
import com.intellij.compiler.ant.taskdefs.Target;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFileManager;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class CompositeBuildTarget extends CompositeGenerator {
public CompositeBuildTarget(ExplodedAndJarTargetParameters parameters,
final String targetName, final String targetDescription,
final String depends, @Nullable String jarPath) {
final File moduleBaseDir = parameters.getChunk().getBaseDir();
final Target buildTarget = new Target(targetName, depends, targetDescription, null);
final BuildConfiguration buildConfiguration = parameters.getBuildConfiguration();
final String baseDirProperty = BuildProperties.getModuleChunkBasedirProperty(parameters.getChunk());
if (buildConfiguration.isExplodedEnabled()) {
final String explodedPath = buildConfiguration.getExplodedPath();
if (explodedPath != null) {
String location = GenerationUtils.toRelativePath(VirtualFileManager.extractPath(explodedPath), moduleBaseDir, baseDirProperty,
parameters.getGenerationOptions());
add(new Property(parameters.getExplodedPathProperty(), location));
}
final AntCall antCall = new AntCall(parameters.getBuildExplodedTargetName());
buildTarget.add(antCall);
antCall.add(new Param(parameters.getExplodedPathParameter(), BuildProperties.propertyRef(parameters.getExplodedPathProperty())));
}
if (jarPath == null) {
jarPath = getJarPath(buildConfiguration);
}
if (jarPath != null) {
String location = GenerationUtils.toRelativePath(VirtualFileManager.extractPath(jarPath), moduleBaseDir, baseDirProperty,
parameters.getGenerationOptions());
add(new Property(parameters.getJarPathProperty(), location));
final AntCall antCall = new AntCall(parameters.getBuildJarTargetName());
buildTarget.add(antCall);
antCall.add(new Param(parameters.getJarPathParameter(), BuildProperties.propertyRef(parameters.getJarPathProperty())));
}
add(buildTarget);
}
@Nullable
protected static String getJarPath(BuildConfiguration buildConfiguration){
return buildConfiguration.isJarEnabled() ? buildConfiguration.getJarPath() : null;
}
}
@@ -1,107 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.ant.j2ee;
import com.intellij.compiler.ant.*;
import com.intellij.compiler.ant.taskdefs.*;
import com.intellij.compiler.make.ExplodedAndJarBuildGenerator;
import com.intellij.compiler.make.MakeUtil;
import com.intellij.openapi.compiler.make.*;
import com.intellij.openapi.module.Module;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
/**
* @author peter
*/
public class DefaultExplodedAndJarBuildGenerator extends ExplodedAndJarBuildGenerator {
public static final DefaultExplodedAndJarBuildGenerator INSTANCE = new DefaultExplodedAndJarBuildGenerator();
@NotNull
public Tag[] generateTagsForExplodedTarget(@NotNull final BuildInstruction instruction, @NotNull final ExplodedAndJarTargetParameters parameters,
final int instructionCount)
throws Exception {
final File moduleBaseDir = parameters.getChunk().getBaseDir();
final List<Tag> tags = new SmartList<Tag>();
instruction.accept(new BuildInstructionVisitor() {
public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws RuntimeException {
if (instruction.isExternalDependencyInstruction()) return true;
final File sourceFile = instruction.getFile();
final String outputRelativePath = "/" + instruction.getOutputRelativePath();
final String baseDirProperty = BuildProperties.getModuleBasedirProperty(instruction.getModule());
final String sourceLocation = GenerationUtils.toRelativePath(sourceFile.getPath(), moduleBaseDir, baseDirProperty,
parameters.getGenerationOptions());
final Copy copy;
if (instruction.isDirectory()) {
copy = new Copy(BuildProperties.propertyRef(parameters.getExplodedPathParameter()) + outputRelativePath);
final FileSet fileSet = new FileSet(sourceLocation);
copy.add(fileSet);
}
else {
copy = new Copy(sourceLocation, BuildProperties.propertyRef(parameters.getExplodedPathParameter()) + outputRelativePath);
}
tags.add(copy);
return true;
}
public boolean visitJarAndCopyBuildInstruction(JarAndCopyBuildInstruction instruction) throws RuntimeException {
if (instruction.isExternalDependencyInstruction()) return true;
final String outputRelativePath = instruction.getOutputRelativePath();
final String destFile = BuildProperties.propertyRef(parameters.getExplodedPathParameter()) + outputRelativePath;
final @NonNls String jarDirProperty = parameters.getBuildExplodedTargetName() + ".jar.dir" + instructionCount;
tags.add(new Dirname(jarDirProperty, destFile));
tags.add(new Mkdir(BuildProperties.propertyRef(jarDirProperty)));
tags.add(generateExplodedTag(instruction, destFile, moduleBaseDir, parameters.getGenerationOptions()));
return true;
}
});
return tags.toArray(new Tag[tags.size()]);
}
private static Tag generateExplodedTag(BuildInstruction instruction, final String destFile, File moduleBaseDir, final GenerationOptions genOptions) {
final Tag tag = new Jar(destFile, "preserve");
final Module module = instruction.getModule();
final String moduleOutputDirPath = MakeUtil.getModuleOutputDirPath(module);
String sourceLocation = GenerationUtils.toRelativePath(moduleOutputDirPath, moduleBaseDir, module, genOptions);
final FileSet fileSet = new FileSet(sourceLocation);
tag.add(fileSet);
return tag;
}
public static Tag generateJarTag(BuildInstruction instruction, final String destFile, File moduleBaseDir, final GenerationOptions genOptions) {
final Tag jarTag = new Jar(destFile, "preserve");
final Manifest manifestTag = new Manifest();
jarTag.add(manifestTag);
manifestTag.applyAttributes(new java.util.jar.Manifest());
final Module module = instruction.getModule();
final String moduleOutputDirPath = MakeUtil.getModuleOutputDirPath(module);
String sourceLocation = GenerationUtils.toRelativePath(moduleOutputDirPath, moduleBaseDir, module, genOptions);
final FileSet fileSet = new FileSet(sourceLocation);
jarTag.add(fileSet);
return jarTag;
}
}
@@ -20,7 +20,6 @@
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.make.BuildInstruction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.UserDataHolderBase;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -31,30 +30,20 @@ import java.util.Collection;
public abstract class BuildInstructionBase extends UserDataHolderBase implements BuildInstruction, Cloneable {
private final String myOutputRelativePath;
private final Module myModule;
private Collection<File> myFilesToDelete;
protected BuildInstructionBase(String outputRelativePath, Module module) {
protected BuildInstructionBase(String outputRelativePath) {
myOutputRelativePath = outputRelativePath;
myModule = module;
}
public String getOutputRelativePath() {
return myOutputRelativePath;
}
public Module getModule() {
return myModule;
}
public BuildInstructionBase clone() {
return (BuildInstructionBase)super.clone();
}
public boolean isExternalDependencyInstruction() {
return getOutputRelativePath().startsWith("..");
}
public void addFileToDelete(File file) {
if (myFilesToDelete == null) {
myFilesToDelete = new THashSet<File>();
@@ -19,15 +19,12 @@
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
import com.intellij.openapi.compiler.make.BuildInstruction;
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.openapi.deployment.DeploymentUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
@@ -69,21 +66,8 @@ public class BuildRecipeImpl implements BuildRecipe {
return true;
}
public void addAll(@NotNull BuildRecipe buildRecipe) {
buildRecipe.visitInstructions(new BuildInstructionVisitor() {
public boolean visitInstruction(BuildInstruction instruction) throws RuntimeException {
addInstruction(instruction);
return true;
}
}, false);
}
public void addFileCopyInstruction(@NotNull File file,
boolean isDirectory,
Module module,
String outputRelativePath,
@Nullable PackagingFileFilter fileFilter) {
addInstruction(new FileCopyInstructionImpl(file, isDirectory, module, DeploymentUtil.trimForwardSlashes(outputRelativePath),fileFilter));
public void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath) {
addInstruction(new FileCopyInstructionImpl(file, isDirectory, DeploymentUtil.trimForwardSlashes(outputRelativePath)));
}
public String toString() {
@@ -18,63 +18,24 @@ package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
import com.intellij.openapi.compiler.make.FileCopyInstruction;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
public class FileCopyInstructionImpl extends BuildInstructionBase implements FileCopyInstruction {
private File myFile;
private boolean myIsDirectory;
// for a directory keep the subset of changed files that need to be copied
private List<FileCopyInstructionImpl> myChangedSet;
private @Nullable final PackagingFileFilter myFileFilter;
protected FileCopyInstructionImpl(File source,
boolean isDirectory,
Module module,
String outputRelativePath) {
this(source, isDirectory, module, outputRelativePath, null);
}
public FileCopyInstructionImpl(File source,
boolean isDirectory,
Module module,
String outputRelativePath,
@Nullable final PackagingFileFilter fileFilter) {
super(outputRelativePath, module);
myFileFilter = fileFilter;
public FileCopyInstructionImpl(File source, boolean isDirectory, String outputRelativePath) {
super(outputRelativePath);
setFile(source, isDirectory);
}
@Nullable
public PackagingFileFilter getFileFilter() {
return myFileFilter;
}
public boolean accept(BuildInstructionVisitor visitor) throws Exception {
return visitor.visitFileCopyInstruction(this);
}
public String toString() {
if (myChangedSet == null) {
if (getModule() != null) {
return CompilerBundle.message("file.copy.instruction.file.from.module.to.file.message.text", getFile(),
ModuleUtil.getModuleNameInReadAction(getModule()), getOutputRelativePath());
} else {
return CompilerBundle.message("file.copy.instruction.file.to.file.message.text", getFile(), getOutputRelativePath());
}
}
else {
StringBuilder builder = new StringBuilder(CompilerBundle.message("file.copy.instruction.message.text", myFile));
for (FileCopyInstruction fileCopyInstruction : myChangedSet) {
builder.append(fileCopyInstruction).append(", ");
}
return builder.toString();
}
return CompilerBundle.message("file.copy.instruction.file.to.file.message.text", getFile(), getOutputRelativePath());
}
public boolean equals(Object o) {
@@ -1,132 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.compiler.make.BuildParticipant;
import com.intellij.openapi.compiler.make.BuildParticipantProvider;
import com.intellij.openapi.deployment.DeploymentUtilImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author nik
*/
public class IncrementalPackagingCompiler extends PackagingCompilerBase {
public static final Key<Set<BuildParticipant>> AFFECTED_PARTICIPANTS_KEY = Key.create("AFFECTED_PARTICIPANTS");
private static final Key<List<String>> FILES_TO_DELETE_KEY = Key.create("files_to_delete");
private static final Key<OldProcessingItemsBuilderContext> BUILDER_CONTEXT_KEY = Key.create("processing_items_builder");
@NonNls private static final String INCREMENTAL_PACKAGING_CACHE_ID = "incremental_packaging";
public IncrementalPackagingCompiler() {
super(FILES_TO_DELETE_KEY, BUILDER_CONTEXT_KEY);
}
@Override
protected PackagingProcessingItem[] collectItems(OldProcessingItemsBuilderContext builderContext, final Project project) {
Module[] allModules = ModuleManager.getInstance(project).getSortedModules();
final BuildParticipantProvider[] providers = DeploymentUtilImpl.getBuildParticipantProviders();
for (BuildParticipantProvider provider : providers) {
addItemsForProvider(provider, allModules, builderContext);
}
return builderContext.getProcessingItems();
}
private static void addItemsForProvider(final BuildParticipantProvider provider,
final Module[] modulesToCompile,
OldProcessingItemsBuilderContext builderContext) {
for (Module module : modulesToCompile) {
final Collection<? extends BuildParticipant> participants = provider.getParticipants(module);
for (BuildParticipant participant : participants) {
addItemsForParticipant(participant, builderContext);
}
}
}
private static void addItemsForParticipant(final BuildParticipant participant, OldProcessingItemsBuilderContext builderContext) {
participant.buildStarted(builderContext.getCompileContext());
new ProcessingItemsBuilder(participant, builderContext).build();
}
@NotNull
public String getDescription() {
return CompilerBundle.message("incremental.packaging.compiler.description");
}
protected String getOutputCacheId() {
return INCREMENTAL_PACKAGING_CACHE_ID;
}
protected void onBuildFinished(OldProcessingItemsBuilderContext builderContext, JarsBuilder builder, final Project project) throws Exception {
final Set<BuildParticipant> affectedParticipants = getAffectedParticipants(builderContext.getCompileContext());
for (ExplodedDestinationInfo destination : builder.getJarsDestinations()) {
affectedParticipants.add(builderContext.getDestinationOwner(destination));
}
CompileContext context = builderContext.getCompileContext();
for (BuildParticipant participant : affectedParticipants) {
BuildConfiguration buildConfiguration = participant.getBuildConfiguration();
if (participant.willBuildExploded()) {
participant.afterExplodedCreated(new File(FileUtil.toSystemDependentName(DeploymentUtilImpl.getOrCreateExplodedDir(participant))),
context);
}
String jarPath = buildConfiguration.getJarPath();
if (buildConfiguration.isJarEnabled() && jarPath != null) {
participant.afterJarCreated(new File(FileUtil.toSystemDependentName(jarPath)), context);
}
participant.buildFinished(context);
}
}
public static Set<BuildParticipant> getAffectedParticipants(CompileContext context) {
return context.getUserData(AFFECTED_PARTICIPANTS_KEY);
}
@Override
protected void beforeBuildStarted(OldProcessingItemsBuilderContext context) {
context.getCompileContext().putUserData(AFFECTED_PARTICIPANTS_KEY, new HashSet<BuildParticipant>());
}
protected OldProcessingItemsBuilderContext createContext(CompileContext context) {
return new OldProcessingItemsBuilderContext(context);
}
@Override
protected void onFileCopied(OldProcessingItemsBuilderContext builderContext, ExplodedDestinationInfo explodedDestination) {
getAffectedParticipants(builderContext.getCompileContext()).add(builderContext.getDestinationOwner(explodedDestination));
}
protected boolean doNotStartBuild(CompileContext context) {
Module[] affectedModules = context.getCompileScope().getAffectedModules();
return affectedModules.length == 0;
}
}
@@ -1,52 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
import com.intellij.openapi.compiler.make.JarAndCopyBuildInstruction;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.io.File;
/**
* Created by IntelliJ IDEA.
* User: cdr
* Date: Jun 21, 2004
* Time: 4:08:34 PM
* To change this template use File | Settings | File Templates.
*/
public class JarAndCopyBuildInstructionImpl extends FileCopyInstructionImpl implements JarAndCopyBuildInstruction {
public JarAndCopyBuildInstructionImpl(Module module, File directoryToJar, String outputRelativePath, @Nullable PackagingFileFilter fileFilter) {
super(directoryToJar, false, module, outputRelativePath, fileFilter);
}
public JarAndCopyBuildInstructionImpl(Module module, File directoryToJar, String outputRelativePath) {
super(directoryToJar, false, module, outputRelativePath);
}
public boolean accept(BuildInstructionVisitor visitor) throws Exception {
return visitor.visitJarAndCopyBuildInstruction(this);
}
@NonNls public String toString() {
return "JAR and copy: " + getFile() + "->"+getOutputRelativePath();
}
}
@@ -1,40 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import java.util.List;
/**
* @author nik
*/
public class ManifestFileInfo {
private final String myOutputPath;
private final List<String> myClasspath;
public ManifestFileInfo(final String outputPath, final List<String> classpath) {
myOutputPath = outputPath;
myClasspath = classpath;
}
public String getOutputPath() {
return myOutputPath;
}
public List<String> getClasspath() {
return myClasspath;
}
}
@@ -1,99 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.compiler.make.BuildParticipant;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.*;
/**
* @author nik
*/
public class OldProcessingItemsBuilderContext extends ProcessingItemsBuilderContext<PackagingProcessingItem> {
private final Map<BuildConfiguration, JarInfo> myCachedJarForConfiguration;
private final Map<ExplodedDestinationInfo, BuildParticipant> myDestinationOwners;
private final MultiValuesMap<Module, PackagingProcessingItem> myItemsByModule;
public OldProcessingItemsBuilderContext(CompileContext compileContext) {
super(compileContext);
myCachedJarForConfiguration = new HashMap<BuildConfiguration, JarInfo>();
myDestinationOwners = new HashMap<ExplodedDestinationInfo, BuildParticipant>();
myItemsByModule = new MultiValuesMap<Module, PackagingProcessingItem>();
}
public PackagingProcessingItem[] getProcessingItems(Module[] modules) {
List<PackagingProcessingItem> items = new ArrayList<PackagingProcessingItem>();
for (Module module : modules) {
Collection<PackagingProcessingItem> itemsByModule = myItemsByModule.get(module);
if (itemsByModule != null) {
items.addAll(itemsByModule);
}
}
return items.toArray(new PackagingProcessingItem[items.size()]);
}
public PackagingProcessingItem getOrCreateProcessingItem(final VirtualFile sourceFile, BuildParticipant participant) {
PackagingProcessingItem item = getOrCreateProcessingItem(sourceFile);
myItemsByModule.put(participant.getModule(), item);
return item;
}
private JarInfo getCachedJar(BuildConfiguration configuration) {
return myCachedJarForConfiguration.get(configuration);
}
private void putCachedJar(BuildConfiguration configuration, JarInfo info) {
myCachedJarForConfiguration.put(configuration, info);
}
public ProcessingItemsBuilder.NestedJarInfo createNestedJarInfo(final DestinationInfo destinationInfo, final BuildConfiguration buildConfiguration,
BuildRecipe buildRecipe) {
JarInfo jarInfo = getCachedJar(buildConfiguration);
boolean addJarContent = jarInfo == null;
if (jarInfo == null) {
jarInfo = new JarInfo();
putCachedJar(buildConfiguration, jarInfo);
}
jarInfo.addDestination(destinationInfo);
if (destinationInfo instanceof ExplodedDestinationInfo) {
registerJarFile(jarInfo, destinationInfo.getOutputFilePath());
}
return new ProcessingItemsBuilder.NestedJarInfo(jarInfo, destinationInfo, addJarContent);
}
public void registerDestination(final BuildParticipant buildParticipant, final ExplodedDestinationInfo destinationInfo) {
myDestinationOwners.put(destinationInfo, buildParticipant);
}
public BuildParticipant getDestinationOwner(ExplodedDestinationInfo destination) {
return myDestinationOwners.get(destination);
}
protected PackagingProcessingItem createProcessingItem(VirtualFile sourceFile) {
return new PackagingProcessingItem(sourceFile);
}
public PackagingProcessingItem[] getProcessingItems() {
final Collection<PackagingProcessingItem> processingItems = myItemsBySource.values();
return processingItems.toArray(new PackagingProcessingItem[processingItems.size()]);
}
}
@@ -1,454 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.compiler.impl.CompilerUtil;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.deployment.DeploymentUtil;
import com.intellij.openapi.deployment.DeploymentUtilImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.*;
import java.util.jar.Manifest;
/**
* @author nik
*/
public abstract class PackagingCompilerBase implements PackagingCompiler {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.packagingCompiler.PackagingCompilerBase");
private final Key<List<String>> myFilesToDeleteKey;
private final Key<OldProcessingItemsBuilderContext> myBuilderContextKey;
@Nullable private PackagingCompilerCache myOutputItemsCache;
protected PackagingCompilerBase(final Key<List<String>> filesToDeleteKey, final Key<OldProcessingItemsBuilderContext> builderContextKey) {
myFilesToDeleteKey = filesToDeleteKey;
myBuilderContextKey = builderContextKey;
}
@NotNull
private PackagingCompilerCache getOutputItemsCache(final Project project) {
if (myOutputItemsCache == null) {
myOutputItemsCache = new PackagingCompilerCache(CompilerPaths.getCompilerSystemDirectory(project).getPath() + File.separator +
getOutputCacheId() + "_timestamp.dat");
}
return myOutputItemsCache;
}
protected abstract String getOutputCacheId();
protected abstract PackagingProcessingItem[] collectItems(OldProcessingItemsBuilderContext builderContext, final Project project);
public void processOutdatedItem(final CompileContext context, final String url, @Nullable final ValidityState state) {
}
protected boolean collectFilesToDelete(final CompileContext context, final PackagingProcessingItem[] allProcessingItems) {
List<String> filesToDelete = new ArrayList<String>();
Set<String> outputPaths = createPathsHashSet();
for (PackagingProcessingItem item : allProcessingItems) {
for (DestinationInfo destinationInfo : item.getDestinations()) {
String outputPath = getOutputPathWithJarSeparator(destinationInfo);
outputPaths.add(outputPath);
}
}
final Iterator<String> pathIterator = getOutputItemsCache(context.getProject()).getUrlsIterator();
while (pathIterator.hasNext()) {
String path = pathIterator.next();
if (!outputPaths.contains(path)) {
filesToDelete.add(path);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Files to delete (" + filesToDelete.size() + "):");
for (String path : filesToDelete) {
LOG.debug(path);
}
}
if (filesToDelete.isEmpty()) {
return false;
}
context.putUserData(myFilesToDeleteKey, filesToDelete);
return true;
}
private static String getOutputPathWithJarSeparator(DestinationInfo destinationInfo) {
String outputPath = destinationInfo.getOutputFilePath();
if (destinationInfo instanceof JarDestinationInfo) {
final String fullOutputPath = destinationInfo.getOutputPath();
final String fileOutputPath = destinationInfo.getOutputFilePath();
if (fullOutputPath.startsWith(fileOutputPath)) {
outputPath += JarFileSystem.JAR_SEPARATOR + DeploymentUtil.trimForwardSlashes(fullOutputPath.substring(fileOutputPath.length()));
}
}
return outputPath;
}
private static THashSet<String> createPathsHashSet() {
return SystemInfo.isFileSystemCaseSensitive ? new THashSet<String>() : new THashSet<String>(CaseInsensitiveStringHashingStrategy.INSTANCE);
}
public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
final Set<String> deletedJars = deleteOutdatedFiles(context);
final List<PackagingProcessingItem> processedItems = new ArrayList<PackagingProcessingItem>();
final Set<String> writtenPaths = createPathsHashSet();
final Ref<Boolean> built = Ref.create(false);
CompilerUtil.runInContext(context, "Copying files", new ThrowableRunnable<RuntimeException>() {
public void run() throws RuntimeException {
built.set(doBuild(context, items, processedItems, writtenPaths, deletedJars));
}
});
if (!built.get()) {
return ProcessingItem.EMPTY_ARRAY;
}
context.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.updating.caches"));
context.getProgressIndicator().setText2("");
refreshOutputFiles(writtenPaths);
new ReadAction() {
protected void run(final Result result) {
processDestinations(processedItems);
}
}.execute();
removeInvalidItems(processedItems);
updateOutputCache(context.getProject(), processedItems);
return processedItems.toArray(new ProcessingItem[processedItems.size()]);
}
private static void removeInvalidItems(List<PackagingProcessingItem> processedItems) {
Set<VirtualFile> files = new THashSet<VirtualFile>(processedItems.size());
for (PackagingProcessingItem item : processedItems) {
files.add(item.getFile());
}
RefreshQueue.getInstance().refresh(false, false, null, files.toArray(new VirtualFile[files.size()]));
final Iterator<PackagingProcessingItem> iterator = processedItems.iterator();
while (iterator.hasNext()) {
PackagingProcessingItem item = iterator.next();
final VirtualFile file = item.getFile();
if (!file.isValid()) {
iterator.remove();
}
}
}
private boolean doBuild(final CompileContext context, final ProcessingItem[] items, final List<PackagingProcessingItem> processedItems,
final Set<String> writtenPaths, final Set<String> deletedJars) {
if (LOG.isDebugEnabled()) {
int num = Math.min(100, items.length);
LOG.debug("Files to process (" + num + " of " + items.length + "):");
for (int i = 0; i < num; i++) {
LOG.debug(items[i].getFile().getPath());
}
}
final DeploymentUtil deploymentUtil = DeploymentUtil.getInstance();
final FileFilter fileFilter = new IgnoredFileFilter();
final OldProcessingItemsBuilderContext builderContext = context.getUserData(myBuilderContextKey);
final Set<JarInfo> changedJars = new THashSet<JarInfo>();
for (String deletedJar : deletedJars) {
final Collection<JarInfo> infos = builderContext.getJarInfos(deletedJar);
if (infos != null) {
changedJars.addAll(infos);
}
}
beforeBuildStarted(builderContext);
try {
int i = 0;
for (final ProcessingItem item0 : items) {
if (item0 instanceof MockProcessingItem) continue;
final PackagingProcessingItem item = (PackagingProcessingItem)item0;
context.getProgressIndicator().checkCanceled();
final Ref<IOException> exception = Ref.create(null);
new ReadAction() {
protected void run(final Result result) {
final List<DestinationInfo> destinations = item.getDestinations();
final File fromFile = VfsUtil.virtualToIoFile(item.getFile());
for (DestinationInfo destination : destinations) {
if (destination instanceof ExplodedDestinationInfo) {
final ExplodedDestinationInfo explodedDestination = (ExplodedDestinationInfo)destination;
File toFile = new File(FileUtil.toSystemDependentName(explodedDestination.getOutputPath()));
if (fromFile.exists()) {
try {
deploymentUtil.copyFile(fromFile, toFile, context, writtenPaths, fileFilter);
}
catch (IOException e) {
exception.set(e);
return;
}
}
onFileCopied(builderContext, explodedDestination);
}
else {
changedJars.add(((JarDestinationInfo)destination).getJarInfo());
}
}
}
}.execute();
if (exception.get() != null) {
throw exception.get();
}
context.getProgressIndicator().setFraction(++i*1.0/items.length);
processedItems.add(item);
}
createManifestFiles(builderContext.getManifestFiles());
JarsBuilder builder = new JarsBuilder(changedJars, fileFilter, context);
final boolean processed = builder.buildJars(writtenPaths);
if (!processed) {
return false;
}
Set<VirtualFile> recompiledSources = new HashSet<VirtualFile>();
for (JarInfo info : builder.getJarsToBuild()) {
for (Pair<String, VirtualFile> pair : info.getPackedFiles()) {
recompiledSources.add(pair.getSecond());
}
}
for (PackagingProcessingItem processedItem : processedItems) {
recompiledSources.remove(processedItem.getFile());
}
for (VirtualFile source : recompiledSources) {
PackagingProcessingItem item = builderContext.getItemBySource(source);
LOG.assertTrue(item != null, source);
processedItems.add(item);
}
onBuildFinished(builderContext, builder, context.getProject());
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Exception e) {
LOG.info(e);
context.addMessage(CompilerMessageCategory.ERROR, e.getLocalizedMessage(), null, -1, -1);
return false;
}
return true;
}
protected void onBuildFinished(OldProcessingItemsBuilderContext context, JarsBuilder builder, final Project project) throws Exception {
}
private static void createManifestFiles(final List<ManifestFileInfo> manifestFileInfos) throws IOException {
for (ManifestFileInfo manifestFileInfo : manifestFileInfos) {
File outputFile = new File(FileUtil.toSystemDependentName(manifestFileInfo.getOutputPath()));
Manifest manifest;
if (outputFile.exists()) {
FileInputStream stream = new FileInputStream(outputFile);
try {
manifest = new Manifest(stream);
}
finally {
stream.close();
}
}
else {
manifest = new Manifest();
}
DeploymentUtilImpl.setManifestAttributes(manifest.getMainAttributes(), manifestFileInfo.getClasspath());
FileUtil.createParentDirs(outputFile);
FileOutputStream out = null;
try {
out = new FileOutputStream(outputFile);
manifest.write(out);
}
finally {
if (out != null) {
out.close();
}
}
}
}
private static void processDestinations(final List<PackagingProcessingItem> items) {
for (PackagingProcessingItem item : items) {
for (DestinationInfo destination : item.getDestinations()) {
destination.update();
}
}
}
private Set<String> deleteOutdatedFiles(final CompileContext context) {
context.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.deleting.outdated.files"));
final List<String> filesToDelete = context.getUserData(myFilesToDeleteKey);
final Set<String> deletedJars;
if (filesToDelete != null) {
deletedJars = deleteFiles(context.getProject(), filesToDelete);
}
else {
deletedJars = Collections.emptySet();
}
context.getProgressIndicator().checkCanceled();
return deletedJars;
}
protected Set<String> deleteFiles(final Project project, final List<String> paths) {
final THashSet<String> deletedJars = new THashSet<String>();
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting outdated files...");
}
List<File> filesToRefresh = new ArrayList<File>();
for (String fullPath : paths) {
int end = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
String filePath = end != -1 ? fullPath.substring(0, end) : fullPath;
if (end != -1) {
deletedJars.add(filePath);
}
File file = new File(FileUtil.toSystemDependentName(filePath));
filesToRefresh.add(file);
boolean deleted = FileUtil.delete(file);
if (!deleted && LOG.isDebugEnabled()) {
LOG.debug("Cannot delete file " + file);
}
if (deleted) {
getOutputItemsCache(project).remove(fullPath);
}
}
CompilerUtil.refreshIOFiles(filesToRefresh);
return deletedJars;
}
private void updateOutputCache(final Project project, final List<PackagingProcessingItem> processedItems) {
for (PackagingProcessingItem processedItem : processedItems) {
for (DestinationInfo destinationInfo : processedItem.getDestinations()) {
final VirtualFile virtualFile = destinationInfo.getOutputFile();
if (virtualFile != null) {
final String path = getOutputPathWithJarSeparator(destinationInfo);
if (LOG.isDebugEnabled()) {
LOG.debug("update output cache: file " + path);
}
getOutputItemsCache(project).update(path, virtualFile.getTimeStamp());
}
}
}
saveCacheIfDirty(project);
}
private static void refreshOutputFiles(Set<String> writtenPaths) {
final ArrayList<File> filesToRefresh = new ArrayList<File>();
for (String path : writtenPaths) {
filesToRefresh.add(new File(path));
}
CompilerUtil.refreshIOFiles(filesToRefresh);
}
private void saveCacheIfDirty(final Project project) {
if (getOutputItemsCache(project).isDirty()) {
getOutputItemsCache(project).save();
}
}
public ValidityState createValidityState(final DataInput is) throws IOException {
return new PackagingItemValidityState(is);
}
public boolean validateConfiguration(final CompileScope scope) {
return true;
}
@NotNull
public ProcessingItem[] getProcessingItems(final CompileContext context) {
return new ReadAction<ProcessingItem[]>() {
protected void run(final Result<ProcessingItem[]> result) {
final boolean doNotStartBuild = doNotStartBuild(context);
if (doNotStartBuild) {
result.setResult(ProcessingItem.EMPTY_ARRAY);
return;
}
OldProcessingItemsBuilderContext builderContext = createContext(context);
context.putUserData(myBuilderContextKey, builderContext);
PackagingProcessingItem[] allProcessingItems = collectItems(builderContext, context.getProject());
if (LOG.isDebugEnabled()) {
int num = Math.min(100, allProcessingItems.length);
LOG.debug("All files (" + num + " of " + allProcessingItems.length + "):");
for (int i = 0; i < num; i++) {
LOG.debug(allProcessingItems[i].getFile().getPath());
}
}
boolean hasFilesToDelete = collectFilesToDelete(context, builderContext.getProcessingItems());
if (hasFilesToDelete) {
MockProcessingItem mockItem = new MockProcessingItem(new LightVirtualFile("239239293"));
result.setResult(ArrayUtil.append(allProcessingItems, mockItem, ProcessingItem.class));
}
else {
result.setResult(allProcessingItems);
}
}
}.execute().getResultObject();
}
protected abstract boolean doNotStartBuild(CompileContext context);
protected abstract OldProcessingItemsBuilderContext createContext(CompileContext context);
protected void onFileCopied(OldProcessingItemsBuilderContext builderContext, ExplodedDestinationInfo explodedDestination) {
}
protected void beforeBuildStarted(OldProcessingItemsBuilderContext context) {
}
private static class MockProcessingItem implements ProcessingItem {
private final VirtualFile myFile;
public MockProcessingItem(final VirtualFile file) {
myFile = file;
}
@NotNull
public VirtualFile getFile() {
return myFile;
}
@Nullable
public ValidityState getValidityState() {
return null;
}
}
}
@@ -1,81 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.ValidityState;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import com.intellij.util.io.IOUtil;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.List;
/**
* @author nik
*/
public class PackagingItemValidityState implements ValidityState {
private final SmartList<Pair<String, Long>> myDestinations;
public PackagingItemValidityState(List<DestinationInfo> destinationInfos) {
myDestinations = new SmartList<Pair<String, Long>>();
for (DestinationInfo info : destinationInfos) {
final VirtualFile outputFile = info.getOutputFile();
long timestamp = outputFile != null ? outputFile.getTimeStamp() : -1;
myDestinations.add(Pair.create(info.getOutputPath(), timestamp));
}
}
public PackagingItemValidityState(DataInput input) throws IOException {
int size = input.readInt();
myDestinations = new SmartList<Pair<String, Long>>();
while (size-- > 0) {
String path = IOUtil.readString(input);
long timestamp = input.readLong();
myDestinations.add(Pair.create(path, timestamp));
}
}
public boolean equalsTo(final ValidityState otherState) {
if (!(otherState instanceof PackagingItemValidityState)) {
return false;
}
final SmartList<Pair<String, Long>> otherDestinations = ((PackagingItemValidityState)otherState).myDestinations;
if (otherDestinations.size() != myDestinations.size()) {
return false;
}
if (myDestinations.size() == 1) {
return myDestinations.get(0).equals(otherDestinations.get(0));
}
return Comparing.haveEqualElements(myDestinations, otherDestinations);
}
public void save(final DataOutput output) throws IOException {
output.writeInt(myDestinations.size());
for (Pair<String, Long> pair : myDestinations) {
IOUtil.writeString(pair.getFirst(), output);
output.writeLong(pair.getSecond());
}
}
}
@@ -1,56 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.FileProcessingCompiler;
import com.intellij.openapi.compiler.ValidityState;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.ArrayList;
/**
* @author nik
*/
public class PackagingProcessingItem implements FileProcessingCompiler.ProcessingItem {
private final VirtualFile mySourceFile;
private final List<DestinationInfo> myDestinations = new ArrayList<DestinationInfo>();
public PackagingProcessingItem(final VirtualFile sourceFile) {
mySourceFile = sourceFile;
}
@NotNull
public VirtualFile getFile() {
return mySourceFile;
}
public void addDestination(DestinationInfo info) {
myDestinations.add(info);
}
public List<DestinationInfo> getDestinations() {
return myDestinations;
}
@Nullable
public ValidityState getValidityState() {
return new PackagingItemValidityState(myDestinations);
}
}
@@ -1,288 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.impl.packagingCompiler;
import com.intellij.openapi.compiler.make.*;
import com.intellij.openapi.deployment.DeploymentUtil;
import com.intellij.openapi.deployment.DeploymentUtilImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import com.intellij.util.text.FilePathHashingStrategy;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.jar.JarFile;
/**
* @author nik
*/
public class ProcessingItemsBuilder extends BuildInstructionVisitor {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.packagingCompiler.ProcessingItemsBuilder");
private final Stack<String> myOutputPaths;
private Stack<NestedJarInfo> myNestedJars;
private final BuildConfiguration myBuildConfiguration;
private final OldProcessingItemsBuilderContext myContext;
private final BuildParticipant myBuildParticipant;
private final LocalFileSystem myLocalFileSystem;
public ProcessingItemsBuilder(final BuildParticipant buildParticipant, OldProcessingItemsBuilderContext context) {
myContext = context;
myBuildParticipant = buildParticipant;
myBuildConfiguration = myBuildParticipant.getBuildConfiguration();
myOutputPaths = new Stack<String>();
myOutputPaths.push("");
myLocalFileSystem = LocalFileSystem.getInstance();
final String jarPath = myBuildConfiguration.getJarPath();
if (myBuildConfiguration.isJarEnabled() && jarPath != null) {
myNestedJars = new Stack<NestedJarInfo>();
final DestinationInfo destinationInfo = createExplodedDestination(jarPath);
myNestedJars.push(myContext.createNestedJarInfo(destinationInfo, myBuildConfiguration, myBuildParticipant.getBuildInstructions(
myContext.getCompileContext())));
}
}
private ExplodedDestinationInfo createExplodedDestination(final String path) {
VirtualFile file = myLocalFileSystem.findFileByPath(path);
return createExplodedDestination(path, file);
}
private ExplodedDestinationInfo createExplodedDestination(final String path, final VirtualFile file) {
ExplodedDestinationInfo destinationInfo = new ExplodedDestinationInfo(path, file);
myContext.registerDestination(myBuildParticipant, destinationInfo);
return destinationInfo;
}
public void build() {
buildItems(myBuildParticipant.getBuildInstructions(myContext.getCompileContext()));
}
private void buildItems(final BuildRecipe instructions) {
instructions.visitInstructions(this, false);
if (myBuildParticipant.willBuildExploded()) {
List<String> classpath = DeploymentUtilImpl.getExternalDependenciesClasspath(instructions);
if (!classpath.isEmpty()) {
String outputRoot = DeploymentUtilImpl.getOrCreateExplodedDir(myBuildParticipant);
String fullOutputPath = getCanonicalConcat(outputRoot, myOutputPaths.peek(), JarFile.MANIFEST_NAME);
myContext.addManifestFile(new ManifestFileInfo(fullOutputPath, classpath));
}
}
}
private static String getCanonicalConcat(final String... paths) {
final String fullOutputPath = DeploymentUtil.concatPaths(paths);
String path = PathUtil.getCanonicalPath(fullOutputPath);
if (path == null) {
LOG.error("invalid path: " + Arrays.toString(paths));
}
return path;
}
public boolean visitFileCopyInstruction(final FileCopyInstruction instruction) throws Exception {
final String output = myOutputPaths.peek();
final VirtualFile sourceFile = myLocalFileSystem.findFileByIoFile(instruction.getFile());
if (sourceFile == null) return true;
PackagingFileFilter fileFilter = instruction.getFileFilter();
String outputRelativePath = instruction.getOutputRelativePath();
if (myBuildParticipant.willBuildExploded()) {
String outputRoot = DeploymentUtilImpl.getOrCreateExplodedDir(myBuildParticipant);
String fullOutputPath = getCanonicalConcat(outputRoot, output, outputRelativePath);
checkRecursiveCopying(sourceFile, fullOutputPath);
addItemsToExplodedRecursively(sourceFile, fullOutputPath, fileFilter);
}
if (myNestedJars != null) {
NestedJarInfo nestedJar = getNestedJar(myNestedJars, instruction.isExternalDependencyInstruction());
if (nestedJar != null) {
checkRecursiveCopying(sourceFile, nestedJar.myDestination.getOutputFilePath());
addItemsToJarRecursively(sourceFile, DeploymentUtil.trimForwardSlashes(trimParentPrefix(outputRelativePath)),
nestedJar.myDestination, nestedJar.myJarInfo, nestedJar.myAddJarContent, fileFilter);
}
else {
String fullOutputPath = getCanonicalConcat(myBuildConfiguration.getJarPath(), outputRelativePath);
checkRecursiveCopying(sourceFile, fullOutputPath);
addItemsToExplodedRecursively(sourceFile, fullOutputPath, fileFilter);
}
}
return true;
}
private void checkRecursiveCopying(@NotNull final VirtualFile sourceFile, @NotNull final String outputPath) {
File fromFile = VfsUtil.virtualToIoFile(sourceFile);
File toFile = new File(FileUtil.toSystemDependentName(outputPath));
try {
if (FileUtil.isAncestor(fromFile, toFile, true)) {
DeploymentUtil.reportRecursiveCopying(myContext.getCompileContext(), fromFile.getAbsolutePath(), toFile.getAbsolutePath(), "", "");
}
}
catch (IOException ignored) {
}
}
private static String trimParentPrefix(String outputRelativePath) {
if (outputRelativePath.startsWith("..")) {
return outputRelativePath.substring(2);
}
return outputRelativePath;
}
@Nullable
private static NestedJarInfo getNestedJar(@NotNull final Stack<NestedJarInfo> nestedJarInfos,
final boolean externalDependencyInstruction) {
if (!externalDependencyInstruction) {
return nestedJarInfos.peek();
}
if (nestedJarInfos.size() > 1) {
return nestedJarInfos.get(nestedJarInfos.size() - 2);
}
return null;
}
private void addItemsToExplodedRecursively(final VirtualFile sourceFile, final String fullOutputPath, @Nullable PackagingFileFilter fileFilter) {
VirtualFile outputFile = myLocalFileSystem.findFileByPath(fullOutputPath);
addItemsToExplodedRecursively(sourceFile, fullOutputPath, outputFile, fileFilter);
}
public boolean visitJarAndCopyBuildInstruction(final JarAndCopyBuildInstruction instruction) throws Exception {
final VirtualFile sourceFile = myLocalFileSystem.findFileByIoFile(instruction.getFile());
if (sourceFile == null) return true;
PackagingFileFilter fileFilter = instruction.getFileFilter();
if (myBuildParticipant.willBuildExploded()) {
String outputRoot = DeploymentUtilImpl.getOrCreateExplodedDir(myBuildParticipant);
String jarPath = getCanonicalConcat(outputRoot, myOutputPaths.peek(), instruction.getOutputRelativePath());
checkRecursiveCopying(sourceFile, jarPath);
addItemsToJar(sourceFile, createExplodedDestination(jarPath), fileFilter);
}
if (myNestedJars != null) {
final NestedJarInfo nestedJar = getNestedJar(myNestedJars, instruction.isExternalDependencyInstruction());
if (nestedJar != null) {
final String outputRelativePath = trimParentPrefix(instruction.getOutputRelativePath());
JarDestinationInfo destination = new JarDestinationInfo(outputRelativePath, nestedJar.myJarInfo, nestedJar.myDestination);
checkRecursiveCopying(sourceFile, destination.getOutputFilePath());
addItemsToJar(sourceFile, destination, fileFilter);
}
else {
String jarPath = getCanonicalConcat(myBuildConfiguration.getJarPath(), instruction.getOutputRelativePath());
checkRecursiveCopying(sourceFile, jarPath);
addItemsToJar(sourceFile, createExplodedDestination(jarPath), fileFilter);
}
}
return true;
}
private void addItemsToJar(final VirtualFile sourceFile, final DestinationInfo destination, @Nullable final PackagingFileFilter fileFilter) {
JarInfo jarInfo = myContext.getCachedJar(sourceFile);
boolean addToJarInfo = jarInfo == null;
if (jarInfo == null) {
jarInfo = new JarInfo();
myContext.putCachedJar(sourceFile, jarInfo);
}
jarInfo.addDestination(destination);
if (destination instanceof ExplodedDestinationInfo) {
myContext.registerJarFile(jarInfo, destination.getOutputFilePath());
}
addItemsToJarRecursively(sourceFile, "", destination, jarInfo, addToJarInfo, fileFilter);
}
private void addItemsToJarRecursively(final VirtualFile sourceFile, String pathInJar, DestinationInfo jarDestination,
final JarInfo jarInfo, boolean addToJarContent, @Nullable PackagingFileFilter fileFilter) {
if (fileFilter != null && !fileFilter.accept(sourceFile, myContext.getCompileContext())) {
return;
}
if (sourceFile.isDirectory()) {
final VirtualFile[] children = sourceFile.getChildren();
for (VirtualFile child : children) {
String childPath = DeploymentUtil.trimForwardSlashes(DeploymentUtil.appendToPath(pathInJar, child.getName()));
addItemsToJarRecursively(child, childPath, jarDestination, jarInfo, addToJarContent, fileFilter);
}
}
else {
String fullOutputPath = DeploymentUtil.appendToPath(jarDestination.getOutputPath(), pathInJar);
if (myContext.checkOutputPath(fullOutputPath, sourceFile)) {
final PackagingProcessingItem item = myContext.getOrCreateProcessingItem(sourceFile, myBuildParticipant);
item.addDestination(new JarDestinationInfo(pathInJar, jarInfo, jarDestination));
if (addToJarContent) {
jarInfo.addContent(pathInJar, sourceFile);
}
}
}
}
private void addItemsToExplodedRecursively(final VirtualFile sourceFile, final String outputPath, @Nullable final VirtualFile outputFile,
@Nullable PackagingFileFilter fileFilter) {
if (fileFilter != null && !fileFilter.accept(sourceFile, myContext.getCompileContext())) {
return;
}
if (sourceFile.isDirectory()) {
final VirtualFile[] children = sourceFile.getChildren();
THashMap<String, VirtualFile> outputChildren = null;
if (outputFile != null) {
outputChildren = new THashMap<String, VirtualFile>(FilePathHashingStrategy.create());
VirtualFile[] files = outputFile.getChildren();
if (files != null) {
for (VirtualFile file : files) {
outputChildren.put(file.getName(), file);
}
}
}
for (VirtualFile child : children) {
final VirtualFile outputChild = outputChildren != null ? outputChildren.get(child.getName()) : null;
addItemsToExplodedRecursively(child, DeploymentUtil.appendToPath(outputPath, child.getName()), outputChild, fileFilter);
}
}
else if (myContext.checkOutputPath(outputPath, sourceFile)) {
PackagingProcessingItem item = myContext.getOrCreateProcessingItem(sourceFile, myBuildParticipant);
item.addDestination(createExplodedDestination(outputPath, outputFile));
}
}
public static class NestedJarInfo {
private final JarInfo myJarInfo;
private final DestinationInfo myDestination;
private final boolean myAddJarContent;
public NestedJarInfo(final JarInfo jarInfo, final DestinationInfo destination, final boolean addJarContent) {
myJarInfo = jarInfo;
myDestination = destination;
myAddJarContent = addJarContent;
}
}
}
@@ -31,24 +31,16 @@ import java.util.*;
public abstract class ProcessingItemsBuilderContext<Item extends FileProcessingCompiler.ProcessingItem> {
protected final Map<VirtualFile, Item> myItemsBySource;
private final Map<String, VirtualFile> mySourceByOutput;
private final Map<VirtualFile, JarInfo> myCachedJarForDir;
private final MultiValuesMap<String, JarInfo> myJarsByPath;
private final CompileContext myCompileContext;
private final List<ManifestFileInfo> myManifestFiles;
public ProcessingItemsBuilderContext(final CompileContext compileContext) {
myCompileContext = compileContext;
myManifestFiles = new ArrayList<ManifestFileInfo>();
myItemsBySource = new HashMap<VirtualFile, Item>();
mySourceByOutput = new HashMap<String, VirtualFile>();
myCachedJarForDir = new HashMap<VirtualFile, JarInfo>();
myJarsByPath = new MultiValuesMap<String, JarInfo>();
}
public List<ManifestFileInfo> getManifestFiles() {
return myManifestFiles;
}
public abstract Item[] getProcessingItems();
public boolean checkOutputPath(final String outputPath, final VirtualFile sourceFile) {
@@ -79,22 +71,10 @@ public abstract class ProcessingItemsBuilderContext<Item extends FileProcessingC
return mySourceByOutput.get(outputPath);
}
public JarInfo getCachedJar(final VirtualFile sourceFile) {
return myCachedJarForDir.get(sourceFile);
}
public void putCachedJar(final VirtualFile sourceFile, final JarInfo jarInfo) {
myCachedJarForDir.put(sourceFile, jarInfo);
}
public CompileContext getCompileContext() {
return myCompileContext;
}
public void addManifestFile(final ManifestFileInfo manifestFileInfo) {
myManifestFiles.add(manifestFileInfo);
}
public Item getOrCreateProcessingItem(VirtualFile sourceFile) {
Item item = myItemsBySource.get(sourceFile);
if (item == null) {
@@ -1,40 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.make;
import com.intellij.compiler.ant.Tag;
import com.intellij.compiler.ant.ExplodedAndJarTargetParameters;
import com.intellij.compiler.ant.taskdefs.ZipFileSet;
import com.intellij.openapi.compiler.make.BuildInstruction;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public abstract class ExplodedAndJarBuildGenerator {
public static final ExtensionPointName<ExplodedAndJarBuildGenerator> EP_NAME = ExtensionPointName.create("com.intellij.explodedAndJarBuildGenerator");
@Nullable
public Tag[] generateTagsForExplodedTarget(@NotNull BuildInstruction instruction, @NotNull ExplodedAndJarTargetParameters parameters,
final int instructionCount)
throws Exception {
return null;
}
}
@@ -16,169 +16,32 @@
package com.intellij.openapi.deployment;
import com.intellij.compiler.impl.packagingCompiler.BuildRecipeImpl;
import com.intellij.compiler.impl.packagingCompiler.JarAndCopyBuildInstructionImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.compiler.make.*;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.PathUtil;
import com.intellij.util.descriptors.ConfigFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.*;
import java.util.jar.Attributes;
import java.util.Set;
/**
* @author Alexey Kudravtsev
*/
public class DeploymentUtilImpl extends DeploymentUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.deployment.MakeUtilImpl");
@NonNls private static final String JAR_SUFFIX = ".jar";
public boolean addModuleOutputContents(@NotNull CompileContext context,
@NotNull BuildRecipe items,
@NotNull final Module sourceModule,
Module targetModule,
final String outputRelativePath,
@Nullable String possibleBaseOuputPath,
@Nullable PackagingFileFilter fileFilter) {
final File outputPath = getModuleOutputPath(sourceModule);
String[] sourceRoots = getSourceRootUrlsInReadAction(sourceModule);
boolean ok = true;
if (outputPath != null && sourceRoots.length != 0) {
ok = outputPath.exists();
boolean added = addItemsRecursively(items, outputPath, targetModule, outputRelativePath, fileFilter, possibleBaseOuputPath);
if (!added) {
LOG.assertTrue(possibleBaseOuputPath != null);
String additionalMessage = CompilerBundle.message("message.text.change.module.output.directory.or.module.exploded.directory",
ModuleUtil.getModuleNameInReadAction(sourceModule),
ModuleUtil.getModuleNameInReadAction(targetModule));
reportRecursiveCopying(context, outputPath.getPath(), appendToPath(possibleBaseOuputPath, outputRelativePath),
CompilerBundle.message("module.output.directory", ModuleUtil.getModuleNameInReadAction(sourceModule)),
additionalMessage);
ok = false;
}
}
return ok;
}
private static String[] getSourceRootUrlsInReadAction(final Module module) {
return ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
public String[] compute() {
return ModuleRootManager.getInstance(module).getSourceRootUrls();
}
});
}
private static File getModuleOutputPath(final Module module) {
return ApplicationManager.getApplication().runReadAction(new Computable<File>() {
@Nullable
public File compute() {
final String url = CompilerModuleExtension.getInstance(module).getCompilerOutputUrl();
if (url == null) return null;
return new File(PathUtil.toPresentableUrl(url));
}
});
}
public void addLibraryLink(@NotNull final CompileContext context,
@NotNull final BuildRecipe items,
@NotNull final LibraryLink libraryLink,
@NotNull final Module module,
@Nullable final String possibleBaseOutputPath) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
String outputRelativePath;
final PackagingMethod packagingMethod = libraryLink.getPackagingMethod();
if (packagingMethod.equals(PackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST)
|| packagingMethod.equals(PackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST)) {
outputRelativePath = getRelativePathForManifestLinking(libraryLink.getURI());
}
else {
outputRelativePath = libraryLink.getURI();
}
final List<String> urls = libraryLink.getClassesRootUrls();
boolean isDestinationDirectory = true;
if (LibraryLink.MODULE_LEVEL.equals(libraryLink.getLevel()) && urls.size() == 1 && outputRelativePath.endsWith(JAR_SUFFIX)) {
isDestinationDirectory = false;
}
for (String url : urls) {
final String path = PathUtil.toPresentableUrl(url);
final File file = new File(path);
boolean packagingMethodIsCopy = packagingMethod.equals(PackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST) ||
packagingMethod.equals(PackagingMethod.COPY_FILES);
String fileDestination = outputRelativePath;
if (isDestinationDirectory) {
if (file.isDirectory()) {
if (!packagingMethodIsCopy) {
fileDestination = appendToPath(fileDestination, file.getName() + JAR_SUFFIX);
}
}
else {
fileDestination = appendToPath(fileDestination, file.getName());
}
}
if (file.isDirectory()) {
boolean ok;
if (packagingMethodIsCopy) {
ok = addItemsRecursively(items, file, module, fileDestination, null, possibleBaseOutputPath);
}
else {
fixPackagingMethod(packagingMethod, libraryLink, context);
BuildInstruction instruction = new JarAndCopyBuildInstructionImpl(module, file, fileDestination);
items.addInstruction(instruction);
ok = true;
}
if (!ok) {
final String name = libraryLink.getPresentableName();
String additionalMessage = CompilerBundle.message("message.text.adjust.library.path");
reportRecursiveCopying(context, file.getPath(), fileDestination,
CompilerBundle.message("directory.description.library.directory", name), additionalMessage);
}
}
else {
items.addFileCopyInstruction(file, false, module, fileDestination, null);
}
}
}
});
}
private static void fixPackagingMethod(final PackagingMethod packagingMethod, final LibraryLink libraryLink, final CompileContext context) {
if (!packagingMethod.equals(PackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST) &&
!packagingMethod.equals(PackagingMethod.JAR_AND_COPY_FILE)) {
libraryLink.setPackagingMethod(PackagingMethod.JAR_AND_COPY_FILE);
String message = CompilerBundle.message("message.text.packaging.method.for.library.reset", libraryLink.getPresentableName(),
PackagingMethod.JAR_AND_COPY_FILE);
context.addMessage(CompilerMessageCategory.WARNING, message, null, -1, -1);
}
}
public void copyFile(@NotNull final File fromFile,
@NotNull final File toFile,
@@ -251,7 +114,6 @@ public class DeploymentUtilImpl extends DeploymentUtil {
@NotNull File root,
Module module,
String outputRelativePath,
@Nullable PackagingFileFilter fileFilter,
@Nullable String possibleBaseOutputPath) {
if (outputRelativePath == null) outputRelativePath = "";
outputRelativePath = trimForwardSlashes(outputRelativePath);
@@ -264,7 +126,7 @@ public class DeploymentUtilImpl extends DeploymentUtil {
}
}
items.addFileCopyInstruction(root, true, module, outputRelativePath, fileFilter);
items.addFileCopyInstruction(root, true, outputRelativePath);
return true;
}
@@ -276,12 +138,6 @@ public class DeploymentUtilImpl extends DeploymentUtil {
context.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
}
public static String getRelativePathForManifestLinking(String relativePath) {
if (!StringUtil.startsWithChar(relativePath, '/')) relativePath = '/' + relativePath;
relativePath = ".." + relativePath;
return relativePath;
}
public void checkConfigFile(final ConfigFile descriptor, final CompileContext compileContext, final Module module) {
if (new File(VfsUtil.urlToPath(descriptor.getUrl())).exists()) {
String message = getConfigFileErrorMessage(descriptor);
@@ -297,128 +153,6 @@ public class DeploymentUtilImpl extends DeploymentUtil {
}
}
public static void setManifestAttributes(final Attributes mainAttributes, final @Nullable List<String> classpathElements) {
if (classpathElements != null && classpathElements.size() > 0) {
StringBuilder builder;
Set<String> existingPaths = new HashSet<String>();
String oldClassPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
if (oldClassPath != null) {
StringTokenizer tokenizer = new StringTokenizer(oldClassPath);
while (tokenizer.hasMoreTokens()) {
existingPaths.add(tokenizer.nextToken());
}
builder = new StringBuilder(oldClassPath);
}
else {
builder = new StringBuilder();
}
for (String path : classpathElements) {
if (!existingPaths.contains(path)) {
if (builder.length() > 0) {
builder.append(' ');
}
builder.append(path);
}
}
mainAttributes.put(Attributes.Name.CLASS_PATH, builder.toString());
}
ManifestBuilder.setGlobalAttributes(mainAttributes);
}
public static List<String> getExternalDependenciesClasspath(final BuildRecipe buildRecipe) {
final List<String> classpath = new ArrayList<String>();
buildRecipe.visitInstructions(new BuildInstructionVisitor() {
public boolean visitInstruction(BuildInstruction instruction) throws RuntimeException {
final String outputRelativePath = instruction.getOutputRelativePath();
if (instruction.isExternalDependencyInstruction()) {
final String jarReference = PathUtil.getCanonicalPath("/tmp/" + outputRelativePath).substring(1);
classpath.add(trimForwardSlashes(jarReference));
}
return true;
}
}, false);
return classpath;
}
public void addJavaModuleOutputs(@NotNull final Module module,
@NotNull ModuleLink[] containingModules,
@NotNull BuildRecipe instructions,
@NotNull CompileContext context,
String explodedPath, final String linkContainerDescription) {
addJavaModuleOutputs(module, containingModules, instructions, context, explodedPath, linkContainerDescription, null);
}
public void addJavaModuleOutputs(@NotNull final Module module,
@NotNull ModuleLink[] containingModules,
@NotNull BuildRecipe instructions,
@NotNull CompileContext context,
@Nullable String possibleExplodedPath, final String linkContainerDescription, @Nullable Map<Module, PackagingFileFilter> fileFilters) {
for (ModuleLink moduleLink : containingModules) {
Module childModule = moduleLink.getModule();
if (childModule != null) {
final PackagingMethod packagingMethod = moduleLink.getPackagingMethod();
if (PackagingMethod.DO_NOT_PACKAGE.equals(packagingMethod)) {
continue;
}
PackagingFileFilter fileFilter = fileFilters != null ? fileFilters.get(childModule) : null;
if (PackagingMethod.JAR_AND_COPY_FILE.equals(packagingMethod)) {
addJarJavaModuleOutput(instructions, childModule, moduleLink.getURI(), context, linkContainerDescription, fileFilter);
}
else if (PackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST.equals(packagingMethod)) {
String relativePath = getRelativePathForManifestLinking(moduleLink.getURI());
addJarJavaModuleOutput(instructions, childModule, relativePath, context, linkContainerDescription, fileFilter);
}
else if (PackagingMethod.COPY_FILES.equals(packagingMethod)) {
addModuleOutputContents(context, instructions, childModule, module, moduleLink.getURI(), possibleExplodedPath, fileFilter);
}
else if (PackagingMethod.COPY_FILES_AND_LINK_VIA_MANIFEST.equals(packagingMethod)) {
moduleLink.setPackagingMethod(PackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST);
String relativePath = getRelativePathForManifestLinking(moduleLink.getURI());
addJarJavaModuleOutput(instructions, childModule, relativePath, context, linkContainerDescription, fileFilter);
context.addMessage(CompilerMessageCategory.WARNING,
CompilerBundle.message("message.text.packaging.method.for.module.reset.to.method",
ModuleUtil.getModuleNameInReadAction(childModule),
PackagingMethod.JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST),
null, -1, -1);
}
else {
LOG.info("invalid packaging method " + packagingMethod + " for module '" + ModuleUtil.getModuleNameInReadAction(childModule)
+ "' in module '" + ModuleUtil.getModuleNameInReadAction(module) + "'");
}
}
}
}
private static void addJarJavaModuleOutput(BuildRecipe instructions,
Module module,
String relativePath,
CompileContext context, final String linkContainerDescription, @Nullable PackagingFileFilter fileFilter) {
final String[] sourceUrls = getSourceRootUrlsInReadAction(module);
if (sourceUrls.length > 0) {
final File outputPath = getModuleOutputPath(module);
if (outputPath != null) {
if ("/".equals(relativePath) || "".equals(relativePath) || getRelativePathForManifestLinking("/").equals(relativePath)) {
context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("message.text.invalid.output.path.for.module.jar", relativePath, module.getName(), linkContainerDescription), null, -1, -1);
}
else {
instructions.addInstruction(new JarAndCopyBuildInstructionImpl(module, outputPath, relativePath, fileFilter));
}
}
}
}
public ModuleLink createModuleLink(@NotNull Module dep, @NotNull Module module) {
return new ModuleLinkImpl(dep, module);
}
public LibraryLink createLibraryLink(Library library, @NotNull Module parentModule) {
return new LibraryLinkImpl(library, parentModule);
}
public BuildRecipe createBuildRecipe() {
return new BuildRecipeImpl();
}
@@ -443,16 +177,4 @@ public class DeploymentUtilImpl extends DeploymentUtil {
return null;
}
@Nullable
public static String getOrCreateExplodedDir(final BuildParticipant buildParticipant) {
BuildConfiguration buildConfiguration = buildParticipant.getBuildConfiguration();
if (buildConfiguration.isExplodedEnabled()) {
return buildConfiguration.getExplodedPath();
}
return buildParticipant.getOrCreateTemporaryDirForExploded();
}
public static BuildParticipantProvider[] getBuildParticipantProviders() {
return Extensions.getExtensions(BuildParticipantProvider.EXTENSION_POINT_NAME);
}
}
@@ -1,37 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.util.InvalidDataException;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author nik
*/
interface LibraryInfo {
String getName();
@NotNull
List<String> getUrls();
String getLevel();
void readExternal(Element element) throws InvalidDataException;
}
@@ -1,68 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.util.InvalidDataException;
import org.jetbrains.annotations.NotNull;
import org.jdom.Element;
import java.util.List;
import java.util.Arrays;
/**
* @author nik
*/
class LibraryInfoBasedOnLibrary implements LibraryInfo {
private final Library myLibrary;
private final LibraryInfoImpl myInfoToRestore;
public LibraryInfoBasedOnLibrary(@NotNull Library library) {
assert !(library instanceof LibraryEx) || !((LibraryEx)library).isDisposed();
myLibrary = library;
myInfoToRestore = new LibraryInfoImpl(library);
}
public String getName() {
return myLibrary.getName();
}
@NotNull
public List<String> getUrls() {
return Arrays.asList(myLibrary.getUrls(OrderRootType.CLASSES));
}
public String getLevel() {
final LibraryTable table = myLibrary.getTable();
return table == null ? LibraryLink.MODULE_LEVEL : table.getTableLevel();
}
@NotNull
public Library getLibrary() {
return myLibrary;
}
public void readExternal(Element element) throws InvalidDataException {
}
public LibraryInfoImpl getInfoToRestore() {
return myInfoToRestore;
}
}
@@ -1,85 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.InvalidDataException;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author nik
*/
class LibraryInfoImpl implements LibraryInfo {
private final List<String> myUrls = new ArrayList<String>();
private String myName;
private String myLevel;
LibraryInfoImpl() {
}
LibraryInfoImpl(@NotNull Library library) {
myName = library.getName();
LibraryTable table = library.getTable();
myLevel = table == null ? LibraryLink.MODULE_LEVEL : table.getTableLevel();
myUrls.addAll(Arrays.asList(library.getUrls(OrderRootType.CLASSES)));
}
public String getName() {
return myName;
}
@NotNull
public List<String> getUrls() {
return myUrls;
}
public String getLevel() {
return myLevel;
}
@Nullable
public Library findLibrary(final Project project, final Module module, final @Nullable ModulesProvider provider) {
if (LibraryLink.MODULE_LEVEL.equals(myLevel)) {
String url = myUrls.size() == 1 ? myUrls.get(0) : null;
return module == null? null : LibraryLinkUtil.findModuleLibrary(module, provider, myName, url);
}
return LibraryLink.findLibrary(myName, myLevel, project);
}
public void readExternal(Element element) throws InvalidDataException {
myName = element.getAttributeValue(LibraryLinkImpl.NAME_ATTRIBUTE_NAME);
myLevel = element.getAttributeValue(LibraryLinkImpl.LEVEL_ATTRIBUTE_NAME);
myUrls.clear();
final List urls = element.getChildren(LibraryLinkImpl.URL_ELEMENT_NAME);
for (Object url1 : urls) {
Element url = (Element)url1;
myUrls.add(url.getText());
}
}
}
@@ -1,252 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.PathUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class LibraryLinkImpl extends LibraryLink {
@NonNls public static final String LEVEL_ATTRIBUTE_NAME = "level";
@NonNls public static final String URL_ELEMENT_NAME = "url";
@NonNls private static final String TEMP_ELEMENT_NAME = "temp";
@NonNls public static final String NAME_ATTRIBUTE_NAME = "name";
@NonNls private static final String JAR_SUFFIX = ".jar";
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.deployment.LibraryLink");
private LibraryInfo myLibraryInfo;
private final Project myProject;
public LibraryLinkImpl(@Nullable Library library, @NotNull Module parentModule) {
super(parentModule);
myProject = parentModule.getProject();
if (library == null) {
myLibraryInfo = new LibraryInfoImpl();
}
else {
myLibraryInfo = new LibraryInfoBasedOnLibrary(library);
}
}
public List<String> getClassesRootUrls() {
List<String> urls = getUrls();
Library library = getLibrary();
if (library == null) {
return urls;
}
return getLibraryClassRoots(library);
}
public static List<String> getLibraryClassRoots(final Library library) {
VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
ArrayList<String> classRoots = new ArrayList<String>(files.length);
for (VirtualFile file : files) {
classRoots.add(file.getUrl());
}
return classRoots;
}
@Nullable
public Library getLibrary() {
return getLibrary(null);
}
@Nullable
public Library getLibrary(@Nullable ModulesProvider provider) {
fixLibraryInfo();
final LibraryInfo libraryInfo = myLibraryInfo;
if (libraryInfo instanceof LibraryInfoBasedOnLibrary) {
return ((LibraryInfoBasedOnLibrary)libraryInfo).getLibrary();
}
LOG.assertTrue(libraryInfo instanceof LibraryInfoImpl);
final LibraryInfoImpl info = (LibraryInfoImpl)libraryInfo;
final Library library = info.findLibrary(myProject, getParentModule(), provider);
if (library != null) {
myLibraryInfo = new LibraryInfoBasedOnLibrary(library);
}
return library;
}
public String toString() {
return CompilerBundle.message("library.link.string.presentation.presentablename.to.uri", getPresentableName(), getURI());
}
public String getPresentableName() {
final String name = getName();
if (name != null) return name;
List<String> urls = getUrls();
if (urls.isEmpty()) return CompilerBundle.message("linrary.link.empty.library.presentable.name");
final String url = urls.get(0);
final String path = PathUtil.toPresentableUrl(url);
return FileUtil.toSystemDependentName(path);
}
public List<String> getUrls() {
fixLibraryInfo();
return myLibraryInfo.getUrls();
}
public boolean equalsIgnoreAttributes(ContainerElement otherElement) {
if (!(otherElement instanceof LibraryLink)) return false;
final LibraryLink otherLibraryLink = (LibraryLink)otherElement;
if (!Comparing.strEqual(getName(), otherLibraryLink.getName())) return false;
if (!Comparing.strEqual(getLevel(), otherLibraryLink.getLevel())) return false;
if (getName() != null) return true;
return getUrls().equals(otherLibraryLink.getUrls());
}
public boolean hasDirectoriesOnly() {
boolean hasDirsOnly = true;
final Library library = getLibrary();
if (library != null) {
final VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
for (VirtualFile file : files) {
if (file != null && !VfsUtil.virtualToIoFile(file).isDirectory()) {
hasDirsOnly = false;
break;
}
}
} else {
final List<String> urls = getClassesRootUrls();
for (final String url : urls) {
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null && !VfsUtil.virtualToIoFile(file).isDirectory()) {
hasDirsOnly = false;
break;
}
}
}
return hasDirsOnly;
}
public String getName() {
return myLibraryInfo.getName();
}
public String getLevel() {
return myLibraryInfo.getLevel();
}
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
myLibraryInfo.readExternal(element);
List<String> urls = getUrls();
if (LibraryLink.MODULE_LEVEL.equals(getLevel()) && urls.size() == 1) {
String jarName = getJarFileName(urls.get(0));
if (jarName != null) {
String outputPath = getURI();
if (outputPath != null) {
int nameIndex = outputPath.lastIndexOf('/');
if (outputPath.substring(nameIndex + 1).equals(jarName)) {
if (nameIndex <= 0) {
setURI("/");
}
else {
setURI(outputPath.substring(0, nameIndex));
}
}
}
}
}
}
@Nullable
private static String getJarFileName(final String url) {
if (!url.endsWith(JarFileSystem.JAR_SEPARATOR)) return null;
String path = url.substring(0, url.length() - JarFileSystem.JAR_SEPARATOR.length());
String jarName = path.substring(path.lastIndexOf('/') + 1);
return jarName.endsWith(JAR_SUFFIX) ? jarName : null;
}
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
String name = getName();
if (name == null) {
List<String> urls = getUrls();
for (final String url : urls) {
final Element urlElement = new Element(URL_ELEMENT_NAME);
urlElement.setText(url);
element.addContent(urlElement);
}
}
else {
element.setAttribute(NAME_ATTRIBUTE_NAME, name);
}
if (getLevel() != null) {
element.setAttribute(LEVEL_ATTRIBUTE_NAME, getLevel());
}
}
public boolean resolveElement(ModulesProvider provider, final FacetsProvider facetsProvider) {
return getLibrary(provider) != null;
}
public LibraryLink clone() {
LibraryLink libraryLink = DeploymentUtil.getInstance().createLibraryLink(getLibrary(), getParentModule());
Element temp = new Element(TEMP_ELEMENT_NAME);
try {
writeExternal(temp);
libraryLink.readExternal(temp);
}
catch (Exception e) {
LOG.error(e);
}
return libraryLink;
}
public void fixLibraryInfo() {
if (myLibraryInfo instanceof LibraryInfoBasedOnLibrary) {
LibraryInfoBasedOnLibrary libraryInfo = (LibraryInfoBasedOnLibrary)myLibraryInfo;
Library library = libraryInfo.getLibrary();
if (((LibraryEx)library).isDisposed()) {
LibraryInfoImpl info = libraryInfo.getInfoToRestore();
Library newLibrary = info.findLibrary(myProject, getParentModule(), null);
myLibraryInfo = newLibrary != null ? new LibraryInfoBasedOnLibrary(newLibrary) : info;
}
}
}
}
@@ -1,80 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Comparing;
import java.util.HashSet;
import java.util.Set;
/**
* @author nik
*/
public class LibraryLinkUtil {
@Nullable
public static Library findModuleLibrary(Module module, @Nullable ModulesProvider provider, @Nullable String name, String url) {
if (url == null && name == null) return null;
if (provider == null) {
provider = new DefaultModulesProvider(module.getProject());
}
return findModuleLibrary(module, provider, url, name, new HashSet<Module>());
}
@Nullable
public static Library findModuleLibrary(Module module, final @NotNull ModulesProvider provider,
String url, @Nullable String name, Set<Module> visited) {
if (!visited.add(module)) {
return null;
}
ModuleRootModel rootModel = provider.getRootModel(module);
OrderEntry[] orderEntries = rootModel.getOrderEntries();
for (OrderEntry orderEntry : orderEntries) {
if (orderEntry instanceof ModuleOrderEntry) {
final Module dependency = ((ModuleOrderEntry)orderEntry).getModule();
if (dependency != null) {
final Library library = findModuleLibrary(dependency, provider, url, name, visited);
if (library != null) {
return library;
}
}
}
else if (orderEntry instanceof LibraryOrderEntry) {
LibraryOrderEntry libraryOrderEntry = ((LibraryOrderEntry)orderEntry);
Library library = libraryOrderEntry.getLibrary();
if (library == null) continue;
if (name != null && library.getTable()==null && name.equals(library.getName())) {
return library;
}
if (name == null) {
String[] urls = library.getUrls(OrderRootType.CLASSES);
if (urls.length == 1 && Comparing.strEqual(urls[0], url)) return library;
}
}
}
return null;
}
}
@@ -1,132 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ModuleLinkImpl extends ModuleLink {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.deployment.ModuleLink");
@NonNls public static final String NAME_ATTRIBUTE_NAME = "name";
@NonNls private static final String TEMP_ELEMENT_NAME = "temp";
private Module myModule;
private String myModuleName;
public ModuleLinkImpl(@NotNull Module module, @NotNull Module parentModule) {
super(parentModule);
myModule = module;
myModuleName = ModuleUtil.getModuleNameInReadAction(myModule);
}
public ModuleLinkImpl(String moduleName, @NotNull Module parentModule) {
super(parentModule);
myModuleName = moduleName;
}
private Module getModule(ModulesProvider provider) {
if (myModule != null && myModule.isDisposed()) {
myModule = null;
}
if (myModule == null) {
myModule = provider.getModule(myModuleName);
}
return myModule;
}
@Nullable
public Module getModule() {
if (myModule != null && myModule.isDisposed()) {
myModule = null;
}
if (myModule == null) {
myModule = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
public Module compute() {
return ModuleManager.getInstance(getParentModule().getProject()).findModuleByName(myModuleName);
}
});
}
return myModule;
}
public String toString() {
return CompilerBundle.message("module.link.string.representation", getName(), getURI());
}
public boolean equalsIgnoreAttributes(ContainerElement otherElement) {
return otherElement instanceof ModuleLink && Comparing.strEqual(((ModuleLink)otherElement).getName(), getName());
}
public String getPresentableName() {
return getName();
}
public boolean resolveElement(ModulesProvider provider, final FacetsProvider facetsProvider) {
return getModule(provider) != null;
}
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
myModuleName = element.getAttributeValue(NAME_ATTRIBUTE_NAME);
migratePackagingMethods();
}
private void migratePackagingMethods() {
if (getPackagingMethod() == PackagingMethod.COPY_CLASSES) {
setPackagingMethod(PackagingMethod.COPY_FILES);
}
}
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
element.setAttribute(NAME_ATTRIBUTE_NAME, getName());
}
public String getName() {
if (myModule == null) {
return myModuleName;
}
else {
return ModuleUtil.getModuleNameInReadAction(myModule);
}
}
public ModuleLink clone() {
ModuleLink moduleLink = new ModuleLinkImpl(getName(), getParentModule());
Element temp = new Element(TEMP_ELEMENT_NAME);
try {
writeExternal(temp);
moduleLink.readExternal(temp);
}
catch (Exception e) {
LOG.error(e);
}
return moduleLink;
}
}
@@ -66,13 +66,13 @@ import java.util.*;
* @author nik
*/
public class IncrementalArtifactsCompiler implements PackagingCompiler {
private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.IncrementalArtifactsCompiler");
private static final Key<List<String>> FILES_TO_DELETE_KEY = Key.create("artifacts_files_to_delete");
private static final Key<Set<Artifact>> AFFECTED_ARTIFACTS = Key.create("affected_artifacts");
private static final Key<ArtifactsProcessingItemsBuilderContext> BUILDER_CONTEXT_KEY = Key.create("artifacts_builder_context");
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.packagingCompiler.PackagingCompilerBase");
@Nullable private PackagingCompilerCache myOutputItemsCache;
protected static ArtifactPackagingProcessingItem[] collectItems(ArtifactsProcessingItemsBuilderContext builderContext, final Project project) {
private static ArtifactPackagingProcessingItem[] collectItems(ArtifactsProcessingItemsBuilderContext builderContext, final Project project) {
final CompileContext context = builderContext.getCompileContext();
final Set<Artifact> artifactsToBuild = ArtifactCompileScope.getArtifactsToBuild(project, context.getCompileScope());
@@ -103,19 +103,45 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
return builderContext.getProcessingItems();
}
protected static void onBuildFinished(ArtifactsProcessingItemsBuilderContext context)
throws Exception {
final CompileContext compileContext = context.getCompileContext();
final Set<Artifact> artifacts = getAffectedArtifacts(compileContext);
for (Artifact artifact : artifacts) {
for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
artifact.getProperties(provider).onBuildFinished(artifact, compileContext);
}
}
}
@NotNull
public ProcessingItem[] getProcessingItems(final CompileContext context) {
return new ReadAction<ProcessingItem[]>() {
protected void run(final Result<ProcessingItem[]> result) {
ArtifactsProcessingItemsBuilderContext builderContext = new ArtifactsProcessingItemsBuilderContext(context);
context.putUserData(BUILDER_CONTEXT_KEY, builderContext);
ArtifactPackagingProcessingItem[] allProcessingItems = collectItems(builderContext, context.getProject());
public static Set<Artifact> getAffectedArtifacts(final CompileContext compileContext) {
return compileContext.getUserData(AFFECTED_ARTIFACTS);
if (LOG.isDebugEnabled()) {
int num = Math.min(100, allProcessingItems.length);
LOG.debug("All files (" + num + " of " + allProcessingItems.length + "):");
for (int i = 0; i < num; i++) {
LOG.debug(allProcessingItems[i].getFile().getPath());
}
}
try {
final FileProcessingCompilerStateCache cache =
CompilerCacheManager.getInstance(context.getProject()).getFileProcessingCompilerCache(IncrementalArtifactsCompiler.this);
for (ArtifactPackagingProcessingItem item : allProcessingItems) {
item.init(cache);
}
}
catch (IOException e) {
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
result.setResult(ProcessingItem.EMPTY_ARRAY);
return;
}
boolean hasFilesToDelete = collectFilesToDelete(context, builderContext.getProcessingItems());
if (hasFilesToDelete) {
MockProcessingItem mockItem = new MockProcessingItem(new LightVirtualFile("239239293"));
result.setResult(ArrayUtil.append(allProcessingItems, mockItem, ProcessingItem.class));
}
else {
result.setResult(allProcessingItems);
}
}
}.execute().getResultObject();
}
private static void collectItems(@NotNull ArtifactsProcessingItemsBuilderContext builderContext,
@@ -125,79 +151,12 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
final CompositePackagingElement<?> rootElement = artifact.getRootElement();
final VirtualFile outputFile = LocalFileSystem.getInstance().findFileByPath(outputPath);
final CopyToDirectoryInstructionCreator instructionCreator =
new CopyToDirectoryInstructionCreator(builderContext, outputPath, outputFile);
new CopyToDirectoryInstructionCreator(builderContext, outputPath, outputFile);
final PackagingElementResolvingContext resolvingContext = ArtifactManager.getInstance(project).getResolvingContext();
builderContext.setCollectingEnabledItems(enable);
rootElement.computeIncrementalCompilerInstructions(instructionCreator, resolvingContext, builderContext, artifact.getArtifactType());
}
@NotNull
public String getDescription() {
return "Artifacts Packaging Compiler";
}
@NotNull
private PackagingCompilerCache getOutputItemsCache(final Project project) {
if (myOutputItemsCache == null) {
myOutputItemsCache = new PackagingCompilerCache(
CompilerPaths.getCompilerSystemDirectory(project).getPath() + File.separator + "incremental_artifacts_timestamp.dat");
}
return myOutputItemsCache;
}
public void processOutdatedItem(final CompileContext context, final String url, @Nullable final ValidityState state) {
}
protected boolean collectFilesToDelete(final CompileContext context, final ArtifactPackagingProcessingItem[] allProcessingItems) {
List<String> filesToDelete = new ArrayList<String>();
Set<String> outputPaths = createPathsHashSet();
for (ArtifactPackagingProcessingItem item : allProcessingItems) {
for (Pair<DestinationInfo, Boolean> destinationInfo : item.getDestinations()) {
String outputPath = getOutputPathWithJarSeparator(destinationInfo.getFirst());
outputPaths.add(outputPath);
}
}
final Iterator<String> pathIterator = getOutputItemsCache(context.getProject()).getUrlsIterator();
while (pathIterator.hasNext()) {
String path = pathIterator.next();
if (!outputPaths.contains(path)) {
filesToDelete.add(path);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Files to delete (" + filesToDelete.size() + "):");
for (String path : filesToDelete) {
LOG.debug(path);
}
}
if (filesToDelete.isEmpty()) {
return false;
}
context.putUserData(FILES_TO_DELETE_KEY, filesToDelete);
return true;
}
private static String getOutputPathWithJarSeparator(DestinationInfo destinationInfo) {
String outputPath = destinationInfo.getOutputFilePath();
if (destinationInfo instanceof JarDestinationInfo) {
final String fullOutputPath = destinationInfo.getOutputPath();
final String fileOutputPath = destinationInfo.getOutputFilePath();
if (fullOutputPath.startsWith(fileOutputPath)) {
outputPath += JarFileSystem.JAR_SEPARATOR + DeploymentUtil.trimForwardSlashes(fullOutputPath.substring(fileOutputPath.length()));
}
}
return outputPath;
}
private static THashSet<String> createPathsHashSet() {
return SystemInfo.isFileSystemCaseSensitive
? new THashSet<String>()
: new THashSet<String>(CaseInsensitiveStringHashingStrategy.INSTANCE);
}
public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
final Set<String> deletedJars = deleteOutdatedFiles(context);
@@ -226,28 +185,11 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
return processedItems.toArray(new ProcessingItem[processedItems.size()]);
}
private static void removeInvalidItems(List<ArtifactPackagingProcessingItem> processedItems) {
Set<VirtualFile> files = new THashSet<VirtualFile>(processedItems.size());
for (ArtifactPackagingProcessingItem item : processedItems) {
files.add(item.getFile());
}
RefreshQueue.getInstance().refresh(false, false, null, files.toArray(new VirtualFile[files.size()]));
final Iterator<ArtifactPackagingProcessingItem> iterator = processedItems.iterator();
while (iterator.hasNext()) {
ArtifactPackagingProcessingItem item = iterator.next();
final VirtualFile file = item.getFile();
if (!file.isValid()) {
iterator.remove();
}
}
}
private static boolean doBuild(final CompileContext context,
final ProcessingItem[] items,
final List<ArtifactPackagingProcessingItem> processedItems,
final Set<String> writtenPaths,
final Set<String> deletedJars) {
final ProcessingItem[] items,
final List<ArtifactPackagingProcessingItem> processedItems,
final Set<String> writtenPaths,
final Set<String> deletedJars) {
final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
if (LOG.isDebugEnabled()) {
@@ -347,6 +289,105 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
return true;
}
public static Set<Artifact> getAffectedArtifacts(final CompileContext compileContext) {
return compileContext.getUserData(AFFECTED_ARTIFACTS);
}
@NotNull
public String getDescription() {
return "Artifacts Packaging Compiler";
}
@NotNull
private PackagingCompilerCache getOutputItemsCache(final Project project) {
if (myOutputItemsCache == null) {
myOutputItemsCache = new PackagingCompilerCache(
CompilerPaths.getCompilerSystemDirectory(project).getPath() + File.separator + "incremental_artifacts_timestamp.dat");
}
return myOutputItemsCache;
}
public void processOutdatedItem(final CompileContext context, final String url, @Nullable final ValidityState state) {
}
protected boolean collectFilesToDelete(final CompileContext context, final ArtifactPackagingProcessingItem[] allProcessingItems) {
List<String> filesToDelete = new ArrayList<String>();
Set<String> outputPaths = createPathsHashSet();
for (ArtifactPackagingProcessingItem item : allProcessingItems) {
for (Pair<DestinationInfo, Boolean> destinationInfo : item.getDestinations()) {
String outputPath = getOutputPathWithJarSeparator(destinationInfo.getFirst());
outputPaths.add(outputPath);
}
}
final Iterator<String> pathIterator = getOutputItemsCache(context.getProject()).getUrlsIterator();
while (pathIterator.hasNext()) {
String path = pathIterator.next();
if (!outputPaths.contains(path)) {
filesToDelete.add(path);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Files to delete (" + filesToDelete.size() + "):");
for (String path : filesToDelete) {
LOG.debug(path);
}
}
if (filesToDelete.isEmpty()) {
return false;
}
context.putUserData(FILES_TO_DELETE_KEY, filesToDelete);
return true;
}
private static String getOutputPathWithJarSeparator(DestinationInfo destinationInfo) {
String outputPath = destinationInfo.getOutputFilePath();
if (destinationInfo instanceof JarDestinationInfo) {
final String fullOutputPath = destinationInfo.getOutputPath();
final String fileOutputPath = destinationInfo.getOutputFilePath();
if (fullOutputPath.startsWith(fileOutputPath)) {
outputPath += JarFileSystem.JAR_SEPARATOR + DeploymentUtil.trimForwardSlashes(fullOutputPath.substring(fileOutputPath.length()));
}
}
return outputPath;
}
protected static void onBuildFinished(ArtifactsProcessingItemsBuilderContext context)
throws Exception {
final CompileContext compileContext = context.getCompileContext();
final Set<Artifact> artifacts = getAffectedArtifacts(compileContext);
for (Artifact artifact : artifacts) {
for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
artifact.getProperties(provider).onBuildFinished(artifact, compileContext);
}
}
}
private static THashSet<String> createPathsHashSet() {
return SystemInfo.isFileSystemCaseSensitive
? new THashSet<String>()
: new THashSet<String>(CaseInsensitiveStringHashingStrategy.INSTANCE);
}
private static void removeInvalidItems(List<ArtifactPackagingProcessingItem> processedItems) {
Set<VirtualFile> files = new THashSet<VirtualFile>(processedItems.size());
for (ArtifactPackagingProcessingItem item : processedItems) {
files.add(item.getFile());
}
RefreshQueue.getInstance().refresh(false, false, null, files.toArray(new VirtualFile[files.size()]));
final Iterator<ArtifactPackagingProcessingItem> iterator = processedItems.iterator();
while (iterator.hasNext()) {
ArtifactPackagingProcessingItem item = iterator.next();
final VirtualFile file = item.getFile();
if (!file.isValid()) {
iterator.remove();
}
}
}
private static void processDestinations(final List<ArtifactPackagingProcessingItem> items) {
for (ArtifactPackagingProcessingItem item : items) {
item.setProcessed();
@@ -437,47 +478,6 @@ public class IncrementalArtifactsCompiler implements PackagingCompiler {
return true;
}
@NotNull
public ProcessingItem[] getProcessingItems(final CompileContext context) {
return new ReadAction<ProcessingItem[]>() {
protected void run(final Result<ProcessingItem[]> result) {
ArtifactsProcessingItemsBuilderContext builderContext = new ArtifactsProcessingItemsBuilderContext(context);
context.putUserData(BUILDER_CONTEXT_KEY, builderContext);
ArtifactPackagingProcessingItem[] allProcessingItems = collectItems(builderContext, context.getProject());
if (LOG.isDebugEnabled()) {
int num = Math.min(100, allProcessingItems.length);
LOG.debug("All files (" + num + " of " + allProcessingItems.length + "):");
for (int i = 0; i < num; i++) {
LOG.debug(allProcessingItems[i].getFile().getPath());
}
}
try {
final FileProcessingCompilerStateCache cache =
CompilerCacheManager.getInstance(context.getProject()).getFileProcessingCompilerCache(IncrementalArtifactsCompiler.this);
for (ArtifactPackagingProcessingItem item : allProcessingItems) {
item.init(cache);
}
}
catch (IOException e) {
context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
result.setResult(ProcessingItem.EMPTY_ARRAY);
return;
}
boolean hasFilesToDelete = collectFilesToDelete(context, builderContext.getProcessingItems());
if (hasFilesToDelete) {
MockProcessingItem mockItem = new MockProcessingItem(new LightVirtualFile("239239293"));
result.setResult(ArrayUtil.append(allProcessingItems, mockItem, ProcessingItem.class));
}
else {
result.setResult(allProcessingItems);
}
}
}.execute().getResultObject();
}
private static class MockProcessingItem implements ProcessingItem {
private final VirtualFile myFile;
@@ -15,7 +15,7 @@
*/
package com.intellij.packaging.impl.compiler;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.packaging.elements.PackagingFileFilter;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
@@ -15,12 +15,14 @@
*/
package com.intellij.packaging.impl.elements;
import com.intellij.openapi.deployment.LibraryLink;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
@@ -146,7 +148,7 @@ public class LibraryPackagingElement extends ComplexPackagingElement<LibraryPack
@Nullable
public Library findLibrary(@NotNull PackagingElementResolvingContext context) {
if (myModuleName == null) {
return LibraryLink.findLibrary(myLibraryName, myLevel, context.getProject());
return findLibrary(myLibraryName, myLevel, context.getProject());
}
final ModulesProvider modulesProvider = context.getModulesProvider();
final Module module = modulesProvider.getModule(myModuleName);
@@ -179,4 +181,28 @@ public class LibraryPackagingElement extends ComplexPackagingElement<LibraryPack
}
return new PackagingElementOutputKind(containsDirectories, containsJars);
}
@Nullable
private static Library findLibrary(String libraryName, String libraryLevel, Project project) {
if (libraryName == null) {
return null;
}
LibraryTable table = findTable(libraryLevel, project);
if (table == null) {
return null;
}
else {
return table.getLibraryByName(libraryName);
}
}
@Nullable
private static LibraryTable findTable(String libraryLevel, Project project) {
if (libraryLevel == null) return null;
if (LibraryTablesRegistrar.APPLICATION_LEVEL.equals(libraryLevel)) {
return LibraryTablesRegistrar.getInstance().getLibraryTable();
}
return project == null? null : LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(libraryLevel, project);
}
}
@@ -1,94 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.compiler.ant;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.module.Module;
/**
* @author nik
*/
public class ExplodedAndJarTargetParameters {
private final ModuleChunk myChunk;
private final Module myContainingModule;
private final GenerationOptions myGenerationOptions;
private final String myExplodedPathParameter;
private final String myJarPathParameter;
private final String myBuildExplodedTargetName;
private final String myBuildJarTargetName;
private final String myExplodedPathProperty;
private final String myJarPathProperty;
private final BuildConfiguration myBuildConfiguration;
public ExplodedAndJarTargetParameters(final ModuleChunk chunk, final Module containingModule, final GenerationOptions generationOptions,
final BuildConfiguration buildConfiguration, final String explodedPathParameter, final String jarPathParameter,
final String buildExplodedTargetName,
final String buildJarTargetName,
final String explodedPathProperty,
final String jarPathProperty) {
myBuildConfiguration = buildConfiguration;
myChunk = chunk;
myContainingModule = containingModule;
myGenerationOptions = generationOptions;
myExplodedPathParameter = explodedPathParameter;
myJarPathParameter = jarPathParameter;
myBuildExplodedTargetName = buildExplodedTargetName;
myBuildJarTargetName = buildJarTargetName;
myExplodedPathProperty = explodedPathProperty;
myJarPathProperty = jarPathProperty;
}
public ModuleChunk getChunk() {
return myChunk;
}
public GenerationOptions getGenerationOptions() {
return myGenerationOptions;
}
public String getExplodedPathParameter() {
return myExplodedPathParameter;
}
public String getJarPathParameter() {
return myJarPathParameter;
}
public Module getContainingModule() {
return myContainingModule;
}
public String getBuildExplodedTargetName() {
return myBuildExplodedTargetName;
}
public String getBuildJarTargetName() {
return myBuildJarTargetName;
}
public String getExplodedPathProperty() {
return myExplodedPathProperty;
}
public String getJarPathProperty() {
return myJarPathProperty;
}
public BuildConfiguration getBuildConfiguration() {
return myBuildConfiguration;
}
}
@@ -1,41 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.compiler.make;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
public abstract class BuildConfiguration {
@NonNls
public abstract String getArchiveExtension();
@Nullable
public abstract String getJarPath();
@Nullable
public abstract String getExplodedPath();
public abstract boolean isJarEnabled();
public abstract boolean isExplodedEnabled();
@Deprecated
public boolean willBuildExploded() {
return isExplodedEnabled() && getExplodedPath() != null;
}
}
@@ -15,13 +15,8 @@
*/
package com.intellij.openapi.compiler.make;
import com.intellij.openapi.module.Module;
public interface BuildInstruction {
String getOutputRelativePath();
Module getModule();
boolean accept(BuildInstructionVisitor visitor) throws Exception;
boolean isExternalDependencyInstruction();
}
@@ -23,7 +23,4 @@ public abstract class BuildInstructionVisitor {
public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws Exception {
return visitInstruction(instruction);
}
public boolean visitJarAndCopyBuildInstruction(JarAndCopyBuildInstruction instruction) throws Exception {
return visitFileCopyInstruction(instruction);
}
}
@@ -16,43 +16,13 @@
package com.intellij.openapi.compiler.make;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.module.Module;
import com.intellij.packaging.artifacts.Artifact;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public abstract class BuildParticipant {
public static final BuildParticipant[] EMPTY_ARRAY = new BuildParticipant[0];
public void afterJarCreated(File jarFile, CompileContext context) throws Exception {
}
public void afterExplodedCreated(File outputDir, CompileContext context) throws Exception {
}
public void buildStarted(CompileContext context) {
}
public void buildFinished(CompileContext context) throws Exception {
}
public abstract BuildRecipe getBuildInstructions(final CompileContext context);
public abstract BuildConfiguration getBuildConfiguration();
@Nullable
public abstract Artifact createArtifact(CompileContext context);
@Nullable
public String getOrCreateTemporaryDirForExploded() {
return null;
}
public abstract Module getModule();
public boolean willBuildExploded() {
BuildConfiguration configuration = getBuildConfiguration();
return configuration.isExplodedEnabled() && configuration.getExplodedPath() != null;
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.compiler.make;
import com.intellij.openapi.module.Module;
public abstract class BuildParticipantBase extends BuildParticipant {
private final Module myModule;
protected BuildParticipantBase(final Module module) {
myModule = module;
}
public Module getModule() {
return myModule;
}
}
@@ -15,9 +15,7 @@
*/
package com.intellij.openapi.compiler.make;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -27,10 +25,5 @@ public interface BuildRecipe {
boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder);
boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception;
void addAll(@NotNull BuildRecipe buildRecipe);
void addFileCopyInstruction(@NotNull File file,
boolean isDirectory,
Module module,
String outputRelativePath,
@Nullable PackagingFileFilter fileFilter);
void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath);
}
@@ -24,6 +24,4 @@ public interface FileCopyInstruction extends BuildInstruction {
boolean isDirectory();
@Nullable
PackagingFileFilter getFileFilter();
}
@@ -1,22 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.compiler.make;
import java.io.File;
public interface JarAndCopyBuildInstruction extends FileCopyInstruction {
}
@@ -1,111 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public abstract class ContainerElement implements JDOMExternalizable, Cloneable, ResolvableElement {
private final Map<String,String> myAttributes = new LinkedHashMap<String, String>();
private final Module myParentModule;
@NonNls public static final String URI_ATTRIBUTE = "URI";
@NonNls public static final String PACKAGING_METHOD_ATTRIBUTE = "method";
@NonNls public static final String ELEMENT_ATTRIBUTE = "attribute";
@NonNls public static final String ATTRIBUTE_NAME = "name";
@NonNls public static final String ATTRIBUTE_VALUE = "value";
protected ContainerElement(@NotNull Module parentModule) {
myParentModule = parentModule;
}
public abstract String getPresentableName();
public String getURI() {
return getAttribute(URI_ATTRIBUTE);
}
public void setURI(String uri) {
setAttribute(URI_ATTRIBUTE, uri);
}
public PackagingMethod getPackagingMethod() {
final String attribute = getAttribute(PACKAGING_METHOD_ATTRIBUTE);
return attribute == null ? PackagingMethod.DO_NOT_PACKAGE : PackagingMethod.getDeploymentMethodById(attribute);
}
public void setPackagingMethod(PackagingMethod method) {
setAttribute(PACKAGING_METHOD_ATTRIBUTE, method.getId());
}
public void setAttribute(String name, String value) {
myAttributes.put(name, value);
}
public String getAttribute(String name) {
return myAttributes.get(name);
}
@NotNull
public Module getParentModule() {
return myParentModule;
}
public void readExternal(Element element) throws InvalidDataException {
final List attrs = element.getChildren(ELEMENT_ATTRIBUTE);
for (Object attr : attrs) {
Element attribute = (Element)attr;
final String name = attribute.getAttributeValue(ATTRIBUTE_NAME);
final String value = attribute.getAttributeValue(ATTRIBUTE_VALUE);
setAttribute(name, value);
}
}
public void writeExternal(Element element) throws WriteExternalException {
for (Object o : myAttributes.keySet()) {
String name = (String)o;
String value = getAttribute(name);
final Element attr = new Element(ELEMENT_ATTRIBUTE);
attr.setAttribute(ATTRIBUTE_NAME, name);
attr.setAttribute(ATTRIBUTE_VALUE, value == null ? "" : value);
element.addContent(attr);
}
}
public abstract boolean equalsIgnoreAttributes(ContainerElement otherElement);
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ContainerElement)) return false;
final ContainerElement otherElement = (ContainerElement)o;
if (!equalsIgnoreAttributes(otherElement)) return false;
return myAttributes.equals(otherElement.myAttributes);
}
public int hashCode() {
return 0;
}
public ContainerElement clone() {
throw new UnsupportedOperationException();
}
}
@@ -16,19 +16,12 @@
package com.intellij.openapi.deployment;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.descriptors.ConfigFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,20 +35,6 @@ public abstract class DeploymentUtil {
return ServiceManager.getService(DeploymentUtil.class);
}
public abstract boolean addModuleOutputContents(@NotNull CompileContext context,
@NotNull BuildRecipe items,
@NotNull Module sourceModule,
Module targetModule,
@NonNls String outputRelativePath,
@Nullable @NonNls String possibleBaseOuputPath,
@Nullable PackagingFileFilter fileFilter);
public abstract void addLibraryLink(@NotNull CompileContext context,
@NotNull BuildRecipe items,
@NotNull LibraryLink libraryLink,
@NotNull Module module,
String possibleBaseOutputPath);
public abstract void copyFile(@NotNull File fromFile,
@NotNull File toFile,
@NotNull CompileContext context,
@@ -65,17 +44,7 @@ public abstract class DeploymentUtil {
public abstract boolean addItemsRecursively(@NotNull BuildRecipe items,
@NotNull File root,
Module module,
String outputRelativePath,
@Nullable PackagingFileFilter fileFilter,
@Nullable String possibleBaseOutputPath);
public static void reportRecursiveCopying(CompileContext context, final String sourceDirPath, String targetDirPath,
final String dirTitle, String additionalMessage) {
final String message = CompilerBundle.message(
"message.text.copy.dirTitle.dirPath.to.targetDirPath.will.lead.to.recursive.copying.additionalMessage", dirTitle,
FileUtil.toSystemDependentName(sourceDirPath), FileUtil.toSystemDependentName(targetDirPath), additionalMessage);
context.addMessage(CompilerMessageCategory.ERROR, message,null,-1,-1);
}
String outputRelativePath, @Nullable String possibleBaseOutputPath);
public static String trimForwardSlashes(@NotNull String path) {
while (path.length() != 0 && (path.charAt(0) == '/' || path.charAt(0) == File.separatorChar)) {
@@ -84,20 +53,8 @@ public abstract class DeploymentUtil {
return path;
}
public static String trimTrailingSlashes(@NotNull String path) {
int l = path.length() - 1;
while (l >= 0 && (path.charAt(l) == '/' || path.charAt(l) == File.separatorChar)) l--;
return path.substring(0, l+1);
}
public abstract void reportDeploymentDescriptorDoesNotExists(ConfigFile descriptor, CompileContext context, Module module);
public abstract void addJavaModuleOutputs(@NotNull Module module,
@NotNull ModuleLink[] containingModules,
@NotNull BuildRecipe instructions,
@NotNull CompileContext context,
String explodedPath, final String linkContainerDescription);
public static String concatPaths(String... paths) {
final StringBuilder builder = new StringBuilder();
for (String path : paths) {
@@ -119,14 +76,6 @@ public abstract class DeploymentUtil {
return path + trimForwardSlashes(name);
}
public static File canonicalRelativePath(File file, final String outputRelativePath) {
return new File(PathUtil.getCanonicalPath(appendToPath(file.getPath(),outputRelativePath)));
}
public abstract ModuleLink createModuleLink(@NotNull Module dep, @NotNull Module module);
public abstract LibraryLink createLibraryLink(Library library, @NotNull Module parentModule);
public abstract BuildRecipe createBuildRecipe();
@Nullable
@@ -1,77 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author Alexey Kudravtsev
*/
public abstract class LibraryLink extends ContainerElement {
@NonNls public static final String MODULE_LEVEL = "module";
public LibraryLink(Module parentModule) {
super(parentModule);
}
@Nullable
public abstract Library getLibrary();
public abstract List<String> getUrls();
public abstract List<String> getClassesRootUrls();
public abstract boolean hasDirectoriesOnly();
@Nullable
public abstract String getName();
public abstract String getLevel();
@Nullable
public static Library findLibrary(String libraryName, String libraryLevel, Project project) {
if (libraryName == null) {
return null;
}
LibraryTable table = findTable(libraryLevel, project);
if (table == null) {
return null;
}
else {
return table.getLibraryByName(libraryName);
}
}
@Nullable
protected static LibraryTable findTable(String libraryLevel, Project project) {
if (libraryLevel == null) return null;
if (LibraryTablesRegistrar.APPLICATION_LEVEL.equals(libraryLevel)) {
return LibraryTablesRegistrar.getInstance().getLibraryTable();
}
return project == null? null : LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(libraryLevel, project);
}
}
@@ -1,34 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.Nullable;
/**
* @author Alexey Kudravtsev
*/
public abstract class ModuleLink extends ContainerElement {
public ModuleLink(Module parentModule) {
super(parentModule);
}
public abstract @Nullable Module getModule();
public abstract String getName();
}
@@ -1,74 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.compiler.CompilerBundle;
import gnu.trove.THashMap;
import java.util.Map;
public class PackagingMethod {
public static final PackagingMethod[] EMPTY_ARRAY = new PackagingMethod[0];
private final String myId;
private final String myDescription;
private static final Map<String, PackagingMethod> ourRegisteredMethods = new THashMap<String, PackagingMethod>();
private PackagingMethod(String id, String description) {
myId = id;
myDescription = description;
ourRegisteredMethods.put(id, this);
}
public String getId() {
return myId;
}
public static final PackagingMethod DO_NOT_PACKAGE = new PackagingMethod("0", CompilerBundle.message("packaging.method.name.do.not.package"));
public static final PackagingMethod COPY_FILES = new PackagingMethod("1",CompilerBundle.message("packaging.method.name.copy.files"));
public static final PackagingMethod COPY_FILES_AND_LINK_VIA_MANIFEST = new PackagingMethod("2",CompilerBundle.message("packaging.method.name.copy.files.and.link.via.manifest"));
/**
* @deprecated
*/
public static final PackagingMethod COPY_CLASSES = new PackagingMethod("3",CompilerBundle.message("packaging.method.name.copy.classes"));
public static final PackagingMethod INCLUDE_MODULE_IN_BUILD = new PackagingMethod("4",CompilerBundle.message("packaging.method.name.include.module.in.build"));
public static final PackagingMethod JAR_AND_COPY_FILE = new PackagingMethod("5",CompilerBundle.message("packaging.method.name.jar.and.copy.file"));
public static final PackagingMethod JAR_AND_COPY_FILE_AND_LINK_VIA_MANIFEST = new PackagingMethod("6",CompilerBundle.message("packaging.method.name.jar.copy.and.link.via.manifest"));
public static PackagingMethod getDeploymentMethodById(String id) {
return ourRegisteredMethods.get(id);
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PackagingMethod)) return false;
final PackagingMethod method = (PackagingMethod)o;
if (!myId.equals(method.myId)) return false;
return true;
}
public int hashCode() {
return myId.hashCode();
}
public String toString() {
return CompilerBundle.message("packaging.method.presentation.with.description", myDescription);
}
}
@@ -1,23 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
public interface ResolvableElement {
boolean resolveElement(ModulesProvider modulesProvider, final FacetsProvider facetsProvider);
}
@@ -1,20 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
public interface TransactionalEditable {
}
@@ -1,33 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.deployment;
public class VerificationException extends Exception {
public VerificationException() {
}
public VerificationException(String message) {
super(message);
}
public VerificationException(Throwable cause) {
super(cause);
}
public VerificationException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -15,7 +15,7 @@
*/
package com.intellij.packaging.elements;
import com.intellij.openapi.compiler.make.PackagingFileFilter;
import com.intellij.packaging.elements.PackagingFileFilter;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.intellij.openapi.compiler.make;
package com.intellij.packaging.elements;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.vfs.VirtualFile;
@@ -18,7 +18,6 @@ package org.jetbrains.idea.devkit.build;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.startup.StartupManager;
@@ -46,7 +45,7 @@ import org.jetbrains.idea.devkit.module.PluginDescriptorConstants;
import java.io.File;
public class PluginBuildConfiguration extends BuildConfiguration implements ModuleComponent, JDOMExternalizable {
public class PluginBuildConfiguration implements ModuleComponent, JDOMExternalizable {
private final Module myModule;
private final ConfigFileContainer myPluginXmlContainer;
private VirtualFilePointer myPluginXmlPointer;
@@ -71,26 +70,6 @@ public class PluginBuildConfiguration extends BuildConfiguration implements Modu
return module.getComponent(PluginBuildConfiguration.class);
}
public String getArchiveExtension() {
return "jar";
}
public String getJarPath() {
return null;
}
public String getExplodedPath() {
return PluginBuildUtil.getPluginExPath(myModule);
}
public boolean isJarEnabled() {
return false;
}
public boolean isExplodedEnabled() {
return true;
}
public void projectOpened() {}
public void projectClosed() {}
@@ -17,9 +17,7 @@ package org.jetbrains.idea.devkit.build;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.compiler.make.BuildConfiguration;
import com.intellij.openapi.compiler.make.BuildParticipantBase;
import com.intellij.openapi.compiler.make.BuildRecipe;
import com.intellij.openapi.compiler.make.BuildParticipant;
import com.intellij.openapi.deployment.DeploymentUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
@@ -57,7 +55,7 @@ import java.util.List;
/**
* @author peter
*/
public class PluginBuildParticipant extends BuildParticipantBase {
public class PluginBuildParticipant extends BuildParticipant {
@NonNls private static final String CLASSES = "/classes";
@NonNls private static final String LIB = "/lib/";
@NonNls private static final String LIB_DIRECTORY = "lib";
@@ -65,17 +63,11 @@ public class PluginBuildParticipant extends BuildParticipantBase {
private final PluginBuildConfiguration myPluginBuildConfiguration;
public PluginBuildParticipant(final Module module, final PluginBuildConfiguration pluginBuildConfiguration) {
super(module);
super();
myModule = module;
myPluginBuildConfiguration = pluginBuildConfiguration;
}
public BuildRecipe getBuildInstructions(final CompileContext context) {
//todo[nik] cache?
final BuildRecipe buildRecipe = DeploymentUtil.getInstance().createBuildRecipe();
return buildRecipe;
}
@Override
public Artifact createArtifact(CompileContext context) {
Sdk jdk = IdeaJdk.findIdeaJdk(ModuleRootManager.getInstance(myModule).getSdk());
@@ -215,8 +207,4 @@ public class PluginBuildParticipant extends BuildParticipantBase {
return true;
}
public BuildConfiguration getBuildConfiguration() {
return myPluginBuildConfiguration;
}
}
-3
View File
@@ -67,9 +67,6 @@
<extensionPoint name="antCustomCompiler"
interface="com.intellij.compiler.ant.ChunkCustomCompilerExtension"/>
<extensionPoint name="explodedAndJarBuildGenerator"
interface="com.intellij.compiler.make.ExplodedAndJarBuildGenerator"/>
<extensionPoint name="methodImplementor"
interface="com.intellij.codeInsight.MethodImplementor"/>