 |
Node[] to File[] Transformation Pattern
It's suggested pattern for most version control actions. ==FileStatusCache== is version system dependent. It can list files with given status.
/**
* Semantics is similar to {@link org.openide.windows.TopComponent#getActivatedNodes()} except that this
* method returns File objects instead od Nodes. Every node is examined for Files it represents. File and Folder
* nodes represent their underlying files or folders. Project nodes are represented by their source groups. Other
* logical nodes must provide FileObjects in their Lookup.
*
* @return File [] array of activated files
* @param nodes or null (then taken from windowsystem, it may be wrong on editor tabs #66700).
*/
public static Context getCurrentContext(Node[] nodes) {
if (nodes == null) {
nodes = TopComponent.getRegistry().getActivatedNodes();
}
if (Arrays.equals(contextNodesCached, nodes)) return contextCached;
List files = new ArrayList(nodes.length);
List rootFiles = new ArrayList(nodes.length);
List rootFileExclusions = new ArrayList(5);
for (int i = 0; i < nodes.length; i++) {
Node node = nodes[i];
Project project = (Project) node.getLookup().lookup(Project.class);
if (project != null) {
addProjectFiles(files, rootFiles, rootFileExclusions, project);
continue;
}
addFileObjects(node, files, rootFiles);
}
contextCached = new Context(files, rootFiles, rootFileExclusions);
contextNodesCached = nodes;
return contextCached;
}
/**
* Semantics is similar to {@link org.openide.windows.TopComponent#getActivatedNodes()} except that this
* method returns File objects instead od Nodes. Every node is examined for Files it represents. File and Folder
* nodes represent their underlying files or folders. Project nodes are represented by their source groups. Other
* logical nodes must provide FileObjects in their Lookup.
*
* @param nodes null (then taken from windowsystem, it may be wrong on editor tabs #66700).
* @param includingFileStatus if any activated file does not have this CVS status, an empty array is returned
* @param includingFolderStatus if any activated folder does not have this CVS status, an empty array is returned
* @return File [] array of activated files, or an empty array if any of examined files/folders does not have given status
*/
public static Context getCurrentContext(Node[] nodes, int includingFileStatus, int includingFolderStatus) {
Context context = getCurrentContext(nodes);
FileStatusCache cache = Subversion.getInstance().getStatusCache();
File [] files = context.getRootFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
FileInformation fi = cache.getStatus(file);
if (file.isDirectory()) {
if ((fi.getStatus() & includingFolderStatus) == 0) return Context.Empty;
} else {
if ((fi.getStatus() & includingFileStatus) == 0) return Context.Empty;
}
}
return context;
}
/**
* @return <code>true</code> if
* <ul>
* <li> the node contains a project in its lookup and
* <li> the project contains at least one CVS versioned source group
* </ul>
* otherwise <code>false</code>.
*/
public static boolean isVersionedProject(Node node) {
Lookup lookup = node.getLookup();
Project project = (Project) lookup.lookup(Project.class);
return isVersionedProject(project);
}
/**
* @return <code>true</code> if
* <ul>
* <li> the project != null and
* <li> the project contains at least one CVS versioned source group
* </ul>
* otherwise <code>false</code>.
*/
public static boolean isVersionedProject(Project project) {
if (project != null) {
FileStatusCache cache = Subversion.getInstance().getStatusCache();
Sources sources = ProjectUtils.getSources(project);
SourceGroup [] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC);
for (int j = 0; j < sourceGroups.length; j++) {
SourceGroup sourceGroup = sourceGroups[j];
File f = FileUtil.toFile(sourceGroup.getRootFolder());
if (f != null) {
// XXX if ((cache.getStatus(f).getStatus() & FileInformation.STATUS_MANAGED) != 0) return true;
File probe = new File (f, ".svn");
File probe2 = new File (f, "_svn");
if (probe.isDirectory() || probe2.isDirectory()) {
return true;
}
}
}
}
return false;
}
private static void addFileObjects(Node node, List files, List rootFiles) {
Collection folders = node.getLookup().lookup(new Lookup.Template(NonRecursiveFolder.class)).allInstances();
List nodeFiles = new ArrayList();
if (folders.size() > 0) {
for (Iterator j = folders.iterator(); j.hasNext();) {
NonRecursiveFolder nonRecursiveFolder = (NonRecursiveFolder) j.next();
nodeFiles.add(new FlatFolder(FileUtil.toFile(nonRecursiveFolder.getFolder()).getAbsolutePath()));
}
} else {
Collection fileObjects = node.getLookup().lookup(new Lookup.Template(FileObject.class)).allInstances();
if (fileObjects.size() > 0) {
nodeFiles.addAll(toFileCollection(fileObjects));
} else {
DataObject dataObject = (DataObject) node.getCookie(DataObject.class);
if (dataObject instanceof DataShadow) {
dataObject = ((DataShadow) dataObject).getOriginal();
}
if (dataObject != null) {
Collection doFiles = toFileCollection(dataObject.files());
nodeFiles.addAll(doFiles);
}
}
}
files.addAll(nodeFiles);
rootFiles.addAll(nodeFiles);
}
/**
* Determines all files and folders that belong to a given project and adds them to the supplied Collection.
*
* @param filteredFiles destination collection of Files
* @param project project to examine
*/
public static void addProjectFiles(Collection filteredFiles, Collection rootFiles, Collection rootFilesExclusions, Project project) {
FileStatusCache cache = Subversion.getInstance().getStatusCache();
Sources sources = ProjectUtils.getSources(project);
SourceGroup [] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC);
for (int j = 0; j < sourceGroups.length; j++) {
SourceGroup sourceGroup = sourceGroups[j];
FileObject srcRootFo = sourceGroup.getRootFolder();
File rootFile = FileUtil.toFile(srcRootFo);
if ((cache.getStatus(rootFile).getStatus() & FileInformation.STATUS_MANAGED) == 0) continue;
rootFiles.add(rootFile);
boolean containsSubprojects = false;
FileObject [] rootChildren = srcRootFo.getChildren();
Set projectFiles = new HashSet(rootChildren.length);
for (int i = 0; i < rootChildren.length; i++) {
FileObject rootChildFo = rootChildren[i];
if (Subversion.getInstance().isAdministrative(rootChildFo.getNameExt())) continue;
File child = FileUtil.toFile(rootChildFo);
if (sourceGroup.contains(rootChildFo)) {
// TODO: #60516 deep scan is required here but not performed due to performace reasons
projectFiles.add(child);
} else {
int status = cache.getStatus(child).getStatus();
if (status != FileInformation.STATUS_NOTVERSIONED_EXCLUDED) {
rootFilesExclusions.add(child);
containsSubprojects = true;
}
}
}
if (containsSubprojects) {
filteredFiles.addAll(projectFiles);
} else {
filteredFiles.add(rootFile);
}
}
}
/**
* May take a long time for many projects, consider making the call from worker threads.
*
* @param projects projects to examine
* @return Context context that defines list of supplied projects
*/
public static Context getProjectsContext(Project [] projects) {
List filtered = new ArrayList();
List roots = new ArrayList();
List exclusions = new ArrayList();
for (int i = 0; i < projects.length; i++) {
addProjectFiles(filtered, roots, exclusions, projects[i]);
}
return new Context(filtered, roots, exclusions);
}
private static Collection toFileCollection(Collection fileObjects) {
Set files = new HashSet(fileObjects.size()*4/3+1);
for (Iterator i = fileObjects.iterator(); i.hasNext();) {
files.add(FileUtil.toFile((FileObject) i.next()));
}
files.remove(null);
return files;
}
public static File [] toFileArray(Collection fileObjects) {
Set files = new HashSet(fileObjects.size()*4/3+1);
for (Iterator i = fileObjects.iterator(); i.hasNext();) {
files.add(FileUtil.toFile((FileObject) i.next()));
}
files.remove(null);
return (File[]) files.toArray(new File[files.size()]);
}
public static Window getCurrentWindow() {
Window wnd = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if (wnd instanceof Dialog || wnd instanceof Frame) {
return wnd;
} else {
return WindowManager.getDefault().getMainWindow();
}
}
-- Main.pkuzel - 03 Apr 2006
|