View | Details | Raw Unified | Return to bug 207344 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/ui/internal/views/log/messages.properties (+4 lines)
Lines 53-58 Link Here
53
LogView_FilterDialog_eventsLogged = Show events logged during:
53
LogView_FilterDialog_eventsLogged = Show events logged during:
54
LogView_FilterDialog_allSessions = &All sessions
54
LogView_FilterDialog_allSessions = &All sessions
55
LogView_FilterDialog_recentSession = &Most recent session
55
LogView_FilterDialog_recentSession = &Most recent session
56
LogView_GroupBy=Group by
57
LogView_GroupByNone=None
58
LogView_GroupByPlugin=Plug-in
59
LogView_GroupBySession=Session
56
LogViewLabelProvider_truncatedMessage=... (Open log entry details for full message)
60
LogViewLabelProvider_truncatedMessage=... (Open log entry details for full message)
57
LogViewLabelProvider_Session=Session
61
LogViewLabelProvider_Session=Session
58
62
(-)src/org/eclipse/ui/internal/views/log/LogSession.java (-31 / +10 lines)
Lines 11-38 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.ui.internal.views.log;
12
package org.eclipse.ui.internal.views.log;
13
13
14
import java.io.PrintWriter;
14
import java.text.ParseException;
15
import java.text.ParseException;
15
import java.util.ArrayList;
16
import java.util.Date;
16
import java.util.Date;
17
import java.util.List;
18
19
import org.eclipse.core.runtime.PlatformObject;
20
import org.eclipse.jface.resource.ImageDescriptor;
21
import org.eclipse.ui.model.IWorkbenchAdapter;
22
17
23
import com.ibm.icu.text.SimpleDateFormat;
18
import com.ibm.icu.text.SimpleDateFormat;
24
19
25
public class LogSession extends PlatformObject implements IWorkbenchAdapter {
20
/**
21
 * Group of entries with additional Session data.
22
 */
23
public class LogSession extends Group {
26
	private String sessionData;
24
	private String sessionData;
27
	private Date date;
25
	private Date date;
28
	private List entries = new ArrayList();
26
	
29
30
	/**
31
	 * Constructor for LogSession.
32
	 */
33
	public LogSession() {
27
	public LogSession() {
28
		super(Messages.LogViewLabelProvider_Session);
34
	}
29
	}
35
30
	
36
	public Date getDate() {
31
	public Date getDate() {
37
		return date;
32
		return date;
38
	}
33
	}
Lines 63-86 Link Here
63
		String dateBuffer = line.substring(0, delim).trim();
58
		String dateBuffer = line.substring(0, delim).trim();
64
		setDate(dateBuffer);
59
		setDate(dateBuffer);
65
	}
60
	}
66
	
67
	public List getEntries() {
68
		return entries;
69
	}
70
71
	public Object[] getChildren(Object o) {
72
		return getEntries().toArray(new LogEntry[getEntries().size()]);
73
	}
74
75
	public ImageDescriptor getImageDescriptor(Object object) {
76
		return null;
77
	}
78
79
	public String getLabel(Object o) {
80
		return null;
81
	}
82
61
83
	public Object getParent(Object o) {
62
	public void write(PrintWriter writer) {
84
		return null;
63
		writer.write(sessionData);
85
	}
64
	}
86
}
65
}
(-)src/org/eclipse/ui/internal/views/log/Messages.java (+4 lines)
Lines 59-64 Link Here
59
	public static String LogView_FilterDialog_eventsLogged;
59
	public static String LogView_FilterDialog_eventsLogged;
60
	public static String LogView_FilterDialog_allSessions;
60
	public static String LogView_FilterDialog_allSessions;
61
	public static String LogView_FilterDialog_recentSession;
61
	public static String LogView_FilterDialog_recentSession;
62
	public static String LogView_GroupBy;
63
	public static String LogView_GroupByNone;
64
	public static String LogView_GroupByPlugin;
65
	public static String LogView_GroupBySession;
62
66
63
	public static String LogViewLabelProvider_Session;
67
	public static String LogViewLabelProvider_Session;
64
	public static String LogViewLabelProvider_truncatedMessage;
68
	public static String LogViewLabelProvider_truncatedMessage;
(-)src/org/eclipse/ui/internal/views/log/LogViewLabelProvider.java (-31 / +33 lines)
Lines 11-16 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.ui.internal.views.log;
12
package org.eclipse.ui.internal.views.log;
13
13
14
import java.text.DateFormat;
15
import java.text.SimpleDateFormat;
14
import java.util.ArrayList;
16
import java.util.ArrayList;
15
17
16
import org.eclipse.core.runtime.IStatus;
18
import org.eclipse.core.runtime.IStatus;
Lines 18-26 Link Here
18
import org.eclipse.jface.viewers.LabelProvider;
20
import org.eclipse.jface.viewers.LabelProvider;
19
import org.eclipse.swt.graphics.Image;
21
import org.eclipse.swt.graphics.Image;
20
22
21
import com.ibm.icu.text.DateFormat;
22
import com.ibm.icu.text.SimpleDateFormat;
23
24
public class LogViewLabelProvider
23
public class LogViewLabelProvider
25
	extends LabelProvider
24
	extends LabelProvider
26
	implements ITableLabelProvider {
25
	implements ITableLabelProvider {
Lines 49-55 Link Here
49
		}
48
		}
50
	}
49
	}
51
	public Image getColumnImage(Object element, int columnIndex) {
50
	public Image getColumnImage(Object element, int columnIndex) {
52
		if (element instanceof LogSession) {
51
		if (element instanceof Group) {
53
			return (columnIndex == 0) ? hierarchicalImage : null;
52
			return (columnIndex == 0) ? hierarchicalImage : null;
54
		}
53
		}
55
		
54
		
Lines 70-107 Link Here
70
	}
69
	}
71
	
70
	
72
	public String getColumnText(Object element, int columnIndex) {
71
	public String getColumnText(Object element, int columnIndex) {
73
		if (element instanceof LogSession) {
72
		if ((element instanceof LogSession) && (columnIndex == 2)) {
74
			LogSession entry = (LogSession) element;
73
			LogSession session = (LogSession) element;
75
			if (columnIndex == 0) {
74
			if (session.getDate() == null)
76
				return Messages.LogViewLabelProvider_Session;
75
				return ""; //$NON-NLS-1$
77
			} else if (columnIndex == 2) {
76
			
78
				if (entry.getDate() != null) {
77
			DateFormat formatter = new SimpleDateFormat(LogEntry.F_DATE_FORMAT);
79
					DateFormat formatter = new SimpleDateFormat(LogEntry.F_DATE_FORMAT);
78
			return formatter.format(session.getDate());
80
					return formatter.format(entry.getDate()); 
81
				}
82
			}
83
			return null;
84
		}
79
		}
85
		
80
		
86
		LogEntry entry = (LogEntry) element;
81
		if ((element instanceof Group) && (columnIndex == 0)) {
87
		switch (columnIndex) {
82
			return element.toString();
88
		case 0:
83
		}
89
			if (entry.getMessage() != null) {
84
		
90
				String message = entry.getMessage();
85
		if (element instanceof LogEntry) {
91
				if (message.length() > MAX_LABEL_LENGTH) {
86
			LogEntry entry = (LogEntry) element;
92
					String warning = Messages.LogViewLabelProvider_truncatedMessage;
87
			switch (columnIndex) {
93
					StringBuffer sb = new StringBuffer(message.substring(0, MAX_LABEL_LENGTH - warning.length()));
88
			case 0:
94
					sb.append(warning);
89
				if (entry.getMessage() != null) {
95
					return sb.toString();
90
					String message = entry.getMessage();
91
					if (message.length() > MAX_LABEL_LENGTH) {
92
						String warning = Messages.LogViewLabelProvider_truncatedMessage;
93
						StringBuffer sb = new StringBuffer(message.substring(0, MAX_LABEL_LENGTH - warning.length()));
94
						sb.append(warning);
95
						return sb.toString();
96
					}
97
					return entry.getMessage();
96
				}
98
				}
97
				return entry.getMessage();
99
			case 1:
100
				if (entry.getPluginId() != null)
101
					return entry.getPluginId();
102
			case 2:
103
				return entry.getFormattedDate();
98
			}
104
			}
99
		case 1:
100
			if (entry.getPluginId() != null)
101
				return entry.getPluginId();
102
		case 2:
103
			return entry.getFormattedDate();
104
		}
105
		}
106
		
105
		return ""; //$NON-NLS-1$
107
		return ""; //$NON-NLS-1$
106
	}
108
	}
