Repository: tapestry-5
Updated Branches:
  refs/heads/master 5b311716e -> ce6e66ea3


Include a list of threads in the default exception report page


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/08807a12
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/08807a12
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/08807a12

Branch: refs/heads/master
Commit: 08807a1266b49cc5d76ac38705ab7fe31e893b6e
Parents: 5b31171
Author: Howard M. Lewis Ship <[email protected]>
Authored: Fri May 30 16:05:33 2014 -0700
Committer: Howard M. Lewis Ship <[email protected]>
Committed: Fri May 30 16:55:24 2014 -0700

----------------------------------------------------------------------
 54_RELEASE_NOTES.md                             |   4 +
 .../corelib/pages/ExceptionReport.java          | 100 ++++++++++++++++++-
 .../META-INF/assets/core/ExceptionReport.css    |  13 +++
 .../tapestry5/corelib/pages/ExceptionReport.tml |  21 ++++
 4 files changed, 135 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/54_RELEASE_NOTES.md
----------------------------------------------------------------------
diff --git a/54_RELEASE_NOTES.md b/54_RELEASE_NOTES.md
index 8044c85..23fc912 100644
--- a/54_RELEASE_NOTES.md
+++ b/54_RELEASE_NOTES.md
@@ -155,6 +155,10 @@ The FormFragment component's visibleBound parameter is no 
longer supported; it w
 far up the DOM above the FormFragment's client-side element should be searched 
when determining visibility. This may
 resurface in the future as a CSS expression, but is currently not supported.
 
+## ExceptionReport Page
+
+The default exception report page has been modified to display a list of 
threads.
+
 ## Symbol tapestry.asset-path-prefix
 
 The definition of the symbol 'tapestry.asset-path-prefix' has changed; it no 
longer includes the leading and trailing

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java
index e6db1ed..1ca7e25 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java
@@ -21,16 +21,20 @@ import org.apache.tapestry5.annotations.ContentType;
 import org.apache.tapestry5.annotations.Import;
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.annotations.UnknownActivationContextCheck;
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.internal.InternalConstants;
 import org.apache.tapestry5.internal.services.PageActivationContextCollector;
 import org.apache.tapestry5.internal.services.ReloadHelper;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.services.*;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -99,17 +103,42 @@ public class ExceptionReport implements ExceptionReporter
 
     @Inject
     private ReloadHelper reloadHelper;
-    
+
     @Inject
     private URLEncoder urlEncoder;
 
     @Property
     private String rootURL;
 
+    @Property
+    private ThreadInfo thread;
+
+    public class ThreadInfo implements Comparable<ThreadInfo>
+    {
+        public final String className, name, flags;
+
+        public final ThreadGroup group;
+
+        public ThreadInfo(String className, String name, String flags, 
ThreadGroup group)
+        {
+            this.className = className;
+            this.name = name;
+            this.flags = flags;
+            this.group = group;
+        }
+
+        @Override
+        public int compareTo(ThreadInfo o)
+        {
+            return name.compareTo(o.name);
+        }
+    }
+
     private final String pathSeparator = 
System.getProperty(PATH_SEPARATOR_PROPERTY);
 
-    public boolean isShowActions() {
-        return failurePage != null && ! request.isXHR();
+    public boolean isShowActions()
+    {
+        return failurePage != null && !request.isXHR();
     }
 
     public void reportException(Throwable exception)
@@ -182,4 +211,69 @@ public class ExceptionReport implements ExceptionReporter
 
         return getPropertyValue().split(pathSeparator);
     }
+
+    private Thread[] assembleThreads()
+    {
+        ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
+
+        while (true)
+        {
+            ThreadGroup parentGroup = rootGroup.getParent();
+            if (parentGroup == null)
+            {
+                break;
+            }
+            rootGroup = parentGroup;
+        }
+
+        Thread[] threads = new Thread[rootGroup.activeCount()];
+
+        while (true)
+        {
+            // A really ugly API. threads.length must be larger than
+            // the actual number of threads, just so we can determine
+            // if we're done.
+            int count = rootGroup.enumerate(threads, true);
+            if (count < threads.length)
+            {
+                return Arrays.copyOf(threads, count);
+            }
+            threads = new Thread[threads.length * 2];
+        }
+    }
+
+    public List<ThreadInfo> getThreads()
+    {
+        return F.flow(assembleThreads()).map(new Mapper<Thread, ThreadInfo>()
+        {
+            @Override
+            public ThreadInfo map(Thread t)
+            {
+                List<String> flags = CollectionFactory.newList();
+
+                if (t.isDaemon())
+                {
+                    flags.add("daemon");
+                }
+                if (!t.isAlive())
+                {
+                    flags.add("NOT alive");
+                }
+                if (t.isInterrupted())
+                {
+                    flags.add("interrupted");
+                }
+
+                if (t.getPriority() != Thread.NORM_PRIORITY)
+                {
+                    flags.add("priority " + t.getPriority());
+                }
+
+                return new ThreadInfo(Thread.currentThread() == t ? 
"active-thread" : "",
+                        t.getName(),
+                        InternalUtils.join(flags),
+                        t.getThreadGroup());
+            }
+        }).sort().toList();
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css 
b/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css
index e770da3..87fdab6 100644
--- a/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css
+++ b/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css
@@ -1,3 +1,16 @@
 body {
     padding-top: 55px;
+}
+
+table.exception-report-threads td, table.exception-report-threads th {
+    text-align: right;
+}
+
+table.exception-report-threads tr td:last-child,
+table.exception-report-threads tr th:last-child {
+    text-align: left;
+}
+
+table.exception-report-threads tr.active-thread {
+    font-weight:  bold;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml
----------------------------------------------------------------------
diff --git 
a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml
 
b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml
index c26ebf1..0190b80 100644
--- 
a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml
+++ 
b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml
@@ -94,6 +94,27 @@
                     </dl>
                 </t:if>
 
+                <h3>Threads</h3>
+
+                <table class="table table-compact table-striped 
exception-report-threads">
+                    <thread>
+                        <tr>
+                            <th>Thread Name</th>
+                            <th>Group Name</th>
+                            <th>Flags</th>
+                        </tr>
+                    </thread>
+                    <tbody>
+
+                        <tr t:type="loop" source="threads" value="thread" 
class="${thread.className}">
+                            <td class="thread-name">${thread.name}</td>
+                            <td>${thread.group?.name}</td>
+                            <td>${thread.flags}</td>
+                        </tr>
+                    </tbody>
+                </table>
+
+
                 <h3>System Properties</h3>
                 <dl>
                     <t:loop source="systemProperties" value="propertyName">

Reply via email to