Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425
from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/compiler/openapi/compiler-openapi.iml b/java/compiler/openapi/compiler-openapi.iml
new file mode 100644
index 0000000..9fb5c93
--- /dev/null
+++ b/java/compiler/openapi/compiler-openapi.iml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="openapi" />
+ </component>
+ <component name="copyright">
+ <Base>
+ <setting name="state" value="0" />
+ </Base>
+ <LanguageOptions name="HTML">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright (c) &#36;today.year, Your Corporation. All Rights Reserved." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="JAVA">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="/* * Copyright (c) &#36;today.year Your Corporation. All Rights Reserved. */" />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="JSP">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright (c) &#36;today.year, Your Corporation. All Rights Reserved." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="JavaScript">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright (c) &#36;today.year, Your Corporation. All Rights Reserved." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="Properties">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright (c) &#36;today.year, Your Corporation. All Rights Reserved." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="XML">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright (c) &#36;today.year, Your Corporation. All Rights Reserved." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="2" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ <LanguageOptions name="__TEMPLATE__">
+ <option name="templateOptions">
+ <value>
+ <option name="block" value="true" />
+ <option name="separateBefore" value="false" />
+ <option name="separateAfter" value="false" />
+ <option name="prefixLines" value="true" />
+ <option name="lenBefore" value="80" />
+ <option name="lenAfter" value="80" />
+ <option name="box" value="false" />
+ <option name="filler" value=" " />
+ </value>
+ </option>
+ <option name="notice" value="Copyright 2000-&#36;{today.year} 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." />
+ <option name="keyword" value="Copyright" />
+ <option name="fileTypeOverride" value="4" />
+ <option name="relativeBefore" value="true" />
+ <option name="addBlankAfter" value="true" />
+ <option name="fileLocation" value="1" />
+ <option name="useAlternate" value="false" />
+ </LanguageOptions>
+ </component>
+</module>
+
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java
new file mode 100644
index 0000000..9aa97cf
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+
+public abstract class CompilerConfiguration {
+ // need this flag for profiling purposes. In production code is always set to 'true'
+ public static final boolean MAKE_ENABLED = true;
+
+ @Nullable
+ public abstract String getProjectBytecodeTarget();
+
+ @Nullable
+ public abstract String getBytecodeTargetLevel(Module module);
+
+ public abstract void setBytecodeTargetLevel(Module module, String level);
+
+ @NotNull
+ public abstract AnnotationProcessingConfiguration getAnnotationProcessingConfiguration(Module module);
+
+ /**
+ * @return true if exists at least one enabled annotation processing profile
+ */
+ public abstract boolean isAnnotationProcessorsEnabled();
+
+ public static CompilerConfiguration getInstance(Project project) {
+ return project.getComponent(CompilerConfiguration.class);
+ }
+
+ public abstract boolean isExcludedFromCompilation(VirtualFile virtualFile);
+
+ public abstract boolean isResourceFile(VirtualFile virtualFile);
+
+ public abstract boolean isResourceFile(String path);
+
+ public abstract void addResourceFilePattern(String namePattern) throws MalformedPatternException;
+
+ public abstract boolean isAddNotNullAssertions();
+
+ public abstract void setAddNotNullAssertions(boolean enabled);
+
+ public abstract ExcludedEntriesConfiguration getExcludedEntriesConfiguration();
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java
new file mode 100644
index 0000000..c2e85ef
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+
+/**
+ * Please use {@link com.intellij.openapi.options.ConfigurableEP#parentId} to put your configurable under Compiler Settings
+ * @author Eugene Zhuravlev
+ * Date: Sep 17, 2008
+ */
+@Deprecated
+public interface CompilerSettingsFactory {
+ ExtensionPointName<CompilerSettingsFactory> EP_NAME = ExtensionPointName.create("com.intellij.compilerSettingsFactory");
+
+ Configurable create(Project project);
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
new file mode 100644
index 0000000..98250d9
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author Eugene Zhuravlev
+ */
+package com.intellij.compiler;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+
+@State(
+ name = "CompilerWorkspaceConfiguration",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.WORKSPACE_FILE
+ )}
+)
+public class CompilerWorkspaceConfiguration implements PersistentStateComponent<CompilerWorkspaceConfiguration> {
+ public static final int DEFAULT_COMPILE_PROCESS_HEAP_SIZE = 700;
+ public static final String DEFAULT_COMPILE_PROCESS_VM_OPTIONS = "-ea";
+
+ public boolean AUTO_SHOW_ERRORS_IN_EDITOR = true;
+ @Deprecated public boolean CLOSE_MESSAGE_VIEW_IF_SUCCESS = true;
+ public boolean CLEAR_OUTPUT_DIRECTORY = true;
+ public boolean USE_COMPILE_SERVER = true;
+ public boolean MAKE_PROJECT_ON_SAVE = true;
+ public boolean PARALLEL_COMPILATION = false;
+ public int COMPILER_PROCESS_HEAP_SIZE = DEFAULT_COMPILE_PROCESS_HEAP_SIZE;
+ public String COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = DEFAULT_COMPILE_PROCESS_VM_OPTIONS;
+
+ public static CompilerWorkspaceConfiguration getInstance(Project project) {
+ return ServiceManager.getService(project, CompilerWorkspaceConfiguration.class);
+ }
+
+ public CompilerWorkspaceConfiguration getState() {
+ return this;
+ }
+
+ public void loadState(CompilerWorkspaceConfiguration state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+
+ public boolean useOutOfProcessBuild() {
+ return USE_COMPILE_SERVER;
+ }
+
+ public boolean allowAutoMakeWhileRunningApplication() {
+ return false;/*ALLOW_AUTOMAKE_WHILE_RUNNING_APPLICATION*/
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.java b/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.java
new file mode 100644
index 0000000..af7636c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+public class MalformedPatternException extends RuntimeException {
+ public MalformedPatternException(Throwable cause) {
+ super(cause);
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return getCause().getLocalizedMessage();
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java
new file mode 100644
index 0000000..44b7b2a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.Chunk;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.graph.*;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author dsl
+ */
+public final class ModuleCompilerUtil {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.ModuleCompilerUtil");
+ private ModuleCompilerUtil() { }
+
+ public static Module[] getDependencies(Module module) {
+ return ModuleRootManager.getInstance(module).getDependencies();
+ }
+
+ public static Graph<Module> createModuleGraph(final Module[] modules) {
+ return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Module>() {
+ public Collection<Module> getNodes() {
+ return Arrays.asList(modules);
+ }
+
+ public Iterator<Module> getIn(Module module) {
+ return Arrays.asList(getDependencies(module)).iterator();
+ }
+ }));
+ }
+
+ public static List<Chunk<Module>> getSortedModuleChunks(Project project, List<Module> modules) {
+ final Module[] allModules = ModuleManager.getInstance(project).getModules();
+ final List<Chunk<Module>> chunks = getSortedChunks(createModuleGraph(allModules));
+
+ final Set<Module> modulesSet = new HashSet<Module>(modules);
+ // leave only those chunks that contain at least one module from modules
+ for (Iterator<Chunk<Module>> it = chunks.iterator(); it.hasNext();) {
+ final Chunk<Module> chunk = it.next();
+ if (!ContainerUtil.intersects(chunk.getNodes(), modulesSet)) {
+ it.remove();
+ }
+ }
+ return chunks;
+ }
+
+ public static <Node> List<Chunk<Node>> getSortedChunks(final Graph<Node> graph) {
+ final Graph<Chunk<Node>> chunkGraph = toChunkGraph(graph);
+ final List<Chunk<Node>> chunks = new ArrayList<Chunk<Node>>(chunkGraph.getNodes().size());
+ for (final Chunk<Node> chunk : chunkGraph.getNodes()) {
+ chunks.add(chunk);
+ }
+ DFSTBuilder<Chunk<Node>> builder = new DFSTBuilder<Chunk<Node>>(chunkGraph);
+ if (!builder.isAcyclic()) {
+ LOG.error("Acyclic graph expected");
+ return null;
+ }
+
+ Collections.sort(chunks, builder.comparator());
+ return chunks;
+ }
+
+ public static <Node> Graph<Chunk<Node>> toChunkGraph(final Graph<Node> graph) {
+ return GraphAlgorithms.getInstance().computeSCCGraph(graph);
+ }
+
+ public static void sortModules(final Project project, final List<Module> modules) {
+ final Application application = ApplicationManager.getApplication();
+ Runnable sort = new Runnable() {
+ public void run() {
+ Comparator<Module> comparator = ModuleManager.getInstance(project).moduleDependencyComparator();
+ Collections.sort(modules, comparator);
+ }
+ };
+ if (application.isDispatchThread()) {
+ sort.run();
+ }
+ else {
+ application.runReadAction(sort);
+ }
+ }
+
+
+ public static <T extends ModuleRootModel> GraphGenerator<T> createGraphGenerator(final Map<Module, T> models) {
+ return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<T>() {
+ public Collection<T> getNodes() {
+ return models.values();
+ }
+
+ public Iterator<T> getIn(final ModuleRootModel model) {
+ final Module[] modules = model.getModuleDependencies();
+ final List<T> dependencies = new ArrayList<T>();
+ for (Module module : modules) {
+ T depModel = models.get(module);
+ if (depModel != null) {
+ dependencies.add(depModel);
+ }
+ }
+ return dependencies.iterator();
+ }
+ }));
+ }
+
+ /**
+ * @return pair of modules which become circular after adding dependency, or null if all remains OK
+ */
+ @Nullable
+ public static Pair<Module, Module> addingDependencyFormsCircularity(final Module currentModule, Module toDependOn) {
+ assert currentModule != toDependOn;
+ // whatsa lotsa of @&#^%$ codes-a!
+
+ final Map<Module, ModifiableRootModel> models = new LinkedHashMap<Module, ModifiableRootModel>();
+ Project project = currentModule.getProject();
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+ models.put(module, model);
+ }
+ ModifiableRootModel currentModel = models.get(currentModule);
+ ModifiableRootModel toDependOnModel = models.get(toDependOn);
+ Collection<Chunk<ModifiableRootModel>> nodesBefore = buildChunks(models);
+ for (Chunk<ModifiableRootModel> chunk : nodesBefore) {
+ if (chunk.containsNode(toDependOnModel) && chunk.containsNode(currentModel)) return null; // they circular already
+ }
+
+ try {
+ currentModel.addModuleOrderEntry(toDependOn);
+ Collection<Chunk<ModifiableRootModel>> nodesAfter = buildChunks(models);
+ for (Chunk<ModifiableRootModel> chunk : nodesAfter) {
+ if (chunk.containsNode(toDependOnModel) && chunk.containsNode(currentModel)) {
+ Iterator<ModifiableRootModel> nodes = chunk.getNodes().iterator();
+ return Pair.create(nodes.next().getModule(), nodes.next().getModule());
+ }
+ }
+ }
+ finally {
+ for (ModifiableRootModel model : models.values()) {
+ model.dispose();
+ }
+ }
+ return null;
+ }
+
+ public static <T extends ModuleRootModel> Collection<Chunk<T>> buildChunks(final Map<Module, T> models) {
+ return toChunkGraph(createGraphGenerator(models)).getNodes();
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java
new file mode 100644
index 0000000..51ee7d1
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java
@@ -0,0 +1,271 @@
+/*
+ * 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;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class BuildProperties extends CompositeGenerator {
+ public static final @NonNls String TARGET_ALL = "all";
+ public static final @NonNls String TARGET_BUILD_MODULES = "build.modules";
+ public static final @NonNls String TARGET_CLEAN = "clean";
+ public static final @NonNls String TARGET_INIT = "init";
+ public static final @NonNls String TARGET_REGISTER_CUSTOM_COMPILERS = "register.custom.compilers";
+ public static final @NonNls String DEFAULT_TARGET = TARGET_ALL;
+ public static final @NonNls String PROPERTY_COMPILER_NAME = "compiler.name";
+ public static final @NonNls String PROPERTY_COMPILER_ADDITIONAL_ARGS = "compiler.args";
+ public static final @NonNls String PROPERTY_COMPILER_MAX_MEMORY = "compiler.max.memory";
+ public static final @NonNls String PROPERTY_COMPILER_EXCLUDES = "compiler.excluded";
+ public static final @NonNls String PROPERTY_COMPILER_RESOURCE_PATTERNS = "compiler.resources";
+ public static final @NonNls String PROPERTY_IGNORED_FILES = "ignored.files";
+ public static final @NonNls String PROPERTY_COMPILER_GENERATE_DEBUG_INFO = "compiler.debug";
+ public static final @NonNls String PROPERTY_COMPILER_GENERATE_NO_WARNINGS = "compiler.generate.no.warnings";
+ public static final @NonNls String PROPERTY_PROJECT_JDK_HOME = "project.jdk.home";
+ public static final @NonNls String PROPERTY_PROJECT_JDK_BIN = "project.jdk.bin";
+ public static final @NonNls String PROPERTY_PROJECT_JDK_CLASSPATH = "project.jdk.classpath";
+ public static final @NonNls String PROPERTY_SKIP_TESTS = "skip.tests";
+ public static final @NonNls String PROPERTY_LIBRARIES_PATTERNS = "library.patterns";
+ public static final @NonNls String PROPERTY_IDEA_HOME = "idea.home";
+ public static final @NonNls String PROPERTY_JAVAC2_HOME = "javac2.home";
+ public static final @NonNls String PROPERTY_JAVAC2_CLASSPATH_ID = "javac2.classpath";
+
+ protected abstract void createJdkGenerators(Project project);
+
+ public static Sdk[] getUsedJdks(Project project) {
+ final Set<Sdk> jdks = new HashSet<Sdk>();
+ Module[] modules = ModuleManager.getInstance(project).getModules();
+ for (Module module : modules) {
+ Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+ if (jdk != null) {
+ jdks.add(jdk);
+ }
+ }
+ return jdks.toArray(new Sdk[jdks.size()]);
+ }
+
+ @NonNls
+ public static String getJdkPathId(@NonNls final String jdkName) {
+ return "jdk.classpath." + convertName(jdkName);
+ }
+
+ @NonNls
+ public static String getModuleChunkJdkClasspathProperty(@NonNls final String moduleChunkName) {
+ return "module.jdk.classpath." + convertName(moduleChunkName);
+ }
+
+ @NonNls
+ public static String getModuleChunkJdkHomeProperty(@NonNls final String moduleChunkName) {
+ return "module.jdk.home." + convertName(moduleChunkName);
+ }
+
+ @NonNls
+ public static String getModuleChunkJdkBinProperty(@NonNls final String moduleChunkName) {
+ return "module.jdk.bin." + convertName(moduleChunkName);
+ }
+
+ @NonNls
+ public static String getModuleChunkCompilerArgsProperty(@NonNls final String moduleName) {
+ return "compiler.args." + convertName(moduleName);
+ }
+
+ @NonNls
+ public static String getLibraryPathId(@NonNls final String libraryName) {
+ return "library." + convertName(libraryName) + ".classpath";
+ }
+
+ @NonNls
+ public static String getJdkHomeProperty(@NonNls final String jdkName) {
+ return "jdk.home." + convertName(jdkName);
+ }
+
+ @NonNls
+ public static String getJdkBinProperty(@NonNls final String jdkName) {
+ return "jdk.bin." + convertName(jdkName);
+ }
+
+ @NonNls
+ public static String getCompileTargetName(@NonNls String moduleName) {
+ return "compile.module." + convertName(moduleName);
+ }
+
+ @NonNls
+ public static String getOutputPathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".output.dir";
+ }
+
+ @NonNls
+ public static String getOutputPathForTestsProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".testoutput.dir";
+ }
+
+ @NonNls
+ public static String getClasspathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".module.production.classpath";
+ }
+
+ @NonNls
+ public static String getTestClasspathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".module.classpath";
+ }
+
+ @NonNls
+ public static String getRuntimeClasspathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".runtime.production.module.classpath";
+ }
+
+ @NonNls
+ public static String getTestRuntimeClasspathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".runtime.module.classpath";
+ }
+
+ @NonNls
+ public static String getBootClasspathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".module.bootclasspath";
+ }
+
+ @NonNls
+ public static String getSourcepathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".module.sourcepath";
+ }
+
+ @NonNls
+ public static String getTestSourcepathProperty(@NonNls String moduleName) {
+ return convertName(moduleName) + ".module.test.sourcepath";
+ }
+
+ @NonNls
+ public static String getExcludedFromModuleProperty(@NonNls String moduleName) {
+ return "excluded.from.module." + convertName(moduleName);
+ }
+
+ @NonNls
+ public static String getExcludedFromCompilationProperty(@NonNls String moduleName) {
+ return "excluded.from.compilation." + convertName(moduleName);
+ }
+
+ @NonNls
+ public static String getProjectBuildFileName(Project project) {
+ return convertName(project.getName());
+ }
+
+ @NonNls
+ public static String getModuleChunkBuildFileName(final ModuleChunk chunk) {
+ return "module_" + convertName(chunk.getName());
+ }
+
+ @NonNls
+ public static String getModuleCleanTargetName(@NonNls String moduleName) {
+ return "clean.module." + convertName(moduleName);
+ }
+
+ @NonNls
+ public static String getModuleChunkBasedirProperty(ModuleChunk chunk) {
+ return "module." + convertName(chunk.getName()) + ".basedir";
+ }
+
+ /**
+ * left for compatibility
+ *
+ * @param module the module to get property for
+ * @return name of the property
+ */
+ @NonNls
+ public static String getModuleBasedirProperty(Module module) {
+ return "module." + convertName(module.getName()) + ".basedir";
+ }
+
+ @NonNls
+ public static String getProjectBaseDirProperty() {
+ return "basedir";
+ }
+
+ public static File getModuleChunkBaseDir(ModuleChunk chunk) {
+ return chunk.getBaseDir();
+ }
+
+ public static File getProjectBaseDir(final Project project) {
+ final VirtualFile baseDir = project.getBaseDir();
+ assert baseDir != null;
+ return VfsUtil.virtualToIoFile(baseDir);
+ }
+
+ /**
+ * Convert name. All double quotes are removed and spaces are replaced with underscore.
+ *
+ * @param name a name to convert
+ * @return a converted name
+ */
+ @NonNls
+ public static String convertName(@NonNls final String name) {
+ //noinspection HardCodedStringLiteral
+ return name.replaceAll("\"", "").replaceAll("\\s+", "_").toLowerCase();
+ }
+
+ @NonNls
+ public static String getPathMacroProperty(@NonNls String pathMacro) {
+ return "path.variable." + convertName(pathMacro);
+ }
+
+ @NonNls
+ public static String propertyRef(@NonNls String propertyName) {
+ return "${" + propertyName + "}";
+ }
+
+ /**
+ * Construct path relative to the specified property
+ *
+ * @param propertyName the property name
+ * @param relativePath the relative path
+ * @return the path relative to the property
+ */
+ @NonNls
+ public static String propertyRelativePath(@NonNls String propertyName, @NonNls String relativePath) {
+ return "${" + propertyName + "}/" + relativePath;
+ }
+
+
+ public static File toCanonicalFile(final File file) {
+ File canonicalFile;
+ try {
+ canonicalFile = file.getCanonicalFile();
+ }
+ catch (IOException e) {
+ canonicalFile = file;
+ }
+ return canonicalFile;
+ }
+
+ @NonNls
+ public static String getTempDirForModuleProperty(@NonNls String moduleName) {
+ return "tmp.dir." + convertName(moduleName);
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java
new file mode 100644
index 0000000..65a7587
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class BuildTargetsFactory {
+ public static BuildTargetsFactory getInstance() {
+ return ServiceManager.getService(BuildTargetsFactory.class);
+ }
+
+ public abstract Generator createComment(String comment);
+
+ //for test
+ public abstract GenerationOptions getDefaultOptions(Project project);
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java
new file mode 100644
index 0000000..adb1cb0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java
@@ -0,0 +1,85 @@
+/*
+ * 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.ExtensionPoints;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ArtifactAntGenerationContext;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class ChunkBuildExtension {
+ public static final ExtensionPointName<ChunkBuildExtension> EP_NAME = ExtensionPointName.create(ExtensionPoints.ANT_BUILD_GEN);
+
+ @NotNull
+ @NonNls
+ public abstract String[] getTargets(final ModuleChunk chunk);
+
+ public abstract void process(Project project, ModuleChunk chunk, GenerationOptions genOptions, CompositeGenerator generator);
+
+ public void generateProjectTargets(Project project, GenerationOptions genOptions, CompositeGenerator generator) {
+ }
+
+ public void generateProperties(final PropertyFileGenerator generator, final Project project, final GenerationOptions options) {
+ }
+
+ public void generateTasksForArtifact(Artifact artifact, boolean preprocessing, ArtifactAntGenerationContext context,
+ CompositeGenerator generator) {
+ }
+
+ public List<String> getCleanTargetNames(Project project, GenerationOptions genOptions) {
+ return Collections.emptyList();
+ }
+
+ public static String[] getAllTargets(ModuleChunk chunk) {
+ List<String> allTargets = new ArrayList<String>();
+ final ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+ for (ChunkBuildExtension extension : extensions) {
+ ContainerUtil.addAll(allTargets, extension.getTargets(chunk));
+ }
+ if (allTargets.isEmpty()) {
+ allTargets.add(BuildProperties.getCompileTargetName(chunk.getName()));
+ }
+ return ArrayUtil.toStringArray(allTargets);
+ }
+
+ public static void process(CompositeGenerator generator, ModuleChunk chunk, GenerationOptions genOptions) {
+ final Project project = chunk.getProject();
+ final ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+ for (ChunkBuildExtension extension : extensions) {
+ extension.process(project, chunk, genOptions, generator);
+ }
+ }
+
+ public static void generateAllProperties(final PropertyFileGenerator propertyFileGenerator,
+ final Project project,
+ final GenerationOptions genOptions) {
+ ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+ for (ChunkBuildExtension extension : extensions) {
+ extension.generateProperties(propertyFileGenerator, project, genOptions);
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java
new file mode 100644
index 0000000..2356389
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java
@@ -0,0 +1,114 @@
+/*
+ * 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.ExtensionPoints;
+import com.intellij.compiler.ant.taskdefs.PatternSetRef;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedList;
+
+/**
+ * The extenstion point for the custom compilers
+ */
+public abstract class ChunkCustomCompilerExtension {
+ /**
+ * Extension point name
+ */
+ public static final ExtensionPointName<ChunkCustomCompilerExtension> EP_NAME =
+ ExtensionPointName.create(ExtensionPoints.ANT_CUSTOM_COMPILER);
+ /**
+ * Comparator that compares extensions using names. It is used for make order of elements predictable.
+ */
+ protected static final Comparator<ChunkCustomCompilerExtension> COMPARATOR = new Comparator<ChunkCustomCompilerExtension>() {
+ public int compare(ChunkCustomCompilerExtension o1, ChunkCustomCompilerExtension o2) {
+ return o1.getClass().getName().compareTo(o2.getClass().getName());
+ }
+ };
+
+ /**
+ * Generate custom compile task inside compile target. Note that if more
+ * than one extension requested custom compilation, all of them are included into ant
+ * build and fail task is added to the compile target.
+ *
+ * @param project the context project
+ * @param chunk the chunk to compile
+ * @param genOptions an options to compile
+ * @param generator a generator where custom compilation tasks will be added.
+ * @param compileTests if true, tests are compiled
+ * @param compilerArgs the javac compilier arguements
+ * @param bootclasspathTag the boot classpath element for the javac compiler
+ * @param classpathTag the classpath tag for the javac compiler
+ * @param compilerExcludes the compiler excluded tag
+ * @param srcTag the soruce tag
+ * @param outputPathRef the output path references
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ public abstract void generateCustomCompile(Project project,
+ ModuleChunk chunk,
+ GenerationOptions genOptions,
+ boolean compileTests,
+ CompositeGenerator generator,
+ Tag compilerArgs,
+ Tag bootclasspathTag,
+ Tag classpathTag,
+ PatternSetRef compilerExcludes,
+ Tag srcTag,
+ String outputPathRef);
+
+ /**
+ * Generate task registration for custom compiler if needed.
+ *
+ * @param project the context project
+ * @param genOptions an options to compile
+ * @param generator a generator where custom compilation tasks will be added.
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ public abstract void generateCustomCompilerTaskRegistration(Project project, GenerationOptions genOptions, CompositeGenerator generator);
+
+ /**
+ * Allows to check if the custom compilation task is required to compile module sources.
+ * Such task should be able to process standard java sources as well.
+ *
+ * @param chunk a chunk to check
+ * @return true if the facet requires custom comiplation.
+ */
+ @SuppressWarnings({"UnusedDeclaration", "MethodMayBeStatic"})
+ public abstract boolean hasCustomCompile(final ModuleChunk chunk);
+
+ /**
+ * Get custom compilation providers for module chunk
+ *
+ * @param chunk a chunk to examine
+ * @return a list of custom compilators
+ */
+ public static ChunkCustomCompilerExtension[] getCustomCompile(ModuleChunk chunk) {
+ final ChunkCustomCompilerExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+ LinkedList<ChunkCustomCompilerExtension> compilers = new LinkedList<ChunkCustomCompilerExtension>();
+ for (ChunkCustomCompilerExtension extension : extensions) {
+ if (extension.hasCustomCompile(chunk)) {
+ compilers.add(extension);
+ }
+ }
+ final ChunkCustomCompilerExtension[] rc = compilers.toArray(new ChunkCustomCompilerExtension[compilers.size()]);
+ Arrays.sort(rc, ChunkCustomCompilerExtension.COMPARATOR);
+ return rc;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java
new file mode 100644
index 0000000..884e125
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.util.Pair;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A composite generator
+ *
+ * @author Eugene Zhuravlev
+ * Date: Mar 25, 2004
+ */
+public class CompositeGenerator extends Generator {
+ /**
+ * child generators
+ */
+ private final List<Pair<Generator, Integer>> myGenerators = new ArrayList<Pair<Generator, Integer>>();
+ /**
+ * New line property
+ */
+ private boolean hasLeadingNewline = true;
+
+ /**
+ * A constructor
+ */
+ public CompositeGenerator() {
+ }
+
+ /**
+ * A constructor that adds two elements
+ *
+ * @param generator1 the first generator
+ * @param generator2 the second generator
+ * @param emptyLinesCount the amount of new lines between two generators
+ */
+ public CompositeGenerator(Generator generator1, Generator generator2, int emptyLinesCount) {
+ add(generator1);
+ add(generator2, emptyLinesCount);
+ }
+
+ /**
+ * By default, the composite generator generates an empty newline before generating nested eleemnts.
+ * Setting the property to the false, allows suppressing it.
+ *
+ * @param value the new value of the property
+ */
+ public void setHasLeadingNewline(boolean value) {
+ hasLeadingNewline = value;
+ }
+
+ /**
+ * Add child generator with no emtpy lines before it
+ *
+ * @param generator the generator to add
+ */
+ public final void add(Generator generator) {
+ add(generator, 0);
+ }
+
+ /**
+ * Add child generator with the specified amount of empty lines before it
+ *
+ * @param generator a generator
+ * @param emptyLinesCount amount of empty lines
+ */
+ public final void add(Generator generator, int emptyLinesCount) {
+ myGenerators.add(new Pair<Generator, Integer>(generator, new Integer(emptyLinesCount)));
+ }
+
+ /**
+ * Generate content.
+ *
+ * @param out output stream
+ * @throws IOException in case of IO propblem
+ * @see #setHasLeadingNewline(boolean)
+ */
+ public void generate(PrintWriter out) throws IOException {
+ boolean first = true;
+ for (final Pair<Generator, Integer> pair : myGenerators) {
+ if (first) {
+ if (hasLeadingNewline) {
+ crlf(out);
+ }
+ first = false;
+ }
+ else {
+ crlf(out);
+ }
+ final int emptyLinesCount = pair.getSecond().intValue();
+ for (int idx = 0; idx < emptyLinesCount; idx++) {
+ crlf(out);
+ }
+ pair.getFirst().generate(out);
+ }
+ }
+
+ /**
+ * @return amount of the child generators
+ */
+ public final int getGeneratorCount() {
+ return myGenerators.size();
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java
new file mode 100644
index 0000000..fc286ee
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java
@@ -0,0 +1,152 @@
+/*
+ * 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.module.Module;
+
+/**
+ * Ant file generation options. This object is availalbe during construction of ant object tree.
+ *
+ * @author anna
+ */
+public abstract class GenerationOptions {
+ /**
+ * This option specifies whether mulitfile or single file ant script is created.
+ */
+ public final boolean generateSingleFile;
+ /**
+ * This option specifies whehter standard javac or javac2 task is used
+ */
+ public final boolean enableFormCompiler;
+ /**
+ * This option speciries whether files are backed up before generation
+ */
+ public final boolean backupPreviouslyGeneratedFiles;
+ /**
+ * This option specifies whether target JDK is forced during compilation or default ant JDK is used.
+ */
+ public final boolean forceTargetJdk;
+ /**
+ * if true, the runtime classpath is inlined
+ */
+ public final boolean inlineRuntimeClasspath;
+ /**
+ * if true, the runtime classpath is inlined
+ */
+ public final boolean expandJarDirectories;
+
+
+ /**
+ * A constructor
+ *
+ * @param forceTargetJdk a value of corresponding option
+ * @param generateSingleFile a value of corresponding option
+ * @param enableFormCompiler a value of corresponding option
+ * @param backupPreviouslyGeneratedFiles a value of corresponding option
+ * @param inlineRuntimeClasspath if true, a runtiem classpaths are inlined
+ * @param expandJarDirectories if true, jar directories are expaned
+ */
+ public GenerationOptions(boolean forceTargetJdk,
+ boolean generateSingleFile,
+ boolean enableFormCompiler,
+ boolean backupPreviouslyGeneratedFiles,
+ boolean inlineRuntimeClasspath,
+ boolean expandJarDirectories) {
+ this.forceTargetJdk = forceTargetJdk;
+ this.generateSingleFile = generateSingleFile;
+ this.enableFormCompiler = enableFormCompiler;
+ this.backupPreviouslyGeneratedFiles = backupPreviouslyGeneratedFiles;
+ this.inlineRuntimeClasspath = inlineRuntimeClasspath;
+ this.expandJarDirectories = expandJarDirectories;
+ }
+
+ /**
+ * A constructor
+ *
+ * @param forceTargetJdk a value of corresponding option
+ * @param generateSingleFile a value of corresponding option
+ * @param enableFormCompiler a value of corresponding option
+ * @param backupPreviouslyGeneratedFiles a value of corresponding option
+ * @param inlineRuntimeClasspath if true a runtiem classpaths are inlined
+ */
+ public GenerationOptions(boolean forceTargetJdk,
+ boolean generateSingleFile,
+ boolean enableFormCompiler,
+ boolean backupPreviouslyGeneratedFiles,
+ boolean inlineRuntimeClasspath) {
+ this(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, inlineRuntimeClasspath, false);
+ }
+
+ /**
+ * A constructor
+ *
+ * @param forceTargetJdk a value of corresponding option
+ * @param generateSingleFile a value of corresponding option
+ * @param enableFormCompiler a value of corresponding option
+ * @param backupPreviouslyGeneratedFiles a value of corresponding option
+ */
+ @Deprecated
+ public GenerationOptions(boolean forceTargetJdk,
+ boolean generateSingleFile,
+ boolean enableFormCompiler,
+ boolean backupPreviouslyGeneratedFiles) {
+ this(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, false);
+ }
+
+ /**
+ * Substitute path prefix with macro reference if it matches some macro.
+ *
+ * @param path a path to update
+ * @return an updated path or argument
+ */
+ public abstract String subsitutePathWithMacros(String path);
+
+ /**
+ * Get property reference for the specified url of module output directory
+ *
+ * @param url an URL to map
+ * @return the property reference in the form ${..}
+ */
+ public abstract String getPropertyRefForUrl(String url);
+
+ /**
+ * @return an array of module chunks. an array must not be modified by the clients.
+ */
+ public abstract ModuleChunk[] getModuleChunks();
+
+ /**
+ * Get the chunk that contains the specified module.
+ *
+ * @param module the module to find
+ * @return the chunk that contains specifid module
+ */
+ public abstract ModuleChunk getChunkByModule(Module module);
+
+ /**
+ * @return a set of custom compilers, each compiler is used at least once in some chunk.
+ */
+ public abstract ChunkCustomCompilerExtension[] getCustomCompilers();
+
+ /**
+ * @return true if the idea home property must be generated
+ */
+ public abstract boolean isIdeaHomeGenerated();
+
+
+ public abstract String getBuildFileName();
+
+ public abstract String getPropertiesFileName();
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java
new file mode 100644
index 0000000..527d913
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java
@@ -0,0 +1,130 @@
+/*
+ * 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.module.Module;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class GenerationUtils {
+ private GenerationUtils() {
+ }
+
+ /**
+ * Get relative file
+ *
+ * @param file a valid file (must be either belong to {@link com.intellij.openapi.vfs.LocalFileSystem} or to point to the root entry on
+ * {@link com.intellij.openapi.vfs.JarFileSystem}.
+ * @param chunk a module chunk.
+ * @param genOptions generation options
+ * @return a relative path
+ */
+ @Nullable
+ public static String toRelativePath(final VirtualFile file, final ModuleChunk chunk, final GenerationOptions genOptions) {
+ final Module module = chunk.getModules()[0];
+ final File moduleBaseDir = chunk.getBaseDir();
+ return toRelativePath(file, moduleBaseDir, BuildProperties.getModuleBasedirProperty(module), genOptions);
+ }
+
+ public static String toRelativePath(final String file, final File baseDir, final Module module, final GenerationOptions genOptions) {
+ return toRelativePath(file, baseDir, BuildProperties.getModuleBasedirProperty(module), genOptions);
+ }
+
+ public static String toRelativePath(final String path, final ModuleChunk chunk, final GenerationOptions genOptions) {
+ return toRelativePath(path, chunk.getBaseDir(), BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions);
+ }
+
+ /**
+ * Get relative file
+ *
+ * @param file a valid file (must be either belong to {@link com.intellij.openapi.vfs.LocalFileSystem} or to point to the root entry on
+ * {@link com.intellij.openapi.vfs.JarFileSystem}.
+ * @param baseDir base director for relative path calculation
+ * @param baseDirPropertyName property name for the base directory
+ * @param genOptions generation options
+ * @return a relative path
+ */
+ @Nullable
+ public static String toRelativePath(final VirtualFile file,
+ final File baseDir,
+ final String baseDirPropertyName,
+ final GenerationOptions genOptions) {
+ final String localPath = PathUtil.getLocalPath(file);
+ if (localPath == null) {
+ return null;
+ }
+ return toRelativePath(localPath, baseDir, baseDirPropertyName, genOptions);
+ }
+
+ public static String toRelativePath(String path,
+ File baseDir,
+ @NonNls final String baseDirPropertyName,
+ GenerationOptions genOptions) {
+ path = normalizePath(path);
+ if(path.length() == 0) {
+ return path;
+ }
+ final String substitutedPath = genOptions.subsitutePathWithMacros(path);
+ if (!substitutedPath.equals(path)) {
+ // path variable substitution has highest priority
+ return substitutedPath;
+ }
+ if (baseDir != null) {
+ File base;
+ try {
+ // use canonical paths in order to resolve symlinks
+ base = baseDir.getCanonicalFile();
+ }
+ catch (IOException e) {
+ base = baseDir;
+ }
+ final String relativepath = FileUtil.getRelativePath(base, new File(path));
+ if (relativepath != null) {
+ final String _relativePath = relativepath.replace(File.separatorChar, '/');
+ final String root = BuildProperties.propertyRef(baseDirPropertyName);
+ return ".".equals(_relativePath) ? root : root + "/" + _relativePath;
+ }
+ }
+ return substitutedPath;
+ }
+
+ /**
+ * Normalize path by ensuring that only "/" is used as file name separator.
+ *
+ * @param path the path to normalize
+ * @return the normalized path
+ */
+ public static String normalizePath(String path) {
+ return path.replace(File.separatorChar, '/');
+ }
+
+ public static String trimJarSeparator(final String path) {
+ return path.endsWith(JarFileSystem.JAR_SEPARATOR) ? path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()) : path;
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.java
new file mode 100644
index 0000000..40c143b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.java
@@ -0,0 +1,62 @@
+/*
+ * 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 java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 16, 2004
+ */
+public abstract class Generator {
+ private static int ourIndent = 0;
+ private static final int INDENT_SHIFT = 2;
+
+ public abstract void generate(PrintWriter out) throws IOException;
+
+ protected static void crlf(PrintWriter out) throws IOException {
+ out.println();
+ indent(out);
+ }
+
+ protected static void shiftIndent() {
+ ourIndent += INDENT_SHIFT;
+ }
+
+ protected static void unshiftIndent() {
+ ourIndent -= INDENT_SHIFT;
+ }
+
+ protected static void indent(PrintWriter out) throws IOException {
+ for (int idx = 0; idx < ourIndent; idx++) {
+ out.print(" ");
+ }
+ }
+
+ /**
+ * Write XML header
+ * @param out a writer
+ * @throws IOException in case of IO problem
+ */
+ protected static void writeXmlHeader(final PrintWriter out) throws IOException {
+ //noinspection HardCodedStringLiteral
+ out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ crlf(out);
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java
new file mode 100644
index 0000000..0665dd2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java
@@ -0,0 +1,134 @@
+/*
+ * 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.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * Module chunk consists of interdependent modules.
+ *
+ * @author Eugene Zhuravlev
+ * Date: Nov 19, 2004
+ */
+public class ModuleChunk {
+ /**
+ * Modules in the chunk
+ */
+ private final Module[] myModules;
+ /**
+ * A array of custom compilation providers.
+ */
+ private final ChunkCustomCompilerExtension[] myCustomCompilers;
+ /**
+ * The main module in the chunck (guessed by heuristic or selected by user)
+ */
+ private Module myMainModule;
+ /**
+ * Chucnk dependendencies
+ */
+ private ModuleChunk[] myDependentChunks;
+ private File myBaseDir = null;
+
+ public ModuleChunk(Module[] modules) {
+ myModules = modules;
+ Arrays.sort(myModules, new Comparator<Module>() {
+ public int compare(final Module o1, final Module o2) {
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+ });
+ myMainModule = myModules[0];
+ myCustomCompilers = ChunkCustomCompilerExtension.getCustomCompile(this);
+ }
+
+ public String getName() {
+ return myMainModule.getName();
+ }
+
+ /**
+ * @return an array of custom compilers for the module chunk
+ */
+ public ChunkCustomCompilerExtension[] getCustomCompilers() {
+ return myCustomCompilers;
+ }
+
+ public Module[] getModules() {
+ return myModules;
+ }
+
+ @Nullable
+ public String getOutputDirUrl() {
+ return CompilerModuleExtension.getInstance(myMainModule).getCompilerOutputUrl();
+ }
+
+ @Nullable
+ public String getTestsOutputDirUrl() {
+ return CompilerModuleExtension.getInstance(myMainModule).getCompilerOutputUrlForTests();
+ }
+
+ public boolean isJdkInherited() {
+ return ModuleRootManager.getInstance(myMainModule).isSdkInherited();
+ }
+
+ @Nullable
+ public Sdk getJdk() {
+ return ModuleRootManager.getInstance(myMainModule).getSdk();
+ }
+
+ public ModuleChunk[] getDependentChunks() {
+ return myDependentChunks;
+ }
+
+ public void setDependentChunks(ModuleChunk[] dependentChunks) {
+ myDependentChunks = dependentChunks;
+ }
+
+ public File getBaseDir() {
+ if (myBaseDir != null) {
+ return myBaseDir;
+ }
+ return new File(myMainModule.getModuleFilePath()).getParentFile();
+ }
+
+ public void setBaseDir(File baseDir) {
+ myBaseDir = baseDir;
+ }
+
+ public void setMainModule(Module module) {
+ myMainModule = module;
+ }
+
+ public Project getProject() {
+ return myMainModule.getProject();
+ }
+
+ public boolean contains(final Module module) {
+ for (Module chunkModule : myModules) {
+ if (chunkModule.equals(module)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.java
new file mode 100644
index 0000000..86c65d7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * @author nik
+ */
+public abstract class PropertyFileGenerator extends Generator {
+ /**
+ * Add property. Note that property name and value
+ * are automatically escaped when the property file
+ * is generated.
+ *
+ * @param name a property name
+ * @param value a property value
+ */
+ public abstract void addProperty(String name, String value);
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java b/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java
new file mode 100644
index 0000000..aa08438
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Tag extends CompositeGenerator {
+ public static final Tag[] EMPTY_ARRAY = new Tag[0];
+ private final String myTagName;
+ private final Pair[] myTagOptions;
+
+ public Tag(@NonNls String tagName, Pair... tagOptions) {
+ myTagName = tagName;
+ myTagOptions = tagOptions;
+ }
+
+ public void generate(PrintWriter out) throws IOException {
+ out.print("<");
+ out.print(myTagName);
+ if (myTagOptions != null && myTagOptions.length > 0) {
+ out.print(" ");
+ int generated = 0;
+ for (final Pair option : myTagOptions) {
+ if (option == null) {
+ continue;
+ }
+ if (generated > 0) {
+ out.print(" ");
+ }
+ out.print((String)option.getFirst());
+ out.print("=\"");
+ out.print(StringUtil.escapeXml((String)option.getSecond()));
+ out.print("\"");
+ generated += 1;
+ }
+ }
+ if (getGeneratorCount() > 0) {
+ out.print(">");
+ shiftIndent();
+ try {
+ super.generate(out);
+ }
+ finally {
+ unshiftIndent();
+ }
+ crlf(out);
+ out.print("</");
+ out.print(myTagName);
+ out.print(">");
+ }
+ else {
+ out.print("/>");
+ }
+ }
+
+ @Nullable
+ protected static Pair<String, String> pair(@NonNls String v1, @Nullable @NonNls String v2) {
+ if (v2 == null) {
+ return null;
+ }
+ return new Pair<String, String>(v1, v2);
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java
new file mode 100644
index 0000000..4768d5f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public class AntCall extends Tag{
+
+ public AntCall(final String target) {
+ super("antcall", new Pair[] {new Pair<String, String>("target", target)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java
new file mode 100644
index 0000000..3aa3eee
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 25, 2004
+ */
+public class AntProject extends Tag {
+ public AntProject(@NonNls String name, @NonNls String defaultTarget) {
+ //noinspection HardCodedStringLiteral
+ super("project", new Pair[]{new Pair<String, String>("name", name), new Pair<String, String>("default", defaultTarget)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java
new file mode 100644
index 0000000..d6098db
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Attribute extends Tag{
+ public Attribute(@NonNls String name, String value) {
+ //noinspection HardCodedStringLiteral
+ super("attribute", new Pair[] {Pair.create("name", name),Pair.create("value", value)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java
new file mode 100644
index 0000000..c95348b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java
@@ -0,0 +1,36 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 23, 2004
+ */
+public class Copy extends Tag {
+ public Copy(@NonNls String toDir) {
+ //noinspection HardCodedStringLiteral
+ super("copy", new Pair[] {new Pair<String, String>("todir", toDir)});
+ }
+ public Copy(@NonNls String file, @NonNls String toFile) {
+ //noinspection HardCodedStringLiteral
+ super("copy", new Pair[] {new Pair<String, String>("file", file), new Pair<String, String>("tofile", toFile)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java
new file mode 100644
index 0000000..2dfe0d3
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Delete extends Tag{
+ public Delete(@NonNls String dir) {
+ //noinspection HardCodedStringLiteral
+ super("delete", new Pair[] {Pair.create("dir", dir)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java
new file mode 100644
index 0000000..b4cba08
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java
@@ -0,0 +1,33 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class DirSet extends Tag{
+
+ public DirSet(@NonNls final String dir) {
+ //noinspection HardCodedStringLiteral
+ super("dirset", new Pair[] {new Pair<String, String>("dir", dir)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java
new file mode 100644
index 0000000..f833f58
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 25, 2004
+ */
+public class Dirname extends Tag{
+ public Dirname(@NonNls String property, @NonNls String file) {
+ //noinspection HardCodedStringLiteral
+ super("dirname", new Pair[] {new Pair<String, String>("property", property), new Pair<String, String>("file", file)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.java
new file mode 100644
index 0000000..42e7a6a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.java
@@ -0,0 +1,34 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Exclude extends Tag {
+
+ public Exclude(@NonNls final String name) {
+ //noinspection HardCodedStringLiteral
+ super("exclude", new Pair[] {new Pair<String, String>("name", name)});
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java
new file mode 100644
index 0000000..5db6e0d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class FileSet extends Tag{
+
+ public FileSet(@NonNls final String dir) {
+ super("fileset", pair("dir", dir));
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.java
new file mode 100644
index 0000000..2c6e23c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.java
@@ -0,0 +1,37 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 24, 2004
+ */
+public class Import extends Tag{
+ public Import(@NonNls String file, boolean optional) {
+ //noinspection HardCodedStringLiteral
+ super("import", new Pair[] {new Pair<String, String>("file", file), new Pair<String, String>("optional", optional? "true" : "false")});
+ }
+
+ public Import(@NonNls String file) {
+ //noinspection HardCodedStringLiteral
+ super("import", new Pair[] {new Pair<String, String>("file", file)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java
new file mode 100644
index 0000000..73352a2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Include extends Tag {
+
+ public Include(@NonNls final String name) {
+ super("include", pair("name", name));
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.java
new file mode 100644
index 0000000..423faa9
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.java
@@ -0,0 +1,34 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Jar extends Tag {
+ public Jar(@NonNls final String destFile, @NonNls String duplicate) {
+ this(destFile, duplicate, false);
+ }
+
+ public Jar(@NonNls final String destFile, @NonNls String duplicate, final boolean useManifestFromFileSets) {
+ super("jar", pair("destfile", destFile), pair("duplicate", duplicate), useManifestFromFileSets ? pair("filesetmanifest", "mergewithoutmain") : null);
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java
new file mode 100644
index 0000000..c64884e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java
@@ -0,0 +1,70 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.GenerationOptions;
+import com.intellij.compiler.ant.ModuleChunk;
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 16, 2004
+ */
+public class Javac extends Tag {
+
+ public Javac(GenerationOptions genOptions, ModuleChunk moduleChunk, final String outputDir) {
+ super(getTagName(genOptions, moduleChunk), getAttributes(genOptions, outputDir, moduleChunk));
+ }
+
+ private static String getTagName(GenerationOptions genOptions, ModuleChunk moduleChunk) {
+ if (moduleChunk.getCustomCompilers().length > 0) {
+ return "instrumentIdeaExtensions";
+ }
+ return genOptions.enableFormCompiler ? "javac2" : "javac";
+ }
+
+ private static Pair[] getAttributes(GenerationOptions genOptions, String outputDir, ModuleChunk moduleChunk) {
+ final List<Pair> pairs = new ArrayList<Pair>();
+ pairs.add(pair("destdir", outputDir));
+ if (moduleChunk.getCustomCompilers().length == 0) {
+ pairs.add(pair("debug", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_DEBUG_INFO)));
+ pairs.add(pair("nowarn", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_NO_WARNINGS)));
+ pairs.add(pair("memorymaximumsize", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_MAX_MEMORY)));
+ pairs.add(pair("fork", "true"));
+ if (genOptions.forceTargetJdk) {
+ pairs.add(pair("executable", getExecutable(moduleChunk.getName())));
+ }
+ }
+ return pairs.toArray(new Pair[pairs.size()]);
+ }
+
+ @Nullable
+ @NonNls
+ private static String getExecutable(String moduleName) {
+ if (moduleName == null) {
+ return null;
+ }
+ return BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkBinProperty(moduleName)) + "/javac";
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java
new file mode 100644
index 0000000..da0ac1c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.compiler.make.ManifestBuilder;
+import com.intellij.openapi.util.Pair;
+
+import java.util.jar.Attributes;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Manifest extends Tag{
+ public Manifest() {
+ super("manifest", new Pair[] {});
+ }
+
+ public void applyAttributes(final java.util.jar.Manifest manifest) {
+ ManifestBuilder.setGlobalAttributes(manifest.getMainAttributes());
+ final Attributes mainAttributes = manifest.getMainAttributes();
+
+ List<Object> keys = new ArrayList<Object>(mainAttributes.keySet());
+ Collections.sort(keys, new Comparator<Object>() {
+ public int compare(final Object o1, final Object o2) {
+ Attributes.Name name1 = (Attributes.Name)o1;
+ Attributes.Name name2 = (Attributes.Name)o2;
+ return name1.toString().compareTo(name2.toString());
+ }
+ });
+ for (final Object o : keys) {
+ Attributes.Name name = (Attributes.Name)o;
+ String value = (String)mainAttributes.get(name);
+ add(new Attribute(name.toString(), value));
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java
new file mode 100644
index 0000000..ef15e5c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 17, 2004
+ */
+public class Mkdir extends Tag {
+ public Mkdir(@NonNls String directory) {
+ //noinspection HardCodedStringLiteral
+ super("mkdir", new Pair[] {new Pair<String, String>("dir", directory)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java
new file mode 100644
index 0000000..19649e0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java
@@ -0,0 +1,36 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Param extends Tag {
+ public Param(@NonNls final String name, final String value) {
+ //noinspection HardCodedStringLiteral
+ super("param", new Pair[] {
+ new Pair<String, String>("name", name),
+ new Pair<String, String>("value", value)
+ });
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.java
new file mode 100644
index 0000000..925c187
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.java
@@ -0,0 +1,31 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Path extends Tag {
+
+ public Path(@NonNls final String id) {
+ super("path", pair("id", id));
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.java
new file mode 100644
index 0000000..f48c1a5
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.java
@@ -0,0 +1,34 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class PathElement extends Tag {
+
+ public PathElement(@NonNls String dir) {
+ //noinspection HardCodedStringLiteral
+ super("pathelement", pair("location", dir));
+ }
+
+}
+
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java
new file mode 100644
index 0000000..1f8d658
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java
@@ -0,0 +1,33 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class PathRef extends Tag{
+
+ public PathRef(@NonNls final String refid) {
+ super("path", new Pair[] {pair("refid", refid)});
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java
new file mode 100644
index 0000000..6a1d237
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java
@@ -0,0 +1,30 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class PatternSet extends Tag{
+ public PatternSet(@NonNls final String id) {
+ super("patternset", pair("id", id));
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java
new file mode 100644
index 0000000..1055016
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class PatternSetRef extends Tag{
+ public PatternSetRef(@NonNls final String refid) {
+ //noinspection HardCodedStringLiteral
+ super("patternset", new Pair[] {new Pair<String, String>("refid", refid)});
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java
new file mode 100644
index 0000000..f28d127
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java
@@ -0,0 +1,44 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Property extends Tag {
+
+ public Property(@NonNls final String name, final String value) {
+ //noinspection HardCodedStringLiteral
+ super("property", new Pair[] {
+ new Pair<String, String>("name", name),
+ new Pair<String, String>("value", value)
+ });
+ }
+
+ public Property(@NonNls final String filePath) {
+ //noinspection HardCodedStringLiteral
+ super("property", new Pair[] {
+ new Pair<String, String>("file", filePath),
+ });
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.java
new file mode 100644
index 0000000..26f35bd
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.java
@@ -0,0 +1,52 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class Target extends Tag{
+ public Target(@NonNls String name, @Nullable String depends, @Nullable String description, @Nullable String unlessCondition) {
+ super("target", getOptions(name, depends, description, unlessCondition));
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ private static Pair[] getOptions(@NonNls String name, @Nullable @NonNls String depends, @Nullable String description, @Nullable @NonNls String unlessCondition) {
+ final List<Pair> options = new ArrayList<Pair>();
+ options.add(new Pair<String, String>("name", name));
+ if (depends != null && depends.length() > 0) {
+ options.add(new Pair<String, String>("depends", depends));
+ }
+ if (description != null && description.length() > 0) {
+ options.add(new Pair<String, String>("description", description));
+ }
+ if (unlessCondition != null && unlessCondition.length() > 0) {
+ options.add(new Pair<String, String>("unless", unlessCondition));
+ }
+ return options.toArray(new Pair[options.size()]);
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java
new file mode 100644
index 0000000..8e3a4e7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2010 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+
+/**
+ * @author nik
+ */
+public class Unzip extends Tag {
+ public Unzip(String archivePath, String dest) {
+ super("unzip", pair("src", archivePath), pair("dest", dest));
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java
new file mode 100644
index 0000000..a79ee96
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java
@@ -0,0 +1,32 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+public class Zip extends Tag {
+ public Zip(@NonNls final String destFile) {
+ //noinspection HardCodedStringLiteral
+ super("zip", new Pair[] {Pair.create("destfile", destFile)});
+ }
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java
new file mode 100644
index 0000000..a11b951
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java
@@ -0,0 +1,68 @@
+/*
+ * 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.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Mar 19, 2004
+ */
+public class ZipFileSet extends Tag{
+ public static final ZipFileSet[] EMPTY_ARRAY = new ZipFileSet[0];
+
+ private ZipFileSet(@NonNls String tagName, Pair... tagOptions) {
+ super(tagName, tagOptions);
+ }
+
+ public ZipFileSet(@NonNls String fileOrDir, @NonNls final String relativePath, boolean isDir) {
+ super("zipfileset",
+ pair(isDir ? "dir" : "file", fileOrDir),
+ pair("prefix", prefix(isDir, relativePath)));
+ }
+
+ public static ZipFileSet createUnpackedSet(@NonNls String zipFilePath, @NotNull String relativePath, final boolean isDir) {
+ return new ZipFileSet("zipfileset",
+ pair("src", zipFilePath),
+ pair("prefix", prefix(isDir, relativePath)));
+ }
+
+ @Nullable
+ private static String prefix(final boolean isDir, final String relativePath) {
+ String path;
+ if (isDir) {
+ path = relativePath;
+ }
+ else {
+ final String parent = new File(relativePath).getParent();
+ path = parent == null ? "" : FileUtil.toSystemIndependentName(parent);
+ }
+ if (path != null) {
+ path = StringUtil.trimStart(path, "/");
+ }
+ return !StringUtil.isEmpty(path) ? path : null;
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java
new file mode 100644
index 0000000..cfcf337
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+
+/**
+ * A tag interface indicating that the compiler will instrument java classes.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface ClassInstrumentingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java
new file mode 100644
index 0000000..203facd
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+
+/**
+ * A tag interface indicating that the compiler will take Java classes and perform some activities on them.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface ClassPostProcessingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java
new file mode 100644
index 0000000..2639194
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.compiler;
+
+public class CompilationStatusAdapter implements CompilationStatusListener {
+ public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
+ }
+
+ public void fileGenerated(String outputRoot, String relativePath) {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java
new file mode 100644
index 0000000..0675098
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+import java.util.EventListener;
+
+/**
+ * A listener for compiler events.
+ *
+ * @see CompilerManager#addCompilationStatusListener(CompilationStatusListener)
+ */
+public interface CompilationStatusListener extends EventListener {
+ /**
+ * Invoked in a Swing dispatch thread after the compilation is finished.
+ *
+ * @param aborted true if compilatioin has been cancelled
+ * @param errors error count
+ * @param warnings warning count
+ * @param compileContext context for the finished compilation
+ */
+ void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext);
+
+ void fileGenerated(String outputRoot, String relativePath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java
new file mode 100644
index 0000000..0f93063
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java
@@ -0,0 +1,157 @@
+/*
+ * 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;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An interface allowing access and modification of the data associated with the current compile session.
+ */
+public interface CompileContext extends UserDataHolder {
+ /**
+ * Allows to add a message to be shown in Compiler message view.
+ * If correct url, line and column numbers are supplied, the navigation to the specified file is available from the view.
+ *
+ * @param category the category of a message (information, error, warning).
+ * @param message the text of the message.
+ * @param url a url to the file to which the message applies, null if not available.
+ * @param lineNum a line number, -1 if not available.
+ * @param columnNum a column number, -1 if not available.
+ */
+ void addMessage(CompilerMessageCategory category, String message, @Nullable String url, int lineNum, int columnNum);
+
+ /**
+ * Allows to add a message to be shown in Compiler message view, with a specified Navigatable
+ * that is used to navigate to the error location.
+ *
+ * @param category the category of a message (information, error, warning).
+ * @param message the text of the message.
+ * @param url a url to the file to which the message applies, null if not available.
+ * @param lineNum a line number, -1 if not available.
+ * @param columnNum a column number, -1 if not available.
+ * @param navigatable the navigatable pointing to the error location.
+ * @since 6.0
+ */
+ void addMessage(CompilerMessageCategory category, String message, @Nullable String url, int lineNum, int columnNum,
+ Navigatable navigatable);
+
+ /**
+ * Returns all messages of the specified category added during the current compile session.
+ *
+ * @param category the category for which messages are requested.
+ * @return all compiler messages of the specified category
+ */
+ CompilerMessage[] getMessages(CompilerMessageCategory category);
+
+ /**
+ * Returns the count of messages of the specified category added during the current compile session.
+ *
+ * @param category the category for which messages are requested.
+ * @return the number of messages of the specified category
+ */
+ int getMessageCount(CompilerMessageCategory category);
+
+ /**
+ * Returns the progress indicator of the compilation process.
+ *
+ * @return the progress indicator instance.
+ */
+ @NotNull
+ ProgressIndicator getProgressIndicator();
+
+ /**
+ * Returns the current compile scope.
+ *
+ * @return current compile scope
+ */
+ CompileScope getCompileScope();
+
+ /**
+ * Returns the compile scope which would be used if the entire project was rebuilt.
+ * {@link #getCompileScope()} may return the scope, that is more narrow than ProjectCompileScope.
+ *
+ * @return project-wide compile scope.
+ */
+ CompileScope getProjectCompileScope();
+
+ /**
+ * A compiler may call this method in order to request complete project rebuild.
+ * This may be necessary, for example, when compiler caches are corrupted.
+ */
+ void requestRebuildNextTime(String message);
+
+ /**
+ * Returns the module to which the specified file belongs. This method is aware of the file->module mapping
+ * for generated files.
+ *
+ * @param file the file to check.
+ * @return the module to which the file belongs
+ */
+ Module getModuleByFile(VirtualFile file);
+
+ /**
+ * Returns the source roots for the specified module.
+ *
+ * @return module's source roots as well as source roots for generated sources that are attributed to the module
+ */
+ VirtualFile[] getSourceRoots(Module module);
+
+ /**
+ * Returns the list of all output directories.
+ *
+ * @return a list of all configured output directories from all modules (including output directories for tests)
+ */
+ VirtualFile[] getAllOutputDirectories();
+
+ /**
+ * Returns the output directory for the specified module.
+ *
+ * @param module the module to check.
+ * @return the output directory for the module specified, null if corresponding VirtualFile is not valid or directory not specified
+ */
+ @Nullable
+ VirtualFile getModuleOutputDirectory(Module module);
+
+ /**
+ * Returns the test output directory for the specified module.
+ *
+ * @param module the module to check.
+ * @return the tests output directory the module specified, null if corresponding VirtualFile is not valid. If in Paths settings
+ * output directory for tests is not configured explicitly, but the output path is present, the output path will be returned.
+ */
+ @Nullable
+ VirtualFile getModuleOutputDirectoryForTests(Module module);
+
+ /**
+ * Checks if the compilation is incremental, i.e. triggered by one of "Make" actions.
+ *
+ * @return true if compilation is incremental.
+ */
+ boolean isMake();
+
+ boolean isRebuild();
+
+ Project getProject();
+
+ boolean isAnnotationProcessorsEnabled();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java
new file mode 100644
index 0000000..5e1c304
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Interface describing the current compilation scope.
+ * Only sources that belong to the scope are compiled.
+ *
+ * @see CompilerManager#compile(CompileScope, CompileStatusNotification)
+ */
+public interface CompileScope extends ExportableUserDataHolder {
+ CompileScope[] EMPTY_ARRAY = new CompileScope[0];
+ /**
+ * Returns the list of files within the scope.
+ *
+ * @param fileType the type of the files. Null should be passed if all available files are needed.
+ * @param inSourceOnly if true, files are searched only in directories within the scope that are marked as "sources" or "test sources" in module settings.
+ * Otherwise files are searched in all directories that belong to the scope.
+ * @return a list of files of given type that belong to this scope.
+ */
+ @NotNull
+ VirtualFile[] getFiles(@Nullable FileType fileType, boolean inSourceOnly);
+
+ /**
+ * Checks if the file with the specified URL belongs to the scope.
+ *
+ * @param url an VFS url. Note that actual file may not exist on the disk.
+ * @return true if the url specified belongs to the scope, false otherwise.
+ * Note: the method may be time-consuming.
+ */
+ boolean belongs(String url);
+
+ /**
+ * Returns the list of modules files in which belong to the scope.
+ *
+ * @return a list of modules this scope affects.
+ */
+ @NotNull
+ Module[] getAffectedModules();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java
new file mode 100644
index 0000000..9a8d7f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+/**
+ * A callback interface passed to ComplerManager methods. Provides notification similar to
+ * {@link CompilationStatusListener}.
+ *
+ * @see CompilerManager#compile(CompileScope, CompileStatusNotification)
+ */
+public interface CompileStatusNotification {
+ /**
+ * Invoked in a Swing dispatch thread after the compilation is finished.
+ *
+ * @param aborted true if compilation has been cancelled.
+ * @param errors error count
+ * @param warnings warning count
+ * @param compileContext context for the finished compilation
+ */
+ void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.java
new file mode 100644
index 0000000..e3bd1df
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+/**
+ * Describes a task to be executed before or after compilation.
+ *
+ * @see CompilerManager#addAfterTask(CompileTask)
+ * @see CompilerManager#addBeforeTask(CompileTask)
+ */
+public interface CompileTask {
+ /**
+ * Executes the task.
+ *
+ * @param context current compile context
+ * @return true if execution succeeded, false otherwise. If the task returns false, the compilation
+ * is aborted, and it's expected that the task adds a message defining the reason for the failure
+ * to the compile context.
+ */
+ boolean execute(CompileContext context);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java
new file mode 100644
index 0000000..77f77f4
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+/**
+ * Base interface for a custom compiler which participates in the IDEA build process.
+ *
+ * @see CompilerManager#addCompiler(Compiler)
+ * @see CompilerManager#removeCompiler(Compiler)
+ */
+public interface Compiler {
+ ExtensionPointName<Compiler> EP_NAME = ExtensionPointName.create("com.intellij.compiler");
+
+ /**
+ * Returns the description of the compiler. All registered compilers should have unique description.
+ *
+ * @return the description string.
+ */
+ @NotNull
+ String getDescription();
+
+ /**
+ * Called before compilation starts. If at least one of registered compilers returned false, compilation won't start.
+ *
+ * @param scope the scope on which the compilation is started.
+ * @return true if everything is ok, false otherwise
+ */
+ boolean validateConfiguration(CompileScope scope);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java
new file mode 100644
index 0000000..eac8c80
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Sep 9, 2005
+ */
+public class CompilerBundle {
+ private static Reference<ResourceBundle> ourBundle;
+
+ @NonNls private static final String BUNDLE = "messages.CompilerBundle";
+
+ private CompilerBundle() {
+ }
+
+ public static String jdkHomeNotFoundMessage(final Sdk jdk) {
+ return message("javac.error.jdk.home.missing", jdk.getName(), jdk.getHomePath());
+ }
+
+ public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
+ return CommonBundle.message(getBundle(), key, params);
+ }
+
+ private static ResourceBundle getBundle() {
+ ResourceBundle bundle = null;
+ if (ourBundle != null) bundle = ourBundle.get();
+ if (bundle == null) {
+ bundle = ResourceBundle.getBundle(BUNDLE);
+ ourBundle = new SoftReference<ResourceBundle>(bundle);
+ }
+ return bundle;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java
new file mode 100644
index 0000000..8147e0b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public interface CompilerFactory {
+ ExtensionPointName<CompilerFactory> EP_NAME = ExtensionPointName.create("com.intellij.compilerFactory");
+
+ Compiler[] createCompilers(@NotNull CompilerManager compilerManager);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java
new file mode 100644
index 0000000..c7a9f7f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Jul 9, 2009
+ */
+public interface CompilerFilter {
+ CompilerFilter ALL = new CompilerFilter() {
+ public boolean acceptCompiler(Compiler compiler) {
+ return true;
+ }
+ };
+ /**
+ * @param compiler
+ * @return true if this compiler can be executed
+ */
+ boolean acceptCompiler(Compiler compiler);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java
new file mode 100644
index 0000000..4456665
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java
@@ -0,0 +1,294 @@
+/*
+ * 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;
+
+import com.intellij.notification.NotificationGroup;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+
+/**
+ * A "root" class in compiler subsystem - allows one to register a custom compiler or a compilation task, register/unregister a compilation listener
+ * and invoke various types of compilations (make, compile, rebuild)
+ */
+public abstract class CompilerManager {
+ public static final Key<Key> CONTENT_ID_KEY = Key.create("COMPILATION_CONTENT_ID_CUSTOM_KEY");
+ public static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.logOnlyGroup("Compiler");
+
+ /**
+ * Returns the compiler manager instance for the specified project.
+ *
+ * @param project the project for which the manager is requested.
+ * @return the manager instance.
+ */
+ public static CompilerManager getInstance(Project project) {
+ return ServiceManager.getService(project, CompilerManager.class);
+ }
+
+ public abstract boolean isCompilationActive();
+
+ /**
+ * Registers a custom compiler.
+ *
+ * @param compiler the compiler to register.
+ */
+ public abstract void addCompiler(@NotNull Compiler compiler);
+
+ /**
+ * Registers a custom translating compiler. Input and output filetype sets allow compiler manager
+ * to sort translating compilers so that output of one compiler will be used as input for another one
+ *
+ * @param compiler compiler implementation
+ * @param inputTypes a set of filetypes that compiler accepts as input
+ * @param outputTypes a set of filetypes that compiler can generate
+ */
+ public abstract void addTranslatingCompiler(@NotNull TranslatingCompiler compiler, Set<FileType> inputTypes, Set<FileType> outputTypes);
+
+ @NotNull
+ public abstract Set<FileType> getRegisteredInputTypes(@NotNull TranslatingCompiler compiler);
+
+ @NotNull
+ public abstract Set<FileType> getRegisteredOutputTypes(@NotNull TranslatingCompiler compiler);
+
+ /**
+ * Unregisters a custom compiler.
+ *
+ * @param compiler the compiler to unregister.
+ */
+ public abstract void removeCompiler(@NotNull Compiler compiler);
+
+ /**
+ * Returns all registered compilers of the specified class.
+ *
+ * @param compilerClass the class for which the compilers should be returned.
+ * @return all registered compilers of the specified class.
+ */
+ @NotNull
+ public abstract <T extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass);
+
+ /**
+ * Returns all registered compilers of the specified class that the filter accepts
+ *
+ * @param compilerClass the class for which the compilers should be returned.
+ * @param filter additional filter to restrict compiler instances
+ * @return all registered compilers of the specified class.
+ */
+ @NotNull
+ public abstract <T extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass, CompilerFilter filter);
+
+ /**
+ * Registers the type as a compilable type so that Compile action will be enabled on files of this type.
+ *
+ * @param type the type for which the Compile action is enabled.
+ */
+ public abstract void addCompilableFileType(@NotNull FileType type);
+
+ /**
+ * Unregisters the type as a compilable type so that Compile action will be disabled on files of this type.
+ *
+ * @param type the type for which the Compile action is disabled.
+ */
+ public abstract void removeCompilableFileType(@NotNull FileType type);
+
+ /**
+ * Checks if files of the specified type can be compiled by one of registered compilers.
+ * If the compiler can process files of certain type, it should register this file type within
+ * the CompilerManager as a compilable file type.
+ *
+ * @param type the type to check.
+ * @return true if the file type is compilable, false otherwise.
+ * @see com.intellij.openapi.compiler.CompilerManager#addCompilableFileType(FileType)
+ */
+ public abstract boolean isCompilableFileType(@NotNull FileType type);
+
+ /**
+ * Registers a compiler task that will be executed before the compilation.
+ *
+ * @param task the task to register.
+ */
+ public abstract void addBeforeTask(@NotNull CompileTask task);
+
+ /**
+ * Registers a compiler task that will be executed after the compilation.
+ *
+ * @param task the task to register.
+ */
+ public abstract void addAfterTask(@NotNull CompileTask task);
+
+ /**
+ * Returns the list of all tasks to be executed before compilation.
+ *
+ * @return all tasks to be executed before compilation.
+ */
+ @NotNull
+ public abstract CompileTask[] getBeforeTasks();
+
+ /**
+ * Returns the list of all tasks to be executed after compilation.
+ *
+ * @return all tasks to be executed after compilation.
+ */
+ @NotNull
+ public abstract CompileTask[] getAfterTasks();
+
+ /**
+ * Compile a set of files.
+ *
+ * @param files a list of files to compile. If a VirtualFile is a directory, all containing files are processed.
+ * Compiler excludes are not honored.
+ * @param callback a notification callback, or null if no notifications needed.
+ */
+ public abstract void compile(@NotNull VirtualFile[] files, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all sources (including test sources) from the module. Compiler excludes are not honored.
+ *
+ * @param module a module which sources are to be compiled
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void compile(@NotNull Module module, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all files from the scope given. Compiler excludes are not honored.
+ *
+ * @param scope a scope to be compiled
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void compile(@NotNull CompileScope scope, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all modified files and all files that depend on them all over the project.
+ * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored.
+ *
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void make(@Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all modified files and all files that depend on them from the given module and all modules this module depends on recursively.
+ * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored.
+ *
+ * @param module a module which sources are to be compiled.
+ * @param callback a notification callback, or null if no notifications needed.
+ */
+ public abstract void make(@NotNull Module module, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all modified files and all files that depend on them from the modules and all modules these modules depend on recursively.
+ * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project.
+ *
+ * @param project a project modules belong to
+ * @param modules modules to compile
+ * @param callback a notification callback, or null if no notifications needed.
+ */
+ public abstract void make(@NotNull Project project, @NotNull Module[] modules, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all modified files and all files that depend on them from the scope given.
+ * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project
+ *
+ * @param scope a scope to be compiled
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void make(@NotNull CompileScope scope, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Compile all modified files and all files that depend on them from the scope given.
+ * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project
+ *
+ * @param scope a scope to be compiled
+ * @param filter filter allowing choose what compilers should be executed
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void make(@NotNull CompileScope scope, CompilerFilter filter, @Nullable CompileStatusNotification callback);
+
+ /**
+ * Checks if compile scope given is up-to-date
+ * @param scope
+ * @return true if make on the scope specified wouldn't do anything or false if something is to be compiled or deleted
+ */
+ public abstract boolean isUpToDate(@NotNull CompileScope scope);
+ /**
+ * Rebuild the whole project from scratch. Compiler excludes are honored.
+ *
+ * @param callback a notification callback, or null if no notifications needed
+ */
+ public abstract void rebuild(@Nullable CompileStatusNotification callback);
+
+ /**
+ * Execute a custom compile task.
+ *
+ * @param task the task to execute.
+ * @param scope compile scope for which the task is executed.
+ * @param contentName the name of a tab in message view where the execution results will be displayed.
+ * @param onTaskFinished a runnable to be executed when the task finishes, null if nothing should be executed.
+ */
+ public abstract void executeTask(@NotNull CompileTask task, @NotNull CompileScope scope, String contentName,
+ @Nullable Runnable onTaskFinished);
+
+ /**
+ * Register a listener to track compilation events.
+ *
+ * @param listener the listener to be registered.
+ */
+ public abstract void addCompilationStatusListener(@NotNull CompilationStatusListener listener);
+ public abstract void addCompilationStatusListener(@NotNull CompilationStatusListener listener, @NotNull Disposable parentDisposable);
+
+ /**
+ * Unregister a compilation listener.
+ *
+ * @param listener the listener to be unregistered.
+ */
+ public abstract void removeCompilationStatusListener(@NotNull CompilationStatusListener listener);
+
+ /**
+ * Checks if the specified file is excluded from compilation.
+ *
+ * @param file the file to check.
+ * @return true if the file is excluded from compilation, false otherwise
+ */
+ public abstract boolean isExcludedFromCompilation(@NotNull VirtualFile file);
+
+ @NotNull
+ public abstract OutputToSourceMapping getJavaCompilerOutputMapping();
+
+ /*
+ * Convetience methods for creating frequently-used compile scopes
+ */
+ @NotNull
+ public abstract CompileScope createFilesCompileScope(@NotNull VirtualFile[] files);
+ @NotNull
+ public abstract CompileScope createModuleCompileScope(@NotNull Module module, final boolean includeDependentModules);
+ @NotNull
+ public abstract CompileScope createModulesCompileScope(@NotNull Module[] modules, final boolean includeDependentModules);
+ @NotNull
+ public abstract CompileScope createModuleGroupCompileScope(@NotNull Project project, @NotNull Module[] modules, final boolean includeDependentModules);
+ @NotNull
+ public abstract CompileScope createProjectCompileScope(@NotNull Project project);
+
+ public abstract void setValidationEnabled(ModuleType moduleType, boolean enabled);
+
+ public abstract boolean isValidationEnabled(Module moduleType);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java
new file mode 100644
index 0000000..3afd6a6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Describes a single compiler message that is shown in compiler message view.
+ *
+ * @see CompileContext#addMessage(CompilerMessageCategory, String, String, int, int)
+ */
+public interface CompilerMessage {
+ /**
+ * An empty array of compiler messages which can be reused to avoid unnecessary allocations.
+ */
+ CompilerMessage[] EMPTY_ARRAY = new CompilerMessage[0];
+
+ /**
+ * Returns the category of the message.
+ *
+ * @return a category this message belongs to (error, warning, information).
+ */
+ CompilerMessageCategory getCategory();
+
+ /**
+ * Returs the message text.
+ *
+ * @return message text
+ */
+ String getMessage();
+
+ /**
+ * Returns the navigatable object allowing to navigate to the message source.
+ *
+ * @return the instance.
+ */
+ @Nullable
+ Navigatable getNavigatable();
+
+ /**
+ * Returns the file to which the message applies.
+ *
+ * @return the file to which the message applies.
+ */
+ VirtualFile getVirtualFile();
+
+ /**
+ * Returns the location prefix prepended to message while exporting compilation results to text.
+ *
+ * @return location prefix prepended to message while exporting compilation results to text.
+ */
+ String getExportTextPrefix();
+
+ /**
+ * Returns the location prefix prepended to message while exporting compilation results to text.
+ *
+ * @return location prefix prepended to message while rendering compilation results in UI.
+ */
+ String getRenderTextPrefix();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java
new file mode 100644
index 0000000..708184f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+/**
+ * A set of constants describing possible message categories.
+ *
+ * @see CompilerMessage#getCategory()
+ * @see CompileContext#addMessage(CompilerMessageCategory, String, String, int, int)
+ */
+public enum CompilerMessageCategory {
+ ERROR {
+ public String toString() {
+ return CompilerBundle.message("message.category.error");
+ }
+ public String getPresentableText() {
+ return toString();
+ }
+ },
+ WARNING {
+ public String toString() {
+ return CompilerBundle.message("message.category.warning");
+ }
+ public String getPresentableText() {
+ return toString();
+ }
+ },
+ INFORMATION {
+ public String toString() {
+ return CompilerBundle.message("message.category.information");
+ }
+ public String getPresentableText() {
+ return toString();
+ }
+ },
+ STATISTICS {
+ public String toString() {
+ return CompilerBundle.message("message.category.statistics");
+ }
+ public String getPresentableText() {
+ return toString();
+ }
+ };
+
+ public abstract String getPresentableText();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java
new file mode 100644
index 0000000..f02820f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.compiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Locale;
+
+/**
+ * A set of utility methods for working with paths
+ */
+public class CompilerPaths {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.compiler.CompilerPaths");
+ private static volatile String ourSystemPath;
+ private static final Comparator<String> URLS_COMPARATOR = new Comparator<String>() {
+ public int compare(String o1, String o2) {
+ return o1.compareTo(o2);
+ }
+ };
+ private static final String DEFAULT_GENERATED_DIR_NAME = "generated";
+
+ /**
+ * Returns a directory
+ * @param project
+ * @param compiler
+ * @return a directory where compiler may generate files. All generated files are not deleted when the application exits
+ */
+ public static File getGeneratedDataDirectory(Project project, Compiler compiler) {
+ //noinspection HardCodedStringLiteral
+ return new File(getGeneratedDataDirectory(project), compiler.getDescription().replaceAll("\\s+", "_"));
+ }
+
+ /**
+ * @param project
+ * @return a root directory where generated files for various compilers are stored
+ */
+ public static File getGeneratedDataDirectory(Project project) {
+ //noinspection HardCodedStringLiteral
+ return new File(getCompilerSystemDirectory(project), ".generated");
+ }
+
+ /**
+ * @param project
+ * @return a root directory where compiler caches for the given project are stored
+ */
+ public static File getCacheStoreDirectory(final Project project) {
+ //noinspection HardCodedStringLiteral
+ return new File(getCompilerSystemDirectory(project), ".caches");
+ }
+
+ public static File getCacheStoreDirectory(String compilerProjectDirName) {
+ //noinspection HardCodedStringLiteral
+ return new File(getCompilerSystemDirectory(compilerProjectDirName), ".caches");
+ }
+
+ public static File getRebuildMarkerFile(Project project) {
+ return new File(getCompilerSystemDirectory(project), "rebuild_required");
+ }
+
+ /**
+ * @param project
+ * @return a directory under IDEA "system" directory where all files related to compiler subsystem are stored (such as compiler caches or generated files)
+ */
+ public static File getCompilerSystemDirectory(Project project) {
+ return getCompilerSystemDirectory(getCompilerSystemDirectoryName(project));
+ }
+
+ public static File getCompilerSystemDirectory(String compilerProjectDirName) {
+ return new File(getCompilerSystemDirectory(), compilerProjectDirName);
+ }
+
+ public static String getCompilerSystemDirectoryName(Project project) {
+ return getPresentableName(project) + "." + project.getLocationHash();
+ }
+
+ @Nullable
+ private static String getPresentableName(final Project project) {
+ if (project.isDefault()) {
+ return project.getName();
+ }
+
+ String location = project.getPresentableUrl();
+ if (location == null) {
+ return null;
+ }
+
+ String projectName = FileUtil.toSystemIndependentName(location);
+ if (projectName.endsWith("/")) {
+ projectName = projectName.substring(0, projectName.length() - 1);
+ }
+
+ final int lastSlash = projectName.lastIndexOf('/');
+ if (lastSlash >= 0 && lastSlash + 1 < projectName.length()) {
+ projectName = projectName.substring(lastSlash + 1);
+ }
+
+ if (StringUtil.endsWithIgnoreCase(projectName, ProjectFileType.DOT_DEFAULT_EXTENSION)) {
+ projectName = projectName.substring(0, projectName.length() - ProjectFileType.DOT_DEFAULT_EXTENSION.length());
+ }
+
+ projectName = projectName.toLowerCase(Locale.US).replace(':', '_'); // replace ':' from windows drive names
+ return projectName;
+ }
+
+ public static File getCompilerSystemDirectory() {
+ //noinspection HardCodedStringLiteral
+ final String systemPath = ourSystemPath != null? ourSystemPath : (ourSystemPath = PathUtil.getCanonicalPath(PathManager.getSystemPath()));
+ return new File(systemPath, "compiler");
+ }
+
+ /**
+ * @param module
+ * @param forTestClasses true if directory for test sources, false - for sources.
+ * @return a directory to which the sources (or test sources depending on the second partameter) should be compiled.
+ * Null is returned if output directory is not specified or is not valid
+ */
+ @Nullable
+ public static VirtualFile getModuleOutputDirectory(final Module module, boolean forTestClasses) {
+ final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+ VirtualFile outPath;
+ if (forTestClasses) {
+ final VirtualFile path = compilerModuleExtension.getCompilerOutputPathForTests();
+ if (path != null) {
+ outPath = path;
+ }
+ else {
+ outPath = compilerModuleExtension.getCompilerOutputPath();
+ }
+ }
+ else {
+ outPath = compilerModuleExtension.getCompilerOutputPath();
+ }
+ if (outPath == null) {
+ return null;
+ }
+ if (!outPath.isValid()) {
+ LOG.info("Requested output path for module " + module.getName() + " is not valid");
+ return null;
+ }
+ return outPath;
+ }
+
+ /**
+ * The same as {@link #getModuleOutputDirectory} but returns String.
+ * The method still returns a non-null value if the output path is specified in Settings but does not exist on disk.
+ */
+ @Nullable
+ public static String getModuleOutputPath(final Module module, boolean forTestClasses) {
+ final String outPathUrl;
+ final Application application = ApplicationManager.getApplication();
+ final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+ if (forTestClasses) {
+ if (application.isDispatchThread()) {
+ final String url = extension.getCompilerOutputUrlForTests();
+ outPathUrl = url != null ? url : extension.getCompilerOutputUrl();
+ }
+ else {
+ outPathUrl = application.runReadAction(new Computable<String>() {
+ public String compute() {
+ final String url = extension.getCompilerOutputUrlForTests();
+ return url != null ? url : extension.getCompilerOutputUrl();
+ }
+ });
+ }
+ }
+ else { // for ordinary classes
+ if (application.isDispatchThread()) {
+ outPathUrl = extension.getCompilerOutputUrl();
+ }
+ else {
+ outPathUrl = application.runReadAction(new Computable<String>() {
+ public String compute() {
+ return extension.getCompilerOutputUrl();
+ }
+ });
+ }
+ }
+ return outPathUrl != null? VirtualFileManager.extractPath(outPathUrl) : null;
+ }
+
+ @Nullable
+ public static String getAnnotationProcessorsGenerationPath(Module module) {
+ final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(module.getProject()).getAnnotationProcessingConfiguration(module);
+ final String sourceDirName = config.getGeneratedSourcesDirectoryName(false);
+ if (config.isOutputRelativeToContentRoot()) {
+ final String[] roots = ModuleRootManager.getInstance(module).getContentRootUrls();
+ if (roots.length == 0) {
+ return null;
+ }
+ if (roots.length > 1) {
+ Arrays.sort(roots, URLS_COMPARATOR);
+ }
+ return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(roots[0]): VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName;
+ }
+
+
+ final String path = getModuleOutputPath(module, false);
+ if (path == null) {
+ return null;
+ }
+ return StringUtil.isEmpty(sourceDirName)? path : path + "/" + sourceDirName;
+ }
+
+ @NonNls
+ public static String getGenerationOutputPath(IntermediateOutputCompiler compiler, Module module, final boolean forTestSources) {
+ final String generatedCompilerDirectoryPath = getGeneratedDataDirectory(module.getProject(), compiler).getPath();
+ //noinspection HardCodedStringLiteral
+ final String moduleDir = module.getName().replaceAll("\\s+", "_") + "." + Integer.toHexString(module.getModuleFilePath().hashCode());
+ return generatedCompilerDirectoryPath.replace(File.separatorChar, '/') + "/" + moduleDir + "/" + (forTestSources? "test" : "production");
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java
new file mode 100644
index 0000000..a3b8c46
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import com.intellij.util.messages.Topic;
+
+/**
+ * @author yole
+ */
+public class CompilerTopics {
+ public static final Topic<CompilationStatusListener> COMPILATION_STATUS = new Topic<CompilationStatusListener>("compilation status", CompilationStatusListener.class);
+
+ private CompilerTopics() {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java
new file mode 100644
index 0000000..7d80c21
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.io.IOUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Compiler which copies the compiled files to a different directory.
+ */
+public abstract class CopyingCompiler implements PackagingCompiler{
+ public abstract VirtualFile[] getFilesToCopy(CompileContext context);
+ public abstract String getDestinationPath(VirtualFile sourceFile);
+
+ public final void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state) {
+ if (state != null) {
+ final String destinationPath = ((DestinationFileInfo)state).getDestinationPath();
+ new File(destinationPath).delete();
+ }
+ }
+
+ @NotNull
+ public final ProcessingItem[] getProcessingItems(final CompileContext context) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<ProcessingItem[]>() {
+ public ProcessingItem[] compute() {
+ final VirtualFile[] filesToCopy = getFilesToCopy(context);
+ final ProcessingItem[] items = new ProcessingItem[filesToCopy.length];
+ for (int idx = 0; idx < filesToCopy.length; idx++) {
+ final VirtualFile file = filesToCopy[idx];
+ items[idx] = new CopyItem(file, getDestinationPath(file));
+ }
+ return items;
+ }
+ });
+ }
+
+ public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) {
+ final List<ProcessingItem> successfullyProcessed = new ArrayList<ProcessingItem>(items.length);
+ for (ProcessingItem item : items) {
+ final CopyItem copyItem = (CopyItem)item;
+ final String fromPath = copyItem.getSourcePath();
+ final String toPath = copyItem.getDestinationPath();
+ try {
+ FileUtil.copy(new File(fromPath), new File(toPath));
+ successfullyProcessed.add(copyItem);
+ }
+ catch (IOException e) {
+ context.addMessage(
+ CompilerMessageCategory.ERROR,
+ CompilerBundle.message("error.copying", fromPath, toPath, e.getMessage()),
+ null, -1, -1
+ );
+ }
+ }
+ return successfullyProcessed.toArray(new ProcessingItem[successfullyProcessed.size()]);
+ }
+
+ @NotNull
+ public String getDescription() {
+ return CompilerBundle.message("file.copying.compiler.description");
+ }
+
+ public boolean validateConfiguration(CompileScope scope) {
+ return true;
+ }
+
+ public ValidityState createValidityState(DataInput in) throws IOException {
+ return new DestinationFileInfo(IOUtil.readString(in), true);
+ }
+
+ private static class CopyItem implements FileProcessingCompiler.ProcessingItem {
+ private final VirtualFile myFile;
+ private final DestinationFileInfo myInfo;
+ private final String mySourcePath;
+
+ public CopyItem(VirtualFile file, String destinationPath) {
+ myFile = file;
+ mySourcePath = file.getPath().replace('/', File.separatorChar);
+ myInfo = new DestinationFileInfo(destinationPath, new File(destinationPath).exists());
+ }
+
+ @NotNull
+ public VirtualFile getFile() {
+ return myFile;
+ }
+
+ public ValidityState getValidityState() {
+ return myInfo;
+ }
+
+ public String getSourcePath() {
+ return mySourcePath;
+ }
+
+ public String getDestinationPath() {
+ return myInfo.getDestinationPath();
+ }
+ }
+
+ private static class DestinationFileInfo implements ValidityState {
+ private final String destinationPath;
+ private final boolean myFileExists;
+
+ public DestinationFileInfo(String destinationPath, boolean fileExists) {
+ this.destinationPath = destinationPath;
+ myFileExists = fileExists;
+ }
+
+ public boolean equalsTo(ValidityState otherState) {
+ if (!(otherState instanceof DestinationFileInfo)) {
+ return false;
+ }
+ DestinationFileInfo destinationFileInfo = (DestinationFileInfo)otherState;
+ return (myFileExists == destinationFileInfo.myFileExists) && (destinationPath.equals(destinationFileInfo.destinationPath));
+ }
+
+ public void save(DataOutput out) throws IOException {
+ IOUtil.writeString(destinationPath, out);
+ }
+
+ public String getDestinationPath() {
+ return destinationPath;
+ }
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java
new file mode 100644
index 0000000..85b0156
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java
@@ -0,0 +1,121 @@
+/*
+ * 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;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class DummyCompileContext implements CompileContext {
+ protected DummyCompileContext() {
+ }
+
+ private static final DummyCompileContext OUR_INSTANCE = new DummyCompileContext();
+
+ public static DummyCompileContext getInstance() {
+ return OUR_INSTANCE;
+ }
+
+ public Project getProject() {
+ return null;
+ }
+
+ public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
+ }
+
+
+ public void addMessage(CompilerMessageCategory category,
+ String message,
+ @Nullable String url,
+ int lineNum,
+ int columnNum,
+ Navigatable navigatable) {
+ }
+
+ public CompilerMessage[] getMessages(CompilerMessageCategory category) {
+ return CompilerMessage.EMPTY_ARRAY;
+ }
+
+ public int getMessageCount(CompilerMessageCategory category) {
+ return 0;
+ }
+
+ public ProgressIndicator getProgressIndicator() {
+ return null;
+ }
+
+ public CompileScope getCompileScope() {
+ return null;
+ }
+
+ public CompileScope getProjectCompileScope() {
+ return null;
+ }
+
+ public void requestRebuildNextTime(String message) {
+ }
+
+ public Module getModuleByFile(VirtualFile file) {
+ return null;
+ }
+
+ public boolean isAnnotationProcessorsEnabled() {
+ return false;
+ }
+
+ public VirtualFile[] getSourceRoots(Module module) {
+ return VirtualFile.EMPTY_ARRAY;
+ }
+
+ public VirtualFile[] getAllOutputDirectories() {
+ return VirtualFile.EMPTY_ARRAY;
+ }
+
+ public VirtualFile getModuleOutputDirectory(final Module module) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
+ public VirtualFile compute() {
+ return CompilerModuleExtension.getInstance(module).getCompilerOutputPath();
+ }
+ });
+ }
+
+ public VirtualFile getModuleOutputDirectoryForTests(Module module) {
+ return null;
+ }
+
+ public <T> T getUserData(@NotNull Key<T> key) {
+ return null;
+ }
+
+ public <T> void putUserData(@NotNull Key<T> key, T value) {
+ }
+
+ public boolean isMake() {
+ return false; // stub implementation
+ }
+
+ public boolean isRebuild() {
+ return false;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java
new file mode 100644
index 0000000..fdcf405
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2010 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;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Empty validity state for force recompilation
+ *
+ * @author Konstantin Bulenkov
+ */
+public final class EmptyValidityState implements ValidityState {
+ /**
+ * In most cases this method returns false to force recompile
+ *
+ * @param otherState the state to compare with.
+ * @return true if and only if otherState == this
+ */
+ public boolean equalsTo(ValidityState otherState) {
+ return otherState == this;
+ }
+
+ /**
+ * Do nothing here
+ */
+ public void save(DataOutput dataOutput) throws IOException {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java
new file mode 100644
index 0000000..1dda010
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.compiler;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolder;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: 2/21/12
+ */
+public interface ExportableUserDataHolder extends UserDataHolder{
+
+ @NotNull
+ Map<Key, Object> exportUserData();
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java
new file mode 100644
index 0000000..4f4e20d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.compiler;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolderBase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class ExportableUserDataHolderBase extends UserDataHolderBase implements ExportableUserDataHolder{
+ private final Set<Key> myKeys = Collections.synchronizedSet(new HashSet<Key>());
+
+ @NotNull
+ public final Map<Key, Object> exportUserData() {
+ final Map<Key, Object> result = new HashMap<Key, Object>();
+ synchronized (myKeys) {
+ for (Key<?> k : myKeys) {
+ final Object data = getUserData(k);
+ if (data != null) {
+ result.put(k, data);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public final <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
+ if (value != null) {
+ myKeys.add(key);
+ }
+ else {
+ myKeys.remove(key);
+ }
+ super.putUserData(key, value);
+ }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java
new file mode 100644
index 0000000..733514c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A base interface describing shared functionality for various types of file processing compilers.
+ * Actual compiler implementation should implement one of these:
+ * {@link ClassInstrumentingCompiler}, {@link ClassPostProcessingCompiler},
+ * {@link SourceInstrumentingCompiler}.
+ */
+public interface FileProcessingCompiler extends Compiler, ValidityStateFactory {
+ /**
+ * Describes a processing unit for this compiler - a virtual file with associated state.
+ */
+ interface ProcessingItem {
+ /**
+ * A utility constant used to return empty arrays of ProcessingItem objects
+ */
+ ProcessingItem[] EMPTY_ARRAY = new ProcessingItem[0];
+
+ /**
+ * Returns the file to be processed.
+ *
+ * @return a file to be processed; cannot be null
+ */
+ @NotNull
+ VirtualFile getFile();
+
+ /**
+ * @return an object describing dependencies of the instrumented file (can be null).
+ * For example, if the file "A" should be processed whenever file "B" or file "C" is changed, the ValidityState object can
+ * be composed of a pair [timestamp("B"), timestamp("C")]. Thus, whenever a timestamp of any of these files is changed,
+ * the current ValidityState won't be equal to the stored ValidityState and the item will be picked up by the make for recompilation.
+ */
+ @Nullable
+ ValidityState getValidityState();
+ }
+
+ /**
+ * Returns the items which will be processed in the current compile operation.
+ * The method is called before the call to {@link #process} method
+ *
+ * @param context the current compilation context.
+ * @return a non-null array of all items that potentially can be processed at the moment of method call. Even if
+ * the file is not changed, it should be returned if it _can_ be processed by the compiler implementing the interface.
+ */
+ @NotNull
+ ProcessingItem[] getProcessingItems(CompileContext context);
+
+ /**
+ * Compiles the specified items.
+ *
+ * @param context the current compilation context.
+ * @param items items to be processed, selected by make subsystem. The items are selected from the list returned by the
+ * {@link #getProcessingItems} method.
+ * @return successfully processed items.
+ */
+ ProcessingItem[] process(CompileContext context, ProcessingItem[] items);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java
new file mode 100644
index 0000000..962bcb2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * A base interface for all compilers that generate new files. The generated files may be processed by other compilers.
+ * Actual implementation should implement one of its subinterfaces. Currently only {@link SourceGeneratingCompiler} is available.
+ */
+public interface GeneratingCompiler extends Compiler, ValidityStateFactory, IntermediateOutputCompiler {
+ /**
+ * Represents a single item generated by the compiler.
+ */
+ interface GenerationItem {
+ /**
+ * Returns the path of the generated file.
+ *
+ * @return path of a generated file, relative to output directory.
+ */
+ String getPath();
+
+ /**
+ * Returns the object describing dependencies of the generated file.
+ *
+ * @return a serializable object describing dependencies of the generated file.
+ */
+ ValidityState getValidityState();
+
+ /**
+ * Returns the module to which the generated item belongs. This affects the sequence
+ * of compiling the generated files.
+ *
+ * @return the module to which the generated item belongs.
+ */
+ Module getModule();
+
+ /**
+ * @return true if the generated item is supposed to be located in test sources, false otherwise
+ */
+ boolean isTestSource();
+ }
+
+ /**
+ * Returns the list of all the files this compiler can generate.
+ *
+ * @param context the current compile context.
+ * @return items describing all the files this compiler can generate.
+ */
+ GenerationItem[] getGenerationItems(CompileContext context);
+
+ /**
+ * Invokes the generation process.
+ *
+ * @param context the current compile context.
+ * @param items what items to generate.
+ * @param outputRootDirectory the root directory under which the items are generated (the paths
+ * in {@link GenerationItem#getPath()} are relative to that directory).
+ * All files generated by the compiler must be placed in that directory or
+ * its subdirectories, otherwise they will not be compiled properly on
+ * subsequent build steps.
+ * @return successfully generated items
+ */
+ GenerationItem[] generate(CompileContext context, GenerationItem[] items, VirtualFile outputRootDirectory);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.java
new file mode 100644
index 0000000..a289393
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.java
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+/**
+ * A tag interface denoting that compiler's output should go into 'intermediate' directory
+ * and can be used as input to another compiler
+ */
+public interface IntermediateOutputCompiler extends Compiler{
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java
new file mode 100644
index 0000000..27a3975
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * This compiler is called right before the java sources compiler.
+ */
+public interface JavaSourceTransformingCompiler extends Compiler {
+
+ /**
+ * Checks if the file can be transformed by the compiler.
+ *
+ * @param file an original file that is about to be compiled with java compiler
+ * @return true if compiler would like to transform the file, false otherwise.
+ * If true is returned, a copy of original file will be made and {@link #transform(CompileContext,com.intellij.openapi.vfs.VirtualFile,com.intellij.openapi.vfs.VirtualFile)}
+ * method will be called on it. If transformation succeeded, the transformed copy will be passed to java compiler instead of original file.
+ */
+ boolean isTransformable(VirtualFile file);
+
+ /**
+ * Transforms the specified file.
+ *
+ * @param context the current compile context.
+ * @param file a copy of original file to be transformed. If there are more than one transformer registered, this copy may already contain transformations made by other transformers which were called before this one
+ * @param originalFile an original file. Since the copy that is supposed to be modified is located outside the project, it is not possible to use PSI for analysis.
+ * So the original file is provided. Note that it is passed for reference purposes only. It MUST NOT be transformed or changed in any way.
+ * For example, it is possible to obtain a PsiFile for the original file:<br><br>
+ * <code>PsiJavaFile originalPsiJavaFile = (PsiJavaFile)PsiManager.getInstance(project).findFile(originalFile)</code>;<br><br>
+ * The obtained originalPsiJavaFile can be analysed, searched etc. For transforming the file by the means of PSI, there should be created a copy of the originalPsiJavaFile:<br><br>
+ * <code>PsiJavaFile psiFileCopy = (PsiJavaFile)originalPsiJavaFile.copy();</code><br><br>
+ * The psiFileCopy can then be transformed, and its text saved to the first "file" argument:<br><br>
+ * <code>String text = psiFileCopy.getText();</code><br><br>
+ * <p/>
+ * <b>Note that transforming files by the means of PSI may considerably slow down the overall make performance.</b>
+ * @return true if transform succeeded, false otherwise.
+ */
+ boolean transform(CompileContext context, VirtualFile file, VirtualFile originalFile);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.java
new file mode 100644
index 0000000..0e1afed
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.java
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+import org.jetbrains.annotations.Nullable;
+
+public interface OutputToSourceMapping {
+ @Nullable
+ String getSourcePath(String outputPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java
new file mode 100644
index 0000000..e7e1350
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import org.jetbrains.annotations.Nullable;
+
+
+/**
+ * A tag interface indicating that the compiler will package the compiled Java classes.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface PackagingCompiler extends FileProcessingCompiler{
+ /**
+ * Called when the compiler detects that an item in the output directory is outdated
+ * and will be recompiled. Note that this method will be called before, and independently from,
+ * subsequent calls to {@link #process}.
+ *
+ * @param context the current compile context.
+ * @param url the URL of a file in the output directory which will be recompiled.
+ * @param state the validity state of the file specified by <code>url</code>.
+ */
+ void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java
new file mode 100644
index 0000000..4c0b646
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * A tag interface indicating that the compiler will generate Java sources.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface SourceGeneratingCompiler extends GeneratingCompiler {
+
+ /**
+ * Used by make subsystem to obtain the file that should be opened in the editor instead of generated file if there were errors found
+ * while compiling the generated file
+ *
+ *
+ * @param context current compile context
+ * @param module the module to which the generated file was attributed
+ * @param outputRoot the compiler output root
+ * @param generatedFile - the file that was generated by this compiler
+ * @return substituting file that should be used for navigation in UI or null if no such substitutor is available
+ *
+ */
+ VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java
new file mode 100644
index 0000000..e8d07f1
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * A tag interface indicating that the compiler will instrument java sources.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> Validator
+ */
+public interface SourceInstrumentingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java
new file mode 100644
index 0000000..8392fdc
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+public interface SourceProcessingCompiler extends FileProcessingCompiler, IntermediateOutputCompiler {
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java
new file mode 100644
index 0000000..d5841ba
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * A simple implementation of ValidityState that is enough for most cases.
+ * The file is considered modified if its timestamp is changed.
+ */
+public final class TimestampValidityState implements ValidityState {
+ private final long myTimestamp;
+
+ /**
+ * Creates a validity state with the specified timestamp.
+ *
+ * @param timestamp the timestamp for the validity state.
+ */
+ public TimestampValidityState(long timestamp) {
+ myTimestamp = timestamp;
+ }
+
+ public boolean equalsTo(ValidityState otherState) {
+ if (!(otherState instanceof TimestampValidityState)) {
+ return false;
+ }
+ return myTimestamp == ((TimestampValidityState)otherState).myTimestamp;
+ }
+
+ /**
+ * Saves the validity state to the specified stream.
+ *
+ * @param out
+ * @throws IOException if the stream write fails.
+ */
+ public void save(DataOutput out) throws IOException {
+ out.writeLong(myTimestamp);
+ }
+
+ /**
+ * Loads the validity state from the specified stream.
+ *
+ * @param is the stream to load the validity state from.
+ * @throws IOException if the stream read fails.
+ * @since 5.0.2
+ */
+ public static TimestampValidityState load(DataInput is) throws IOException {
+ return new TimestampValidityState(is.readLong());
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java
new file mode 100644
index 0000000..3c56f8d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+
+import java.util.Collection;
+
+/**
+ * A tag interface indicating that the compiler will translate one type of files into another (e.g. .java -> .class).
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface TranslatingCompiler extends Compiler {
+
+ /**
+ * Defines a single file compiled by the compiler.
+ */
+ interface OutputItem {
+ /**
+ * Returns the path to the output file.
+ *
+ * @return absolute path of the output file ('/' slashes used)
+ */
+ String getOutputPath();
+
+ /**
+ * Returns the path to the source file.
+ *
+ * @return the source file to be compiled
+ */
+ VirtualFile getSourceFile();
+ }
+
+ interface OutputSink {
+ /**
+ *
+ * @param outputRoot output directory
+ * @param items output items that were successfully compiled.
+ * @param filesToRecompile virtual files that should be considered as "modified" next time compilation is invoked.
+ */
+ void add(String outputRoot, Collection<OutputItem> items, VirtualFile[] filesToRecompile);
+ }
+
+
+ /**
+ * Checks if the compiler can compile the specified file.
+ *
+ * @param file the file to check.
+ * @param context the context for the current compile operation.
+ * @return true if can compile the file, false otherwise. If the method returns false, <code>file</code>
+ * will not be included in the list of files passed to {@link #compile(CompileContext,Chunk<Module>,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
+ */
+ boolean isCompilableFile(VirtualFile file, CompileContext context);
+
+ /**
+ * Compiles the specified files.
+ *
+ * @param context the context for the current compile operation.
+ * @param moduleChunk contains modules that form a cycle. If project module graph has no cycles, a chunk corresponds to a single module
+ * @param files the source files to compile that correspond to the module chunk
+ * @param sink storage that accepts compiler output results
+ */
+ void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java
new file mode 100644
index 0000000..560ef8a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+/**
+ * A tag interface indicating that the compiler will perform any validation on the files in given compile scope.
+ * Error/Warning messages should be added to the CompileContext object.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface Validator extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java
new file mode 100644
index 0000000..65d12e6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Instances of this class are associated with the files processed by compilers.
+ * A file is considered modified if currently associated ValidityState differs from the previously stored ValiditySate for this file.
+ */
+public interface ValidityState {
+ /**
+ * Compares this validity state to other ValidityState.
+ *
+ * @param otherState the state to compare with.
+ * @return true if states can be considered equal, false otherwise.
+ */
+ boolean equalsTo(ValidityState otherState);
+ /**
+ * Invoked by make subsystem in order to store the state.
+ *
+ * @param out the output to which the state should be stored.
+ * @throws IOException if the save operation failed because of an I/O error.
+ * @see TimestampValidityState#load(java.io.DataInputStream)
+ */
+ void save(DataOutput out) throws IOException;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java
new file mode 100644
index 0000000..626f8db
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+/**
+ * A factory for creating {@link ValidityState} objects.
+ */
+public interface ValidityStateFactory {
+ /**
+ * Used for deserialization of ValidityState objects from compiler internal caches.
+ * @see ValidityState
+ * @param in
+ */
+ ValidityState createValidityState(DataInput in) throws IOException;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java
new file mode 100644
index 0000000..0f40216
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ex;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerPaths;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.containers.OrderedSet;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Set;
+
+public class CompilerPathsEx extends CompilerPaths {
+ public static final Key<Boolean> CLEAR_ALL_OUTPUTS_KEY = Key.create("_should_clear_all_outputs_");
+
+ public static File getZippedOutputPath(Project project, String outputDirectoryPath) {
+ final File outputDir = new File(outputDirectoryPath);
+ return new File(getZipStoreDirectory(project), "_" + outputDir.getName() + Integer.toHexString(outputDirectoryPath.hashCode()) + ".zip");
+ }
+
+ public static File getZipStoreDirectory(Project project) {
+ return new File(getCompilerSystemDirectory(project), ".zip");
+ }
+
+ public static class FileVisitor {
+ protected void accept(final VirtualFile file, final String fileRoot, final String filePath) {
+ if (file.isDirectory()) {
+ acceptDirectory(file, fileRoot, filePath);
+ }
+ else {
+ acceptFile(file, fileRoot, filePath);
+ }
+ }
+
+ protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
+ }
+
+ protected void acceptDirectory(final VirtualFile file, final String fileRoot, final String filePath) {
+ ProgressManager.checkCanceled();
+ final VirtualFile[] children = file.getChildren();
+ for (final VirtualFile child : children) {
+ final String name = child.getName();
+ final String _filePath;
+ final StringBuilder buf = StringBuilderSpinAllocator.alloc();
+ try {
+ buf.append(filePath).append("/").append(name);
+ _filePath = buf.toString();
+ }
+ finally {
+ StringBuilderSpinAllocator.dispose(buf);
+ }
+ accept(child, fileRoot, _filePath);
+ }
+ }
+ }
+
+ public static void visitFiles(final Collection<VirtualFile> directories, final FileVisitor visitor) {
+ for (final VirtualFile outputDir : directories) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final String path = outputDir.getPath();
+ visitor.accept(outputDir, path, path);
+ }
+ });
+ }
+ }
+
+ public static String[] getOutputPaths(Module[] modules) {
+ final Set<String> outputPaths = new OrderedSet<String>();
+ for (Module module : modules) {
+ final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+ if (compilerModuleExtension == null) {
+ continue;
+ }
+ String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl();
+ if (outputPathUrl != null) {
+ outputPaths.add(VirtualFileManager.extractPath(outputPathUrl).replace('/', File.separatorChar));
+ }
+
+ String outputPathForTestsUrl = compilerModuleExtension.getCompilerOutputUrlForTests();
+ if (outputPathForTestsUrl != null) {
+ outputPaths.add(VirtualFileManager.extractPath(outputPathForTestsUrl).replace('/', File.separatorChar));
+ }
+ }
+ return ArrayUtil.toStringArray(outputPaths);
+ }
+
+ public static VirtualFile[] getOutputDirectories(final Module[] modules) {
+ final Set<VirtualFile> dirs = new OrderedSet<VirtualFile>();
+ for (Module module : modules) {
+ final VirtualFile outputDir = getModuleOutputDirectory(module, false);
+ if (outputDir != null) {
+ dirs.add(outputDir);
+ }
+ VirtualFile testsOutputDir = getModuleOutputDirectory(module, true);
+ if (testsOutputDir != null) {
+ dirs.add(testsOutputDir);
+ }
+ }
+ return VfsUtil.toVirtualFileArray(dirs);
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java
new file mode 100644
index 0000000..148e152
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+public interface BuildInstruction {
+ String getOutputRelativePath();
+
+ boolean accept(BuildInstructionVisitor visitor) throws Exception;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java
new file mode 100644
index 0000000..6ae9b33
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+
+public abstract class BuildInstructionVisitor {
+ public boolean visitInstruction(BuildInstruction instruction) throws Exception {
+ return true;
+ }
+ public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws Exception {
+ return visitInstruction(instruction);
+ }
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java
new file mode 100644
index 0000000..48022b6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java
@@ -0,0 +1,31 @@
+/*
+ * 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.compiler.CompileContext;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead
+ */
+public abstract class BuildParticipant {
+ public static final BuildParticipant[] EMPTY_ARRAY = new BuildParticipant[0];
+
+ @Nullable
+ public abstract Artifact createArtifact(CompileContext context);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java
new file mode 100644
index 0000000..a0f46da
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java
@@ -0,0 +1,35 @@
+/*
+ * 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.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ *
+ * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead
+ */
+public abstract class BuildParticipantProvider {
+ public static final ExtensionPointName<BuildParticipantProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.buildParticipantProvider");
+
+
+ public abstract Collection<? extends BuildParticipant> getParticipants(Module module);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java
new file mode 100644
index 0000000..ad30291
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java
@@ -0,0 +1,30 @@
+/*
+ * 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.NotNull;
+
+import java.io.File;
+
+@Deprecated
+public interface BuildRecipe {
+ void addInstruction(BuildInstruction instruction);
+
+ boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder);
+ boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception;
+
+ void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath);
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java
new file mode 100644
index 0000000..4109410
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java
@@ -0,0 +1,27 @@
+/*
+ * 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.Nullable;
+
+import java.io.File;
+
+public interface FileCopyInstruction extends BuildInstruction {
+ File getFile();
+
+ boolean isDirectory();
+
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java
new file mode 100644
index 0000000..3f645d0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java
@@ -0,0 +1,44 @@
+/*
+ * 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.application.ApplicationNamesInfo;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.jar.Attributes;
+
+public class ManifestBuilder {
+ @NonNls private static final String NAME = "Created-By";
+ private static final Attributes.Name CREATED_BY = new Attributes.Name(NAME);
+
+ private ManifestBuilder() {
+ }
+
+ public static void setGlobalAttributes(Attributes mainAttributes) {
+ setVersionAttribute(mainAttributes);
+ setIfNone(mainAttributes, CREATED_BY, ApplicationNamesInfo.getInstance().getFullProductName());
+ }
+
+ public static void setVersionAttribute(Attributes mainAttributes) {
+ setIfNone(mainAttributes, Attributes.Name.MANIFEST_VERSION, "1.0");
+ }
+
+ private static void setIfNone(Attributes mainAttributes, Attributes.Name attrName, String value) {
+ if (mainAttributes.getValue(attrName) == null) {
+ mainAttributes.put(attrName, value);
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html
new file mode 100644
index 0000000..839258a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for extending the build process.
+</body></html>
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.java
new file mode 100644
index 0000000..b752e8e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 3, 2002
+ * @author Jeka
+ */
+package com.intellij.openapi.compiler.options;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import org.jetbrains.annotations.Nullable;
+
+public class ExcludeEntryDescription implements Disposable {
+ private boolean myIsFile;
+ private boolean myIncludeSubdirectories;
+ private VirtualFilePointer myFilePointer;
+ private final Disposable myParentDisposable;
+
+ public ExcludeEntryDescription(String url, boolean includeSubdirectories, boolean isFile, Disposable parent) {
+ myParentDisposable = parent;
+ myFilePointer = VirtualFilePointerManager.getInstance().create(url, parent, null);
+ myIncludeSubdirectories = includeSubdirectories;
+ myIsFile = isFile;
+ }
+
+ public ExcludeEntryDescription(VirtualFile virtualFile, boolean includeSubdirectories, boolean isFile, Disposable parent) {
+ this(virtualFile.getUrl(), includeSubdirectories, isFile, parent);
+ }
+
+ public ExcludeEntryDescription copy(Disposable parent) {
+ return new ExcludeEntryDescription(getUrl(), myIncludeSubdirectories, myIsFile,parent);
+ }
+
+ public void setPresentableUrl(String newUrl) {
+ myFilePointer = VirtualFilePointerManager.getInstance().create(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(newUrl)), myParentDisposable, null);
+ final VirtualFile file = getVirtualFile();
+ if (file != null) {
+ myIsFile = !file.isDirectory();
+ }
+ }
+
+ public boolean isFile() {
+ return myIsFile;
+ }
+
+ public String getUrl() {
+ return myFilePointer.getUrl();
+ }
+
+ public String getPresentableUrl() {
+ return myFilePointer.getPresentableUrl();
+ }
+
+ public boolean isIncludeSubdirectories() {
+ return myIncludeSubdirectories;
+ }
+
+ public void setIncludeSubdirectories(boolean includeSubdirectories) {
+ myIncludeSubdirectories = includeSubdirectories;
+ }
+
+ @Nullable
+ public VirtualFile getVirtualFile() {
+ return myFilePointer.getFile();
+ }
+
+ public boolean isValid() {
+ return myFilePointer.isValid();
+ }
+
+ public boolean equals(Object obj) {
+ if(!(obj instanceof ExcludeEntryDescription)) {
+ return false;
+ }
+ ExcludeEntryDescription entryDescription = (ExcludeEntryDescription)obj;
+ if(entryDescription.myIsFile != myIsFile) {
+ return false;
+ }
+ if(entryDescription.myIncludeSubdirectories != myIncludeSubdirectories) {
+ return false;
+ }
+ return Comparing.equal(entryDescription.getUrl(), getUrl());
+ }
+
+ public int hashCode() {
+ int result = (myIsFile ? 1 : 0);
+ result = 31 * result + (myIncludeSubdirectories ? 1 : 0);
+ result = 31 * result + getUrl().hashCode();
+ return result;
+ }
+
+ public void dispose() {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java
new file mode 100644
index 0000000..6a2cd87
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.compiler.options;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class ExcludedEntriesConfigurable implements UnnamedConfigurable {
+ private final Project myProject;
+ private final ArrayList<ExcludeEntryDescription> myExcludeEntryDescriptions = new ArrayList<ExcludeEntryDescription>();
+ private final FileChooserDescriptor myDescriptor;
+ private final ExcludedEntriesConfiguration myConfiguration;
+ private ExcludedEntriesPanel myExcludedEntriesPanel;
+
+ public ExcludedEntriesConfigurable(Project project) {
+ this(project, new FileChooserDescriptor(true, true, false, false, false, true),
+ CompilerConfiguration.getInstance(project).getExcludedEntriesConfiguration());
+ }
+
+ public ExcludedEntriesConfigurable(Project project, FileChooserDescriptor descriptor, final ExcludedEntriesConfiguration configuration) {
+ myDescriptor = descriptor;
+ myConfiguration = configuration;
+ myProject = project;
+ }
+
+ public void reset() {
+ ExcludeEntryDescription[] descriptions = myConfiguration.getExcludeEntryDescriptions();
+ disposeMyDescriptions();
+ for (ExcludeEntryDescription description : descriptions) {
+ myExcludeEntryDescriptions.add(description.copy(myProject));
+ }
+ ((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
+ }
+
+ public void addEntry(ExcludeEntryDescription description) {
+ myExcludeEntryDescriptions.add(description);
+ ((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
+ }
+
+ private void disposeMyDescriptions() {
+ for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+ Disposer.dispose(description);
+ }
+ myExcludeEntryDescriptions.clear();
+ }
+
+ public void apply() {
+ myConfiguration.removeAllExcludeEntryDescriptions();
+ for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+ myConfiguration.addExcludeEntryDescription(description.copy(myProject));
+ }
+ FileStatusManager.getInstance(myProject).fileStatusesChanged(); // refresh exclude from compile status
+ }
+
+ public boolean isModified() {
+ ExcludeEntryDescription[] excludeEntryDescriptions = myConfiguration.getExcludeEntryDescriptions();
+ if(excludeEntryDescriptions.length != myExcludeEntryDescriptions.size()) {
+ return true;
+ }
+ for(int i = 0; i < excludeEntryDescriptions.length; i++) {
+ ExcludeEntryDescription description = excludeEntryDescriptions[i];
+ if(!Comparing.equal(description, myExcludeEntryDescriptions.get(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public JComponent createComponent() {
+ if (myExcludedEntriesPanel == null) {
+ myExcludedEntriesPanel = new ExcludedEntriesPanel();
+ }
+ return myExcludedEntriesPanel;
+ }
+
+ public void disposeUIResources() {
+ myExcludedEntriesPanel = null;
+ }
+
+ private class ExcludedEntriesPanel extends PanelWithButtons {
+ private JButton myRemoveButton;
+ private JBTable myExcludedTable;
+
+ public ExcludedEntriesPanel() {
+ initPanel();
+ }
+
+ protected String getLabelText(){
+ return null;
+ }
+
+ protected JButton[] createButtons(){
+ final JButton addButton = new JButton(IdeBundle.message("button.add"));
+ addButton.addActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e){
+ addPath(myDescriptor);
+ }
+ }
+ );
+
+ myRemoveButton = new JButton(IdeBundle.message("button.remove"));
+ myRemoveButton.addActionListener(
+ new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ removePaths();
+ }
+ }
+ );
+ myRemoveButton.setEnabled(false);
+ myRemoveButton.getModel().addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ if (myExcludedTable.getSelectedRow() == -1) {
+ myRemoveButton.setEnabled(false);
+ }
+ }
+ });
+
+ return new JButton[]{/*addButton, myRemoveButton*/};
+ }
+
+ private void addPath(FileChooserDescriptor descriptor) {
+ int selected = -1 /*myExcludedTable.getSelectedRow() + 1*/;
+ if(selected < 0) {
+ selected = myExcludeEntryDescriptions.size();
+ }
+ int savedSelected = selected;
+ VirtualFile[] chosen = FileChooser.chooseFiles(descriptor, myProject, null);
+ for (final VirtualFile chosenFile : chosen) {
+ if (isFileExcluded(chosenFile)) {
+ continue;
+ }
+ ExcludeEntryDescription description;
+ if (chosenFile.isDirectory()) {
+ description = new ExcludeEntryDescription(chosenFile, true, false, myProject);
+ }
+ else {
+ description = new ExcludeEntryDescription(chosenFile, false, true, myProject);
+ }
+ myExcludeEntryDescriptions.add(selected, description);
+ selected++;
+ }
+ if (selected > savedSelected) { // actually added something
+ AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
+ model.fireTableRowsInserted(savedSelected, selected-1);
+ myExcludedTable.setRowSelectionInterval(savedSelected, selected - 1);
+ }
+ }
+
+ private boolean isFileExcluded(VirtualFile file) {
+ for (final ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+ final VirtualFile descriptionFile = description.getVirtualFile();
+ if (descriptionFile == null) {
+ continue;
+ }
+ if (file.equals(descriptionFile)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void removePaths() {
+ int[] selected = myExcludedTable.getSelectedRows();
+ if(selected == null || selected.length <= 0) {
+ return;
+ }
+ if(myExcludedTable.isEditing()) {
+ TableCellEditor editor = myExcludedTable.getCellEditor();
+ if (editor != null) {
+ editor.stopCellEditing();
+ }
+ }
+ AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
+ Arrays.sort(selected);
+ int indexToSelect = selected[selected.length - 1];
+ int removedCount = 0;
+ for (int indexToRemove : selected) {
+ final int row = indexToRemove - removedCount;
+ ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+ Disposer.dispose(description);
+ myExcludeEntryDescriptions.remove(row);
+ model.fireTableRowsDeleted(row, row);
+ removedCount += 1;
+ }
+ if(indexToSelect >= myExcludeEntryDescriptions.size()) {
+ indexToSelect = myExcludeEntryDescriptions.size() - 1;
+ }
+ if(indexToSelect >= 0) {
+ myExcludedTable.setRowSelectionInterval(indexToSelect, indexToSelect);
+ }
+ myExcludedTable.requestFocus();
+ }
+
+ protected JComponent createMainComponent(){
+ final String[] names = {
+ CompilerBundle.message("exclude.from.compile.table.path.column.name"),
+ CompilerBundle.message("exclude.from.compile.table.recursively.column.name")
+ };
+ // Create a model of the data.
+ TableModel dataModel = new AbstractTableModel() {
+ public int getColumnCount() {
+ return names.length;
+ }
+
+ public int getRowCount() {
+ return myExcludeEntryDescriptions.size();
+ }
+
+ public Object getValueAt(int row, int col) {
+ ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+ if(col == 0) {
+ return description.getPresentableUrl();
+ }
+ if(col == 1) {
+ if(!description.isFile()) {
+ return description.isIncludeSubdirectories() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public String getColumnName(int column) {
+ return names[column];
+ }
+
+ public Class getColumnClass(int c) {
+ if(c == 0) {
+ return String.class;
+ }
+ if(c == 1) {
+ return Boolean.class;
+ }
+ return null;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ if(col == 1) {
+ ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+ return !description.isFile();
+ }
+ return true;
+ }
+
+ public void setValueAt(Object aValue, int row, int col) {
+ ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+ if (col == 1) {
+ description.setIncludeSubdirectories(aValue.equals(Boolean.TRUE));
+ } else {
+ final String path = (String)aValue;
+ description.setPresentableUrl(path);
+ }
+ }
+ };
+
+ myExcludedTable = new JBTable(dataModel);
+ myExcludedTable.setEnableAntialiasing(true);
+
+ myExcludedTable.getEmptyText().setText(CompilerBundle.message("no.excludes"));
+ myExcludedTable.setPreferredScrollableViewportSize(new Dimension(300, myExcludedTable.getRowHeight() * 6));
+ myExcludedTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
+ myExcludedTable.setDefaultRenderer(Object.class, new MyObjectRenderer());
+ myExcludedTable.getColumn(names[0]).setPreferredWidth(350);
+ final int cbWidth = 15 + myExcludedTable.getTableHeader().getFontMetrics(myExcludedTable.getTableHeader().getFont()).stringWidth(names[1]);
+ final TableColumn cbColumn = myExcludedTable.getColumn(names[1]);
+ cbColumn.setPreferredWidth(cbWidth);
+ cbColumn.setMaxWidth(cbWidth);
+ myExcludedTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ myExcludedTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ myRemoveButton.setEnabled(myExcludedTable.getSelectedRow() >= 0);
+ }
+ });
+ TableCellEditor editor = myExcludedTable.getDefaultEditor(String.class);
+ if(editor instanceof DefaultCellEditor) {
+ ((DefaultCellEditor)editor).setClickCountToStart(1);
+ }
+
+ return ToolbarDecorator.createDecorator(myExcludedTable)
+ .disableUpAction()
+ .disableDownAction()
+ .setAddAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ addPath(myDescriptor);
+ }
+ })
+ .setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ removePaths();
+ }
+ }).createPanel();
+
+
+ //return ScrollPaneFactory.createScrollPane(myExcludedTable);
+ }
+ }
+
+ private static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
+ private final JPanel myPanel = new JPanel();
+
+ public BooleanRenderer() {
+ setHorizontalAlignment(CENTER);
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus,
+ int row, int column) {
+ if(value == null) {
+ if(isSelected) {
+ myPanel.setBackground(table.getSelectionBackground());
+ }
+ else {
+ myPanel.setBackground(table.getBackground());
+ }
+ return myPanel;
+ }
+ if(isSelected) {
+ setForeground(table.getSelectionForeground());
+ super.setBackground(table.getSelectionBackground());
+ }
+ else {
+ setForeground(table.getForeground());
+ setBackground(table.getBackground());
+ }
+ setSelected(((Boolean)value).booleanValue());
+ return this;
+ }
+ }
+
+ private class MyObjectRenderer extends DefaultTableCellRenderer {
+ public MyObjectRenderer() {
+ setUI(new RightAlignedLabelUI());
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ final ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+ component.setForeground(!description.isValid() ? JBColor.RED : isSelected ? table.getSelectionForeground() : table.getForeground());
+ component.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
+ return component;
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java
new file mode 100644
index 0000000..67e8745
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java
@@ -0,0 +1,145 @@
+/*
+ * 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.options;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+/**
+ * @author nik
+ */
+public class ExcludedEntriesConfiguration implements PersistentStateComponent<ExcludedEntriesConfiguration>, JDOMExternalizable, Disposable {
+ @NonNls private static final String FILE = "file";
+ @NonNls private static final String DIRECTORY = "directory";
+ @NonNls private static final String URL = "url";
+ @NonNls private static final String INCLUDE_SUBDIRECTORIES = "includeSubdirectories";
+ private final Collection<ExcludeEntryDescription> myExcludeEntryDescriptions = new LinkedHashSet<ExcludeEntryDescription>();
+ private ExcludeEntryDescription[] myCachedDescriptions = null;
+
+ public synchronized ExcludeEntryDescription[] getExcludeEntryDescriptions() {
+ if (myCachedDescriptions == null) {
+ myCachedDescriptions = myExcludeEntryDescriptions.toArray(new ExcludeEntryDescription[myExcludeEntryDescriptions.size()]);
+ }
+ return myCachedDescriptions;
+ }
+
+ public synchronized void addExcludeEntryDescription(ExcludeEntryDescription description) {
+ myExcludeEntryDescriptions.add(description);
+ myCachedDescriptions = null;
+ }
+
+ public synchronized void removeExcludeEntryDescription(ExcludeEntryDescription description) {
+ myExcludeEntryDescriptions.remove(description);
+ myCachedDescriptions = null;
+ }
+
+ public synchronized void removeAllExcludeEntryDescriptions() {
+ myExcludeEntryDescriptions.clear();
+ myCachedDescriptions = null;
+ }
+
+ public synchronized boolean containsExcludeEntryDescription(ExcludeEntryDescription description) {
+ return myExcludeEntryDescriptions.contains(description);
+ }
+
+ public void readExternal(final Element node) {
+ for (final Object o : node.getChildren()) {
+ Element element = (Element)o;
+ String url = element.getAttributeValue(URL);
+ if (url == null) continue;
+ if (FILE.equals(element.getName())) {
+ ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, false, true, this);
+ addExcludeEntryDescription(excludeEntryDescription);
+ }
+ if (DIRECTORY.equals(element.getName())) {
+ boolean includeSubdirectories = Boolean.parseBoolean(element.getAttributeValue(INCLUDE_SUBDIRECTORIES));
+ ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, includeSubdirectories, false,this);
+ addExcludeEntryDescription(excludeEntryDescription);
+ }
+ }
+ }
+
+ public void writeExternal(final Element element) {
+ for (final ExcludeEntryDescription description : getExcludeEntryDescriptions()) {
+ if (description.isFile()) {
+ Element entry = new Element(FILE);
+ entry.setAttribute(URL, description.getUrl());
+ element.addContent(entry);
+ }
+ else {
+ Element entry = new Element(DIRECTORY);
+ entry.setAttribute(URL, description.getUrl());
+ entry.setAttribute(INCLUDE_SUBDIRECTORIES, Boolean.toString(description.isIncludeSubdirectories()));
+ element.addContent(entry);
+ }
+ }
+ }
+
+ public boolean isExcluded(VirtualFile virtualFile) {
+ for (final ExcludeEntryDescription entryDescription : getExcludeEntryDescriptions()) {
+ VirtualFile descriptionFile = entryDescription.getVirtualFile();
+ if (descriptionFile == null) {
+ continue;
+ }
+ if (entryDescription.isFile()) {
+ if (descriptionFile.equals(virtualFile)) {
+ return true;
+ }
+ }
+ else if (entryDescription.isIncludeSubdirectories()) {
+ if (VfsUtil.isAncestor(descriptionFile, virtualFile, false)) {
+ return true;
+ }
+ }
+ else {
+ if (virtualFile.isDirectory()) {
+ continue;
+ }
+ if (descriptionFile.equals(virtualFile.getParent())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void dispose() {
+ for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+ Disposer.dispose(description);
+ }
+ }
+
+ public ExcludedEntriesConfiguration getState() {
+ return this;
+ }
+
+ public void loadState(final ExcludedEntriesConfiguration state) {
+ for (ExcludeEntryDescription description : state.getExcludeEntryDescriptions()) {
+ addExcludeEntryDescription(description.copy(this));
+ }
+ Disposer.dispose(state);
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html b/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html
new file mode 100644
index 0000000..b938f8e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for invoking the compiler, listening to compilation events and implementing
+custom compilers or compilation steps.
+</body></html>
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java
new file mode 100644
index 0000000..64088c8
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java
@@ -0,0 +1,95 @@
+/*
+ * 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.util;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInspection.InspectionToolProvider;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author peter
+ */
+public abstract class InspectionValidator {
+ public static final ExtensionPointName<InspectionValidator> EP_NAME = ExtensionPointName.create("com.intellij.compiler.inspectionValidator");
+ private final String myDescription;
+ private final String myProgressIndicatorText;
+ private final Class<? extends LocalInspectionTool>[] myInspectionToolClasses;
+
+ protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final Class<? extends LocalInspectionTool>... inspectionToolClasses) {
+ myDescription = description;
+ myProgressIndicatorText = progressIndicatorText;
+ myInspectionToolClasses = inspectionToolClasses;
+ }
+
+ protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final InspectionToolProvider provider) {
+ //noinspection unchecked
+ this(description, progressIndicatorText, provider.getInspectionClasses());
+ }
+
+ protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final Class<? extends InspectionToolProvider> providerClass)
+ throws IllegalAccessException, InstantiationException {
+ this(description, progressIndicatorText, providerClass.newInstance());
+ }
+
+
+ public abstract boolean isAvailableOnScope(@NotNull CompileScope scope);
+
+ public abstract Collection<VirtualFile> getFilesToProcess(final Project project, final CompileContext context);
+
+ @NotNull
+ public Collection<? extends PsiElement> getDependencies(final PsiFile psiFile) {
+ return Collections.emptyList();
+ }
+
+ @NotNull
+ public Class<? extends LocalInspectionTool>[] getInspectionToolClasses(final CompileContext context) {
+ return myInspectionToolClasses;
+ }
+
+ public final String getDescription() {
+ return myDescription;
+ }
+
+ public final String getProgressIndicatorText() {
+ return myProgressIndicatorText;
+ }
+
+ public CompilerMessageCategory getCategoryByHighlightDisplayLevel(@NotNull final HighlightDisplayLevel severity, @NotNull final VirtualFile virtualFile, @NotNull final CompileContext context) {
+ if (severity == HighlightDisplayLevel.ERROR) return CompilerMessageCategory.ERROR;
+ if (severity == HighlightDisplayLevel.WARNING) return CompilerMessageCategory.WARNING;
+ return CompilerMessageCategory.INFORMATION;
+ }
+
+ @NotNull
+ public Map<ProblemDescriptor, HighlightDisplayLevel> checkAdditionally(PsiFile file) {
+ return Collections.emptyMap();
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java b/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java
new file mode 100644
index 0000000..dc1ff57
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java
@@ -0,0 +1,131 @@
+/*
+ * 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.CompileContext;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.descriptors.ConfigFile;
+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.Set;
+
+public abstract class DeploymentUtil {
+ public static DeploymentUtil getInstance() {
+ return ServiceManager.getService(DeploymentUtil.class);
+ }
+
+ public abstract void copyFile(@NotNull File fromFile,
+ @NotNull File toFile,
+ @NotNull CompileContext context,
+ @Nullable Set<String> writtenPaths,
+ @Nullable FileFilter fileFilter) throws IOException;
+
+ @Deprecated
+ public abstract boolean addItemsRecursively(@NotNull BuildRecipe items, @NotNull File root, String outputRelativePath);
+
+ public static String trimForwardSlashes(@NotNull String path) {
+ while (path.length() != 0 && (path.charAt(0) == '/' || path.charAt(0) == File.separatorChar)) {
+ path = path.substring(1);
+ }
+ return path;
+ }
+
+ public abstract void reportDeploymentDescriptorDoesNotExists(ConfigFile descriptor, CompileContext context, Module module);
+
+ public static String concatPaths(String... paths) {
+ final StringBuilder builder = new StringBuilder();
+ for (String path : paths) {
+ if (path.length() == 0) continue;
+
+ final int len = builder.length();
+ if (len > 0 && builder.charAt(len - 1) != '/' && builder.charAt(len - 1) != File.separatorChar) {
+ builder.append('/');
+ }
+ builder.append(len != 0 ? trimForwardSlashes(path) : path);
+ }
+ return builder.toString();
+ }
+
+ public static String appendToPath(@NotNull String basePath, @NotNull String relativePath) {
+ final boolean endsWithSlash = StringUtil.endsWithChar(basePath, '/') || StringUtil.endsWithChar(basePath, '\\');
+ final boolean startsWithSlash = StringUtil.startsWithChar(relativePath, '/') || StringUtil.startsWithChar(relativePath, '\\');
+ String tail;
+ if (endsWithSlash && startsWithSlash) {
+ tail = trimForwardSlashes(relativePath);
+ }
+ else if (!endsWithSlash && !startsWithSlash && basePath.length() > 0 && relativePath.length() > 0) {
+ tail = "/" + relativePath;
+ }
+ else {
+ tail = relativePath;
+ }
+ return basePath + tail;
+ }
+
+ @Deprecated
+ public abstract BuildRecipe createBuildRecipe();
+
+ @Nullable
+ public abstract String getConfigFileErrorMessage(ConfigFile configFile);
+
+ /**
+ * @deprecated use {@link com.intellij.openapi.util.io.FileUtil#getRelativePath}
+ */
+ @Nullable
+ public static String getRelativePath(@NotNull String basePath, @NotNull final String filePath) {
+ if (basePath.equals(filePath)) return "";
+ if (!basePath.endsWith(File.separator)) basePath += File.separatorChar;
+
+ int len = 0;
+ int lastSeparatorIndex = 0; // need this for cases like this: base="/temp/abcde/baseDir" and file="/temp/ab"
+ while (len < filePath.length() && len < basePath.length() && filePath.charAt(len) == basePath.charAt(len)) {
+ if (basePath.charAt(len) == File.separatorChar) {
+ lastSeparatorIndex = len;
+ }
+ len++;
+ }
+
+ if (len == 0) {
+ return null;
+ }
+ final StringBuilder relativePath = StringBuilderSpinAllocator.alloc();
+ try {
+ for (int i=len; i < basePath.length(); i++) {
+ if (basePath.charAt(i) == File.separatorChar) {
+ relativePath.append("..");
+ relativePath.append(File.separatorChar);
+ }
+ }
+ relativePath.append(filePath.substring(lastSeparatorIndex + 1));
+
+ return relativePath.toString();
+ }
+ finally {
+ StringBuilderSpinAllocator.dispose(relativePath);
+ }
+ }
+
+ public abstract void checkConfigFile(final ConfigFile descriptor, final CompileContext compileContext, final Module module);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java
new file mode 100644
index 0000000..8155cf0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java
@@ -0,0 +1,52 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface Artifact extends UserDataHolder {
+ @NotNull
+ ArtifactType getArtifactType();
+
+ String getName();
+
+ boolean isBuildOnMake();
+
+ @NotNull
+ CompositePackagingElement<?> getRootElement();
+
+ @Nullable
+ String getOutputPath();
+
+ Collection<? extends ArtifactPropertiesProvider> getPropertiesProviders();
+
+ ArtifactProperties<?> getProperties(@NotNull ArtifactPropertiesProvider propertiesProvider);
+
+ @Nullable
+ VirtualFile getOutputFile();
+
+ @Nullable
+ String getOutputFilePath();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java
new file mode 100644
index 0000000..34b91f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArtifactAdapter implements ArtifactListener {
+ public void artifactAdded(@NotNull Artifact artifact) {
+ }
+
+ public void artifactRemoved(@NotNull Artifact artifact) {
+ }
+
+ public void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName) {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java
new file mode 100644
index 0000000..88dddea
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface ArtifactListener extends EventListener {
+
+ void artifactAdded(@NotNull Artifact artifact);
+
+ void artifactRemoved(@NotNull Artifact artifact);
+
+ void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.java
new file mode 100644
index 0000000..9610bfa
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.java
@@ -0,0 +1,62 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.util.messages.Topic;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactManager implements ArtifactModel {
+ public static final Topic<ArtifactListener> TOPIC = Topic.create("artifacts changes", ArtifactListener.class);
+ public static final Comparator<Artifact> ARTIFACT_COMPARATOR = new Comparator<Artifact>() {
+ public int compare(Artifact o1, Artifact o2) {
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+ };
+
+ public static ArtifactManager getInstance(@NotNull Project project) {
+ return project.getComponent(ArtifactManager.class);
+ }
+
+ public abstract Artifact[] getSortedArtifacts();
+
+ public abstract ModifiableArtifactModel createModifiableModel();
+
+ public abstract PackagingElementResolvingContext getResolvingContext();
+
+ @NotNull
+ public abstract Artifact addArtifact(@NonNls @NotNull String name, @NotNull ArtifactType type, @Nullable CompositePackagingElement<?> root);
+
+ public abstract void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath,
+ @NotNull Collection<? extends PackagingElement<?>> elements);
+
+ public abstract void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath,
+ @NotNull PackagingElement<?> element);
+
+ public abstract ModificationTracker getModificationTracker();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java
new file mode 100644
index 0000000..91f3ae7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java
@@ -0,0 +1,43 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactModel {
+ @NotNull
+ Artifact[] getArtifacts();
+
+ @Nullable
+ Artifact findArtifact(@NotNull String name);
+
+ @NotNull
+ Artifact getArtifactByOriginal(@NotNull Artifact artifact);
+
+ @NotNull
+ Artifact getOriginalArtifact(@NotNull Artifact artifact);
+
+ Collection<? extends Artifact> getArtifactsByType(@NotNull ArtifactType type);
+
+ List<? extends Artifact> getAllArtifactsIncludingInvalid();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java
new file mode 100644
index 0000000..ee1ed1c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ArtifactPointer {
+
+ @NotNull
+ String getArtifactName();
+
+ @Nullable
+ Artifact getArtifact();
+
+ @NotNull
+ String getArtifactName(@NotNull ArtifactModel artifactModel);
+
+ @Nullable
+ Artifact findArtifact(@NotNull ArtifactModel artifactModel);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java
new file mode 100644
index 0000000..c5f32f4
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.components.ServiceManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPointerManager {
+ public static ArtifactPointerManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, ArtifactPointerManager.class);
+ }
+
+ public abstract ArtifactPointer createPointer(@NotNull String name);
+
+ public abstract ArtifactPointer createPointer(@NotNull Artifact artifact);
+
+ public abstract ArtifactPointer createPointer(@NotNull Artifact artifact, @NotNull ArtifactModel artifactModel);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java
new file mode 100644
index 0000000..65d590b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java
@@ -0,0 +1,36 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.ArtifactPropertiesEditor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactProperties<S> implements PersistentStateComponent<S> {
+
+ public void onBuildStarted(@NotNull Artifact artifact, @NotNull CompileContext compileContext) {
+ }
+
+ public void onBuildFinished(@NotNull Artifact artifact, @NotNull CompileContext compileContext) {
+ }
+
+ public abstract ArtifactPropertiesEditor createEditor(@NotNull ArtifactEditorContext context);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java
new file mode 100644
index 0000000..bb3c162
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java
@@ -0,0 +1,59 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPropertiesProvider {
+ public static final ExtensionPointName<ArtifactPropertiesProvider> EP_NAME = ExtensionPointName.create("com.intellij.packaging.artifactPropertiesProvider");
+ private final String myId;
+
+ protected ArtifactPropertiesProvider(@NotNull @NonNls String id) {
+ myId = id;
+ }
+
+ public final String getId() {
+ return myId;
+ }
+
+ public boolean isAvailableFor(@NotNull ArtifactType type) {
+ return true;
+ }
+
+ @NotNull
+ public abstract ArtifactProperties<?> createProperties(@NotNull ArtifactType artifactType);
+
+ public static ArtifactPropertiesProvider[] getProviders() {
+ return Extensions.getExtensions(EP_NAME);
+ }
+
+ @Nullable
+ public static ArtifactPropertiesProvider findById(@NotNull @NonNls String id) {
+ for (ArtifactPropertiesProvider provider : getProviders()) {
+ if (provider.getId().equals(id)) {
+ return provider;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java
new file mode 100644
index 0000000..f1b8827
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java
@@ -0,0 +1,78 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactTemplate {
+
+ public abstract String getPresentableName();
+
+ /**
+ * @deprecated override {@link #createArtifact()} instead
+ */
+ @Deprecated
+ public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+ return null;
+ }
+
+ /**
+ * @deprecated override {@link #createArtifact()} instead
+ */
+ @Deprecated
+ @NotNull
+ public String suggestArtifactName() {
+ return "unnamed";
+ }
+
+ @Nullable
+ public NewArtifactConfiguration createArtifact() {
+ final String name = suggestArtifactName();
+ return new NewArtifactConfiguration(createRootElement(name), name, null);
+ }
+
+ public void setUpArtifact(@NotNull Artifact artifact, @NotNull NewArtifactConfiguration configuration) {
+ }
+
+ public static class NewArtifactConfiguration {
+ private final CompositePackagingElement<?> myRootElement;
+ private final String myArtifactName;
+ private final ArtifactType myArtifactType;
+
+ public NewArtifactConfiguration(CompositePackagingElement<?> rootElement, String artifactName, ArtifactType artifactType) {
+ myRootElement = rootElement;
+ myArtifactName = artifactName;
+ myArtifactType = artifactType;
+ }
+
+ public CompositePackagingElement<?> getRootElement() {
+ return myRootElement;
+ }
+
+ public String getArtifactName() {
+ return myArtifactName;
+ }
+
+ public ArtifactType getArtifactType() {
+ return myArtifactType;
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java
new file mode 100644
index 0000000..130d0e2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java
@@ -0,0 +1,100 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.ui.ArtifactProblemsHolder;
+import com.intellij.packaging.ui.PackagingSourceItem;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactType {
+ public static final ExtensionPointName<ArtifactType> EP_NAME = ExtensionPointName.create("com.intellij.packaging.artifactType");
+ private final String myId;
+ private final String myTitle;
+
+ protected ArtifactType(@NonNls String id, String title) {
+ myId = id;
+ myTitle = title;
+ }
+
+ public final String getId() {
+ return myId;
+ }
+
+ public String getPresentableName() {
+ return myTitle;
+ }
+
+ @NotNull
+ public abstract Icon getIcon();
+
+ @Nullable
+ public String getDefaultPathFor(@NotNull PackagingSourceItem sourceItem) {
+ return getDefaultPathFor(sourceItem.getKindOfProducedElements());
+ }
+
+ @Nullable
+ public abstract String getDefaultPathFor(@NotNull PackagingElementOutputKind kind);
+
+ public boolean isSuitableItem(@NotNull PackagingSourceItem sourceItem) {
+ return true;
+ }
+
+ public static ArtifactType[] getAllTypes() {
+ return Extensions.getExtensions(EP_NAME);
+ }
+
+ @Nullable
+ public static ArtifactType findById(@NotNull @NonNls String id) {
+ for (ArtifactType type : getAllTypes()) {
+ if (id.equals(type.getId())) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ @NotNull
+ public abstract CompositePackagingElement<?> createRootElement(@NotNull String artifactName);
+
+ @NotNull
+ public List<? extends ArtifactTemplate> getNewArtifactTemplates(@NotNull PackagingElementResolvingContext context) {
+ return Collections.emptyList();
+ }
+
+ public void checkRootElement(@NotNull CompositePackagingElement<?> rootElement, @NotNull Artifact artifact, @NotNull ArtifactProblemsHolder manager) {
+ }
+
+ @Nullable
+ public List<? extends PackagingElement<?>> getSubstitution(@NotNull Artifact artifact, @NotNull PackagingElementResolvingContext context,
+ @NotNull ArtifactType parentType) {
+ return null;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.java
new file mode 100644
index 0000000..0b3f245
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.java
@@ -0,0 +1,37 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ModifiableArtifact extends Artifact {
+
+ void setBuildOnMake(boolean enabled);
+
+ void setOutputPath(String outputPath);
+
+ void setName(@NotNull String name);
+
+ void setRootElement(CompositePackagingElement<?> root);
+
+ void setProperties(ArtifactPropertiesProvider provider, ArtifactProperties<?> properties);
+
+ void setArtifactType(@NotNull ArtifactType selected);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java
new file mode 100644
index 0000000..5e6172f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java
@@ -0,0 +1,51 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ModifiableArtifactModel extends ArtifactModel {
+
+ @NotNull
+ ModifiableArtifact addArtifact(final @NotNull String name, @NotNull ArtifactType artifactType);
+
+ @NotNull
+ ModifiableArtifact addArtifact(final @NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement<?> rootElement);
+
+ void removeArtifact(@NotNull Artifact artifact);
+
+ @NotNull
+ ModifiableArtifact getOrCreateModifiableArtifact(@NotNull Artifact artifact);
+
+ @Nullable
+ Artifact getModifiableCopy(Artifact artifact);
+
+ void addListener(@NotNull ArtifactListener listener);
+
+ void removeListener(@NotNull ArtifactListener listener);
+
+
+ boolean isModified();
+
+ void commit();
+
+ void dispose();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java b/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java
new file mode 100644
index 0000000..fc0eb03
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java
@@ -0,0 +1,42 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface AntCopyInstructionCreator {
+
+ @NotNull
+ Tag createDirectoryContentCopyInstruction(@NotNull String dirPath);
+
+ @NotNull
+ Tag createFileCopyInstruction(@NotNull String filePath, String outputFileName);
+
+ @NotNull
+ AntCopyInstructionCreator subFolder(@NotNull String directoryName);
+
+ @Nullable
+ Generator createSubFolderCommand(@NotNull String directoryName);
+
+ @NotNull
+ Generator createExtractedDirectoryInstruction(@NotNull String jarPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java
new file mode 100644
index 0000000..46864f3
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.GenerationOptions;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public interface ArtifactAntGenerationContext {
+
+ void runBeforeCurrentArtifact(Generator generator);
+
+ void runBeforeBuild(Generator generator);
+
+ void runAfterBuild(Generator generator);
+
+ String createNewTempFileProperty(@NonNls String basePropertyName, @NonNls String fileName);
+
+ String getModuleOutputPath(@NonNls String moduleName);
+
+ String getModuleTestOutputPath(@NonNls String moduleName);
+
+ String getSubstitutedPath(@NonNls String path);
+
+ String getArtifactOutputProperty(@NotNull Artifact artifact);
+
+ Project getProject();
+
+ GenerationOptions getGenerationOptions();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java
new file mode 100644
index 0000000..6ee65f5
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java
@@ -0,0 +1,22 @@
+/*
+ * 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.packaging.elements;
+
+/**
+ * @author nik
+ */
+public interface ArtifactIncrementalCompilerContext {
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java
new file mode 100644
index 0000000..37da8ba
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactRootElement<S> extends CompositePackagingElement<S> {
+ protected ArtifactRootElement(PackagingElementType type) {
+ super(type);
+ }
+
+ @Override
+ public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+ return false;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java
new file mode 100644
index 0000000..5a09569
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java
@@ -0,0 +1,72 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * @author nik
+ */
+public abstract class ComplexPackagingElement<S> extends PackagingElement<S> {
+ protected ComplexPackagingElement(PackagingElementType type) {
+ super(type);
+ }
+
+ @Override
+ public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+ @NotNull ArtifactAntGenerationContext generationContext,
+ @NotNull ArtifactType artifactType) {
+ final List<? extends PackagingElement<?>> substitution = getSubstitution(resolvingContext, artifactType);
+ if (substitution == null) {
+ return Collections.emptyList();
+ }
+
+ final List<Generator> fileSets = new ArrayList<Generator>();
+ for (PackagingElement<?> element : substitution) {
+ fileSets.addAll(element.computeAntInstructions(resolvingContext, creator, generationContext, artifactType));
+ }
+ return fileSets;
+ }
+
+ @Override
+ public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+ @NotNull PackagingElementResolvingContext resolvingContext,
+ @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+ final List<? extends PackagingElement<?>> substitution = getSubstitution(resolvingContext, artifactType);
+ if (substitution == null) return;
+
+ for (PackagingElement<?> element : substitution) {
+ element.computeIncrementalCompilerInstructions(creator, resolvingContext, compilerContext,
+ getArtifactTypeForSubstitutedElements(resolvingContext, artifactType));
+ }
+ }
+
+ protected ArtifactType getArtifactTypeForSubstitutedElements(PackagingElementResolvingContext resolvingContext, ArtifactType artifactType) {
+ return artifactType;
+ }
+
+
+ @Nullable
+ public abstract List<? extends PackagingElement<?>> getSubstitution(@NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java
new file mode 100644
index 0000000..7fd3d99
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java
@@ -0,0 +1,39 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ComplexPackagingElementType<E extends ComplexPackagingElement<?>> extends PackagingElementType<E> {
+ protected ComplexPackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+ super(id, presentableName);
+ }
+
+ public abstract String getShowContentActionText();
+
+ @Nullable
+ public ModificationTracker getAllSubstitutionsModificationTracker(@NotNull Project project) {
+ return null;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java
new file mode 100644
index 0000000..fbfa5e0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java
@@ -0,0 +1,140 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class CompositePackagingElement<S> extends PackagingElement<S> implements RenameablePackagingElement {
+ private final List<PackagingElement<?>> myChildren = new ArrayList<PackagingElement<?>>();
+ private List<PackagingElement<?>> myUnmodifiableChildren;
+
+ protected CompositePackagingElement(PackagingElementType type) {
+ super(type);
+ }
+
+ public <T extends PackagingElement<?>> T addOrFindChild(@NotNull T child) {
+ for (PackagingElement<?> element : myChildren) {
+ if (element.isEqualTo(child)) {
+ if (element instanceof CompositePackagingElement) {
+ final List<PackagingElement<?>> children = ((CompositePackagingElement<?>)child).getChildren();
+ ((CompositePackagingElement<?>)element).addOrFindChildren(children);
+ }
+ //noinspection unchecked
+ return (T) element;
+ }
+ }
+ myChildren.add(child);
+ return child;
+ }
+
+ public void addFirstChild(@NotNull PackagingElement<?> child) {
+ myChildren.add(0, child);
+ for (int i = 1; i < myChildren.size(); i++) {
+ PackagingElement<?> element = myChildren.get(i);
+ if (element.isEqualTo(child)) {
+ if (element instanceof CompositePackagingElement<?>) {
+ ((CompositePackagingElement<?>)child).addOrFindChildren(((CompositePackagingElement<?>)element).getChildren());
+ }
+ myChildren.remove(i);
+ break;
+ }
+ }
+ }
+
+ public List<? extends PackagingElement<?>> addOrFindChildren(Collection<? extends PackagingElement<?>> children) {
+ List<PackagingElement<?>> added = new ArrayList<PackagingElement<?>>();
+ for (PackagingElement<?> child : children) {
+ added.add(addOrFindChild(child));
+ }
+ return added;
+ }
+
+ @Nullable
+ public PackagingElement<?> moveChild(int index, int direction) {
+ int target = index + direction;
+ if (0 <= index && index < myChildren.size() && 0 <= target && target < myChildren.size()) {
+ final PackagingElement<?> element1 = myChildren.get(index);
+ final PackagingElement<?> element2 = myChildren.get(target);
+ myChildren.set(index, element2);
+ myChildren.set(target, element1);
+ return element1;
+ }
+ return null;
+ }
+
+ public void removeChild(@NotNull PackagingElement<?> child) {
+ myChildren.remove(child);
+ }
+
+ public void removeChildren(@NotNull Collection<? extends PackagingElement<?>> children) {
+ myChildren.removeAll(children);
+ }
+
+ @NotNull
+ public List<PackagingElement<?>> getChildren() {
+ if (myUnmodifiableChildren == null) {
+ myUnmodifiableChildren = Collections.unmodifiableList(myChildren);
+ }
+ return myUnmodifiableChildren;
+ }
+
+ public boolean canBeRenamed() {
+ return true;
+ }
+
+ protected List<? extends Generator> computeChildrenGenerators(PackagingElementResolvingContext resolvingContext,
+ final AntCopyInstructionCreator copyInstructionCreator,
+ final ArtifactAntGenerationContext generationContext, ArtifactType artifactType) {
+ final List<Generator> generators = new ArrayList<Generator>();
+ for (PackagingElement<?> child : myChildren) {
+ generators.addAll(child.computeAntInstructions(resolvingContext, copyInstructionCreator, generationContext, artifactType));
+ }
+ return generators;
+ }
+
+ protected void computeChildrenInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+ @NotNull PackagingElementResolvingContext resolvingContext,
+ @NotNull ArtifactIncrementalCompilerContext compilerContext, ArtifactType artifactType) {
+ for (PackagingElement<?> child : myChildren) {
+ child.computeIncrementalCompilerInstructions(creator, resolvingContext, compilerContext, artifactType);
+ }
+ }
+
+ public void removeAllChildren() {
+ myChildren.clear();
+ }
+
+ @Nullable
+ public CompositePackagingElement<?> findCompositeChild(@NotNull String name) {
+ for (PackagingElement<?> child : myChildren) {
+ if (child instanceof CompositePackagingElement && name.equals(((CompositePackagingElement)child).getName())) {
+ return (CompositePackagingElement)child;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java
new file mode 100644
index 0000000..92af59d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class CompositePackagingElementType<E extends CompositePackagingElement<?>> extends PackagingElementType<E> {
+ protected CompositePackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+ super(id, presentableName);
+ }
+
+ @Override
+ public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+ return true;
+ }
+
+
+ @Nullable
+ public abstract CompositePackagingElement<?> createComposite(CompositePackagingElement<?> parent, @Nullable String baseName, @NotNull ArtifactEditorContext context);
+
+ @NotNull
+ public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact, @NotNull CompositePackagingElement<?> parent) {
+ final PackagingElement<?> composite = createComposite(parent, null, context);
+ return composite != null ? Collections.singletonList(composite) : Collections.<E>emptyList();
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java b/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java
new file mode 100644
index 0000000..7c1f1d0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface IncrementalCompilerInstructionCreator {
+
+ void addFileCopyInstruction(@NotNull VirtualFile file, @NotNull String outputFileName);
+
+ void addDirectoryCopyInstructions(@NotNull VirtualFile directory);
+
+ void addDirectoryCopyInstructions(@NotNull VirtualFile directory, @Nullable PackagingFileFilter filter);
+
+ IncrementalCompilerInstructionCreator subFolder(@NotNull String directoryName);
+
+ IncrementalCompilerInstructionCreator archive(@NotNull String archiveFileName);
+
+ IncrementalCompilerInstructionCreator subFolderByRelativePath(@NotNull String relativeDirectoryPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java
new file mode 100644
index 0000000..599c07f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2011 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.packaging.elements;
+
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ManifestFileProvider {
+ @Nullable
+ List<String> getClasspathFromManifest(@NotNull CompositePackagingElement<?> archiveRoot, @NotNull ArtifactType artifactType);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java
new file mode 100644
index 0000000..377616b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElement<S> implements PersistentStateComponent<S> {
+ private final PackagingElementType myType;
+
+ protected PackagingElement(PackagingElementType type) {
+ myType = type;
+ }
+
+ public abstract PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context);
+
+ public final PackagingElementType getType() {
+ return myType;
+ }
+
+ public abstract List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+ @NotNull ArtifactAntGenerationContext generationContext,
+ @NotNull ArtifactType artifactType);
+
+ public abstract void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator, @NotNull PackagingElementResolvingContext resolvingContext,
+ @NotNull ArtifactIncrementalCompilerContext compilerContext,
+ @NotNull ArtifactType artifactType);
+
+ public abstract boolean isEqualTo(@NotNull PackagingElement<?> element);
+
+ @NotNull
+ public PackagingElementOutputKind getFilesKind(PackagingElementResolvingContext context) {
+ return PackagingElementOutputKind.OTHER;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java
new file mode 100644
index 0000000..d6574fa
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java
@@ -0,0 +1,124 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementFactory {
+
+ public static PackagingElementFactory getInstance() {
+ return ServiceManager.getService(PackagingElementFactory.class);
+ }
+
+ @NotNull
+ public abstract ArtifactRootElement<?> createArtifactRootElement();
+
+ @NotNull
+ public abstract CompositePackagingElement<?> createDirectory(@NotNull @NonNls String directoryName);
+
+ @NotNull
+ public abstract CompositePackagingElement<?> createArchive(@NotNull @NonNls String archiveFileName);
+
+ public abstract PackagingElement<?> createFileCopy(@NotNull String filePath, @Nullable String outputFileName);
+
+ @NotNull
+ public abstract PackagingElement<?> createModuleOutput(@NotNull String moduleName, @NotNull Project project);
+
+ @NotNull
+ public abstract PackagingElement<?> createModuleOutput(@NotNull Module module);
+
+ @NotNull
+ public abstract PackagingElement<?> createTestModuleOutput(@NotNull Module module);
+
+ @NotNull
+ public abstract List<? extends PackagingElement<?>> createLibraryElements(@NotNull Library library);
+
+ @NotNull
+ public abstract PackagingElement<?> createArtifactElement(@NotNull ArtifactPointer artifactPointer, @NotNull Project project);
+
+ @NotNull
+ public abstract PackagingElement<?> createArtifactElement(@NotNull Artifact artifact, @NotNull Project project);
+
+ @NotNull
+ public abstract PackagingElement<?> createLibraryFiles(@NotNull String libraryName, @NotNull String level, String moduleName);
+
+
+ @NotNull
+ public abstract PackagingElement<?> createDirectoryCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath);
+
+ @NotNull
+ public abstract PackagingElement<?> createExtractedDirectoryWithParentDirectories(@NotNull String jarPath, @NotNull String pathInJar,
+ @NotNull String relativeOutputPath);
+
+ @NotNull
+ public abstract PackagingElement<?> createExtractedDirectory(@NotNull VirtualFile jarEntry);
+
+ @NotNull
+ public abstract PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath,
+ @Nullable String outputFileName);
+
+ @NotNull
+ public abstract PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath);
+
+
+ @NotNull
+ public abstract CompositePackagingElement<?> getOrCreateDirectory(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath);
+
+ @NotNull
+ public abstract CompositePackagingElement<?> getOrCreateArchive(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath);
+
+ public abstract void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath,
+ final String outputFileName);
+
+ public abstract void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath);
+
+ @NotNull
+ public abstract PackagingElement<?> createParentDirectories(@NotNull String relativeOutputPath, @NotNull PackagingElement<?> element);
+
+
+ @NotNull
+ public abstract List<? extends PackagingElement<?>> createParentDirectories(@NotNull String relativeOutputPath, @NotNull List<? extends PackagingElement<?>> elements);
+
+ @NotNull
+
+ public abstract CompositePackagingElementType<?>[] getCompositeElementTypes();
+
+ @Nullable
+ public abstract PackagingElementType<?> findElementType(String id);
+
+ @NotNull
+ public abstract PackagingElementType<?>[] getNonCompositeElementTypes();
+
+ @NotNull
+ public abstract PackagingElementType[] getAllElementTypes();
+
+ @NotNull
+ public abstract ComplexPackagingElementType<?>[] getComplexElementTypes();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.java
new file mode 100644
index 0000000..4ba42df
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.java
@@ -0,0 +1,40 @@
+/*
+ * 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.packaging.elements;
+
+/**
+ * @author nik
+ */
+public class PackagingElementOutputKind {
+ public static final PackagingElementOutputKind DIRECTORIES_WITH_CLASSES = new PackagingElementOutputKind(true, false);
+ public static final PackagingElementOutputKind JAR_FILES = new PackagingElementOutputKind(false, true);
+ public static final PackagingElementOutputKind OTHER = new PackagingElementOutputKind(false, false);
+ private final boolean myContainsDirectoriesWithClasses;
+ private final boolean myContainsJarFiles;
+
+ public PackagingElementOutputKind(boolean containsDirectoriesWithClasses, boolean containsJarFiles) {
+ myContainsDirectoriesWithClasses = containsDirectoriesWithClasses;
+ myContainsJarFiles = containsJarFiles;
+ }
+
+ public boolean containsDirectoriesWithClasses() {
+ return myContainsDirectoriesWithClasses;
+ }
+
+ public boolean containsJarFiles() {
+ return myContainsJarFiles;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java
new file mode 100644
index 0000000..a033d3c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java
@@ -0,0 +1,47 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.project.Project;
+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.packaging.artifacts.ArtifactModel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface PackagingElementResolvingContext {
+ @NotNull
+ Project getProject();
+
+ @NotNull
+ ArtifactModel getArtifactModel();
+
+ @NotNull
+ ModulesProvider getModulesProvider();
+
+ @NotNull
+ FacetsProvider getFacetsProvider();
+
+ @Nullable
+ Library findLibrary(@NotNull String level, @NotNull String libraryName);
+
+ @NotNull
+ ManifestFileProvider getManifestFileProvider();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java
new file mode 100644
index 0000000..48cc0c2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java
@@ -0,0 +1,79 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementType<E extends PackagingElement<?>> {
+ public static final ExtensionPointName<PackagingElementType> EP_NAME = ExtensionPointName.create("com.intellij.packaging.elementType");
+ private final String myId;
+ private final String myPresentableName;
+
+ protected PackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+ myId = id;
+ myPresentableName = presentableName;
+ }
+
+ public final String getId() {
+ return myId;
+ }
+
+ public String getPresentableName() {
+ return myPresentableName;
+ }
+
+ @Nullable
+ public Icon getCreateElementIcon() {
+ return null;
+ }
+
+ public abstract boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact);
+
+ @NotNull
+ public abstract List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+ @NotNull CompositePackagingElement<?> parent);
+
+ @NotNull
+ public abstract E createEmpty(@NotNull Project project);
+
+ protected static <T extends PackagingElementType<?>> T getInstance(final Class<T> aClass) {
+ for (PackagingElementType type : Extensions.getExtensions(EP_NAME)) {
+ if (aClass.isInstance(type)) {
+ return aClass.cast(type);
+ }
+ }
+ throw new AssertionError();
+ }
+
+ @Nullable
+ public PackagingElementPropertiesPanel createElementPropertiesPanel(@NotNull E element, @NotNull ArtifactEditorContext context) {
+ return null;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java
new file mode 100644
index 0000000..363b391
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java
@@ -0,0 +1,30 @@
+/*
+ * 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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.compiler.CompileContext;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingFileFilter {
+
+ public abstract boolean accept(@NotNull VirtualFile virtualFile, @NotNull CompileContext context);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.java
new file mode 100644
index 0000000..d34fb89
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.java
@@ -0,0 +1,29 @@
+/*
+ * 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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface RenameablePackagingElement {
+ String getName();
+
+ boolean canBeRenamed();
+
+ void rename(@NotNull String newName);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java
new file mode 100644
index 0000000..144bda2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactEditor {
+ void updateLayoutTree();
+
+ void putLibraryIntoDefaultLocation(@NotNull Library library);
+
+ void putModuleIntoDefaultLocation(@NotNull Module module);
+
+ void addToClasspath(CompositePackagingElement<?> element, List<String> classpath);
+
+ boolean isDisposed();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java
new file mode 100644
index 0000000..7ede5be
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java
@@ -0,0 +1,80 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.facet.Facet;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactEditorContext extends PackagingElementResolvingContext {
+
+ void queueValidation();
+
+ @NotNull
+ ArtifactType getArtifactType();
+
+ @NotNull
+ ModifiableArtifactModel getOrCreateModifiableArtifactModel();
+
+ @Nullable
+ ModifiableModuleModel getModifiableModuleModel();
+
+ @NotNull
+ ModifiableRootModel getOrCreateModifiableRootModel(@NotNull Module module);
+
+ @Nullable
+ ManifestFileConfiguration getManifestFile(CompositePackagingElement<?> element, ArtifactType artifactType);
+
+
+ CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact);
+
+ void editLayout(@NotNull Artifact artifact, Runnable runnable);
+
+ ArtifactEditor getOrCreateEditor(Artifact originalArtifact);
+
+ ArtifactEditor getThisArtifactEditor();
+
+ void selectArtifact(@NotNull Artifact artifact);
+
+ void selectFacet(@NotNull Facet<?> facet);
+
+ void selectModule(@NotNull Module module);
+
+ void selectLibrary(@NotNull Library library);
+
+
+ List<Artifact> chooseArtifacts(List<? extends Artifact> artifacts, String title);
+
+ List<Module> chooseModules(List<Module> modules, final String title);
+
+ List<Library> chooseLibraries(String title);
+
+ Artifact getArtifact();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java
new file mode 100644
index 0000000..851ce79
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java
@@ -0,0 +1,37 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactProblemQuickFix {
+ private String myActionName;
+
+ protected ArtifactProblemQuickFix() {
+ this("Fix");
+ }
+
+ protected ArtifactProblemQuickFix(String actionName) {
+ myActionName = actionName;
+ }
+
+ public String getActionName() {
+ return myActionName;
+ }
+
+ public abstract void performFix(ArtifactEditorContext artifactEditorContext);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java
new file mode 100644
index 0000000..abe8229
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactProblemsHolder {
+ @NotNull
+ PackagingElementResolvingContext getContext();
+
+ void registerError(@NotNull String message, @NotNull String problemTypeId);
+
+ void registerError(@NotNull String message, @NotNull String problemTypeId, @Nullable List<PackagingElement<?>> pathToPlace,
+ @NotNull ArtifactProblemQuickFix... quickFixes);
+
+ void registerWarning(@NotNull String message, @NotNull String problemTypeId, @Nullable List<PackagingElement<?>> pathToPlace,
+ @NotNull ArtifactProblemQuickFix... quickFixes);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
new file mode 100644
index 0000000..220b079
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.openapi.options.UnnamedConfigurable;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPropertiesEditor implements UnnamedConfigurable {
+ public static final String VALIDATION_TAB = "Validation";
+ public static final String POST_PROCESSING_TAB = "Post-processing";
+ public static final String PRE_PROCESSING_TAB = "Pre-processing";
+
+ public abstract String getTabName();
+
+ public abstract void apply();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.java
new file mode 100644
index 0000000..116d68d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.java
@@ -0,0 +1,103 @@
+/*
+ * 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.packaging.ui;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author nik
+ */
+public class ManifestFileConfiguration {
+ private final boolean myWritable;
+ private List<String> myClasspath = new ArrayList<String>();
+ private String myMainClass;
+ private String myManifestFilePath;
+
+ public ManifestFileConfiguration(@NotNull ManifestFileConfiguration configuration) {
+ myWritable = configuration.isWritable();
+ myClasspath.addAll(configuration.getClasspath());
+ myMainClass = configuration.getMainClass();
+ myManifestFilePath = configuration.getManifestFilePath();
+ }
+
+ public ManifestFileConfiguration(@NotNull String manifestFilePath, @Nullable List<String> classpath, @Nullable String mainClass, boolean isWritable) {
+ myWritable = isWritable;
+ if (classpath != null) {
+ myClasspath.addAll(classpath);
+ }
+ myMainClass = mainClass;
+ myManifestFilePath = manifestFilePath;
+ }
+
+ public List<String> getClasspath() {
+ return myClasspath;
+ }
+
+ public boolean isWritable() {
+ return myWritable;
+ }
+
+ public void setClasspath(List<String> classpath) {
+ myClasspath = classpath;
+ }
+
+ public String getMainClass() {
+ return myMainClass;
+ }
+
+ public void setMainClass(String mainClass) {
+ myMainClass = mainClass;
+ }
+
+ public String getManifestFilePath() {
+ return myManifestFilePath;
+ }
+
+ public void setManifestFilePath(String manifestFilePath) {
+ myManifestFilePath = manifestFilePath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ManifestFileConfiguration)) return false;
+
+ ManifestFileConfiguration that = (ManifestFileConfiguration)o;
+
+ if (!myClasspath.equals(that.myClasspath)) return false;
+ if (myMainClass != null ? !myMainClass.equals(that.myMainClass) : that.myMainClass != null) return false;
+ if (myManifestFilePath != null ? !myManifestFilePath.equals(that.myManifestFilePath) : that.myManifestFilePath != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addToClasspath(List<String> classpath) {
+ for (String path : classpath) {
+ if (!myClasspath.contains(path)) {
+ myClasspath.add(path);
+ }
+ }
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.java
new file mode 100644
index 0000000..d26375c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.java
@@ -0,0 +1,23 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementPresentation extends TreeNodePresentation {
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.java
new file mode 100644
index 0000000..739677e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.java
@@ -0,0 +1,29 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.openapi.options.UnnamedConfigurable;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementPropertiesPanel implements UnnamedConfigurable {
+
+ public abstract void apply();
+
+ public void disposeUIResources() {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java
new file mode 100644
index 0000000..f193e9b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java
@@ -0,0 +1,33 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public class PackagingElementWeights {
+ public static final int ARTIFACT = 100;
+ public static final int DIRECTORY = 50;
+ public static final int DIRECTORY_COPY = 40;
+ public static final int EXTRACTED_DIRECTORY = 39;
+ public static final int LIBRARY = 30;
+ public static final int MODULE = 20;
+ public static final int FACET = 10;
+ public static final int FILE_COPY = 0;
+
+ private PackagingElementWeights() {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java
new file mode 100644
index 0000000..d222876
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingSourceItem {
+ private boolean myProvideElements;
+
+ protected PackagingSourceItem() {
+ this(true);
+ }
+
+ protected PackagingSourceItem(boolean provideElements) {
+ myProvideElements = provideElements;
+ }
+
+ @Override
+ public abstract boolean equals(Object obj);
+
+ @Override
+ public abstract int hashCode();
+
+ public abstract SourceItemPresentation createPresentation(@NotNull ArtifactEditorContext context);
+
+ @NotNull
+ public abstract List<? extends PackagingElement<?>> createElements(@NotNull ArtifactEditorContext context);
+
+ public boolean isProvideElements() {
+ return myProvideElements;
+ }
+
+ @NotNull
+ public PackagingElementOutputKind getKindOfProducedElements() {
+ return PackagingElementOutputKind.OTHER;
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.java
new file mode 100644
index 0000000..3b62092
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.java
@@ -0,0 +1,34 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingSourceItemsProvider {
+ public static final ExtensionPointName<PackagingSourceItemsProvider> EP_NAME = ExtensionPointName.create("com.intellij.packaging.sourceItemProvider");
+
+ @NotNull
+ public abstract Collection<? extends PackagingSourceItem> getSourceItems(@NotNull ArtifactEditorContext editorContext, @NotNull Artifact artifact,
+ @Nullable PackagingSourceItem parent);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java
new file mode 100644
index 0000000..42de0ae
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java
@@ -0,0 +1,22 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class SourceItemPresentation extends TreeNodePresentation {
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.java b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.java
new file mode 100644
index 0000000..70e05f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.java
@@ -0,0 +1,31 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public class SourceItemWeights {
+ public static final int ARTIFACTS_GROUP_WEIGHT = 200;
+ public static final int ARTIFACT_WEIGHT = 150;
+ public static final int MODULE_GROUP_WEIGHT = 100;
+ public static final int MODULE_WEIGHT = 50;
+ public static final int MODULE_OUTPUT_WEIGHT = 30;
+ public static final int LIBRARY_WEIGHT = 10;
+
+ private SourceItemWeights() {
+ }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java
new file mode 100644
index 0000000..96fe6ec
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.ui;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ui.SimpleTextAttributes;
+
+/**
+ * @author nik
+ */
+public abstract class TreeNodePresentation {
+ public abstract String getPresentableName();
+
+ public String getSearchName() {
+ return getPresentableName();
+ }
+
+ public abstract void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes,
+ SimpleTextAttributes commentAttributes);
+
+ @Nullable
+ public String getTooltipText() {
+ return null;
+ }
+
+ public boolean canNavigateToSource() {
+ return false;
+ }
+
+ public void navigateToSource() {
+ }
+
+ /**
+ * @deprecated this method is not used and will be removed in the future
+ */
+ @Nullable
+ public Object getSourceObject() {
+ return null;
+ }
+
+ public abstract int getWeight();
+}