107
109
(-)src/org/eclipse/ui/internal/views/log/LogView.java (-26 / +217 lines)
Lines 26-32 Link Here
26
import java.io.StringWriter;
26
import java.io.StringWriter;
27
import java.lang.reflect.InvocationTargetException;
27
import java.lang.reflect.InvocationTargetException;
28
import java.util.ArrayList;
28
import java.util.ArrayList;
29
import java.util.Arrays;
30
import java.util.Collections;
29
import java.util.Comparator;
31
import java.util.Comparator;
32
import java.util.Date;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Map;
30
37
31
import org.eclipse.core.runtime.ILogListener;
38
import org.eclipse.core.runtime.ILogListener;
32
import org.eclipse.core.runtime.IProgressMonitor;
39
import org.eclipse.core.runtime.IProgressMonitor;
Lines 37-42 Link Here
37
import org.eclipse.core.runtime.Status;
44
import org.eclipse.core.runtime.Status;
38
import org.eclipse.core.runtime.jobs.Job;
45
import org.eclipse.core.runtime.jobs.Job;
39
import org.eclipse.jface.action.Action;
46
import org.eclipse.jface.action.Action;
47
import org.eclipse.jface.action.IContributionItem;
40
import org.eclipse.jface.action.IMenuListener;
48
import org.eclipse.jface.action.IMenuListener;
41
import org.eclipse.jface.action.IMenuManager;
49
import org.eclipse.jface.action.IMenuManager;
42
import org.eclipse.jface.action.IStatusLineManager;
50
import org.eclipse.jface.action.IStatusLineManager;
Lines 116-121 Link Here
116
	public static final String P_SHOW_FILTER_TEXT = "show_filter_text"; //$NON-NLS-1$
124
	public static final String P_SHOW_FILTER_TEXT = "show_filter_text"; //$NON-NLS-1$
117
	public static final String P_ORDER_TYPE = "orderType"; //$NON-NLS-1$
125
	public static final String P_ORDER_TYPE = "orderType"; //$NON-NLS-1$
118
	public static final String P_ORDER_VALUE = "orderValue"; //$NON-NLS-1$
126
	public static final String P_ORDER_VALUE = "orderValue"; //$NON-NLS-1$
127
	public static final String P_GROUP_BY = "groupBy"; //$NON-NLS-1$
119
128
120
	private int MESSAGE_ORDER;
129
	private int MESSAGE_ORDER;
121
	private int PLUGIN_ORDER;
130
	private int PLUGIN_ORDER;
Lines 127-133 Link Here
127
	public static int ASCENDING = 1;
136
	public static int ASCENDING = 1;
128
	public static int DESCENDING = -1;
137
	public static int DESCENDING = -1;
129
138
130
	private ArrayList fLogs;
139
	public static final int GROUP_BY_NONE = 0;
140
	public static final int GROUP_BY_SESSION = 1;
141
	public static final int GROUP_BY_PLUGIN = 2;
142
	
143
	private List elements;
144
	private Map groups;
145
	private LogSession currentSession;
131
146
132
	private Clipboard fClipboard;
147
	private Clipboard fClipboard;
133
148
Lines 161-170 Link Here
161
	private Action fExportAction;
176
	private Action fExportAction;
162
	
177
	
163
	/**
178
	/**
179
	 * Action called when user selects "Group by -> ..." from menu.
180
	 */
181
	class GroupByAction extends Action {
182
		private int groupBy;
183
		
184
		public GroupByAction(String text, int groupBy) {
185
			super(text, Action.AS_RADIO_BUTTON);
186
			
187
			this.groupBy = groupBy;
188
			
189
			if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() == groupBy) {
190
				setChecked(true);
191
			}
192
		}
193
194
		public void run() {
195
			if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() != groupBy) {
196
				fMemento.putInteger(LogView.P_GROUP_BY, groupBy);
197
				reloadLog();
198
			}
199
		}		
200
	}
201
	
202
	/**
164
	 * Constructor
203
	 * Constructor
165
	 */
204
	 */
166
	public LogView() {
205
	public LogView() {
167
		fLogs = new ArrayList();
206
		elements = new ArrayList();
207
		groups = new HashMap();
168
		fInputFile = Platform.getLogFileLocation().toFile();
208
		fInputFile = Platform.getLogFileLocation().toFile();
169
	}
209
	}
170
210
Lines 228-241 Link Here
228
		toolBarManager.add(new Separator());
268
		toolBarManager.add(new Separator());
229
269
230
		IMenuManager mgr = bars.getMenuManager();
270
		IMenuManager mgr = bars.getMenuManager();
231
		mgr.add(createFilterAction());
271
		
272
		mgr.add(createGroupByAction());
273
		
232
		mgr.add(new Separator());
274
		mgr.add(new Separator());
275
		
276
		mgr.add(createFilterAction());
233
277
278
		mgr.add(new Separator());
279
		
234
		fActivateViewAction = createActivateViewAction();
280
		fActivateViewAction = createActivateViewAction();
235
		mgr.add(fActivateViewAction);
281
		mgr.add(fActivateViewAction);
236
		
282
		
237
		mgr.add(createShowTextFilter());
283
		mgr.add(createShowTextFilter());
238
284
		
239
		createPropertiesAction();
285
		createPropertiesAction();
240
286
241
		MenuManager popupMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
287
		MenuManager popupMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
Lines 437-442 Link Here
437
		fFilteredTree.layout(false);
483
		fFilteredTree.layout(false);
438
	}
484
	}
439
	
485
	
486
	private IContributionItem createGroupByAction() {
487
		IMenuManager groupByMenu = new MenuManager(Messages.LogView_GroupBy);
488
		
489
		groupByMenu.add(new GroupByAction(Messages.LogView_GroupByNone, LogView.GROUP_BY_NONE));
490
		groupByMenu.add(new GroupByAction(Messages.LogView_GroupBySession, LogView.GROUP_BY_SESSION));
491
		groupByMenu.add(new GroupByAction(Messages.LogView_GroupByPlugin, LogView.GROUP_BY_PLUGIN));
492
		
493
		return groupByMenu;
494
	}
495
	
