/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2012, 2016 Ericsson, École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Pattern;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.swt.SWT;
/**
public class TimeGraphEntry implements ITimeGraphEntry {
/** Entry's parent */
- private ITimeGraphEntry fParent = null;
+ private TimeGraphEntry fParent = null;
/** List of child entries */
- private final List<ITimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
+ private final List<@NonNull TimeGraphEntry> fChildren = new CopyOnWriteArrayList<>();
/** Name of this entry (text to show) */
private String fName;
private long fStartTime = SWT.DEFAULT;
private long fEndTime = SWT.DEFAULT;
- private List<ITimeEvent> fEventList = new ArrayList<>();
- private List<ITimeEvent> fZoomedEventList = new ArrayList<>();
+ private @NonNull List<ITimeEvent> fEventList = new ArrayList<>();
+ private @NonNull List<ITimeEvent> fZoomedEventList = new ArrayList<>();
private Comparator<ITimeGraphEntry> fComparator;
/**
// Getters and setters
// ---------------------------------------------
- @Override
- public ITimeGraphEntry getParent() {
- return fParent;
- }
-
/**
- * Sets the entry's parent
- *
- * @param entry The new parent entry
+ * @since 2.0
*/
- /*
- * TODO: This method can be removed in the next major API version.
- */
- protected void setParent(TimeGraphEntry entry) {
- fParent = entry;
+ @Override
+ public TimeGraphEntry getParent() {
+ return fParent;
}
/**
* Sets the entry's parent
*
* @param entry The new parent entry
+ * @since 2.0
*/
- /*
- * TODO: This method should be added to the interface in the next major API version.
- */
- protected void setParent(ITimeGraphEntry entry) {
+ public void setParent(TimeGraphEntry entry) {
fParent = entry;
}
}
@Override
- public synchronized List<? extends ITimeGraphEntry> getChildren() {
+ public synchronized List<@NonNull TimeGraphEntry> getChildren() {
return fChildren;
}
+ /**
+ * Clear the children of the entry
+ *
+ * @since 2.0
+ */
+ public synchronized void clearChildren() {
+ fChildren.clear();
+ }
+
@Override
public String getName() {
return fName;
}
@Override
- public Iterator<ITimeEvent> getTimeEventsIterator() {
+ public Iterator<@NonNull ITimeEvent> getTimeEventsIterator() {
if (hasTimeEvents()) {
return new EventIterator(fEventList, fZoomedEventList);
}
}
@Override
- public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
+ public Iterator<@NonNull ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long visibleDuration) {
if (!hasTimeEvents()) {
return null;
}
public void addEvent(ITimeEvent event) {
long start = event.getTime();
long end = start + event.getDuration();
- synchronized (fEventList) {
- int lastIndex = fEventList.size() - 1;
- if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
- fEventList.set(lastIndex, event);
- } else {
- fEventList.add(event);
- }
- if (fStartTime == SWT.DEFAULT || start < fStartTime) {
- fStartTime = start;
- }
- if (fEndTime == SWT.DEFAULT || end > fEndTime) {
- fEndTime = end;
- }
+ int lastIndex = fEventList.size() - 1;
+ if (lastIndex >= 0 && fEventList.get(lastIndex).getTime() == event.getTime()) {
+ fEventList.set(lastIndex, event);
+ } else {
+ fEventList.add(event);
+ }
+ if (event instanceof NullTimeEvent) {
+ /* A NullTimeEvent should not affect the entry bounds */
+ return;
+ }
+ if (fStartTime == SWT.DEFAULT || start < fStartTime) {
+ fStartTime = start;
+ }
+ if (fEndTime == SWT.DEFAULT || end > fEndTime) {
+ fEndTime = end;
}
}
/**
- * Set the general event list of this entry.
+ * Set the general event list of this entry. The list should be modifiable
+ * but will only increase in size over time.
*
* @param eventList
- * The list of time events
+ * The modifiable list of time events, or null to clear the list
*/
public void setEventList(List<ITimeEvent> eventList) {
if (eventList != null) {
- fEventList = new ArrayList<>(eventList);
+ fEventList = eventList;
} else {
fEventList = new ArrayList<>();
}
}
/**
- * Set the zoomed event list of this entry.
+ * Set the zoomed event list of this entry. The list should be modifiable
+ * but will only increase in size over time.
*
* @param eventList
- * The list of time events
+ * The modifiable list of time events, or null to clear the list
*/
public void setZoomedEventList(List<ITimeEvent> eventList) {
if (eventList != null) {
- fZoomedEventList = new ArrayList<>(eventList);
+ fZoomedEventList = eventList;
} else {
fZoomedEventList = new ArrayList<>();
}
}
/**
- * Add a child entry to this one
+ * Add an event to this entry's zoomed event list. If necessary, update the
+ * start and end time of the entry. If the zoomed event list's last event
+ * starts at the same time as the event to add, it is replaced by the new
+ * event. If the new event starts before the zoomed event list's last event,
+ * the new event is ignored and is assumed to be already part of the list.
+ * If the new event starts before the zoomed event list's first event, the
+ * list is assumed to be incomplete and is cleared, and the event is added.
*
- * @param child
- * The child entry
- */
- /*
- * TODO: This method can be removed in the next major API version.
+ * @param event
+ * The time event to add
+ * @since 1.1
*/
- public synchronized void addChild(TimeGraphEntry child) {
- addChild((ITimeGraphEntry) child);
+ public void addZoomedEvent(ITimeEvent event) {
+ long start = event.getTime();
+ long end = start + event.getDuration();
+ int lastIndex = fZoomedEventList.size() - 1;
+ long lastStart = lastIndex >= 0 ? fZoomedEventList.get(lastIndex).getTime() : Long.MIN_VALUE;
+ if (start > lastStart) {
+ fZoomedEventList.add(event);
+ } else if (start == lastStart) {
+ fZoomedEventList.set(lastIndex, event);
+ } else if (start < fZoomedEventList.get(0).getTime()) {
+ fZoomedEventList.clear();
+ fZoomedEventList.add(event);
+ }
+ if (event instanceof NullTimeEvent) {
+ /* A NullTimeEvent should not affect the entry bounds */
+ return;
+ }
+ if (fStartTime == SWT.DEFAULT || start < fStartTime) {
+ fStartTime = start;
+ }
+ if (fEndTime == SWT.DEFAULT || end > fEndTime) {
+ fEndTime = end;
+ }
}
/**
* @param child
* The child entry
*/
- public synchronized void addChild(ITimeGraphEntry child) {
- /*
- * TODO: Use setParent() once it is added to the interface.
- */
- if (child instanceof TimeGraphEntry) {
- ((TimeGraphEntry) child).fParent = this;
- }
+ public synchronized void addChild(@NonNull TimeGraphEntry child) {
+ child.setParent(this);
if (fComparator == null) {
fChildren.add(child);
} else {
* Index at which the specified entry is to be inserted
* @param child
* The child entry
+ * @since 2.0
*/
- public synchronized void addChild(int index, ITimeGraphEntry child) {
- /*
- * TODO: Use setParent() once it is added to the interface.
- */
- if (child instanceof TimeGraphEntry) {
- ((TimeGraphEntry) child).fParent = this;
- }
+ public synchronized void addChild(int index, @NonNull TimeGraphEntry child) {
+ child.setParent(this);
fChildren.add(index, child);
}
+ /**
+ * Remove a child entry from this one.
+ *
+ * @param child
+ * The child entry
+ * @since 2.0
+ */
+ public synchronized void removeChild(@NonNull TimeGraphEntry child) {
+ child.setParent(null);
+ fChildren.remove(child);
+ }
+
/**
* Sort the children of this entry using the provided comparator. Subsequent
- * calls to {@link #addChild(ITimeGraphEntry)} will use this comparator to
+ * calls to {@link #addChild(TimeGraphEntry)} will use this comparator to
* maintain the sort order.
*
* @param comparator
if (comparator == null) {
return;
}
- ITimeGraphEntry[] array = fChildren.toArray(new ITimeGraphEntry[0]);
+ @NonNull TimeGraphEntry[] array = fChildren.toArray(new @NonNull TimeGraphEntry[0]);
Arrays.sort(array, comparator);
fChildren.clear();
fChildren.addAll(Arrays.asList(array));
return getClass().getSimpleName() + '(' + fName + ')';
}
+ /**
+ * @since 2.0
+ */
+ @Override
+ public boolean matches(@NonNull Pattern pattern) {
+ // Default implementation
+ return pattern.matcher(fName).find();
+ }
+
}