1 /*******************************************************************************
2 * Copyright (c) 2016 Ecole Polytechnique de Montreal, Ericsson
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 package org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.segment
;
11 import java
.io
.IOException
;
12 import java
.io
.ObjectInputStream
;
13 import java
.io
.ObjectOutputStream
;
14 import java
.util
.Collections
;
15 import java
.util
.Comparator
;
16 import java
.util
.HashMap
;
19 import org
.eclipse
.jdt
.annotation
.NonNull
;
20 import org
.eclipse
.jdt
.annotation
.Nullable
;
21 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
22 import org
.eclipse
.tracecompass
.segmentstore
.core
.SegmentComparators
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
28 import com
.google
.common
.collect
.Ordering
;
31 * This class implements an XML Pattern Segment. This type of segment has
32 * content and a default timestamp, which is the start time of the segment.
34 * @author Jean-Christian Kouame
38 public class TmfXmlPatternSegment
implements ISegment
{
41 * The serial version UID
43 private static final long serialVersionUID
= 3556323761465412078L;
45 /* 'Byte' equivalent for state values types */
46 private static final byte TYPE_NULL
= -1;
47 private static final byte TYPE_INTEGER
= 0;
48 private static final byte TYPE_STRING
= 1;
49 private static final byte TYPE_LONG
= 2;
51 private static final @NonNull Comparator
<ISegment
> COMPARATOR
= Ordering
52 .from(SegmentComparators
.INTERVAL_START_COMPARATOR
)
53 .compound(SegmentComparators
.INTERVAL_END_COMPARATOR
)
54 /* Kind of lazy, but should work! */
55 .compound(Ordering
.usingToString());
57 private final int fScale
;
58 private final long fStart
;
59 private final long fEnd
;
60 private final String fSegmentName
;
61 private transient Map
<@NonNull String
, @NonNull ITmfStateValue
> fContent
;
64 * Constructs an XML pattern segment
67 * Start time of the pattern segment
69 * End time of the pattern segment
71 * Scale of the pattern segment
73 * Name of the pattern segment
75 * Fields of the pattern segment
77 public TmfXmlPatternSegment(long start
, long end
, int scale
, String segmentName
, @NonNull Map
<@NonNull String
, @NonNull ITmfStateValue
> fields
) {
81 fSegmentName
= segmentName
;
82 fContent
= Collections
.unmodifiableMap(fields
);
86 * Get the start timestamp of the segment
88 * @return The start timestamp
90 public @NonNull ITmfTimestamp
getTimestampStart() {
91 return new TmfTimestamp(fStart
, fScale
);
95 * Get the end timestamp of this segment
97 * @return The end timestamp
99 public @NonNull ITmfTimestamp
getTimestampEnd() {
100 return new TmfTimestamp(fEnd
, fScale
);
104 * Get the content of the pattern segment
105 * @return The content
107 public Map
<@NonNull String
, @NonNull ITmfStateValue
> getContent() {
112 * Get the name of pattern segment
115 public String
getName() {
120 * Get the timestamp scale of the pattern segment
121 * @return The timestamp scale
123 public int getScale() {
128 public int compareTo(@Nullable ISegment o
) {
130 throw new IllegalArgumentException("Cannot compare to null"); //$NON-NLS-1$
132 return COMPARATOR
.compare(this, o
);
136 public long getStart() {
141 public long getEnd() {
146 public String
toString() {
147 return new StringBuilder(getClass().getSimpleName())
148 .append(", [fTimestampStart=").append(getTimestampStart()) //$NON-NLS-1$
149 .append(", fTimestampEnd=").append(getTimestampEnd()) //$NON-NLS-1$
150 .append(", duration= ").append(getLength()) //$NON-NLS-1$
151 .append(", fName=").append(getName()) //$NON-NLS-1$
152 .append(", fContent=").append(getContent()) //$NON-NLS-1$
153 .append("]").toString(); //$NON-NLS-1$
156 private void writeObject(ObjectOutputStream out
) throws IOException
{
157 out
.defaultWriteObject();
159 // Write the number of fields
160 out
.writeInt(fContent
.size());
163 for (Map
.Entry
<String
, ITmfStateValue
> entry
: fContent
.entrySet()) {
164 out
.writeInt(entry
.getKey().length());
165 out
.writeBytes(entry
.getKey());
166 final ITmfStateValue value
= entry
.getValue();
167 final byte type
= getByteFromType(value
.getType());
173 out
.writeInt(value
.unboxInt());
176 out
.writeLong(value
.unboxLong());
179 final @NonNull String string
= value
.unboxStr();
180 out
.writeInt(string
.length());
181 out
.writeBytes(string
);
184 throw new IOException("Write object failed : Invalid data"); //$NON-NLS-1$
189 private void readObject(ObjectInputStream in
) throws IOException
, ClassNotFoundException
{
190 in
.defaultReadObject();
191 int contentSize
= in
.readInt();
193 final Map
<@NonNull String
, @NonNull ITmfStateValue
> content
= new HashMap
<>();
194 for (int i
= 0; i
< contentSize
; i
++) {
195 int length
= in
.readInt();
196 byte[] bytes
= new byte[length
];
197 in
.read(bytes
, 0, length
);
198 String name
= new String(bytes
);
200 Byte type
= in
.readByte();
201 ITmfStateValue value
;
204 value
= TmfStateValue
.nullValue();
207 value
= TmfStateValue
.newValueInt(in
.readInt());
210 value
= TmfStateValue
.newValueLong(in
.readLong());
213 length
= in
.readInt();
214 bytes
= new byte[length
];
215 in
.read(bytes
, 0, length
);
216 value
= TmfStateValue
.newValueString(new String(bytes
));
219 throw new IOException("Read object failed : Invalid data"); //$NON-NLS-1$
221 content
.put(name
, value
);
227 * Here we determine how state values "types" are written in the 8-bit field
228 * that indicates the value type in the file.
230 private static byte getByteFromType(ITmfStateValue
.Type type
) {
242 /* Should not happen if the switch is fully covered */
243 throw new IllegalStateException("Data type " + type
+ " not supported"); //$NON-NLS-1$ //$NON-NLS-2$