KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > ui > ModulesNodeFactory


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.apisupport.project.ui;
21
22 import java.awt.EventQueue JavaDoc;
23 import java.awt.Image JavaDoc;
24 import java.awt.event.ActionEvent JavaDoc;
25 import java.beans.PropertyChangeEvent JavaDoc;
26 import java.beans.PropertyChangeListener JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.SortedSet JavaDoc;
30 import java.util.TreeSet JavaDoc;
31 import javax.swing.AbstractAction JavaDoc;
32 import javax.swing.Action JavaDoc;
33 import javax.swing.event.ChangeEvent JavaDoc;
34 import javax.swing.event.ChangeListener JavaDoc;
35 import org.netbeans.api.project.Project;
36 import org.netbeans.api.project.ProjectInformation;
37 import org.netbeans.api.project.ProjectManager;
38 import org.netbeans.api.project.ProjectUtils;
39 import org.netbeans.api.project.ui.OpenProjects;
40 import org.netbeans.modules.apisupport.project.NbModuleProject;
41 import org.netbeans.modules.apisupport.project.Util;
42 import org.netbeans.modules.apisupport.project.suite.SuiteProject;
43 import org.netbeans.modules.apisupport.project.ui.customizer.SuiteUtils;
44 import org.netbeans.modules.apisupport.project.ui.wizard.NewNbModuleWizardIterator;
45 import org.netbeans.spi.project.SubprojectProvider;
46 import org.netbeans.spi.project.ui.support.NodeFactory;
47 import org.netbeans.spi.project.ui.support.NodeFactorySupport;
48 import org.netbeans.spi.project.ui.support.NodeList;
49 import org.openide.DialogDisplayer;
50 import org.openide.ErrorManager;
51 import org.openide.NotifyDescriptor;
52 import org.openide.awt.StatusDisplayer;
53 import org.openide.nodes.AbstractNode;
54 import org.openide.nodes.Children;
55 import org.openide.nodes.Node;
56 import org.openide.util.HelpCtx;
57 import org.openide.util.NbBundle;
58 import org.openide.util.RequestProcessor;
59 import org.openide.util.Utilities;
60 import org.openide.util.actions.CookieAction;
61 import org.openide.util.actions.NodeAction;
62 import org.openide.util.lookup.Lookups;
63 import org.openide.windows.WindowManager;
64
65 /**
66  *
67  * @author mkleint
68  */

