diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java index 3b14386067f4..b5635bf76df5 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.packaging.impl.artifacts; +import com.intellij.openapi.roots.ProjectModelExternalSource; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -23,8 +24,8 @@ import com.intellij.packaging.artifacts.*; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.impl.elements.ArchivePackagingElement; import com.intellij.util.EventDispatcher; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -43,20 +44,24 @@ public class ArtifactImpl extends UserDataHolderBase implements ModifiableArtifa private final EventDispatcher myDispatcher; private ArtifactType myArtifactType; private Map> myProperties; + private final ProjectModelExternalSource myExternalSource; - public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, @NotNull CompositePackagingElement rootElement, - String outputPath) { - this(name, artifactType, buildOnMake, rootElement, outputPath, null); + public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, + @NotNull CompositePackagingElement rootElement, String outputPath, + @Nullable ProjectModelExternalSource externalSource) { + this(name, artifactType, buildOnMake, rootElement, outputPath, externalSource, null); } - public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, @NotNull CompositePackagingElement rootElement, - String outputPath, - EventDispatcher dispatcher) { + + public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, + @NotNull CompositePackagingElement rootElement, String outputPath, + @Nullable ProjectModelExternalSource externalSource, EventDispatcher dispatcher) { myName = name; myArtifactType = artifactType; myBuildOnMake = buildOnMake; myRootElement = rootElement; myOutputPath = outputPath; myDispatcher = dispatcher; + myExternalSource = externalSource; myProperties = new HashMap<>(); resetProperties(); } @@ -96,8 +101,15 @@ public class ArtifactImpl extends UserDataHolderBase implements ModifiableArtifa return Collections.unmodifiableCollection(myProperties.keySet()); } + @Nullable + @Override + public ProjectModelExternalSource getExternalSource() { + return myExternalSource; + } + public ArtifactImpl createCopy(EventDispatcher dispatcher) { - final ArtifactImpl artifact = new ArtifactImpl(myName, myArtifactType, myBuildOnMake, myRootElement, myOutputPath, dispatcher); + final ArtifactImpl artifact = new ArtifactImpl(myName, myArtifactType, myBuildOnMake, myRootElement, myOutputPath, myExternalSource, + dispatcher); for (Map.Entry> entry : myProperties.entrySet()) { final ArtifactProperties newProperties = artifact.myProperties.get(entry.getKey()); //noinspection unchecked diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java index 38c548a0ea28..ab10a1c5b092 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java @@ -25,11 +25,14 @@ import com.intellij.openapi.components.Storage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.ProjectLoadingErrorsNotifier; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ExternalProjectSystemRegistry; +import com.intellij.openapi.roots.ProjectModelExternalSource; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector; import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SimpleModificationTracker; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.packaging.artifacts.*; @@ -122,6 +125,12 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo artifactState.setOutputPath(artifact.getOutputPath()); artifactState.setRootElement(serializePackagingElement(artifact.getRootElement())); artifactState.setArtifactType(artifact.getArtifactType().getId()); + ProjectModelExternalSource externalSource = artifact.getExternalSource(); + if (externalSource != null && Registry.is("store.imported.project.elements.separately")) { + //we can add this attribute only if the artifact configuration will be stored separately, otherwise we will get modified files in .idea/artifacts. + artifactState.setExternalSystemId(externalSource.getId()); + } + for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) { final ArtifactPropertiesState propertiesState = serializeProperties(provider, artifact.getProperties(provider)); if (propertiesState != null) { @@ -210,8 +219,9 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo private ArtifactImpl loadArtifact(ArtifactState state) { ArtifactType type = ArtifactType.findById(state.getArtifactType()); + ProjectModelExternalSource externalSource = findExternalSource(state.getExternalSystemId()); if (type == null) { - return createInvalidArtifact(state, "Unknown artifact type: " + state.getArtifactType()); + return createInvalidArtifact(state, externalSource, "Unknown artifact type: " + state.getArtifactType()); } final Element element = state.getRootElement(); @@ -222,14 +232,15 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo rootElement = (CompositePackagingElement)deserializeElement(element); } catch (UnknownPackagingElementTypeException e) { - return createInvalidArtifact(state, "Unknown element: " + e.getTypeId()); + return createInvalidArtifact(state, externalSource, "Unknown element: " + e.getTypeId()); } } else { rootElement = type.createRootElement(artifactName); } - final ArtifactImpl artifact = new ArtifactImpl(artifactName, type, state.isBuildOnMake(), rootElement, state.getOutputPath()); + final ArtifactImpl artifact = new ArtifactImpl(artifactName, type, state.isBuildOnMake(), rootElement, state.getOutputPath(), + externalSource); final List propertiesList = state.getPropertiesList(); for (ArtifactPropertiesState propertiesState : propertiesList) { final ArtifactPropertiesProvider provider = ArtifactPropertiesProvider.findById(propertiesState.getId()); @@ -237,19 +248,24 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo deserializeProperties(artifact.getProperties(provider), propertiesState); } else { - return createInvalidArtifact(state, "Unknown artifact properties: " + propertiesState.getId()); + return createInvalidArtifact(state, externalSource, "Unknown artifact properties: " + propertiesState.getId()); } } return artifact; } - private InvalidArtifact createInvalidArtifact(ArtifactState state, String errorMessage) { - final InvalidArtifact artifact = new InvalidArtifact(state, errorMessage); + private InvalidArtifact createInvalidArtifact(ArtifactState state, ProjectModelExternalSource externalSource, String errorMessage) { + final InvalidArtifact artifact = new InvalidArtifact(state, errorMessage, externalSource); ProjectLoadingErrorsNotifier.getInstance(myProject).registerError(new ArtifactLoadingErrorDescription(myProject, artifact)); UnknownFeaturesCollector.getInstance(myProject).registerUnknownFeature("com.intellij.packaging.artifacts.ArtifactType", state.getArtifactType(), "Artifact"); return artifact; } + @Nullable + private static ProjectModelExternalSource findExternalSource(@Nullable String externalSourceId) { + return externalSourceId != null ? ExternalProjectSystemRegistry.getInstance().getSourceById(externalSourceId) : null; + } + private static void deserializeProperties(ArtifactProperties artifactProperties, ArtifactPropertiesState propertiesState) { final Element options = propertiesState.getOptions(); if (artifactProperties == null || options == null) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java index e3af7f8ff3f1..5ccaf6a6a35a 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.packaging.impl.artifacts; +import com.intellij.openapi.roots.ProjectModelExternalSource; import com.intellij.packaging.artifacts.*; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.util.EventDispatcher; @@ -68,9 +69,16 @@ public class ArtifactModelImpl extends ArtifactModelBase implements ModifiableAr @NotNull public ModifiableArtifact addArtifact(@NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement rootElement) { + return addArtifact(name, artifactType, rootElement, null); + } + + @Override + @NotNull + public ModifiableArtifact addArtifact(@NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement rootElement, + @Nullable ProjectModelExternalSource externalSource) { final String uniqueName = generateUniqueName(name); final String outputPath = ArtifactUtil.getDefaultArtifactOutputPath(uniqueName, myArtifactManager.getProject()); - final ArtifactImpl artifact = new ArtifactImpl(uniqueName, artifactType, false, rootElement, outputPath, myDispatcher); + final ArtifactImpl artifact = new ArtifactImpl(uniqueName, artifactType, false, rootElement, outputPath, externalSource, myDispatcher); myOriginalArtifacts.add(artifact); myArtifact2ModifiableCopy.put(artifact, artifact); myModifiable2Original.put(artifact, artifact); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java index c6df02ec5188..06c44fe6bc34 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java @@ -15,6 +15,7 @@ */ package com.intellij.packaging.impl.artifacts; +import com.intellij.openapi.roots.ProjectModelExternalSource; import com.intellij.packaging.elements.PackagingElementFactory; import org.jetbrains.jps.model.serialization.artifact.ArtifactState; @@ -25,8 +26,9 @@ public class InvalidArtifact extends ArtifactImpl { private ArtifactState myState; private final String myErrorMessage; - public InvalidArtifact(ArtifactState state, String errorMessage) { - super(state.getName(), InvalidArtifactType.getInstance(), false, PackagingElementFactory.getInstance().createArtifactRootElement(), ""); + public InvalidArtifact(ArtifactState state, String errorMessage, ProjectModelExternalSource externalSource) { + super(state.getName(), InvalidArtifactType.getInstance(), false, PackagingElementFactory.getInstance().createArtifactRootElement(), "", + externalSource); myState = state; myErrorMessage = errorMessage; } diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java index 8155cf05af6e..318d6a5e7d6e 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java +++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java @@ -15,6 +15,7 @@ */ package com.intellij.packaging.artifacts; +import com.intellij.openapi.roots.ProjectModelElement; import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packaging.elements.CompositePackagingElement; @@ -26,7 +27,7 @@ import java.util.Collection; /** * @author nik */ -public interface Artifact extends UserDataHolder { +public interface Artifact extends UserDataHolder, ProjectModelElement { @NotNull ArtifactType getArtifactType(); diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java index 5e6172f8e6c2..ef0f2d61b419 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java +++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java @@ -15,6 +15,7 @@ */ package com.intellij.packaging.artifacts; +import com.intellij.openapi.roots.ProjectModelExternalSource; import com.intellij.packaging.elements.CompositePackagingElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +31,10 @@ public interface ModifiableArtifactModel extends ArtifactModel { @NotNull ModifiableArtifact addArtifact(final @NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement rootElement); + @NotNull + ModifiableArtifact addArtifact(@NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement rootElement, + @Nullable ProjectModelExternalSource externalSource); + void removeArtifact(@NotNull Artifact artifact); @NotNull diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java index 060d281d3331..4ec515c71f3c 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/ArtifactState.java @@ -37,6 +37,7 @@ public class ArtifactState { private boolean myBuildOnMake; private Element myRootElement; private List myPropertiesList = new ArrayList<>(); + private String myExternalSystemId; @Attribute(NAME_ATTRIBUTE) public String getName() { @@ -53,6 +54,11 @@ public class ArtifactState { return myBuildOnMake; } + @Attribute("external-system-id") + public String getExternalSystemId() { + return myExternalSystemId; + } + @Tag("output-path") public String getOutputPath() { return myOutputPath; @@ -89,6 +95,10 @@ public class ArtifactState { myBuildOnMake = buildOnMake; } + public void setExternalSystemId(String externalSystemId) { + myExternalSystemId = externalSystemId; + } + public void setRootElement(Element rootElement) { myRootElement = rootElement; }