From ce62f75bcb409dff802c84b44d1afa4ec8bc91a9 Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Fri, 10 Jul 2009 08:40:22 +0400 Subject: [PATCH] artifacts validation: checking descriptors --- .../impl/artifacts/ArtifactModelImpl.java | 7 +-- .../impl/elements/FileCopyPackagingElement.java | 6 ++- .../intellij/packaging/artifacts/ArtifactType.java | 3 +- .../packaging/ui/ArtifactProblemQuickFix.java | 22 ++++++++ .../packaging/ui/ArtifactValidationManager.java | 17 ++++++ .../artifacts/ArtifactConfigurable.java | 3 +- .../artifacts/ArtifactEditorImpl.java | 39 ++++++++++++++ .../artifacts/ArtifactErrorPanel.form | 34 ++++++++++++ .../artifacts/ArtifactErrorPanel.java | 54 +++++++++++++++++++ .../ui/configuration/artifacts/ArtifactUtil.java | 61 +++++++++++++++++++++- .../artifacts/ArtifactsEditorImpl.form | 10 +++- .../ui/configuration/artifacts/LayoutTree.java | 1 + .../artifacts/LayoutTreeComponent.java | 2 + 13 files changed, 249 insertions(+), 10 deletions(-) create mode 100644 compiler/openapi/com/intellij/packaging/ui/ArtifactProblemQuickFix.java create mode 100644 compiler/openapi/com/intellij/packaging/ui/ArtifactValidationManager.java create mode 100644 source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.form create mode 100644 source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java diff --git a/compiler/impl/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java b/compiler/impl/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java index 56782e4ed2..6470565ff8 100644 --- a/compiler/impl/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java +++ b/compiler/impl/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java @@ -1,8 +1,6 @@ package com.intellij.packaging.impl.artifacts; -import com.intellij.openapi.roots.CompilerProjectExtension; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactUtil; import com.intellij.packaging.artifacts.*; import com.intellij.util.EventDispatcher; import org.jetbrains.annotations.NotNull; @@ -50,8 +48,7 @@ public class ArtifactModelImpl extends ArtifactModelBase implements ModifiableAr @NotNull public ModifiableArtifact addArtifact(@NotNull final String name, @NotNull ArtifactType artifactType) { - final String outputUrl = CompilerProjectExtension.getInstance(myArtifactManager.getProject()).getCompilerOutputUrl(); - final String outputPath = outputUrl != null ? VfsUtil.urlToPath(outputUrl) + "/artifacts/" + FileUtil.sanitizeFileName(name) : null; + final String outputPath = ArtifactUtil.getDefaultArtifactOutputPath(name, myArtifactManager.getProject()); final ArtifactImpl artifact = new ArtifactImpl(generateUniqueName(name), artifactType, false, artifactType.createRootElement(), outputPath, true); diff --git a/compiler/impl/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java b/compiler/impl/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java index d4b89010e4..034de05e54 100644 --- a/compiler/impl/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java +++ b/compiler/impl/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java @@ -47,11 +47,15 @@ public class FileCopyPackagingElement extends PackagingElement createRootElement(); - public void checkRootElement(@NotNull CompositePackagingElement rootElement) { + public void checkRootElement(@NotNull CompositePackagingElement rootElement, @NotNull ArtifactValidationManager manager) { } } diff --git a/compiler/openapi/com/intellij/packaging/ui/ArtifactProblemQuickFix.java b/compiler/openapi/com/intellij/packaging/ui/ArtifactProblemQuickFix.java new file mode 100644 index 0000000000..1db1b4e974 --- /dev/null +++ b/compiler/openapi/com/intellij/packaging/ui/ArtifactProblemQuickFix.java @@ -0,0 +1,22 @@ +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(); +} diff --git a/compiler/openapi/com/intellij/packaging/ui/ArtifactValidationManager.java b/compiler/openapi/com/intellij/packaging/ui/ArtifactValidationManager.java new file mode 100644 index 0000000000..1e854a8548 --- /dev/null +++ b/compiler/openapi/com/intellij/packaging/ui/ArtifactValidationManager.java @@ -0,0 +1,17 @@ +package com.intellij.packaging.ui; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public interface ArtifactValidationManager { + + PackagingEditorContext getContext(); + + + void registerProblem(@NotNull String messsage); + + void registerProblem(@NotNull String messsage, @Nullable ArtifactProblemQuickFix quickFix); +} diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java index 533ad41a4d..4799356b2b 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java @@ -8,8 +8,8 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactType; -import com.intellij.packaging.ui.PackagingEditorContext; import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.ui.PackagingEditorContext; import org.jetbrains.annotations.Nls; import javax.swing.*; @@ -37,6 +37,7 @@ public class ArtifactConfigurable extends NamedConfigurable { final String oldName = getArtifact().getName(); if (name != null && !name.equals(oldName) && !myIsInUpdateName) { myPackagingEditorContext.getModifiableArtifactModel().getOrCreateModifiableArtifact(myOriginalArtifact).setName(name); + myEditor.updateOutputPath(oldName, name); } } diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java index 18f75939ba..fb5aea21ba 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java @@ -20,6 +20,8 @@ import com.intellij.packaging.artifacts.ModifiableArtifact; import com.intellij.packaging.elements.PackagingElementType; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.ui.PackagingEditorContext; +import com.intellij.packaging.ui.ArtifactValidationManager; +import com.intellij.packaging.ui.ArtifactProblemQuickFix; import com.intellij.ui.PopupHandler; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TabbedPaneWrapper; @@ -46,6 +48,7 @@ public class ArtifactEditorImpl implements ArtifactEditor { private JCheckBox myShowIncludedCheckBox; private JPanel myEditorPanel; private JCheckBox myClearOnRebuildCheckBox; + private JPanel myErrorPanelPlace; private Splitter mySplitter; private final Project myProject; private final ComplexElementSubstitutionParameters mySubstitutionParameters = new ComplexElementSubstitutionParameters(); @@ -56,6 +59,8 @@ public class ArtifactEditorImpl implements ArtifactEditor { private final LayoutTreeComponent myLayoutTreeComponent; private TabbedPaneWrapper myTabbedPane; private ArtifactPropertiesEditors myPropertiesEditors; + private ArtifactErrorPanel myErrorPanel; + private ArtifactEditorImpl.ArtifactValidationManagerImpl myValidationManager; public ArtifactEditorImpl(final PackagingEditorContext context, Artifact artifact) { myContext = context; @@ -73,6 +78,12 @@ public class ArtifactEditorImpl implements ArtifactEditor { CompilerBundle.message("chooser.description.select.output.directory.for.0.artifact", getArtifact().getName()), myProject, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + setOutputPath(outputPath); + myErrorPanel = new ArtifactErrorPanel(this); + myValidationManager = new ArtifactValidationManagerImpl(); + } + + private void setOutputPath(@Nullable String outputPath) { myOutputDirectoryField.setText(outputPath != null ? FileUtil.toSystemDependentName(outputPath) : null); } @@ -122,12 +133,19 @@ public class ArtifactEditorImpl implements ArtifactEditor { mySourceItemsTree.rebuildTree(); } + public void checkLayout() { + myErrorPanel.clearError(); + getArtifact().getArtifactType().checkRootElement(getRootElement(), myValidationManager); + } + public JComponent createMainComponent() { mySourceItemsTree.initTree(); myLayoutTreeComponent.initTree(); myMainPanel.putClientProperty(DataManager.CLIENT_PROPERTY_DATA_PROVIDER, new TypeSafeDataProviderAdapter(new MyDataProvider())); + myErrorPanelPlace.add(myErrorPanel.getMainPanel(), BorderLayout.CENTER); + mySplitter = new Splitter(false); final JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.add(myLayoutTreeComponent.getTreePanel(), BorderLayout.CENTER); @@ -241,6 +259,13 @@ public class ArtifactEditorImpl implements ArtifactEditor { return myLayoutTreeComponent; } + public void updateOutputPath(@NotNull String oldArtifactName, @NotNull String newArtifactName) { + final String oldDefaultPath = ArtifactUtil.getDefaultArtifactOutputPath(oldArtifactName, myProject); + if (Comparing.equal(oldDefaultPath, getConfiguredOutputPath())) { + setOutputPath(ArtifactUtil.getDefaultArtifactOutputPath(newArtifactName, myProject)); + } + } + private class MyDataProvider implements TypeSafeDataProvider { public void calcData(DataKey key, DataSink sink) { if (ARTIFACTS_EDITOR_KEY.equals(key)) { @@ -248,4 +273,18 @@ public class ArtifactEditorImpl implements ArtifactEditor { } } } + + private class ArtifactValidationManagerImpl implements ArtifactValidationManager { + public PackagingEditorContext getContext() { + return myContext; + } + + public void registerProblem(@NotNull String messsage) { + registerProblem(messsage, null); + } + + public void registerProblem(@NotNull String messsage, @Nullable ArtifactProblemQuickFix quickFix) { + myErrorPanel.showError(messsage, quickFix); + } + } } \ No newline at end of file diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.form b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.form new file mode 100644 index 0000000000..6991fd73ff --- /dev/null +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.form @@ -0,0 +1,34 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java new file mode 100644 index 0000000000..4910e55e4c --- /dev/null +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java @@ -0,0 +1,54 @@ +package com.intellij.openapi.roots.ui.configuration.artifacts; + +import com.intellij.openapi.util.IconLoader; +import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author nik + */ +public class ArtifactErrorPanel { + private JPanel myMainPanel; + private JButton myFixButton; + private JLabel myErrorLabel; + private ArtifactProblemQuickFix myCurrentQuickFix; + + public ArtifactErrorPanel(final ArtifactEditorImpl artifactEditor) { + myErrorLabel.setIcon(IconLoader.getIcon("/runConfigurations/configurationWarning.png")); + myFixButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (myCurrentQuickFix != null) { + myCurrentQuickFix.performFix(); + artifactEditor.checkLayout(); + } + } + }); + clearError(); + } + + public void showError(@NotNull String message, @Nullable ArtifactProblemQuickFix quickFix) { + myErrorLabel.setVisible(true); + myErrorLabel.setText("" + message + ""); + myMainPanel.setVisible(true); + myCurrentQuickFix = quickFix; + myFixButton.setVisible(quickFix != null); + if (quickFix != null) { + myFixButton.setText(quickFix.getActionName()); + } + } + + public void clearError() { + myMainPanel.setVisible(false); + myErrorLabel.setVisible(false); + myFixButton.setVisible(false); + } + + public JComponent getMainPanel() { + return myMainPanel; + } +} diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactUtil.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactUtil.java index a5f61a6b14..82f7737ddf 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactUtil.java +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactUtil.java @@ -1,9 +1,15 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.CompilerProjectExtension; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtil; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactProperties; import com.intellij.packaging.artifacts.ArtifactType; import com.intellij.packaging.elements.*; +import com.intellij.packaging.impl.elements.FileCopyPackagingElement; import com.intellij.util.Processor; import com.intellij.util.containers.FList; import org.jetbrains.annotations.NotNull; @@ -64,7 +70,15 @@ public class ArtifactUtil { @NotNull PackagingElementProcessor processor, final @NotNull PackagingElementResolvingContext resolvingContext, final boolean processSubstituions) { - return processElements(artifact.getRootElement(), type, processor, resolvingContext, processSubstituions, artifact.getArtifactType(), + return processPackagingElements(artifact.getRootElement(), type, processor, resolvingContext, processSubstituions, artifact.getArtifactType()); + } + + public static > boolean processPackagingElements(final CompositePackagingElement rootElement, @Nullable PackagingElementType type, + @NotNull PackagingElementProcessor processor, + final @NotNull PackagingElementResolvingContext resolvingContext, + final boolean processSubstituions, + final ArtifactType artifactType) { + return processElements(rootElement, type, processor, resolvingContext, processSubstituions, artifactType, FList.>emptyList()); } @@ -144,4 +158,49 @@ public class ArtifactUtil { public static void copyProperties(ArtifactProperties from, ArtifactProperties to) { to.loadState((S)from.getState()); } + + @Nullable + public static String getDefaultArtifactOutputPath(@NotNull String artifactName, final @NotNull Project project) { + final String outputUrl = CompilerProjectExtension.getInstance(project).getCompilerOutputUrl(); + return outputUrl != null ? VfsUtil.urlToPath(outputUrl) + "/artifacts/" + FileUtil.sanitizeFileName(artifactName) : null; + } + + public static PackagingElement findFileByName(@NotNull List> elements, @NotNull String name, + @NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType) { + for (PackagingElement element : elements) { + if (element instanceof CompositePackagingElement && name.equals(((CompositePackagingElement)element).getName()) || + element instanceof FileCopyPackagingElement && name.equals(((FileCopyPackagingElement)element).getFileName())) { + return element; + } + if (element instanceof ComplexPackagingElement) { + final List> substitution = ((ComplexPackagingElement)element).getSubstitution(context, artifactType); + if (substitution != null) { + final PackagingElement packagingElement = findFileByName(substitution, name, context, artifactType); + if (packagingElement != null) { + return packagingElement; + } + } + } + } + return null; + } + + public static PackagingElement findByRelativePath(@NotNull CompositePackagingElement parent, @NotNull String relativePath, + @NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType) { + relativePath = StringUtil.trimStart(relativePath, "/"); + if (relativePath.length() == 0) { + return parent; + } + + int i = relativePath.indexOf('/'); + String firstName = i != -1 ? relativePath.substring(0, i) : relativePath; + String tail = i != -1 ? relativePath.substring(i+1) : ""; + final PackagingElement child = findFileByName(parent.getChildren(), firstName, context, artifactType); + if (tail.length() == 0) { + return child; + } + + if (!(child instanceof CompositePackagingElement)) return null; + return findByRelativePath((CompositePackagingElement)child, tail, context, artifactType); + } } diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form index 5561cabc99..9e88a3fcdc 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsEditorImpl.form @@ -1,6 +1,6 @@
- + @@ -81,6 +81,14 @@ + + + + + + + +
diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTree.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTree.java index 038a8e88df..b5db29fec3 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTree.java +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTree.java @@ -175,6 +175,7 @@ public class LayoutTree extends SimpleDnDAwareTree implements AdvancedDnDSource final boolean stopped = super.stopCellEditing(); if (stopped && currentElement != null) { currentElement.rename(newValue); + myArtifactsEditor.checkLayout(); addSubtreeToUpdate((DefaultMutableTreeNode)path.getLastPathComponent()); } return stopped; diff --git a/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java b/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java index 7ec8c1b744..899433e8f0 100644 --- a/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java +++ b/source/com/intellij/openapi/roots/ui/configuration/artifacts/LayoutTreeComponent.java @@ -114,6 +114,7 @@ public class LayoutTreeComponent implements DnDTarget, Disposable { public void rebuildTree() { myBuilder.updateFromRoot(true); updatePropertiesPanel(); + myArtifactsEditor.checkLayout(); } public LayoutTreeSelection getSelection() { @@ -167,6 +168,7 @@ public class LayoutTreeComponent implements DnDTarget, Disposable { } public void updateAndSelect(PackagingElementNode node, final List> toSelect) { + myArtifactsEditor.checkLayout(); final DefaultMutableTreeNode treeNode = TreeUtil.findNodeWithObject(myTree.getRootNode(), node); myBuilder.addSubtreeToUpdate(treeNode, new Runnable() { public void run() { -- 2.11.4.GIT