public abstract class RecordContainer extends Record
{
protected Record[] _children;
+ private Boolean addingChildRecordLock = new Boolean(true);
/**
* Return any children
* return the new list.
*/
public Record[] appendChildRecord(Record newChild, Record[] children) {
- Record[] r = new Record[children.length + 1];
- System.arraycopy(children,0,r,0,children.length);
- r[r.length-1] = newChild;
+ Record[] r;
+ synchronized(addingChildRecordLock) {
+ r = new Record[children.length + 1];
+ System.arraycopy(children,0,r,0,children.length);
+ r[r.length-1] = newChild;
+ }
return r;
}
+ /**
+ * Finds the location of the given child record
+ */
+ private int findChildLocation(Record child) {
+ // Synchronized as we don't want things changing
+ // as we're doing our search
+ synchronized(addingChildRecordLock) {
+ for(int i=0; i<_children.length; i++) {
+ if(_children[i].equals(child)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Adds the given new Child Record at the given location,
+ * shuffling everything from there on down by one
+ * @param newChild
+ * @param position
+ */
+ private void addChildAt(Record newChild, int position) {
+ synchronized(addingChildRecordLock) {
+ Record[] newChildren = new Record[_children.length+1];
+ // Move over to the new array, shuffling on by one after
+ // the addition point
+ for(int i=0; i<_children.length; i++) {
+ if(i == position) {
+ newChildren[i] = newChild;
+ }
+
+ if(i >= position) {
+ newChildren[i+1] = _children[i];
+ }
+ if(i < position) {
+ newChildren[i] = _children[i];
+ }
+ }
+
+ // Special case - new record goes at the end
+ if(position == _children.length) {
+ newChildren[position] = newChild;
+ }
+
+ // All done, replace our child list
+ _children = newChildren;
+ }
+ }
+
/**
* Adds the given Child Record after the supplied record
* @param newChild
* @param after
*/
- public synchronized void addChildAfter(Record newChild, Record after) {
- boolean added = false;
- Record[] newChildren = new Record[_children.length+1];
- for(int i=0; i<_children.length; i++) {
- int newPos = i;
- if(added) { newPos++; }
-
- newChildren[newPos] = _children[i];
- if(_children[i].equals(after)) {
- // Found one to add after
- added = true;
- newPos++;
- newChildren[newPos] = newChild;
+ public void addChildAfter(Record newChild, Record after) {
+ synchronized(addingChildRecordLock) {
+ // Decide where we're going to put it
+ int loc = findChildLocation(after);
+ if(loc == -1) {
+ throw new IllegalArgumentException("Asked to add a new child after another record, but that record wasn't one of our children!");
}
+
+ // Add one place after the supplied record
+ addChildAt(newChild, loc+1);
}
-
- if(added) {
- _children = newChildren;
- } else {
- throw new IllegalArgumentException("Asked to add a new child after another record, but that record wasn't one of our children!");
+ }
+
+ /**
+ * Adds the given Child Record before the supplied record
+ * @param newChild
+ * @param after
+ */
+ public void addChildBefore(Record newChild, Record before) {
+ synchronized(addingChildRecordLock) {
+ // Decide where we're going to put it
+ int loc = findChildLocation(before);
+ if(loc == -1) {
+ throw new IllegalArgumentException("Asked to add a new child before another record, but that record wasn't one of our children!");
+ }
+
+ // Add at the place of the supplied record
+ addChildAt(newChild, loc);
}
}
-
+
/**
* Write out our header, and our children.
* @param headerA the first byte of the header