210 lines · 7.6 KB · Java
RawDownload
/* * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.example.debug.tty; import com.sun.jdi.*;import com.sun.jdi.request.EventRequest;import com.sun.jdi.request.ExceptionRequest;import com.sun.jdi.request.ClassPrepareRequest;import com.sun.jdi.event.ClassPrepareEvent;import java.util.ArrayList; abstract class EventRequestSpec {     final ReferenceTypeSpec refSpec;     int suspendPolicy = EventRequest.SUSPEND_ALL;     EventRequest resolved = null;    ClassPrepareRequest prepareRequest = null;     EventRequestSpec(ReferenceTypeSpec refSpec) {        this.refSpec = refSpec;    }     /**     * The 'refType' is known to match, return the EventRequest.     */    abstract EventRequest resolveEventRequest(ReferenceType refType)                                           throws Exception;     /**     * @return If this EventRequestSpec matches the 'refType'     * return the cooresponding EventRequest.  Otherwise     * return null.     */    synchronized EventRequest resolve(ClassPrepareEvent event) throws Exception {        if ((resolved == null) &&            (prepareRequest != null) &&            prepareRequest.equals(event.request())) {             resolved = resolveEventRequest(event.referenceType());            prepareRequest.disable();            Env.vm().eventRequestManager().deleteEventRequest(prepareRequest);            prepareRequest = null;             if (refSpec instanceof PatternReferenceTypeSpec) {                PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;                if (! prs.isUnique()){                    /*                     * Class pattern event requests are never                     * considered "resolved", since future class loads                     * might also match.                     * Create and enable a new ClassPrepareRequest to                     * keep trying to resolve.                     */                    resolved = null;                    prepareRequest = refSpec.createPrepareRequest();                    prepareRequest.enable();                }            }        }        return resolved;    }     synchronized void remove() {        if (isResolved()) {            Env.vm().eventRequestManager().deleteEventRequest(resolved());        }        if (refSpec instanceof PatternReferenceTypeSpec) {            PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;            if (! prs.isUnique()){                /*                 * This is a class pattern.  Track down and delete                 * all EventRequests matching this spec.                 * Note: Class patterns apply only to ExceptionRequests,                 * so that is all we need to examine.                 */                ArrayList<ExceptionRequest> deleteList = new ArrayList<ExceptionRequest>();                for (ExceptionRequest er :                         Env.vm().eventRequestManager().exceptionRequests()) {                    if (prs.matches(er.exception())) {                        deleteList.add (er);                    }                }                Env.vm().eventRequestManager().deleteEventRequests(deleteList);            }        }    }     private EventRequest resolveAgainstPreparedClasses() throws Exception {        for (ReferenceType refType : Env.vm().allClasses()) {            if (refType.isPrepared() && refSpec.matches(refType)) {                resolved = resolveEventRequest(refType);            }        }        return resolved;    }     synchronized EventRequest resolveEagerly() throws Exception {        try {            if (resolved == null) {                /*                 * Not resolved.  Schedule a prepare request so we                 * can resolve later.                 */                prepareRequest = refSpec.createPrepareRequest();                prepareRequest.enable();                 // Try to resolve in case the class is already loaded.                resolveAgainstPreparedClasses();                if (resolved != null) {                    prepareRequest.disable();                    Env.vm().eventRequestManager().deleteEventRequest(prepareRequest);                    prepareRequest = null;                }            }            if (refSpec instanceof PatternReferenceTypeSpec) {                PatternReferenceTypeSpec prs = (PatternReferenceTypeSpec)refSpec;                if (! prs.isUnique()){                    /*                     * Class pattern event requests are never                     * considered "resolved", since future class loads                     * might also match.  Create a new                     * ClassPrepareRequest if necessary and keep                     * trying to resolve.                     */                    resolved = null;                    if (prepareRequest == null) {                        prepareRequest = refSpec.createPrepareRequest();                        prepareRequest.enable();                    }                }            }        } catch (VMNotConnectedException e) {            // Do nothing. Another resolve will be attempted when the            // VM is started.        }        return resolved;    }     /**     * @return the eventRequest this spec has been resolved to,     * null if so far unresolved.     */    EventRequest resolved() {        return resolved;    }     /**     * @return true if this spec has been resolved.     */    boolean isResolved() {        return resolved != null;    }     protected boolean isJavaIdentifier(String s) {        if (s.length() == 0) {            return false;        }         int cp = s.codePointAt(0);        if (! Character.isJavaIdentifierStart(cp)) {            return false;        }         for (int i = Character.charCount(cp); i < s.length(); i += Character.charCount(cp)) {            cp = s.codePointAt(i);            if (! Character.isJavaIdentifierPart(cp)) {                return false;            }        }         return true;    }     String errorMessageFor(Exception e) {        if (e instanceof IllegalArgumentException) {            return (MessageOutput.format("Invalid command syntax"));        } else if (e instanceof RuntimeException) {            // A runtime exception that we were not expecting            throw (RuntimeException)e;        } else {            return (MessageOutput.format("Internal error; unable to set",                                         this.refSpec.toString()));        }    }}