TMF: Add trace stub for TMF unit tests
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core.tests / stubs / org / eclipse / linuxtools / tmf / tests / stubs / trace / xml / TmfXmlTraceStub.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 * Geneviève Bastien - Initial implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.tests.stubs.trace.xml;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.net.URL;
19
20 import javax.xml.XMLConstants;
21 import javax.xml.transform.Source;
22 import javax.xml.transform.stream.StreamSource;
23 import javax.xml.validation.Schema;
24 import javax.xml.validation.SchemaFactory;
25 import javax.xml.validation.Validator;
26
27 import org.eclipse.core.resources.IProject;
28 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.runtime.IStatus;
30 import org.eclipse.core.runtime.Status;
31 import org.eclipse.linuxtools.internal.tmf.core.Activator;
32 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
33 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
34 import org.eclipse.linuxtools.tmf.core.event.ITmfEventType;
35 import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
36 import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
37 import org.eclipse.linuxtools.tmf.core.event.TmfEventType;
38 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
39 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomEventContent;
40 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent;
41 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace;
42 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition;
43 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
44 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
45 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
46 import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
47 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
48 import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
49 import org.eclipse.osgi.util.NLS;
50 import org.xml.sax.SAXException;
51
52 /**
53 * An XML development trace using a custom XML trace definition and schema.
54 *
55 * This class will typically be used to build custom traces to unit test more
56 * complex functionalities like analyzes or to develop and test data-driven
57 * analyzes.
58 *
59 * This class wraps a custom XML trace and rewrites the returned events in the
60 * getNext() method so that event's fields are the ones defined in <field ... />
61 * elements instead of those defined in the custom XML parser. This way, each
62 * event can have a different set of fields. This class can, for example, mimic
63 * a CTF trace.
64 *
65 * @author Geneviève Bastien
66 */
67 public class TmfXmlTraceStub extends TmfTrace {
68
69 private static final String DEVELOPMENT_TRACE_PARSER_PATH = "TmfXmlDevelopmentTrace.xml"; //$NON-NLS-1$
70 private static final String DEVELOPMENT_TRACE_XSD = "TmfXmlDevelopmentTrace.xsd"; //$NON-NLS-1$
71 private static final String EMPTY = ""; //$NON-NLS-1$
72
73 /* XML elements and attributes names */
74 private static final String EVENT_NAME_FIELD = "Message"; //$NON-NLS-1$
75 private static final String FIELD_NAMES_FIELD = "fields"; //$NON-NLS-1$
76 private static final String SOURCE_FIELD = "source"; //$NON-NLS-1$
77 private static final String VALUES_FIELD = "values"; //$NON-NLS-1$
78 private static final String TYPES_FIELD = "type"; //$NON-NLS-1$
79 private static final String VALUES_SEPARATOR = " \\| "; //$NON-NLS-1$
80 private static final String TYPE_INTEGER = "int"; //$NON-NLS-1$
81 private static final String TYPE_LONG = "long"; //$NON-NLS-1$
82
83 private final CustomXmlTrace fTrace;
84
85 /**
86 * Constructor. Constructs the custom XML trace with the appropriate
87 * definition.
88 */
89 public TmfXmlTraceStub() {
90
91 /* Load custom XML definition */
92 try (InputStream in = TmfXmlTraceStub.class.getResourceAsStream(DEVELOPMENT_TRACE_PARSER_PATH);) {
93 CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(in);
94 if (definitions.length == 0) {
95 throw new IllegalStateException("The custom trace definition does not exist"); //$NON-NLS-1$
96 }
97 fTrace = new CustomXmlTrace(definitions[0]);
98 /* Deregister the custom XML trace */
99 TmfSignalManager.deregister(fTrace);
100 this.setParser(fTrace);
101 } catch (IOException e) {
102 throw new IllegalStateException("Cannot open the trace parser for development traces"); //$NON-NLS-1$
103 }
104
105 }
106
107 @Override
108 public void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException {
109 super.initTrace(resource, path, type);
110 fTrace.initTrace(resource, path, type);
111 ITmfContext ctx;
112 /* Set the start and (current) end times for this trace */
113 ctx = seekEvent(0L);
114 ITmfEvent event = getNext(ctx);
115 if (event != null) {
116 final ITmfTimestamp curTime = event.getTimestamp();
117 this.setStartTime(curTime);
118 this.setEndTime(curTime);
119 }
120 }
121
122 @Override
123 public ITmfLocation getCurrentLocation() {
124 return fTrace.getCurrentLocation();
125 }
126
127 @Override
128 public double getLocationRatio(ITmfLocation location) {
129 return fTrace.getLocationRatio(location);
130 }
131
132 @Override
133 public ITmfContext seekEvent(ITmfLocation location) {
134 return fTrace.seekEvent(location);
135 }
136
137 @Override
138 public ITmfContext seekEvent(double ratio) {
139 return fTrace.seekEvent(ratio);
140 }
141
142 @Override
143 public IStatus validate(IProject project, String path) {
144 File xmlFile = new File(path);
145 if (!xmlFile.exists() || !xmlFile.isFile() || !xmlFile.canRead()) {
146 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_FileNotFound, path));
147 }
148 /* Does the XML file validate with the XSD */
149 SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
150 Source xmlSource = new StreamSource(xmlFile);
151
152 try {
153 URL url = TmfXmlTraceStub.class.getResource(DEVELOPMENT_TRACE_XSD);
154 Schema schema = schemaFactory.newSchema(url);
155
156 Validator validator = schema.newValidator();
157 validator.validate(xmlSource);
158 } catch (SAXException e) {
159 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_ValidationError, path), e);
160 } catch (IOException e) {
161 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.linuxtools.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_IoError, path), e);
162 }
163 return Status.OK_STATUS;
164 }
165
166 @Override
167 public synchronized ITmfEvent getNext(ITmfContext context) {
168 final ITmfContext savedContext = new TmfContext(context.getLocation(), context.getRank());
169 CustomXmlEvent event = fTrace.getNext(context);
170 if (event == null) {
171 return null;
172 }
173
174 /* Translate the content of the event */
175 /* The "fields" field contains a | separated list of field names */
176 /* The "values" field contains a | separated list of field values */
177 /* the "type" field contains a | separated list of field types */
178 ITmfEventField content = event.getContent();
179 String fieldString = (String) content.getField(FIELD_NAMES_FIELD).getValue();
180 String valueString = (String) content.getField(VALUES_FIELD).getValue();
181 String typeString = (String) content.getField(TYPES_FIELD).getValue();
182
183 String[] fields = fieldString.split(VALUES_SEPARATOR);
184 String[] values = valueString.split(VALUES_SEPARATOR);
185 String[] types = typeString.split(VALUES_SEPARATOR);
186 ITmfEventField[] fieldsArray = new TmfEventField[fields.length];
187
188 for (int i = 0; i < fields.length; i++) {
189 String value = EMPTY;
190 if (values.length > i) {
191 value = values[i];
192 }
193 String type = null;
194 if (types.length > i) {
195 type = types[i];
196 }
197 Object val = value;
198 if (type != null) {
199 switch (type) {
200 case TYPE_INTEGER: {
201 try {
202 val = Integer.valueOf(value);
203 } catch (NumberFormatException e) {
204 Activator.logError(String.format("Get next XML event: cannot cast value %s to integer", value), e); //$NON-NLS-1$
205 val = 0;
206 }
207 break;
208 }
209 case TYPE_LONG: {
210 try {
211 val = Long.valueOf(value);
212 } catch (NumberFormatException e) {
213 Activator.logError(String.format("Get next XML event: cannot cast value %s to long", value), e); //$NON-NLS-1$
214 val = 0L;
215 }
216 break;
217 }
218 default:
219 break;
220 }
221 }
222 fieldsArray[i] = new TmfEventField(fields[i], val, null);
223 }
224
225 /* Create a new event with new fields and name */
226 ITmfEventType customEventType = event.getType();
227 TmfEventType eventType = new TmfEventType(customEventType.getContext(), (String) content.getField(EVENT_NAME_FIELD).getValue(), customEventType.getRootField());
228 ITmfEventField eventFields = new CustomEventContent(content.getName(), content.getValue(), fieldsArray);
229 TmfEvent newEvent = new TmfEvent(this, event.getTimestamp(), (String) content.getField(SOURCE_FIELD).getValue(), eventType, eventFields, event.getReference());
230 updateAttributes(savedContext, event.getTimestamp());
231 context.increaseRank();
232
233 return newEvent;
234 }
235
236 }
This page took 0.06432 seconds and 6 git commands to generate.