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