KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > spi > VCSContext


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 package org.netbeans.modules.versioning.spi;
20
21 import org.netbeans.modules.versioning.util.Utils;
22 import org.netbeans.modules.versioning.util.FlatFolder;
23 import org.netbeans.api.project.Project;
24 import org.netbeans.api.project.Sources;
25 import org.netbeans.api.project.ProjectUtils;
26 import org.netbeans.api.project.SourceGroup;
27 import org.netbeans.api.fileinfo.NonRecursiveFolder;
28 import org.netbeans.api.queries.SharabilityQuery;
29 import org.openide.nodes.Node;
30 import org.openide.filesystems.FileObject;
31 import org.openide.filesystems.FileUtil;
32 import org.openide.util.Lookup;
33 import org.openide.loaders.DataObject;
34 import org.openide.loaders.DataShadow;
35
36 import java.io.File JavaDoc;
37 import java.util.*;
38 import java.lang.ref.WeakReference JavaDoc;
39 import java.lang.ref.Reference JavaDoc;
40
41 /**
42  * This encapsulates a context, typically set of selected files or nodes. Context is passed to VCSAnnotators when
43  * asked for actions available on a given context or to annotate a name (label) representing a context.
44  *
45  * @author Maros Sandor
46  */

47 public final class VCSContext {
48     
49     public static final VCSContext Empty = new VCSContext(null, emptySet(), emptySet() );
50
51     /**
52      * Caching of current context for performance reasons, also see #72006.
53      */

54     private static VCSContext contextCached;
55     private static Reference JavaDoc<Node[]> contextNodesCached = new WeakReference JavaDoc<Node []>(null);
56
57     private final Node [] nodes;
58     
59     private final Set<File JavaDoc> rootFiles;
60     private final Set<File JavaDoc> exclusions;
61
62     /**
63      * Constructs a VCSContext out of a Lookup, basically taking all Nodes inside.
64      * Nodes are converted to Files based on their nature.
65      * For example Project Nodes are queried for their SourceRoots and those roots become the root files of this context.
66      *
67      * @param lookup a lookup
68      * @return VCSContext containing nodes from Lookup
69      */

70     public static VCSContext forLookup(Lookup lookup) {
71         Lookup.Result<Node> result = lookup.lookup(new Lookup.Template<Node>(Node.class));
72         Collection<? extends Node> nodes = result.allInstances();
73         return VCSContext.forNodes(nodes.toArray(new Node[nodes.size()]));
74     }
75     
76     /**
77      * Constructs a VCSContext out of a set of files. These files are later available via getRootFiles().
78      *
79      * @param rootFiles set of Files
80      * @return VCSContext a context representing supplied set of Files
81      */

82     public static VCSContext forFiles(Set<File JavaDoc> rootFiles) {
83         return new VCSContext(null, Collections.unmodifiableSet(new HashSet<File JavaDoc>(rootFiles)), emptySet());
84     }
85
86     /**
87      * Initializes the context from array of nodes (typically currently activated nodes).
88      * Nodes are converted to Files based on their nature.
89      * For example Project Nodes are queried for their SourceRoots and those roots become the root files of this context.
90      *
91      * @param nodes array of Nodes
92      * @return VCSContext containing nodes and corresponding files they represent
93      */

94     public synchronized static VCSContext forNodes(Node[] nodes) {
95         if (Arrays.equals(contextNodesCached.get(), nodes)) return contextCached;
96         Set<File JavaDoc> files = new HashSet<File JavaDoc>(nodes.length);
97         Set<File JavaDoc> rootFiles = new HashSet<File JavaDoc>(nodes.length);
98         Set<File JavaDoc> rootFileExclusions = new HashSet<File JavaDoc>(5);
99         for (int i = 0; i < nodes.length; i++) {
100             Node node = nodes[i];
101             File JavaDoc aFile = node.getLookup().lookup(File JavaDoc.class);
102             if (aFile != null) {
103                 files.add(aFile);
104                 rootFiles.add(aFile);
105                 continue;
106             }
107             Project project = node.getLookup().lookup(Project.class);
108             if (project != null) {
109                 addProjectFiles(rootFiles, rootFileExclusions, project);
110                 continue;
111             }
112             addFileObjects(node, files, rootFiles);
113         }
114         
115         contextCached = new VCSContext(nodes, rootFiles, rootFileExclusions);
116         contextNodesCached = new WeakReference JavaDoc<Node []>(nodes);
117         return contextCached;
118     }
119     
120     /**
121      * Retrieves Nodes that were originally used to construct this context object.
122      *
123      * @return Node[] array of Nodes this context represents or null if this context was not originally created from Nodes
124      */

125     public Node[] getNodes() {
126         return nodes;
127     }
128
129     /**
130      * Retrieves set of files/folders that represent this context.
131      *
132      * @return Set<File> set of Files this context represents
133      */

134     public Set<File JavaDoc> getRootFiles() {
135         return rootFiles;
136     }
137
138     /**
139      * Retrieves set of files/folders that are excluded from this context.
140      *
141      * @return Set<File> set of Files that are not part of (are excluded from) this context
142      */

143     public Set<File JavaDoc> getExclusions() {
144         return exclusions;
145     }
146
147     /**
148      * Determines whether the supplied File is contained in this context. In other words, the file must be either a root file
149      * or be a child under some root file and also must NOT be a child of some excluded file.
150      *
151      * @param file a File to test
152      * @return true if this context contains the supplied file, false otherwise
153      */

154     public boolean contains(File JavaDoc file) {
155         outter : for (File JavaDoc root : rootFiles) {
156             if (Utils.isParentOrEqual(root, file)) {
157                 for (File JavaDoc excluded : exclusions) {
158                     if (Utils.isParentOrEqual(excluded, file)) {
159                         continue outter;
160                     }
161                 }
162                 return true;
163             }
164         }
165         return false;
166     }
167         
168     private static void addProjectFiles(Collection<File JavaDoc> rootFiles, Collection<File JavaDoc> rootFilesExclusions, Project project) {
169         Sources sources = ProjectUtils.getSources(project);
170         SourceGroup[] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC);
171         for (int j = 0; j < sourceGroups.length; j++) {
172             SourceGroup sourceGroup = sourceGroups[j];
173             FileObject srcRootFo = sourceGroup.getRootFolder();
174             File JavaDoc rootFile = FileUtil.toFile(srcRootFo);
175             rootFiles.add(rootFile);
176             FileObject [] rootChildren = srcRootFo.getChildren();
177             for (int i = 0; i < rootChildren.length; i++) {
178                 FileObject rootChildFo = rootChildren[i];
179                 File JavaDoc child = FileUtil.toFile(rootChildFo);
180                 // TODO: #60516 deep scan is required here but not performed due to performace reasons
181
if (!sourceGroup.contains(rootChildFo) && SharabilityQuery.getSharability(child) != SharabilityQuery.NOT_SHARABLE) {
182                     rootFilesExclusions.add(child);
183                 }
184             }
185         }
186     }
187     
188     private static void addFileObjects(Node node, Set<File JavaDoc> files, Set<File JavaDoc> rootFiles) {
189         Collection<? extends NonRecursiveFolder> folders = node.getLookup().lookup(new Lookup.Template<NonRecursiveFolder>(NonRecursiveFolder.class)).allInstances();
190         List<File JavaDoc> nodeFiles = new ArrayList<File JavaDoc>();
191         if (folders.size() > 0) {
192             for (Iterator j = folders.iterator(); j.hasNext();) {
193                 NonRecursiveFolder nonRecursiveFolder = (NonRecursiveFolder) j.next();
194                 nodeFiles.add(new FlatFolder(FileUtil.toFile(nonRecursiveFolder.getFolder()).getAbsolutePath()));
195             }
196         } else {
197             Collection<? extends FileObject> fileObjects = node.getLookup().lookup(new Lookup.Template<FileObject>(FileObject.class)).allInstances();
198             if (fileObjects.size() > 0) {
199                 nodeFiles.addAll(toFileCollection(fileObjects));
200             } else {
201                 DataObject dataObject = node.getCookie(DataObject.class);
202                 if (dataObject instanceof DataShadow) {
203                     dataObject = ((DataShadow) dataObject).getOriginal();
204                 }
205                 if (dataObject != null) {
206                     Collection<File JavaDoc> doFiles = toFileCollection(dataObject.files());
207                     nodeFiles.addAll(doFiles);
208                 }
209             }
210         }
211         files.addAll(nodeFiles);
212         rootFiles.addAll(nodeFiles);
213     }
214     
215     private static Collection<File JavaDoc> toFileCollection(Collection<? extends FileObject> fileObjects) {
216         Set<File JavaDoc> files = new HashSet<File JavaDoc>(fileObjects.size()*4/3+1);
217         for (FileObject fo : fileObjects) {
218             files.add(FileUtil.toFile(fo));
219         }
220         files.remove(null);
221         return files;
222     }
223
224     private VCSContext(Node [] nodes, Set<File JavaDoc> rootFiles, Set<File JavaDoc> exclusions) {
225         this.nodes = nodes; // TODO: construct artificial nodes in case nodes == null ?
226
this.rootFiles = Collections.unmodifiableSet(new HashSet<File JavaDoc>(rootFiles));
227         this.exclusions = Collections.unmodifiableSet(new HashSet<File JavaDoc>(exclusions));
228     }
229
230     private static final Set<File JavaDoc> emptySet() {
231         return Collections.emptySet();
232     }
233 }
234
Popular Tags