1 /*******************************************************************************
2 * Copyright (c) 2014, 2016 École Polytechnique de Montréal and others.
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
10 * Florian Wininger - Initial API and implementation
11 * Geneviève Bastien - Review of the initial implementation
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.views
.timegraph
;
16 import java
.util
.Collections
;
17 import java
.util
.Iterator
;
18 import java
.util
.List
;
19 import java
.util
.regex
.Pattern
;
21 import org
.apache
.commons
.lang3
.StringUtils
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.jdt
.annotation
.Nullable
;
24 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.model
.ITmfXmlModelFactory
;
25 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.model
.ITmfXmlStateAttribute
;
26 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.model
.TmfXmlLocation
;
27 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.model
.readonly
.TmfXmlReadOnlyModelFactory
;
28 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
29 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.TmfXmlUiStrings
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
31 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemUtils
;
32 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
33 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.TmfXmlUtils
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
35 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
36 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.TimeGraphEntry
;
37 import org
.w3c
.dom
.Element
;
40 * An XML-defined entry, or row, to display in the XML state system view
42 * @author Florian Wininger
44 public class XmlEntry
extends TimeGraphEntry
implements IXmlStateSystemContainer
, Comparable
<XmlEntry
> {
46 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
48 /** Type of resource */
49 public static enum EntryDisplayType
{
50 /** Entries without events to display (filler rows, etc.) */
52 /** Entries with time events */
56 private final @NonNull ITmfTrace fTrace
;
57 private final EntryDisplayType fType
;
58 private final int fBaseQuark
;
59 private final int fDisplayQuark
;
60 private final String fParentId
;
61 private final String fId
;
62 private final @NonNull ITmfStateSystem fSs
;
63 private final @Nullable Element fElement
;
69 * The quark matching this entry, or <code>-1</code> if no quark
71 * The quark containing the value to display. It was needed by
72 * the caller to get the start and end time of this entry, so we
73 * receive it as parameter from him.
75 * The trace on which we are working (FIXME: is this parameter
78 * The name of this entry. It will be overridden if a "name" XML
79 * tag is specified in the entryElement. It will also be used as
80 * the ID of this entry if no "id" XML tag is specified. It
81 * typically is the attribute name corresponding the the base
84 * The start time of this entry lifetime
86 * The end time of this entry
88 * The display type of this entry
90 * The state system this entry belongs to
92 * The XML element describing this entry. This element will be
93 * used to determine, if available, the parent, ID, name and
94 * other display option of this entry
96 public XmlEntry(int baseQuark
, int displayQuark
, @NonNull ITmfTrace trace
, String name
, long startTime
, long endTime
, EntryDisplayType type
, @NonNull ITmfStateSystem ss
, Element entryElement
) {
97 super(name
, startTime
, endTime
);
100 fBaseQuark
= baseQuark
;
101 fDisplayQuark
= displayQuark
;
103 fElement
= entryElement
;
105 /* Get the parent if specified */
106 List
<Element
> elements
= TmfXmlUtils
.getChildElements(fElement
, TmfXmlUiStrings
.PARENT_ELEMENT
);
107 if (elements
.size() > 0) {
108 fParentId
= getFirstValue(elements
.get(0));
110 fParentId
= EMPTY_STRING
;
113 /* Get the name of this entry */
114 elements
= TmfXmlUtils
.getChildElements(fElement
, TmfXmlUiStrings
.NAME_ELEMENT
);
115 if (elements
.size() > 0) {
116 String nameFromSs
= getFirstValue(elements
.get(0));
117 if (!nameFromSs
.isEmpty()) {
122 /* Get the id of this entry */
123 elements
= TmfXmlUtils
.getChildElements(fElement
, TmfXmlUiStrings
.ID_ELEMENT
);
124 if (elements
.size() > 0) {
125 fId
= getFirstValue(elements
.get(0));
136 * The quark matching this entry, or <code>-1</code> if no quark
138 * The trace on which we are working
140 * The exec_name of this entry
142 * The state system this entry belongs to
144 public XmlEntry(int baseQuark
, @NonNull ITmfTrace trace
, String name
, @NonNull ITmfStateSystem ss
) {
145 super(name
, ss
.getStartTime(), ss
.getCurrentEndTime());
147 fType
= EntryDisplayType
.NULL
;
148 fBaseQuark
= baseQuark
;
149 fDisplayQuark
= baseQuark
;
152 fParentId
= EMPTY_STRING
;
156 /** Return the state value of the first interval with a non-null value */
157 private String
getFirstValue(Element stateAttribute
) {
158 if (stateAttribute
== null) {
159 throw new IllegalArgumentException();
162 ITmfXmlModelFactory factory
= TmfXmlReadOnlyModelFactory
.getInstance();
163 ITmfXmlStateAttribute display
= factory
.createStateAttribute(stateAttribute
, this);
164 int quark
= display
.getAttributeQuark(fBaseQuark
, null);
165 if (quark
!= IXmlStateSystemContainer
.ERROR_QUARK
) {
166 ITmfStateInterval firstInterval
= StateSystemUtils
.queryUntilNonNullValue(fSs
, quark
, getStartTime(), getEndTime());
167 if (firstInterval
!= null) {
168 return firstInterval
.getStateValue().toString();
175 * Get the trace this entry was taken from
177 * @return the entry's trace
179 public @NonNull ITmfTrace
getTrace() {
184 * Get the entry Type of this entry. Uses the inner EntryDisplayType enum.
186 * @return The entry type
188 public EntryDisplayType
getType() {
193 * Get the quark from which to get the time event intervals for this entry.
195 * @return The attribute quark containing the intervals to display
197 public int getDisplayQuark() {
198 return fDisplayQuark
;
202 * Get this entry's ID
204 * @return The id of the entry.
206 public String
getId() {
211 * Return the entry's parent ID. It corresponds to another entry's ID
212 * received from the {@link #getId()} method.
214 * @return The parent ID of this entry
216 public String
getParentId() {
221 public boolean hasTimeEvents() {
222 if (fType
== EntryDisplayType
.NULL
) {
229 * Return the state system this entry is associated to
231 * @return The state system, or <code>null</code> if the state system can't
236 public ITmfStateSystem
getStateSystem() {
241 public String
getAttributeValue(String name
) {
246 public Iterable
<TmfXmlLocation
> getLocations() {
247 return Collections
.EMPTY_SET
;
251 public Iterator
<@NonNull ITimeEvent
> getTimeEventsIterator() {
252 return super.getTimeEventsIterator();
256 public boolean matches(@NonNull Pattern pattern
) {
257 if (pattern
.matcher(getName()).find()) {
260 if (pattern
.matcher(fId
).find()) {
263 return pattern
.matcher(fParentId
).find();
267 public int compareTo(XmlEntry other
) {
268 // First compare by type
269 int cmp
= getType().compareTo(other
.getType());
273 // For equal type, then compare by element's attribute (to not mix
274 // different element's entries)
275 Element element
= fElement
;
276 String attrib
= (element
== null) ? StringUtils
.EMPTY
: element
.getAttribute(TmfXmlUiStrings
.PATH
);
277 element
= other
.fElement
;
278 String otherAttrib
= (element
== null) ? StringUtils
.EMPTY
: element
.getAttribute(TmfXmlUiStrings
.PATH
);
279 cmp
= attrib
.compareTo(otherAttrib
);
283 // Then compare by name
284 return getName().compareTo(other
.getName());