440
	private void createViewer(Composite parent) {
496
	private void createViewer(Composite parent) {
441
497
442
		fFilteredTree = new FilteredTree(parent, SWT.FULL_SELECTION, new PatternFilter() {
498
		fFilteredTree = new FilteredTree(parent, SWT.FULL_SELECTION, new PatternFilter() {
Lines 556-563 Link Here
556
		Platform.removeLogListener(this);
612
		Platform.removeLogListener(this);
557
		fClipboard.dispose();
613
		fClipboard.dispose();
558
		if (fTextShell != null)
614
		if (fTextShell != null)
559
			fTextShell.dispose();	
615
			fTextShell.dispose();
560
		LogReader.reset();
561
		fLabelProvider.disconnect(this);
616
		fLabelProvider.disconnect(this);
562
		fFilteredTree.dispose();
617
		fFilteredTree.dispose();
563
		super.dispose();
618
		super.dispose();
Lines 654-661 Link Here
654
		String message = Messages.LogView_confirmDelete_message; 
709
		String message = Messages.LogView_confirmDelete_message; 
655
		if (!MessageDialog.openConfirm(fTree.getShell(), title, message))
710
		if (!MessageDialog.openConfirm(fTree.getShell(), title, message))
656
			return;
711
			return;
657
		if (fInputFile.delete() || fLogs.size() > 0) {
712
		if (fInputFile.delete() || elements.size() > 0) {
658
			fLogs.clear();
713
			elements.clear();
714
			groups.clear();
715
			currentSession.removeAllChildren();
659
			asyncRefresh(false);
716
			asyncRefresh(false);
660
			resetDialogButtons();
717
			resetDialogButtons();
661
		}
718
		}
Lines 664-678 Link Here
664
	public void fillContextMenu(IMenuManager manager) {
721
	public void fillContextMenu(IMenuManager manager) {
665
	}
722
	}
666
723
667
	public LogSession[] getLogs() {
724
	public AbstractEntry[] getElements() {
668
		return (LogSession[]) fLogs.toArray(new LogSession[fLogs.size()]);
725
		return (AbstractEntry[]) elements.toArray(new AbstractEntry[elements.size()]);
669
	}
726
	}
670
727
671
	protected void handleClear() {
728
	protected void handleClear() {
672
		BusyIndicator.showWhile(fTree.getDisplay(),
729
		BusyIndicator.showWhile(fTree.getDisplay(),
673
				new Runnable() {
730
				new Runnable() {
674
			public void run() {
731
			public void run() {
675
				fLogs.clear();
732
				elements.clear();
733
				groups.clear();
734
				currentSession.removeAllChildren();
676
				asyncRefresh(false);
735
				asyncRefresh(false);
677
				resetDialogButtons();
736
				resetDialogButtons();
678
			}
737
			}
Lines 700-709 Link Here
700
	}
759
	}
701
760
702
	private void readLogFile() {
761
	private void readLogFile() {
703
		fLogs.clear();
704
		if (!fInputFile.exists())
762
		if (!fInputFile.exists())
705
			return;
763
			return;
706
		LogReader.parseLogFile(fInputFile, fLogs, fMemento);
764
		
765
		elements.clear();
766
		groups.clear();
767
		
768
		List result = new ArrayList();
769
		currentSession = LogReader.parseLogFile(fInputFile, result, fMemento);
770
		group(result);
771
		limitEntriesCount();
772
	}
773
	
774
	/**
775
	 * Add new entries to correct groups in the view.
776
	 * @param entries new entries to show up in groups in the view.
777
	 */
778
	private void group(List entries) {
779
		if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
780
			elements.addAll(entries);
781
		} else {
782
			for (Iterator i = entries.iterator(); i.hasNext(); ) {
783
				LogEntry entry = (LogEntry) i.next();
784
				Group group = getGroup(entry);
785
				group.addChild(entry);
786
			}
787
		}
788
	}
789
	
790
	/**
791
	 * Limits the number of entries according to the max entries limit set in
792
	 * memento.
793
	 */
794
	private void limitEntriesCount() {
795
		int limit = Integer.MAX_VALUE;
796
		if (fMemento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$
797
			limit = fMemento.getInteger(LogView.P_LOG_LIMIT).intValue();
798
		}
799
		
800
		int entriesCount = getEntriesCount();
801
		
802
		if (entriesCount <= limit) {
803
			return;
804
		} else { // remove oldest
805
			Comparator dateComparator = new Comparator() {
806
				public int compare(Object o1, Object o2) {
807
					Date l1 = ((LogEntry) o1).getDate();
808
					Date l2 = ((LogEntry) o2).getDate();
809
					if ((l1 != null) && (l2 != null)) {
810
						return l1.before(l2) ? -1 : 1;
811
					} else if ((l1 == null) && (l2 == null)) {
812
						 return 0;
813
					} else return (l1 == null) ? -1 : 1; 
814
				}
815
			};
816
			
817
			if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
818
				elements.subList(0, elements.size() - limit).clear();
819
			} else {
820
				List copy = new ArrayList(entriesCount);
821
				for (Iterator i = elements.iterator(); i.hasNext(); ) {
822
					AbstractEntry group = (AbstractEntry) i.next();
823
					copy.addAll(Arrays.asList(group.getChildren(group)));
824
				}
825
				
826
				Collections.sort(copy, dateComparator);
827
				List toRemove = copy.subList(0, copy.size() - limit);
828
				
829
				for (Iterator i = elements.iterator(); i.hasNext(); ) {
830
					AbstractEntry group = (AbstractEntry) i.next();
831
					group.removeChildren(toRemove);
832
				}
833
			}
834
		}
835
		
836
	}
837
	
838
	private int getEntriesCount() {
839
		if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
840
			return elements.size();
841
		} else {
842
			int size = 0;
843
			for (Iterator i = elements.iterator(); i.hasNext(); ) {
844
				AbstractEntry group = (AbstractEntry)i.next();
845
				size += group.size();
846
			}
847
			return size;
848
		}
849
	}
850
	
851
	/**
852
	 * Returns group appropriate for the entry. Group depends on P_GROUP_BY
853
	 * preference, or is null if grouping is disabled (GROUP_BY_NONE), or group
854
	 * could not be determined. May create group if it haven't existed before.
855
	 * 
856
	 * @param entry entry to be grouped
857
	 * @return group or null if grouping is disabled
858
	 */
859
	protected Group getGroup(LogEntry entry) {
860
		int groupBy = fMemento.getInteger(P_GROUP_BY).intValue();
861
		Object elementGroupId = null;
862
		String groupName = null;
863
864
		switch (groupBy) {
865
		case GROUP_BY_PLUGIN:
866
			groupName = entry.getPluginId();
867
			elementGroupId = groupName;
868
			break;
869
870
		case GROUP_BY_SESSION:
871
			elementGroupId = entry.getSession();
872
			break;
873
874
		default: // grouping is disabled
875
			return null;
876
		}
877
878
		if (elementGroupId == null) { // could not determine group
879
			return null;
880
		}
881
882
		Group group = (Group) groups.get(elementGroupId);
883
		if (group == null) {
884
			if (groupBy == GROUP_BY_SESSION) {
885
				group = entry.getSession();
886
			} else {
887
				group = new Group(groupName);
888
			}
889
			groups.put(elementGroupId, group);
890
			elements.add(group);
891
		}
892
		
893
		return group;
707
	}
894
	}
708
895
709
	public void logging(IStatus status, String plugin) {
896
	public void logging(IStatus status, String plugin) {
Lines 711-733 Link Here
711
			return;
898
			return;
712
		if (fFirstEvent) {
899
		if (fFirstEvent) {
713
			readLogFile();
900
			readLogFile();
714
			asyncRefresh();
901
			asyncRefresh(true);
715
			fFirstEvent = false;
902
			fFirstEvent = false;
716
		} else {
903
		} else {
717
			pushStatus(status);
904
			pushStatus(status);
718
		}
905
		}
719
	}
906
	}
720
907
721
	private void pushStatus(IStatus status) {
908
	private synchronized void pushStatus(IStatus status) {
722
		LogEntry entry = new LogEntry(status);
909
		LogEntry entry = new LogEntry(status);
723
		if (fLogs.isEmpty()) {
910
		entry.setSession(currentSession);
724
			fLogs.add(new LogSession());
911
		
912
		if (LogReader.isLogged(entry, fMemento)) {
913
			group(Collections.singletonList(entry));
914
			limitEntriesCount();
725
		}
915
		}
726
		LogReader.addEntry(entry, ((LogSession)fLogs.get(fLogs.size() - 1)).getEntries(), fMemento, true);
727
		asyncRefresh();
728
	}
729
730
	private void asyncRefresh() {
731
		asyncRefresh(true);
916
		asyncRefresh(true);
732
	}
917
	}
733
918
Lines 875-880 Link Here
875
		}
1060
		}
876
		fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
1061
		fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
877
		fMemento.putInteger(P_ORDER_TYPE, DATE);
1062
		fMemento.putInteger(P_ORDER_TYPE, DATE);
1063
		if (fMemento.getInteger(P_GROUP_BY) == null) {
1064
			fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE);
1065
		}
878
	}
1066
	}
879
1067
880
	public void saveState(IMemento memento) {
1068
	public void saveState(IMemento memento) {
Lines 1017-1024 Link Here
1017
		}
1205
		}
1018
	}
1206
	}
1019
1207
1020
	private int getNumberOfParents(LogEntry entry){
1208
	private int getNumberOfParents(AbstractEntry entry){
1021
		LogEntry parent = (LogEntry)entry.getParent(entry);
1209
		AbstractEntry parent = (AbstractEntry)entry.getParent(entry);
1022
		if (parent ==null)
1210
		if (parent ==null)
1023
			return 0;
1211
			return 0;
1024
		return 1 + getNumberOfParents(parent);
1212
		return 1 + getNumberOfParents(parent);
Lines 1042-1048 Link Here
1042
						date2 = ((LogSession) e2).getDate() == null ? 0 : ((LogSession) e2).getDate().getTime();
1230
						date2 = ((LogSession) e2).getDate() == null ? 0 : ((LogSession) e2).getDate().getTime();
1043
					}
1231
					}
