/* * WOEventDisplayPage.java * (c) Copyright 2001 Apple Computer, Inc. All rights reserved. * This a modified version. * Original license: http://www.opensource.apple.com/apsl/ */ package com.webobjects.woextensions; import java.util.Enumeration; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WOEvent; import com.webobjects.eocontrol.EOEvent; import com.webobjects.eocontrol.EOEventCenter; import com.webobjects.eocontrol.EOSortOrdering; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSComparator; import com.webobjects.foundation.NSForwardException; import com.webobjects.foundation.NSMutableArray; import com.webobjects.foundation.NSMutableDictionary; public class WOEventDisplayPage extends WOEventPage { /** * Do I need to update serialVersionUID? * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a> */ private static final long serialVersionUID = 1L; public EOEvent currentEvent; public NSArray selectionPath; public int _displayMode; public NSArray events; public NSMutableDictionary cache; public NSMutableArray webEvents, eofEvents; public WOEventDisplayPage _self = this; protected _EventComparator _eventAscendingComparator; public WOEventDisplayPage(WOContext aContext) { super(aContext); selectionPath = new NSMutableArray(); _displayMode = 1; cache = new NSMutableDictionary(); // we sort these things descending, i.e. the opposite of normal sorting order _eventAscendingComparator = new _EventComparator(EOSortOrdering.CompareDescending, this); } public int displayMode() { return _displayMode; } public void setDisplayMode(Object ick) { if (ick == null) { _displayMode = 0; } else if (ick instanceof Number) { _displayMode = ((Number)ick).intValue(); } else { try { _displayMode = Integer.parseInt(ick.toString()); } catch (NumberFormatException e) { _displayMode = 0; } } } public int displayLevelForEvent(EOEvent e) { int index, i, n; NSArray children; index = selectionPath.indexOfObject(e); if (index != NSArray.NotFound) return index; children = rootEventList(); if (children.containsObject(e)) return 0; int count = selectionPath.count(); for (i = 0, n = count; i < n; i++) { children = (NSArray)cache.objectForKey(selectionPath.objectAtIndex(i)); if (null==children) break; if (children.containsObject(e)) return i+1; } return -1; } public NSArray filterEvents(NSArray evs, int level) { int i, n; NSArray filtered; if (evs == null) { return NSArray.EmptyArray; } // in the general case, it is sufficient to sort the events // by their plain duration, which is what the default implementation does. try { if (_displayMode != 4 || level != 0) { try { filtered = evs.sortedArrayUsingComparator(_eventAscendingComparator); } catch (IllegalStateException ex) { filtered = evs; } } else { // For association mode, we need to filter out unwanted events, // i.e. those which are not related to associations. int count = evs.count(); NSMutableArray mutableFiltered = new NSMutableArray(count); for (i = 0, n = count; i < n; i++) { if (childrenForEvent((EOEvent)evs.objectAtIndex(i)).count()!=0) mutableFiltered.addObject(evs.objectAtIndex(i)); } mutableFiltered.sortUsingComparator(_eventAscendingComparator); filtered = mutableFiltered; } } catch (NSComparator.ComparisonException e) { throw NSForwardException._runtimeExceptionForThrowable(e); } return filtered; } public int groupTagForDisplayLevel(int level) { switch (_displayMode) { case 0: return -1; case 1: return -1; case 2: switch (level) { case 0: return 2; case 1: return 1; default: return -1; } case 3: if (level == 0) return 2; else return -1; case 4: if (level == 0) return 2; else return -1; default: // bogus return -1; } } public int aggregateTagForDisplayLevel(int level) { switch (_displayMode) { case 0: return -1; case 1: return 0; case 2: if (level <= 1) return -1; else return 0; case 3: if (level == 0) return -1; else return 0; case 4: if (level == 0) return -1; else return 3; default: // bogus return -1; } } public NSArray rootEventList() { if (null == events) { switch (_displayMode) { case 0: case 1: events = EOEventCenter.rootEventsForAllCenters(); break; default: events = EOEventCenter.allEventsForAllCenters(); break; } events = EOEvent.groupEvents(events, groupTagForDisplayLevel(0)); events = EOEvent.aggregateEvents(events, aggregateTagForDisplayLevel(0)); events = filterEvents(events, 0); } return events; } public EOEvent object() { return currentEvent; } public NSArray childrenForEvent(EOEvent event) { NSArray anArray; int level, tag; anArray = (NSArray)cache.objectForKey(event); if (null!=anArray) { if (anArray.count()==0) return null; else return anArray; } anArray = event.subevents(); if (anArray == null || (anArray.count()==0)) { cache.setObjectForKey(NSArray.EmptyArray, event); return null; } level = displayLevelForEvent(event) + 1; if (level == -1) level = selectionPath.count() + 1; tag = groupTagForDisplayLevel(level); if (tag >= 0) anArray = EOEvent.groupEvents(anArray, tag); tag = aggregateTagForDisplayLevel(level); if (tag >= 0) anArray = EOEvent.aggregateEvents(anArray, tag); anArray = filterEvents(anArray, level); cache.setObjectForKey(anArray, event); return anArray; } public NSArray currentEventChildren() { NSArray result = childrenForEvent(currentEvent); return (result != null) ? result : NSArray.EmptyArray; } public boolean isDirectory() { return currentEventChildren().count() > 0; } public WOComponent resetLoggingClicked() { EOEventCenter.resetLoggingForAllCenters(); return refreshLoggingClicked(); } public WOComponent refreshLoggingClicked() { cache.removeAllObjects(); selectionPath = new NSMutableArray(); events = null; webEvents = null; eofEvents = null; return null; } public String displayComponentName() { if (currentEvent == null) { return ""; } return currentEvent.displayComponentName(); } public int eventCount() { return EOEventCenter.allEventsForAllCenters().count(); } public long topmostDurationValue() { NSArray roots; roots = rootEventList(); if (roots == null || (roots.count()==0)) return 0; else return durationOfEvent((EOEvent)roots.objectAtIndex(0)); } public long durationOfEvent(EOEvent e) { int i, n; long sum; NSArray kids; // mode 4 is in so far special as we need to filter out events which will not // be displayed, even if they may have a duration. if (_displayMode != 4) { sum = e.duration(); return sum; } // if an event has no kids, but we are still here, it means that it is // an association event (because otherwise it would be filtered out). kids = childrenForEvent(e); if (kids == null) { kids = NSArray.EmptyArray; } n = kids.count(); if (n!=0) { for (i = 0, sum = 0; i < n; i++) { sum += ((EOEvent)kids.objectAtIndex(i)).duration(); } } else { sum = e.duration(); } return sum; } public void _cacheWebEofEvents() { if (webEvents != null) return; NSArray allCenters = EOEventCenter.allEventsForAllCenters(); int halfCount = allCenters.count() / 2; webEvents = new NSMutableArray(halfCount); eofEvents = new NSMutableArray(halfCount); Enumeration anEnumerator = allCenters.objectEnumerator(); while (anEnumerator.hasMoreElements()) { EOEvent e = (EOEvent) anEnumerator.nextElement(); if (e instanceof WOEvent) webEvents.addObject(e); else eofEvents.addObject(e); } } public int webEventDuration() { int i, n, time; _cacheWebEofEvents(); n = (webEvents != null) ? webEvents.count() : 0; for (i = 0, time = 0; i < n; i++) { EOEvent e = (EOEvent) webEvents.objectAtIndex(i); if (e instanceof WOEvent) time = time + (int) e.durationWithoutSubevents(); } return time; } public int eofEventDuration() { int i, n, time; _cacheWebEofEvents(); n = (eofEvents != null) ? eofEvents.count() : 0; for (i = 0, time = 0; i < n; i++) { EOEvent e = (EOEvent) eofEvents.objectAtIndex(i); if (!(e instanceof WOEvent)) time = time + (int) e.durationWithoutSubevents(); } return time; } public int webEventCount() { _cacheWebEofEvents(); return (webEvents != null) ? webEvents.count() : 0; } public int eofEventCount() { _cacheWebEofEvents(); return (eofEvents != null) ? eofEvents.count() : 0; } public boolean isEmpty() { return eventCount() == 0; } }