Source Code Cross Referenced for DebuggerManager.java in  » IDE-Netbeans » ant » org » netbeans » api » debugger » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » ant » org.netbeans.api.debugger 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.api.debugger;
0043:
0044:        import java.beans.*;
0045:        import java.util.*;
0046:        import java.util.HashMap;
0047:
0048:        import org.openide.util.Cancellable;
0049:        import org.openide.util.Task;
0050:
0051:        import org.netbeans.spi.debugger.ContextProvider;
0052:        import org.netbeans.spi.debugger.DelegatingDebuggerEngineProvider;
0053:        import org.netbeans.spi.debugger.DelegatingSessionProvider;
0054:        import org.netbeans.spi.debugger.DebuggerEngineProvider;
0055:        import org.netbeans.spi.debugger.SessionProvider;
0056:
0057:        /**
0058:         * The root class of Debugger APIs. DebuggerManager manages list of
0059:         * {@link org.netbeans.api.debugger.Session}s, 
0060:         * {@link org.netbeans.api.debugger.Breakpoint}s and
0061:         * {@link org.netbeans.api.debugger.Watch}es.
0062:         *  
0063:         *
0064:         * <p><br><table border="1" cellpadding="3" cellspacing="0" width="100%">
0065:         * <tbody><tr bgcolor="#ccccff">
0066:         * <td colspan="2"><font size="+2"><b>Description </b></font></td>
0067:         * </tr><tr><td align="left" valign="top" width="1%"><font size="+1">
0068:         * <b>Functionality</b></font></td><td> 
0069:         *
0070:         * <b>Start & finish debugging:</b>
0071:         *    DebuggerManager manages a process of starting a new debugging (
0072:         *    {@link #startDebugging}). It cooperates with all installed
0073:         *    {@link org.netbeans.spi.debugger.DebuggerEngineProvider}s to create a new 
0074:         *    {@link org.netbeans.api.debugger.Session} (or Sessions) and a new 
0075:         *    {@link org.netbeans.api.debugger.DebuggerEngine} (or Engines).
0076:         *    It supports kill all sessions too ({@link #finishAllSessions}).
0077:         *
0078:         * <br><br>
0079:         * <b>Sessions management:</b>
0080:         *    DebuggerManager keeps list of all 
0081:         *    {@link org.netbeans.api.debugger.Session}s ({@link #getSessions}),
0082:         *    and manages current session ({@link #getCurrentSession},
0083:         *    {@link #setCurrentSession}).
0084:         *
0085:         * <br><br>
0086:         * <b>Engine management:</b>
0087:         *    DebuggerManager provides current engine ({@link #getCurrentEngine}).
0088:         *    Current engine is derivated from current session. So,
0089:         *    <i>
0090:         *    debuggerManager.getCurrentEngine () == debuggerManager.
0091:         *    getCurrentSession.getCurrentEngine ()
0092:         *    </i>
0093:         *    should be always true.
0094:         *
0095:         * <br><br>
0096:         * <b>Breakpoints management:</b>
0097:         *    DebuggerManager keeps list of all shared breakpoints 
0098:         *    ({@link #getBreakpoints}).
0099:         *    Breakpoint can be added ({@link #addBreakpoint}) and removed
0100:         *    ({@link #removeBreakpoint}).
0101:         *
0102:         * <br><br>
0103:         * <b>Watches management:</b>
0104:         *    DebuggerManager keeps list of all shared watches ({@link #getWatches}).
0105:         *    Watch can be created & added ({@link #createWatch}).
0106:         *
0107:         * <br><br>
0108:         * <b>Support for listening:</b>
0109:         *    DebuggerManager propagates all changes to two type of listeners - general
0110:         *    {@link java.beans.PropertyChangeListener} and specific
0111:         *    {@link org.netbeans.api.debugger.DebuggerManagerListener}.
0112:         *
0113:         * <br>
0114:         * </td></tr><tr><td align="left" valign="top" width="1%"><font size="+1">
0115:         * <b>Clinents / Providers</b></font></td><td> 
0116:         *
0117:         * DebuggerCore module should be the only one provider of this abstract class.
0118:         * This class should be called from debugger plug-in modules and from debugger
0119:         * UI modules. 
0120:         * 
0121:         * <br>
0122:         * </td></tr><tr><td align="left" valign="top" width="1%"><font size="+1">
0123:         * <b>Lifecycle</b></font></td><td> 
0124:         *
0125:         * The only one instance of DebuggerManager should exist, and it should be 
0126:         * created in {@link #getDebuggerManager} method.
0127:         * 
0128:         * </td></tr><tr><td align="left" valign="top" width="1%"><font size="+1">
0129:         * <b>Evolution</b></font></td><td>
0130:         *
0131:         * No method should be removed from this class, but some functionality can 
0132:         * be added.
0133:         *
0134:         * </td></tr></tbody></table>
0135:         *
0136:         * @author Jan Jancura
0137:         */
0138:        public final class DebuggerManager implements  ContextProvider {
0139:
0140:            // TODO: deprecate all these properties. They are useless, since there are
0141:            //       dedicated methods in DebuggerManagerListener
0142:
0143:            // OR: Remove DebuggerManagerListener and use just the properties.
0144:            // - probably not possible because of initBreakpoints() method.
0145:
0146:            /** Name of property for the set of breakpoints in the system. */
0147:            public static final String PROP_BREAKPOINTS_INIT = "breakpointsInit"; // NOI18N
0148:
0149:            /** Name of property for the set of breakpoints in the system. */
0150:            public static final String PROP_BREAKPOINTS = "breakpoints"; // NOI18N
0151:
0152:            /** Name of property for current debugger engine. */
0153:            public static final String PROP_CURRENT_ENGINE = "currentEngine";
0154:
0155:            /** Name of property for current debugger session. */
0156:            public static final String PROP_CURRENT_SESSION = "currentSession";
0157:
0158:            /** Name of property for set of running debugger sessions. */
0159:            public static final String PROP_SESSIONS = "sessions";
0160:
0161:            /** Name of property for set of running debugger engines. */
0162:            public static final String PROP_DEBUGGER_ENGINES = "debuggerEngines";
0163:
0164:            /** Name of property for the set of watches in the system. */
0165:            public static final String PROP_WATCHES = "watches"; // NOI18N
0166:
0167:            /** Name of property for the set of watches in the system. */
0168:            public static final String PROP_WATCHES_INIT = "watchesInit"; // NOI18N
0169:
0170:            private static DebuggerManager debuggerManager;
0171:            private Session currentSession;
0172:            private DebuggerEngine currentEngine;
0173:            private List sessions = new ArrayList();
0174:            private Set engines = new HashSet();
0175:            private Vector breakpoints = new Vector();
0176:            private boolean breakpointsInitializing = false;
0177:            private boolean breakpointsInitialized = false;
0178:            private Vector watches = new Vector();
0179:            private boolean watchesInitialized = false;
0180:            private SessionListener sessionListener = new SessionListener();
0181:            private Vector listeners = new Vector();
0182:            private HashMap listenersMap = new HashMap();
0183:            private ActionsManager actionsManager = null;
0184:
0185:            private Lookup lookup = new Lookup.MetaInf(null);
0186:
0187:            //private ModuleUnloadListeners             moduleUnloadListeners = new ModuleUnloadListeners();
0188:
0189:            /**
0190:             * Returns default instance of DebuggerManager.
0191:             *
0192:             * @return default instance of DebuggerManager
0193:             */
0194:            public static synchronized DebuggerManager getDebuggerManager() {
0195:                if (debuggerManager == null)
0196:                    debuggerManager = new DebuggerManager();
0197:                return debuggerManager;
0198:            }
0199:
0200:            /**
0201:             * Creates a new instance of DebuggerManager.
0202:             * It's called from a synchronized block, do not call any foreign code from here.
0203:             */
0204:            private DebuggerManager() {
0205:            }
0206:
0207:            public synchronized ActionsManager getActionsManager() {
0208:                if (actionsManager == null)
0209:                    actionsManager = new ActionsManager(lookup);
0210:                return actionsManager;
0211:            }
0212:
0213:            // lookup management .............................................
0214:
0215:            /**
0216:             * Returns list of services of given type from given folder.
0217:             *
0218:             * @param service a type of service to look for
0219:             * @return list of services of given type
0220:             */
0221:            public <T> List<? extends T> lookup(String folder, Class<T> service) {
0222:                return lookup.lookup(folder, service);
0223:            }
0224:
0225:            /**
0226:             * Returns one service of given type from given folder.
0227:             *
0228:             * @param service a type of service to look for
0229:             * @return ne service of given type
0230:             */
0231:            public <T> T lookupFirst(String folder, Class<T> service) {
0232:                return lookup.lookupFirst(folder, service);
0233:            }
0234:
0235:            /**
0236:             * Join two lookups together.
0237:             * The result will merge the lookups.
0238:             * The result of its {@link #lookup} method will additionally implement {@link Customizer}.
0239:             * @param cp1 first lookup
0240:             * @param cp2 second lookup
0241:             * @return a merger of the two
0242:             * @since org.netbeans.api.debugger/1 1.13
0243:             */
0244:            public static ContextProvider join(ContextProvider cp1,
0245:                    ContextProvider cp2) {
0246:                return new Lookup.Compound(cp1, cp2);
0247:            }
0248:
0249:            // session / engine management .............................................
0250:
0251:            /** 
0252:             * Start a new debugging for given 
0253:             * {@link org.netbeans.api.debugger.DebuggerInfo}. DebuggerInfo provides
0254:             * information needed to start new debugging. DebuggerManager finds
0255:             * all {@link org.netbeans.spi.debugger.SessionProvider}s and 
0256:             *  {@link org.netbeans.spi.debugger.DelegatingSessionProvider}s
0257:             * installed for given DebuggerInfo, and creates a new 
0258:             * {@link Session}(s). 
0259:             * After that it looks for all 
0260:             * {@link org.netbeans.spi.debugger.DebuggerEngineProvider}s and 
0261:             * {@link org.netbeans.spi.debugger.DelegatingDebuggerEngineProvider}s
0262:             * installed for Session, and crates a new 
0263:             * {@link DebuggerEngine}(s).
0264:             * <br>
0265:             * If the implementation of ACTION_START providers support cancellation (implements {@link Cancellable}),
0266:             * this startup sequence can be canceled via Thread.interrupt() while
0267:             * startDebugging() method is waiting for the action providers.
0268:             *
0269:             * @param info debugger startup info
0270:             * @return DebuggerEngines started for given info
0271:             */
0272:            public DebuggerEngine[] startDebugging(DebuggerInfo info) {
0273:                //S ystem.out.println("@StartDebugging info: " + info);
0274:
0275:                // init sessions
0276:                ArrayList sessionProviders = new ArrayList();
0277:                ArrayList engines = new ArrayList();
0278:                Lookup l = info.getLookup();
0279:                Lookup l2 = info.getLookup();
0280:                synchronized (l) {
0281:                    sessionProviders.addAll(l.lookup(null,
0282:                            SessionProvider.class));
0283:                    sessionProviders.addAll(l.lookup(null,
0284:                            DelegatingSessionProvider.class));
0285:                }
0286:                Session sessionToStart = null;
0287:                int i, k = sessionProviders.size();
0288:                for (i = 0; i < k; i++) {
0289:                    Session s = null;
0290:                    if (sessionProviders.get(i) instanceof  DelegatingSessionProvider) {
0291:                        s = ((DelegatingSessionProvider) sessionProviders
0292:                                .get(i)).getSession(info);
0293:                        l = new Lookup.Compound(l, s.privateLookup);
0294:                        //S ystem.out.println("@  StartDebugging DelegaingSession: " + s);
0295:                    } else {
0296:                        SessionProvider sp = (SessionProvider) sessionProviders
0297:                                .get(i);
0298:                        s = new Session(sp.getSessionName(), sp
0299:                                .getLocationName(), sp.getTypeID(), sp
0300:                                .getServices(), l);
0301:                        sessionToStart = s;
0302:                        l = s.getLookup();
0303:                        l2 = s.getLookup();
0304:                        addSession(s);
0305:                        //S ystem.out.println("@  StartDebugging new Session: " + s);
0306:                    }
0307:
0308:                    // init DebuggerEngines
0309:                    ArrayList engineProviders = new ArrayList();
0310:                    synchronized (l2) {
0311:                        engineProviders.addAll(l2.lookup(null,
0312:                                DebuggerEngineProvider.class));
0313:                        engineProviders.addAll(l2.lookup(null,
0314:                                DelegatingDebuggerEngineProvider.class));
0315:                    }
0316:                    int j, jj = engineProviders.size();
0317:                    for (j = 0; j < jj; j++) {
0318:                        DebuggerEngine engine = null;
0319:                        String[] languages = null;
0320:                        if (engineProviders.get(j) instanceof  DebuggerEngineProvider) {
0321:                            DebuggerEngineProvider ep = (DebuggerEngineProvider) engineProviders
0322:                                    .get(j);
0323:                            Object[] services = ep.getServices();
0324:                            engine = new DebuggerEngine(
0325:                                    ((DebuggerEngineProvider) engineProviders
0326:                                            .get(j)).getEngineTypeID(), s,
0327:                                    services, l);
0328:                            languages = ep.getLanguages();
0329:                            ep.setDestructor(engine.new Destructor());
0330:                            engines.add(engine);
0331:                            //S ystem.out.println("@    StartDebugging new Engine: " + engine);
0332:                        } else {
0333:                            DelegatingDebuggerEngineProvider dep = (DelegatingDebuggerEngineProvider) engineProviders
0334:                                    .get(j);
0335:                            languages = dep.getLanguages();
0336:                            engine = dep.getEngine();
0337:                            dep.setDestructor(engine.new Destructor());
0338:                            //S ystem.out.println("@    StartDebugging DelegatingEngine: " + engine);
0339:                        }
0340:                        int w, ww = languages.length;
0341:                        for (w = 0; w < ww; w++)
0342:                            s.addLanguage(languages[w], engine);
0343:                    }
0344:                }
0345:
0346:                k = engines.size();
0347:                for (i = 0; i < k; i++) {
0348:                    if (Thread.interrupted()) {
0349:                        break;
0350:                    }
0351:                    Task task = ((DebuggerEngine) engines.get(i))
0352:                            .getActionsManager().postAction(
0353:                                    ActionsManager.ACTION_START);
0354:                    if (task instanceof  Cancellable) {
0355:                        try {
0356:                            task.waitFinished(0);
0357:                        } catch (InterruptedException iex) {
0358:                            if (((Cancellable) task).cancel()) {
0359:                                break;
0360:                            } else {
0361:                                task.waitFinished();
0362:                            }
0363:                        }
0364:                    } else {
0365:                        task.waitFinished();
0366:                    }
0367:                }
0368:                if (i < k) { // It was canceled
0369:                    int n = i + 1;
0370:                    for (i = 0; i < k; i++) {
0371:                        ActionsManager am = ((DebuggerEngine) engines.get(i))
0372:                                .getActionsManager();
0373:                        if (i < (n - 1))
0374:                            am.postAction(ActionsManager.ACTION_KILL); // kill the started engines
0375:                        am.destroy();
0376:                    }
0377:                    return new DebuggerEngine[] {};
0378:                }
0379:
0380:                if (sessionToStart != null)
0381:                    setCurrentSession(sessionToStart);
0382:
0383:                DebuggerEngine[] des = new DebuggerEngine[engines.size()];
0384:                return (DebuggerEngine[]) engines.toArray(des);
0385:            }
0386:
0387:            /**
0388:             * Kills all {@link org.netbeans.api.debugger.Session}s and
0389:             * {@link org.netbeans.api.debugger.DebuggerEngine}s.
0390:             */
0391:            public void finishAllSessions() {
0392:                Session[] ds = getSessions();
0393:
0394:                if (ds.length == 0)
0395:                    return;
0396:
0397:                // finish all non persistent sessions
0398:                int i, k = ds.length;
0399:                for (i = 0; i < k; i++)
0400:                    ds[i].getCurrentEngine().getActionsManager().doAction(
0401:                            ActionsManager.ACTION_KILL);
0402:            }
0403:
0404:            /**
0405:             * Returns current debugger session or <code>null</code>.
0406:             *
0407:             * @return current debugger session or <code>null</code>
0408:             */
0409:            public Session getCurrentSession() {
0410:                return currentSession;
0411:            }
0412:
0413:            /**
0414:             * Sets current debugger session.
0415:             *
0416:             * @param session a session to be current
0417:             */
0418:            public void setCurrentSession(Session session) {
0419:                Session oldSession;
0420:                Session newSession;
0421:                DebuggerEngine oldEngine;
0422:                DebuggerEngine newEngine;
0423:                synchronized (sessions) {
0424:                    // 1) check if the session is registerred
0425:                    if (session != null) {
0426:                        int i, k = sessions.size();
0427:                        for (i = 0; i < k; i++)
0428:                            if (session == sessions.get(i))
0429:                                break;
0430:                        if (i == k)
0431:                            return;
0432:                    }
0433:
0434:                    // fire all changes
0435:                    oldSession = getCurrentSession();
0436:                    if (session == oldSession)
0437:                        return;
0438:                    currentSession = newSession = session;
0439:
0440:                    oldEngine = currentEngine;
0441:                    newEngine = null;
0442:                    if (getCurrentSession() != null)
0443:                        newEngine = getCurrentSession().getCurrentEngine();
0444:                    currentEngine = newEngine;
0445:                }
0446:                if (oldEngine != newEngine) {
0447:                    firePropertyChange(PROP_CURRENT_ENGINE, oldEngine,
0448:                            newEngine);
0449:                }
0450:                firePropertyChange(PROP_CURRENT_SESSION, oldSession, newSession);
0451:            }
0452:
0453:            /**
0454:             * Returns set of running debugger sessions.
0455:             *
0456:             * @return set of running debugger sessions
0457:             */
0458:            public Session[] getSessions() {
0459:                synchronized (sessions) {
0460:                    return (Session[]) sessions.toArray(new Session[0]);
0461:                }
0462:            }
0463:
0464:            /**
0465:             * Returns set of running debugger engines.
0466:             *
0467:             * @return set of running debugger engines
0468:             */
0469:            public DebuggerEngine[] getDebuggerEngines() {
0470:                synchronized (engines) {
0471:                    return (DebuggerEngine[]) engines
0472:                            .toArray(new DebuggerEngine[engines.size()]);
0473:                }
0474:            }
0475:
0476:            /**
0477:             * Returns current debugger engine or <code>null</code>.
0478:             *
0479:             * @return current debugger engine or <code>null</code>
0480:             */
0481:            public DebuggerEngine getCurrentEngine() {
0482:                return currentEngine;
0483:            }
0484:
0485:            // breakpoints management ..................................................
0486:
0487:            /** 
0488:             * Adds a new breakpoint.
0489:             *
0490:             * @param breakpoint a new breakpoint
0491:             */
0492:            public void addBreakpoint(Breakpoint breakpoint) {
0493:                if (initBreakpoints(breakpoint)) {
0494:                    registerBreakpoint(breakpoint);
0495:                    breakpoints.addElement(breakpoint);
0496:                    fireBreakpointCreated(breakpoint, null);
0497:                }
0498:            }
0499:
0500:            private void registerBreakpoint(Breakpoint breakpoint) {
0501:                Class c = breakpoint.getClass();
0502:                ClassLoader cl = c.getClassLoader();
0503:                synchronized (breakpointsByClassLoaders) {
0504:                    Set<Breakpoint> lb = breakpointsByClassLoaders.get(cl);
0505:                    if (lb == null) {
0506:                        lb = new HashSet<Breakpoint>();
0507:                        breakpointsByClassLoaders.put(cl, lb);
0508:                        //moduleUnloadListeners.listenOn(cl);
0509:                    }
0510:                    lb.add(breakpoint);
0511:                }
0512:            }
0513:
0514:            /** 
0515:             * Removes breakpoint.
0516:             *
0517:             * @param breakpoint a breakpoint to be removed
0518:             */
0519:            public void removeBreakpoint(Breakpoint breakpoint) {
0520:                removeBreakpoint(breakpoint, false);
0521:            }
0522:
0523:            private void removeBreakpoint(Breakpoint breakpoint,
0524:                    boolean ignoreInitBreakpointsListeners) {
0525:                if (!ignoreInitBreakpointsListeners) {
0526:                    initBreakpoints();
0527:                    Class c = breakpoint.getClass();
0528:                    ClassLoader cl = c.getClassLoader();
0529:                    synchronized (breakpointsByClassLoaders) {
0530:                        Set<Breakpoint> lb = breakpointsByClassLoaders.get(cl);
0531:                        if (lb != null) {
0532:                            lb.remove(breakpoint);
0533:                            if (lb.isEmpty()) {
0534:                                breakpointsByClassLoaders.remove(cl);
0535:                            }
0536:                        }
0537:                    }
0538:                    breakpoints.removeElement(breakpoint);
0539:                    breakpoint.disposeOut();
0540:                } else {
0541:                    breakpoints.removeElement(breakpoint);
0542:                    breakpoint.dispose();
0543:                }
0544:                fireBreakpointRemoved(breakpoint,
0545:                        ignoreInitBreakpointsListeners, null);
0546:            }
0547:
0548:            /** 
0549:             * Gets all registered breakpoints.
0550:             *
0551:             * @return all breakpoints
0552:             */
0553:            public Breakpoint[] getBreakpoints() {
0554:                initBreakpoints();
0555:                return (Breakpoint[]) breakpoints.toArray(new Breakpoint[0]);
0556:            }
0557:
0558:            private void moduleUnloaded(ClassLoader cl) {
0559:                Set<Breakpoint> lb;
0560:                synchronized (breakpointsByClassLoaders) {
0561:                    lb = breakpointsByClassLoaders.remove(cl);
0562:                }
0563:                if (lb == null)
0564:                    return;
0565:                for (Breakpoint b : lb) {
0566:                    removeBreakpoint(b, true);
0567:                }
0568:            }
0569:
0570:            // watches management ......................................................
0571:
0572:            /** 
0573:             * Creates a watch with its expression set to an initial value.
0574:             * Also allows creation of a hidden watch (not presented to the user), 
0575:             * for example for internal use in the editor to obtain values of variables
0576:             * under the mouse pointer.
0577:             *
0578:             * @param expr expression to watch for (the format is the responsibility 
0579:             *    of the debugger plug-in implementation, but it is typically 
0580:             *    a variable name).
0581:             * @return the new watch
0582:             */
0583:            public Watch createWatch(String expr) {
0584:                initWatches();
0585:                Watch w = new Watch(expr);
0586:                watches.addElement(w);
0587:                fireWatchCreated(w);
0588:                return w;
0589:            }
0590:
0591:            /**
0592:             * Gets all shared watches in the system.
0593:             *
0594:             * @return all watches
0595:             */
0596:            public Watch[] getWatches() {
0597:                initWatches();
0598:                return (Watch[]) watches.toArray(new Watch[0]);
0599:            }
0600:
0601:            /**
0602:             * Removes all watches from the system.
0603:             */
0604:            public void removeAllWatches() {
0605:                initWatches();
0606:                Vector v = (Vector) watches.clone();
0607:                int i, k = v.size();
0608:                for (i = k - 1; i >= 0; i--)
0609:                    ((Watch) v.elementAt(i)).remove();
0610:            }
0611:
0612:            /**
0613:             * Removes watch.
0614:             *
0615:             * @param w watch to be removed
0616:             */
0617:            void removeWatch(Watch w) {
0618:                initWatches();
0619:                watches.removeElement(w);
0620:                fireWatchRemoved(w);
0621:            }
0622:
0623:            // listenersMap ...............................................................
0624:
0625:            /**
0626:             * Fires property change.
0627:             */
0628:            private void firePropertyChange(String name, Object o, Object n) {
0629:                initDebuggerManagerListeners();
0630:                Vector l = (Vector) listeners.clone();
0631:                Vector l1;
0632:                synchronized (listenersMap) {
0633:                    l1 = (Vector) listenersMap.get(name);
0634:                    if (l1 != null)
0635:                        l1 = (Vector) l1.clone();
0636:                }
0637:                PropertyChangeEvent ev = new PropertyChangeEvent(this , name, o,
0638:                        n);
0639:                int i, k = l.size();
0640:                for (i = 0; i < k; i++)
0641:                    ((DebuggerManagerListener) l.elementAt(i))
0642:                            .propertyChange(ev);
0643:                if (l1 != null) {
0644:                    k = l1.size();
0645:                    for (i = 0; i < k; i++)
0646:                        ((DebuggerManagerListener) l1.elementAt(i))
0647:                                .propertyChange(ev);
0648:                }
0649:            }
0650:
0651:            /**
0652:             * This listener notificates about changes of breakpoints, watches and threads.
0653:             *
0654:             * @param l listener object.
0655:             */
0656:            public void addDebuggerListener(DebuggerManagerListener l) {
0657:                listeners.addElement(l);
0658:            }
0659:
0660:            /**
0661:             * Removes debugger listener.
0662:             *
0663:             * @param l listener object.
0664:             */
0665:            public void removeDebuggerListener(DebuggerManagerListener l) {
0666:                listeners.removeElement(l);
0667:            }
0668:
0669:            /** 
0670:             * Add a debuggerManager listener to changes of watches and breakpoints.
0671:             *
0672:             * @param propertyName a name of property to listen on
0673:             * @param l the debuggerManager listener to add
0674:             */
0675:            public void addDebuggerListener(String propertyName,
0676:                    DebuggerManagerListener l) {
0677:                synchronized (listenersMap) {
0678:                    Vector listeners = (Vector) listenersMap.get(propertyName);
0679:                    if (listeners == null) {
0680:                        listeners = new Vector();
0681:                        listenersMap.put(propertyName, listeners);
0682:                    }
0683:                    listeners.addElement(l);
0684:                }
0685:            }
0686:
0687:            /** 
0688:             * Remove a debuggerManager listener to changes of watches and breakpoints.
0689:             *
0690:             * @param propertyName a name of property to listen on
0691:             * @param l the debuggerManager listener to remove
0692:             */
0693:            public void removeDebuggerListener(String propertyName,
0694:                    DebuggerManagerListener l) {
0695:                synchronized (listenersMap) {
0696:                    Vector listeners = (Vector) listenersMap.get(propertyName);
0697:                    if (listeners == null)
0698:                        return;
0699:                    listeners.removeElement(l);
0700:                    if (listeners.size() == 0)
0701:                        listenersMap.remove(propertyName);
0702:                }
0703:            }
0704:
0705:            /**
0706:             * Notifies registered listeners about a change.
0707:             * Notifies {@link #listeners registered listeners} that a breakpoint
0708:             * {@link DebuggerManagerListener#breakpointAdded was added}
0709:             * and its properties
0710:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
0711:             * were changed.
0712:             *
0713:             * @param breakpoint  a breakpoint that was created
0714:             */
0715:            private void fireBreakpointCreated(final Breakpoint breakpoint,
0716:                    final DebuggerManagerListener originatingListener) {
0717:                initDebuggerManagerListeners();
0718:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
0719:                        PROP_BREAKPOINTS, null, null);
0720:
0721:                Vector l = (Vector) listeners.clone();
0722:                int i, k = l.size();
0723:                for (i = 0; i < k; i++) {
0724:                    DebuggerManagerListener dl = (DebuggerManagerListener) l
0725:                            .elementAt(i);
0726:                    if (dl != originatingListener) {
0727:                        dl.breakpointAdded(breakpoint);
0728:                        dl.propertyChange(ev);
0729:                    }
0730:                }
0731:
0732:                Vector l1;
0733:                synchronized (listenersMap) {
0734:                    l1 = (Vector) listenersMap.get(PROP_BREAKPOINTS);
0735:                    if (l1 != null) {
0736:                        l1 = (Vector) l1.clone();
0737:                    }
0738:                }
0739:                if (l1 != null) {
0740:                    k = l1.size();
0741:                    for (i = 0; i < k; i++) {
0742:                        DebuggerManagerListener dl = (DebuggerManagerListener) l1
0743:                                .elementAt(i);
0744:                        if (dl != originatingListener) {
0745:                            dl.breakpointAdded(breakpoint);
0746:                            dl.propertyChange(ev);
0747:                        }
0748:                    }
0749:                }
0750:            }
0751:
0752:            /**
0753:             * Notifies registered listenersMap about a change.
0754:             * Notifies {@link #listeners registered listenersMap} that a breakpoint
0755:             * {@link DebuggerManagerListener#breakpointRemoved was removed}
0756:             * and its properties
0757:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
0758:             * were changed.
0759:             *
0760:             * @param breakpoint  a breakpoint that was removed
0761:             */
0762:            private void fireBreakpointRemoved(final Breakpoint breakpoint,
0763:                    boolean ignoreInitBreakpointsListeners,
0764:                    DebuggerManagerListener ignoredListener) {
0765:                initDebuggerManagerListeners();
0766:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
0767:                        PROP_BREAKPOINTS, null, null);
0768:
0769:                Vector l = (Vector) listeners.clone();
0770:                int i, k = l.size();
0771:                for (i = 0; i < k; i++) {
0772:                    DebuggerManagerListener ml = (DebuggerManagerListener) l
0773:                            .elementAt(i);
0774:                    if (ml == ignoredListener)
0775:                        continue;
0776:                    Breakpoint[] bps;
0777:                    if (ignoreInitBreakpointsListeners
0778:                            && (bps = ml.initBreakpoints()) != null
0779:                            && bps.length > 0) {
0780:                        continue;
0781:                    }
0782:                    ml.breakpointRemoved(breakpoint);
0783:                    ml.propertyChange(ev);
0784:                }
0785:
0786:                Vector l1;
0787:                synchronized (listenersMap) {
0788:                    l1 = (Vector) listenersMap.get(PROP_BREAKPOINTS);
0789:                    if (l1 != null) {
0790:                        l1 = (Vector) l1.clone();
0791:                    }
0792:                }
0793:                if (l1 != null) {
0794:                    k = l1.size();
0795:                    for (i = 0; i < k; i++) {
0796:                        DebuggerManagerListener ml = (DebuggerManagerListener) l1
0797:                                .elementAt(i);
0798:                        if (ml == ignoredListener)
0799:                            continue;
0800:                        Breakpoint[] bps;
0801:                        if (ignoreInitBreakpointsListeners
0802:                                && (bps = ml.initBreakpoints()) != null
0803:                                && bps.length > 0) {
0804:                            continue;
0805:                        }
0806:                        ml.breakpointRemoved(breakpoint);
0807:                        ml.propertyChange(ev);
0808:                    }
0809:                }
0810:            }
0811:
0812:            private void initBreakpoints() {
0813:                initBreakpoints(null);
0814:            }
0815:
0816:            private List<Breakpoint> createdBreakpoints;
0817:            private Map<ClassLoader, Set<Breakpoint>> breakpointsByClassLoaders = new HashMap<ClassLoader, Set<Breakpoint>>();
0818:
0819:            /**
0820:             * @param newBreakpoint a breakpoint that is to be added if the breakpoints are not yet initialized.
0821:             * @return true if the breakpoints were successfully initialized.
0822:             */
0823:            private boolean initBreakpoints(Breakpoint newBreakpoint) {
0824:                // All is under the lock, including DebuggerManagerListener.initBreakpoints()
0825:                // and DebuggerManagerListener.propertyChange(..PROP_BREAKPOINTS_INIT..) calls.
0826:                // Clients should return the breakpoints via that listener, not add them
0827:                // directly. Therefore this should not lead to deadlock...
0828:                Map<Breakpoint, DebuggerManagerListener> originatingListeners;
0829:                List<Breakpoint> breakpointsToAdd;
0830:                synchronized (breakpoints) {
0831:                    if (breakpointsInitialized)
0832:                        return true;
0833:                    if (breakpointsInitializing) {
0834:                        if (newBreakpoint != null) {
0835:                            // Someone is trying to add new breakpoints during initialization process.
0836:                            // We must permit that doue to historical reasons - see web/jspdebug/src/org/netbeans/modules/web/debug/breakpoints/JspLineBreakpoint.java
0837:                            createdBreakpoints.add(newBreakpoint);
0838:                            return false;
0839:                        }
0840:                        throw new IllegalStateException(
0841:                                "Breakpoints not yet initialized and tried to initialize again...");
0842:                    }
0843:                    breakpointsInitializing = true;
0844:                    try {
0845:                        initDebuggerManagerListeners();
0846:
0847:                        createdBreakpoints = new ArrayList();
0848:                        originatingListeners = new HashMap();
0849:
0850:                        Vector l = (Vector) listeners.clone();
0851:                        int i, k = l.size();
0852:                        for (i = 0; i < k; i++) {
0853:                            DebuggerManagerListener dl = (DebuggerManagerListener) l
0854:                                    .elementAt(i);
0855:                            Breakpoint[] breakpoints = dl.initBreakpoints();
0856:                            createdBreakpoints.addAll(Arrays
0857:                                    .asList(breakpoints));
0858:                            for (int j = 0; j < breakpoints.length; j++) {
0859:                                originatingListeners.put(breakpoints[j], dl);
0860:                            }
0861:                        }
0862:
0863:                        Vector l1;
0864:                        synchronized (listenersMap) {
0865:                            l1 = (Vector) listenersMap
0866:                                    .get(PROP_BREAKPOINTS_INIT);
0867:                            if (l1 != null) {
0868:                                l1 = (Vector) l1.clone();
0869:                            }
0870:                        }
0871:                        if (l1 != null) {
0872:                            k = l1.size();
0873:                            for (i = 0; i < k; i++) {
0874:                                DebuggerManagerListener dl = (DebuggerManagerListener) l1
0875:                                        .elementAt(i);
0876:                                Breakpoint[] breakpoints = dl.initBreakpoints();
0877:                                createdBreakpoints.addAll(Arrays
0878:                                        .asList(breakpoints));
0879:                                for (int j = 0; j < breakpoints.length; j++) {
0880:                                    originatingListeners
0881:                                            .put(breakpoints[j], dl);
0882:                                }
0883:                            }
0884:                        }
0885:
0886:                        breakpoints.addAll(createdBreakpoints);
0887:                    } finally {
0888:                        breakpointsInitializing = false;
0889:                    }
0890:                    breakpointsInitialized = true;
0891:                    breakpointsToAdd = createdBreakpoints;
0892:                    createdBreakpoints = null;
0893:                }
0894:                for (Breakpoint bp : breakpointsToAdd) {
0895:                    registerBreakpoint(bp);
0896:                    fireBreakpointCreated(bp, originatingListeners.get(bp));
0897:                }
0898:                return true;
0899:            }
0900:
0901:            private void addBreakpoints(DebuggerManagerListener dl) {
0902:                if (!breakpointsInitialized) {
0903:                    return;
0904:                }
0905:                //System.err.println("\n addBreakpoints("+dl+")\n");
0906:                Map<Breakpoint, DebuggerManagerListener> originatingListeners = new HashMap<Breakpoint, DebuggerManagerListener>();
0907:                List<Breakpoint> breakpointsToAdd;
0908:                synchronized (breakpoints) {
0909:                    breakpointsInitialized = false;
0910:                    breakpointsInitializing = true;
0911:                    try {
0912:                        createdBreakpoints = new ArrayList<Breakpoint>();
0913:                        Breakpoint[] bps = dl.initBreakpoints();
0914:                        createdBreakpoints.addAll(Arrays.asList(bps));
0915:                        for (int j = 0; j < bps.length; j++) {
0916:                            originatingListeners.put(bps[j], dl);
0917:                        }
0918:                        //System.err.println("createdBreakpoints = "+createdBreakpoints);
0919:                        breakpoints.addAll(createdBreakpoints);
0920:                    } finally {
0921:                        breakpointsInitializing = false;
0922:                        breakpointsInitialized = true;
0923:                    }
0924:                    breakpointsToAdd = createdBreakpoints;
0925:                    createdBreakpoints = null;
0926:                }
0927:                //System.err.println("createdBreakpoints = "+breakpointsToAdd);
0928:                for (Breakpoint bp : breakpointsToAdd) {
0929:                    registerBreakpoint(bp);
0930:                    fireBreakpointCreated(bp, originatingListeners.get(bp));
0931:                }
0932:            }
0933:
0934:            private void removeBreakpoints(DebuggerManagerListener dl) {
0935:                if (!breakpointsInitialized) {
0936:                    return;
0937:                }
0938:                Breakpoint[] bps;
0939:                try {
0940:                    java.lang.reflect.Method unloadMethod = dl.getClass()
0941:                            .getMethod("unloadBreakpoints", new Class[] {});
0942:                    bps = (Breakpoint[]) unloadMethod.invoke(dl,
0943:                            new Object[] {});
0944:                } catch (Exception exc) {
0945:                    return;
0946:                }
0947:                //Breakpoint[] bps = dl.unloadBreakpoints();
0948:                //System.err.println("\n removeBreakpoints("+dl+")\n");
0949:                breakpoints.removeAll(Arrays.asList(bps));
0950:                for (Breakpoint breakpoint : bps) {
0951:                    Class c = breakpoint.getClass();
0952:                    ClassLoader cl = c.getClassLoader();
0953:                    synchronized (breakpointsByClassLoaders) {
0954:                        Set<Breakpoint> lb = breakpointsByClassLoaders.get(cl);
0955:                        if (lb != null) {
0956:                            lb.remove(breakpoint);
0957:                            if (lb.isEmpty()) {
0958:                                breakpointsByClassLoaders.remove(cl);
0959:                            }
0960:                        }
0961:                    }
0962:                    breakpoint.disposeOut();
0963:                }
0964:                //System.err.println("removedBreakpoints = "+Arrays.asList(bps));
0965:                for (Breakpoint bp : bps) {
0966:                    fireBreakpointRemoved(bp, false, dl);
0967:                }
0968:            }
0969:
0970:            /**
0971:             * Notifies registered listeners about a change.
0972:             * Notifies {@link #listeners registered listeners} that a watch
0973:             * {@link DebuggerManagerListener#watchAdded was added}
0974:             * and its properties
0975:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
0976:             * were changed.
0977:             *
0978:             * @param watch  a watch that was created
0979:             */
0980:            private void fireWatchCreated(final Watch watch) {
0981:                initDebuggerManagerListeners();
0982:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
0983:                        PROP_WATCHES, null, null);
0984:
0985:                Vector l = (Vector) listeners.clone();
0986:                int i, k = l.size();
0987:                for (i = 0; i < k; i++) {
0988:                    ((DebuggerManagerListener) l.elementAt(i))
0989:                            .watchAdded(watch);
0990:                    ((DebuggerManagerListener) l.elementAt(i))
0991:                            .propertyChange(ev);
0992:                }
0993:
0994:                Vector l1;
0995:                synchronized (listenersMap) {
0996:                    l1 = (Vector) listenersMap.get(PROP_WATCHES);
0997:                    if (l1 != null) {
0998:                        l1 = (Vector) l1.clone();
0999:                    }
1000:                }
1001:                if (l1 != null) {
1002:                    k = l1.size();
1003:                    for (i = 0; i < k; i++) {
1004:                        ((DebuggerManagerListener) l1.elementAt(i))
1005:                                .watchAdded(watch);
1006:                        ((DebuggerManagerListener) l1.elementAt(i))
1007:                                .propertyChange(ev);
1008:                    }
1009:                }
1010:            }
1011:
1012:            /**
1013:             * Notifies registered listeners about a change.
1014:             * Notifies {@link #listeners registered listeners} that a watch
1015:             * {@link DebuggerManagerListener#watchRemoved was removed}
1016:             * and its properties
1017:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
1018:             * were changed.
1019:             *
1020:             * @param watch  a watch that was removed
1021:             */
1022:            private void fireWatchRemoved(final Watch watch) {
1023:                initDebuggerManagerListeners();
1024:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1025:                        PROP_WATCHES, null, null);
1026:
1027:                Vector l = (Vector) listeners.clone();
1028:                int i, k = l.size();
1029:                for (i = 0; i < k; i++) {
1030:                    ((DebuggerManagerListener) l.elementAt(i))
1031:                            .watchRemoved(watch);
1032:                    // TODO: fix nonsense double firing
1033:                    ((DebuggerManagerListener) l.elementAt(i))
1034:                            .propertyChange(ev);
1035:                }
1036:
1037:                Vector l1;
1038:                synchronized (listenersMap) {
1039:                    l1 = (Vector) listenersMap.get(PROP_WATCHES);
1040:                    if (l1 != null) {
1041:                        l1 = (Vector) l1.clone();
1042:                    }
1043:                }
1044:                if (l1 != null) {
1045:                    k = l1.size();
1046:                    for (i = 0; i < k; i++) {
1047:                        ((DebuggerManagerListener) l1.elementAt(i))
1048:                                .watchRemoved(watch);
1049:                        // TODO: fix nonsense double firing
1050:                        ((DebuggerManagerListener) l1.elementAt(i))
1051:                                .propertyChange(ev);
1052:                    }
1053:                }
1054:            }
1055:
1056:            private void initWatches() {
1057:                synchronized (watches) {
1058:                    if (watchesInitialized)
1059:                        return;
1060:                    watchesInitialized = true;
1061:                }
1062:                initDebuggerManagerListeners();
1063:                // The rest must not be synchronized, since initWatches() does call createWatch()
1064:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1065:                        PROP_WATCHES_INIT, null, null);
1066:
1067:                Vector l = (Vector) listeners.clone();
1068:                int i, k = l.size();
1069:                for (i = 0; i < k; i++) {
1070:                    ((DebuggerManagerListener) l.elementAt(i)).initWatches();
1071:                    ((DebuggerManagerListener) l.elementAt(i))
1072:                            .propertyChange(ev);
1073:                }
1074:
1075:                Vector l1;
1076:                synchronized (listenersMap) {
1077:                    l1 = (Vector) listenersMap.get(PROP_WATCHES_INIT);
1078:                    if (l1 != null) {
1079:                        l1 = (Vector) l1.clone();
1080:                    }
1081:                }
1082:                if (l1 != null) {
1083:                    k = l1.size();
1084:                    for (i = 0; i < k; i++) {
1085:                        ((DebuggerManagerListener) l1.elementAt(i))
1086:                                .initWatches();
1087:                        ((DebuggerManagerListener) l1.elementAt(i))
1088:                                .propertyChange(ev);
1089:                    }
1090:                }
1091:            }
1092:
1093:            /**
1094:             * Notifies registered listeners about a change.
1095:             * Notifies {@link #listeners registered listeners} that a session
1096:             * {@link DebuggerManagerListener#sessionAdded was added}
1097:             * and its properties
1098:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
1099:             * were changed.
1100:             *
1101:             * @param session a session that was created
1102:             */
1103:            private void fireSessionAdded(final Session session,
1104:                    final Session[] old, final Session[] ne) {
1105:                initDebuggerManagerListeners();
1106:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1107:                        PROP_SESSIONS, old, ne);
1108:
1109:                Vector l = (Vector) listeners.clone();
1110:                int i, k = l.size();
1111:                for (i = 0; i < k; i++) {
1112:                    ((DebuggerManagerListener) l.elementAt(i))
1113:                            .sessionAdded(session);
1114:                    ((DebuggerManagerListener) l.elementAt(i))
1115:                            .propertyChange(ev);
1116:                }
1117:
1118:                Vector l1;
1119:                synchronized (listenersMap) {
1120:                    l1 = (Vector) listenersMap.get(PROP_SESSIONS);
1121:                    if (l1 != null) {
1122:                        l1 = (Vector) l1.clone();
1123:                    }
1124:                }
1125:                if (l1 != null) {
1126:                    k = l1.size();
1127:                    for (i = 0; i < k; i++) {
1128:                        ((DebuggerManagerListener) l1.elementAt(i))
1129:                                .sessionAdded(session);
1130:                        ((DebuggerManagerListener) l1.elementAt(i))
1131:                                .propertyChange(ev);
1132:                    }
1133:                }
1134:            }
1135:
1136:            /**
1137:             * Notifies registered listeners about a change.
1138:             * Notifies {@link #listeners registered listeners} that a session
1139:             * {@link DebuggerManagerListener#sessionRemoved was removed}
1140:             * and its properties
1141:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
1142:             * were changed.
1143:             *
1144:             * @param session a session that was removed
1145:             */
1146:            private void fireSessionRemoved(final Session session,
1147:                    final Session[] old, final Session[] ne) {
1148:                initDebuggerManagerListeners();
1149:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1150:                        PROP_SESSIONS, old, ne);
1151:
1152:                Vector l = (Vector) listeners.clone();
1153:                int i, k = l.size();
1154:                for (i = 0; i < k; i++) {
1155:                    ((DebuggerManagerListener) l.elementAt(i))
1156:                            .sessionRemoved(session);
1157:                    ((DebuggerManagerListener) l.elementAt(i))
1158:                            .propertyChange(ev);
1159:                }
1160:
1161:                Vector l1;
1162:                synchronized (listenersMap) {
1163:                    l1 = (Vector) listenersMap.get(PROP_SESSIONS);
1164:                    if (l1 != null) {
1165:                        l1 = (Vector) l1.clone();
1166:                    }
1167:                }
1168:                if (l1 != null) {
1169:                    k = l1.size();
1170:                    for (i = 0; i < k; i++) {
1171:                        ((DebuggerManagerListener) l1.elementAt(i))
1172:                                .sessionRemoved(session);
1173:                        ((DebuggerManagerListener) l1.elementAt(i))
1174:                                .propertyChange(ev);
1175:                    }
1176:                }
1177:            }
1178:
1179:            /**
1180:             * Notifies registered listeners about a change.
1181:             * Notifies {@link #listeners registered listeners} that a engine
1182:             * {@link DebuggerManagerListener#engineAdded was added}
1183:             * and its properties
1184:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
1185:             * were changed.
1186:             *
1187:             * @param engine a engine that was created
1188:             */
1189:            private void fireEngineAdded(final DebuggerEngine engine,
1190:                    final DebuggerEngine[] old, final DebuggerEngine[] ne) {
1191:                initDebuggerManagerListeners();
1192:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1193:                        PROP_DEBUGGER_ENGINES, old, ne);
1194:
1195:                Vector l = (Vector) listeners.clone();
1196:                int i, k = l.size();
1197:                for (i = 0; i < k; i++) {
1198:                    ((DebuggerManagerListener) l.elementAt(i))
1199:                            .engineAdded(engine);
1200:                    ((DebuggerManagerListener) l.elementAt(i))
1201:                            .propertyChange(ev);
1202:                }
1203:
1204:                Vector l1;
1205:                synchronized (listenersMap) {
1206:                    l1 = (Vector) listenersMap.get(PROP_DEBUGGER_ENGINES);
1207:                    if (l1 != null) {
1208:                        l1 = (Vector) l1.clone();
1209:                    }
1210:                }
1211:                if (l1 != null) {
1212:                    k = l1.size();
1213:                    for (i = 0; i < k; i++) {
1214:                        ((DebuggerManagerListener) l1.elementAt(i))
1215:                                .engineAdded(engine);
1216:                        ((DebuggerManagerListener) l1.elementAt(i))
1217:                                .propertyChange(ev);
1218:                    }
1219:                }
1220:            }
1221:
1222:            /**
1223:             * Notifies registered listeners about a change.
1224:             * Notifies {@link #listeners registered listeners} that a engine
1225:             * {@link DebuggerManagerListener#engineRemoved was removed}
1226:             * and its properties
1227:             * {@link PropertyChangeSupport#firePropertyChange(PropertyChangeEvent)}
1228:             * were changed.
1229:             *
1230:             * @param engine a engine that was removed
1231:             */
1232:            private void fireEngineRemoved(final DebuggerEngine engine,
1233:                    final DebuggerEngine[] old, final DebuggerEngine[] ne) {
1234:                initDebuggerManagerListeners();
1235:                PropertyChangeEvent ev = new PropertyChangeEvent(this ,
1236:                        PROP_DEBUGGER_ENGINES, old, ne);
1237:
1238:                Vector l = (Vector) listeners.clone();
1239:                int i, k = l.size();
1240:                for (i = 0; i < k; i++) {
1241:                    ((DebuggerManagerListener) l.elementAt(i))
1242:                            .engineRemoved(engine);
1243:                    ((DebuggerManagerListener) l.elementAt(i))
1244:                            .propertyChange(ev);
1245:                }
1246:
1247:                Vector l1;
1248:                synchronized (listenersMap) {
1249:                    l1 = (Vector) listenersMap.get(PROP_DEBUGGER_ENGINES);
1250:                    if (l1 != null) {
1251:                        l1 = (Vector) l1.clone();
1252:                    }
1253:                }
1254:                if (l1 != null) {
1255:                    k = l1.size();
1256:                    for (i = 0; i < k; i++) {
1257:                        ((DebuggerManagerListener) l1.elementAt(i))
1258:                                .engineRemoved(engine);
1259:                        ((DebuggerManagerListener) l1.elementAt(i))
1260:                                .propertyChange(ev);
1261:                    }
1262:                }
1263:            }
1264:
1265:            // helper methods ....................................................
1266:
1267:            private Set<LazyDebuggerManagerListener> loadedListeners;
1268:            private List<? extends LazyDebuggerManagerListener> listenersLookupList;
1269:
1270:            private void initDebuggerManagerListeners() {
1271:                synchronized (listenersMap) {
1272:                    if (loadedListeners == null) {
1273:                        loadedListeners = new HashSet<LazyDebuggerManagerListener>();
1274:                        listenersLookupList = lookup.lookup(null,
1275:                                LazyDebuggerManagerListener.class);
1276:                        refreshDebuggerManagerListeners(listenersLookupList);
1277:                        ((Customizer) listenersLookupList)
1278:                                .addPropertyChangeListener(new PropertyChangeListener() {
1279:
1280:                                    public void propertyChange(
1281:                                            PropertyChangeEvent evt) {
1282:                                        refreshDebuggerManagerListeners((List<? extends LazyDebuggerManagerListener>) evt
1283:                                                .getSource());
1284:                                    }
1285:                                });
1286:                    }
1287:
1288:                }
1289:            }
1290:
1291:            private void refreshDebuggerManagerListeners(
1292:                    List<? extends LazyDebuggerManagerListener> listenersLookupList) {
1293:                //System.err.println("\n refreshDebuggerManagerListeners()");
1294:                //It's neccessary to pay attention on the order in which the listeners and breakpoints are registered!
1295:                //Annotation listeners must be unregistered AFTER breakpoints are removed
1296:                //and registered back BEFORE breakpoints are loaded
1297:                Set<LazyDebuggerManagerListener> addedInitBreakpointsListeners = new HashSet<LazyDebuggerManagerListener>();
1298:                Set<ClassLoader> uninstalledModules = new HashSet<ClassLoader>();
1299:                synchronized (listenersLookupList) {
1300:                    int i, k = listenersLookupList.size();
1301:                    //System.err.println("size() = "+k+",  content = "+listenersLookupList+"\n");
1302:                    for (i = 0; i < k; i++) {
1303:                        LazyDebuggerManagerListener l = listenersLookupList
1304:                                .get(i);
1305:                        if (loadedListeners.add(l)) {
1306:                            String[] props = l.getProperties();
1307:                            if ((props == null) || (props.length == 0)) {
1308:                                addDebuggerListener(l);
1309:                            } else {
1310:                                int j, jj = props.length;
1311:                                for (j = 0; j < jj; j++) {
1312:                                    addDebuggerListener(props[j], l);
1313:                                }
1314:                            }
1315:                            //System.err.println("ADDED listener: "+l);
1316:                            addedInitBreakpointsListeners.add(l);
1317:                        }
1318:                    }
1319:                    Set<LazyDebuggerManagerListener> listenersToRemove = new HashSet<LazyDebuggerManagerListener>(
1320:                            loadedListeners);
1321:                    listenersToRemove.removeAll(listenersLookupList);
1322:                    for (LazyDebuggerManagerListener l : listenersToRemove) {
1323:                        if (loadedListeners.contains(l)) {
1324:                            removeBreakpoints(l);
1325:                        }
1326:                    }
1327:                    for (LazyDebuggerManagerListener l : listenersToRemove) {
1328:                        if (loadedListeners.remove(l)) {
1329:                            moduleUnloaded(l.getClass().getClassLoader());
1330:                            String[] props = l.getProperties();
1331:                            if ((props == null) || (props.length == 0)) {
1332:                                removeDebuggerListener(l);
1333:                            } else {
1334:                                int j, jj = props.length;
1335:                                for (j = 0; j < jj; j++) {
1336:                                    removeDebuggerListener(props[j], l);
1337:                                }
1338:                            }
1339:                            //System.err.println("REMOVED listener: "+l);
1340:                        }
1341:                    }
1342:                }
1343:                for (LazyDebuggerManagerListener l : addedInitBreakpointsListeners) {
1344:                    addBreakpoints(l);
1345:                }
1346:            }
1347:
1348:            private void addSession(Session session) {
1349:                Session[] oldSessions;
1350:                Session[] newSessions;
1351:                synchronized (sessions) {
1352:                    oldSessions = getSessions();
1353:                    int i, k = oldSessions.length;
1354:                    for (i = 0; i < k; i++)
1355:                        if (session == oldSessions[i])
1356:                            return;
1357:
1358:                    newSessions = new Session[oldSessions.length + 1];
1359:                    System.arraycopy(oldSessions, 0, newSessions, 0,
1360:                            oldSessions.length);
1361:                    newSessions[oldSessions.length] = session;
1362:                    this .sessions.add(session);
1363:
1364:                    session.addPropertyChangeListener(sessionListener);
1365:                }
1366:                fireSessionAdded(session, oldSessions, newSessions);
1367:            }
1368:
1369:            private void removeSession(Session session) {
1370:                Session[] oldSessions;
1371:                Session[] newSessions;
1372:                Session nCurrentSesson = null;
1373:                synchronized (sessions) {
1374:                    oldSessions = getSessions();
1375:                    // find index of given debugger and new instance of currentDebugger
1376:                    int i, k = oldSessions.length;
1377:                    for (i = 0; i < k; i++) {
1378:                        if (oldSessions[i] == session) {
1379:                            break;
1380:                        } else if (nCurrentSesson == null) {
1381:                            nCurrentSesson = oldSessions[i];
1382:                        }
1383:                    }
1384:                    if (i == k)
1385:                        return; // this debugger is not registered
1386:
1387:                    // set new current debugger session
1388:                    if (session == getCurrentSession()) {
1389:                        if ((nCurrentSesson == null) && (k > 1))
1390:                            nCurrentSesson = oldSessions[1];
1391:                    } else {
1392:                        nCurrentSesson = getCurrentSession();
1393:                    }
1394:
1395:                    newSessions = new Session[oldSessions.length - 1];
1396:                    System.arraycopy(oldSessions, 0, newSessions, 0, i);
1397:                    if ((oldSessions.length - i) > 1)
1398:                        System.arraycopy(oldSessions, i + 1, newSessions, i,
1399:                                oldSessions.length - i - 1);
1400:                    sessions.remove(i);
1401:
1402:                    session.removePropertyChangeListener(sessionListener);
1403:                    // The current engine is set in setCurrentSession().
1404:                }
1405:                setCurrentSession(nCurrentSesson);
1406:                fireSessionRemoved(session, oldSessions, newSessions);
1407:            }
1408:
1409:            void addEngine(DebuggerEngine engine) {
1410:                DebuggerEngine[] old;
1411:                DebuggerEngine[] ne;
1412:                synchronized (engines) {
1413:                    if (engines.contains(engine))
1414:                        return;
1415:                    old = (DebuggerEngine[]) engines
1416:                            .toArray(new DebuggerEngine[engines.size()]);
1417:                    engines.add(engine);
1418:                    ne = (DebuggerEngine[]) engines
1419:                            .toArray(new DebuggerEngine[engines.size()]);
1420:                }
1421:                fireEngineAdded(engine, old, ne);
1422:            }
1423:
1424:            void removeEngine(DebuggerEngine engine) {
1425:                DebuggerEngine[] old;
1426:                DebuggerEngine[] ne;
1427:                synchronized (engines) {
1428:                    if (!engines.contains(engine))
1429:                        return;
1430:                    old = (DebuggerEngine[]) engines
1431:                            .toArray(new DebuggerEngine[engines.size()]);
1432:                    engines.remove(engine);
1433:                    ne = (DebuggerEngine[]) engines
1434:                            .toArray(new DebuggerEngine[engines.size()]);
1435:                }
1436:                fireEngineRemoved(engine, old, ne);
1437:            }
1438:
1439:            // innerclasses ............................................................
1440:
1441:            /**
1442:             * Listens on all engines and sessions for: 
1443:             * current thread changes 
1444:             * start / finish of engines
1445:             * last action
1446:             * current engine
1447:             */
1448:            private class SessionListener implements  PropertyChangeListener {
1449:                public void propertyChange(PropertyChangeEvent e) {
1450:                    if (e.getSource() instanceof  Session) {
1451:                        if ((!e.getPropertyName().equals(
1452:                                Session.PROP_CURRENT_LANGUAGE))
1453:                                && (!e.getPropertyName().equals(
1454:                                        Session.PROP_SUPPORTED_LANGUAGES)))
1455:                            return;
1456:                        // update the current engine
1457:                        DebuggerEngine oldEngine;
1458:                        DebuggerEngine newEngine;
1459:                        synchronized (sessions) {
1460:                            oldEngine = currentEngine;
1461:                            newEngine = null;
1462:                            if (getCurrentSession() != null)
1463:                                newEngine = getCurrentSession()
1464:                                        .getCurrentEngine();
1465:                            currentEngine = newEngine;
1466:                        }
1467:                        if (newEngine != oldEngine) {
1468:                            firePropertyChange(PROP_CURRENT_ENGINE, oldEngine,
1469:                                    newEngine);
1470:                        }
1471:                        Session s = (Session) e.getSource();
1472:                        if (s.getSupportedLanguages().length == 0)
1473:                            removeSession(s);
1474:                    }
1475:                }
1476:            }
1477:
1478:            /*
1479:            private class ModuleUnloadListeners {
1480:                
1481:                private Map<ClassLoader, ModuleChangeListener> moduleChangeListeners
1482:                        = new HashMap<ClassLoader, ModuleChangeListener>();
1483:                
1484:                public void listenOn(ClassLoader cl) {
1485:                    /*
1486:                    org.openide.util.Lookup.Result<ModuleInfo> moduleLookupResult =
1487:                            org.openide.util.Lookup.getDefault ().lookup(
1488:                                new org.openide.util.Lookup.Template<ModuleInfo>(ModuleInfo.class));
1489:                    synchronized(moduleChangeListeners) {
1490:                        if (!moduleChangeListeners.containsKey(cl)) {
1491:                            for (ModuleInfo mi : moduleLookupResult.allInstances()) {
1492:                                if (mi.isEnabled() && mi.getClassLoader() == cl) {
1493:                                    ModuleChangeListener l = new ModuleChangeListener(cl);
1494:                                    mi.addPropertyChangeListener(WeakListeners.propertyChange(l, mi));
1495:                                    moduleChangeListeners.put(cl, l);
1496:                                }
1497:                            }
1498:                        }
1499:                    }
1500:             *//*
1501:                    }
1502:                    
1503:                    private final class ModuleChangeListener implements PropertyChangeListener {
1504:                        
1505:                        private ClassLoader cl;
1506:
1507:                        public ModuleChangeListener(ClassLoader cl) {
1508:                            this.cl = cl;
1509:                        }
1510:
1511:                        public void propertyChange(PropertyChangeEvent evt) {
1512:                            ModuleInfo mi = (ModuleInfo) evt.getSource();
1513:                            if (!mi.isEnabled()) {
1514:                                synchronized (moduleChangeListeners) {
1515:                                    moduleChangeListeners.remove(cl);
1516:                                }
1517:                                moduleUnloaded(cl);
1518:                            }
1519:                        }
1520:
1521:                    }
1522:                }
1523:             */
1524:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.