1044
					if (date1 == date2) {
1232
					if (date1 == date2) {
1045
						int result = fLogs.indexOf(e2) - fLogs.indexOf(e1);
1233
						int result = elements.indexOf(e2) - elements.indexOf(e1); 
1046
						if (DATE_ORDER == DESCENDING)
1234
						if (DATE_ORDER == DESCENDING)
1047
							result *= DESCENDING;
1235
							result *= DESCENDING;
1048
						return result;
1236
						return result;
Lines 1118-1124 Link Here
1118
					}
1306
					}
1119
					
1307
					
1120
					if (date1 == date2) {
1308
					if (date1 == date2) {
1121
						int result = fLogs.indexOf(e2) - fLogs.indexOf(e1);
1309
						int result = elements.indexOf(e2) - elements.indexOf(e1);
1122
						if (DATE_ORDER == DESCENDING)
1310
						if (DATE_ORDER == DESCENDING)
1123
							result *= DESCENDING;
1311
							result *= DESCENDING;
1124
						return result;
1312
						return result;
Lines 1176-1181 Link Here
1176
			fMemento.putInteger(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
1364
			fMemento.putInteger(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
1177
			fMemento.putInteger(P_ORDER_TYPE, p.getInt(P_ORDER_TYPE));
1365
			fMemento.putInteger(P_ORDER_TYPE, p.getInt(P_ORDER_TYPE));
1178
			fMemento.putBoolean(P_SHOW_FILTER_TEXT, p.getBoolean(P_SHOW_FILTER_TEXT));
1366
			fMemento.putBoolean(P_SHOW_FILTER_TEXT, p.getBoolean(P_SHOW_FILTER_TEXT));
1367
			fMemento.putInteger(P_GROUP_BY, p.getInt(P_GROUP_BY));
1179
		} catch (NumberFormatException e) {
1368
		} catch (NumberFormatException e) {
1180
			fMemento.putInteger(P_LOG_LIMIT, 50);
1369
			fMemento.putInteger(P_LOG_LIMIT, 50);
1181
			fMemento.putInteger(P_COLUMN_1, 300);
1370
			fMemento.putInteger(P_COLUMN_1, 300);
Lines 1183-1188 Link Here
1183
			fMemento.putInteger(P_COLUMN_3, 150);
1372
			fMemento.putInteger(P_COLUMN_3, 150);
1184
			fMemento.putInteger(P_ORDER_TYPE, DATE);
1373
			fMemento.putInteger(P_ORDER_TYPE, DATE);
1185
			fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
1374
			fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
1375
			fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE);
1186
		}
1376
		}
1187
	}
1377
	}
1188
1378
Lines 1213-1218 Link Here
1213
		preferences.setValue(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
1403
		preferences.setValue(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
1214
		preferences.setValue(P_ORDER_TYPE, fMemento.getInteger(P_ORDER_TYPE).intValue());
1404
		preferences.setValue(P_ORDER_TYPE, fMemento.getInteger(P_ORDER_TYPE).intValue());
1215
		preferences.setValue(P_SHOW_FILTER_TEXT, fMemento.getBoolean(P_SHOW_FILTER_TEXT).booleanValue());
1405
		preferences.setValue(P_SHOW_FILTER_TEXT, fMemento.getBoolean(P_SHOW_FILTER_TEXT).booleanValue());
1406
		preferences.setValue(P_GROUP_BY, fMemento.getInteger(P_GROUP_BY).intValue());
1216
	}
1407
	}
