[HACKYSTAT-DEV-L:26] Re: CDT and hackyEclipse
> As you say, it was not possible to efficiently
extend the build problem
> detection functionality to CDT and keep it *DT
independent. However, I
> think that your above suggestion would not work,
because Resource Change
> listeners are language independent. The only
difference between these
> two listeners would be that detectBuildProblem
would have to behave
> differently according to the *DT. For this
reason, these listeners are
> identical. Eclipse documentation states that
adding a
> ResourceChangeListener has no effect if an
identical listener is already
> registered.
These are not identical. The "identical" in the
IWorkspace (Workspace)
means that the instance of the class extending
IResourceChangeListener
is pointing the same address (Same meaning of the
Object.equals(Object)).
Thus, the instantiating the difference class in a
different time and
adding them is not adding the same reference objects
to the workspace.
So it should work.
> case IResourceChangeEvent.POST_BUILD:
> /* Instead of using a visit method
to visit all the
> children that was affected from the change
> * it is more efficient to be
interested in the resource
> children who were changed.
> */
> try {
> IResourceDelta[] deltas =
>
event.getDelta().getAffectedChildren(IResourceDelta.CHANGED);
> IMarkerDelta[] markerdeltas =
null;
> for (int i = 0; i <=
deltas.length; i++) {
> if
((deltas[i].getResource()) instanceof IProject) {
> /* More specifically,
what we are interested
> in are the problem markers associated with the
project
> * The following
structure ensures that both
> JDT and CDT compatibility. Depending on the
project nature
> * the proper problem
marker is searched for.
> For not wasting too much time here, utility method
> * findMarkerDeltas of
IResourceDelta is used.
> */
> IProject project =
(IProject)
> deltas[i].getResource();
>
if(project.hasNature(JavaCore.NATURE_ID)){
> markerdeltas =
>
event.findMarkerDeltas(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
> else
if((CoreModel.hasCCNature(project)) ||
> (CoreModel.hasCNature(project))) {
> markerdeltas =
>
event.findMarkerDeltas(ICModelMarker.C_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
> }
> }
> } catch (CoreException e) {
> e.printStackTrace();
> }
Good try. First attempt we are try to do is to get
the result what we
want!. However, it seems that this still might not be
efficient way.
Do you have any reason why you use the following?
> IResourceDelta[] deltas =
>
event.getDelta().getAffectedChildren(IResourceDelta.CHANGED);
Is this to find the resource delta which is the
instance of "IProject"?
Usually, the affected resource delta children is a lot
of including
projects, folders, and files. so if a lot of resources
are changed by a
file change, your iteration is huge to just find the
instance which is
the instance of IProject. I recommend you to use,
visiter pattern to find
the IProject instance, which is usually found after
the workspaceroot
visit. so that, you might need only several iteration
to find a project.
> IProject project =
(IProject)
> deltas[i].getResource();
>
if(project.hasNature(JavaCore.NATURE_ID)){
> markerdeltas =
>
event.findMarkerDeltas(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
> else
if((CoreModel.hasCCNature(project)) ||
> (CoreModel.hasCNature(project))) {
> markerdeltas =
>
event.findMarkerDeltas(ICModelMarker.C_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
I am not sure to use if else here. Rather I prefer
creating own listener
for each language because it is more simple if another
languages come
out such as COBOL, FORTRAN, etc. If this is the case,
developer just
create own listener class and add it to workspace.
Cheers,
Takuya
On Tue, 07 Sep 2004 16:48:59 -0500
Turker Keskinpala
<[EMAIL PROTECTED]> wrote:
> Hi Takuya,
>
> Thanks for your comments. I was working on
changing the resource change
> structure and I think I came up with a working
solution. I will try to
> explain here as I go through your suggestion
below:
>
> >>>markers =
fileEditorInput.getFile().findMarkers(
> >>>
IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true,
> >>>IResource.DEPTH_INFINITE);
> >>>
> >>>should be changed with
> >>>
> >>>markers =
fileEditorInput.getFile().findMarkers(
> >>>
ICModelMarker.C_MODEL_PROBLEM_MARKER, true,
> >>>IResource.DEPTH_INFINITE);
> >>>
> >>>
> >
> >This change seems only supporting C/C++
problem marker so that you still can
> >not support both C/C++ and Java.
> >
> You are correct here since this is not what I
wanted to do. I was trying
> to make the point that it is easy to look for C
problem markers but I
> did not focus on the fact that I was looking for
these on the active
> file. Actually, my aim is to make the whole think
file editor specific.
>
> >I guess you and we have to change the
> >resource chage structure in such a way that
each langauge specific
> >resource change listener should be
imeplemented apart from the main
> >resourche change adapter which has been
already implemented in the
> >EclipseSensor. My propose is that:
> >
> >[Java]
> >
> >JavaResourceChangeAdapter implements
IResourceChangeListener, IResourceDeltaVisitor {
> > ...
> > public boolean visit(IResourceDelta
delta) throws CoreException {
> > ...
> > detectJavaBuildProblem();
> > ...
> > }
> >}
> >
> >[C/C++]
> >
> >CResourceChangeAdapter implements
IResourceChangeListener, IResourceDeltaVisitor {
> >
> > public boolean visit(IResourceDelta
delta) throws CoreException {
> > ...
> > detectCBuildProblem();
> > ...
> > }
> >}
> >
> >After creating own language adapter, you can
add them to
> >
> >workspace.addResourceChangeListener(new
CResourceChangeAdapter());
> >
> >This would enable sensor to extend any
language in the future which
> >would be supported in Eclipse.
> >
> >
> As you say, it was not possible to efficiently
extend the build problem
> detection functionality to CDT and keep it *DT
independent. However, I
> think that your above suggestion would not work,
because Resource Change
> listeners are language independent. The only
difference between these
> two listeners would be that detectBuildProblem
would have to behave
> differently according to the *DT. For this
reason, these listeners are
> identical. Eclipse documentation states that
adding a
> ResourceChangeListener has no effect if an
identical listener is already
> registered.
>
> Instead of separating the resource change
handling according to the *DT,
> I focused on separating the handling of specific
resource change event
> types. In this case, the event types that we are
interested in are
> POST_CHANGE (mainly to record open/close project,
save/open/close file
> actions) and POST_BUILD to be able to detect and
record build problems.
> The first change I made is to add the
ResourceChangeAdapter to listen to
> POST_BUILD events as well as POST_CHANGE events:
>
> workspace.addResourceChangeListener(
> new ResourceChangeAdapter(),
> IResourceChangeEvent.POST_CHANGE |
IResourceChangeEvent.POST_BUILD);
>
> Following that change, in the new resource change
structure, two actions
> will be selected depending on the event type.
POST_CHANGE events will be
> handled in the visit() method as have been.
However, this time, the
> visit() method will not check the problem markers
and will not make a
> call to detectBuildProblems().
>
> For the POST_BUILD events I decided not to use
the visit pattern, since
> I figured I can do what I want to do without
visiting all the files in
> the project. The Eclipse documentation recommends
using available
> utility methods and spending less time if this is
at all possible. So,
> when the POST_BUILD event occurs, I get only the
affectedChildren which
> will be a project of some nature, check the
project's nature, and use
> the IResourceEvent.findMarkerDeltas(String type,
boolean
> includesubTypes) with the proper marker type
depending on the project
> nature. Finally, I call the new
detectBuildProblem(IMarkerDelta) method
> to record the problems that were ADDED or
CHANGED. Below is the
> resourceChanged() method of the
ResourceChangeAdapter and the
> detectBuildProblem method:
>
> public void resourceChanged(IResourceChangeEvent
event) {
> IResource resource = event.getResource();
> // Need to select the proper action
depending on the resource
> change event type
> switch (event.getType()) {
> case IResourceChangeEvent.POST_BUILD:
> /* Instead of using a visit method
to visit all the
> children that was affected from the change
> * it is more efficient to be
interested in the resource
> children who were changed.
> */
> try {
> IResourceDelta[] deltas =
>
event.getDelta().getAffectedChildren(IResourceDelta.CHANGED);
> IMarkerDelta[] markerdeltas =
null;
> for (int i = 0; i <=
deltas.length; i++) {
> if
((deltas[i].getResource()) instanceof IProject) {
> /* More specifically,
what we are interested
> in are the problem markers associated with the
project
> * The following
structure ensures that both
> JDT and CDT compatibility. Depending on the
project nature
> * the proper problem
marker is searched for.
> For not wasting too much time here, utility method
> * findMarkerDeltas of
IResourceDelta is used.
> */
> IProject project =
(IProject)
> deltas[i].getResource();
>
if(project.hasNature(JavaCore.NATURE_ID)){
> markerdeltas =
>
event.findMarkerDeltas(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
> else
if((CoreModel.hasCCNature(project)) ||
> (CoreModel.hasCNature(project))) {
> markerdeltas =
>
event.findMarkerDeltas(ICModelMarker.C_MODEL_PROBLEM_MARKER,false);
>
detectBuildProblem(markerdeltas);
> }
> }
> }
> } catch (CoreException e) {
> e.printStackTrace();
> }
> case IResourceChangeEvent.POST_CHANGE:
> try {
> event.getDelta().accept(this);
> } catch (CoreException e1) {
> e1.printStackTrace();
> }
> }
>
--------------------------------------------------------------------------------------------------
> private void detectBuildProblem(IMarkerDelta[]
markerdeltas) {
> if (markerdeltas != null) {
> for (int i = 0; i <=
markerdeltas.length; i++) {
> if ((markerdeltas[i].getKind() ==
IResourceDelta.ADDED)
> || (markerdeltas[i].getKind() ==
IResourceDelta.CHANGED)) {
> String data = "">
>
markerdeltas[i].getResource().getLocation().toString() + "#" + (String)
> markerdeltas[i].getAttribute("message");
> String[] args = {"add",
"Build Error", data};
>
this.eclipseSensorShell.doCommand("Activity",
> Arrays.asList(args));
> }
>
> }
> }
> }
>
--------------------------------------------------------------------------------------------------
>
> I tested this structure with both JDT and CDT and
it worked as I
> expected. There is no preference to set, there is
no file to change. One
> may work on CDT or JDT (and switch back and
forth) and do not worry
> about what hackyEclipse is collecting. Another
advantage this structure
> brings, in my opinion, is that, we are not
dealing with active editor
> and approaching the build problem detection from
a higher level (from
> the project level). I will keep testing and
playing with it to see if
> there are any problems that I could not foresee.
>
> How does that implementation look?
>
> Cheers,
> Turker
================================
Takuya Yamashita
E-mail: [EMAIL PROTECTED]
================================