manifest editing in artifacts improved: IDEADEV-40906, IDEADEV-40727, IDEADEV-40713, IDEADEV-40709, IDEADEV-40712

This commit is contained in:
nik
2009-10-23 13:33:31 +04:00
parent 24881dc543
commit aef4ce013c
17 changed files with 380 additions and 137 deletions
@@ -152,7 +152,8 @@ public class ArtifactModelImpl extends ArtifactModelBase implements ModifiableAr
}
@Nullable
public ArtifactImpl getModifiableCopy(ArtifactImpl artifact) {
public ArtifactImpl getModifiableCopy(Artifact artifact) {
//noinspection SuspiciousMethodCalls
return myArtifact2ModifiableCopy.get(artifact);
}
@@ -15,8 +15,11 @@
*/
package com.intellij.packaging.impl.artifacts;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerProjectExtension;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
@@ -355,56 +358,55 @@ public class ArtifactUtil {
return files.isEmpty() ? null : files.get(0);
}
public static List<VirtualFile> findSourceFilesByOutputPath(CompositePackagingElement<?> parent, String outputPath,
PackagingElementResolvingContext context, ArtifactType artifactType) {
outputPath = StringUtil.trimStart(outputPath, "/");
if (outputPath.length() == 0) {
public static List<VirtualFile> findSourceFilesByOutputPath(CompositePackagingElement<?> parent, final String outputPath,
final PackagingElementResolvingContext context, final ArtifactType artifactType) {
final String path = StringUtil.trimStart(outputPath, "/");
if (path.length() == 0) {
return Collections.emptyList();
}
int i = outputPath.indexOf('/');
final String firstName = i != -1 ? outputPath.substring(0, i) : outputPath;
String tail = i != -1 ? outputPath.substring(i+1) : "";
int i = path.indexOf('/');
final String firstName = i != -1 ? path.substring(0, i) : path;
final String tail = i != -1 ? path.substring(i+1) : "";
final List<CompositePackagingElement<?>> compositeChildren = new SmartList<CompositePackagingElement<?>>();
final List<FileCopyPackagingElement> fileCopies = new SmartList<FileCopyPackagingElement>();
final List<DirectoryCopyPackagingElement> dirCopies = new SmartList<DirectoryCopyPackagingElement>();
final List<VirtualFile> result = new SmartList<VirtualFile>();
processElements(parent.getChildren(), context, artifactType, new Processor<PackagingElement<?>>() {
public boolean process(PackagingElement<?> element) {
//todo[nik] replace by method findSourceFile() in PackagingElement
if (element instanceof CompositePackagingElement) {
final CompositePackagingElement<?> compositeElement = (CompositePackagingElement<?>)element;
if (firstName.equals(compositeElement.getName())) {
compositeChildren.add(compositeElement);
result.addAll(findSourceFilesByOutputPath(compositeElement, tail, context, artifactType));
}
}
else if (element instanceof FileCopyPackagingElement) {
final FileCopyPackagingElement fileCopyElement = (FileCopyPackagingElement)element;
if (firstName.equals(fileCopyElement.getOutputFileName())) {
fileCopies.add(fileCopyElement);
if (firstName.equals(fileCopyElement.getOutputFileName()) && tail.length() == 0) {
ContainerUtil.addIfNotNull(fileCopyElement.findFile(), result);
}
}
else if (element instanceof DirectoryCopyPackagingElement) {
dirCopies.add((DirectoryCopyPackagingElement)element);
final VirtualFile sourceRoot = ((DirectoryCopyPackagingElement)element).findFile();
if (sourceRoot != null) {
ContainerUtil.addIfNotNull(sourceRoot.findFileByRelativePath(path), result);
}
}
else if (element instanceof ModuleOutputPackagingElement) {
final Module module = ((ModuleOutputPackagingElement)element).findModule(context);
final ContentEntry[] contentEntries = context.getModulesProvider().getRootModel(module).getContentEntries();
for (ContentEntry contentEntry : contentEntries) {
for (SourceFolder sourceFolder : contentEntry.getSourceFolders()) {
final VirtualFile sourceRoot = sourceFolder.getFile();
if (!sourceFolder.isTestSource() && sourceRoot != null) {
ContainerUtil.addIfNotNull(sourceRoot.findFileByRelativePath(path), result);
}
}
}
}
return true;
}
});
List<VirtualFile> result = new SmartList<VirtualFile>();
for (CompositePackagingElement<?> child : compositeChildren) {
result.addAll(findSourceFilesByOutputPath(child, tail, context, artifactType));
}
if (tail.length() == 0) {
for (FileCopyPackagingElement fileCopy : fileCopies) {
ContainerUtil.addIfNotNull(fileCopy.findFile(), result);
}
}
for (DirectoryCopyPackagingElement dirCopy : dirCopies) {
final VirtualFile sourceRoot = dirCopy.findFile();
if (sourceRoot != null) {
ContainerUtil.addIfNotNull(sourceRoot.findFileByRelativePath(outputPath), result);
}
}
return result;
}
@@ -58,7 +58,7 @@ public class FileCopyPackagingElement extends FileOrDirectoryCopyPackagingElemen
}
public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
return new FileCopyPresentation(myFilePath, getOutputFileName());
return new FileCopyPresentation(myFilePath, getOutputFileName(), context);
}
@Override
@@ -27,7 +27,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementFactory;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
@@ -55,16 +54,19 @@ public class ManifestFileUtil {
public static final String MANIFEST_FILE_NAME = PathUtil.getFileName(MANIFEST_PATH);
public static final String MANIFEST_DIR_NAME = PathUtil.getParentPath(MANIFEST_PATH);
private ManifestFileUtil() {
}
@Nullable
public static VirtualFile findManifestFile(@NotNull CompositePackagingElement<?> root, PackagingElementResolvingContext context, ArtifactType artifactType) {
return ArtifactUtil.findSourceFileByOutputPath(root, MANIFEST_PATH, context, artifactType);
}
@NotNull
public static String suggestManifestFilePathAndAddElement(@NotNull CompositePackagingElement<?> root, PackagingElementResolvingContext context, ArtifactType artifactType) {
@Nullable
public static VirtualFile suggestManifestFileDirectory(@NotNull CompositePackagingElement<?> root, PackagingElementResolvingContext context, ArtifactType artifactType) {
final VirtualFile metaInfDir = ArtifactUtil.findSourceFileByOutputPath(root, MANIFEST_DIR_NAME, context, artifactType);
if (metaInfDir != null) {
return metaInfDir.getPath() + "/" + MANIFEST_FILE_NAME;
return metaInfDir;
}
final Ref<VirtualFile> sourceDir = Ref.create(null);
@@ -89,17 +91,15 @@ public class ManifestFileUtil {
});
if (!sourceDir.isNull()) {
return sourceDir.get().getPath() + "/" + MANIFEST_PATH;
return sourceDir.get();
}
final Project project = context.getProject();
final VirtualFile dir = suggestBaseDir(project, sourceFile.get());
String filePath = dir.getPath() + "/" + MANIFEST_PATH;
PackagingElementFactory.getInstance().addFileCopy(root, MANIFEST_DIR_NAME, filePath);
return filePath;
return suggestBaseDir(project, sourceFile.get());
}
@Nullable
private static VirtualFile suggestBaseDir(Project project, final @Nullable VirtualFile file) {
final VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
if (file == null && contentRoots.length > 0) {
@@ -189,7 +189,11 @@ public class ManifestFileUtil {
@NotNull
public static ManifestFileConfiguration createManifestFileConfiguration(CompositePackagingElement<?> element,
final PackagingElementResolvingContext context, final ArtifactType artifactType) {
final VirtualFile manifestFile = findManifestFile(element, context, artifactType);
return createManifestFileConfiguration(findManifestFile(element, context, artifactType));
}
@NotNull
public static ManifestFileConfiguration createManifestFileConfiguration(@Nullable VirtualFile manifestFile) {
final List<String> classpath = new ArrayList<String>();
String mainClass = null;
final String path;
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.impl.elements.PackagingElementFactoryImpl;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingElementPresentation;
import com.intellij.packaging.ui.PackagingElementWeights;
import com.intellij.ui.SimpleTextAttributes;
@@ -32,10 +33,12 @@ import org.jetbrains.annotations.NotNull;
public class FileCopyPresentation extends PackagingElementPresentation {
private final String mySourcePath;
private final String myOutputFileName;
private final ArtifactEditorContext myContext;
private final VirtualFile myFile;
public FileCopyPresentation(String filePath, String outputFileName) {
public FileCopyPresentation(String filePath, String outputFileName, ArtifactEditorContext context) {
myOutputFileName = outputFileName;
myContext = context;
String parentPath;
myFile = LocalFileSystem.getInstance().findFileByPath(filePath);
@@ -61,8 +64,8 @@ public class FileCopyPresentation extends PackagingElementPresentation {
}
public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
if (myFile != null && !myFile.isDirectory()) {
presentationData.setIcons(myFile.getIcon());
if (myFile != null && !myFile.isDirectory() || myContext.isManifestFile(mySourcePath)) {
presentationData.setIcons(myFile != null ? myFile.getIcon() : PackagingElementFactoryImpl.FileCopyElementType.ICON);
presentationData.addText(myOutputFileName, mainAttributes);
presentationData.addText(" (" + mySourcePath + ")", commentAttributes);
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.packaging.impl.ui.properties.ElementWithManifestPropertiesPanel">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="5" right="5"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -8,61 +8,152 @@
<properties/>
<border type="none"/>
<children>
<component id="9a3d6" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.text.main.class"/>
</properties>
</component>
<vspacer id="e5716">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="d87aa" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myMainClassField">
<grid id="98ebe" binding="myPropertiesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="40600" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.text.class.path"/>
</properties>
</component>
<component id="a5121" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myClasspathField">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="e12c" class="javax.swing.JLabel" binding="myTitleLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="element name"/>
</properties>
</component>
<component id="446b5" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Manifest &amp;File:"/>
</properties>
</component>
<component id="52135" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myManifestFilePathField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<border type="none"/>
<children>
<grid id="e398c" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<card name="properties"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="9a3d6" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.text.main.class"/>
</properties>
</component>
<component id="d87aa" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myMainClassField">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="40600" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/CompilerBundle" key="label.text.class.path"/>
</properties>
</component>
<component id="a5121" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myClasspathField">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="e12c" class="javax.swing.JLabel" binding="myTitleLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="element name"/>
</properties>
</component>
<component id="446b5" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="aca67"/>
<text value="Manifest &amp;File:"/>
</properties>
</component>
<grid id="599de" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="12e45" class="javax.swing.JButton" binding="myRemoveFromArtifactButton" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Remove from Artifact"/>
</properties>
</component>
<hspacer id="7cf11">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<component id="aca67" class="javax.swing.JTextField" binding="myManifestPathField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<editable value="false"/>
</properties>
</component>
</children>
</grid>
<grid id="4473f" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<card name="buttons"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="66e62" class="javax.swing.JButton" binding="myCreateManifestButton" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Create Manifest..."/>
</properties>
</component>
<hspacer id="970f7">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="bf917">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="c6af2" class="javax.swing.JButton" binding="myUseExistingManifestButton" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Use Existing Manifest..."/>
</properties>
</component>
<component id="a0a7b" class="javax.swing.JLabel" binding="myManifestNotFoundLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Manifest.mf file not found"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>
@@ -15,21 +15,29 @@
*/
package com.intellij.packaging.impl.ui.properties;
import com.intellij.CommonBundle;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.PackagingElementFactory;
import com.intellij.packaging.impl.elements.CompositeElementWithManifest;
import com.intellij.packaging.impl.elements.ManifestFileUtil;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
import com.intellij.packaging.ui.ManifestFileConfiguration;
import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
@@ -40,21 +48,29 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
/**
* @author nik
*/
public abstract class ElementWithManifestPropertiesPanel<E extends CompositeElementWithManifest<?>> extends PackagingElementPropertiesPanel {
private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.ui.properties.ElementWithManifestPropertiesPanel");
private final E myElement;
private final ArtifactEditorContext myContext;
private JPanel myMainPanel;
private TextFieldWithBrowseButton myMainClassField;
private TextFieldWithBrowseButton myClasspathField;
private JLabel myTitleLabel;
private TextFieldWithBrowseButton myManifestFilePathField;
private JButton myRemoveFromArtifactButton;
private JButton myCreateManifestButton;
private JButton myUseExistingManifestButton;
private JPanel myPropertiesPanel;
private JTextField myManifestPathField;
private JLabel myManifestNotFoundLabel;
private ManifestFileConfiguration myManifestFileConfiguration;
public ElementWithManifestPropertiesPanel(E element, final ArtifactEditorContext context) {
@@ -78,46 +94,123 @@ public abstract class ElementWithManifestPropertiesPanel<E extends CompositeElem
}
});
myMainClassField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
createManifestFileIfNeeded();
}
});
myClasspathField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Messages.showTextAreaDialog(myClasspathField.getTextField(), "Edit Classpath", "classpath-attribute-editor");
}
});
myManifestFilePathField.addBrowseFolderListener("Specify Path to MANIFEST.MF file", "", context.getProject(), new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
return super.isFileVisible(file, showHiddenFiles) && file.isDirectory() || file.getName().equalsIgnoreCase(ManifestFileUtil.MANIFEST_FILE_NAME);
}
});
myClasspathField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
createManifestFileIfNeeded();
myContext.queueValidation();
}
});
myUseExistingManifestButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
chooseManifest();
}
});
myCreateManifestButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
createManifest();
}
});
//todo[nik] do we really need this button?
myRemoveFromArtifactButton.setVisible(false);
myRemoveFromArtifactButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeManifest();
}
});
}
private void createManifestFileIfNeeded() {
if ((myClasspathField.getText().trim().length() > 0 || myMainClassField.getText().trim().length() > 0)
&& myManifestFilePathField.getText().length() == 0) {
final String path = ManifestFileUtil.suggestManifestFilePathAndAddElement(myElement, myContext, myContext.getArtifactType());
myManifestFilePathField.setText(FileUtil.toSystemDependentName(path));
private void removeManifest() {
}
private void createManifest() {
FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.setTitle("Select Directory for MANIFEST.MF file");
final VirtualFile[] files = FileChooser.chooseFiles(myContext.getProject(), descriptor, ManifestFileUtil.suggestManifestFileDirectory(myElement, myContext, myContext.getArtifactType()));
if (files.length != 1) return;
final Ref<IOException> exc = Ref.create(null);
final VirtualFile file = new WriteAction<VirtualFile>() {
protected void run(final Result<VirtualFile> result) {
VirtualFile dir = files[0];
try {
if (!dir.getName().equals(ManifestFileUtil.MANIFEST_DIR_NAME)) {
VirtualFile newDir = dir.findChild(ManifestFileUtil.MANIFEST_DIR_NAME);
if (newDir == null) {
newDir = dir.createChildDirectory(this, ManifestFileUtil.MANIFEST_DIR_NAME);
}
dir = newDir;
}
result.setResult(dir.createChildData(this, ManifestFileUtil.MANIFEST_FILE_NAME));
}
catch (IOException e) {
exc.set(e);
}
}
}.execute().getResultObject();
final IOException exception = exc.get();
if (exception != null) {
LOG.info(exception);
Messages.showErrorDialog(myMainPanel, exception.getMessage(), CommonBundle.getErrorTitle());
return;
}
PackagingElementFactory.getInstance().addFileCopy(myElement, ManifestFileUtil.MANIFEST_DIR_NAME, file.getPath());
myContext.getThisArtifactEditor().updateLayoutTree();
updateComponents(new ManifestFileConfiguration(null, null, file.getPath()));
apply();
}
private void chooseManifest() {
final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() ||
file.getName().equalsIgnoreCase(ManifestFileUtil.MANIFEST_FILE_NAME));
}
};
descriptor.setTitle("Specify Path to MANIFEST.MF file");
final VirtualFile[] files = FileChooser.chooseFiles(myContext.getProject(), descriptor);
if (files.length != 1) return;
final String path = files[0].getPath();
PackagingElementFactory.getInstance().addFileCopy(myElement, ManifestFileUtil.MANIFEST_DIR_NAME, path);
myContext.getThisArtifactEditor().updateLayoutTree();
updateComponents(ManifestFileUtil.createManifestFileConfiguration(files[0]));
apply();
}
private void updateComponents(@NotNull ManifestFileConfiguration configuration) {
final String manifestFilePath = configuration.getManifestFilePath();
final String card;
if (manifestFilePath != null) {
card = "properties";
myManifestPathField.setText(FileUtil.toSystemDependentName(manifestFilePath));
myMainClassField.setText(StringUtil.notNullize(configuration.getMainClass()));
myClasspathField.setText(StringUtil.join(configuration.getClasspath(), " "));
}
else {
card = "buttons";
myManifestPathField.setText("");
}
((CardLayout)myPropertiesPanel.getLayout()).show(myPropertiesPanel, card);
}
public void reset() {
myTitleLabel.setText("'" + myElement.getName() + "' manifest properties:");
myMainClassField.setText(StringUtil.notNullize(myManifestFileConfiguration.getMainClass()));
myClasspathField.setText(StringUtil.join(myManifestFileConfiguration.getClasspath(), " "));
myManifestFilePathField.setText(FileUtil.toSystemDependentName(StringUtil.notNullize(myManifestFileConfiguration.getManifestFilePath())));
createManifestFileIfNeeded();
myManifestNotFoundLabel.setText("Manifest.mf file not found in '" + myElement.getName() + "'");
final VirtualFile file = ManifestFileUtil.findManifestFile(myElement, myContext, myContext.getArtifactType());
String path = file != null ? file.getPath() : null;
if (!Comparing.equal(path, myManifestFileConfiguration.getManifestFilePath())) {
myManifestFileConfiguration.copyFrom(ManifestFileUtil.createManifestFileConfiguration(file));
}
updateComponents(myManifestFileConfiguration);
}
public boolean isModified() {
@@ -128,7 +221,7 @@ public abstract class ElementWithManifestPropertiesPanel<E extends CompositeElem
@Nullable
private String getConfiguredManifestPath() {
final String path = myManifestFilePathField.getText();
final String path = myManifestPathField.getText();
return path.length() != 0 ? FileUtil.toSystemIndependentName(path) : null;
}
@@ -17,6 +17,7 @@ package com.intellij.packaging.artifacts;
import com.intellij.packaging.elements.CompositePackagingElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
@@ -38,4 +39,6 @@ public interface ModifiableArtifactModel extends ArtifactModel {
void commit();
@Nullable
Artifact getModifiableCopy(Artifact artifact);
}
@@ -25,6 +25,7 @@ import java.util.List;
* @author nik
*/
public interface ArtifactEditor {
void updateLayoutTree();
void putLibraryIntoDefaultLocation(@NotNull Library library);
@@ -43,12 +43,16 @@ public interface ArtifactEditorContext extends PackagingElementResolvingContext
@NotNull
ManifestFileConfiguration getManifestFile(CompositePackagingElement<?> element, ArtifactType artifactType);
boolean isManifestFile(String path);
CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact);
void editLayout(@NotNull Artifact artifact, Runnable runnable);
ArtifactEditor getOrCreateEditor(Artifact originalArtifact);
ArtifactEditor getThisArtifactEditor();
void selectArtifact(@NotNull Artifact artifact);
@@ -15,6 +15,9 @@
*/
package com.intellij.packaging.ui;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.ArrayList;
@@ -26,18 +29,25 @@ public class ManifestFileConfiguration {
private String myMainClass;
private String myManifestFilePath;
public ManifestFileConfiguration(ManifestFileConfiguration configuration) {
myClasspath = new ArrayList<String>(configuration.getClasspath());
myMainClass = configuration.getMainClass();
myManifestFilePath = configuration.getManifestFilePath();
public ManifestFileConfiguration(@NotNull ManifestFileConfiguration configuration) {
copyFrom(configuration);
}
public ManifestFileConfiguration(List<String> classpath, String mainClass, String manifestFilePath) {
myClasspath = classpath;
public ManifestFileConfiguration(@Nullable List<String> classpath, @Nullable String mainClass, @Nullable String manifestFilePath) {
if (classpath != null) {
myClasspath.addAll(classpath);
}
myMainClass = mainClass;
myManifestFilePath = manifestFilePath;
}
public void copyFrom(@NotNull ManifestFileConfiguration configuration) {
myClasspath.clear();
myClasspath.addAll(configuration.getClasspath());
myMainClass = configuration.getMainClass();
myManifestFilePath = configuration.getManifestFilePath();
}
public List<String> getClasspath() {
return myClasspath;
}
@@ -66,6 +66,10 @@ public class ArtifactEditorContextImpl implements ArtifactEditorContext {
return myParent.getManifestFile(element, artifactType);
}
public boolean isManifestFile(String path) {
return myParent.isManifestFile(path);
}
@NotNull
public Project getProject() {
return myParent.getProject();
@@ -83,6 +87,10 @@ public class ArtifactEditorContextImpl implements ArtifactEditorContext {
return myParent.getOrCreateEditor(artifact);
}
public ArtifactEditor getThisArtifactEditor() {
return myEditor;
}
public void selectArtifact(@NotNull Artifact artifact) {
ProjectStructureConfigurable.getInstance(getProject()).select(artifact, true);
}
@@ -372,6 +372,10 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
}
}
public void updateLayoutTree() {
myLayoutTreeComponent.rebuildTree();
}
public void putLibraryIntoDefaultLocation(@NotNull Library library) {
myLayoutTreeComponent.putIntoDefaultLocations(Collections.singletonList(new LibrarySourceItem(library)));
}
@@ -393,10 +397,8 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
final CompositePackagingElement<?> oldRootElement = getRootElement();
final CompositePackagingElement<?> newRootElement = artifactType.createRootElement(getArtifact().getName());
if (!newRootElement.getType().equals(oldRootElement.getType())) {
ArtifactUtil.copyChildren(oldRootElement, newRootElement, myProject);
myLayoutTreeComponent.setRootElement(newRootElement);
}
ArtifactUtil.copyChildren(oldRootElement, newRootElement, myProject);
myLayoutTreeComponent.setRootElement(newRootElement);
}
private class MyDataProvider implements TypeSafeDataProvider {
@@ -34,6 +34,8 @@ public interface ArtifactsStructureConfigurableContext extends PackagingElementR
@NotNull
ManifestFileConfiguration getManifestFile(CompositePackagingElement<?> element, ArtifactType artifactType);
boolean isManifestFile(String path);
CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact);
void editLayout(@NotNull Artifact artifact, Runnable action);
@@ -77,15 +77,19 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon
public CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact) {
artifact = getOriginalArtifact(artifact);
if (myModifiableModel != null) {
final CompositePackagingElement<?> rootElement = myModifiableModel.getArtifactByOriginal(artifact).getRootElement();
if (rootElement != artifact.getRootElement()) {
myModifiableRoots.put(artifact, rootElement);
final Artifact modifiableArtifact = myModifiableModel.getModifiableCopy(artifact);
if (modifiableArtifact != null) {
myModifiableRoots.put(artifact, modifiableArtifact.getRootElement());
}
}
CompositePackagingElement<?> root = myModifiableRoots.get(artifact);
return getOrCreateModifiableRootElement(artifact);
}
private CompositePackagingElement<?> getOrCreateModifiableRootElement(Artifact originalArtifact) {
CompositePackagingElement<?> root = myModifiableRoots.get(originalArtifact);
if (root == null) {
root = ArtifactUtil.copyFromRoot(artifact.getRootElement(), myProject);
myModifiableRoots.put(artifact, root);
root = ArtifactUtil.copyFromRoot(originalArtifact.getRootElement(), myProject);
myModifiableRoots.put(originalArtifact, root);
}
return root;
}
@@ -94,7 +98,7 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon
artifact = getOriginalArtifact(artifact);
final ModifiableArtifact modifiableArtifact = getModifiableArtifactModel().getOrCreateModifiableArtifact(artifact);
if (modifiableArtifact.getRootElement() == artifact.getRootElement()) {
modifiableArtifact.setRootElement(getRootElement(artifact));
modifiableArtifact.setRootElement(getOrCreateModifiableRootElement(artifact));
}
action.run();
myContext.getDaemonAnalyzer().queueUpdate(new ArtifactProjectStructureElement(myContext, this, artifact));
@@ -144,6 +148,10 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon
return myManifestFilesInfo.getManifestFile(element, artifactType, this);
}
public boolean isManifestFile(String path) {
return myManifestFilesInfo.isManifestFile(path);
}
public ManifestFilesInfo getManifestFilesInfo() {
return myManifestFilesInfo;
}
@@ -130,7 +130,7 @@ public class LayoutTreeComponent implements DnDTarget, Disposable {
public void updatePropertiesPanel(final boolean force) {
final PackagingElement<?> selected = getSelection().getElementIfSingle();
if (force || Comparing.equal(selected, mySelectedElementInfo.myElement)) {
if (!force && Comparing.equal(selected, mySelectedElementInfo.myElement)) {
return;
}
mySelectedElementInfo.save();
@@ -504,6 +504,7 @@ public class LayoutTreeComponent implements DnDTarget, Disposable {
else {
cardLayout.show(myPropertiesPanelWrapper, EMPTY_CARD);
}
myPropertiesPanelWrapper.repaint();
}
}
@@ -24,6 +24,7 @@ import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import com.intellij.packaging.impl.elements.ManifestFileUtil;
import com.intellij.packaging.ui.ManifestFileConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Map;
@@ -79,4 +80,13 @@ public class ManifestFilesInfo {
myManifestFiles.clear();
myOriginalManifestFiles.clear();
}
public boolean isManifestFile(@NotNull String path) {
for (ManifestFileConfiguration configuration : myManifestFiles.values()) {
if (path.equals(configuration.getManifestFilePath())) {
return true;
}
}
return false;
}
}