1217
1408
1218
	public void sortByDateDescending() {
1409
	public void sortByDateDescending() {
(-)src/org/eclipse/ui/internal/views/log/LogEntry.java (-37 / +6 lines)
Lines 14-37 Link Here
14
import java.io.PrintWriter;
14
import java.io.PrintWriter;
15
import java.io.StringWriter;
15
import java.io.StringWriter;
16
import java.text.ParseException;
16
import java.text.ParseException;
17
import java.util.ArrayList;
18
import java.util.Date;
17
import java.util.Date;
19
import java.util.StringTokenizer;
18
import java.util.StringTokenizer;
20
19
21
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.PlatformObject;
23
import org.eclipse.jface.resource.ImageDescriptor;
21
import org.eclipse.jface.resource.ImageDescriptor;
24
import org.eclipse.ui.model.IWorkbenchAdapter;
22
import org.eclipse.ui.model.IWorkbenchAdapter;
25
23
26
import com.ibm.icu.text.SimpleDateFormat;
24
import com.ibm.icu.text.SimpleDateFormat;
27
25
28
public class LogEntry extends PlatformObject implements IWorkbenchAdapter {
26
public class LogEntry extends AbstractEntry {
29
	
27
	
30
	public static final String F_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$
28
	public static final String F_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$
31
	private static final SimpleDateFormat F_SDF = new SimpleDateFormat(F_DATE_FORMAT);
29
	private static final SimpleDateFormat F_SDF = new SimpleDateFormat(F_DATE_FORMAT);
32
	
30
	
33
	private ArrayList children;
34
	private LogEntry parent;
35
	private String pluginId;
31
	private String pluginId;
36
	private int severity;
32
	private int severity;
37
	private int code;
33
	private int code;
Lines 44-51 Link Here
44
	public LogEntry() {}
40
	public LogEntry() {}
45
41
46
	public LogSession getSession() {
42
	public LogSession getSession() {
47
		if ((session == null) && (parent != null))
43
		if ((session == null) && (parent != null) && (parent instanceof LogEntry))
48
			return parent.getSession();
44
			return ((LogEntry)parent).getSession();
49
		
45
		
50
		return session;
46
		return session;
51
	}
47
	}
Lines 89-109 Link Here
89
	public String getSeverityText() {
85
	public String getSeverityText() {
90
		return getSeverityText(severity);
86
		return getSeverityText(severity);
91
	}
87
	}
92
	public boolean hasChildren() {
88
	
93
		return children != null && children.size() > 0;
94
	}
95
	public String toString() {
89
	public String toString() {
96
		return getSeverityText();
90
		return getSeverityText();
97
	}
91
	}
98
	/**
92
	
99
	 * @see IWorkbenchAdapter#getChildren(Object)
100
	 */
101
	public Object[] getChildren(Object parent) {
102
		if (children == null)
103
			return new Object[0];
104
		return children.toArray();
105
	}
106
107
	/**
93
	/**
108
	 * @see IWorkbenchAdapter#getImageDescriptor(Object)
94
	 * @see IWorkbenchAdapter#getImageDescriptor(Object)
109
	 */
95
	 */
Lines 118-134 Link Here
118
		return getSeverityText();
104
		return getSeverityText();
119
	}
105
	}
120
106
121
	/**
122
	 * @see IWorkbenchAdapter#getParent(Object)
123
	 */
124
	public Object getParent(Object obj) {
125
		return parent;
126
	}
127
128
	void setParent(LogEntry parent) {
129
		this.parent = parent;
130
	}
131
132
	private String getSeverityText(int severity) {
107
	private String getSeverityText(int severity) {
133
		switch (severity) {
108
		switch (severity) {
134
			case IStatus.ERROR :
109
			case IStatus.ERROR :
Lines 283-301 Link Here
283
		}
258
		}
284
		IStatus[] schildren = status.getChildren();
259
		IStatus[] schildren = status.getChildren();
285
		if (schildren.length > 0) {
260
		if (schildren.length > 0) {
286
			children = new ArrayList();
287
			for (int i = 0; i < schildren.length; i++) {
261
			for (int i = 0; i < schildren.length; i++) {
288
				LogEntry child = new LogEntry(schildren[i]);
262
				LogEntry child = new LogEntry(schildren[i]);
289
				addChild(child);
263
				addChild(child);
290
			}
264
			}
291
		}
265
		}
292
	}
266
	}
293
	void addChild(LogEntry child) {
267
	
294
		if (children == null)
295
			children = new ArrayList();
296
		children.add(child);
297
		child.setParent(this);
298
	}
299
	public void write(PrintWriter writer) {
268
	public void write(PrintWriter writer) {
300
		if (session != null)
269
		if (session != null)
301
			writer.println(session.getSessionData());
270
			writer.println(session.getSessionData());
(-)src/org/eclipse/ui/internal/views/log/EventDetailsDialogAction.java (-2 / +2 lines)
Lines 56-62 Link Here
56
	}
56
	}
57
	public void resetSelection(){
57
	public void resetSelection(){
58
		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
58
		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
59
		if (element == null)
59
		if ((element == null) || (! (element instanceof LogEntry)))
60
			return;
60
			return;
61
		if (propertyDialog != null && propertyDialog.isOpen())
61
		if (propertyDialog != null && propertyDialog.isOpen())
62
			propertyDialog.resetSelection(element);
62
			propertyDialog.resetSelection(element);
Lines 81-87 Link Here
81
		
81
		
82
		//get initial selection
82
		//get initial selection
83
		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
83
		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
84
		if ((element == null) || (element instanceof LogSession))
84
		if ((element == null) || (! (element instanceof LogEntry)))
85
			return;
85
			return;
86
		
86
		
87
		propertyDialog = new EventDetailsDialog(shell, element, provider, comparator);
87
		propertyDialog = new EventDetailsDialog(shell, element, provider, comparator);
(-)src/org/eclipse/ui/internal/views/log/LogViewContentProvider.java (-13 / +4 lines)
Lines 11-18 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.ui.internal.views.log;
12
package org.eclipse.ui.internal.views.log;
13
13
14
import java.util.List;
15
16
import org.eclipse.jface.viewers.ITreeContentProvider;
14
import org.eclipse.jface.viewers.ITreeContentProvider;
17
import org.eclipse.jface.viewers.Viewer;
15
import org.eclipse.jface.viewers.Viewer;
18
16
Lines 25-50 Link Here
25
	public void dispose() {
23
	public void dispose() {
26
	}
24
	}
27
	public Object[] getChildren(Object element) {
25
	public Object[] getChildren(Object element) {
28
		if (element instanceof LogSession) {
26
		return ((AbstractEntry) element).getChildren(element);
29
			List entries = ((LogSession) element).getEntries();
30
			return entries.toArray(new LogEntry[entries.size()]);
31
		}
32
		return ((LogEntry) element).getChildren(element);
33
	}
27
	}
34
	public Object[] getElements(Object element) {
28
	public Object[] getElements(Object element) {
35
		return logView.getLogs();
29
		return logView.getElements();
36
	}
30
	}
37
	public Object getParent(Object element) {
31
	public Object getParent(Object element) {
38
		if (element instanceof LogSession) {
32
		if (element instanceof LogSession) {
39
			return null;
33
			return null;
40
		}
34
		}
41
		return ((LogEntry) element).getParent(element);
35
		return ((AbstractEntry) element).getParent(element);
42
	}
36
	}
43
	public boolean hasChildren(Object element) {
37
	public boolean hasChildren(Object element) {
44
		if (element instanceof LogSession) {
38
		return ((AbstractEntry) element).getChildren(element).length > 0;
45
			return ((LogSession) element).getEntries().size() > 0;
46
		}
47
		return ((LogEntry) element).hasChildren();
48
	}
39
	}
49
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
40
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
50
	}
41
	}
(-)src/org/eclipse/ui/internal/views/log/EventDetailsDialog.java (-91 / +144 lines)
Lines 15-22 Link Here
15
import java.io.PrintWriter;
15
import java.io.PrintWriter;
16
import java.io.StringWriter;
16
import java.io.StringWriter;
17
import java.text.Collator;
17
import java.text.Collator;
18
import java.util.ArrayList;
18
import java.util.Arrays;
19
import java.util.Arrays;
19
import java.util.Collections;
20
import java.util.Comparator;
20
import java.util.Comparator;
21
import java.util.Date;
21
import java.util.Date;
22
import java.util.List;
22
import java.util.List;
Lines 29-34 Link Here
29
import org.eclipse.jface.viewers.ISelection;
29
import org.eclipse.jface.viewers.ISelection;
30
import org.eclipse.jface.viewers.ISelectionProvider;
30
import org.eclipse.jface.viewers.ISelectionProvider;
31
import org.eclipse.jface.viewers.IStructuredSelection;
31
import org.eclipse.jface.viewers.IStructuredSelection;
32
import org.eclipse.jface.viewers.ITreeContentProvider;
32
import org.eclipse.jface.viewers.StructuredSelection;
33
import org.eclipse.jface.viewers.StructuredSelection;
33
import org.eclipse.jface.viewers.TreeViewer;
34
import org.eclipse.jface.viewers.TreeViewer;
34
import org.eclipse.swt.SWT;
35
import org.eclipse.swt.SWT;
Lines 49-60 Link Here
49
import org.eclipse.ui.PlatformUI;
50
import org.eclipse.ui.PlatformUI;
50
51
51
public class EventDetailsDialog extends TrayDialog {
52
public class EventDetailsDialog extends TrayDialog {
52
	private LogEntry entry, parentEntry;
53
	private AbstractEntry entry;
54
	private AbstractEntry parentEntry; // parent of the entry
55
	private AbstractEntry[] entryChildren; // children of the entry
56
	
53
	private LogViewLabelProvider labelProvider;
57
	private LogViewLabelProvider labelProvider;
54
	private static int COPY_ID = 22;
55
	private TreeViewer provider;
58
	private TreeViewer provider;
56
	private int elementNum, totalElementCount;
59
	
57
	private LogEntry[] entryChildren;
60
	private static int COPY_ID = 22;
61
	
62
	private int elementNum; // number of selected element
63
	private int totalElementCount; // number of all elements
64
	
58
	private int childIndex = 0;
65
	private int childIndex = 0;
59
	private boolean isOpen;
66
	private boolean isOpen;
60
	private boolean isLastChild;
67
	private boolean isLastChild;
Lines 93-99 Link Here
93
		this.provider = (TreeViewer) provider;
100
		this.provider = (TreeViewer) provider;
94
		labelProvider = (LogViewLabelProvider)this.provider.getLabelProvider();
101
		labelProvider = (LogViewLabelProvider)this.provider.getLabelProvider();
95
		labelProvider.connect(this);
102
		labelProvider.connect(this);
96
		this.entry = (LogEntry)selection;
103
		this.entry = (AbstractEntry)selection;
97
		this.comparator = comparator;
104
		this.comparator = comparator;
98
		setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE);
105
		setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE);
99
		clipboard = new Clipboard(parentShell.getDisplay());
106
		clipboard = new Clipboard(parentShell.getDisplay());
Lines 107-150 Link Here
107
	private void initialize() {
114
	private void initialize() {
108
		elementNum = getParentElementNum();
115
		elementNum = getParentElementNum();
109
		resetTotalElementCount();
116
		resetTotalElementCount();
110
		parentEntry = (LogEntry) entry.getParent(entry);
117
		parentEntry = (AbstractEntry) entry.getParent(entry);
111
		if (isChild(entry)){
118
		if (isChild(entry)){
112
			setEntryChildren(parentEntry);
119
			setEntryChildren(parentEntry);
113
			resetChildIndex();
120
			resetChildIndex();
121
		} else {
122
			setEntryChildren();
114
		}
123
		}
115
		isLastChild = false;
124
		isLastChild = false;
116
		isAtEndOfLog = false;
125
		isAtEndOfLog = false;
117
	}
126
	}
118
	
127
	
119
	private void resetChildIndex() {
128
	private void resetChildIndex() {
129
		if (! (entry instanceof AbstractEntry)) {
130
			return;
131
		}
132
		
133
		if (entryChildren == null)
134
			return;
135
		
136
		LogEntry thisEntry = (LogEntry) entry;
137
		
120
		for (int i = 0; i < entryChildren.length; i++) {
138
		for (int i = 0; i < entryChildren.length; i++) {
121
			if (equal(entryChildren[i].getMessage(), entry.getMessage())
139
			if (entryChildren[i] instanceof LogEntry) {
122
					&& equal(entryChildren[i].getDate(), entry.getDate())
140
			
123
					&& equal(entryChildren[i].getPluginId(), entry
141
				LogEntry logEntry = (LogEntry) entryChildren[i];
124
							.getPluginId())
142
				
125
					&& entryChildren[i].getSeverity() == entry.getSeverity()
143
				if (logEntry == thisEntry) {
126
					&& equal(entryChildren[i].getSeverityText(), entry
144
					childIndex = i;
127
							.getSeverityText())) {
145
					return;
128
				childIndex = i;
146
				}
129
				break;
130
			}
147
			}
131
		}
148
		}
132
	}
149
	}
133
	
150
	
134
	private boolean equal(String str1, String str2) {
151
	private boolean isChild(AbstractEntry entry) {
135
		if (str1 == null) {
136
			return str1 == str2;
137
		}
138
		return str1.equals(str2);
139
	}
140
	
141
	private boolean equal(Date d1, Date d2) {
142
		if (d1 == null)
143
			return d1 == d2;
144
		return d1.equals(d2);
145
	}
146
147
	private boolean isChild(LogEntry entry) {
148
		return entry.getParent(entry) != null;
152
		return entry.getParent(entry) != null;
149
	}
153
	}
150
	
154
	
Lines 212-223 Link Here
212
				}
216
				}
