Author: nick Date: Sun Mar 19 08:29:31 2006 New Revision: 386996 URL: http://svn.apache.org/viewcvs?rev=386996&view=rev Log: Improve the child record adding code
Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java?rev=386996&r1=386995&r2=386996&view=diff ============================================================================== --- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java (original) +++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java Sun Mar 19 08:29:31 2006 @@ -35,6 +35,7 @@ public abstract class RecordContainer extends Record { protected Record[] _children; + private Boolean addingChildRecordLock = new Boolean(true); /** * Return any children @@ -51,40 +52,101 @@ * 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 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] Mailing List: http://jakarta.apache.org/site/mail2.html#poi The Apache Jakarta POI Project: http://jakarta.apache.org/poi/