import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
+import java.util.HashSet;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tracecompass.internal.tmf.core.Activator;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.TmfContext;
import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
+import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.xml.sax.SAXException;
private static final String VALUES_SEPARATOR = " \\| "; //$NON-NLS-1$
private static final String TYPE_INTEGER = "int"; //$NON-NLS-1$
private static final String TYPE_LONG = "long"; //$NON-NLS-1$
- private static final String ASPECT_SPECIAL_EVENT = "set_aspects";
private static final String ASPECT_CPU = "cpu";
private static final Long SECONDS_TO_NS = 1000000000L;
- private final CustomXmlTrace fTrace;
+ private final CustomXmlTraceDefinition fDefinition;
+ private CustomXmlTrace fTrace;
- private Collection<ITmfEventAspect> fAspects;
+ private Collection<ITmfEventAspect<?>> fAspects = TmfTrace.BASE_ASPECTS;
+ private final Collection<ITmfEventAspect<?>> fAdditionalAspects = new HashSet<>();
/**
* Constructor. Constructs the custom XML trace with the appropriate
/* Load custom XML definition */
try (InputStream in = TmfXmlTraceStub.class.getResourceAsStream(DEVELOPMENT_TRACE_PARSER_PATH);) {
CustomXmlTraceDefinition[] definitions = CustomXmlTraceDefinition.loadAll(in);
- if (definitions.length == 0) {
+ if (definitions.length < 2) {
throw new IllegalStateException("The custom trace definition does not exist"); //$NON-NLS-1$
}
- fTrace = new CustomXmlTrace(definitions[0]);
- /* Deregister the custom XML trace */
- TmfSignalManager.deregister(fTrace);
-
- Collection<ITmfEventAspect> aspects = TmfTrace.BASE_ASPECTS;
- fAspects = aspects;
+ /* The first definition parses the 'set_aspects' event */
+ fTrace = new CustomXmlTrace(definitions[0]) {
+ @Override
+ protected ITmfTraceIndexer createIndexer(int interval) {
+ /* Use the in-memory checkpoint indexer */
+ return new TmfCheckpointIndexer(this, interval);
+ }
+ };
+ /* The second definition parses 'event' trace events */
+ fDefinition = checkNotNull(definitions[1]);
} catch (IOException e) {
throw new IllegalStateException("Cannot open the trace parser for development traces"); //$NON-NLS-1$
}
@Override
public void initTrace(@Nullable IResource resource, @Nullable String path, @Nullable Class<? extends ITmfEvent> type) throws TmfTraceException {
super.initTrace(resource, path, type);
- fTrace.initTrace(resource, path, type);
ITmfContext ctx;
+
+ /* Initialize and read the trace with the 'set_aspects' definition */
+ TmfSignalManager.deregister(fTrace);
+ fTrace.initTrace(resource, path, type);
+ ctx = seekEvent(0L);
+ /* If a set_aspects event exists, getNext() will process it */
+ getNext(ctx);
+ ctx.dispose();
+ fTrace.dispose();
+
+ /* Initialize a new trace with the trace events definition */
+ fTrace = new CustomXmlTrace(fDefinition);
+ TmfSignalManager.deregister(fTrace);
+ fTrace.initTrace(resource, path, type);
/* Set the start and (current) end times for this trace */
ctx = seekEvent(0L);
if (ctx == null) {
this.setStartTime(curTime);
this.setEndTime(curTime);
}
+ ctx.dispose();
}
@Override
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.Messages.TmfDevelopmentTrace_IoError, path), e);
}
- @SuppressWarnings("null")
- @NonNull
- IStatus status = Status.OK_STATUS;
- return status;
+ return Status.OK_STATUS;
}
private static String getStringValue(ITmfEventField content, String fieldName) {
fieldsArray[i] = new TmfEventField(checkNotNull(fields[i]), val, null);
}
- /* Generate the aspects for this trace if it is the aspects special event */
- String eventName = getStringValue(content, EVENT_NAME_FIELD);
- if (eventName.equals(ASPECT_SPECIAL_EVENT)) {
+ /*
+ * Generate the aspects for this trace if it is the 'set_aspects'
+ * definition
+ */
+ if (fTrace.getDefinition() != fDefinition) {
generateAspects(fieldsArray);
- return getNext(context);
+ return null;
}
/* Create a new event with new fields and name */
ITmfEventType customEventType = event.getType();
+ String eventName = getStringValue(content, EVENT_NAME_FIELD);
TmfEventType eventType = new TmfEventType(eventName, customEventType.getRootField());
ITmfEventField eventFields = new CustomEventContent(content.getName(), content.getValue(), fieldsArray);
/*
ITmfTimestamp timestamp = new TmfNanoTimestamp(event.getTimestamp().getValue() / SECONDS_TO_NS);
TmfEvent newEvent = new TmfEvent(this, ITmfContext.UNKNOWN_RANK, timestamp, eventType, eventFields);
updateAttributes(savedContext, event);
- context.increaseRank();
-
return newEvent;
}
private void generateAspects(ITmfEventField[] fieldsArray) {
- ImmutableList.Builder<ITmfEventAspect> builder = new ImmutableList.Builder<>();
+ ImmutableList.Builder<ITmfEventAspect<?>> builder = new ImmutableList.Builder<>();
/* Initialize the first default trace aspects */
builder.add(ITmfEventAspect.BaseAspects.TIMESTAMP);
/* Add custom aspects in between */
for (ITmfEventField field : fieldsArray) {
String name = field.getName();
- final ITmfEventAspect aspect = new TmfContentFieldAspect(name, name);
+ final ITmfEventAspect<?> aspect = new TmfContentFieldAspect(name, name);
if (name.equals(ASPECT_CPU)) {
builder.add(new TmfCpuAspect() {
@Override
/* Add the big content aspect */
builder.add(ITmfEventAspect.BaseAspects.CONTENTS);
-
- @SuppressWarnings("null")
- @NonNull Collection<ITmfEventAspect> aspectList = builder.build();
- fAspects = aspectList;
+ /* Add the additional aspects */
+ builder.addAll(fAdditionalAspects);
+ fAspects = builder.build();
}
@Override
- public Iterable<ITmfEventAspect> getEventAspects() {
+ public Iterable<ITmfEventAspect<?>> getEventAspects() {
return fAspects;
}
+ /**
+ * Adds a new event aspect to this type of trace. Since this trace type is
+ * used to build custom traces that mimic the behavior of real traces, the
+ * required aspects may be missing and this method allows to add them. This
+ * method should be called before calling
+ * {@link #initTrace(IResource, String, Class)} otherwise the additional
+ * aspects will not be picked up when generating the aspects.
+ *
+ * @param aspect
+ * The aspect to have
+ */
+ public void addEventAspect(ITmfEventAspect<?> aspect) {
+ fAdditionalAspects.add(aspect);
+ }
+
}