213
				childIndex--;
217
				childIndex--;
214
				entry = entryChildren[childIndex];
218
				entry = entryChildren[childIndex];
215
			} else
219
			} else {
216
				entry = parentEntry;
220
				if (parentEntry instanceof LogEntry) {
221
					entry = parentEntry;
222
					if (isChild(entry)) {
223
						setEntryChildren((AbstractEntry)entry.getParent(entry));
224
					} else {
225
						setEntryChildren();
226
					}
227
				}
228
			}
217
		} else {
229
		} else {
218
			if (elementNum - 1 >= 0)
230
			if ((elementNum - 1 >= 0) && (entryChildren[elementNum-1] instanceof LogEntry)) {
219
				elementNum -= 1;
231
				elementNum -= 1;
220
			entry = entryChildren[elementNum];
232
				entry = entryChildren[elementNum];
233
			}
221
		}
234
		}
222
		setEntrySelectionInTable();
235
		setEntrySelectionInTable();
223
	}
236
	}
Lines 229-246 Link Here
229
			isLastChild = childIndex == entryChildren.length - 1;
242
			isLastChild = childIndex == entryChildren.length - 1;
230
		} else if (isChild(entry) && isLastChild && !isAtEndOfLog){
243
		} else if (isChild(entry) && isLastChild && !isAtEndOfLog){
231
			findNextSelectedChild(entry);
244
			findNextSelectedChild(entry);
232
		} else if (elementNum + 1 < totalElementCount){
245
		} else if (elementNum + 1 < totalElementCount){ // at end of element, go to next element
233
			if (isLastChild){
246
			if (isLastChild){
234
				setEntryChildren();
247
				setEntryChildren();
235
				isLastChild = false;
248
				isLastChild = false;
236
			}
249
			}
237
			elementNum += 1;
250
			
238
			entry = entryChildren[elementNum];
251
			if (entryChildren[elementNum+1] instanceof LogEntry) {
252
				elementNum += 1;
253
				entry = entryChildren[elementNum];
254
			}
239
		} else { // at end of list but can branch into child elements - bug 58083
255
		} else { // at end of list but can branch into child elements - bug 58083
240
			setEntryChildren(entry);
256
			if (entry.hasChildren()) {
241
			entry = entryChildren[0];
257
				setEntryChildren(entry);
242
			isAtEndOfLog = entryChildren.length == 0;
258
				entry = entryChildren[0];
243
			isLastChild = entryChildren.length == 0;
259
				isAtEndOfLog = entryChildren.length == 0;
260
				isLastChild = entryChildren.length == 0;
261
			}
244
		}
262
		}
245
		setEntrySelectionInTable();
263
		setEntrySelectionInTable();
246
	}
264
	}
Lines 306-313 Link Here
306
			updateProperties();
324
			updateProperties();
307
			return;
325
			return;
308
		}
326
		}
309
		if (selectedEntry instanceof LogEntry) {
327
		if (selectedEntry instanceof AbstractEntry) {
310
			entry = (LogEntry)selectedEntry;
328
			entry = (AbstractEntry)selectedEntry;
311
			initialize();
329
			initialize();
312
			updateProperties();
330
			updateProperties();
313
		}
331
		}
Lines 325-331 Link Here
325
	
343
	
326
	public void updateProperties() {	
344
	public void updateProperties() {	
327
		if (isChild(entry)){
345
		if (isChild(entry)){
328
			parentEntry = (LogEntry) entry.getParent(entry);
346
			parentEntry = (AbstractEntry) entry.getParent(entry);
329
			setEntryChildren(parentEntry);
347
			setEntryChildren(parentEntry);
330
			resetChildIndex();
348
			resetChildIndex();
331
			if (childIndex == entryChildren.length - 1)
349
			if (childIndex == entryChildren.length - 1)
Lines 334-354 Link Here
334
352
335
		resetTotalElementCount();
353
		resetTotalElementCount();
336
		
354
		
337
		String strDate = entry.getFormattedDate();
355
		if (entry instanceof LogEntry) {
338
		dateLabel.setText(strDate);
356
			LogEntry logEntry = (LogEntry) entry;
339
		severityImageLabel.setImage(labelProvider.getColumnImage(entry, 0));
357
			
340
		severityLabel.setText(entry.getSeverityText());
358
			String strDate = logEntry.getFormattedDate();
341
		msgText.setText(entry.getMessage() != null ? entry.getMessage() : ""); //$NON-NLS-1$
359
			dateLabel.setText(strDate);
342
		String stack = entry.getStack();
360
			severityImageLabel.setImage(labelProvider.getColumnImage(entry, 0));
343
		if (stack != null) {
361
			severityLabel.setText(logEntry.getSeverityText());
344
			stackTraceText.setText(stack);
362
			msgText.setText(logEntry.getMessage() != null ? logEntry.getMessage() : ""); //$NON-NLS-1$
363
			String stack = logEntry.getStack();
364
			if (stack != null) {
365
				stackTraceText.setText(stack);
366
			} else {
367
				stackTraceText.setText(Messages.EventDetailsDialog_noStack);
368
			}
369
			
370
			String session = logEntry.getSession().getSessionData();
371
			if (stack != null) {
372
				sessionDataText.setText(session);
373
			}
374
			
345
		} else {
375
		} else {
346
			stackTraceText.setText(Messages.EventDetailsDialog_noStack);
376
			dateLabel.setText(""); //$NON-NLS-1$
377
			severityImageLabel.setImage(null);
378
			severityLabel.setText(""); //$NON-NLS-1$
379
			msgText.setText(""); //$NON-NLS-1$
380
			stackTraceText.setText(""); //$NON-NLS-1$
381
			sessionDataText.setText(""); //$NON-NLS-1$
347
		}
382
		}
348
		LogSession session = entry.getSession();
383
		
349
		if (session != null && session.getSessionData() != null)
350
			sessionDataText.setText(session.getSessionData());
351
352
		updateButtons();
384
		updateButtons();
353
	}
385
	}
354
	
386
	
Lines 363-377 Link Here
363
		}
395
		}
364
	}
396
	}
365
	
397
	
