Add null-checks for Map.get()
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.ui / src / org / eclipse / tracecompass / tmf / analysis / xml / ui / views / timegraph / XmlPresentationProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Florian Wininger - Initial API and implementation
11 * Geneviève Bastien - Review of the initial implementation
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph;
15
16 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.eclipse.jdt.annotation.NonNull;
25 import org.eclipse.swt.graphics.GC;
26 import org.eclipse.swt.graphics.RGB;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings;
30 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
31 import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
32 import org.eclipse.tracecompass.tmf.analysis.xml.ui.views.timegraph.XmlEntry.EntryDisplayType;
33 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
34 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
35 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
36 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
37 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
38 import org.w3c.dom.Element;
39
40 /**
41 * Presentation provider for the XML view, based on the generic TMF presentation
42 * provider.
43 *
44 * TODO: This should support colors/states defined for each entry element in the
45 * XML element. Also, event values may not be integers only (for instance, this
46 * wouldn't support yet the callstack view)
47 *
48 * @author Florian Wininger
49 */
50 public class XmlPresentationProvider extends TimeGraphPresentationProvider {
51
52 private List<StateItem> stateValues = new ArrayList<>();
53 /*
54 * Maps the value of an event with the corresponding index in the
55 * stateValues list
56 */
57 private Map<Integer, Integer> stateIndex = new HashMap<>();
58
59 @Override
60 public int getStateTableIndex(ITimeEvent event) {
61 if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
62 TimeEvent tcEvent = (TimeEvent) event;
63
64 XmlEntry entry = (XmlEntry) event.getEntry();
65 int value = tcEvent.getValue();
66
67 if (entry.getType() == EntryDisplayType.DISPLAY) {
68 // Draw state only if state is already known
69 Integer index = stateIndex.get(value);
70 if (index != null) {
71 return index;
72 }
73 }
74 }
75 return INVISIBLE;
76 }
77
78 @Override
79 public StateItem[] getStateTable() {
80 return stateValues.toArray(new StateItem[stateValues.size()]);
81 }
82
83 @Override
84 public String getEventName(ITimeEvent event) {
85 if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
86 TimeEvent tcEvent = (TimeEvent) event;
87
88 XmlEntry entry = (XmlEntry) event.getEntry();
89 int value = tcEvent.getValue();
90
91 if (entry.getType() == EntryDisplayType.DISPLAY) {
92 Integer index = checkNotNull(stateIndex.get(value));
93 String rgb = stateValues.get(index.intValue()).getStateString();
94 return rgb;
95 }
96 return null;
97 }
98 return Messages.XmlPresentationProvider_MultipleStates;
99 }
100
101 @Override
102 public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
103 /*
104 * TODO: Add the XML elements to support adding extra information in the
105 * tooltips and implement this
106 */
107 return Collections.EMPTY_MAP;
108 }
109
110 @Override
111 public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
112 /*
113 * TODO Add the XML elements to support texts in intervals and implement
114 * this
115 */
116 }
117
118 @Override
119 public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
120 }
121
122 /**
123 * Loads the states from a {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} XML
124 * element
125 *
126 * @param viewElement
127 * The XML view element
128 */
129 public void loadNewStates(@NonNull Element viewElement) {
130 stateValues.clear();
131 stateIndex.clear();
132 List<Element> states = XmlUtils.getChildElements(viewElement, TmfXmlStrings.DEFINED_VALUE);
133
134 for (Element state : states) {
135 int value = Integer.parseInt(state.getAttribute(TmfXmlStrings.VALUE));
136 String name = state.getAttribute(TmfXmlStrings.NAME);
137 String color = state.getAttribute(TmfXmlStrings.COLOR);
138
139 // FIXME Allow this case
140 if (value < 0) {
141 return;
142 }
143
144 RGB colorRGB = new RGB(255, 0, 0);
145 if (color.startsWith(TmfXmlStrings.COLOR_PREFIX)) {
146 Integer hex = Integer.parseInt(color.substring(1), 16);
147 int hex1 = hex.intValue() % 256;
148 int hex2 = (hex.intValue() / 256) % 256;
149 int hex3 = (hex.intValue() / (256 * 256)) % 256;
150 colorRGB = new RGB(hex3, hex2, hex1);
151 } else {
152 colorRGB = calcColor(value);
153 }
154
155 StateItem item = new StateItem(colorRGB, name);
156
157 Integer index = stateIndex.get(value);
158 if (index == null) {
159 /* Add the new state value */
160 stateIndex.put(value, stateValues.size());
161 stateValues.add(item);
162 } else {
163 /* Override a previous state value */
164 stateValues.set(index, item);
165 }
166 }
167 Display.getDefault().asyncExec(new Runnable() {
168 @Override
169 public void run() {
170 fireColorSettingsChanged();
171 }
172 });
173 }
174
175 private static RGB calcColor(int value) {
176 int x = (value * 97) % 1530;
177 int r = 0, g = 0, b = 0;
178 if (x >= 0 && x < 255) {
179 r = 255;
180 g = x;
181 b = 0;
182 }
183 if (x >= 255 && x < 510) {
184 r = 510 - x;
185 g = 255;
186 b = 0;
187 }
188 if (x >= 510 && x < 765) {
189 r = 0;
190 g = 255;
191 b = x - 510;
192 }
193 if (x >= 765 && x < 1020) {
194 r = 0;
195 g = 1020 - x;
196 b = 255;
197 }
198 if (x >= 1020 && x < 1275) {
199 r = x - 1020;
200 g = 0;
201 b = 255;
202 }
203 if (x >= 1275 && x <= 1530) {
204 r = 255;
205 g = 0;
206 b = 1530 - x;
207 }
208 return new RGB(r, g, b);
209 }
210
211 }
This page took 0.049803 seconds and 5 git commands to generate.