2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
43
package org.netbeans.modules.j2ee.archive.ui;
45
import java.util.ArrayList;
46
import java.util.Collections;
47
import java.util.Iterator;
48
import java.util.List;
49
import java.util.ResourceBundle;
50
import javax.swing.Action;
51
import javax.swing.JSeparator;
52
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.ProjectUtils;
54
import org.netbeans.modules.j2ee.archive.project.ArchiveProject;
55
import org.netbeans.modules.j2ee.archive.project.ArchiveProjectProperties;
56
import org.netbeans.modules.j2ee.spi.ejbjar.support.J2eeProjectView;
57
import org.netbeans.spi.project.ActionProvider;
58
import org.netbeans.spi.project.ui.support.CommonProjectActions;
59
import org.netbeans.spi.project.ui.support.ProjectSensitiveActions;
60
import org.openide.filesystems.FileChangeListener;
61
import org.openide.filesystems.FileObject;
62
import org.openide.loaders.DataFolder;
63
import org.openide.nodes.Children;
64
import org.openide.nodes.Node;
65
//import org.openide.util.HelpCtx;
66
import org.openide.util.Lookup;
67
import org.openide.util.NbBundle;
68
import org.openide.util.actions.SystemAction;
69
import org.openide.util.lookup.Lookups;
71
public class RootNode extends org.openide.nodes.AbstractNode {
73
// private boolean broken;
75
// private BrokenLinksAction brokenLinksAction;
77
// private BrokenServerAction brokenServerAction;
79
public RootNode(ArchiveProject ap) {
80
super(new LogicalViewChildren(ap), createLookup(ap));
81
super.setName(ProjectUtils.getInformation(ap).getDisplayName());
82
setIconBaseWithExtension("org/netbeans/modules/j2ee/archive/project/resources/packaged_archive_16.png"); // NOI18N
83
// if (hasBrokenLinks()) {
86
// brokenLinksAction = new BrokenLinksAction();
87
// brokenServerAction = new BrokenServerAction();
89
ArchiveProjectProperties app = ap.getArchiveProjectProperties();
90
String sourceArchive = ap.getPropertyEvaluator().evaluate((String)app.get(ArchiveProjectProperties.SOURCE_ARCHIVE));
91
setShortDescription(NbBundle.getMessage(RootNode.class,"LBL_ProjectToolTip", // NOI18N
95
public Action[] getActions( boolean context ) {
98
retVal = super.getActions( true );
100
retVal = getAdditionalActions();
105
private Action[] getAdditionalActions() {
107
ResourceBundle bundle = NbBundle.getBundle(RootNode.class);
109
List actions = new ArrayList(30);
110
actions.add(CommonProjectActions.newFileAction());
112
actions.add(ProjectSensitiveActions.projectCommandAction(
113
ActionProvider.COMMAND_BUILD, bundle.getString("LBL_BuildAction_Name"), null)); // NOI18N
114
actions.add(ProjectSensitiveActions.projectCommandAction(
115
"verify", bundle.getString("LBL_VerifyAction_Name"), null)); // NOI18N
116
actions.add(ProjectSensitiveActions.projectCommandAction(
117
ActionProvider.COMMAND_RUN, bundle.getString("LBL_RunAction_Name"), null)); // NOI18N
119
actions.add(CommonProjectActions.setAsMainProjectAction());
120
actions.add(CommonProjectActions.openSubprojectsAction());
121
actions.add(CommonProjectActions.closeProjectAction());
123
actions.add(CommonProjectActions.renameProjectAction());
124
actions.add(CommonProjectActions.moveProjectAction());
125
actions.add(CommonProjectActions.copyProjectAction());
126
actions.add(CommonProjectActions.deleteProjectAction());
128
actions.add(SystemAction.get( org.openide.actions.FindAction.class ));
130
// honor 57874 contact
133
Lookup lookup = Lookups.forPath("Projects/Actions"); // NOI18N
134
Lookup.Template query = new Lookup.Template(Object.class);
135
Iterator it = lookup.lookup(query).allInstances().iterator();
139
while (it.hasNext()) {
140
Object next = it.next();
141
if (next instanceof Action) {
143
} else if (next instanceof JSeparator) {
148
// actions.add(null);
149
// if (brokenLinksAction != null && brokenLinksAction.isEnabled()) {
150
// actions.add(brokenLinksAction);
152
// if (brokenServerAction.isEnabled()) {
153
// actions.add(brokenServerAction);
156
actions.add(CommonProjectActions.customizeProjectAction());
158
return (Action[])actions.toArray(new Action[actions.size()]);
161
static final class LogicalViewChildren extends Children.Keys/*<FileObject>*/ implements FileChangeListener {
163
// XXX does not react correctly to addition or removal of src/ subdir
165
private static final String KEY_DOC_BASE = "docBase"; //NOI18N
166
private static final String KEY_SETUP_DIR = "setupDir"; //NOI18N
168
private ArchiveProject project;
170
public LogicalViewChildren(ArchiveProject project) {
171
assert project != null;
172
this.project = project;
175
protected void addNotify() {
177
project.getProjectDirectory().addFileChangeListener(this);
181
private void createNodes() {
182
List l = new ArrayList();
183
DataFolder docBaseDir = getFolder((String)project.getArchiveProjectProperties().get(ArchiveProjectProperties.PROXY_PROJECT_DIR)); // WEB_CONF);
184
if (docBaseDir != null) {
187
l.add(KEY_SETUP_DIR);
189
String dir = (String)project.getArchiveProjectProperties().get(ArchiveProjectProperties.PROXY_PROJECT_DIR);
190
FileObject fo = project.getProjectDirectory().getFileObject("subarchives"); // NOI18N
192
FileObject subarchives[] = fo.getChildren();
193
for (FileObject innerFo : subarchives) {
194
FileObject innerProj = null;
195
if (null != innerFo) {
196
innerProj = innerFo.getFileObject("tmpproj"); // NOI18N
198
if (null != innerProj && innerProj.isFolder()) {
199
DataFolder folder = getFolder("subarchives/"+innerFo.getName()+"/"+dir); // NOI18N
200
if (null == folder) {
203
Node n = new ModuleNode(folder,
204
NbBundle.getMessage(RootNode.class,"LBL_ModuleNode", // NOI18N
205
project.getEarPath(innerFo.getName())));
213
protected void removeNotify() {
214
setKeys(Collections.EMPTY_SET);
215
project.getProjectDirectory().removeFileChangeListener(this);
216
super.removeNotify();
219
protected Node[] createNodes(Object key) {
221
if (key == KEY_DOC_BASE) {
222
n = new ConfigFilesNode(getFolder((String)project.getArchiveProjectProperties().get(ArchiveProjectProperties.PROXY_PROJECT_DIR)));
223
} else if (key == KEY_SETUP_DIR) {
224
n = J2eeProjectView.createServerResourcesNode(project);
228
return n == null ? new Node[0] : new Node[] {n};
231
private DataFolder getFolder(String dir) {
232
FileObject fo = project.getProjectDirectory();
237
fo = fo.getFileObject(dir);
243
// check for a web app
244
fo = fo.getFileObject("web"); // NOI18N
246
fo = fo.getFileObject("WEB-INF"); // NOI18N
248
DataFolder df = DataFolder.findFolder(fo);
254
fo = project.getProjectDirectory().getFileObject(dir);
258
fo = fo.getFileObject("src"); // NOI18N
262
fo = fo.getFileObject("conf"); // NOI18N
266
return DataFolder.findFolder(fo);
269
// file change events in the project directory
270
public void fileAttributeChanged(org.openide.filesystems.FileAttributeEvent fe) {
273
public void fileChanged(org.openide.filesystems.FileEvent fe) {
276
public void fileDataCreated(org.openide.filesystems.FileEvent fe) {
279
public void fileDeleted(org.openide.filesystems.FileEvent fe) {
280
// setup folder deleted
281
//this was playing in a deadlock stack of 74613.
282
// This needs to be re-evaluated
287
public void fileFolderCreated(org.openide.filesystems.FileEvent fe) {
288
// setup folder could be created
292
public void fileRenamed(org.openide.filesystems.FileRenameEvent fe) {
293
// setup folder could be renamed
299
private static Lookup createLookup( Project project ) {
300
DataFolder rootFolder = DataFolder.findFolder( project.getProjectDirectory() );
301
// XXX Remove root folder after FindAction rewrite
302
return Lookups.fixed( new Object[] { project, rootFolder } );
305
// private static final String[] BREAKABLE_PROPERTIES = new String[] {
306
// ArchiveProjectProperties.SOURCE_ARCHIVE,
309
// public boolean hasBrokenLinks() {
310
// return BrokenReferencesSupport.isBroken(helper.getAntProjectHelper(), resolver, getBreakableProperties(),
311
// new String[] {WebProjectProperties.JAVA_PLATFORM});
314
// private String[] getBreakableProperties() {
315
//// SourceRoots roots = this.project.getSourceRoots();
316
//// String[] srcRootProps = roots.getRootProperties();
317
//// roots = this.project.getTestSourceRoots();
318
//// String[] testRootProps = roots.getRootProperties();
319
// String[] result = new String [BREAKABLE_PROPERTIES.length]; // + srcRootProps.length + testRootProps.length];
320
// System.arraycopy(BREAKABLE_PROPERTIES, 0, result, 0, BREAKABLE_PROPERTIES.length);
321
//// System.arraycopy(srcRootProps, 0, result, BREAKABLE_PROPERTIES.length, srcRootProps.length);
322
//// System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length);
326
// private static Image brokenProjectBadge = Utilities.loadImage( "org/netbeans/modules/web/project/ui/resources/brokenProjectBadge.gif" ); // NOI18N
328
/** This action is created only when project has broken references.
329
* Once these are resolved the action is disabled.
331
// private class BrokenLinksAction extends AbstractAction implements PropertyChangeListener, ChangeListener, Runnable {
333
// private RequestProcessor.Task task = null;
335
// private PropertyChangeListener weakPCL;
337
// public BrokenLinksAction() {
338
// putValue(Action.NAME, NbBundle.getMessage(RootNode.class, "LBL_Fix_Broken_Links_Action"));
339
// setEnabled(broken);
340
//// evaluator.addPropertyChangeListener( this );
341
// // When evaluator fires changes that platform properties were
342
// // removed the platform still exists in JavaPlatformManager.
343
// // That's why I have to listen here also on JPM:
344
// //weakPCL = WeakListeners.propertyChange( this, JavaPlatformManager.getDefault() );
345
// //JavaPlatformManager.getDefault().addPropertyChangeListener( weakPCL );
346
// RootNode.this.addChangeListener((ChangeListener)WeakListeners.change(this, RootNode.this));
349
// public void actionPerformed(ActionEvent e) {
351
// helper.requestSave();
352
// BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String[]{WebProjectProperties.JAVA_PLATFORM});
354
// } catch (IOException ioe) {
355
// ErrorManager.getDefault().notify(ioe);
359
// public void propertyChange(PropertyChangeEvent evt) {
363
// public void stateChanged(ChangeEvent evt) {
367
// public synchronized void run() {
368
// boolean old = broken;
369
// broken = hasBrokenLinks();
370
// if (old != broken) {
371
// setEnabled(broken);
373
// fireOpenedIconChange();
374
// fireDisplayNameChange(null, null);
375
// //project.getWebProjectProperties().save();
379
// public void refsMayChanged() {
380
// // check project state whenever there was a property change
381
// // or change in list of platforms.
382
// // Coalesce changes since they can come quickly:
383
// if (task == null) {
384
// task = BROKEN_LINKS_RP.create(this);
386
// task.schedule(100);
391
// private class BrokenServerAction extends AbstractAction implements
392
// InstanceListener, PropertyChangeListener {
394
// private boolean brokenServer;
396
// public BrokenServerAction() {
397
// putValue(Action.NAME, NbBundle.getMessage(RootNode.class, "LBL_Fix_Missing_Server_Action")); // NOI18N
398
// evaluator.addPropertyChangeListener(this);
399
// checkMissingServer();
402
// public boolean isEnabled() {
403
// return brokenServer;
406
// public void actionPerformed(ActionEvent e) {
407
// BrokenServerSupport.showCustomizer(project, helper);
408
// checkMissingServer();
411
// public void propertyChange(PropertyChangeEvent evt) {
412
// if (ArchiveProjectProperties.J2EE_SERVER_INSTANCE.equals(evt.getPropertyName())) {
413
// checkMissingServer();
417
// public void changeDefaultInstance(String oldServerInstanceID, String newServerInstanceID) {
420
// public void instanceAdded(String serverInstanceID) {
421
// checkMissingServer();
424
// public void instanceRemoved(String serverInstanceID) {
425
// checkMissingServer();
428
// private void checkMissingServer() {
429
// boolean old = brokenServer;
430
// String servInstID = evaluator.getProperty(ArchiveProjectProperties.J2EE_SERVER_INSTANCE);
431
// brokenServer = BrokenServerSupport.isBroken(servInstID);
432
// if (old != brokenServer) {
434
// fireOpenedIconChange();
435
// fireDisplayNameChange(null, null);