001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdi.internal.request;
011:
012: import java.io.ByteArrayOutputStream;
013: import java.io.DataInputStream;
014: import java.io.DataOutputStream;
015: import java.io.IOException;
016: import java.util.ArrayList;
017: import java.util.HashMap;
018: import java.util.Map;
019:
020: import org.eclipse.jdi.internal.FieldImpl;
021: import org.eclipse.jdi.internal.LocationImpl;
022: import org.eclipse.jdi.internal.MirrorImpl;
023: import org.eclipse.jdi.internal.ObjectReferenceImpl;
024: import org.eclipse.jdi.internal.ReferenceTypeImpl;
025: import org.eclipse.jdi.internal.ThreadReferenceImpl;
026: import org.eclipse.jdi.internal.VirtualMachineImpl;
027: import org.eclipse.jdi.internal.event.EventImpl;
028: import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
029: import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
030:
031: import com.sun.jdi.InternalException;
032: import com.sun.jdi.ObjectCollectedException;
033: import com.sun.jdi.ObjectReference;
034: import com.sun.jdi.ReferenceType;
035: import com.sun.jdi.ThreadReference;
036: import com.sun.jdi.VMMismatchException;
037: import com.sun.jdi.request.EventRequest;
038: import com.sun.jdi.request.InvalidRequestStateException;
039: import com.sun.jdi.request.StepRequest;
040:
041: /**
042: * this class implements the corresponding interfaces
043: * declared by the JDI specification. See the com.sun.jdi package
044: * for more information.
045: *
046: */
047: public abstract class EventRequestImpl extends MirrorImpl implements
048: EventRequest {
049: /** Jdwp constants for StepRequests. */
050: public static final byte STEP_SIZE_MIN_JDWP = 0;
051: public static final byte STEP_SIZE_LINE_JDWP = 1;
052: public static final byte STEP_DEPTH_INTO_JDWP = 0;
053: public static final byte STEP_DEPTH_OVER_JDWP = 1;
054: public static final byte STEP_DEPTH_OUT_JDWP = 2;
055: public static final byte STEP_DEPTH_REENTER_JDWP_HCR = 3; // OTI specific for Hot Code Replacement.
056:
057: /** Jdwp constants for SuspendPolicy. */
058: public static final byte SUSPENDPOL_NONE_JDWP = 0;
059: public static final byte SUSPENDPOL_EVENT_THREAD_JDWP = 1;
060: public static final byte SUSPENDPOL_ALL_JDWP = 2;
061:
062: /** Constants for ModifierKind. */
063: public static final byte MODIF_KIND_COUNT = 1;
064: public static final byte MODIF_KIND_CONDITIONAL = 2;
065: public static final byte MODIF_KIND_THREADONLY = 3;
066: public static final byte MODIF_KIND_CLASSONLY = 4;
067: public static final byte MODIF_KIND_CLASSMATCH = 5;
068: public static final byte MODIF_KIND_CLASSEXCLUDE = 6;
069: public static final byte MODIF_KIND_LOCATIONONLY = 7;
070: public static final byte MODIF_KIND_EXCEPTIONONLY = 8;
071: public static final byte MODIF_KIND_FIELDONLY = 9;
072: public static final byte MODIF_KIND_STEP = 10;
073: public static final byte MODIF_KIND_INSTANCE = 11;
074: public static final byte MODIF_KIND_SOURCE_NAME_FILTER = 12;
075:
076: /** Mapping of command codes to strings. */
077: private static HashMap fStepSizeMap = null;
078: private static HashMap fStepDepthMap = null;
079: private static HashMap fSuspendPolicyMap = null;
080: private static HashMap fModifierKindMap = null;
081:
082: /** Flag that indicates the request was generated from inside of this JDI implementation. */
083: private boolean fGeneratedInside = false;
084:
085: /** User property map. */
086: private HashMap fPropertyMap;
087:
088: /** RequestId of EventRequest, assigned by the reply data of the JDWP Event Reuqest Set command, null if request had not yet been enabled. */
089: protected RequestID fRequestID = null;
090: /** Determines the threads to suspend when the requested event occurs in the target VM. */
091: private byte fSuspendPolicy = SUSPEND_ALL; // Default is as specified by JDI spec.
092:
093: /**
094: * Modifiers.
095: */
096: /** Count filters. */
097: protected ArrayList fCountFilters;
098:
099: /** Thread filters. */
100: protected ArrayList fThreadFilters = null;
101:
102: /** Class filters. */
103: protected ArrayList fClassFilters = null;
104:
105: /** Class filters. */
106: protected ArrayList fClassFilterRefs = null;
107:
108: /** Class Exclusion filters. */
109: protected ArrayList fClassExclusionFilters = null;
110:
111: /** Location filters. */
112: protected ArrayList fLocationFilters = null;
113:
114: /** Exception filters. */
115: protected ArrayList fExceptionFilters = null;
116:
117: /** Field filters. */
118: protected ArrayList fFieldFilters = null;
119:
120: /** Thread step filters. */
121: protected ArrayList fThreadStepFilters = null;
122:
123: /** Instance filters. */
124: protected ArrayList fInstanceFilters = null;
125: /**
126: * source name filters
127: * @since 3.3
128: */
129: protected ArrayList fSourceNameFilters = null;
130:
131: /**
132: * Creates new EventRequest.
133: */
134: protected EventRequestImpl(String description,
135: VirtualMachineImpl vmImpl) {
136: super (description, vmImpl);
137: }
138:
139: /**
140: * @return Returns string representation.
141: */
142: public String toString() {
143: return super .toString()
144: + (fRequestID == null ? RequestMessages.EventRequestImpl___not_enabled__1
145: : RequestMessages.EventRequestImpl____2
146: + fRequestID); //
147: }
148:
149: /**
150: * @return Returns the value of the property with the specified key.
151: */
152: public Object getProperty(Object key) {
153: if (fPropertyMap == null) {
154: return null;
155: }
156:
157: return fPropertyMap.get(key);
158: }
159:
160: /**
161: * Add an arbitrary key/value "property" to this request.
162: */
163: public void putProperty(Object key, Object value) {
164: if (fPropertyMap == null)
165: fPropertyMap = new HashMap();
166:
167: if (value == null)
168: fPropertyMap.remove(key);
169: else
170: fPropertyMap.put(key, value);
171: }
172:
173: /**
174: * Sets the generated inside flag. Used for requests that are not generated by JDI requests from outside.
175: */
176: public void setGeneratedInside() {
177: fGeneratedInside = true;
178: }
179:
180: /**
181: * @return Returns whether the event request was generated from inside of this JDI implementation.
182: */
183: public final boolean isGeneratedInside() {
184: return fGeneratedInside;
185: }
186:
187: /**
188: * Disables event request.
189: */
190: public synchronized void disable() {
191: if (!isEnabled())
192: return;
193:
194: initJdwpRequest();
195: try {
196: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
197: DataOutputStream outData = new DataOutputStream(outBytes);
198: writeByte(eventKind(),
199: "event kind", EventImpl.eventKindMap(), outData); //$NON-NLS-1$
200: fRequestID.write(this , outData);
201:
202: JdwpReplyPacket replyPacket = requestVM(
203: JdwpCommandPacket.ER_CLEAR, outBytes);
204: switch (replyPacket.errorCode()) {
205: case JdwpReplyPacket.NOT_FOUND:
206: throw new InvalidRequestStateException();
207: }
208: defaultReplyErrorHandler(replyPacket.errorCode());
209:
210: virtualMachineImpl().eventRequestManagerImpl()
211: .removeRequestIDMapping(this );
212: fRequestID = null;
213: } catch (IOException e) {
214: defaultIOExceptionHandler(e);
215: } finally {
216: handledJdwpRequest();
217: }
218: }
219:
220: /**
221: * Enables event request.
222: */
223: public synchronized void enable() {
224: if (isEnabled())
225: return;
226:
227: initJdwpRequest();
228: try {
229: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
230: DataOutputStream outData = new DataOutputStream(outBytes);
231: writeByte(eventKind(),
232: "event kind", EventImpl.eventKindMap(), outData); //$NON-NLS-1$
233: writeByte(
234: suspendPolicyJDWP(),
235: "suspend policy", EventRequestImpl.suspendPolicyMap(), outData); //$NON-NLS-1$
236: writeInt(modifierCount(), "modifiers", outData); //$NON-NLS-1$
237: writeModifiers(outData);
238:
239: JdwpReplyPacket replyPacket = requestVM(
240: JdwpCommandPacket.ER_SET, outBytes);
241: defaultReplyErrorHandler(replyPacket.errorCode());
242: DataInputStream replyData = replyPacket.dataInStream();
243: fRequestID = RequestID.read(this , replyData);
244: virtualMachineImpl().eventRequestManagerImpl()
245: .addRequestIDMapping(this );
246: } catch (IOException e) {
247: defaultIOExceptionHandler(e);
248: } finally {
249: handledJdwpRequest();
250: }
251: }
252:
253: /**
254: * Clear all breakpoints (used by EventRequestManager).
255: */
256: public static void clearAllBreakpoints(MirrorImpl mirror) {
257: mirror.initJdwpRequest();
258: try {
259: JdwpReplyPacket replyPacket = mirror
260: .requestVM(JdwpCommandPacket.ER_CLEAR_ALL_BREAKPOINTS);
261: mirror.defaultReplyErrorHandler(replyPacket.errorCode());
262: } finally {
263: mirror.handledJdwpRequest();
264: }
265: }
266:
267: /**
268: * @return Returns whether event request is enabled.
269: */
270: public synchronized final boolean isEnabled() {
271: return fRequestID != null;
272: }
273:
274: /**
275: * Disables or enables event request.
276: */
277: public void setEnabled(boolean enable) {
278: if (enable)
279: enable();
280: else
281: disable();
282: }
283:
284: /**
285: * @exception InvalidRequestStateException is thrown if this request is enabled.
286: */
287: public void checkDisabled() throws InvalidRequestStateException {
288: if (isEnabled())
289: throw new InvalidRequestStateException();
290: }
291:
292: /**
293: * Sets suspend policy.
294: */
295: public void setSuspendPolicy(int suspendPolicy) {
296: fSuspendPolicy = (byte) suspendPolicy;
297: if (isEnabled()) {
298: disable();
299: enable();
300: }
301: }
302:
303: /**
304: * @return Returns suspend policy.
305: */
306: public int suspendPolicy() {
307: return fSuspendPolicy;
308: }
309:
310: /**
311: * @return Returns requestID, or null if request ID is not (yet) assigned.
312: */
313: public final RequestID requestID() {
314: return fRequestID;
315: }
316:
317: /**
318: * Sets countfilter.
319: */
320: public void addCountFilter(int count)
321: throws InvalidRequestStateException {
322: checkDisabled();
323: if (fCountFilters == null)
324: fCountFilters = new ArrayList();
325:
326: fCountFilters.add(new Integer(count));
327: }
328:
329: /**
330: * Restricts reported events to those in the given thread.
331: */
332: public void addThreadFilter(ThreadReference threadFilter)
333: throws ObjectCollectedException, VMMismatchException,
334: InvalidRequestStateException {
335: checkVM(threadFilter);
336: checkDisabled();
337: if (threadFilter.isCollected())
338: throw new ObjectCollectedException();
339: if (fThreadFilters == null)
340: fThreadFilters = new ArrayList();
341:
342: fThreadFilters.add(threadFilter);
343: }
344:
345: /**
346: * Restricts the events generated by this request to the preparation of reference types whose name matches this restricted regular expression.
347: */
348: public void addClassFilter(ReferenceType filter)
349: throws VMMismatchException, InvalidRequestStateException {
350: checkVM(filter);
351: checkDisabled();
352: if (fClassFilterRefs == null)
353: fClassFilterRefs = new ArrayList();
354:
355: fClassFilterRefs.add(filter);
356: }
357:
358: /**
359: * Restricts the events generated by this request to be the preparation of the given reference type and any subtypes.
360: */
361: public void addClassFilter(String filter)
362: throws InvalidRequestStateException {
363: checkDisabled();
364: if (fClassFilters == null)
365: fClassFilters = new ArrayList();
366:
367: fClassFilters.add(filter);
368: }
369:
370: /**
371: * Restricts the events generated by this request to the preparation of reference types whose name does not match this restricted regular expression.
372: */
373: public void addClassExclusionFilter(String filter)
374: throws InvalidRequestStateException {
375: checkDisabled();
376: if (fClassExclusionFilters == null)
377: fClassExclusionFilters = new ArrayList();
378:
379: fClassExclusionFilters.add(filter);
380: }
381:
382: /**
383: * Restricts the events generated by this request to those that occur at the given location.
384: */
385: public void addLocationFilter(LocationImpl location)
386: throws VMMismatchException {
387: checkDisabled();
388: // Used in createBreakpointRequest.
389: checkVM(location);
390: if (fLocationFilters == null)
391: fLocationFilters = new ArrayList();
392:
393: fLocationFilters.add(location);
394: }
395:
396: /**
397: * Restricts reported exceptions by their class and whether they are caught or uncaught.
398: */
399: public void addExceptionFilter(ReferenceTypeImpl refType,
400: boolean notifyCaught, boolean notifyUncaught)
401: throws VMMismatchException {
402: checkDisabled();
403: // refType Null means report exceptions of all types.
404: if (refType != null)
405: checkVM(refType);
406:
407: if (fExceptionFilters == null)
408: fExceptionFilters = new ArrayList();
409:
410: ExceptionFilter filter = new ExceptionFilter();
411: filter.fException = refType;
412: filter.fNotifyCaught = notifyCaught;
413: filter.fNotifyUncaught = notifyUncaught;
414: fExceptionFilters.add(filter);
415: }
416:
417: /**
418: * Restricts reported events to those that occur for a given field.
419: */
420: public void addFieldFilter(FieldImpl field)
421: throws VMMismatchException {
422: checkDisabled();
423: // Used in createXWatchpointRequest methods.
424: checkVM(field);
425: if (fFieldFilters == null)
426: fFieldFilters = new ArrayList();
427:
428: fFieldFilters.add(field);
429: }
430:
431: /**
432: * Restricts reported step events to those which satisfy depth and size constraints.
433: */
434: public void addStepFilter(ThreadReferenceImpl thread, int size,
435: int depth) throws VMMismatchException {
436: checkDisabled();
437: // Used in createStepRequest.
438: checkVM(thread);
439:
440: if (fThreadStepFilters == null)
441: fThreadStepFilters = new ArrayList();
442:
443: ThreadStepFilter filter = new ThreadStepFilter();
444: filter.fThread = thread;
445: filter.fThreadStepSize = size;
446: filter.fThreadStepDepth = depth;
447: fThreadStepFilters.add(filter);
448: }
449:
450: /**
451: * Helper method which allows instance filters to be added
452: * @param instance the object ref instance to add to the listing
453: */
454: public void addInstanceFilter(ObjectReference instance) {
455: checkDisabled();
456: checkVM(instance);
457: if (fInstanceFilters == null) {
458: fInstanceFilters = new ArrayList();
459: }
460: fInstanceFilters.add(instance);
461: }
462:
463: /**
464: * Adds a source name filter to the request. An exact match or pattern beginning
465: * OR ending in '*'.
466: *
467: * @param pattern source name pattern
468: * @since 3.3
469: */
470: public void addSourceNameFilter(String pattern) {
471: checkDisabled();
472: if (fSourceNameFilters == null) {
473: fSourceNameFilters = new ArrayList();
474: }
475: fSourceNameFilters.add(pattern);
476: }
477:
478: /**
479: * From here on JDWP functionality of EventRequest is implemented.
480: */
481:
482: /**
483: * @return Returns JDWP constant for suspend policy.
484: */
485: public byte suspendPolicyJDWP() {
486: switch (fSuspendPolicy) {
487: case SUSPEND_NONE:
488: return SUSPENDPOL_NONE_JDWP;
489: case SUSPEND_EVENT_THREAD:
490: return SUSPENDPOL_EVENT_THREAD_JDWP;
491: case SUSPEND_ALL:
492: return SUSPENDPOL_ALL_JDWP;
493: default:
494: throw new InternalException(
495: RequestMessages.EventRequestImpl_Invalid_suspend_policy_encountered___3
496: + fSuspendPolicy);
497: }
498: }
499:
500: /**
501: * @return Returns JDWP constant for step size.
502: */
503: public int threadStepSizeJDWP(int threadStepSize) {
504: switch (threadStepSize) {
505: case StepRequest.STEP_MIN:
506: return STEP_SIZE_MIN_JDWP;
507: case StepRequest.STEP_LINE:
508: return STEP_SIZE_LINE_JDWP;
509: default:
510: throw new InternalException(
511: RequestMessages.EventRequestImpl_Invalid_step_size_encountered___4
512: + threadStepSize);
513: }
514: }
515:
516: /**
517: * @return Returns JDWP constant for step depth.
518: */
519: public int threadStepDepthJDWP(int threadStepDepth) {
520: switch (threadStepDepth) {
521: case StepRequest.STEP_INTO:
522: return STEP_DEPTH_INTO_JDWP;
523: case StepRequest.STEP_OVER:
524: return STEP_DEPTH_OVER_JDWP;
525: case StepRequest.STEP_OUT:
526: return STEP_DEPTH_OUT_JDWP;
527: default:
528: throw new InternalException(
529: RequestMessages.EventRequestImpl_Invalid_step_depth_encountered___5
530: + threadStepDepth);
531: }
532: }
533:
534: /**
535: * @return Returns JDWP EventKind.
536: */
537: protected abstract byte eventKind();
538:
539: /**
540: * @return Returns number of modifiers.
541: */
542: protected int modifierCount() {
543: int count = 0;
544:
545: if (fCountFilters != null)
546: count += fCountFilters.size();
547: if (fThreadFilters != null)
548: count += fThreadFilters.size();
549: if (fClassFilterRefs != null)
550: count += fClassFilterRefs.size();
551: if (fClassFilters != null)
552: count += fClassFilters.size();
553: if (fClassExclusionFilters != null)
554: count += fClassExclusionFilters.size();
555: if (fLocationFilters != null)
556: count += fLocationFilters.size();
557: if (fExceptionFilters != null)
558: count += fExceptionFilters.size();
559: if (fFieldFilters != null)
560: count += fFieldFilters.size();
561: if (fThreadStepFilters != null)
562: count += fThreadStepFilters.size();
563: if (fInstanceFilters != null)
564: count += fInstanceFilters.size();
565: if (fSourceNameFilters != null) {
566: if (supportsSourceNameFilters()) {
567: count += fSourceNameFilters.size();
568: }
569: }
570: return count;
571: }
572:
573: /**
574: * Writes JDWP bytestream representation of modifiers.
575: */
576: protected void writeModifiers(DataOutputStream outData)
577: throws IOException {
578: // Note: for some reason the order of these modifiers matters when communicating with SUN's VM.
579: // It seems to expect them 'the wrong way around'.
580: if (fThreadStepFilters != null) {
581: for (int i = 0; i < fThreadStepFilters.size(); i++) {
582: ThreadStepFilter filter = (ThreadStepFilter) fThreadStepFilters
583: .get(i);
584: writeByte(MODIF_KIND_STEP,
585: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
586: filter.fThread.write(this , outData);
587: writeInt(threadStepSizeJDWP(filter.fThreadStepSize),
588: "step size", outData); //$NON-NLS-1$
589: writeInt(threadStepDepthJDWP(filter.fThreadStepDepth),
590: "step depth", outData); //$NON-NLS-1$
591: }
592: }
593: if (fFieldFilters != null) {
594: for (int i = 0; i < fFieldFilters.size(); i++) {
595: writeByte(MODIF_KIND_FIELDONLY,
596: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
597: ((FieldImpl) fFieldFilters.get(i))
598: .writeWithReferenceType(this , outData);
599: }
600: }
601: if (fExceptionFilters != null) {
602: for (int i = 0; i < fExceptionFilters.size(); i++) {
603: ExceptionFilter filter = (ExceptionFilter) fExceptionFilters
604: .get(i);
605: writeByte(MODIF_KIND_EXCEPTIONONLY,
606: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
607: if (filter.fException != null)
608: filter.fException.write(this , outData);
609: else
610: ReferenceTypeImpl.writeNull(this , outData);
611:
612: writeBoolean(filter.fNotifyCaught,
613: "notify caught", outData); //$NON-NLS-1$
614: writeBoolean(filter.fNotifyUncaught,
615: "notify uncaught", outData); //$NON-NLS-1$
616: }
617: }
618: if (fLocationFilters != null) {
619: for (int i = 0; i < fLocationFilters.size(); i++) {
620: writeByte(MODIF_KIND_LOCATIONONLY,
621: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
622: ((LocationImpl) fLocationFilters.get(i)).write(this ,
623: outData);
624: }
625: }
626: if (fClassExclusionFilters != null) {
627: for (int i = 0; i < fClassExclusionFilters.size(); i++) {
628: writeByte(MODIF_KIND_CLASSEXCLUDE,
629: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
630: writeString((String) fClassExclusionFilters.get(i),
631: "class excl. filter", outData); //$NON-NLS-1$
632: }
633: }
634: if (fClassFilters != null) {
635: for (int i = 0; i < fClassFilters.size(); i++) {
636: writeByte(MODIF_KIND_CLASSMATCH,
637: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
638: writeString((String) fClassFilters.get(i),
639: "class filter", outData); //$NON-NLS-1$
640: }
641: }
642: if (fClassFilterRefs != null) {
643: for (int i = 0; i < fClassFilterRefs.size(); i++) {
644: writeByte(MODIF_KIND_CLASSONLY,
645: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
646: ((ReferenceTypeImpl) fClassFilterRefs.get(i)).write(
647: this , outData);
648: }
649: }
650: if (fThreadFilters != null) {
651: for (int i = 0; i < fThreadFilters.size(); i++) {
652: writeByte(MODIF_KIND_THREADONLY,
653: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
654: ((ThreadReferenceImpl) fThreadFilters.get(i)).write(
655: this , outData);
656: }
657: }
658: if (fCountFilters != null) {
659: for (int i = 0; i < fCountFilters.size(); i++) {
660: writeByte(MODIF_KIND_COUNT,
661: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
662: writeInt(((Integer) fCountFilters.get(i)).intValue(),
663: "count filter", outData); //$NON-NLS-1$
664: }
665: }
666: if (fInstanceFilters != null) {
667: for (int i = 0; i < fInstanceFilters.size(); i++) {
668: writeByte(MODIF_KIND_INSTANCE,
669: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
670: ((ObjectReferenceImpl) fInstanceFilters.get(i)).write(
671: this , outData);
672: }
673: }
674: if (fSourceNameFilters != null) {
675: if (supportsSourceNameFilters()) {
676: for (int i = 0; i < fSourceNameFilters.size(); i++) {
677: writeByte(MODIF_KIND_SOURCE_NAME_FILTER,
678: "modifier", modifierKindMap(), outData); //$NON-NLS-1$
679: writeString((String) fSourceNameFilters.get(i),
680: "modifier", outData); //$NON-NLS-1$
681: }
682: }
683: }
684: }
685:
686: /**
687: * Returns whether JDWP supports source name filters (a 1.6 feature).
688: *
689: * @return whether JDWP supports source name filters
690: */
691: private boolean supportsSourceNameFilters() {
692: return ((VirtualMachineImpl) virtualMachine())
693: .isJdwpVersionGreaterOrEqual(1, 6);
694: }
695:
696: /**
697: * Retrieves constant mappings.
698: */
699: public static void getConstantMaps() {
700: if (fStepSizeMap != null)
701: return;
702:
703: java.lang.reflect.Field[] fields = EventRequestImpl.class
704: .getDeclaredFields();
705: fStepSizeMap = new HashMap();
706: fStepDepthMap = new HashMap();
707: fSuspendPolicyMap = new HashMap();
708: fModifierKindMap = new HashMap();
709: for (int i = 0; i < fields.length; i++) {
710: java.lang.reflect.Field field = fields[i];
711: if ((field.getModifiers() & java.lang.reflect.Modifier.PUBLIC) == 0
712: || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0
713: || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0)
714: continue;
715:
716: try {
717: String name = field.getName();
718: Integer intValue = new Integer(field.getInt(null));
719: if (name.startsWith("STEP_SIZE_")) { //$NON-NLS-1$
720: name = name.substring(10);
721: fStepSizeMap.put(intValue, name);
722: } else if (name.startsWith("STEP_DEPTH_")) { //$NON-NLS-1$
723: name = name.substring(11);
724: fStepDepthMap.put(intValue, name);
725: } else if (name.startsWith("SUSPENDPOL_")) { //$NON-NLS-1$
726: name = name.substring(11);
727: fSuspendPolicyMap.put(intValue, name);
728: } else if (name.startsWith("MODIF_KIND_")) { //$NON-NLS-1$
729: name = name.substring(11);
730: fModifierKindMap.put(intValue, name);
731: }
732: } catch (IllegalAccessException e) {
733: // Will not occur for own class.
734: } catch (IllegalArgumentException e) {
735: // Should not occur.
736: // We should take care that all public static final constants
737: // in this class are numbers that are convertible to int.
738: }
739: }
740: }
741:
742: /**
743: * @return Returns a map with string representations of tags.
744: */
745: public static Map stepSizeMap() {
746: getConstantMaps();
747: return fStepSizeMap;
748: }
749:
750: /**
751: * @return Returns a map with string representations of tags.
752: */
753: public static Map stepDepthMap() {
754: getConstantMaps();
755: return fStepDepthMap;
756: }
757:
758: /**
759: * @return Returns a map with string representations of type tags.
760: */
761: public static Map suspendPolicyMap() {
762: getConstantMaps();
763: return fSuspendPolicyMap;
764: }
765:
766: /**
767: * @return Returns a map with string representations of type tags.
768: */
769: public static Map modifierKindMap() {
770: getConstantMaps();
771: return fModifierKindMap;
772: }
773:
774: class ExceptionFilter {
775: /** If non-null, specifies that exceptions which are instances of fExceptionFilterRef will be reported. */
776: ReferenceTypeImpl fException = null;
777: /** If true, caught exceptions will be reported. */
778: boolean fNotifyCaught = false;
779: /** If true, uncaught exceptions will be reported. */
780: boolean fNotifyUncaught = false;
781: }
782:
783: class ThreadStepFilter {
784: /** ThreadReference of thread in which to step. */
785: protected ThreadReferenceImpl fThread = null;
786: /** Size of each step. */
787: protected int fThreadStepSize;
788: /** Relative call stack limit. */
789: protected int fThreadStepDepth;
790: }
791: }
|