366
	private void findNextSelectedChild(LogEntry originalEntry){
398
	private void findNextSelectedChild(AbstractEntry originalEntry){
367
		if (isChild (parentEntry)){
399
		if (isChild (parentEntry)){
368
			// we're at the end of the child list; find next parent
400
			// we're at the end of the child list; find next parent
369
			// to select.  If the parent is a child at the end of the child
401
			// to select.  If the parent is a child at the end of the child
370
			// list, find its next parent entry to select, etc.
402
			// list, find its next parent entry to select, etc.
371
			
403
			
372
			entry = parentEntry;
404
			entry = parentEntry;
373
			setEntryChildren((LogEntry)parentEntry.getParent(parentEntry));
405
			setEntryChildren((AbstractEntry)parentEntry.getParent(parentEntry));
374
			parentEntry = (LogEntry)parentEntry.getParent(parentEntry);
406
			parentEntry = (AbstractEntry)parentEntry.getParent(parentEntry);
375
			resetChildIndex();
407
			resetChildIndex();
376
			isLastChild = childIndex == entryChildren.length-1;
408
			isLastChild = childIndex == entryChildren.length-1;
377
			if (isLastChild){
409
			if (isLastChild){
Lines 386-400 Link Here
386
		}
418
		}
387
	}
419
	}
388
	
420
	
389
	private boolean nextChildExists(LogEntry originalEntry, LogEntry originalParent, LogEntry[] originalEntries){
421
	private boolean nextChildExists(AbstractEntry originalEntry, AbstractEntry originalParent, AbstractEntry[] originalEntries){
390
		if (isChild (parentEntry)){
422
		if (isChild (parentEntry)){
391
			// we're at the end of the child list; find next parent
423
			// we're at the end of the child list; find next parent
392
			// to select.  If the parent is a child at the end of the child
424
			// to select.  If the parent is a child at the end of the child
393
			// list, find its next parent entry to select, etc.
425
			// list, find its next parent entry to select, etc.
394
			
426
			
395
			entry = parentEntry;
427
			entry = parentEntry;
396
			setEntryChildren((LogEntry)parentEntry.getParent(parentEntry));
428
			setEntryChildren((AbstractEntry)parentEntry.getParent(parentEntry));
397
			parentEntry = (LogEntry)parentEntry.getParent(parentEntry);
429
			parentEntry = (AbstractEntry)parentEntry.getParent(parentEntry);
398
			resetChildIndex();
430
			resetChildIndex();
399
			if (childIndex == entryChildren.length-1){
431
			if (childIndex == entryChildren.length-1){
400
				nextChildExists(originalEntry, originalParent, originalEntries);
432
				nextChildExists(originalEntry, originalParent, originalEntries);
Lines 413-467 Link Here
413
		return false;
445
		return false;
414
		
446
		
415
	}
447
	}
448
	
449
	/**
450
	 * Sets entry children (Prev-Next navigable) to top-level elements
451
	 */
416
	private void setEntryChildren(){
452
	private void setEntryChildren(){
417
		Object[] children = ((LogViewContentProvider)provider.getContentProvider()).getElements(null);
453
		AbstractEntry[] children = getElements();
418
454
419
		if (comparator != null)
455
		if (comparator != null)
420
			Arrays.sort(children, comparator);
456
			Arrays.sort(children, comparator);
421
		entryChildren = new LogEntry[children.length];
457
		entryChildren = new AbstractEntry[children.length];
422
		
458
		
423
		System.arraycopy(children,0,entryChildren,0,children.length);
459
		System.arraycopy(children,0,entryChildren,0,children.length);
424
	}
460
	}
425
	
461
	
426
	private void resetTotalElementCount(){
462
	private void resetTotalElementCount(){
427
		totalElementCount = entry.getSession().getEntries().size();
463
		totalElementCount = getElements().length;
428
	}
464
	}
429
	
465
	
430
	private void setEntryChildren(LogEntry entry){
466
	/**
431
		LogSession session = entry.getSession();
467
	 * Sets entry children (Prev-Next navigable) to children of given entry
432
		if (session == null)
468
	 */
433
			return;
469
	private void setEntryChildren(AbstractEntry entry){
470
		Object[] children = entry.getChildren(entry);
434
		
471
		
435
		List children = session.getEntries();
436
		if (comparator != null)
472
		if (comparator != null)
437
			Collections.sort(children, comparator);
473
			Arrays.sort(children, comparator);
438
		entryChildren = (LogEntry[])children.toArray(new LogEntry[children.size()]);
474
		
475
		List result = new ArrayList();
476
		for (int i = 0; i < children.length; i++) {
477
			if (children[i] instanceof AbstractEntry) {
478
				result.add(children[i]);
479
			}
480
		}
481
		
482
		entryChildren = (AbstractEntry[])result.toArray(new AbstractEntry[result.size()]);
439
	}
483
	}
440
484
	
485
	/**
486
	 * Returns the number of top level element containing current entry.
487
	 * @return
488
	 */
441
	private int getParentElementNum(){
489
	private int getParentElementNum(){
442
		LogEntry itemEntry = (LogEntry)((IStructuredSelection)provider.getSelection()).getFirstElement();
490
		AbstractEntry itemEntry = (AbstractEntry)((IStructuredSelection)provider.getSelection()).getFirstElement();
443
		itemEntry = getRootEntry(itemEntry);
491
		AbstractEntry topParent = itemEntry;
444
		
492
		
445
		setEntryChildren(itemEntry);
493
		while (topParent.getParent(itemEntry) != null) {
446
		for (int i = 0; i<entryChildren.length; i++){
494
			topParent = (AbstractEntry) topParent.getParent(itemEntry);
447
			try {
495
		}
448
				LogEntry littleEntry = entryChildren[i];
496
		
449
				if (itemEntry.equals(littleEntry)){
497
		AbstractEntry[] topElements = getElements();
450
					return i;
498
		if (comparator != null)
451
				}
499
			Arrays.sort(topElements, comparator);
452
			} catch (Exception e){
500
		
453
				
501
		for (int i = 0; i < topElements.length; i++ ) {
502
			if (topElements[i].equals(topParent)) {
503
				return i;
454
			}
504
			}
455
		}
505
		}
506
		
456
		return 0;
507
		return 0;
457
	}
508
	}
458
	
509
	
459
	private LogEntry getRootEntry(LogEntry entry){
460
		if (!isChild(entry))
461
			return entry;
462
		return getRootEntry((LogEntry)entry.getParent(entry));
463
	}
464
	
465
	public SashForm getSashForm(){
510
	public SashForm getSashForm(){
466
		return sashForm;
511
		return sashForm;
467
	}
512
	}
Lines 696-699 Link Here
696
		s.put("sashWidth1", sashWeights[0]); //$NON-NLS-1$
741
		s.put("sashWidth1", sashWeights[0]); //$NON-NLS-1$
697
		s.put("sashWidth2", sashWeights[1]); //$NON-NLS-1$
742
		s.put("sashWidth2", sashWeights[1]); //$NON-NLS-1$
698
	}
743
	}
744
	
745
	/**
746
	 * Utility method to get all top level elements of the Log View
747
	 * @return top level elements of the Log View
748
	 */
749
	private AbstractEntry[] getElements() {
750
		return (AbstractEntry[])((ITreeContentProvider)provider.getContentProvider()).getElements(null);
751
	}
699
}
752
}
(-)src/org/eclipse/ui/internal/views/log/LogReader.java (-42 / +52 lines)
Lines 35-47 Link Here
35
	private static final int STACK_STATE = 50;
35
	private static final int STACK_STATE = 50;
36
	private static final int TEXT_STATE = 60;
36
	private static final int TEXT_STATE = 60;
37
	private static final int UNKNOWN_STATE = 70;
37
	private static final int UNKNOWN_STATE = 70;
38
	
39
	private static LogSession currentSession;
40
		
38
		
41
	public static void parseLogFile(File file, ArrayList sessions, IMemento memento) {
39
	public static LogSession parseLogFile(File file, List entries, IMemento memento) {
42
		if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$
40
		if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$
43
				&& memento.getInteger(LogView.P_LOG_LIMIT).intValue() == 0)
41
				&& memento.getInteger(LogView.P_LOG_LIMIT).intValue() == 0)
44
			return;
42
			return null;
45
		
43
		
46
		ArrayList parents = new ArrayList();
44
		ArrayList parents = new ArrayList();
47
		LogEntry current = null;
45
		LogEntry current = null;
Lines 50-56 Link Here
50
		StringWriter swriter = null;
48
		StringWriter swriter = null;
51
		PrintWriter writer = null;
49
		PrintWriter writer = null;
52
		int state = UNKNOWN_STATE;
50
		int state = UNKNOWN_STATE;
53
		currentSession = null;
51
		LogSession currentSession = null;
54
		BufferedReader reader = null;
52
		BufferedReader reader = null;
55
		try {
53
		try {
56
					
54
					
Lines 109-130 Link Here
109
					swriter = new StringWriter();
107
					swriter = new StringWriter();
110
					writer = new PrintWriter(swriter, true);
108
					writer = new PrintWriter(swriter, true);
111
					writerState = SESSION_STATE;
109
					writerState = SESSION_STATE;
112
					updateCurrentSession(session);
110
					currentSession = updateCurrentSession(currentSession, session);
113
					// if current session is most recent and not showing all sessions
111
					// if current session is most recent and not showing all sessions
114
					if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$
112
					if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$
115
						sessions.clear();
113
						entries.clear();
116
					sessions.add(currentSession);
117
				} else if (state == ENTRY_STATE) {
114
				} else if (state == ENTRY_STATE) {
118
					if (currentSession == null) { // create fake session if there was no any
115
					if (currentSession == null) { // create fake session if there was no any
119
						currentSession = new LogSession();
116
						currentSession = new LogSession();
120
						sessions.add(currentSession);
121
					}
117
					}
122
					LogEntry entry = new LogEntry();
118
					LogEntry entry = new LogEntry();
123
					entry.setSession(currentSession);
119
					entry.setSession(currentSession);
124
					entry.processEntry(line);
120
					entry.processEntry(line);
125
					setNewParent(parents, entry, 0);
121
					setNewParent(parents, entry, 0);
126
					current = entry;
122
					current = entry;
127
					addEntry(current, currentSession.getEntries(), memento, false);
123
					addEntry(current, entries, memento);
128
				} else if (state == SUBENTRY_STATE) {
124
				} else if (state == SUBENTRY_STATE) {
129
					if (parents.size() > 0) {
125
					if (parents.size() > 0) {
130
						LogEntry entry = new LogEntry();
126
						LogEntry entry = new LogEntry();
Lines 161-223 Link Here
161
			if (writer != null)
157
			if (writer != null)
162
				writer.close();
158
				writer.close();
163
		}
159
		}
160
		
161
		return currentSession;
164
	}
162
	}
165
		
163
		
166
	/**
164
	/**
167
	 * Updates the {@link currentSession} to be the one that is not null or has most recent date.
165
	 * Updates the {@link currentSession} to be the one that is not null or has most recent date.
168
	 * @param session
166
	 * @param session
169
	 */
167
	 */
170
	private static void updateCurrentSession(LogSession session) {
168
	private static LogSession updateCurrentSession(LogSession currentSession, LogSession session) {
171
		if (currentSession == null) {
169
		if (currentSession == null) {
172
			currentSession = session;
170
			return session;
173
			return;
174
		}		
171
		}		
175
		Date currentDate = currentSession.getDate();
172
		Date currentDate = currentSession.getDate();
176
		Date sessionDate = session.getDate();		
173
		Date sessionDate = session.getDate();		
177
		if (currentDate == null && sessionDate != null)
174
		if (currentDate == null && sessionDate != null)
178
			currentSession = session;
175
			return session;
179
		else if (currentDate != null && sessionDate == null)
176
		else if (currentDate != null && sessionDate == null)
180
			currentSession = session;
177
			return session;
181
		else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate))
178
		else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate))
