### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.views.log Index: src/org/eclipse/ui/internal/views/log/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/messages.properties,v retrieving revision 1.4 diff -u -r1.4 messages.properties --- src/org/eclipse/ui/internal/views/log/messages.properties 8 Nov 2007 01:20:02 -0000 1.4 +++ src/org/eclipse/ui/internal/views/log/messages.properties 30 Nov 2007 12:30:47 -0000 @@ -53,6 +53,10 @@ LogView_FilterDialog_eventsLogged = Show events logged during: LogView_FilterDialog_allSessions = &All sessions LogView_FilterDialog_recentSession = &Most recent session +LogView_GroupBy=Group by +LogView_GroupByNone=None +LogView_GroupByPlugin=Plug-in +LogView_GroupBySession=Session LogViewLabelProvider_truncatedMessage=... (Open log entry details for full message) LogViewLabelProvider_Session=Session Index: src/org/eclipse/ui/internal/views/log/LogSession.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/LogSession.java,v retrieving revision 1.2 diff -u -r1.2 LogSession.java --- src/org/eclipse/ui/internal/views/log/LogSession.java 22 Oct 2007 15:18:42 -0000 1.2 +++ src/org/eclipse/ui/internal/views/log/LogSession.java 30 Nov 2007 12:30:46 -0000 @@ -11,28 +11,23 @@ *******************************************************************************/ package org.eclipse.ui.internal.views.log; +import java.io.PrintWriter; import java.text.ParseException; -import java.util.ArrayList; import java.util.Date; -import java.util.List; - -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.model.IWorkbenchAdapter; import com.ibm.icu.text.SimpleDateFormat; -public class LogSession extends PlatformObject implements IWorkbenchAdapter { +/** + * Group of entries with additional Session data. + */ +public class LogSession extends Group { private String sessionData; private Date date; - private List entries = new ArrayList(); - - /** - * Constructor for LogSession. - */ + public LogSession() { + super(Messages.LogViewLabelProvider_Session); } - + public Date getDate() { return date; } @@ -63,24 +58,8 @@ String dateBuffer = line.substring(0, delim).trim(); setDate(dateBuffer); } - - public List getEntries() { - return entries; - } - - public Object[] getChildren(Object o) { - return getEntries().toArray(new LogEntry[getEntries().size()]); - } - - public ImageDescriptor getImageDescriptor(Object object) { - return null; - } - - public String getLabel(Object o) { - return null; - } - public Object getParent(Object o) { - return null; + public void write(PrintWriter writer) { + writer.write(sessionData); } } Index: src/org/eclipse/ui/internal/views/log/Messages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/Messages.java,v retrieving revision 1.5 diff -u -r1.5 Messages.java --- src/org/eclipse/ui/internal/views/log/Messages.java 8 Nov 2007 01:20:02 -0000 1.5 +++ src/org/eclipse/ui/internal/views/log/Messages.java 30 Nov 2007 12:30:47 -0000 @@ -59,6 +59,10 @@ public static String LogView_FilterDialog_eventsLogged; public static String LogView_FilterDialog_allSessions; public static String LogView_FilterDialog_recentSession; + public static String LogView_GroupBy; + public static String LogView_GroupByNone; + public static String LogView_GroupByPlugin; + public static String LogView_GroupBySession; public static String LogViewLabelProvider_Session; public static String LogViewLabelProvider_truncatedMessage; Index: src/org/eclipse/ui/internal/views/log/LogViewLabelProvider.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/LogViewLabelProvider.java,v retrieving revision 1.4 diff -u -r1.4 LogViewLabelProvider.java --- src/org/eclipse/ui/internal/views/log/LogViewLabelProvider.java 22 Oct 2007 15:18:42 -0000 1.4 +++ src/org/eclipse/ui/internal/views/log/LogViewLabelProvider.java 30 Nov 2007 12:30:47 -0000 @@ -11,6 +11,8 @@ *******************************************************************************/ package org.eclipse.ui.internal.views.log; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import org.eclipse.core.runtime.IStatus; @@ -18,9 +20,6 @@ import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.graphics.Image; -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.text.SimpleDateFormat; - public class LogViewLabelProvider extends LabelProvider implements ITableLabelProvider { @@ -49,7 +48,7 @@ } } public Image getColumnImage(Object element, int columnIndex) { - if (element instanceof LogSession) { + if (element instanceof Group) { return (columnIndex == 0) ? hierarchicalImage : null; } @@ -70,38 +69,41 @@ } public String getColumnText(Object element, int columnIndex) { - if (element instanceof LogSession) { - LogSession entry = (LogSession) element; - if (columnIndex == 0) { - return Messages.LogViewLabelProvider_Session; - } else if (columnIndex == 2) { - if (entry.getDate() != null) { - DateFormat formatter = new SimpleDateFormat(LogEntry.F_DATE_FORMAT); - return formatter.format(entry.getDate()); - } - } - return null; + if ((element instanceof LogSession) && (columnIndex == 2)) { + LogSession session = (LogSession) element; + if (session.getDate() == null) + return ""; //$NON-NLS-1$ + + DateFormat formatter = new SimpleDateFormat(LogEntry.F_DATE_FORMAT); + return formatter.format(session.getDate()); } - LogEntry entry = (LogEntry) element; - switch (columnIndex) { - case 0: - if (entry.getMessage() != null) { - String message = entry.getMessage(); - if (message.length() > MAX_LABEL_LENGTH) { - String warning = Messages.LogViewLabelProvider_truncatedMessage; - StringBuffer sb = new StringBuffer(message.substring(0, MAX_LABEL_LENGTH - warning.length())); - sb.append(warning); - return sb.toString(); + if ((element instanceof Group) && (columnIndex == 0)) { + return element.toString(); + } + + if (element instanceof LogEntry) { + LogEntry entry = (LogEntry) element; + switch (columnIndex) { + case 0: + if (entry.getMessage() != null) { + String message = entry.getMessage(); + if (message.length() > MAX_LABEL_LENGTH) { + String warning = Messages.LogViewLabelProvider_truncatedMessage; + StringBuffer sb = new StringBuffer(message.substring(0, MAX_LABEL_LENGTH - warning.length())); + sb.append(warning); + return sb.toString(); + } + return entry.getMessage(); } - return entry.getMessage(); + case 1: + if (entry.getPluginId() != null) + return entry.getPluginId(); + case 2: + return entry.getFormattedDate(); } - case 1: - if (entry.getPluginId() != null) - return entry.getPluginId(); - case 2: - return entry.getFormattedDate(); } + return ""; //$NON-NLS-1$ } Index: src/org/eclipse/ui/internal/views/log/LogView.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/LogView.java,v retrieving revision 1.11 diff -u -r1.11 LogView.java --- src/org/eclipse/ui/internal/views/log/LogView.java 8 Nov 2007 01:23:43 -0000 1.11 +++ src/org/eclipse/ui/internal/views/log/LogView.java 30 Nov 2007 12:30:47 -0000 @@ -26,7 +26,14 @@ import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import org.eclipse.core.runtime.ILogListener; import org.eclipse.core.runtime.IProgressMonitor; @@ -37,6 +44,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; @@ -116,6 +124,7 @@ public static final String P_SHOW_FILTER_TEXT = "show_filter_text"; //$NON-NLS-1$ public static final String P_ORDER_TYPE = "orderType"; //$NON-NLS-1$ public static final String P_ORDER_VALUE = "orderValue"; //$NON-NLS-1$ + public static final String P_GROUP_BY = "groupBy"; //$NON-NLS-1$ private int MESSAGE_ORDER; private int PLUGIN_ORDER; @@ -127,7 +136,13 @@ public static int ASCENDING = 1; public static int DESCENDING = -1; - private ArrayList fLogs; + public static final int GROUP_BY_NONE = 0; + public static final int GROUP_BY_SESSION = 1; + public static final int GROUP_BY_PLUGIN = 2; + + private List elements; + private Map groups; + private LogSession currentSession; private Clipboard fClipboard; @@ -161,10 +176,35 @@ private Action fExportAction; /** + * Action called when user selects "Group by -> ..." from menu. + */ + class GroupByAction extends Action { + private int groupBy; + + public GroupByAction(String text, int groupBy) { + super(text, Action.AS_RADIO_BUTTON); + + this.groupBy = groupBy; + + if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() == groupBy) { + setChecked(true); + } + } + + public void run() { + if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() != groupBy) { + fMemento.putInteger(LogView.P_GROUP_BY, groupBy); + reloadLog(); + } + } + } + + /** * Constructor */ public LogView() { - fLogs = new ArrayList(); + elements = new ArrayList(); + groups = new HashMap(); fInputFile = Platform.getLogFileLocation().toFile(); } @@ -228,14 +268,20 @@ toolBarManager.add(new Separator()); IMenuManager mgr = bars.getMenuManager(); - mgr.add(createFilterAction()); + + mgr.add(createGroupByAction()); + mgr.add(new Separator()); + + mgr.add(createFilterAction()); + mgr.add(new Separator()); + fActivateViewAction = createActivateViewAction(); mgr.add(fActivateViewAction); mgr.add(createShowTextFilter()); - + createPropertiesAction(); MenuManager popupMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$ @@ -437,6 +483,16 @@ fFilteredTree.layout(false); } + private IContributionItem createGroupByAction() { + IMenuManager groupByMenu = new MenuManager(Messages.LogView_GroupBy); + + groupByMenu.add(new GroupByAction(Messages.LogView_GroupByNone, LogView.GROUP_BY_NONE)); + groupByMenu.add(new GroupByAction(Messages.LogView_GroupBySession, LogView.GROUP_BY_SESSION)); + groupByMenu.add(new GroupByAction(Messages.LogView_GroupByPlugin, LogView.GROUP_BY_PLUGIN)); + + return groupByMenu; + } + private void createViewer(Composite parent) { fFilteredTree = new FilteredTree(parent, SWT.FULL_SELECTION, new PatternFilter() { @@ -556,8 +612,7 @@ Platform.removeLogListener(this); fClipboard.dispose(); if (fTextShell != null) - fTextShell.dispose(); - LogReader.reset(); + fTextShell.dispose(); fLabelProvider.disconnect(this); fFilteredTree.dispose(); super.dispose(); @@ -654,8 +709,10 @@ String message = Messages.LogView_confirmDelete_message; if (!MessageDialog.openConfirm(fTree.getShell(), title, message)) return; - if (fInputFile.delete() || fLogs.size() > 0) { - fLogs.clear(); + if (fInputFile.delete() || elements.size() > 0) { + elements.clear(); + groups.clear(); + currentSession.removeAllChildren(); asyncRefresh(false); resetDialogButtons(); } @@ -664,15 +721,17 @@ public void fillContextMenu(IMenuManager manager) { } - public LogSession[] getLogs() { - return (LogSession[]) fLogs.toArray(new LogSession[fLogs.size()]); + public AbstractEntry[] getElements() { + return (AbstractEntry[]) elements.toArray(new AbstractEntry[elements.size()]); } protected void handleClear() { BusyIndicator.showWhile(fTree.getDisplay(), new Runnable() { public void run() { - fLogs.clear(); + elements.clear(); + groups.clear(); + currentSession.removeAllChildren(); asyncRefresh(false); resetDialogButtons(); } @@ -700,10 +759,138 @@ } private void readLogFile() { - fLogs.clear(); if (!fInputFile.exists()) return; - LogReader.parseLogFile(fInputFile, fLogs, fMemento); + + elements.clear(); + groups.clear(); + + List result = new ArrayList(); + currentSession = LogReader.parseLogFile(fInputFile, result, fMemento); + group(result); + limitEntriesCount(); + } + + /** + * Add new entries to correct groups in the view. + * @param entries new entries to show up in groups in the view. + */ + private void group(List entries) { + if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) { + elements.addAll(entries); + } else { + for (Iterator i = entries.iterator(); i.hasNext(); ) { + LogEntry entry = (LogEntry) i.next(); + Group group = getGroup(entry); + group.addChild(entry); + } + } + } + + /** + * Limits the number of entries according to the max entries limit set in + * memento. + */ + private void limitEntriesCount() { + int limit = Integer.MAX_VALUE; + if (fMemento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$ + limit = fMemento.getInteger(LogView.P_LOG_LIMIT).intValue(); + } + + int entriesCount = getEntriesCount(); + + if (entriesCount <= limit) { + return; + } else { // remove oldest + Comparator dateComparator = new Comparator() { + public int compare(Object o1, Object o2) { + Date l1 = ((LogEntry) o1).getDate(); + Date l2 = ((LogEntry) o2).getDate(); + if ((l1 != null) && (l2 != null)) { + return l1.before(l2) ? -1 : 1; + } else if ((l1 == null) && (l2 == null)) { + return 0; + } else return (l1 == null) ? -1 : 1; + } + }; + + if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) { + elements.subList(0, elements.size() - limit).clear(); + } else { + List copy = new ArrayList(entriesCount); + for (Iterator i = elements.iterator(); i.hasNext(); ) { + AbstractEntry group = (AbstractEntry) i.next(); + copy.addAll(Arrays.asList(group.getChildren(group))); + } + + Collections.sort(copy, dateComparator); + List toRemove = copy.subList(0, copy.size() - limit); + + for (Iterator i = elements.iterator(); i.hasNext(); ) { + AbstractEntry group = (AbstractEntry) i.next(); + group.removeChildren(toRemove); + } + } + } + + } + + private int getEntriesCount() { + if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) { + return elements.size(); + } else { + int size = 0; + for (Iterator i = elements.iterator(); i.hasNext(); ) { + AbstractEntry group = (AbstractEntry)i.next(); + size += group.size(); + } + return size; + } + } + + /** + * Returns group appropriate for the entry. Group depends on P_GROUP_BY + * preference, or is null if grouping is disabled (GROUP_BY_NONE), or group + * could not be determined. May create group if it haven't existed before. + * + * @param entry entry to be grouped + * @return group or null if grouping is disabled + */ + protected Group getGroup(LogEntry entry) { + int groupBy = fMemento.getInteger(P_GROUP_BY).intValue(); + Object elementGroupId = null; + String groupName = null; + + switch (groupBy) { + case GROUP_BY_PLUGIN: + groupName = entry.getPluginId(); + elementGroupId = groupName; + break; + + case GROUP_BY_SESSION: + elementGroupId = entry.getSession(); + break; + + default: // grouping is disabled + return null; + } + + if (elementGroupId == null) { // could not determine group + return null; + } + + Group group = (Group) groups.get(elementGroupId); + if (group == null) { + if (groupBy == GROUP_BY_SESSION) { + group = entry.getSession(); + } else { + group = new Group(groupName); + } + groups.put(elementGroupId, group); + elements.add(group); + } + + return group; } public void logging(IStatus status, String plugin) { @@ -711,23 +898,21 @@ return; if (fFirstEvent) { readLogFile(); - asyncRefresh(); + asyncRefresh(true); fFirstEvent = false; } else { pushStatus(status); } } - private void pushStatus(IStatus status) { + private synchronized void pushStatus(IStatus status) { LogEntry entry = new LogEntry(status); - if (fLogs.isEmpty()) { - fLogs.add(new LogSession()); + entry.setSession(currentSession); + + if (LogReader.isLogged(entry, fMemento)) { + group(Collections.singletonList(entry)); + limitEntriesCount(); } - LogReader.addEntry(entry, ((LogSession)fLogs.get(fLogs.size() - 1)).getEntries(), fMemento, true); - asyncRefresh(); - } - - private void asyncRefresh() { asyncRefresh(true); } @@ -875,6 +1060,9 @@ } fMemento.putInteger(P_ORDER_VALUE, DESCENDING); fMemento.putInteger(P_ORDER_TYPE, DATE); + if (fMemento.getInteger(P_GROUP_BY) == null) { + fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE); + } } public void saveState(IMemento memento) { @@ -1017,8 +1205,8 @@ } } - private int getNumberOfParents(LogEntry entry){ - LogEntry parent = (LogEntry)entry.getParent(entry); + private int getNumberOfParents(AbstractEntry entry){ + AbstractEntry parent = (AbstractEntry)entry.getParent(entry); if (parent ==null) return 0; return 1 + getNumberOfParents(parent); @@ -1042,7 +1230,7 @@ date2 = ((LogSession) e2).getDate() == null ? 0 : ((LogSession) e2).getDate().getTime(); } if (date1 == date2) { - int result = fLogs.indexOf(e2) - fLogs.indexOf(e1); + int result = elements.indexOf(e2) - elements.indexOf(e1); if (DATE_ORDER == DESCENDING) result *= DESCENDING; return result; @@ -1118,7 +1306,7 @@ } if (date1 == date2) { - int result = fLogs.indexOf(e2) - fLogs.indexOf(e1); + int result = elements.indexOf(e2) - elements.indexOf(e1); if (DATE_ORDER == DESCENDING) result *= DESCENDING; return result; @@ -1176,6 +1364,7 @@ fMemento.putInteger(P_ORDER_VALUE, order == 0 ? DESCENDING : order); fMemento.putInteger(P_ORDER_TYPE, p.getInt(P_ORDER_TYPE)); fMemento.putBoolean(P_SHOW_FILTER_TEXT, p.getBoolean(P_SHOW_FILTER_TEXT)); + fMemento.putInteger(P_GROUP_BY, p.getInt(P_GROUP_BY)); } catch (NumberFormatException e) { fMemento.putInteger(P_LOG_LIMIT, 50); fMemento.putInteger(P_COLUMN_1, 300); @@ -1183,6 +1372,7 @@ fMemento.putInteger(P_COLUMN_3, 150); fMemento.putInteger(P_ORDER_TYPE, DATE); fMemento.putInteger(P_ORDER_VALUE, DESCENDING); + fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE); } } @@ -1213,6 +1403,7 @@ preferences.setValue(P_ORDER_VALUE, order == 0 ? DESCENDING : order); preferences.setValue(P_ORDER_TYPE, fMemento.getInteger(P_ORDER_TYPE).intValue()); preferences.setValue(P_SHOW_FILTER_TEXT, fMemento.getBoolean(P_SHOW_FILTER_TEXT).booleanValue()); + preferences.setValue(P_GROUP_BY, fMemento.getInteger(P_GROUP_BY).intValue()); } public void sortByDateDescending() { Index: src/org/eclipse/ui/internal/views/log/LogEntry.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/LogEntry.java,v retrieving revision 1.3 diff -u -r1.3 LogEntry.java --- src/org/eclipse/ui/internal/views/log/LogEntry.java 13 Nov 2007 14:55:27 -0000 1.3 +++ src/org/eclipse/ui/internal/views/log/LogEntry.java 30 Nov 2007 12:30:46 -0000 @@ -14,24 +14,20 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.text.ParseException; -import java.util.ArrayList; import java.util.Date; import java.util.StringTokenizer; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.PlatformObject; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.model.IWorkbenchAdapter; import com.ibm.icu.text.SimpleDateFormat; -public class LogEntry extends PlatformObject implements IWorkbenchAdapter { +public class LogEntry extends AbstractEntry { public static final String F_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$ private static final SimpleDateFormat F_SDF = new SimpleDateFormat(F_DATE_FORMAT); - private ArrayList children; - private LogEntry parent; private String pluginId; private int severity; private int code; @@ -44,8 +40,8 @@ public LogEntry() {} public LogSession getSession() { - if ((session == null) && (parent != null)) - return parent.getSession(); + if ((session == null) && (parent != null) && (parent instanceof LogEntry)) + return ((LogEntry)parent).getSession(); return session; } @@ -89,21 +85,11 @@ public String getSeverityText() { return getSeverityText(severity); } - public boolean hasChildren() { - return children != null && children.size() > 0; - } + public String toString() { return getSeverityText(); } - /** - * @see IWorkbenchAdapter#getChildren(Object) - */ - public Object[] getChildren(Object parent) { - if (children == null) - return new Object[0]; - return children.toArray(); - } - + /** * @see IWorkbenchAdapter#getImageDescriptor(Object) */ @@ -118,17 +104,6 @@ return getSeverityText(); } - /** - * @see IWorkbenchAdapter#getParent(Object) - */ - public Object getParent(Object obj) { - return parent; - } - - void setParent(LogEntry parent) { - this.parent = parent; - } - private String getSeverityText(int severity) { switch (severity) { case IStatus.ERROR : @@ -283,19 +258,13 @@ } IStatus[] schildren = status.getChildren(); if (schildren.length > 0) { - children = new ArrayList(); for (int i = 0; i < schildren.length; i++) { LogEntry child = new LogEntry(schildren[i]); addChild(child); } } } - void addChild(LogEntry child) { - if (children == null) - children = new ArrayList(); - children.add(child); - child.setParent(this); - } + public void write(PrintWriter writer) { if (session != null) writer.println(session.getSessionData()); Index: src/org/eclipse/ui/internal/views/log/EventDetailsDialogAction.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/EventDetailsDialogAction.java,v retrieving revision 1.2 diff -u -r1.2 EventDetailsDialogAction.java --- src/org/eclipse/ui/internal/views/log/EventDetailsDialogAction.java 22 Oct 2007 15:18:42 -0000 1.2 +++ src/org/eclipse/ui/internal/views/log/EventDetailsDialogAction.java 30 Nov 2007 12:30:46 -0000 @@ -56,7 +56,7 @@ } public void resetSelection(){ IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement(); - if (element == null) + if ((element == null) || (! (element instanceof LogEntry))) return; if (propertyDialog != null && propertyDialog.isOpen()) propertyDialog.resetSelection(element); @@ -81,7 +81,7 @@ //get initial selection IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement(); - if ((element == null) || (element instanceof LogSession)) + if ((element == null) || (! (element instanceof LogEntry))) return; propertyDialog = new EventDetailsDialog(shell, element, provider, comparator); Index: src/org/eclipse/ui/internal/views/log/LogViewContentProvider.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/LogViewContentProvider.java,v retrieving revision 1.2 diff -u -r1.2 LogViewContentProvider.java --- src/org/eclipse/ui/internal/views/log/LogViewContentProvider.java 22 Oct 2007 15:18:42 -0000 1.2 +++ src/org/eclipse/ui/internal/views/log/LogViewContentProvider.java 30 Nov 2007 12:30:47 -0000 @@ -11,8 +11,6 @@ *******************************************************************************/ package org.eclipse.ui.internal.views.log; -import java.util.List; - import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; @@ -25,26 +23,19 @@ public void dispose() { } public Object[] getChildren(Object element) { - if (element instanceof LogSession) { - List entries = ((LogSession) element).getEntries(); - return entries.toArray(new LogEntry[entries.size()]); - } - return ((LogEntry) element).getChildren(element); + return ((AbstractEntry) element).getChildren(element); } public Object[] getElements(Object element) { - return logView.getLogs(); + return logView.getElements(); } public Object getParent(Object element) { if (element instanceof LogSession) { return null; } - return ((LogEntry) element).getParent(element); + return ((AbstractEntry) element).getParent(element); } public boolean hasChildren(Object element) { - if (element instanceof LogSession) { - return ((LogSession) element).getEntries().size() > 0; - } - return ((LogEntry) element).hasChildren(); + return ((AbstractEntry) element).getChildren(element).length > 0; } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } Index: src/org/eclipse/ui/internal/views/log/EventDetailsDialog.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.views.log/src/org/eclipse/ui/internal/views/log/EventDetailsDialog.java,v retrieving revision 1.5 diff -u -r1.5 EventDetailsDialog.java --- src/org/eclipse/ui/internal/views/log/EventDetailsDialog.java 25 Oct 2007 15:54:49 -0000 1.5 +++ src/org/eclipse/ui/internal/views/log/EventDetailsDialog.java 30 Nov 2007 12:30:46 -0000 @@ -15,8 +15,8 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.text.Collator; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; @@ -29,6 +29,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; @@ -49,12 +50,18 @@ import org.eclipse.ui.PlatformUI; public class EventDetailsDialog extends TrayDialog { - private LogEntry entry, parentEntry; + private AbstractEntry entry; + private AbstractEntry parentEntry; // parent of the entry + private AbstractEntry[] entryChildren; // children of the entry + private LogViewLabelProvider labelProvider; - private static int COPY_ID = 22; private TreeViewer provider; - private int elementNum, totalElementCount; - private LogEntry[] entryChildren; + + private static int COPY_ID = 22; + + private int elementNum; // number of selected element + private int totalElementCount; // number of all elements + private int childIndex = 0; private boolean isOpen; private boolean isLastChild; @@ -93,7 +100,7 @@ this.provider = (TreeViewer) provider; labelProvider = (LogViewLabelProvider)this.provider.getLabelProvider(); labelProvider.connect(this); - this.entry = (LogEntry)selection; + this.entry = (AbstractEntry)selection; this.comparator = comparator; setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE); clipboard = new Clipboard(parentShell.getDisplay()); @@ -107,44 +114,41 @@ private void initialize() { elementNum = getParentElementNum(); resetTotalElementCount(); - parentEntry = (LogEntry) entry.getParent(entry); + parentEntry = (AbstractEntry) entry.getParent(entry); if (isChild(entry)){ setEntryChildren(parentEntry); resetChildIndex(); + } else { + setEntryChildren(); } isLastChild = false; isAtEndOfLog = false; } private void resetChildIndex() { + if (! (entry instanceof AbstractEntry)) { + return; + } + + if (entryChildren == null) + return; + + LogEntry thisEntry = (LogEntry) entry; + for (int i = 0; i < entryChildren.length; i++) { - if (equal(entryChildren[i].getMessage(), entry.getMessage()) - && equal(entryChildren[i].getDate(), entry.getDate()) - && equal(entryChildren[i].getPluginId(), entry - .getPluginId()) - && entryChildren[i].getSeverity() == entry.getSeverity() - && equal(entryChildren[i].getSeverityText(), entry - .getSeverityText())) { - childIndex = i; - break; + if (entryChildren[i] instanceof LogEntry) { + + LogEntry logEntry = (LogEntry) entryChildren[i]; + + if (logEntry == thisEntry) { + childIndex = i; + return; + } } } } - private boolean equal(String str1, String str2) { - if (str1 == null) { - return str1 == str2; - } - return str1.equals(str2); - } - - private boolean equal(Date d1, Date d2) { - if (d1 == null) - return d1 == d2; - return d1.equals(d2); - } - - private boolean isChild(LogEntry entry) { + private boolean isChild(AbstractEntry entry) { return entry.getParent(entry) != null; } @@ -212,12 +216,21 @@ } childIndex--; entry = entryChildren[childIndex]; - } else - entry = parentEntry; + } else { + if (parentEntry instanceof LogEntry) { + entry = parentEntry; + if (isChild(entry)) { + setEntryChildren((AbstractEntry)entry.getParent(entry)); + } else { + setEntryChildren(); + } + } + } } else { - if (elementNum - 1 >= 0) + if ((elementNum - 1 >= 0) && (entryChildren[elementNum-1] instanceof LogEntry)) { elementNum -= 1; - entry = entryChildren[elementNum]; + entry = entryChildren[elementNum]; + } } setEntrySelectionInTable(); } @@ -229,18 +242,23 @@ isLastChild = childIndex == entryChildren.length - 1; } else if (isChild(entry) && isLastChild && !isAtEndOfLog){ findNextSelectedChild(entry); - } else if (elementNum + 1 < totalElementCount){ + } else if (elementNum + 1 < totalElementCount){ // at end of element, go to next element if (isLastChild){ setEntryChildren(); isLastChild = false; } - elementNum += 1; - entry = entryChildren[elementNum]; + + if (entryChildren[elementNum+1] instanceof LogEntry) { + elementNum += 1; + entry = entryChildren[elementNum]; + } } else { // at end of list but can branch into child elements - bug 58083 - setEntryChildren(entry); - entry = entryChildren[0]; - isAtEndOfLog = entryChildren.length == 0; - isLastChild = entryChildren.length == 0; + if (entry.hasChildren()) { + setEntryChildren(entry); + entry = entryChildren[0]; + isAtEndOfLog = entryChildren.length == 0; + isLastChild = entryChildren.length == 0; + } } setEntrySelectionInTable(); } @@ -306,8 +324,8 @@ updateProperties(); return; } - if (selectedEntry instanceof LogEntry) { - entry = (LogEntry)selectedEntry; + if (selectedEntry instanceof AbstractEntry) { + entry = (AbstractEntry)selectedEntry; initialize(); updateProperties(); } @@ -325,7 +343,7 @@ public void updateProperties() { if (isChild(entry)){ - parentEntry = (LogEntry) entry.getParent(entry); + parentEntry = (AbstractEntry) entry.getParent(entry); setEntryChildren(parentEntry); resetChildIndex(); if (childIndex == entryChildren.length - 1) @@ -334,21 +352,35 @@ resetTotalElementCount(); - String strDate = entry.getFormattedDate(); - dateLabel.setText(strDate); - severityImageLabel.setImage(labelProvider.getColumnImage(entry, 0)); - severityLabel.setText(entry.getSeverityText()); - msgText.setText(entry.getMessage() != null ? entry.getMessage() : ""); //$NON-NLS-1$ - String stack = entry.getStack(); - if (stack != null) { - stackTraceText.setText(stack); + if (entry instanceof LogEntry) { + LogEntry logEntry = (LogEntry) entry; + + String strDate = logEntry.getFormattedDate(); + dateLabel.setText(strDate); + severityImageLabel.setImage(labelProvider.getColumnImage(entry, 0)); + severityLabel.setText(logEntry.getSeverityText()); + msgText.setText(logEntry.getMessage() != null ? logEntry.getMessage() : ""); //$NON-NLS-1$ + String stack = logEntry.getStack(); + if (stack != null) { + stackTraceText.setText(stack); + } else { + stackTraceText.setText(Messages.EventDetailsDialog_noStack); + } + + String session = logEntry.getSession().getSessionData(); + if (stack != null) { + sessionDataText.setText(session); + } + } else { - stackTraceText.setText(Messages.EventDetailsDialog_noStack); + dateLabel.setText(""); //$NON-NLS-1$ + severityImageLabel.setImage(null); + severityLabel.setText(""); //$NON-NLS-1$ + msgText.setText(""); //$NON-NLS-1$ + stackTraceText.setText(""); //$NON-NLS-1$ + sessionDataText.setText(""); //$NON-NLS-1$ } - LogSession session = entry.getSession(); - if (session != null && session.getSessionData() != null) - sessionDataText.setText(session.getSessionData()); - + updateButtons(); } @@ -363,15 +395,15 @@ } } - private void findNextSelectedChild(LogEntry originalEntry){ + private void findNextSelectedChild(AbstractEntry originalEntry){ if (isChild (parentEntry)){ // we're at the end of the child list; find next parent // to select. If the parent is a child at the end of the child // list, find its next parent entry to select, etc. entry = parentEntry; - setEntryChildren((LogEntry)parentEntry.getParent(parentEntry)); - parentEntry = (LogEntry)parentEntry.getParent(parentEntry); + setEntryChildren((AbstractEntry)parentEntry.getParent(parentEntry)); + parentEntry = (AbstractEntry)parentEntry.getParent(parentEntry); resetChildIndex(); isLastChild = childIndex == entryChildren.length-1; if (isLastChild){ @@ -386,15 +418,15 @@ } } - private boolean nextChildExists(LogEntry originalEntry, LogEntry originalParent, LogEntry[] originalEntries){ + private boolean nextChildExists(AbstractEntry originalEntry, AbstractEntry originalParent, AbstractEntry[] originalEntries){ if (isChild (parentEntry)){ // we're at the end of the child list; find next parent // to select. If the parent is a child at the end of the child // list, find its next parent entry to select, etc. entry = parentEntry; - setEntryChildren((LogEntry)parentEntry.getParent(parentEntry)); - parentEntry = (LogEntry)parentEntry.getParent(parentEntry); + setEntryChildren((AbstractEntry)parentEntry.getParent(parentEntry)); + parentEntry = (AbstractEntry)parentEntry.getParent(parentEntry); resetChildIndex(); if (childIndex == entryChildren.length-1){ nextChildExists(originalEntry, originalParent, originalEntries); @@ -413,55 +445,68 @@ return false; } + + /** + * Sets entry children (Prev-Next navigable) to top-level elements + */ private void setEntryChildren(){ - Object[] children = ((LogViewContentProvider)provider.getContentProvider()).getElements(null); + AbstractEntry[] children = getElements(); if (comparator != null) Arrays.sort(children, comparator); - entryChildren = new LogEntry[children.length]; + entryChildren = new AbstractEntry[children.length]; System.arraycopy(children,0,entryChildren,0,children.length); } private void resetTotalElementCount(){ - totalElementCount = entry.getSession().getEntries().size(); + totalElementCount = getElements().length; } - private void setEntryChildren(LogEntry entry){ - LogSession session = entry.getSession(); - if (session == null) - return; + /** + * Sets entry children (Prev-Next navigable) to children of given entry + */ + private void setEntryChildren(AbstractEntry entry){ + Object[] children = entry.getChildren(entry); - List children = session.getEntries(); if (comparator != null) - Collections.sort(children, comparator); - entryChildren = (LogEntry[])children.toArray(new LogEntry[children.size()]); + Arrays.sort(children, comparator); + + List result = new ArrayList(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof AbstractEntry) { + result.add(children[i]); + } + } + + entryChildren = (AbstractEntry[])result.toArray(new AbstractEntry[result.size()]); } - + + /** + * Returns the number of top level element containing current entry. + * @return + */ private int getParentElementNum(){ - LogEntry itemEntry = (LogEntry)((IStructuredSelection)provider.getSelection()).getFirstElement(); - itemEntry = getRootEntry(itemEntry); + AbstractEntry itemEntry = (AbstractEntry)((IStructuredSelection)provider.getSelection()).getFirstElement(); + AbstractEntry topParent = itemEntry; - setEntryChildren(itemEntry); - for (int i = 0; i 0) { LogEntry entry = new LogEntry(); @@ -161,63 +157,77 @@ if (writer != null) writer.close(); } + + return currentSession; } /** * Updates the {@link currentSession} to be the one that is not null or has most recent date. * @param session */ - private static void updateCurrentSession(LogSession session) { + private static LogSession updateCurrentSession(LogSession currentSession, LogSession session) { if (currentSession == null) { - currentSession = session; - return; + return session; } Date currentDate = currentSession.getDate(); Date sessionDate = session.getDate(); if (currentDate == null && sessionDate != null) - currentSession = session; + return session; else if (currentDate != null && sessionDate == null) - currentSession = session; + return session; else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate)) - currentSession = session; + return session; + + return currentSession; } - public synchronized static void addEntry(LogEntry current, List entries, IMemento memento, boolean useCurrentSession) { - int severity = current.getSeverity(); - boolean doAdd = true; + /** + * Adds entry to the list if it's not filtered. Removes entries exceeding the count limit. + * + * @param entry + * @param entries + * @param memento + */ + private static void addEntry(LogEntry entry, List entries, IMemento memento) { + + if (isLogged(entry, memento)) { + entries.add(entry); + + if (memento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$ + int limit = memento.getInteger(LogView.P_LOG_LIMIT).intValue(); + if (entries.size() > limit) { + entries.remove(0); + } + } + } + } + + /** + * Returns whether given entry is logged (true) or filtered (false). + * + * @param entry + * @param memento + * @return + */ + public static boolean isLogged(LogEntry entry, IMemento memento) { + int severity = entry.getSeverity(); switch(severity) { case IStatus.INFO: - doAdd = memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$ - break; + return memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$ case IStatus.WARNING: - doAdd = memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$ - break; + return memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$ case IStatus.ERROR: - doAdd = memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$ - break; - } - if (doAdd) { - if (useCurrentSession) - current.setSession(currentSession); - entries.add(0, current); - - if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$ - && entries.size() > memento.getInteger(LogView.P_LOG_LIMIT).intValue()) - entries.remove(entries.size() - 1); + return memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$ } + + return false; } - private static void setNewParent( - ArrayList parents, - LogEntry entry, - int depth) { + private static void setNewParent(ArrayList parents, LogEntry entry, + int depth) { if (depth + 1 > parents.size()) parents.add(entry); else parents.set(depth, entry); } - - public static void reset() { - currentSession = null; - } } Index: src/org/eclipse/ui/internal/views/log/AbstractEntry.java =================================================================== RCS file: src/org/eclipse/ui/internal/views/log/AbstractEntry.java diff -N src/org/eclipse/ui/internal/views/log/AbstractEntry.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/views/log/AbstractEntry.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,88 @@ +package org.eclipse.ui.internal.views.log; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * Everything that appears in LogView is Abstract Entry. It provides composite pattern. + * + */ +public abstract class AbstractEntry extends PlatformObject implements IWorkbenchAdapter { + + private List children; + protected Object parent; + + public void addChild(AbstractEntry child) { + if (children == null) { + children = new ArrayList(); + } + children.add(0, child); + child.setParent(this); + } + + public void addChild(AbstractEntry child, int limit) { + addChild(child); + if (children.size() > limit) { + children.remove(children.size() - 1); + } + } + + /** + * @see IWorkbenchAdapter#getChildren(Object) + */ + public Object[] getChildren(Object parent) { + if (children == null) + return new Object[0]; + return children.toArray(); + } + + public boolean hasChildren() { + return children != null && children.size() > 0; + } + + public int size() { + return children != null ? children.size() : 0; + } + + /** + * @see IWorkbenchAdapter#getImageDescriptor(Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return null; + } + + /** + * @see IWorkbenchAdapter#getLabel(Object) + */ + public String getLabel(Object o) { + return null; + } + + /** + * @see IWorkbenchAdapter#getParent(Object) + */ + public Object getParent(Object o) { + return parent; + } + + public void setParent(AbstractEntry parent) { + this.parent = parent; + } + + public void removeChildren(List list) { + if (children != null) { + children.removeAll(list); + } + } + + public void removeAllChildren() { + children.clear(); + } + + public abstract void write(PrintWriter writer); +} Index: src/org/eclipse/ui/internal/views/log/Group.java =================================================================== RCS file: src/org/eclipse/ui/internal/views/log/Group.java diff -N src/org/eclipse/ui/internal/views/log/Group.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ui/internal/views/log/Group.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,24 @@ +package org.eclipse.ui.internal.views.log; + +import java.io.PrintWriter; + +/** + * Groups other Abstract Entries under given name. + */ +public class Group extends AbstractEntry { + + private String name; + + public Group(String name) { + this.name = name; + } + + public void write(PrintWriter writer) { + // empty + } + + public String toString() { + return name; + } + +}