Community
Participate
Working Groups
If a parent package is included in a working set, child packages are automatically included even if they are explicitly un-selected. e.g. A working set is created. In it I have selected com.foo to be a member, but I did not select child package com.foo.bar. When I use the working set to filter against tasks. Tasks related to com.foo.bar appear even thought they are explicitly not selected in the working set. p.s. Searching the bug data base it appears there used to be a working set component, but I couldn't find it posting this bug. Hopefully it will get to the correct place. Thanks, John Groppe
The problem is that Java working sets and resource working sets are not interchangeable. They should be. Using a resource working set works in the Tasks view. Using a Java working set in the Navigator (or in the Tasks view) does not work. Bug 14441 was reopened to address this issue. Closing bug 14441 since this one is more specific. Here is the relevant discussion from bug 14441 ------- Additional Comments From Shash Chatterjee 2002-05-22 15:14 ------- Hi! I just tested this using the F1 build. It is better in the sense that I can filter based on a working set, and only errors/warnings from that working set are being shown in the task view. But if I edit the working set to uncheck one or more particular packages in the source hierarchy (those that have errors that I can neglect), the errors are still showing up in the Task view. Shash ------- Additional Comments From Knut Radloff 2002-05-24 18:41 ------- The problem is a combination of the fact that the org.eclipse.ui.views.tasklist.TasksFilter is resource based and the way working set elements are collected in the Resource- and JavaWorkingSetPage. Given a structure A a A.java a.b AB.java The TasksFilter assumes that if folder a is checked and included in a working set all of a's children should be displayed. This works with a resource working set because a is only checked if all its children are checked in the ResourceWorkingSetPage. Otherwise only the checked children are placed in the working set. I.e., if b below a is not checked a is grayed out and A.java is added instead of a. This does not work with Java working sets because package a may be included in the working set but a.b may not. a is checked and a.b is not but the working set contains a instead of a/A.java. There are two possible solutions: 1) Change TasksFilter.isEnclosed to test the path of a resource for equality with a working set element. This means that all leaf elements of folders have to be included in a working set. This would change the semantics of the ResourceWorkingSetPage since currently, checking a folder means the actual folder is placed in the working set vs. all its children. New children are automatically considered to be included in the working set. It would also degrade performance since working sets would contain a potentially huge number of leaf elements vs. a single folder or project. Filtering in the resource navigator would be slower. 2) Change JavaWorkingSetPage to mimic the ResourceWorkingSetPage. Leave the UI the way it is but explicitly include children of packages in the working set instead of the packages themselves if not all package fragments are checked (e.g, a is but a.b is not). This would mimic the graying out of a in the ResourceWorkingSetPage. There is another option which I don't think we can/should seriously consider. That would be to allow for a custom working set filter in the org.eclipse.ui.workingSet extension point. I hacked the JavaWorkingSetPage to simply test if a checked element is a package fragment. This is a lesss optimal but quick version of solution 2). It would cause leaf elements to be included even if all packages are selected. Moving to JDT UI for comment/fix. See the changed JavaWorkingSetPage.findCheckedElements: Object[] children= fTreeContentProvider.getChildren(parent); for (int i= 0; i < children.length; i++) { if (fTree.getGrayed(children[i])) findCheckedElements(checkedResources, children[i]); else if (fTree.getChecked(children[i])) { // don't add package fragments directly if ((children[i] instanceof PackageFragment)) findCheckedElements(checkedResources, children[i]); else checkedResources.add(children[i]); } } ------- Additional Comments From Knut Radloff 2002-05-24 18:42 ------- Shash, Please confirm that the scenario I describe above matches your scenario. I.e., you deselect package a.b, keep package a selected and still see errors for a.b. ------- Additional Comments From Shash Chatterjee 2002-05-24 19:54 ------- Yes, I confirm this is exactly what is happening. I have (with the project source directory being WEB-INF/src): WEB-INF/ src/ com/ jcorporate/ expresso/ X.java core/ Y.java security/ Z.java strongencryption/ A.java B.java weakencryption/ C.java D.java In this enviornment, because I didn't install the required JAR(s), strongencryption/*.java all have compilation errors. So, I unchecked the com.jcorporate.expresso.core.security.strongencryption. But those errors still show up in the task view, until I uncheck the following as well: com.jcorporate.expresso.core.security com.jcorporate.expresso.core com.jcorporate.expresso com.jcorporate WEB-INF/src ------- Additional Comments From Erich Gamma 2002-05-25 17:12 ------- This problem is real so that we should tolerate a minor hack that get's us there. Should investigate for F1. ------- Additional Comments From Erich Gamma 2002-05-26 14:15 ------- Thinking of it again. Option 2) isn't an option. The main reason why we wanted to have support for Java specific working set is that you can define working sets with the Java semantics. This is already leveraged for Java specific searching. We do not want to loose this functionality. The original idea for handling this problem was to leverage the IWorkbenchAdapter. Did you ever investigate more into this path? There were some issues but the path looked promising to me. This was Nick's latest proposal: - The working set has the shape as proposed in 2, and contains IJavaElements, e.g. { package fragment: java.lang } - This is mapped to the corresponding resource using getAdapter (IResource.class): IAdaptable item = workingSet.getItems()[0]; IResource resource = (IResource) item.getAdapter(IResource.class); // e.g. resource is folder /JCL/src/java/lang - We get the children using IWorkbenchAdapter on the working set item (not the resource): IWorkbenchAdapter a = (IWorbenchAdapter) item.getAdapter (IWorkbenchAdapter.class); Object[] children = a.getChildren(item); // the adapter doesn't wrap the item, so we need to pass it back // e.g. children now contains CU: Object.java, etc., but not package fragment: java.lang.reflect for (int i = ...) { IResource childResource = (IResource) children[i].getAdapter (IResource.class); // e.g. children[i] is the CU for Object.java, childResource is the corresponding IFile }
Marking P2 to reflect priority of bug 14441.
A note from the newsgroup and my reply, related to JRE_LIB and resource working sets in the package explorer: Did you use a Resource working set or a Java working set? When I use a Resource working set I see strange behavior wrt. the JRE_LIB. I can't select the JRE_LIB when creating the working set (it doesn't exist in the content provider) but I still see JRE_LIB when I select the working set in the package explorer. When I expand the JRE_LIB I only see the copyright.txt. This may be related to bug 25274. "Colin Sharples" <sharples@nz1.ibm.com> wrote in message news:3DB86399.5030602@nz1.ibm.com... > I had an odd problem yesterday where I couldn't expand the JRE_LIB jar > file when I had a working set selected. It worked fine if I deselected > the working set. I put in bug #25291, but I couldn't reproduce the > problem today, so I closed the bug. [...]
*** Bug 28026 has been marked as a duplicate of this bug. ***
I tried reimplementing the ResourceWorkingSetFilter (used in the ResorceNavigator) using the IWorkbenchAdapter approach. There's one problem when a java project is selected in the Java working set. When I expand the project to displays its files and folders the filter is called with the children, which are IFiles and IFolders. When I get the children for the Java project they include the package fragment root which then contains the children in the IResource project. At this point I stop because I don't find the filter elements as direct children of the working set item. This approach seems correct to me. Am I missing something?
To clarify: The problem is that the children of the JavaProject workbench adapter are not the files and folders but an indirect level above them.
The following is a bit of a rambling brain-dump. When a Java working set is selected in the Navigator, we want to show the resources corresponding to: - the Java elements in the working set, - all their children, - all their parents (to allow you to navigate to the elements in the working set), being careful to use the Java parent-child relationship, not the Resource one. So package a.b is not a child of package a. Likewise, package a is not a parent of package a.b. For the Tasks view, the problem is similar except we don't want to include parents. We want to show only the tasks on the resources corresponding to: - the Java elements in the working set, - all their children (again in terms of the Java parent-child relationship) One way to do this is to take the elements in the working set, recursively collect all the parents and children via IWorkbenchAdapter, map all these to resources, and put them in a set. Then, the Navigator's filter just has to check for membership in this set. For the Tasks view, it would have to check if the marker's resource is in the set. This approach has two problems: - it's pretty expensive in terms of space, and - it's hard to maintain incrementally when elements are added or removed from the workspace or Java model (changes to the working set itself are easier to deal with) The question is: can we do better? Is there a way to determine whether a resource is in that set without actually maintaining the complete picture of the set? My proposal above (2002-05-26 14:15) really only explains how to calculate the set, not how to check if an arbitrary resource is in the set without calculating it. This is complicated by the fact that there is not necessarily any direct parallel between the Java hierarchy and the Resource hierarchy. As you've discovered, a resource in the set ChildrenOf(ResourceOf(SomeJavaElement)) is not necessarily in the set ResourcesOf(ChildrenOf(SomeJavaElement)), but it may still be in the overall set of resources corresponding to elements in the working set. So we can't assume that you can descend both structures simultaneously. And simply looking up the parent chain of a resource to find one that is in ResourcesOf(ElementsIn(WorkingSet)), since that would include children of package a.b if a is included, even if a.b is not. For the Java working set case, what we really need to do is map the resource in question to the corresponding Java element, then see if it is in the working set, or if it is a descendent or ancestor of any of the elements in the working set. Unfortunately, the Navigator filter can't do this because it doesn't know anything about JDT. Maybe the only way we can do this is to give more smarts to the working set after all. E.g. /** * Returns whether the given element is an element in the working set. * * @param includeDescendents whether to consider descendents of the working set elements as being in the working set * @param includeAncestors whether to consider ancestors of the working set elements as being in the working set */ boolean contains(Object element, boolean includeDescendents, boolean includeAncestors); This would be sufficient for the Navigator, but would be inefficient for the Tasks view. It would have to gather all markers and check their resources individually. The Tasks view could optimize somewhat by initially asking for only those markers under resources corresponding to the working set elements, but it would still have to check each one. E.g. ask for markers under the folder corresponding to package a, but still check the resource for each one to exclude those under the folder corresponding to package a.b. Maybe it's not so bad after all.
The way I implemented the ResourceWorkingSetFilter now is similar to what the contains method would do. I iterate over the working set elements and do a cheap check whether the currently filtered element is one of the working set elements or the parent of one (prefixOf check works here). The expensive part is checking if the filtered element is a child of a working set element. I was hoping to only have to descend one level using the workbench adapter. Since the resource tree does not map 1:1 to the Java element tree I have to do what you suggest and descend down all the way, potentially to the leaves. This is not so bad for the Java case if the working set contains mostly packages and files. When it contains projects there can be a large number of source folders and packages to traverse. Doing this in a WorkingSet.contains method would make the algorithm available to others. You are not suggesting that IWorkingSet be implementable by others to provide their own specific "contains" implementation, are you?
Actually I was. It seems like for the Java working set case, only JDT can efficiently determine whether a resource should be included or not.
Recursing into the IWorkbenchAdapter children for every viewer element is horribly slow when starting at the project level. This also does not include non-Java resources even though they are shown and selected in the Java working set edit page. A "contains" method on IWorkbenchAdapter would be sufficient. It would return true if the given element is a (direct or indirect) child of the receiver. We could add an IWorkingSetAdapter to support this. In this scenario I would iterate over the working set elements and ask each for its working set adapter. This seems simpler than opening up WorkingSet itself for extension/implementation.
Please provide more details on how the new APIs would look, and how it would address the following scenarios: - Navigator: showing only the resources corresponding to elements included in the working set and their children, and the parent resources need to navigate to these - Tasks: showing only the tasks for resources corresponding to elements included in the working set and their children
Note that we cannot add new methods to IWorkbenchAdapter since that would break existing implementations.
We would add an interface IWorkingSetAdapter with a method "contains". For greatest flexibility the contains method should be spec'd like you do in your comment #7. For every element I get in the resource filter I iterate over the working set elements and use the IWorkingSetAdapter to determine if the element should be filtered out or not. The ancestors check for resource and Java working sets is trivial and the descendents check should also be quick for a Java specific IWorkingSetAdapter. The Task list filter currently operates (inefficiently) as you describe. It gets all markers for the applicable resources (e.g., workspace root) and then runs them through the filter. This could indeed be improved by asking for the markers of working set resources and their children With the IWorkingSetAdapter the task filter would use the descendents parameter only.
Would the IWorkingSetAdapter be obtained from the working set or the elements in the working set? If it's the latter, how does it know which criteria to use? E.g., if it's on a java element, does this imply that a Java working set is in use?
Silly question. It has to be on the working set, otherwise it doesn't know the working set elements.
Sorry, my description missed some important detail. The assumption is that the IWorkingSetAdapter is on the working set element, not the working set itself. I would say (syntactically incorrect): IWorkingSetAdapter adapter = workingSet.getElements()[0].getAdapter (IWorkingSetAdapter.class) adapter.contains(navigatorElement, true, true) I know which working set I want to filter on and the working set elements know the most efficient way to filter.
This is fine as long as the containment relationship is defined by the model elements themselves, and is unaffected by any other state in the working set. This makes sense to me -- the containment relationship really is defined by the model, and the working set is just a simple list of elements. I think we should try it.
Added IContainmentAdapter with contains method. Changed the name from IWorkingSetAdapter since it may be used independent of working sets. The method signature is boolean contains(Object containmentContext, Object element, boolean includeDescendents, boolean includeAncestors); See the JavaDoc for details. Changed ResourceWorkingSetFilter and TasksFilter to use IContainmentAdapter. Both fall back to use the old resource based compare if there is no IContainmentAdapter. JDT needs to implement an IContainmentAdapter for java elements. I tested this and it works correctly and fast in both the resource navigator and tasks view.
Created attachment 3028 [details] JavaElementAdapterFactory with support for IContainmentAdapter
Created attachment 3029 [details] JavaWorkbenchAdapter implementing IContainmentAdapter I don't recommend using the attached implementation as a reference. I hacked it up to see if the adapter approach works to solve this bug. It seems to work fine for the navigator and tasks view. However, assume I don't know what I'm doing and that it is bogus.
It would be nice to get this into 2.1 Otherwise there is no benefit of using IContainmentAdapter in Platform UI. Please check with Nick or myself first as there are minor changes planned for IContainmentAdapter.
Implemented a Java specific containment adapter. Fixed for RC1 build
Bug 8043 seems related to this.