182
			currentSession = session;
179
			return session;
180
		
181
		return currentSession;
183
	}
182
	}
184
	
183
	
185
	public synchronized static void addEntry(LogEntry current, List entries, IMemento memento, boolean useCurrentSession) {
184
	/**
186
		int severity = current.getSeverity();
185
	 * Adds entry to the list if it's not filtered. Removes entries exceeding the count limit.
187
		boolean doAdd = true;
186
	 * 
187
	 * @param entry
188
	 * @param entries
189
	 * @param memento
190
	 */
191
	private static void addEntry(LogEntry entry, List entries, IMemento memento) {
192
		
193
		if (isLogged(entry, memento)) {
194
			entries.add(entry);
195
			
196
			if (memento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$
197
				int limit = memento.getInteger(LogView.P_LOG_LIMIT).intValue();
198
				if (entries.size() > limit) {
199
					entries.remove(0);
200
				}
201
			}
202
		}
203
	}
204
	
205
	/**
206
	 * Returns whether given entry is logged (true) or filtered (false).
207
	 * 
208
	 * @param entry
209
	 * @param memento
210
	 * @return
211
	 */
212
	public static boolean isLogged(LogEntry entry, IMemento memento) {
213
		int severity = entry.getSeverity();
188
		switch(severity) {
214
		switch(severity) {
189
			case IStatus.INFO:
215
			case IStatus.INFO:
190
				doAdd = memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$
216
				return memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$
191
				break;
192
			case IStatus.WARNING:
217
			case IStatus.WARNING:
193
				doAdd = memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$
218
				return memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$
194
				break;
195
			case IStatus.ERROR:
219
			case IStatus.ERROR:
196
				doAdd = memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$
220
				return memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$
197
				break;
198
		}
199
		if (doAdd) {
200
			if (useCurrentSession)
201
				current.setSession(currentSession);
202
			entries.add(0, current);
203
			
204
			if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$
205
				&& entries.size() > memento.getInteger(LogView.P_LOG_LIMIT).intValue())
206
				entries.remove(entries.size() - 1);
207
		}
221
		}
222
		
223
		return false;
208
	}
224
	}
209
225
210
	private static void setNewParent(
226
	private static void setNewParent(ArrayList parents, LogEntry entry,
211
		ArrayList parents,
227
			int depth) {
212
		LogEntry entry,
213
		int depth) {
214
		if (depth + 1 > parents.size())
228
		if (depth + 1 > parents.size())
215
			parents.add(entry);
229
			parents.add(entry);
216
		else
230
		else
217
			parents.set(depth, entry);
231
			parents.set(depth, entry);
218
	}
232
	}
219
	
220
	public static void reset() {
221
		currentSession = null;
222
	}
223
}
233
}
(-)src/org/eclipse/ui/internal/views/log/AbstractEntry.java (+88 lines)
Added Link Here
1
package org.eclipse.ui.internal.views.log;
2
3
import java.io.PrintWriter;
4
import java.util.ArrayList;
5
import java.util.List;
6
7
import org.eclipse.core.runtime.PlatformObject;
8
import org.eclipse.jface.resource.ImageDescriptor;
9
import org.eclipse.ui.model.IWorkbenchAdapter;
10
11
/**
12
 * Everything that appears in LogView is Abstract Entry. It provides composite pattern.
13
 *
14
 */
15
public abstract class AbstractEntry extends PlatformObject implements IWorkbenchAdapter {
16
17
	private List children;
18
	protected Object parent;
19
	
20
	public void addChild(AbstractEntry child) {
21
		if (children == null) {
22
			children = new ArrayList();
23
		}
24
		children.add(0, child);
25
		child.setParent(this);
26
	}
27
	
28
	public void addChild(AbstractEntry child, int limit) {
29
		addChild(child);
30
		if (children.size() > limit) {
31
			children.remove(children.size() - 1);
32
		}
33
	}
34
	
35
	/**
36
	 * @see IWorkbenchAdapter#getChildren(Object)
37
	 */
38
	public Object[] getChildren(Object parent) {
39
		if (children == null)
40
			return new Object[0];
41
		return children.toArray();
42
	}
43
	
44
	public boolean hasChildren() {
45
		return children != null && children.size() > 0;
46
	}
47
	
48
	public int size() {
49
		return children != null ? children.size() : 0;
50
	}
51
52
	/**
53
	 * @see IWorkbenchAdapter#getImageDescriptor(Object)
54
	 */
55
	public ImageDescriptor getImageDescriptor(Object object) {
56
		return null;
57
	}
58
59
	/**
60
	 * @see IWorkbenchAdapter#getLabel(Object)
61
	 */
62
	public String getLabel(Object o) {
63
		return null;
64
	}
65
66
	/**
67
	 * @see IWorkbenchAdapter#getParent(Object)
68
	 */
69
	public Object getParent(Object o) {
70
		return parent;
71
	}
72
	
73
	public void setParent(AbstractEntry parent) {
74
		this.parent = parent;
75
	}
76
77
	public void removeChildren(List list) {
78
		if (children != null) {
79
			children.removeAll(list);
80
		}
81
	}
82
	
83
	public void removeAllChildren() {
84
		children.clear();
85
	}
86
	
87
	public abstract void write(PrintWriter writer);
88
}
(-)src/org/eclipse/ui/internal/views/log/Group.java (+24 lines)
Added Link Here
1
package org.eclipse.ui.internal.views.log;
2
3
import java.io.PrintWriter;
4
5
/**
6
 * Groups other Abstract Entries under given name.
7
 */
8
public class Group extends AbstractEntry {
9
10
	private String name;
11
	
12
	public Group(String name) {
13
		this.name = name;
14
	}
15
	
16
	public void write(PrintWriter writer) {
17
		// empty
18
	}
19
	
20
	public String toString() {
21
		return name;
22
	}
23
24
}

Return to bug 207344