69 public class ModulesNodeFactory implements NodeFactory {
70     
71     /** Creates a new instance of ImportantFilesNodeFactory */
72     public ModulesNodeFactory() {
73     }
74     
75     public NodeList createNodes(Project p) {
76         SuiteProject prj = p.getLookup().lookup(SuiteProject.class);
77         assert prj != null;
78         return NodeFactorySupport.fixedNodeList(new ModulesNode(prj));
79     }
80     
81     private static String JavaDoc getMessage(final String JavaDoc key) {
82         return NbBundle.getMessage(SuiteLogicalView.class, key);
83     }
84     
85
86     /** Represent <em>Modules</em> node in the Suite Logical View. */
87     static final class ModulesNode extends AbstractNode {
88         
89         private SuiteProject suite;
90         
91         ModulesNode(final SuiteProject suite) {
92             super(new ModuleChildren(suite));
93             this.suite = suite;
94             setName("modules"); // NOI18N
95
setDisplayName(getMessage("CTL_Modules"));
96         }
97         
98         public Action JavaDoc[] getActions(boolean context) {
99             return new Action JavaDoc[] {
100                 new AddNewSuiteComponentAction(suite),
101                 new AddNewLibraryWrapperAction(suite),
102                 new AddSuiteComponentAction(suite),
103             };
104         }
105         
106         private Image JavaDoc getIcon(boolean opened) {
107             Image JavaDoc badge = Utilities.loadImage("org/netbeans/modules/apisupport/project/suite/resources/module-badge.gif", true);
108             return Utilities.mergeImages(UIUtil.getTreeFolderIcon(opened), badge, 9, 9);
109         }
110         
111         public Image JavaDoc getIcon(int type) {
112             return getIcon(false);
113         }
114         
115         public Image JavaDoc getOpenedIcon(int type) {
116             return getIcon(true);
117         }
118         
119         static final class ModuleChildren extends Children.Keys<NbModuleProject> implements ChangeListener JavaDoc {
120             
121             private final SuiteProject suite;
122             
123             public ModuleChildren(SuiteProject suite) {
124                 suite.getLookup().lookup(SubprojectProvider.class).addChangeListener(this);
125                 this.suite = suite;
126             }
127             
128             protected void addNotify() {
129                 updateKeys();
130             }
131             
132             private void updateKeys() {
133                 // e.g.(?) Explorer view under Children.MUTEX subsequently calls e.g.
134
// SuiteProject$Info.getSimpleName() which acquires ProjectManager.mutex(). And
135
// since this method might be called under ProjectManager.mutex() write access
136
// and updateKeys() --> setKeys() in turn calls Children.MUTEX write access,
137
// deadlock is here, so preventing it... (also got this under read access)
138
EventQueue.invokeLater(new Runnable JavaDoc() {
139                     public void run() {
140                         // #70112: sort them.
141
SortedSet JavaDoc<NbModuleProject> subModules = new TreeSet JavaDoc(Util.projectDisplayNameComparator());
142                         subModules.addAll(SuiteUtils.getSubProjects(suite));
143                         setKeys(subModules);
144                     }
145                 });
146             }
147             
148             protected void removeNotify() {
149                 suite.getLookup().lookup(SubprojectProvider.class).removeChangeListener(this);
150                 setKeys(Collections.EMPTY_SET);
151             }
152             
153             protected Node[] createNodes(NbModuleProject p) {
154                 return new Node[] {new SuiteComponentNode(p)};
155             }
156             
157             public void stateChanged(ChangeEvent JavaDoc ev) {
158                 updateKeys();
159             }
160             
161         }
162         
163     }
164     
165     private static final class AddSuiteComponentAction extends AbstractAction JavaDoc {
166         
167         private final SuiteProject suite;
168         
169         public AddSuiteComponentAction(final SuiteProject suite) {
170             super(getMessage("CTL_AddModule"));
171             this.suite = suite;
172         }
173         
174         public void actionPerformed(ActionEvent JavaDoc evt) {
175             NbModuleProject project = UIUtil.chooseSuiteComponent(
176                     WindowManager.getDefault().getMainWindow(),
177                     suite);
178             if (project != null) {
179                 if (!SuiteUtils.contains(suite, project)) {
180                     try {
181                         SuiteUtils.addModule(suite, (NbModuleProject) project);
182                         ProjectManager.getDefault().saveProject(suite);
183                     } catch (IOException JavaDoc ex) {
184                         ErrorManager.getDefault().notify(ex);
185                     }
186                 } else {
187                     DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
188                             NbBundle.getMessage(SuiteLogicalView.class, "MSG_SuiteAlreadyContainsCNB", project.getCodeNameBase())));
189                 }
190             }
191         }
192         
193     }
194     
195     private static final class AddNewSuiteComponentAction extends AbstractAction JavaDoc {
196         
197         private final SuiteProject suite;
198         
199         public AddNewSuiteComponentAction(final SuiteProject suite) {
200             super(getMessage("CTL_AddNewModule"));
201             this.suite = suite;
202         }
203         
204         public void actionPerformed(ActionEvent JavaDoc evt) {
205             NewNbModuleWizardIterator iterator = NewNbModuleWizardIterator.createSuiteComponentIterator(suite);
206             UIUtil.runProjectWizard(iterator, "CTL_NewModuleProject"); // NOI18N
207
}
208         
209     }
210     
211     static final class AddNewLibraryWrapperAction extends AbstractAction JavaDoc {
212         
213         private final Project suiteProvider;
214         private final NbModuleProject target;
215         
216         public AddNewLibraryWrapperAction(final Project suiteProvider, final NbModuleProject target) {
217             super(getMessage("CTL_AddNewLibrary"));
218             this.suiteProvider = suiteProvider;
219             this.target = target;
220         }
221         
222         public AddNewLibraryWrapperAction(final Project suiteProvider) {
223             this(suiteProvider, null);
224         }
225         
226         public void actionPerformed(ActionEvent JavaDoc evt) {
227             NbModuleProject project = UIUtil.runLibraryWrapperWizard(suiteProvider);
228             if (project != null && target != null) {
229                 try {
230                     Util.addDependency(target, project);
231                     ProjectManager.getDefault().saveProject(target);
232                 } catch (IOException JavaDoc e) {
233                     assert false : e;
234                 }
235             }
236         }
237         
238     }
239     
240     /** Represent one module (a suite component) node. */
241     private static final class SuiteComponentNode extends AbstractNode {
242         
243         private final static Action JavaDoc REMOVE_ACTION = new RemoveSuiteComponentAction();
244         private final static Action JavaDoc OPEN_ACTION = new OpenProjectAction();
245         
246         public SuiteComponentNode(final NbModuleProject suiteComponent) {
247             super(Children.LEAF, Lookups.fixed(new Object JavaDoc[] {suiteComponent}));
248             ProjectInformation info = ProjectUtils.getInformation(suiteComponent);
249             setName(info.getName());
250             setDisplayName(info.getDisplayName());
251             setIconBaseWithExtension(NbModuleProject.NB_PROJECT_ICON_PATH);
252             info.addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
253                 public void propertyChange(PropertyChangeEvent JavaDoc evt) {
254                     if (evt.getPropertyName() == ProjectInformation.PROP_DISPLAY_NAME) {
255                         SuiteComponentNode.this.setDisplayName((String JavaDoc) evt.getNewValue());
256                     } else if (evt.getPropertyName() == ProjectInformation.PROP_NAME) {
257                         SuiteComponentNode.this.setName((String JavaDoc) evt.getNewValue());
258                     }
259                 }
260             });
261         }
262         
263         public Action JavaDoc[] getActions(boolean context) {
264             return new Action JavaDoc[] {
265                 OPEN_ACTION, REMOVE_ACTION
266             };
267         }
268         
269         public Action JavaDoc getPreferredAction() {
270             return OPEN_ACTION;
271         }
272         
273     }
274     
275     private static final class RemoveSuiteComponentAction extends NodeAction {
276         
277         protected void performAction(Node[] activatedNodes) {
278             for (int i = 0; i < activatedNodes.length; i++) {
279                 final NbModuleProject suiteComponent =
280                         (NbModuleProject) activatedNodes[i].getLookup().lookup(NbModuleProject.class);
281                 assert suiteComponent != null : "NbModuleProject in lookup"; // NOI18N
282
try {
283                     NbModuleProject[] modules = SuiteUtils.getDependentModules(suiteComponent);
284                     boolean remove = true;
285                     if (modules.length > 0) {
286                         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("<ul>"); // NOI18N
287
for (int j = 0; j < modules.length; j++) {
288                             sb.append("<li>" + ProjectUtils.getInformation(modules[j]).getDisplayName() + "</li>"); // NOI18N
289
}
290                         sb.append("</ul>"); // NOI18N
291
String JavaDoc displayName = ProjectUtils.getInformation(suiteComponent).getDisplayName();
292                         String JavaDoc confirmMessage = NbBundle.getMessage(SuiteLogicalView.class,
293                                 "MSG_RemovingModuleMessage", displayName, sb.toString()); // NOI18N
294
remove = UIUtil.showAcceptCancelDialog(
295                                 NbBundle.getMessage(SuiteLogicalView.class, "CTL_RemovingModuleTitle", displayName),
296                                 confirmMessage, getMessage("CTL_RemoveDependency"), null, NotifyDescriptor.QUESTION_MESSAGE);
297                     }
298                     if (remove) {
299                         SuiteUtils.removeModuleFromSuiteWithDependencies(suiteComponent);
300                     }
301                 } catch (IOException JavaDoc ex) {
302                     ErrorManager.getDefault().notify(ex);
303                 }
304             }
305         }
306         
307         protected boolean enable(Node[] activatedNodes) {
308             return true;
309         }
310         
311         public String JavaDoc getName() {
312             return getMessage("CTL_RemoveModule");
313         }
314         
315         public HelpCtx getHelpCtx() {
316             return HelpCtx.DEFAULT_HELP;
317         }
318         
319         protected boolean asynchronous() {
320             return false;
321         }
322         
323     }
324     
325     private static final class OpenProjectAction extends CookieAction {
326         
327         protected void performAction(Node[] activatedNodes) {
328             final Project[] projects = new Project[activatedNodes.length];
329             for (int i = 0; i < activatedNodes.length; i++) {
330                 Project project = (Project) activatedNodes[i].getLookup().lookup(Project.class);
331                 projects[i] = project;
332             }
333             RequestProcessor.getDefault().post(new Runnable JavaDoc() {
334                 public void run() {
335                     StatusDisplayer.getDefault().setStatusText(getMessage("MSG_OpeningProjects"));
336                     OpenProjects.getDefault().open(projects, false);
337                 }
338             });
339         }
340         
341         public String JavaDoc getName() {
342             return getMessage("CTL_OpenProject");
343         }
344         
345         public HelpCtx getHelpCtx() {
346             return HelpCtx.DEFAULT_HELP;
347         }
348         
349         protected boolean asynchronous() {
350             return false;
351         }
352         
353         protected int mode() {
354             return CookieAction.MODE_ALL;
355         }
356         
357         protected Class JavaDoc[] cookieClasses() {
358             return new Class JavaDoc[] { Project.class };
359         }
360         
361     }
362     
363 }
364
Popular Tags