View Javadoc
1   /*
2    * Copyright (c) 1999, 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  
35  package com.sun.tools.example.debug.bdi;
36  
37  import com.sun.jdi.*;
38  import com.sun.jdi.request.EventRequest;
39  
40  abstract public class EventRequestSpec {
41  
42      static final int STATUS_UNRESOLVED = 1;
43      static final int STATUS_RESOLVED = 2;
44      static final int STATUS_ERROR = 3;
45  
46      static final Object specPropertyKey = "spec";
47  
48      final EventRequestSpecList specs;
49      final ReferenceTypeSpec refSpec;
50      EventRequest request = null;
51  
52      int status = STATUS_UNRESOLVED;
53  
54      EventRequestSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec) {
55          this.specs = specs;
56          this.refSpec = refSpec;
57      }
58  
59      void setRequest(EventRequest request) {
60          this.request = request;
61          request.putProperty(specPropertyKey, this);
62          request.enable();
63      }
64  
65      /**
66       * The 'refType' is known to match.
67       */
68      abstract void resolve(ReferenceType refType) throws Exception;
69  
70      abstract void notifySet(SpecListener listener, SpecEvent evt);
71      abstract void notifyDeferred(SpecListener listener, SpecEvent evt);
72      abstract void notifyResolved(SpecListener listener, SpecEvent evt);
73      abstract void notifyDeleted(SpecListener listener, SpecEvent evt);
74      abstract void notifyError(SpecListener listener, SpecErrorEvent evt);
75  
76      /**
77       * The 'refType' is known to match.
78       */
79      void resolveNotify(ReferenceType refType) {
80          try {
81              resolve(refType);
82              status = STATUS_RESOLVED;
83              specs.notifyResolved(this);
84          } catch(Exception exc) {
85              status = STATUS_ERROR;
86              specs.notifyError(this, exc);
87          }
88      }
89  
90      /**
91       * See if 'refType' matches and resolve.
92       */
93      void attemptResolve(ReferenceType refType) {
94          if (!isResolved() && refSpec.matches(refType)) {
95              resolveNotify(refType);
96          }
97      }
98  
99      void attemptImmediateResolve(VirtualMachine vm) {
100         // try to resolve immediately
101         for (ReferenceType refType : vm.allClasses()) {
102             if (refSpec.matches(refType)) {
103                 try {
104                     resolve(refType);
105                     status = STATUS_RESOLVED;
106                     specs.notifySet(this);
107                 } catch(Exception exc) {
108                     status = STATUS_ERROR;
109                     specs.notifyError(this, exc);
110                 }
111                 return;
112             }
113         }
114         specs.notifyDeferred(this);
115     }
116 
117     public EventRequest getEventRequest() {
118         return request;
119     }
120 
121     /**
122      * @return true if this spec has been resolved.
123      */
124     public boolean isResolved() {
125         return status == STATUS_RESOLVED;
126     }
127 
128     /**
129      * @return true if this spec has not yet been resolved.
130      */
131     public boolean isUnresolved() {
132         return status == STATUS_UNRESOLVED;
133     }
134 
135     /**
136      * @return true if this spec is unresolvable due to error.
137      */
138     public boolean isErroneous() {
139         return status == STATUS_ERROR;
140     }
141 
142     public String getStatusString() {
143         switch (status) {
144             case STATUS_RESOLVED:
145                 return "resolved";
146             case STATUS_UNRESOLVED:
147                 return "deferred";
148             case STATUS_ERROR:
149                 return "erroneous";
150         }
151         return "unknown";
152     }
153 
154     boolean isJavaIdentifier(String s) {
155         return Utils.isJavaIdentifier(s);
156     }
157 
158     public String errorMessageFor(Exception e) {
159         if (e instanceof IllegalArgumentException) {
160             return ("Invalid command syntax");
161         } else if (e instanceof RuntimeException) {
162             // A runtime exception that we were not expecting
163             throw (RuntimeException)e;
164         } else {
165             return ("Internal error; unable to set" + this);
166         }
167     }
168 }