Index: freeform/src/org/netbeans/modules/ant/freeform/Actions.java =================================================================== RCS file: /cvs/ant/freeform/src/org/netbeans/modules/ant/freeform/Actions.java,v retrieving revision 1.14 diff -u -r1.14 Actions.java --- freeform/src/org/netbeans/modules/ant/freeform/Actions.java 11 May 2005 16:01:34 -0000 1.14 +++ freeform/src/org/netbeans/modules/ant/freeform/Actions.java 22 Jun 2005 09:16:55 -0000 @@ -71,6 +71,7 @@ */ private static final Set/**/ COMMON_IDE_GLOBAL_ACTIONS = new HashSet(Arrays.asList(new String[] { ActionProvider.COMMAND_DEBUG, + ActionProvider.COMMAND_DELETE, })); /** * Similar to {@link #COMMON_IDE_GLOBAL_ACTIONS}, but these are not IDE-specific. @@ -113,10 +114,15 @@ } // #46886: also always enable all common global actions, in case they should be selected: names.addAll(COMMON_NON_IDE_GLOBAL_ACTIONS); + names.add(COMMAND_DELETE); return (String[])names.toArray(new String[names.size()]); } public boolean isActionEnabled(String command, Lookup context) throws IllegalArgumentException { + if (COMMAND_DELETE.equals(command)) { + return true; + } + Element genldata = project.helper().getPrimaryConfigurationData(true); Element actionsEl = Util.findElement(genldata, "ide-actions", FreeformProjectType.NS_GENERAL); // NOI18N if (actionsEl == null) { @@ -166,6 +172,10 @@ } public void invokeAction(String command, Lookup context) throws IllegalArgumentException { + if (COMMAND_DELETE.equals(command)) { + project.helper().performDefaultDeleteOperation(); + return ; + } Element genldata = project.helper().getPrimaryConfigurationData(true); Element actionsEl = Util.findElement(genldata, "ide-actions", FreeformProjectType.NS_GENERAL); // NOI18N if (actionsEl == null) { @@ -427,6 +437,8 @@ actions.add(CommonProjectActions.setAsMainProjectAction()); actions.add(CommonProjectActions.openSubprojectsAction()); actions.add(CommonProjectActions.closeProjectAction()); + actions.add(null); + actions.add(CommonProjectActions.deleteProjectAction()); actions.add(null); actions.add(SystemAction.get(FindAction.class)); Index: freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java =================================================================== RCS file: /cvs/ant/freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java,v retrieving revision 1.34 diff -u -r1.34 FreeformProject.java --- freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java 23 Jan 2005 20:34:11 -0000 1.34 +++ freeform/src/org/netbeans/modules/ant/freeform/FreeformProject.java 22 Jun 2005 09:16:55 -0000 @@ -82,6 +82,7 @@ new Subprojects(this), // SubprojectProvider new ArtifactProvider(this), // AntArtifactProvider new LookupMergerImpl(), // LookupMerger + new FreeformProjectOperation(this), }); return new FreeformLookup(baseLookup, this, helper, eval, aux); } Index: freeform/src/org/netbeans/modules/ant/freeform/FreeformProjectOperation.java =================================================================== RCS file: freeform/src/org/netbeans/modules/ant/freeform/FreeformProjectOperation.java diff -N freeform/src/org/netbeans/modules/ant/freeform/FreeformProjectOperation.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ freeform/src/org/netbeans/modules/ant/freeform/FreeformProjectOperation.java 22 Jun 2005 09:16:55 -0000 @@ -0,0 +1,112 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.ant.freeform; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.netbeans.modules.ant.freeform.spi.support.Util; +import org.netbeans.spi.project.ProjectOperationsImplementation.DeleteOperationImplementation; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.w3c.dom.Element; + +/** + * + * @author Jan Lahoda + */ +public class FreeformProjectOperation implements DeleteOperationImplementation { + + private FreeformProject project; + + public FreeformProjectOperation(FreeformProject project) { + this.project = project; + } + + private static void addFile(FileObject projectDirectory, String fileName, List/**/ result) { + FileObject file = projectDirectory.getFileObject(fileName); + + if (file != null) { + result.add(file); + } + } + + public List/**/ getMetadataFiles() { + FileObject projectDirectory = project.getProjectDirectory(); + List/**/ files = new ArrayList(); + + addFile(projectDirectory, "nbproject", files); // NOI18N + + return files; + } + + public List/**/ getDataFiles() { + Element genldata = project.helper().getPrimaryConfigurationData(true); + Element foldersEl = Util.findElement(genldata, "folders", FreeformProjectType.NS_GENERAL); // NOI18N + List/**/ folders = Util.findSubElements(foldersEl); + List/**/ result = new ArrayList/**/(); + + for (Iterator i = folders.iterator(); i.hasNext(); ) { + Element el = (Element) i.next(); + + if ("source-folder".equals(el.getLocalName()) && FreeformProjectType.NS_GENERAL.equals(el.getNamespaceURI())) { + addFile(el, result); + } + } + + addFile(project.getProjectDirectory(), "build.xml", result); // NOI18N + + return result; + } + + private void addFile(Element folder, List/**/ result) { + Element location = Util.findElement(folder, "location", FreeformProjectType.NS_GENERAL); + + if (location == null) { + return ; + } + + PropertyEvaluator evaluator = project.evaluator(); + String val = evaluator.evaluate(Util.findText(location)); + + if (val == null) { + return ; + } + + File f = project.helper().resolveFile(val); + + if (f == null) { + return ; + } + + FileObject fo = FileUtil.toFileObject(f); + + if (fo != null && FileUtil.isParentOf(project.getProjectDirectory(), fo)) { + result.add(fo); + } + } + + public void performClean() throws IOException { + //TODO: invoke clean action if bound. + } + + public void notifyDeleted() throws IOException { + project.helper().notifyDeleted(); + } + +} Index: project/apichanges.xml =================================================================== RCS file: /cvs/ant/project/apichanges.xml,v retrieving revision 1.6 diff -u -r1.6 apichanges.xml --- project/apichanges.xml 3 Apr 2005 01:41:49 -0000 1.6 +++ project/apichanges.xml 22 Jun 2005 09:16:55 -0000 @@ -76,6 +76,20 @@ + + + Basic Support SPI for Project Delete + + + + + + AntProjectHelper.notifyDeleted() and AntProjectHelper.performDefaultDeleteOperation() + added. + + + + Support SPI for creating/storing Swing models for simple Ant properties Index: project/nbproject/project.properties =================================================================== RCS file: /cvs/ant/project/nbproject/project.properties,v retrieving revision 1.14 diff -u -r1.14 project.properties --- project/nbproject/project.properties 6 Jun 2005 20:32:26 -0000 1.14 +++ project/nbproject/project.properties 22 Jun 2005 09:16:55 -0000 @@ -22,9 +22,11 @@ test.unit.cp.extra=\ ${nb_all}/projects/projectapi/build/test/unit/classes:\ - ${diff.dir}/modules/org-netbeans-modules-diff.jar + ${diff.dir}/modules/org-netbeans-modules-diff.jar:\ + ${projects/projectui.dir}/modules/org-netbeans-modules-projectui.jar # For XMLSerializer, needed for XMLUtil.write to work w/ namespaces: test.unit.run.cp.extra=\ ${libs/xerces.dir}/modules/ext/xerces-2.6.2.jar:\ ${libs/xerces.dir}/modules/ext/xml-commons-dom-ranges-1.0.b2.jar:\ - ${openide/masterfs.dir}/modules/org-netbeans-modules-masterfs.jar + ${openide/masterfs.dir}/modules/org-netbeans-modules-masterfs.jar:\ + ${openide/options.dir}/modules/org-openide-options.jar Index: project/nbproject/project.xml =================================================================== RCS file: /cvs/ant/project/nbproject/project.xml,v retrieving revision 1.13 diff -u -r1.13 project.xml --- project/nbproject/project.xml 4 Jun 2005 05:10:41 -0000 1.13 +++ project/nbproject/project.xml 22 Jun 2005 09:16:55 -0000 @@ -26,7 +26,23 @@ + org.netbeans.modules.projectuiapi + + + + 1 + + + org.netbeans.modules.queries + + + + 1 + + + + org.netbeans.api.progress Index: project/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java =================================================================== RCS file: /cvs/ant/project/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java,v retrieving revision 1.6 diff -u -r1.6 AntBasedProjectFactorySingleton.java --- project/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java 23 Feb 2005 12:25:42 -0000 1.6 +++ project/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java 22 Jun 2005 09:16:55 -0000 @@ -15,13 +15,15 @@ import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.WeakHashMap; import org.netbeans.api.project.Project; import org.netbeans.spi.project.ProjectFactory; @@ -55,6 +57,7 @@ private static final Map/*>*/ project2Helper = new WeakHashMap(); private static final Map/*>*/ helper2Project = new WeakHashMap(); + private static final Map/*>>*/ type2Projects = new HashMap(); //for second part of #42738 private static final Lookup.Result/**/ antBasedProjectTypes; private static Map/**/ antBasedProjectTypesByType = null; static { @@ -62,12 +65,41 @@ antBasedProjectTypes.addLookupListener(new LookupListener() { public void resultChanged(LookupEvent ev) { synchronized (AntBasedProjectFactorySingleton.class) { + Set/**/ oldTypes = type2Projects.keySet(); + Set/**/ removed = new HashSet(oldTypes); + + removed.removeAll(antBasedProjectTypes.allInstances()); + + antBasedProjectTypesRemoved(removed); + antBasedProjectTypesByType = null; } } }); } + private static void antBasedProjectTypesRemoved(Set/**/ removed) { + for (Iterator/**/ i = removed.iterator(); i.hasNext(); ){ + AntBasedProjectType type = (AntBasedProjectType) i.next(); + List/*>*/ projects = (List/*>*/) type2Projects.get(type); + + if (projects != null) { + for (Iterator/*>*/ prjs = projects.iterator(); prjs.hasNext(); ) { + Reference/**/ r = (Reference/**/) prjs.next(); + Object instance = r.get(); + + if (instance != null) { + AntProjectHelper helper = (AntProjectHelper) instance; + + helper.notifyDeleted(); + } + } + } + + type2Projects.remove(type); + } + } + private static synchronized AntBasedProjectType findAntBasedProjectType(String type) { if (antBasedProjectTypesByType == null) { Iterator it = new ArrayList(antBasedProjectTypes.allInstances()).iterator(); @@ -133,6 +165,14 @@ Project project = provider.createProject(helper); project2Helper.put(project, new WeakReference(helper)); helper2Project.put(helper, new WeakReference(project)); + List/*>*/ l = (List/*>*/) type2Projects.get(provider); + + if (l == null) { + type2Projects.put(provider, l = new ArrayList/*>*/()); + } + + l.add(new WeakReference(helper)); + return project; } Index: project/src/org/netbeans/modules/project/ant/Bundle.properties =================================================================== RCS file: /cvs/ant/project/src/org/netbeans/modules/project/ant/Bundle.properties,v retrieving revision 1.4 diff -u -r1.4 Bundle.properties --- project/src/org/netbeans/modules/project/ant/Bundle.properties 12 Aug 2004 04:53:54 -0000 1.4 +++ project/src/org/netbeans/modules/project/ant/Bundle.properties 22 Jun 2005 09:16:55 -0000 @@ -18,3 +18,23 @@ # UserQuestionHandler TITLE_CannotWriteFile=Cannot Write to File + +LBL_Progress_Cleaning_Project=Cleaning Project + +LBL_Project_cannot_be_deleted.=Project {0} cannot be deleted. + +LBL_Delete_Project_Caption=Delete Project + +LBL_Project_Deletion_in_Progress_Caption=Project Deletion in Progress + +LBL_Project_Deleted_Caption=Project {0} has been successfully deleted. + +LBL_Deleting_Project=Deleting Project\: + +LBL_Progress_Deleting_File=Deleting {0} + +LBL_Pre_Delete_Warning=Are you sure you want to delete project "{0}"? + +LBL_Delete_Also_Sources=Also Delete Sources Under "{0}" folder. + +LBL_File_To_Delete=Files to Delete\: Index: project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.form =================================================================== RCS file: project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.form diff -N project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.form --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.form 22 Jun 2005 09:16:55 -0000 @@ -0,0 +1,50 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.java =================================================================== RCS file: project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.java diff -N project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project/src/org/netbeans/modules/project/ant/DefaultAntProjectDeletePanel.java 22 Jun 2005 09:16:55 -0000 @@ -0,0 +1,142 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.project.ant; + +import java.awt.Component; +import java.awt.Window; +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.List; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.NbBundle; + +/** + * + * @author Jan Lahoda + */ +final class DefaultAntProjectDeletePanel extends javax.swing.JPanel { + + private String projectDisplaName; + private String projectFolder; + private boolean enableCheckbox; +// private List/**/ metadataFileNames; +// private List/**/ allFileNames; + + /** + * Creates new form DefaultAntProjectDeletePanel + */ + public DefaultAntProjectDeletePanel(String projectDisplaName, String projectFolder, boolean enableCheckbox) { + this.projectDisplaName = projectDisplaName; + this.projectFolder = projectFolder; +// this.metadataFileNames = metadataFileNames; +// this.allFileNames = allFileNames; + this.enableCheckbox = enableCheckbox; + initComponents(); +// updateSourcesList(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + warningText = new javax.swing.JTextArea(); + deleteSourcesCheckBox = new javax.swing.JCheckBox(); + + setLayout(new java.awt.GridBagLayout()); + + warningText.setEditable(false); + warningText.setFont(javax.swing.UIManager.getFont("Label.font")); + warningText.setText(getWarningText()); + warningText.setDisabledTextColor(javax.swing.UIManager.getColor("Label.foreground")); + warningText.setOpaque(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 12); + add(warningText, gridBagConstraints); + + deleteSourcesCheckBox.setText(getCheckboxText()); + deleteSourcesCheckBox.setEnabled(enableCheckbox); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 12); + add(deleteSourcesCheckBox, gridBagConstraints); + + } + // //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox deleteSourcesCheckBox; + private javax.swing.JTextArea warningText; + // End of variables declaration//GEN-END:variables + + public boolean isDeleteSources() { + return deleteSourcesCheckBox.isSelected(); + } + +/* private void updateSourcesList() { + boolean enabled = deleteSourcesCheckBox.isSelected(); + + if (enabled) { + deleteList.setText(getTextForFiles(allFileNames)); + } else { + deleteList.setText(getTextForFiles(metadataFileNames)); + } + + Component c = this; + + while (c != null && !(c instanceof Window)) { + c = c.getParent(); + } + + if (c != null) { + ((Window) c).pack(); + } + }*/ + +// private static String getTextForFiles(List/**/ files) { +// StringBuffer result = new StringBuffer(); +// +// for (Iterator/**/ i = files.iterator(); i.hasNext(); ) { +// String file = (String) i.next(); +// +// result.append(file); +// +// if (i.hasNext()) { +// result.append("\n"); // NOI18N +// } +// } +// +// return result.toString(); +// } + + private String getWarningText() { + return MessageFormat.format(NbBundle.getBundle(DefaultAntProjectDeletePanel.class).getString("LBL_Pre_Delete_Warning"), new Object[] {projectDisplaName}); + } + + private String getCheckboxText() { + return MessageFormat.format(NbBundle.getBundle(DefaultAntProjectDeletePanel.class).getString("LBL_Delete_Also_Sources"), new Object[] {projectFolder}); + } + +} Index: project/src/org/netbeans/modules/project/ant/DefaultAntProjectOperation.java =================================================================== RCS file: project/src/org/netbeans/modules/project/ant/DefaultAntProjectOperation.java diff -N project/src/org/netbeans/modules/project/ant/DefaultAntProjectOperation.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project/src/org/netbeans/modules/project/ant/DefaultAntProjectOperation.java 22 Jun 2005 09:16:55 -0000 @@ -0,0 +1,320 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.project.ant; + +import java.awt.Dialog; +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.api.progress.ProgressHandleFactory; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectUtils; +import org.netbeans.api.project.ui.OpenProjects; +import org.netbeans.api.project.ProjectOperations; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.openide.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.ErrorManager; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; + + +/** + * + * @author Jan Lahoda + */ +public final class DefaultAntProjectOperation { + + private static final ErrorManager ERR = ErrorManager.getDefault(); // NOI18N + + private DefaultAntProjectOperation() { + } + + private static String getDisplayName(Project project) { + return ProjectUtils.getInformation(project).getDisplayName(); + } + + // + /** + * @return true if success + */ + private static boolean performDelete(AntProjectHelper helper, Project project, List/*FileObject>*/ toDelete, ProgressHandle handle) { + try { + String progressFormat = NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Progress_Deleting_File"); + + handle.start(toDelete.size() + 1 /*clean*/); + + int done = 0; + + handle.progress(NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Progress_Cleaning_Project")); + + ProjectOperations.getDefault().performClean(project); + + handle.progress(++done); + + for (Iterator i = toDelete.iterator(); i.hasNext(); ) { + FileObject f = (FileObject) i.next(); + + handle.progress(MessageFormat.format(progressFormat, new Object[] {FileUtil.getFileDisplayName(f)})); + + if (f != null) + f.delete(); + + handle.progress(++done); + } + + FileObject projectFolder = project.getProjectDirectory(); + + if (projectFolder.getChildren().length == 0) { + //empty, delete: + projectFolder.delete(); + } + + handle.finish(); + + ProjectOperations.getDefault().notifyDeleted(project); + return true; + } catch (IOException e) { + String displayName = getDisplayName(project); + String message = NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Project_cannot_be_deleted.", new Object[] {displayName}); + + ErrorManager.getDefault().annotate(e, message); + ErrorManager.getDefault().notify(ErrorManager.USER, e); + + return false; + } + } + + public static void deleteProject(final Project project) { + Runnable r = new Runnable() { + public void run() { + deleteProject(project, new GUIUserInputHandler()); + } + }; + + if (SwingUtilities.isEventDispatchThread()) { + r.run(); + } else { + SwingUtilities.invokeLater(r); + } + } + + /*package private*/static void deleteProject(final Project project, final UserInputHandler handler) { + String displayName = getDisplayName(project); + String projectFolder = FileUtil.getFileDisplayName(project.getProjectDirectory()); + + final AntProjectHelper helper = AntBasedProjectFactorySingleton.getHelperFor(project); + + assert helper != null; + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "delete started: " + displayName); // NOI18N + } + + List/**/ metadataFiles = ProjectOperations.getDefault().getMetadataFiles(project); + List/**/ dataFiles = ProjectOperations.getDefault().getDataFiles(project); + List/**/ allFiles = new ArrayList/**/(); + + allFiles.addAll(metadataFiles); + allFiles.addAll(dataFiles); + + int userAnswer = handler.userConfirmation(displayName, projectFolder, !dataFiles.isEmpty()); + List/**/ toDeleteImpl = null; + + switch (userAnswer) { + case UserInputHandler.USER_CANCEL: + return ; + case UserInputHandler.USER_OK_METADATA: + toDeleteImpl = metadataFiles; + break; + case UserInputHandler.USER_OK_ALL: + toDeleteImpl = allFiles; + break; + default: + throw new IllegalStateException("Invalid user answer: " + userAnswer); + } + + final ProgressHandle handle = handler.getProgressHandle(); + final List/**/ toDelete = toDeleteImpl; + final boolean[] result = new boolean[1]; + + OpenProjects.getDefault().close(new Project[] {project}); + + handler.delete(new Runnable() { + public void run() { + result[0] = performDelete(helper, project, toDelete, handle); + } + }); + +/* if (result[0]) { + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "delete successfull"); // NOI18N + } + + String message = NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Project_Deleted_Caption", new Object[] {displayName}); + NotifyDescriptor nd = new NotifyDescriptor.Message(message); + + DialogDisplayer.getDefault().notify(nd); + }*/ + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "delete done: " + displayName); // NOI18N + } + } + + /*package private*/interface UserInputHandler { + + public int USER_CANCEL = 1; + public int USER_OK_METADATA = 2; + public int USER_OK_ALL = 3; + + public abstract int userConfirmation(String displayName, String projectFolder, boolean enableData); + + public abstract ProgressHandle getProgressHandle(); + + public abstract void delete(Runnable r); + + } + + private static final class GUIUserInputHandler implements UserInputHandler { + + public int userConfirmation(String displayName, String projectFolder, boolean enableData) { + DefaultAntProjectDeletePanel deletePanel = new DefaultAntProjectDeletePanel(displayName, projectFolder, enableData); + + String caption = NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Delete_Project_Caption"); + + DialogDescriptor dd = new DialogDescriptor(deletePanel, caption); + + DialogDisplayer.getDefault().createDialog(dd).setVisible(true); + + if (dd.getValue() == DialogDescriptor.OK_OPTION) { + if (deletePanel.isDeleteSources()) { + return USER_OK_ALL; + } else { + return USER_OK_METADATA; + } + } else { + return USER_CANCEL; + } + } + + private ProgressHandle handle = null; + + public synchronized ProgressHandle getProgressHandle() { + if (handle == null) { + handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Delete_Project_Caption")); + } + + return handle; + } + + public void delete(final Runnable r) { + String inProgressCaption = NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Project_Deletion_in_Progress_Caption"); + DialogDescriptor dd2 = new DialogDescriptor(createProgressDialog(handle), inProgressCaption, true, new Object[0], null, DialogDescriptor.BOTTOM_ALIGN, HelpCtx.DEFAULT_HELP, null); + + final Dialog dialog = DialogDisplayer.getDefault().createDialog(dd2); + final boolean[] result = new boolean[1]; + + RequestProcessor.getDefault().post(new Runnable() { + public void run() { + r.run(); + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "delete finished"); // NOI18N + } + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "calling hide on progress dialog"); // NOI18N + } + + dialog.hide(); + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "done"); // NOI18N + } + } + }); + } + }); + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "showing progress dialog"); // NOI18N + } + + dialog.show(); + + if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) { + ERR.log(ErrorManager.INFORMATIONAL, "progress dialog hidden"); // NOI18N + } + } + + } + + private static JComponent createProgressDialog(ProgressHandle handle) { + JPanel dialog = new JPanel(); + + GridBagConstraints gridBagConstraints; + + JLabel jLabel1 = new JLabel(); + JComponent progress = ProgressHandleFactory.createProgressComponent(handle); + JPanel padding = new JPanel(); + + dialog.setLayout(new java.awt.GridBagLayout()); + + jLabel1.setText(NbBundle.getMessage(DefaultAntProjectOperation.class, "LBL_Deleting_Project")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new Insets(12, 12, 0, 12); + dialog.add(jLabel1, gridBagConstraints); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new Insets(12, 12, 0, 12); + dialog.add(progress, gridBagConstraints); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL | GridBagConstraints.VERTICAL; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new Insets(12, 12, 12, 12); + dialog.add(padding, gridBagConstraints); + + return dialog; + } + // + +} Index: project/src/org/netbeans/spi/project/support/ant/AntProjectHelper.java =================================================================== RCS file: /cvs/ant/project/src/org/netbeans/spi/project/support/ant/AntProjectHelper.java,v retrieving revision 1.30 diff -u -r1.30 AntProjectHelper.java --- project/src/org/netbeans/spi/project/support/ant/AntProjectHelper.java 14 Apr 2005 19:15:57 -0000 1.30 +++ project/src/org/netbeans/spi/project/support/ant/AntProjectHelper.java 22 Jun 2005 09:16:56 -0000 @@ -29,6 +29,7 @@ import org.netbeans.api.project.ProjectManager; import org.netbeans.api.project.ant.AntArtifact; import org.netbeans.modules.project.ant.AntBasedProjectFactorySingleton; +import org.netbeans.modules.project.ant.DefaultAntProjectOperation; import org.netbeans.modules.project.ant.FileChangeSupport; import org.netbeans.modules.project.ant.FileChangeSupportEvent; import org.netbeans.modules.project.ant.FileChangeSupportListener; @@ -37,6 +38,7 @@ import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.spi.project.CacheDirectoryProvider; import org.netbeans.spi.project.ProjectState; +import org.netbeans.api.project.ProjectOperations; import org.netbeans.spi.queries.FileBuiltQueryImplementation; import org.netbeans.spi.queries.SharabilityQueryImplementation; import org.openide.ErrorManager; @@ -469,6 +471,36 @@ */ public FileObject getProjectDirectory() { return dir; + } + + /**Notification that this project has been deleted. + * See {@link org.netbeans.api.projects.ProjectState#notifyDeleted}. + * + * @since 1.7 + */ + public void notifyDeleted() { + state.notifyDeleted(); + } + + /**Perform default delete operation. Gathers all necessary data, shows a confirmation + * dialog and deletes the project (if confirmed by the user). + * + * @since 1.7 + * + * @throws IllegalStateException if + * {@link org.netbeans.api.projects.ProjectOperations.getDefault().isDeleteOperationSupported} + * returns false for this project. + */ + public void performDefaultDeleteOperation() throws IllegalStateException { + Project p = AntBasedProjectFactorySingleton.getProjectFor(this); + + assert p != null; + + if (!ProjectOperations.getDefault().isDeleteOperationSupported(p)) { + throw new IllegalStateException("Attempt to delete project that does not support deletion."); + } + + DefaultAntProjectOperation.deleteProject(p); } /** Index: project/test/unit/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingletonTest.java =================================================================== RCS file: project/test/unit/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingletonTest.java diff -N project/test/unit/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingletonTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project/test/unit/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingletonTest.java 22 Jun 2005 09:16:56 -0000 @@ -0,0 +1,123 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.project.ant; + +import java.lang.reflect.Method; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.TestUtil; +import org.netbeans.junit.NbTestCase; +import org.netbeans.spi.project.support.ant.AntBasedProjectType; +import org.netbeans.spi.project.support.ant.AntBasedTestUtil; +import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.AntProjectHelperTest; +import org.openide.filesystems.FileObject; +import org.openide.util.lookup.Lookups; + + +/** + * + * @author Jan Lahoda + */ +public class AntBasedProjectFactorySingletonTest extends NbTestCase { + + public AntBasedProjectFactorySingletonTest(String testName) { + super(testName); + } + + private FileObject scratch; + private FileObject projdir; + + protected void setUp() throws Exception { + scratch = TestUtil.makeScratchDir(this); + projdir = scratch.createFolder("proj"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/private.xml"), projdir, "nbproject/private/private.xml"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/project.properties"), projdir, "nbproject/project.properties"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/private.properties"), projdir, "nbproject/private/private.properties"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/global.properties"), scratch, "userdir/build.properties"); + TestUtil.setLookup(new Object[] { + AntBasedTestUtil.testAntBasedProjectType(), + }); + } + + protected void tearDown() throws Exception { + } + + public static Test suite() { + TestSuite suite = new TestSuite(AntBasedProjectFactorySingletonTest.class); + + return suite; + } + + /**Test for second part of #42738. + */ + public void testAntBasedProjectTypesChanged() throws Exception { + AntBasedProjectFactorySingleton factory = new AntBasedProjectFactorySingleton(); + AntBasedProjectType type1 = AntBasedTestUtil.testAntBasedProjectType(); + AntBasedProjectType type2 = AntBasedTestUtil.testAntBasedProjectType(); + + TestUtil.setLookup(Lookups.fixed(new Object[] { + factory, + type1, + type2, + })); + + Method getAntBasedProjectTypeMethod = AntProjectHelper.class.getDeclaredMethod("getType", new Class[0]); + + getAntBasedProjectTypeMethod.setAccessible(true); + + Project p = ProjectManager.getDefault().findProject(projdir); + AntProjectHelper helper = (AntProjectHelper) p.getLookup().lookup(AntProjectHelper.class); + + assertTrue(getAntBasedProjectTypeMethod.invoke(helper, null) == type2); + + TestUtil.setLookup(Lookups.fixed(new Object[] { + factory, + type1, + })); + + p = ProjectManager.getDefault().findProject(projdir); + helper = (AntProjectHelper) p.getLookup().lookup(AntProjectHelper.class); + + assertTrue(getAntBasedProjectTypeMethod.invoke(helper, null) == type1); + + TestUtil.setLookup(Lookups.fixed(new Object[] { + factory, + type2, + })); + + p = ProjectManager.getDefault().findProject(projdir); + helper = (AntProjectHelper) p.getLookup().lookup(AntProjectHelper.class); + + assertTrue(getAntBasedProjectTypeMethod.invoke(helper, null) == type2); + + TestUtil.setLookup(Lookups.fixed(new Object[] { + factory, + })); + + assertNull(ProjectManager.getDefault().findProject(projdir)); + + TestUtil.setLookup(Lookups.fixed(new Object[] { + factory, + type1, + type2, + })); + + assertTrue(getAntBasedProjectTypeMethod.invoke(helper, null) == type2); + } + +} Index: project/test/unit/src/org/netbeans/modules/project/ant/DefaultAntProjectOperationTest.java =================================================================== RCS file: project/test/unit/src/org/netbeans/modules/project/ant/DefaultAntProjectOperationTest.java diff -N project/test/unit/src/org/netbeans/modules/project/ant/DefaultAntProjectOperationTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project/test/unit/src/org/netbeans/modules/project/ant/DefaultAntProjectOperationTest.java 22 Jun 2005 09:16:56 -0000 @@ -0,0 +1,169 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.project.ant; + +import java.io.File; +import java.util.Arrays; +import junit.framework.*; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.api.progress.ProgressHandleFactory; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.TestUtil; +import org.netbeans.junit.NbTestCase; +import org.netbeans.modules.project.ant.DefaultAntProjectOperation.UserInputHandler; +import org.netbeans.modules.project.ui.OpenProjectsTrampolineImpl; +import org.netbeans.spi.project.support.ant.AntBasedTestUtil; +import org.netbeans.spi.project.support.ant.AntProjectHelperTest; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + + +/** + * + * @author Jan Lahoda + */ +public class DefaultAntProjectOperationTest extends NbTestCase { + + public DefaultAntProjectOperationTest(String testName) { + super(testName); + } + + private FileObject scratch; + private FileObject projdir; + private Project prj; + private File projectDirectory; + + private void createProject(FileObject projdir) throws Exception { + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/project.xml"), projdir, "nbproject/project.xml"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/private.xml"), projdir, "nbproject/private/private.xml"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/project.properties"), projdir, "nbproject/project.properties"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/private.properties"), projdir, "nbproject/private/private.properties"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/test.txt"), projdir, "src/test/test.txt"); + TestUtil.createFileFromContent(AntProjectHelperTest.class.getResource("data/global.properties"), scratch, "userdir/build.properties"); + } + + protected void setUp() throws Exception { + scratch = TestUtil.makeScratchDir(this); + projdir = scratch.createFolder("proj"); + + createProject(projdir); + + TestUtil.setLookup(new Object[] { + AntBasedTestUtil.testAntBasedProjectType(), + new OpenProjectsTrampolineImpl(), + }); + + prj = ProjectManager.getDefault().findProject(projdir); + + assertNotNull(prj); + + projectDirectory = FileUtil.toFile(projdir); + + assertNotNull(projectDirectory); + } + + public void testDeleteProjectDeleteAll() throws Exception { + TestUserInputHandler handler = new TestUserInputHandler(UserInputHandler.USER_OK_ALL); + + DefaultAntProjectOperation.deleteProject(prj, handler); + + assertTrue(handler.userConfirmationCalled); + assertTrue(handler.enableData); + assertTrue(handler.getProgressHandleCalled); + assertTrue(handler.deleteCalled); + + assertFalse(projectDirectory.exists()); + } + + public void testDeleteProjectDeleteMetadata() throws Exception { + TestUserInputHandler handler = new TestUserInputHandler(UserInputHandler.USER_OK_METADATA); + + DefaultAntProjectOperation.deleteProject(prj, handler); + + assertTrue(handler.userConfirmationCalled); + assertTrue(handler.enableData); + assertTrue(handler.getProgressHandleCalled); + assertTrue(handler.deleteCalled); + + assertTrue(projectDirectory.exists()); + assertTrue(Arrays.equals(new String[] {"src"}, projectDirectory.list())); + } + + public void testDeleteProjectDoNotDelete() throws Exception { + TestUserInputHandler handler = new TestUserInputHandler(UserInputHandler.USER_CANCEL); + + DefaultAntProjectOperation.deleteProject(prj, handler); + + assertTrue(handler.userConfirmationCalled); + assertTrue(handler.enableData); + assertFalse(handler.getProgressHandleCalled); + assertFalse(handler.deleteCalled); + + assertTrue(projectDirectory.exists()); + assertTrue(Arrays.equals(new String[] {"nbproject", "src"}, projectDirectory.list())); + } + + public void testDeleteProjectNestedProject() throws Exception { + FileObject projdir2 = projdir.createFolder("proj2"); + + createProject(projdir2); + + TestUserInputHandler handler = new TestUserInputHandler(UserInputHandler.USER_OK_ALL); + + DefaultAntProjectOperation.deleteProject(prj, handler); + + assertTrue(handler.userConfirmationCalled); + assertTrue(handler.enableData); + assertTrue(handler.getProgressHandleCalled); + assertTrue(handler.deleteCalled); + + assertTrue(projectDirectory.exists()); + assertTrue(Arrays.equals(new String[] {"proj2"}, projectDirectory.list())); + } + + private static final class TestUserInputHandler implements UserInputHandler { + + private int answer; + private ProgressHandle handle; + + private boolean userConfirmationCalled; + private boolean enableData; + private boolean getProgressHandleCalled; + private boolean deleteCalled; + + public TestUserInputHandler(int answer) { + this.answer = answer; + this.handle = ProgressHandleFactory.createHandle("test"); + } + + public int userConfirmation(String displayName, String projectFolder, boolean enableData) { + userConfirmationCalled = true; + this.enableData = enableData; + return answer; + } + + public ProgressHandle getProgressHandle() { + getProgressHandleCalled = true; + return handle; + } + + public void delete(Runnable r) { + deleteCalled = true; + r.run(); + } + + } + +} Index: project/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java =================================================================== RCS file: /cvs/ant/project/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java,v retrieving revision 1.15 diff -u -r1.15 AntBasedTestUtil.java --- project/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java 3 Apr 2005 01:29:15 -0000 1.15 +++ project/test/unit/src/org/netbeans/spi/project/support/ant/AntBasedTestUtil.java 22 Jun 2005 09:16:56 -0000 @@ -7,7 +7,7 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun * Microsystems, Inc. All Rights Reserved. */ @@ -29,6 +29,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -50,6 +51,8 @@ import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.api.project.ProjectInformation; import org.netbeans.api.project.ProjectManager; +import org.netbeans.spi.project.ProjectOperationsImplementation; +import org.netbeans.spi.project.ProjectOperationsImplementation.DeleteOperationImplementation; import org.netbeans.spi.project.ant.AntArtifactProvider; import org.netbeans.spi.queries.CollocationQueryImplementation; import org.openide.filesystems.FileObject; @@ -160,6 +163,7 @@ } }, "hello", + new DeleteProjectOperationImpl(this), }); } @@ -238,6 +242,43 @@ public void setBuildArtifacts(AntArtifact[] arts) { this.arts = arts; + } + + } + + public final class DeleteProjectOperationImpl implements DeleteOperationImplementation { + + private boolean wasCleaned = false; + private boolean wasNotified = false; + + private TestAntBasedProject project; + + public DeleteProjectOperationImpl(TestAntBasedProject project) { + this.project = project; + } + + public List getMetadataFiles() { + return Collections.singletonList(project.getProjectDirectory().getFileObject("nbproject")); + } + + public List getDataFiles() { + return Collections.singletonList(project.getProjectDirectory().getFileObject("src")); + } + + public synchronized boolean getWasCleaned() { + return wasCleaned; + } + + public synchronized void performClean() throws IOException { + wasCleaned = true; + } + + public synchronized boolean getWasNotified() { + return wasNotified; + } + + public synchronized void notifyDeleted() throws IOException { + wasNotified = true; } } Index: project/test/unit/src/org/netbeans/spi/project/support/ant/data/test.txt =================================================================== RCS file: project/test/unit/src/org/netbeans/spi/project/support/ant/data/test.txt diff -N project/test/unit/src/org/netbeans/spi/project/support/ant/data/test.txt