Source Code Cross Referenced for TreeItemLogger.java in  » Ajax » GWT » com » google » gwt » dev » util » log » 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 » Ajax » GWT » com.google.gwt.dev.util.log 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2007 Google Inc.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005:         * use this file except in compliance with the License. You may obtain a copy of
006:         * 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, WITHOUT
012:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013:         * License for the specific language governing permissions and limitations under
014:         * the License.
015:         */
016:        package com.google.gwt.dev.util.log;
017:
018:        import com.google.gwt.core.ext.TreeLogger;
019:
020:        import org.eclipse.swt.SWT;
021:        import org.eclipse.swt.graphics.Color;
022:        import org.eclipse.swt.graphics.Image;
023:        import org.eclipse.swt.widgets.Display;
024:        import org.eclipse.swt.widgets.Tree;
025:        import org.eclipse.swt.widgets.TreeItem;
026:
027:        import java.io.IOException;
028:        import java.io.InputStream;
029:        import java.util.Iterator;
030:        import java.util.LinkedList;
031:        import java.util.List;
032:        import java.util.Stack;
033:
034:        /**
035:         * Tree logger built on an SWT tree item.
036:         */
037:        public final class TreeItemLogger extends AbstractTreeLogger {
038:
039:            /**
040:             * Represents an individual log event.
041:             */
042:            public static class LogEvent {
043:                public final Throwable caught;
044:
045:                public final int index;
046:
047:                public final boolean isBranchCommit;
048:
049:                public final TreeItemLogger logger;
050:
051:                public final String message;
052:
053:                public final TreeLogger.Type type;
054:
055:                public LogEvent(TreeItemLogger logger, boolean isBranchCommit,
056:                        int index, Type type, String message, Throwable caught) {
057:                    this .logger = logger;
058:                    this .isBranchCommit = isBranchCommit;
059:                    this .index = index;
060:                    this .type = type;
061:                    this .message = message;
062:                    this .caught = caught;
063:                }
064:
065:                @Override
066:                public String toString() {
067:                    String s = "";
068:                    s += "[logger " + logger.toString();
069:                    s += ", " + (isBranchCommit ? "BRANCH" : "LOG");
070:                    s += ", index " + index;
071:                    s += ", type " + type.toString();
072:                    s += ", msg '" + message + "'";
073:                    s += "]";
074:                    return s;
075:                }
076:
077:                /**
078:                 * Can only be called by the UI thread.
079:                 */
080:                public void uiFlush(Tree tree) {
081:                    // Get or create the tree item associated with this logger.
082:                    //
083:                    TreeItem treeItem = createTreeItem(tree);
084:
085:                    if (treeItem == null) {
086:                        // The logger associated with this log event is dead, so it should
087:                        // show no ui at all.
088:                        //
089:                        return;
090:                    }
091:
092:                    // Style all ancestors.
093:                    //
094:                    uiStyleChildAndAncestors(type, treeItem);
095:                }
096:
097:                /**
098:                 * Creates a tree item in a way that is sensitive to the log event and its
099:                 * position in the tree.
100:                 */
101:                private TreeItem createTreeItem(Tree tree) {
102:                    TreeItem treeItem = null;
103:
104:                    if (isBranchCommit) {
105:                        // A child logger is committing.
106:                        // 'logger' is the logger that needs a tree item.
107:                        // We can be sure that the child logger's parent is non-null
108:                        // and that either (1) it is has a TreeItem meaning it is not a
109:                        // top-level entry or (2) it is a top-level entry and gets attached to
110:                        // the Tree.
111:                        //
112:                        TreeItemLogger parentLogger = (TreeItemLogger) logger
113:                                .getParentLogger();
114:                        if (parentLogger.lazyTreeItem == null) {
115:                            // Is top level.
116:                            //
117:                            treeItem = new TreeItem(tree, SWT.NONE);
118:                            logger.lazyTreeItem = treeItem;
119:                        } else if (!parentLogger.lazyTreeItem.isDisposed()) {
120:                            // Is not top level, but still valid to write to.
121:                            //
122:                            treeItem = new TreeItem(parentLogger.lazyTreeItem,
123:                                    SWT.NONE);
124:                            logger.lazyTreeItem = treeItem;
125:                        } else {
126:                            // The tree item associated with this logger's parent has been
127:                            // disposed, so we simply ignore all pending updates related to it.
128:                            // We also mark that logger dead to avoid adding log events for it.
129:                            //
130:                            parentLogger.markLoggerDead();
131:                            return null;
132:                        }
133:                    } else {
134:                        // Create a regular log item on 'logger'.
135:                        // The logger may be the root logger, in which case we create TreeItems
136:                        // directly underneath Tree, or it may be a branched logger, in which
137:                        // case we create TreeItems underneath the branched logger's TreeItem
138:                        // (which cannot be null because of the careful ordering of log events).
139:                        //
140:                        if (logger.lazyTreeItem == null) {
141:                            // Is top level.
142:                            //
143:                            treeItem = new TreeItem(tree, SWT.NONE);
144:                        } else if (!logger.lazyTreeItem.isDisposed()) {
145:                            // Is not top level, but still valid to write to.
146:                            //
147:                            treeItem = new TreeItem(logger.lazyTreeItem,
148:                                    SWT.NONE);
149:                        } else {
150:                            // The tree item associated with this logger's parent has been
151:                            // disposed, so we simply ignore all pending updates related to it.
152:                            // We also mark that logger dead to avoid adding log events for it.
153:                            //
154:                            logger.markLoggerDead();
155:                            return null;
156:                        }
157:                    }
158:
159:                    // Set the text of the new tree item.
160:                    //
161:                    String label = message;
162:                    if (label == null) {
163:                        if (caught != null) {
164:                            label = caught.getMessage();
165:
166:                            if (label == null || label.trim().length() == 0) {
167:                                label = caught.toString();
168:                            }
169:                        }
170:                    }
171:                    treeItem.setText(label);
172:
173:                    // This LogEvent object becomes the tree item's custom data.
174:                    //
175:                    treeItem.setData(this );
176:
177:                    return treeItem;
178:                }
179:
180:                /**
181:                 * Can only be called by the UI thread.
182:                 */
183:                private void uiStyleChildAndAncestors(TreeLogger.Type type,
184:                        TreeItem child) {
185:                    Display display = child.getDisplay();
186:                    Color color;
187:
188:                    Image image = null;
189:                    if (type == TreeLogger.ERROR) {
190:                        color = display.getSystemColor(SWT.COLOR_RED);
191:                        image = imageError;
192:                    } else if (type == TreeLogger.WARN) {
193:                        color = display.getSystemColor(SWT.COLOR_DARK_YELLOW);
194:                        image = imageWarning;
195:                    } else if (type == TreeLogger.INFO) {
196:                        color = display.getSystemColor(SWT.COLOR_BLACK);
197:                        image = imageInfo;
198:                    } else if (type == TreeLogger.TRACE) {
199:                        color = display.getSystemColor(SWT.COLOR_DARK_GRAY);
200:                        image = imageTrace;
201:                    } else if (type == TreeLogger.DEBUG) {
202:                        color = display.getSystemColor(SWT.COLOR_DARK_CYAN);
203:                        image = imageDebug;
204:                    } else {
205:                        // if (type == TreeLogger.SPAM)
206:                        color = display.getSystemColor(SWT.COLOR_DARK_GREEN);
207:                        image = imageSpam;
208:                    }
209:
210:                    if (image != null) {
211:                        child.setImage(image);
212:                    }
213:
214:                    // Set this item's color.
215:                    //
216:                    child.setForeground(color);
217:
218:                    // For types needing attention, set all parents to the warning color.
219:                    //
220:                    if (type.needsAttention()) {
221:                        /*
222:                         * Originally, this code would expand TreeItems from this child up to
223:                         * its top level ancestor. However, on Mac and Linux, the TreeItems fail
224:                         * to expand if its parent is not already expanded. It appears to be an
225:                         * interaction between SWT and GTK, specifically bug
226:                         * https://bugs.eclipse.org/bugs/show_bug.cgi?id=97757. The following
227:                         * loop stores the ancestors and the second loop will set the expanded
228:                         * attribute on from the top level ancestor down to this child.
229:                         */
230:                        Stack<TreeItem> parents = new Stack<TreeItem>();
231:
232:                        boolean propagateColor = true;
233:                        TreeItem parent = child.getParentItem();
234:                        while (parent != null) {
235:                            parents.push(parent);
236:
237:                            LogEvent parentEvent = (LogEvent) parent.getData();
238:                            if (propagateColor) {
239:                                if (parentEvent.type.isLowerPriorityThan(type)) {
240:                                    parent.setForeground(color);
241:                                } else {
242:                                    propagateColor = false;
243:                                }
244:                            }
245:
246:                            parent = parent.getParentItem();
247:                        }
248:
249:                        while (!parents.isEmpty()) {
250:                            parent = parents.pop();
251:                            parent.setExpanded(true);
252:                        }
253:                    }
254:                }
255:            }
256:
257:            /**
258:             * One object that is shared across all logger instances in the same tree.
259:             * This class is the synchronization choke point that prevents the ui thread
260:             * from flushing events while other threads are adding them, and it also
261:             * provides tree-wide shared objects such as log item images.
262:             */
263:            private static class PendingUpdates {
264:                private List<LogEvent> updates = new LinkedList<LogEvent>();
265:
266:                private final Object updatesLock = new Object();
267:
268:                public void add(LogEvent update) {
269:                    synchronized (updatesLock) {
270:                        updates.add(update);
271:                    }
272:                }
273:
274:                /**
275:                 * Flushes any pending log entries.
276:                 * 
277:                 * @return <code>true</code> if any new entries were written
278:                 */
279:                public synchronized boolean uiFlush(Tree tree) {
280:                    // Move the list to flush into a local copy then release the udpate
281:                    // lock so log events can keep coming in while we flush.
282:                    //
283:                    List<LogEvent> toFlush = null;
284:                    synchronized (updatesLock) {
285:                        if (updates.isEmpty()) {
286:                            // Nothing to do.
287:                            //
288:                            return false;
289:                        }
290:                        toFlush = updates;
291:                        updates = new LinkedList<LogEvent>();
292:                    }
293:
294:                    for (Iterator<LogEvent> iter = toFlush.iterator(); iter
295:                            .hasNext();) {
296:                        LogEvent update = iter.next();
297:                        // Loggers can be die while flushing, so we have to be sure never
298:                        // to try to flush an entry to a dead logger.
299:                        //
300:                        if (!update.logger.isLoggerDead()) {
301:                            update.uiFlush(tree);
302:                        }
303:                    }
304:
305:                    return true;
306:                }
307:            }
308:
309:            // These don't get disposed, but they do last for the entire process, so
310:            // not a big deal.
311:            //
312:            private static final Image imageDebug = tryLoadImage("log-item-debug.gif");
313:            private static final Image imageError = tryLoadImage("log-item-error.gif");
314:            private static final Image imageInfo = tryLoadImage("log-item-info.gif");
315:            private static final Image imageSpam = tryLoadImage("log-item-spam.gif");
316:            private static final Image imageTrace = tryLoadImage("log-item-trace.gif");
317:            private static final Image imageWarning = tryLoadImage("log-item-warning.gif");
318:
319:            private static Image tryLoadImage(String simpleName) {
320:                InputStream is = TreeItemLogger.class
321:                        .getResourceAsStream(simpleName);
322:                if (is != null) {
323:                    try {
324:                        Image image = new Image(null, is);
325:                        return image;
326:                    } finally {
327:                        try {
328:                            is.close();
329:                        } catch (IOException e) {
330:                        }
331:                    }
332:                } else {
333:                    // Bad image.
334:                    //
335:                    return null;
336:                }
337:            }
338:
339:            private boolean dead;
340:
341:            private TreeItem lazyTreeItem;
342:
343:            private final PendingUpdates sharedPendingUpdates;
344:
345:            /**
346:             * Constructs the top-level TreeItemLogger.
347:             */
348:            public TreeItemLogger() {
349:                sharedPendingUpdates = new PendingUpdates();
350:            }
351:
352:            /**
353:             * Constructs an internal logger.
354:             */
355:            private TreeItemLogger(PendingUpdates sharedPendingUpdates) {
356:                // Inherit the one and only update list from my parent.
357:                this .sharedPendingUpdates = sharedPendingUpdates;
358:            }
359:
360:            public void markLoggerDead() {
361:                // Cannot kill the root logger, even if attempted.
362:                //
363:                if (getParentLogger() != null) {
364:                    dead = true;
365:                }
366:            }
367:
368:            /**
369:             * Flushes log records to the UI; must only be called by the UI thread.
370:             * 
371:             * @return <code>true</code> if any new entries were written
372:             */
373:            public boolean uiFlush(Tree tree) {
374:                return sharedPendingUpdates.uiFlush(tree);
375:            }
376:
377:            @Override
378:            protected AbstractTreeLogger doBranch() {
379:                return new TreeItemLogger(sharedPendingUpdates);
380:            }
381:
382:            @Override
383:            protected void doCommitBranch(
384:                    AbstractTreeLogger childBeingCommitted, Type type,
385:                    String msg, Throwable caught) {
386:                if (isLoggerDead()) {
387:                    return;
388:                }
389:
390:                TreeItemLogger commitChild = (TreeItemLogger) childBeingCommitted;
391:                sharedPendingUpdates.add(new LogEvent(commitChild, true,
392:                        commitChild.getBranchedIndex(), type, msg, caught));
393:            }
394:
395:            @Override
396:            protected void doLog(int index, TreeLogger.Type type, String msg,
397:                    Throwable caught) {
398:                if (isLoggerDead()) {
399:                    return;
400:                }
401:
402:                sharedPendingUpdates.add(new LogEvent(this , false, index, type,
403:                        msg, caught));
404:            }
405:
406:            /**
407:             * Used for an extra check to avoid creating log events for dead loggers. A
408:             * dead logger is one that can no longer interact with the UI.
409:             */
410:            private boolean isLoggerDead() {
411:                // Deadness was cached.
412:                //
413:                if (dead) {
414:                    return true;
415:                }
416:
417:                // Check upward in the parent chain for any dead parent.
418:                //
419:                TreeItemLogger parentLogger = (TreeItemLogger) getParentLogger();
420:                if (parentLogger == null) {
421:                    // This is the root logger, which cannot die.
422:                    //
423:                    return false;
424:                }
425:
426:                // Otherwise, this logger is dead if its parent is dead (recursively).
427:                //
428:                if (parentLogger.isLoggerDead()) {
429:                    // This logger is dead because my parent is dead.
430:                    //
431:                    markLoggerDead();
432:                    return true;
433:                }
434:
435:                // I'm not quite dead yet.
436:                //
437:                return false;
438:            }
439:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.