1/*
2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * This source code is provided to illustrate the usage of a given feature
28 * or technique and has been deliberately simplified. Additional steps
29 * required for a production-quality application, such as security checks,
30 * input validation and proper error handling, might not be present in
31 * this sample code.
32 */
33
34
35package com.sun.tools.example.debug.tty;
36
37import com.sun.jdi.request.EventRequest;
38import com.sun.jdi.event.ClassPrepareEvent;
39
40import java.util.ArrayList;
41import java.util.Collections;
42import java.util.List;
43
44class EventRequestSpecList {
45
46    private static final int statusResolved = 1;
47    private static final int statusUnresolved = 2;
48    private static final int statusError = 3;
49
50    // all specs
51    private List<EventRequestSpec> eventRequestSpecs = Collections.synchronizedList(
52                                                  new ArrayList<EventRequestSpec>());
53
54    EventRequestSpecList() {
55    }
56
57    /**
58     * Resolve all deferred eventRequests waiting for 'refType'.
59     * @return true if it completes successfully, false on error.
60     */
61    boolean resolve(ClassPrepareEvent event) {
62        boolean failure = false;
63        synchronized(eventRequestSpecs) {
64            for (EventRequestSpec spec : eventRequestSpecs) {
65                if (!spec.isResolved()) {
66                    try {
67                        EventRequest eventRequest = spec.resolve(event);
68                        if (eventRequest != null) {
69                            MessageOutput.println("Set deferred", spec.toString());
70                        }
71                    } catch (Exception e) {
72                        MessageOutput.println("Unable to set deferred",
73                                              new Object [] {spec.toString(),
74                                                             spec.errorMessageFor(e)});
75                        failure = true;
76                    }
77                }
78            }
79        }
80        return !failure;
81    }
82
83    void resolveAll() {
84        for (EventRequestSpec spec : eventRequestSpecs) {
85            try {
86                EventRequest eventRequest = spec.resolveEagerly();
87                if (eventRequest != null) {
88                    MessageOutput.println("Set deferred", spec.toString());
89                }
90            } catch (Exception e) {
91            }
92        }
93    }
94
95    boolean addEagerlyResolve(EventRequestSpec spec) {
96        try {
97            eventRequestSpecs.add(spec);
98            EventRequest eventRequest = spec.resolveEagerly();
99            if (eventRequest != null) {
100                MessageOutput.println("Set", spec.toString());
101            }
102            return true;
103        } catch (Exception exc) {
104            MessageOutput.println("Unable to set",
105                                  new Object [] {spec.toString(),
106                                                 spec.errorMessageFor(exc)});
107            return false;
108        }
109    }
110
111    BreakpointSpec createBreakpoint(String classPattern, int line)
112        throws ClassNotFoundException {
113        ReferenceTypeSpec refSpec =
114            new PatternReferenceTypeSpec(classPattern);
115        return new BreakpointSpec(refSpec, line);
116    }
117
118    BreakpointSpec createBreakpoint(String classPattern,
119                                 String methodId,
120                                    List<String> methodArgs)
121                                throws MalformedMemberNameException,
122                                       ClassNotFoundException {
123        ReferenceTypeSpec refSpec =
124            new PatternReferenceTypeSpec(classPattern);
125        return new BreakpointSpec(refSpec, methodId, methodArgs);
126    }
127
128    EventRequestSpec createExceptionCatch(String classPattern,
129                                          boolean notifyCaught,
130                                          boolean notifyUncaught)
131                                            throws ClassNotFoundException {
132        ReferenceTypeSpec refSpec =
133            new PatternReferenceTypeSpec(classPattern);
134        return new ExceptionSpec(refSpec, notifyCaught, notifyUncaught);
135    }
136
137    WatchpointSpec createAccessWatchpoint(String classPattern,
138                                       String fieldId)
139                                      throws MalformedMemberNameException,
140                                             ClassNotFoundException {
141        ReferenceTypeSpec refSpec =
142            new PatternReferenceTypeSpec(classPattern);
143        return new AccessWatchpointSpec(refSpec, fieldId);
144    }
145
146    WatchpointSpec createModificationWatchpoint(String classPattern,
147                                       String fieldId)
148                                      throws MalformedMemberNameException,
149                                             ClassNotFoundException {
150        ReferenceTypeSpec refSpec =
151            new PatternReferenceTypeSpec(classPattern);
152        return new ModificationWatchpointSpec(refSpec, fieldId);
153    }
154
155    boolean delete(EventRequestSpec proto) {
156        synchronized (eventRequestSpecs) {
157            int inx = eventRequestSpecs.indexOf(proto);
158            if (inx != -1) {
159                EventRequestSpec spec = eventRequestSpecs.get(inx);
160                spec.remove();
161                eventRequestSpecs.remove(inx);
162                return true;
163            } else {
164                return false;
165            }
166        }
167    }
168
169    List<EventRequestSpec> eventRequestSpecs() {
170       // We need to make a copy to avoid synchronization problems
171        synchronized (eventRequestSpecs) {
172            return new ArrayList<EventRequestSpec>(eventRequestSpecs);
173        }
174    }
175}
176