SwingAddon.java
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2008-2017 the original author or authors.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package org.codehaus.griffon.runtime.swing;
019 
020 import griffon.core.CallableWithArgs;
021 import griffon.core.GriffonApplication;
022 import griffon.core.GriffonExceptionHandler;
023 import org.codehaus.griffon.runtime.core.addon.AbstractGriffonAddon;
024 import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
025 import org.jdesktop.swinghelper.debug.EventDispatchThreadHangMonitor;
026 import sun.awt.AppContext;
027 
028 import javax.annotation.Nonnull;
029 import javax.annotation.Nullable;
030 import javax.inject.Named;
031 import javax.swing.RepaintManager;
032 
033 /**
034  @author Andres Almiray
035  @since 2.0.0
036  */
037 @Named("swing")
038 public class
039     SwingAddon extends AbstractGriffonAddon {
040     private static final String SWING_EDT_VIOLATIONS_KEY = "griffon.swing.edt.violations.check";
041     private static final String SWING_EDT_HANG_MONITOR_KEY = "griffon.swing.edt.hang.monitor";
042     private static final String SWING_EDT_HANG_MONITOR_TIMEOUT_KEY = "griffon.swing.edt.hang.monitor.timeout";
043 
044     private static final String[] EXCLUDED_PACKAGES =
045         System.getProperty("groovy.sanitized.stacktraces",
046             "groovy.," +
047                 "org.codehaus.groovy.," +
048                 "java.," +
049                 "javax.," +
050                 "sun.," +
051                 "gjdk.groovy.," +
052                 CheckThreadViolationRepaintManager.class.getPackage().getName()
053         ).split("(\\s|,)+");
054 
055     @Override
056     public void init(@Nonnull GriffonApplication application) {
057         String value = System.getProperty(SWING_EDT_VIOLATIONS_KEY);
058         if (value != null && Boolean.parseBoolean(value)) {
059             if (getLog().isInfoEnabled()) {
060                 getLog().info("EDT violations check enabled.");
061             }
062             RepaintManager currentRepaintManager = getCurrentRepaintManager();
063             if (null == currentRepaintManager) {
064                 currentRepaintManager = new RepaintManager();
065             }
066             ifcurrentRepaintManager instanceof CheckThreadViolationRepaintManager) {
067                 return;
068             }
069             RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager(currentRepaintManager));
070 
071             GriffonExceptionHandler.addClassTest(new CallableWithArgs<Boolean>() {
072                 @Override
073                 @Nullable
074                 public Boolean call(@Nullable Object... args) {
075                     String className = (Stringargs[0];
076                     for (String groovyPackage : EXCLUDED_PACKAGES) {
077                         if (className.startsWith(groovyPackage)) {
078                             return false;
079                         }
080                     }
081                     return true;
082                 }
083             });
084         }
085 
086         value = System.getProperty(SWING_EDT_HANG_MONITOR_KEY);
087         if (value != null && Boolean.parseBoolean(value)) {
088             if (getLog().isInfoEnabled()) {
089                 getLog().info("EDT hang monitor enabled.");
090             }
091             EventDispatchThreadHangMonitor.initMonitoring();
092             value = System.getProperty(SWING_EDT_HANG_MONITOR_TIMEOUT_KEY);
093             if (value != null) {
094                 try {
095                     EventDispatchThreadHangMonitor.getInstance().setTimeout(Long.parseLong(value));
096                 catch (NumberFormatException e) {
097                     // ignore
098                 }
099             }
100         }
101     }
102 
103     private RepaintManager getCurrentRepaintManager() {
104         return (RepaintManagerAppContext.getAppContext().get(RepaintManager.class);
105     }
106 }