001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.apisupport.project.ui;
043:
044: import java.awt.Image;
045: import java.beans.PropertyChangeEvent;
046: import java.beans.PropertyChangeListener;
047: import java.util.HashSet;
048: import java.util.Set;
049: import javax.swing.Action;
050: import org.netbeans.api.project.ProjectUtils;
051: import org.netbeans.spi.java.project.support.ui.PackageView;
052: import org.netbeans.api.project.ProjectInformation;
053: import org.netbeans.api.project.SourceGroup;
054: import org.netbeans.api.project.Sources;
055: import org.netbeans.modules.apisupport.project.NbModuleProject;
056: import org.netbeans.spi.project.ui.LogicalViewProvider;
057: import org.netbeans.spi.project.ui.support.DefaultProjectOperations;
058: import org.netbeans.spi.project.ui.support.NodeFactorySupport;
059: import org.openide.filesystems.FileObject;
060: import org.openide.filesystems.FileUtil;
061: import org.openide.loaders.DataObject;
062: import org.openide.loaders.DataObjectNotFoundException;
063: import org.openide.nodes.Node;
064: import org.openide.util.NbBundle;
065: import org.openide.util.lookup.Lookups;
066:
067: /**
068: * Provides a logical view of a NetBeans module project.
069: * @author Jesse Glick
070: */
071: public final class ModuleLogicalView implements LogicalViewProvider {
072:
073: private final NbModuleProject project;
074:
075: public ModuleLogicalView(NbModuleProject project) {
076: this .project = project;
077: }
078:
079: public Node createLogicalView() {
080: return new RootNode(project);
081: }
082:
083: /** cf. #45952 */
084: public Node findPath(Node root, Object target) {
085: if (root.getLookup().lookup(NbModuleProject.class) != project) {
086: // Not intended for this project. Should not normally happen anyway.
087: return null;
088: }
089:
090: Node[] rootChildren = root.getChildren().getNodes(true);
091: DataObject file;
092:
093: if (target instanceof FileObject) {
094: try {
095: file = DataObject.find((FileObject) target);
096: } catch (DataObjectNotFoundException e) {
097: throw new AssertionError(e);
098: }
099: } else if (target instanceof DataObject) {
100: file = (DataObject) target;
101: } else {
102: // What is it?
103: return null;
104: }
105:
106: for (int i = 0; i < rootChildren.length; i++) {
107: Node found = PackageView.findPath(rootChildren[i], target);
108: //System.err.println("found " + found + " for " + target + " in " + rootChildren[i]);
109: if (found != null) {
110: return found;
111: }
112: // For Important Files node:
113: if (rootChildren[i].getName().equals(
114: ImportantFilesNodeFactory.IMPORTANT_FILES_NAME)) {
115: Node[] ifChildren = rootChildren[i].getChildren()
116: .getNodes(true);
117: for (int j = 0; j < ifChildren.length; j++) {
118: if (ifChildren[j].getCookie(DataObject.class) == file) {
119: return ifChildren[j];
120: }
121: }
122: }
123: }
124:
125: return null;
126: }
127:
128: private static final class RootNode extends AnnotatedNode {
129:
130: private final NbModuleProject project;
131:
132: public RootNode(NbModuleProject project) {
133:
134: // XXX add a NodePathResolver impl to lookup
135: super (
136: NodeFactorySupport
137: .createCompositeChildren(project,
138: "Projects/org-netbeans-modules-apisupport-project/Nodes"),
139: Lookups.fixed(new Object[] { project }));
140: this .project = project;
141: setForceAnnotation(true);
142: setIconBaseWithExtension(NbModuleProject.NB_PROJECT_ICON_PATH);
143: ProjectInformation pi = ProjectUtils
144: .getInformation(project);
145: setDisplayName(pi.getDisplayName());
146: setShortDescription(NbBundle.getMessage(
147: ModuleLogicalView.class, "HINT_project_root_node",
148: FileUtil.getFileDisplayName(project
149: .getProjectDirectory())));
150: setFiles(getProjectFiles());
151: pi.addPropertyChangeListener(new PropertyChangeListener() {
152: public void propertyChange(PropertyChangeEvent evt) {
153: if (evt.getPropertyName() == ProjectInformation.PROP_DISPLAY_NAME) {
154: RootNode.this .setDisplayName((String) evt
155: .getNewValue());
156: } else if (evt.getPropertyName() == ProjectInformation.PROP_NAME) {
157: RootNode.this .setName((String) evt
158: .getNewValue());
159: }
160: }
161: });
162: }
163:
164: private Set<FileObject> getProjectFiles() {
165: Set<FileObject> roots = new HashSet<FileObject>();
166: Sources sources = ProjectUtils.getSources(project);
167:
168: // TODO add Sources.addChangeListener(this)
169: SourceGroup[] groups = sources
170: .getSourceGroups(Sources.TYPE_GENERIC);
171: for (int i = 0; i < groups.length; i++) {
172: SourceGroup group = groups[i];
173: FileObject fo = group.getRootFolder();
174: if (fo != null) {
175: FileObject[] files = fo.getChildren();
176: for (int j = 0; j < files.length; j++) {
177: FileObject file = files[j];
178: if (group.contains(file)) {
179: roots.add(file);
180: }
181: }
182: }
183: }
184: return roots;
185: }
186:
187: public Action[] getActions(boolean ignore) {
188: return ModuleActions.getProjectActions(project);
189: }
190:
191: public Image getIcon(int type) {
192: return annotateIcon(super .getIcon(type), type);
193: }
194:
195: public Image getOpenedIcon(int type) {
196: return getIcon(type); // the same in the meantime
197: }
198:
199: public boolean canRename() {
200: return true;
201: }
202:
203: public String getName() {
204: return ProjectUtils.getInformation(project)
205: .getDisplayName();
206: }
207:
208: public void setName(String name) {
209: DefaultProjectOperations.performDefaultRenameOperation(
210: project, name);
211: }
212:
213: }
214: }
|