Merge xdebug 1.3.x
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.core / src / net / sourceforge / phpeclipse / xdebug / php / model / XDebugBreakpoint.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.xdebug.php.model;
12
13  
14 import java.util.ArrayList;
15 //import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 //import java.util.Iterator;
19 import java.util.List;
20 //import java.util.Map;
21 import java.util.Set;
22
23 import org.eclipse.core.resources.IMarker;
24 import org.eclipse.core.runtime.CoreException;
25 //import org.eclipse.core.runtime.MultiStatus;
26 //import org.eclipse.core.runtime.Preferences;
27 //import org.eclipse.debug.core.DebugEvent;
28 import org.eclipse.debug.core.DebugPlugin;
29 //import org.eclipse.debug.core.IDebugEventSetListener;
30 import org.eclipse.debug.core.model.Breakpoint;
31 //import org.eclipse.debug.core.model.IDebugTarget;
32 import net.sourceforge.phpeclipse.xdebug.php.model.IXDebugBreakpoint;
33
34 //import org.eclipse.jdt.debug.core.IJavaDebugTarget;
35 import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget;
36
37 //import org.eclipse.jdt.debug.core.IJavaThread;
38 //import net.sourceforge.phpeclipse.xdebug.php.model.XDebugThread;
39
40 //import org.eclipse.jdt.debug.core.IJavaObject;
41 //import org.eclipse.jdt.debug.core.IJavaType;
42 //import org.eclipse.jdt.debug.core.JDIDebugModel;
43 //import org.eclipse.jdt.internal.debug.core.IJDIEventListener;
44 //import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
45 //import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
46 /*import org.eclipse.jdt.internal.debug.core.model.JDIObjectValue;
47 import org.eclipse.jdt.internal.debug.core.model.JDIThread;
48 import org.eclipse.jdt.internal.debug.core.model.JDIType;*/
49
50 //import com.ibm.icu.text.MessageFormat;
51 //import com.sun.jdi.ObjectReference;
52 //import com.sun.jdi.ReferenceType;
53 /*import com.sun.jdi.ThreadReference;
54 import com.sun.jdi.VMDisconnectedException;
55 import com.sun.jdi.event.ClassPrepareEvent;
56 import com.sun.jdi.event.Event;
57 import com.sun.jdi.event.LocatableEvent;
58 import com.sun.jdi.request.ClassPrepareRequest;
59 import com.sun.jdi.request.EventRequest;
60 import com.sun.jdi.request.EventRequestManager;
61 */
62 public abstract class XDebugBreakpoint extends Breakpoint implements IXDebugBreakpoint/*,*/ /*IJDIEventListener,*/ /*IDebugEventSetListener*/ {
63
64         /**
65          * Breakpoint attribute storing the expired value (value <code>"org.eclipse.jdt.debug.core.expired"</code>).
66          * This attribute is stored as a <code>boolean</code>. Once a hit count has
67          * been reached, a breakpoint is considered to be "expired".
68          */
69         protected static final String EXPIRED = "org.eclipse.jdt.debug.core.expired"; //$NON-NLS-1$
70         /**
71          * Breakpoint attribute storing a breakpoint's hit count value
72          * (value <code>"org.eclipse.jdt.debug.core.hitCount"</code>). This attribute is stored as an
73          * <code>int</code>.
74          */
75         protected static final String HIT_COUNT = "net.sourceforge.phpeclipse.xdebug.php.model.hitCount"; //$NON-NLS-1$
76         /**
77          * Breakpoint attribute storing the number of debug targets a
78          * breakpoint is installed in (value <code>"org.eclipse.jdt.debug.core.installCount"</code>).
79          * This attribute is a <code>int</code>.
80          */
81         protected static final String INSTALL_COUNT = "org.eclipse.jdt.debug.core.installCount"; //$NON-NLS-1$  
82         
83         /**
84          * Breakpoint attribute storing the fully qualified name of the type
85          * this breakpoint is located in.
86          * (value <code>"org.eclipse.jdt.debug.core.typeName"</code>). This attribute is a <code>String</code>.
87          */
88         protected static final String TYPE_NAME = "org.eclipse.jdt.debug.core.typeName"; //$NON-NLS-1$          
89         
90         /**
91          * Stores the collection of requests that this breakpoint has installed in
92          * debug targets.
93          * key: a debug target
94          * value: the requests this breakpoint has installed in that target
95          */
96         protected HashMap fRequestsByTarget;
97         
98         /**
99          * The list of threads (ThreadReference objects) in which this breakpoint will suspend,
100          * associated with the target in which each thread exists (JDIDebugTarget).
101          * key: targets the debug targets (IJavaDebugTarget)
102          * value: thread the filtered thread (IJavaThread) in the given target
103          */
104         //protected Map fFilteredThreadsByTarget;
105         
106         /**
107          * Stores the type name that this breakpoint was last installed
108          * in. When a breakpoint is created, the TYPE_NAME attribute assigned to it
109          * is that of its top level enclosing type. When installed, the type
110          * may actually be an inner type. We need to keep track of the type 
111          * type the breakpoint was installed in, in case we need to re-install
112          * the breakpoint for HCR (i.e. in case an inner type is HCR'd).
113          */
114         protected String fInstalledTypeName = null;
115         
116         /**
117          * List of targets in which this breakpoint is installed.
118          * Used to prevent firing of more than one install notification
119          * when a breakpoint's requests are re-created.
120          */
121         protected Set fInstalledTargets = null;
122         
123         /**
124          * List of active instance filters for this breakpoint
125          * (list of <code>IJavaObject</code>).
126          */
127         protected List fInstanceFilters = null;
128         
129         /**
130          * Empty instance filters array.
131          */
132         protected static final /*IJava*/Object[] fgEmptyInstanceFilters = new /*IJava*/Object[0];
133         
134         /**
135          * Property identifier for a breakpoint object on an event request
136          */
137         public static final String JAVA_BREAKPOINT_PROPERTY = "org.eclipse.jdt.debug.breakpoint"; //$NON-NLS-1$
138         
139         /**
140          * JavaBreakpoint attributes
141          */     
142         protected static final String[] fgExpiredEnabledAttributes= new String[]{EXPIRED, ENABLED};
143         
144         public XDebugBreakpoint() {
145                 fRequestsByTarget = new HashMap(1);
146                 //fFilteredThreadsByTarget= new HashMap(1);
147         }       
148
149         /* (non-Javadoc)
150          * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
151          */
152         public String getModelIdentifier() {
153                 return "asd"; //JDIDebugModel.getPluginIdentifier();
154         }
155
156         /* (non-Javadoc)
157          * @see org.eclipse.debug.core.model.Breakpoint#setMarker(org.eclipse.core.resources.IMarker)
158          */
159         public void setMarker(IMarker marker) throws CoreException {
160                 super.setMarker(marker);
161                 configureAtStartup();
162         }
163
164         /**
165          * Add this breakpoint to the breakpoint manager,
166          * or sets it as unregistered.
167          */
168         protected void register(boolean register) throws CoreException {
169         DebugPlugin plugin = DebugPlugin.getDefault();
170                 if (plugin != null && register) {
171             plugin.getBreakpointManager().addBreakpoint(this);
172                 } else {
173                         setRegistered(false);
174                 }
175         }       
176         
177         /**
178          * Add the given event request to the given debug target. If 
179          * the request is the breakpoint request associated with this 
180          * breakpoint, increment the install count.
181          */
182         /*protected void registerRequest(EventRequest request, XDebugTarget target) throws CoreException {
183                 if (request == null) {
184                         return;
185                 }
186                 List reqs = getRequests(target);
187                 if (reqs.isEmpty()) {
188                         fRequestsByTarget.put(target, reqs);
189                 }
190                 reqs.add(request);
191                 target.addJDIEventListener(this, request);
192                 // update the install attribute on the breakpoint
193                 if (!(request instanceof ClassPrepareRequest)) {
194                         incrementInstallCount();
195                         // notification 
196                         fireInstalled(target);
197                 }
198         }*/
199         
200         /**
201          * Returns a String corresponding to the reference type
202          * name to the top enclosing type in which this breakpoint
203          * is located or <code>null</code> if no reference type could be
204          * found.
205          */
206         /*protected String getEnclosingReferenceTypeName() throws CoreException {
207                 String name= getTypeName();
208                 int index = name.indexOf('$');
209                 if (index == -1) {
210                         return name;
211                 }
212                 return name.substring(0, index);
213         }*/     
214                 
215         /**
216          * Returns the requests that this breakpoint has installed
217          * in the given target.
218          */
219         protected ArrayList getRequests(XDebugTarget target) {
220                 ArrayList list= (ArrayList)fRequestsByTarget.get(target);
221                 if (list == null) {
222                         list= new ArrayList(2);
223                 }
224                 return list;
225         }
226         
227         /**
228          * Remove the given request from the given target. If the request
229          * is the breakpoint request associated with this breakpoint,
230          * decrement the install count.
231          */
232         /*protected void deregisterRequest(EventRequest request, XDebugTarget target) throws CoreException {
233                 target.removeJDIEventListener(this, request);
234                 // A request may be getting de-registered because the breakpoint has
235                 // been deleted. It may be that this occurred because of a marker deletion.
236                 // Don't try updating the marker (decrementing the install count) if
237                 // it no longer exists.
238                 if (!(request instanceof ClassPrepareRequest) && getMarker().exists()) {
239                         decrementInstallCount();
240                 }
241         }*/
242
243         /* (non-Javadoc)
244          * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#handleEvent(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
245          */
246         /*public boolean handleEvent(Event event, XDebugTarget target) {
247                 if (event instanceof ClassPrepareEvent) {
248                         return handleClassPrepareEvent((ClassPrepareEvent)event, target);
249                 }
250                 ThreadReference threadRef= ((LocatableEvent)event).thread();
251                 XDebugThread thread= target.findThread(threadRef);      
252                 if (thread == null || thread.isIgnoringBreakpoints()) {
253                         return true;
254                 }
255                 return handleBreakpointEvent(event, target, thread);            
256         }*/
257         
258         /* (non-Javadoc)
259          * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#wonSuspendVote(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
260          */
261         /*public void wonSuspendVote(Event event, XDebugTarget target) {
262                 ThreadReference threadRef = null;
263                 if (event instanceof ClassPrepareEvent) {
264                         threadRef = ((ClassPrepareEvent)event).thread();
265                 } else if (event instanceof LocatableEvent) {
266                         threadRef = ((LocatableEvent)event).thread();
267                 }
268                 if (threadRef == null) {
269                         return;
270                 }
271                 XDebugThread thread= target.findThread(threadRef);      
272                 if (thread == null || thread.isIgnoringBreakpoints()) {
273                         return;
274                 }
275                 thread.wonSuspendVote(this);
276         }*/
277
278         /**
279          * Handle the given class prepare event, which was generated by the
280          * class prepare event installed in the given target by this breakpoint.
281          * 
282          * If the class which has been loaded is a class in which this breakpoint
283          * should install, create a breakpoint request for that class.
284          */     
285         /*public boolean handleClassPrepareEvent(ClassPrepareEvent event, XDebugTarget target) {
286                 try {
287                         if (!installableReferenceType(event.referenceType(), target)) {
288                                 // Don't install this breakpoint in an
289                                 // inappropriate type
290                                 return true;
291                         }                       
292                         createRequest(target, event.referenceType());
293                 } catch (CoreException e) {
294                         XDebugCorePlugin.log(e);
295                 }
296                 return true;
297         }*/
298         
299         /**
300          * @see IJDIEventListener#handleEvent(Event, JDIDebugTarget)
301          * 
302          * Handle the given event, which was generated by the breakpoint request
303          * installed in the given target by this breakpoint.
304          */
305         /*public boolean handleBreakpointEvent(Event event, XDebugTarget target, XDebugThread thread) {
306                 expireHitCount(event);
307                 return !suspend(thread); // Resume if suspend fails
308         }*/
309         
310         /**
311          * Delegates to the given thread to suspend, and
312          * returns whether the thread suspended
313          * It is possible that the thread will not suspend
314          * as directed by a Java breakpoint listener.
315          * 
316          * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint)
317          */
318         /*protected boolean suspend(XDebugThread thread) {
319                 return thread.handleSuspendForBreakpoint(this, true);
320         }*/
321         
322         /**
323          * Returns whether the given reference type is appropriate for this
324          * breakpoint to be installed in the given target. Query registered
325          * breakpoint listeners.
326          */
327         /*protected boolean installableReferenceType(ReferenceType type, XDebugTarget target) throws CoreException {
328                 String installableType= getTypeName();
329                 String queriedType= type.name();
330                 if (installableType == null || queriedType == null) {
331                         return false;
332                 }
333                 int index= queriedType.indexOf('<');
334                 if (index != -1) {
335                         queriedType= queriedType.substring(0, index);
336                 }
337                 if (installableType.equals(queriedType)) {
338                         return queryInstallListeners(target, type);
339                 }
340                 index= queriedType.indexOf('$', 0);
341                 if (index == -1) {
342                         return false;
343                 }
344                 if (installableType.regionMatches(0, queriedType, 0, index)) {
345                         return queryInstallListeners(target, type);
346                 }
347                 return false;
348         }*/
349         
350         /**
351          * Called when a breakpoint event is encountered. Expires the
352          * hit count in the event's request and updates the marker.
353          * @param event the event whose request should have its hit count
354          * expired or <code>null</code> to only update the breakpoint marker.
355          */
356         /*protected void expireHitCount(Event event) {
357                 Integer requestCount= null;
358                 EventRequest request= null;
359                 if (event != null) {
360                         request= event.request();
361                         requestCount= (Integer) request.getProperty(HIT_COUNT);
362                 }
363                 if (requestCount != null) {
364                         if (request != null) {
365                                 request.putProperty(EXPIRED, Boolean.TRUE);
366                         }
367                         try {
368                                 setAttributes(fgExpiredEnabledAttributes, new Object[]{Boolean.TRUE, Boolean.FALSE});
369                                 // make a note that we auto-disabled this breakpoint.
370                         } catch (CoreException ce) {
371                                 XDebugCorePlugin.log(ce);
372                         }
373                 }
374         }*/
375         
376         /**
377          * Returns whether this breakpoint should be "skipped". Breakpoints
378          * are skipped if the breakpoint manager is disabled and the breakpoint
379          * is registered with the manager
380          * 
381          * @return whether this breakpoint should be skipped
382          */
383         public boolean shouldSkipBreakpoint() throws CoreException {
384                 DebugPlugin plugin = DebugPlugin.getDefault();
385         return plugin != null && isRegistered() && !plugin.getBreakpointManager().isEnabled();
386         }
387
388         /**
389          * Attempts to create a breakpoint request for this breakpoint in the given
390          * reference type in the given target.
391          * 
392          * @return Whether a request was created
393          */
394         /*protected boolean createRequest(XDebugTarget target, ReferenceType type) throws CoreException {
395                 if (shouldSkipBreakpoint()) {
396                         return false;
397                 }
398                 EventRequest[] requests= newRequests(target, type);
399                 if (requests == null) {
400                         return false;
401                 }
402                 fInstalledTypeName = type.name();
403                 for (int i = 0; i < requests.length; i++) {
404             EventRequest request = requests[i];
405             registerRequest(request, target);    
406         }
407                 return true;
408         }*/
409         
410         /**
411          * Configure a breakpoint request with common properties:
412          * <ul>
413          * <li><code>JAVA_BREAKPOINT_PROPERTY</code></li>
414          * <li><code>HIT_COUNT</code></li>
415          * <li><code>EXPIRED</code></li>
416          * </ul>
417          * and sets the suspend policy of the request to suspend 
418          * the event thread.
419          */
420         /*protected void configureRequest(EventRequest request, XDebugTarget target) throws CoreException {
421                 request.setSuspendPolicy(getJDISuspendPolicy());
422                 request.putProperty(JAVA_BREAKPOINT_PROPERTY, this);
423                 configureRequestThreadFilter(request, target);
424                 configureRequestHitCount(request);
425                 configureInstanceFilters(request, target);
426                 // Important: only enable a request after it has been configured
427                 updateEnabledState(request, target);
428         }*/
429         
430         /**
431          * Adds an instance filter to the given request. Since the implementation is
432          * request specific, subclasses must override.
433          * 
434          * @param request
435          * @param object instance filter
436          */
437         //protected abstract void addInstanceFilter(EventRequest request, ObjectReference object);
438         
439         /**
440          * Configure the thread filter property of the given request.
441          */
442         /*protected void configureRequestThreadFilter(EventRequest request, XDebugTarget target) {
443                 IJavaThread thread= (IJavaThread)fFilteredThreadsByTarget.get(target);
444                 if (thread == null || (!(thread instanceof JDIThread))) {
445                         return;
446                 }
447                 setRequestThreadFilter(request, ((JDIThread)thread).getUnderlyingThread());
448         }*/
449         
450         /**
451          * Configure the given request's hit count
452          */
453         /*protected void configureRequestHitCount(EventRequest request) throws CoreException {
454                 int hitCount= getHitCount();
455                 if (hitCount > 0) {
456                         request.addCountFilter(hitCount);
457                         request.putProperty(HIT_COUNT, new Integer(hitCount));
458                 }
459         }*/
460         
461         /*protected void configureInstanceFilters(EventRequest request, XDebugTarget target) {
462                 if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) {
463                         Iterator iter = fInstanceFilters.iterator();
464                         while (iter.hasNext()) {*/
465                                 /*IJava*//*Object object = (*//*IJava*//*Object)iter.next();
466                                 if (object.getDebugTarget().equals(target)) {
467                                         addInstanceFilter(request, ((JDIObjectValue)object).getUnderlyingObject());
468                                 }
469                         }
470                 }
471         }*/     
472         
473         /**
474          * Creates, installs, and returns all event requests for this breakpoint
475          * in the given reference type and and target.
476          * 
477          * @return the event requests created or <code>null</code> if creation failed
478          */
479         //protected abstract EventRequest[] newRequests(XDebugTarget target, ReferenceType type) throws CoreException;
480         
481         /**
482          * Add this breakpoint to the given target. After it has been
483          * added to the given target, this breakpoint will suspend
484          * execution of that target as appropriate.
485          */
486         /*public void addToTarget(XDebugTarget target) throws CoreException {
487                 fireAdding(target);
488                 createRequests(target);
489         }*/
490         
491         /**
492          * Creates event requests for the given target
493          */
494         /*protected void createRequests(XDebugTarget target) throws CoreException {
495                 if (target.isTerminated() || shouldSkipBreakpoint()) {
496                         return;
497                 }
498                 String referenceTypeName= getTypeName();
499                 String enclosingTypeName= getEnclosingReferenceTypeName();
500                 if (referenceTypeName == null || enclosingTypeName == null) {
501                         return;
502                 }
503                 // create request to listen to class loads
504                 if (referenceTypeName.indexOf('$') == -1) {
505                         registerRequest(target.createClassPrepareRequest(enclosingTypeName), target);
506                         //register to ensure we hear about local and anonymous inner classes
507                         registerRequest(target.createClassPrepareRequest(enclosingTypeName + "$*"), target);  //$NON-NLS-1$
508                 } else {
509                         registerRequest(target.createClassPrepareRequest(referenceTypeName), target);
510                         //register to ensure we hear about local and anonymous inner classes
511                         registerRequest(target.createClassPrepareRequest(enclosingTypeName + "$*", referenceTypeName), target);  //$NON-NLS-1$
512                 }
513
514                 // create breakpoint requests for each class currently loaded
515                 List classes= target.jdiClassesByName(referenceTypeName);
516                 if (classes.isEmpty() && enclosingTypeName.equals(referenceTypeName)) {
517                         return;
518                 }
519
520                 boolean success= false;
521                 Iterator iter = classes.iterator();
522                 while (iter.hasNext()) {
523                         ReferenceType type= (ReferenceType) iter.next();
524                         if (createRequest(target, type)) {
525                                 success= true;
526                         }
527                 }
528
529                 if (!success) {
530                         addToTargetForLocalType(target, enclosingTypeName);
531                 }               
532         }*/
533         
534         /**
535          * Local types (types defined in methods) are handled specially due to the
536          * different types that the local type is associated with as well as the 
537          * performance problems of using ReferenceType#nestedTypes.  From the Java 
538          * model perspective a local type is defined within a method of a type.  
539          * Therefore the type of a breakpoint placed in a local type is the type
540          * that encloses the method where the local type was defined.
541          * The local type is enclosed within the top level type according
542          * to the VM.
543          * So if "normal" attempts to create a request when a breakpoint is
544          * being added to a target fail, we must be dealing with a local type and therefore resort
545          * to looking up all of the nested types of the top level enclosing type.
546          */
547         /*protected void addToTargetForLocalType(XDebugTarget target, String enclosingTypeName) throws CoreException {
548                 List classes= target.jdiClassesByName(enclosingTypeName);
549                 if (!classes.isEmpty()) {
550                         Iterator iter = classes.iterator();
551                         while (iter.hasNext()) {
552                                 ReferenceType type= (ReferenceType) iter.next();
553                                 Iterator nestedTypes= type.nestedTypes().iterator();
554                                 while (nestedTypes.hasNext()) {
555                                         ReferenceType nestedType= (ReferenceType) nestedTypes.next();
556                                         if (createRequest(target, nestedType)) {
557                                                 break;
558                                         }                               
559                                 }
560                         }
561                 }
562         }*/
563                         
564         /**
565          * Returns the JDI suspend policy that corresponds to this
566          * breakpoint's suspend policy
567          * 
568          * @return the JDI suspend policy that corresponds to this
569          *  breakpoint's suspend policy
570          * @exception CoreException if unable to access this breakpoint's
571          *  suspend policy setting
572          */
573         /*protected int getJDISuspendPolicy() throws CoreException {
574                 int breakpointPolicy = getSuspendPolicy();
575                 if (breakpointPolicy == IXDebugBreakpoint.SUSPEND_THREAD) {
576                         return EventRequest.SUSPEND_EVENT_THREAD;
577                 }
578                 return EventRequest.SUSPEND_ALL;
579         }*/
580
581         /**
582          * returns the default suspend policy based on the pref setting on the 
583          * Java-Debug pref page
584          * @return the default suspend policy
585          * @since 3.2
586          */
587         /*protected int getDefaultSuspendPolicy() {
588                 Preferences store = JDIDebugModel.getPreferences();
589                 return store.getInt(JDIDebugPlugin.PREF_DEFAULT_BREAKPOINT_SUSPEND_POLICY);
590         }*/
591         
592         
593         /**
594          * Returns whether the hitCount of this breakpoint is equal to the hitCount of
595          * the associated request.
596          */
597         /*protected boolean hasHitCountChanged(EventRequest request) throws CoreException {
598                 int hitCount= getHitCount();
599                 Integer requestCount= (Integer) request.getProperty(HIT_COUNT);
600                 int oldCount = -1;
601                 if (requestCount != null)  {
602                         oldCount = requestCount.intValue();
603                 } 
604                 return hitCount != oldCount;
605         }*/
606         
607         /**
608          * Removes this breakpoint from the given target.
609          */
610         /*public void removeFromTarget(final XDebugTarget target) throws CoreException {
611                 removeRequests(target);
612                 Object removed = fFilteredThreadsByTarget.remove(target);
613                 boolean changed = removed != null;
614                 boolean markerExists = markerExists();
615                 if (!markerExists || (markerExists && getInstallCount() == 0)) {
616                         fInstalledTypeName = null;
617                 }
618                 
619                 // remove instance filters 
620                 if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) {
621                         for (int i = 0; i < fInstanceFilters.size(); i++) {
622                                 IJavaObject object = (IJavaObject)fInstanceFilters.get(i);
623                                 if (object.getDebugTarget().equals(target)) {
624                                         fInstanceFilters.remove(i);
625                                         changed = true;
626                                 }
627                         }
628                 }
629                 
630                 // fire change notification if required
631                 if (changed) {
632                         fireChanged();
633                 }
634                 
635                 // notification
636                 fireRemoved(target);
637         }       */      
638         
639         /**
640          * Remove all requests that this breakpoint has installed in the given
641          * debug target.
642          */
643         /*protected void removeRequests(final XDebugTarget target) throws CoreException {
644                 // removing was previously done is a workspace runnable, but that is
645                 // not possible since it can be a resource callback (marker deletion) that
646                 // causes a breakpoint to be removed
647                 ArrayList requests= (ArrayList)getRequests(target).clone();
648                 // Iterate over a copy of the requests since this list of requests
649                 // can be changed in other threads which would cause an ConcurrentModificationException
650                 Iterator iter = requests.iterator();
651                 EventRequest req;
652                 while (iter.hasNext()) {
653                         req = (EventRequest)iter.next();
654                         try {
655                                 if (target.isAvailable() && !isExpired(req)) { // cannot delete an expired request
656                                         EventRequestManager manager = target.getEventRequestManager();
657                                         if (manager != null) {
658                                                 manager.deleteEventRequest(req); // disable & remove 
659                                         }                                       
660                                 }
661                         } catch (VMDisconnectedException e) {
662                                 if (target.isAvailable()) {
663                                         JDIDebugPlugin.log(e);
664                                 }
665                         } catch (RuntimeException e) {
666                 target.internalError(e);
667                         } finally {
668                                 deregisterRequest(req, target);
669                         }
670                 }
671                 fRequestsByTarget.remove(target);
672         }*/
673                 
674         /**
675          * Update the enabled state of the given request in the given target, which is associated
676          * with this breakpoint. Set the enabled state of the request
677          * to the enabled state of this breakpoint.
678          */
679         /*protected void updateEnabledState(EventRequest request, XDebugTarget target) throws CoreException  {
680                 internalUpdateEnabledState(request, isEnabled(), target);
681         }*/
682         
683         /**
684          * Set the enabled state of the given request to the given
685          * value, also taking into account instance filters.
686          */
687         /*protected void internalUpdateEnabledState(EventRequest request, boolean enabled, XDebugTarget target) {
688                 if (request.isEnabled() != enabled) {
689                         // change the enabled state
690                         try {
691                                 // if the request has expired, do not disable.
692                                 // BreakpointRequests that have expired cannot be deleted.
693                                 if (!isExpired(request)) {
694                                         request.setEnabled(enabled);
695                                 }
696                         //} catch (VMDisconnectedException e) {
697                         } catch (RuntimeException e) {
698                                 //target.internalError(e);
699                         }
700                 }
701         }*/
702                 
703         /**
704          * Returns whether this breakpoint has expired.
705          */
706         public boolean isExpired() throws CoreException {
707                 return ensureMarker().getAttribute(EXPIRED, false);
708         }       
709         
710         /**
711          * Returns whether the given request is expired
712          */
713         /*protected boolean isExpired(EventRequest request) {
714                 Boolean requestExpired= (Boolean) request.getProperty(EXPIRED);
715                 if (requestExpired == null) {
716                                 return false;
717                 }
718                 return requestExpired.booleanValue();
719         }*/
720
721         /* (non-Javadoc)
722          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#isInstalled()
723          */
724         public boolean isInstalled() throws CoreException {
725                 return ensureMarker().getAttribute(INSTALL_COUNT, 0) > 0;
726         }       
727         
728         /**
729          * Increments the install count of this breakpoint
730          */
731         protected void incrementInstallCount() throws CoreException {   
732                 int count = getInstallCount();
733                 setAttribute(INSTALL_COUNT, count + 1);
734         }       
735         
736         /**
737          * Returns the <code>INSTALL_COUNT</code> attribute of this breakpoint
738          * or 0 if the attribute is not set.
739          */
740         public int getInstallCount() throws CoreException {
741                 return ensureMarker().getAttribute(INSTALL_COUNT, 0);
742         }       
743
744         /**
745          * Decrements the install count of this breakpoint.
746          */
747         protected void decrementInstallCount() throws CoreException {
748                 int count= getInstallCount();
749                 if (count > 0) {
750                         setAttribute(INSTALL_COUNT, count - 1); 
751                 }
752                 if (count == 1) {
753                         if (isExpired()) {
754                                 // if breakpoint was auto-disabled, re-enable it
755                                 setAttributes(fgExpiredEnabledAttributes,
756                                                 new Object[]{Boolean.FALSE, Boolean.TRUE});
757                         }
758                 }
759         }
760         
761         /**
762          * Sets the type name in which to install this breakpoint.
763          */
764         protected void setTypeName(String typeName) throws CoreException {
765                 setAttribute(TYPE_NAME, typeName);
766         }       
767
768         /* (non-Javadoc)
769          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getTypeName()
770          */
771         public String getTypeName() throws CoreException {
772                 if (fInstalledTypeName == null) {
773                         return ensureMarker().getAttribute(TYPE_NAME, null);
774                 }
775                 return fInstalledTypeName;
776         }
777         
778         /**
779          * Resets the install count attribute on this breakpoint's marker
780          * to "0".  Resets the expired attribute on all breakpoint markers to <code>false</code>.
781          * Resets the enabled attribute on the breakpoint marker to <code>true</code>.
782          * If a workbench crashes, the attributes could have been persisted
783          * in an incorrect state.
784          */
785         private void configureAtStartup() throws CoreException {
786                 List attributes= null;
787                 List values= null;
788                 if (isInstalled()) {
789                         attributes= new ArrayList(3);
790                         values= new ArrayList(3);
791                         attributes.add(INSTALL_COUNT);
792                         values.add(new Integer(0));
793                 }
794                 if (isExpired()) {
795                         if (attributes == null) {
796                                 attributes= new ArrayList(3);
797                                 values= new ArrayList(3);
798                         }
799                         // if breakpoint was auto-disabled, re-enable it
800                         attributes.add(EXPIRED);
801                         values.add(Boolean.FALSE);
802                         attributes.add(ENABLED);
803                         values.add(Boolean.TRUE);
804                 }
805                 if (attributes != null) {
806                         String[] strAttributes= new String[attributes.size()];
807                         setAttributes((String[])attributes.toArray(strAttributes), values.toArray());
808                 }
809         }       
810
811         /* (non-Javadoc)
812          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getHitCount()
813          */
814         public int getHitCount() throws CoreException {
815                 return ensureMarker().getAttribute(HIT_COUNT, -1);
816         }
817         
818         /* (non-Javadoc)
819          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setHitCount(int)
820          */
821         public void setHitCount(int count) throws CoreException {       
822                 if (getHitCount() != count) {
823                         if (!isEnabled() && count > -1) {
824                                 setAttributes(new String []{ENABLED, HIT_COUNT, EXPIRED},
825                                         new Object[]{Boolean.TRUE, new Integer(count), Boolean.FALSE});
826                         } else {
827                                 setAttributes(new String[]{HIT_COUNT, EXPIRED},
828                                         new Object[]{new Integer(count), Boolean.FALSE});
829                         }
830                         ///recreate();
831                 }
832         }
833         
834         protected String getMarkerMessage(int hitCount, int suspendPolicy) {
835                 StringBuffer buff= new StringBuffer();
836                 /*if (hitCount > 0){
837                         buff.append(MessageFormat.format(JDIDebugBreakpointMessages.JavaBreakpoint___Hit_Count___0___1, new Object[]{Integer.toString(hitCount)})); 
838                         buff.append(' ');
839                 }
840                 String suspendPolicyString;
841                 if (suspendPolicy == IJavaBreakpoint.SUSPEND_THREAD) {
842                         suspendPolicyString= JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__thread__1; 
843                 } else {
844                         suspendPolicyString= JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__VM__2; 
845                 }
846                 
847                 buff.append(suspendPolicyString);*/
848                 return buff.toString();
849         }       
850         
851         /**
852          * Sets whether this breakpoint's hit count has expired.
853          */
854         public void setExpired(boolean expired) throws CoreException {
855                 setAttribute(EXPIRED, expired); 
856         }       
857
858         /* (non-Javadoc)
859          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getSuspendPolicy()
860          */
861         /*public int getSuspendPolicy() throws CoreException {
862                 return ensureMarker().getAttribute(SUSPEND_POLICY, IJavaBreakpoint.SUSPEND_THREAD);
863         }*/
864
865         /* (non-Javadoc)
866          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setSuspendPolicy(int)
867          */
868         /*public void setSuspendPolicy(int suspendPolicy) throws CoreException {
869                 if(getSuspendPolicy() != suspendPolicy) {
870                         setAttribute(SUSPEND_POLICY, suspendPolicy);
871                         recreate();
872                 }
873         }*/
874         
875         /**
876          * Notifies listeners this breakpoint is to be added to the
877          * given target.
878          * 
879          * @param target debug target
880          */
881         /*protected void fireAdding(XDebugTarget target) {
882                 XDebugCorePlugin plugin = XDebugCorePlugin.getDefault();
883         if (plugin != null)
884             plugin.fireBreakpointAdding(target, this);
885         }*/
886         
887         /**
888          * Notifies listeners this breakpoint has been removed from the
889          * given target.
890          * 
891          * @param target debug target
892          */
893         /*protected void fireRemoved(XDebugTarget target) {
894                 XDebugCorePlugin plugin = XDebugCorePlugin.getDefault();
895         if (plugin != null) {
896             plugin.fireBreakpointRemoved(target, this);
897             setInstalledIn(target, false);
898         }
899         }*/     
900         
901         /**
902          * Notifies listeners this breakpoint has been installed in the
903          * given target.
904          * 
905          * @param target debug target
906          */
907         /*protected void fireInstalled(XDebugTarget target) {
908                 XDebugCorePlugin plugin = XDebugCorePlugin.getDefault();
909                 if (plugin!= null && !isInstalledIn(target)) {
910             plugin.fireBreakpointInstalled(target, this);
911                         setInstalledIn(target, true);
912                 }
913         }       */
914         
915         /**
916          * Returns whether this breakpoint is installed in the given target.
917          * 
918          * @param target
919          * @return whether this breakpoint is installed in the given target
920          */
921         protected boolean isInstalledIn(XDebugTarget target) {
922                 return fInstalledTargets != null && fInstalledTargets.contains(target);
923         }
924         
925         /**
926          * Sets this breakpoint as installed in the given target
927          * 
928          * @param target
929          * @param installed whether installed
930          */
931         protected void setInstalledIn(XDebugTarget target, boolean installed) {
932                 if (installed) {
933                         if (fInstalledTargets == null) {
934                                 fInstalledTargets = new HashSet();
935                         }
936                         fInstalledTargets.add(target);
937                 } else {
938                         if (fInstalledTargets != null) {
939                                 fInstalledTargets.remove(target);
940                         }
941                 }
942         }
943         
944         /* (non-Javadoc)
945          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setThreadFilter(org.eclipse.jdt.debug.core.IJavaThread)
946          */
947         /*public void setThreadFilter(IJavaThread thread) throws CoreException {
948                 if (!(thread.getDebugTarget() instanceof JDIDebugTarget) || !(thread instanceof JDIThread)) {
949                         return;
950                 }
951                 JDIDebugTarget target= (JDIDebugTarget)thread.getDebugTarget();
952                 if (thread != fFilteredThreadsByTarget.put(target, thread) ) {
953                         // recreate the breakpoint only if it is not the same thread
954                         
955                         // Other breakpoints set attributes on the underlying
956                         // marker and the marker changes are eventually
957                         // propagated to the target. The target then asks the
958                         // breakpoint to update its request. Since thread filters
959                         // are transient properties, they are not set on
960                         // the marker. Thus we must update the request
961                         // here.
962                         recreate(target);
963                         fireChanged();
964                 }
965         }*/
966         
967         /* (non-Javadoc)
968          * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
969          */
970         /*public void handleDebugEvents(DebugEvent[] events) {
971                 for (int i = 0; i < events.length; i++) {
972                         DebugEvent event = events[i];
973                         if (event.getKind() == DebugEvent.TERMINATE) {
974                                 Object source= event.getSource();
975                                 if (!(source instanceof JDIThread)) {
976                                         return;
977                                 }
978                                 try {
979                                         cleanupForThreadTermination((JDIThread)source);
980                                 } catch (VMDisconnectedException exception) {
981                                         // Thread death often occurs at shutdown.
982                                         // A VMDisconnectedException trying to 
983                                         // update the breakpoint request is
984                                         // acceptable.
985                                 }
986                         }
987                 }
988         }*/
989         
990         /**
991          * Removes cached information relevant to this thread which has
992          * terminated.
993          * 
994          * Remove thread filters for terminated threads
995          * 
996          * Subclasses may override but need to call super.
997          */
998         /*protected void cleanupForThreadTermination(JDIThread thread) {
999                 JDIDebugTarget target= (JDIDebugTarget)thread.getDebugTarget();
1000                 try {
1001                         if (thread == getThreadFilter(target)) {
1002                                 removeThreadFilter(target);
1003                         }
1004                 } catch (CoreException exception) {
1005                         JDIDebugPlugin.log(exception);
1006                 }
1007         }*/
1008         
1009         /** 
1010          * EventRequest does not support thread filters, so they
1011          * can't be set generically here. However, each of the breakpoint
1012          * subclasses of EventRequest do support thread filters. So
1013          * subclasses can set thread filters on their specific
1014          * request type.
1015          */
1016         //protected abstract void setRequestThreadFilter(EventRequest request, ThreadReference thread);
1017         
1018         /* (non-Javadoc)
1019          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilter(org.eclipse.jdt.debug.core.IJavaDebugTarget)
1020          */
1021         /*public IJavaThread getThreadFilter(IJavaDebugTarget target) {
1022                 return (IJavaThread)fFilteredThreadsByTarget.get(target);
1023         }*/
1024         
1025         /* (non-Javadoc)
1026          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilters()
1027          */
1028         /*public IJavaThread[] getThreadFilters() {
1029                 IJavaThread[] threads= null;
1030                 Collection values= fFilteredThreadsByTarget.values();
1031                 threads= new IJavaThread[values.size()];
1032                 values.toArray(threads);
1033                 return threads;
1034         }*/
1035
1036         /* (non-Javadoc)
1037          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#removeThreadFilter(org.eclipse.jdt.debug.core.IJavaDebugTarget)
1038          */
1039         /*public void removeThreadFilter(XDebugTarget javaTarget) throws CoreException {
1040                 if (!(javaTarget instanceof XDebugTarget)) {
1041                         return;
1042                 }
1043                 XDebugTarget target= (XDebugTarget)javaTarget;
1044                 if (fFilteredThreadsByTarget.remove(target) != null) {
1045                         recreate(target);
1046                         fireChanged();
1047                 }
1048         }*/
1049         
1050         /**
1051          * Returns whether this breakpoint should be installed in the given reference
1052          * type in the given target according to registered breakpoint listeners.
1053          * 
1054          * @param target debug target
1055          * @param type reference type or <code>null</code> if this breakpoint is
1056          *  not installed in a specific type
1057          */
1058         /*protected boolean queryInstallListeners(XDebugTarget target, ReferenceType type) {
1059         XDebugCorePlugin plugin = XDebugCorePlugin.getDefault();
1060         if (plugin != null) {
1061             IJavaType jt = null;
1062             if (type != null) {
1063                 jt = JDIType.createType(target, type);
1064             }
1065             return plugin.fireInstalling(target, this, jt);
1066         }
1067         return false;
1068         }*/
1069         
1070         /* (non-Javadoc)
1071          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#addInstanceFilter(org.eclipse.jdt.debug.core.IJavaObject)
1072          */
1073         public void addInstanceFilter(/*IJava*/Object object) throws CoreException {
1074                 if (fInstanceFilters == null) {
1075                         fInstanceFilters= new ArrayList();
1076                 }
1077                 if (!fInstanceFilters.contains(object)) {
1078                         fInstanceFilters.add(object);
1079                         ///recreate((XDebugTarget)object.getDebugTarget());
1080                         fireChanged();
1081                 }
1082         }
1083         
1084         /**
1085          * Change notification when there are no marker changes. If the marker
1086          * does not exist, do not fire a change notification (the marker may not
1087          * exist if the associated project was closed).
1088          */
1089         protected void fireChanged() {
1090         DebugPlugin plugin = DebugPlugin.getDefault();
1091                 if (plugin != null && markerExists()) { 
1092             plugin.getBreakpointManager().fireBreakpointChanged(this);
1093                 }                                       
1094         }
1095
1096         /* (non-Javadoc)
1097          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getInstanceFilters()
1098          */
1099         public /*IJava*/Object[] getInstanceFilters() {
1100                 if (fInstanceFilters == null || fInstanceFilters.isEmpty()) {
1101                         return fgEmptyInstanceFilters;
1102                 }
1103                 return (/*IJava*/Object[])fInstanceFilters.toArray(new /*IJava*/Object[fInstanceFilters.size()]);
1104         }
1105
1106         /* (non-Javadoc)
1107          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#removeInstanceFilter(org.eclipse.jdt.debug.core.IJavaObject)
1108          */
1109         public void removeInstanceFilter(/*IJava*/Object object) throws CoreException {
1110                 if (fInstanceFilters == null) {
1111                         return;
1112                 }
1113                 if (fInstanceFilters.remove(object)) {
1114                         ///recreate((XDebugTarget)object.getDebugTarget());
1115                         fireChanged();
1116                 }
1117         }
1118         
1119         /**
1120          * An attribute of this breakpoint has changed - recreate event requests in
1121          * all targets.
1122          */
1123         /*protected void recreate() throws CoreException {
1124                 DebugPlugin plugin = DebugPlugin.getDefault();
1125         if (plugin != null) {
1126             IDebugTarget[] targets = plugin.getLaunchManager().getDebugTargets();
1127             for (int i = 0; i < targets.length; i++) {
1128                 IDebugTarget target = targets[i];
1129                 MultiStatus multiStatus = new MultiStatus(XDebugCorePlugin.getUniqueIdentifier(), JDIDebugPlugin.ERROR, JDIDebugBreakpointMessages.JavaBreakpoint_Exception, null);
1130                 IJavaDebugTarget jdiTarget = (IJavaDebugTarget) target.getAdapter(IJavaDebugTarget.class);
1131                 if (jdiTarget instanceof JDIDebugTarget) {
1132                     try {
1133                         recreate((JDIDebugTarget) jdiTarget);
1134                     } catch (CoreException e) {
1135                         multiStatus.add(e.getStatus());
1136                     }
1137                 }
1138                 if (!multiStatus.isOK()) {
1139                     throw new CoreException(multiStatus);
1140                 }
1141             }
1142         }
1143     }*/
1144         
1145         /**
1146          * Recreate this breakpoint in the given target, as long as the
1147          * target already contains this breakpoint.
1148          * 
1149          * @param target the target in which to re-create the breakpoint 
1150          */
1151         /*protected void recreate(XDebugTarget target) throws CoreException {
1152                 if (target.isAvailable() && target.getBreakpoints().contains(this)) {
1153                         removeRequests(target);
1154                         createRequests(target);
1155                 }
1156         }*/
1157
1158         /* (non-Javadoc)
1159          * @see org.eclipse.debug.core.model.Breakpoint#setEnabled(boolean)
1160          */
1161         public void setEnabled(boolean enabled) throws CoreException {
1162                 super.setEnabled(enabled);
1163                 //recreate();
1164         }
1165
1166         /* (non-Javadoc)
1167          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsInstanceFilters()
1168          */
1169         public boolean supportsInstanceFilters() {
1170                 return true;
1171         }
1172         /* (non-Javadoc)
1173          * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsThreadFilters()
1174          */
1175         /*public boolean supportsThreadFilters() {
1176                 return true;
1177         }*/
1178 }