001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.debugger.jpda.breakpoints;
043:
044: import java.beans.PropertyChangeEvent;
045: import java.beans.PropertyChangeListener;
046: import java.util.Map;
047: import java.util.WeakHashMap;
048:
049: import org.netbeans.api.debugger.Breakpoint;
050: import org.netbeans.api.debugger.Properties;
051: import org.netbeans.api.debugger.jpda.ClassLoadUnloadBreakpoint;
052: import org.netbeans.api.debugger.jpda.ExceptionBreakpoint;
053: import org.netbeans.api.debugger.jpda.FieldBreakpoint;
054: import org.netbeans.api.debugger.jpda.JPDABreakpoint;
055: import org.netbeans.api.debugger.jpda.LineBreakpoint;
056: import org.netbeans.api.debugger.jpda.MethodBreakpoint;
057: import org.netbeans.api.debugger.jpda.ThreadBreakpoint;
058:
059: /**
060: *
061: * @author Jan Jancura
062: */
063: public class BreakpointsReader implements Properties.Reader,
064: PropertyChangeListener {
065:
066: private Map<JPDABreakpoint, String> cachedClassNames = new WeakHashMap<JPDABreakpoint, String>();
067: private Map<JPDABreakpoint, String> cachedSourceRoots = new WeakHashMap<JPDABreakpoint, String>();
068:
069: public String[] getSupportedClassNames() {
070: return new String[] { JPDABreakpoint.class.getName(), };
071: }
072:
073: synchronized String findCachedClassName(JPDABreakpoint b) {
074: return cachedClassNames.get(b);
075: }
076:
077: synchronized String findCachedSourceRoot(JPDABreakpoint b) {
078: return cachedSourceRoots.get(b);
079: }
080:
081: void storeCachedClassName(JPDABreakpoint b, String className) {
082: synchronized (this ) {
083: if (b instanceof LineBreakpoint
084: && !cachedClassNames.containsKey(b)) {
085: // Line breakpoint, class name is cached for the first time.
086: // We need to listen on URL changes and clear the cache then.
087: b.addPropertyChangeListener(LineBreakpoint.PROP_URL,
088: this );
089: }
090: cachedClassNames.put(b, className);
091: }
092: PersistenceManager.storeBreakpoints();
093: }
094:
095: void storeCachedSourceRoot(JPDABreakpoint b, String sourceRoot) {
096: synchronized (this ) {
097: cachedSourceRoots.put(b, sourceRoot);
098: }
099: PersistenceManager.storeBreakpoints();
100: }
101:
102: public Object read(String typeID, Properties properties) {
103: JPDABreakpoint b = null;
104: // Read both LineBreakpoint and LineBreakpoint$LineBreakpointImpl
105: if (typeID.equals(LineBreakpoint.class.getName())
106: || typeID.equals(LineBreakpoint.class.getName()
107: + "$LineBreakpointImpl")) {
108: LineBreakpoint lb = LineBreakpoint.create(properties
109: .getString(LineBreakpoint.PROP_URL, null),
110: properties.getInt(LineBreakpoint.PROP_LINE_NUMBER,
111: 1));
112: lb.setCondition(properties.getString(
113: LineBreakpoint.PROP_CONDITION, ""));
114: lb.setPreferredClassName(properties.getString(
115: LineBreakpoint.PROP_PREFERRED_CLASS_NAME, null));
116: synchronized (this ) {
117: cachedClassNames.put(lb, properties.getString(
118: "className", null));
119: // We need to listen on URL changes and clear the cache then.
120: lb.addPropertyChangeListener(LineBreakpoint.PROP_URL,
121: this );
122: cachedSourceRoots.put(lb, properties.getString(
123: "sourceRoot", null));
124: }
125: b = lb;
126: }
127: if (typeID.equals(MethodBreakpoint.class.getName())
128: || typeID.equals(MethodBreakpoint.class.getName()
129: + "$MethodBreakpointImpl")) {
130: MethodBreakpoint mb = MethodBreakpoint.create();
131: mb
132: .setClassFilters((String[]) properties.getArray(
133: MethodBreakpoint.PROP_CLASS_FILTERS,
134: new String[0]));
135: mb.setClassExclusionFilters((String[]) properties.getArray(
136: MethodBreakpoint.PROP_CLASS_EXCLUSION_FILTERS,
137: new String[0]));
138: mb.setMethodName(properties.getString(
139: MethodBreakpoint.PROP_METHOD_NAME, ""));
140: mb.setMethodSignature(properties.getString(
141: MethodBreakpoint.PROP_METHOD_SIGNATURE, null));
142: mb.setCondition(properties.getString(
143: MethodBreakpoint.PROP_CONDITION, ""));
144: mb.setBreakpointType(properties.getInt(
145: MethodBreakpoint.PROP_BREAKPOINT_TYPE,
146: MethodBreakpoint.TYPE_METHOD_ENTRY));
147: synchronized (this ) {
148: cachedSourceRoots.put(mb, properties.getString(
149: "sourceRoot", null));
150: }
151: b = mb;
152: }
153: if (typeID.equals(ClassLoadUnloadBreakpoint.class.getName())) {
154: ClassLoadUnloadBreakpoint cb = ClassLoadUnloadBreakpoint
155: .create(properties
156: .getInt(
157: ClassLoadUnloadBreakpoint.PROP_BREAKPOINT_TYPE,
158: ClassLoadUnloadBreakpoint.TYPE_CLASS_LOADED));
159: cb.setClassFilters((String[]) properties.getArray(
160: ClassLoadUnloadBreakpoint.PROP_CLASS_FILTERS,
161: new String[0]));
162: cb
163: .setClassExclusionFilters((String[]) properties
164: .getArray(
165: ClassLoadUnloadBreakpoint.PROP_CLASS_EXCLUSION_FILTERS,
166: new String[0]));
167: synchronized (this ) {
168: cachedSourceRoots.put(cb, properties.getString(
169: "sourceRoot", null));
170: }
171: b = cb;
172: }
173: if (typeID.equals(ExceptionBreakpoint.class.getName())) {
174: ExceptionBreakpoint eb = ExceptionBreakpoint
175: .create(
176: properties
177: .getString(
178: ExceptionBreakpoint.PROP_EXCEPTION_CLASS_NAME,
179: null),
180: properties
181: .getInt(
182: ExceptionBreakpoint.PROP_CATCH_TYPE,
183: ExceptionBreakpoint.TYPE_EXCEPTION_CATCHED_UNCATCHED));
184: eb.setCondition(properties.getString(
185: ExceptionBreakpoint.PROP_CONDITION, ""));
186: String[] classFilters = (String[]) properties.getArray(
187: ExceptionBreakpoint.PROP_CLASS_FILTERS, null);
188: if (classFilters != null) {
189: eb.setClassFilters(classFilters);
190: }
191: String[] classExclusionFilters = (String[]) properties
192: .getArray(
193: ExceptionBreakpoint.PROP_CLASS_EXCLUSION_FILTERS,
194: null);
195: if (classExclusionFilters != null) {
196: eb.setClassExclusionFilters(classExclusionFilters);
197: }
198: synchronized (this ) {
199: cachedSourceRoots.put(eb, properties.getString(
200: "sourceRoot", null));
201: }
202: b = eb;
203: }
204: if (typeID.equals(FieldBreakpoint.class.getName())
205: || typeID.equals(FieldBreakpoint.class.getName()
206: + "$FieldBreakpointImpl")) {
207: FieldBreakpoint fb = FieldBreakpoint.create(properties
208: .getString(FieldBreakpoint.PROP_CLASS_NAME, null),
209: properties.getString(
210: FieldBreakpoint.PROP_FIELD_NAME, null),
211: properties.getInt(
212: FieldBreakpoint.PROP_BREAKPOINT_TYPE,
213: FieldBreakpoint.TYPE_ACCESS));
214: fb.setCondition(properties.getString(
215: FieldBreakpoint.PROP_CONDITION, ""));
216: synchronized (this ) {
217: cachedSourceRoots.put(fb, properties.getString(
218: "sourceRoot", null));
219: }
220: b = fb;
221: }
222: if (typeID.equals(ThreadBreakpoint.class.getName())) {
223: ThreadBreakpoint tb = ThreadBreakpoint.create();
224: tb.setBreakpointType(properties.getInt(
225: ThreadBreakpoint.PROP_BREAKPOINT_TYPE,
226: ThreadBreakpoint.TYPE_THREAD_STARTED_OR_DEATH));
227: b = tb;
228: }
229: assert b != null : "Unknown breakpoint type: \"" + typeID
230: + "\"";
231: b.setPrintText(properties.getString(
232: JPDABreakpoint.PROP_PRINT_TEXT, ""));
233: b.setGroupName(properties.getString(
234: JPDABreakpoint.PROP_GROUP_NAME, ""));
235: b.setSuspend(properties.getInt(JPDABreakpoint.PROP_SUSPEND,
236: JPDABreakpoint.SUSPEND_ALL));
237: int hitCountFilter = properties.getInt(
238: JPDABreakpoint.PROP_HIT_COUNT_FILTER, 0);
239: Breakpoint.HIT_COUNT_FILTERING_STYLE hitCountFilteringStyle;
240: if (hitCountFilter > 0) {
241: hitCountFilteringStyle = Breakpoint.HIT_COUNT_FILTERING_STYLE
242: .values()[properties.getInt(
243: JPDABreakpoint.PROP_HIT_COUNT_FILTER + "_style", 0)]; // NOI18N
244: } else {
245: hitCountFilteringStyle = null;
246: }
247: b.setHitCountFilter(hitCountFilter, hitCountFilteringStyle);
248: if (properties.getBoolean(JPDABreakpoint.PROP_ENABLED, true))
249: b.enable();
250: else
251: b.disable();
252: return b;
253: }
254:
255: public void write(Object object, Properties properties) {
256: JPDABreakpoint b = (JPDABreakpoint) object;
257: properties.setString(JPDABreakpoint.PROP_PRINT_TEXT, b
258: .getPrintText());
259: properties.setString(JPDABreakpoint.PROP_GROUP_NAME, b
260: .getGroupName());
261: properties.setInt(JPDABreakpoint.PROP_SUSPEND, b.getSuspend());
262: properties.setBoolean(JPDABreakpoint.PROP_ENABLED, b
263: .isEnabled());
264: properties.setInt(JPDABreakpoint.PROP_HIT_COUNT_FILTER, b
265: .getHitCountFilter());
266: Breakpoint.HIT_COUNT_FILTERING_STYLE style = b
267: .getHitCountFilteringStyle();
268: properties.setInt(JPDABreakpoint.PROP_HIT_COUNT_FILTER
269: + "_style", style != null ? style.ordinal() : 0); // NOI18N
270:
271: if (object instanceof LineBreakpoint) {
272: LineBreakpoint lb = (LineBreakpoint) object;
273: properties.setString(LineBreakpoint.PROP_URL, lb.getURL());
274: properties.setInt(LineBreakpoint.PROP_LINE_NUMBER, lb
275: .getLineNumber());
276: properties.setString(LineBreakpoint.PROP_CONDITION, lb
277: .getCondition());
278: properties.setString(
279: LineBreakpoint.PROP_PREFERRED_CLASS_NAME, lb
280: .getPreferredClassName());
281: properties.setString("className", findCachedClassName(lb));
282: properties
283: .setString("sourceRoot", findCachedSourceRoot(lb));
284: return;
285: } else if (object instanceof MethodBreakpoint) {
286: MethodBreakpoint mb = (MethodBreakpoint) object;
287: properties.setArray(MethodBreakpoint.PROP_CLASS_FILTERS, mb
288: .getClassFilters());
289: properties.setArray(
290: MethodBreakpoint.PROP_CLASS_EXCLUSION_FILTERS, mb
291: .getClassExclusionFilters());
292: properties.setString(MethodBreakpoint.PROP_METHOD_NAME, mb
293: .getMethodName());
294: properties.setString(
295: MethodBreakpoint.PROP_METHOD_SIGNATURE, mb
296: .getMethodSignature());
297: properties.setString(MethodBreakpoint.PROP_CONDITION, mb
298: .getCondition());
299: properties.setInt(MethodBreakpoint.PROP_BREAKPOINT_TYPE, mb
300: .getBreakpointType());
301: properties
302: .setString("sourceRoot", findCachedSourceRoot(mb));
303: return;
304: } else if (object instanceof ClassLoadUnloadBreakpoint) {
305: ClassLoadUnloadBreakpoint cb = (ClassLoadUnloadBreakpoint) object;
306: properties.setArray(
307: ClassLoadUnloadBreakpoint.PROP_CLASS_FILTERS, cb
308: .getClassFilters());
309: properties
310: .setArray(
311: ClassLoadUnloadBreakpoint.PROP_CLASS_EXCLUSION_FILTERS,
312: cb.getClassExclusionFilters());
313: properties.setInt(
314: ClassLoadUnloadBreakpoint.PROP_BREAKPOINT_TYPE, cb
315: .getBreakpointType());
316: properties
317: .setString("sourceRoot", findCachedSourceRoot(cb));
318: return;
319: } else if (object instanceof ExceptionBreakpoint) {
320: ExceptionBreakpoint eb = (ExceptionBreakpoint) object;
321: properties.setString(
322: ExceptionBreakpoint.PROP_EXCEPTION_CLASS_NAME, eb
323: .getExceptionClassName());
324: properties.setInt(ExceptionBreakpoint.PROP_CATCH_TYPE, eb
325: .getCatchType());
326: properties.setArray(ExceptionBreakpoint.PROP_CLASS_FILTERS,
327: eb.getClassFilters());
328: properties.setArray(
329: ExceptionBreakpoint.PROP_CLASS_EXCLUSION_FILTERS,
330: eb.getClassExclusionFilters());
331: properties.setString(ExceptionBreakpoint.PROP_CONDITION, eb
332: .getCondition());
333: properties
334: .setString("sourceRoot", findCachedSourceRoot(eb));
335: return;
336: } else if (object instanceof FieldBreakpoint) {
337: FieldBreakpoint fb = (FieldBreakpoint) object;
338: properties.setString(FieldBreakpoint.PROP_CLASS_NAME, fb
339: .getClassName());
340: properties.setString(FieldBreakpoint.PROP_FIELD_NAME, fb
341: .getFieldName());
342: properties.setString(FieldBreakpoint.PROP_CONDITION, fb
343: .getCondition());
344: properties.setInt(FieldBreakpoint.PROP_BREAKPOINT_TYPE, fb
345: .getBreakpointType());
346: properties
347: .setString("sourceRoot", findCachedSourceRoot(fb));
348: return;
349: } else if (object instanceof ThreadBreakpoint) {
350: ThreadBreakpoint tb = (ThreadBreakpoint) object;
351: properties.setInt(ThreadBreakpoint.PROP_BREAKPOINT_TYPE, tb
352: .getBreakpointType());
353: return;
354: }
355: return;
356: }
357:
358: public void propertyChange(PropertyChangeEvent evt) {
359: if (LineBreakpoint.PROP_URL.equals(evt.getPropertyName())) {
360: LineBreakpoint lb = (LineBreakpoint) evt.getSource();
361: storeCachedClassName(lb, null);
362: }
363: }
364:
365: }
|