<s> package org . eclipse . jdt . internal . core . jdom ; import java . util . Enumeration ; import org . eclipse . jdt . core . jdom . * ; import org . eclipse . jdt . internal . core . util . CharArrayBuffer ; import org . eclipse . jdt . internal . core . util . Messages ; public abstract class DOMNode implements IDOMNode { protected DOMNode fFirstChild = null ; protected DOMNode fLastChild = null ; protected DOMNode fNextNode = null ; protected DOMNode fParent = null ; protected DOMNode fPreviousNode = null ; protected boolean fIsFragmented = false ; protected String fName = null ; protected int [ ] fNameRange ; protected char [ ] fDocument = null ; protected int [ ] fSourceRange ; protected int fStateMask = 0 ; protected int fInsertionPosition ; protected static final int MASK_FIELD_HAS_INITIALIZER = 0x00000001 ; protected static final int MASK_FIELD_IS_VARIABLE_DECLARATOR = 0x00000002 ; protected static final int MASK_FIELD_TYPE_ALTERED = 0x00000004 ; protected static final int MASK_NAME_ALTERED = 0x00000008 ; protected static final int MASK_HAS_BODY = 0x00000010 ; protected static final int MASK_HAS_COMMENT = 0x00000020 ; protected static final int MASK_IS_CONSTRUCTOR = 0x00000040 ; protected static final int MASK_TYPE_IS_CLASS = 0x00000080 ; protected static final int MASK_TYPE_HAS_SUPERCLASS = 0x00000100 ; protected static final int MASK_TYPE_HAS_INTERFACES = 0x00000200 ; protected static final int MASK_RETURN_TYPE_ALTERED = 0x00000400 ; protected static final int MASK_DETAILED_SOURCE_INDEXES = 0x00000800 ; DOMNode ( ) { this . fName = null ; this . fDocument = null ; this . fSourceRange = new int [ ] { - 1 , - 1 } ; this . fNameRange = new int [ ] { - 1 , - 1 } ; fragment ( ) ; } DOMNode ( char [ ] document , int [ ] sourceRange , String name , int [ ] nameRange ) { super ( ) ; this . fDocument = document ; this . fSourceRange = sourceRange ; this . fName = name ; this . fNameRange = nameRange ; } public void addChild ( IDOMNode child ) throws IllegalArgumentException , DOMException { basicAddChild ( child ) ; if ( child . getNodeType ( ) == IDOMNode . METHOD && ( ( IDOMMethod ) child ) . isConstructor ( ) ) { ( ( DOMNode ) child ) . fragment ( ) ; } else { fragment ( ) ; } } protected void appendContents ( CharArrayBuffer buffer ) { if ( isFragmented ( ) ) { appendFragmentedContents ( buffer ) ; } else { buffer . append ( this . fDocument , this . fSourceRange [ 0 ] , this . fSourceRange [ 1 ] + 1 - this . fSourceRange [ 0 ] ) ; } } protected void appendContentsOfChildren ( CharArrayBuffer buffer ) { DOMNode child = this . fFirstChild ; DOMNode sibling ; int start = 0 , end = 0 ; if ( child != null ) { start = child . getStartPosition ( ) ; end = child . getEndPosition ( ) ; } while ( child != null ) { sibling = child . fNextNode ; if ( sibling != null ) { if ( sibling . isContentMergableWith ( child ) ) { end = sibling . getEndPosition ( ) ; } else { if ( child . isFragmented ( ) ) { child . appendContents ( buffer ) ; } else { buffer . append ( child . getDocument ( ) , start , end + 1 - start ) ; } start = sibling . getStartPosition ( ) ; end = sibling . getEndPosition ( ) ; } } else { if ( child . isFragmented ( ) ) { child . appendContents ( buffer ) ; } else { buffer . append ( child . getDocument ( ) , start , end + 1 - start ) ; } } child = sibling ; } } protected abstract void appendFragmentedContents ( CharArrayBuffer buffer ) ; void basicAddChild ( IDOMNode child ) throws IllegalArgumentException , DOMException { if ( ! canHaveChildren ( ) ) { throw new DOMException ( Messages . dom_unableAddChild ) ; } if ( child == null ) { throw new IllegalArgumentException ( Messages . dom_addNullChild ) ; } if ( ! isAllowableChild ( child ) ) { throw new DOMException ( Messages . dom_addIncompatibleChild ) ; } if ( child . getParent ( ) != null ) { throw new DOMException ( Messages . dom_addChildWithParent ) ; } if ( child == getRoot ( ) ) { throw new DOMException ( Messages . dom_addAncestorAsChild ) ; } DOMNode node = ( DOMNode ) child ; if ( node . getDocument ( ) != getDocument ( ) ) { node . localizeContents ( ) ; } if ( this . fFirstChild == null ) { this . fFirstChild = node ; } else { this . fLastChild . fNextNode = node ; node . fPreviousNode = this . fLastChild ; } this . fLastChild = node ; node . fParent = this ; } protected void becomeDetailed ( ) throws DOMException { if ( ! isDetailed ( ) ) { DOMNode detailed = getDetailedNode ( ) ; if ( detailed == null ) { throw new DOMException ( Messages . dom_cannotDetail ) ; } if ( detailed != this ) { shareContents ( detailed ) ; } } } public boolean canHaveChildren ( ) { return false ; } public Object clone ( ) { int length = 0 ; char [ ] buffer = null ; int offset = this . fSourceRange [ 0 ] ; if ( offset >= 0 ) { length = this . fSourceRange [ 1 ] - offset + 1 ; buffer = new char [ length ] ; System . arraycopy ( this . fDocument , offset , buffer , 0 , length ) ; } DOMNode clone = newDOMNode ( ) ; clone . shareContents ( this ) ; clone . fDocument = buffer ; if ( offset > 0 ) { clone . offset ( 0 - offset ) ; } if ( canHaveChildren ( ) ) { Enumeration children = getChildren ( ) ; while ( children . hasMoreElements ( ) ) { DOMNode child = ( DOMNode ) children . nextElement ( ) ; if ( child . fDocument == this . fDocument ) { DOMNode childClone = child . cloneSharingDocument ( buffer , offset ) ; clone . basicAddChild ( childClone ) ; } else { DOMNode childClone = ( DOMNode ) child . clone ( ) ; clone . addChild ( childClone ) ; } } } return clone ; } private DOMNode cloneSharingDocument ( char [ ] document , int rootOffset ) { DOMNode clone = newDOMNode ( ) ; clone . shareContents ( this ) ; clone . fDocument = document ; if ( rootOffset > 0 ) { clone . offset ( 0 - rootOffset ) ; } if ( canHaveChildren ( ) ) { Enumeration children = getChildren ( ) ; while ( children . hasMoreElements ( ) ) { DOMNode child = ( DOMNode ) children . nextElement ( ) ; if ( child . fDocument == this . fDocument ) { DOMNode childClone = child . cloneSharingDocument ( document , rootOffset ) ; clone . basicAddChild ( childClone ) ; } else { DOMNode childClone = ( DOMNode ) child . clone ( ) ; clone . addChild ( childClone ) ; } } } return clone ; } protected void fragment ( ) { if ( ! isFragmented ( ) ) { this . fIsFragmented = true ; if ( this . fParent != null ) { this . fParent . fragment ( ) ; } } } public char [ ] getCharacters ( ) { CharArrayBuffer buffer = new CharArrayBuffer ( ) ; appendContents ( buffer ) ; return buffer . getContents ( ) ; } public IDOMNode getChild ( String name ) { DOMNode child = this . fFirstChild ; while ( child != null ) { String n = child . getName ( ) ; if ( name == null ) { if ( n == null ) { return child ; } } else { if ( name . equals ( n ) ) { return child ; } } child = child . fNextNode ; } return null ; } public Enumeration getChildren ( ) { return new SiblingEnumeration ( this . fFirstChild ) ; } public String getContents ( ) { CharArrayBuffer buffer = new CharArrayBuffer ( ) ; appendContents ( buffer ) ; return buffer . toString ( ) ; } protected DOMNode getDetailedNode ( ) { return this ; } protected char [ ] getDocument ( ) { return this . fDocument ; } public int getEndPosition ( ) { return this . fSourceRange [ 1 ] ; } protected IDOMFactory getFactory ( ) { return new DOMFactory ( ) ; } public IDOMNode getFirstChild ( ) { return this . fFirstChild ; } public int getInsertionPosition ( ) { return this . fInsertionPosition ; } protected boolean getMask ( int mask ) { return ( this . fStateMask & mask ) > 0 ; } public String getName ( ) { return this . fName ; } protected char [ ] getNameContents ( ) { if ( isNameAltered ( ) ) { return this . fName . toCharArray ( ) ; } else { if ( this . fName == null || this . fNameRange [ 0 ] < 0 ) { return null ; } else { int length = this . fNameRange [ 1 ] + 1 - this . fNameRange [ 0 ] ; char [ ] result = new char [ length ] ; System . arraycopy ( this . fDocument , this . fNameRange [ 0 ] , result , 0 , length ) ; return result ; } } } public IDOMNode getNextNode ( ) { return this . fNextNode ; } public IDOMNode getParent ( ) { return this . fParent ; } protected int getParentEndDeclaration ( ) { IDOMNode parent = getParent ( ) ; if ( parent == null ) { return 0 ; } else { if ( parent instanceof IDOMCompilationUnit ) { return 0 ; } else { return ( ( DOMType ) parent ) . getOpenBodyEnd ( ) ; } } } public IDOMNode getPreviousNode ( ) { return this . fPreviousNode ; } protected IDOMNode getRoot ( ) { if ( this . fParent == null ) { return this ; } else { return this . fParent . getRoot ( ) ; } } public int getStartPosition ( ) { return this . fSourceRange [ 0 ] ; } public void insertSibling ( IDOMNode sibling ) throws IllegalArgumentException , DOMException { if ( sibling == null ) { throw new IllegalArgumentException ( Messages . dom_addNullSibling ) ; } if ( this . fParent == null ) { throw new DOMException ( Messages . dom_addSiblingBeforeRoot ) ; } if ( ! this . fParent . isAllowableChild ( sibling ) ) { throw new DOMException ( Messages . dom_addIncompatibleSibling ) ; } if ( sibling . getParent ( ) != null ) { throw new DOMException ( Messages . dom_addSiblingWithParent ) ; } if ( sibling == getRoot ( ) ) { throw new DOMException ( Messages . dom_addAncestorAsSibling ) ; } DOMNode node = ( DOMNode ) sibling ; if ( node . getDocument ( ) != getDocument ( ) ) { node . localizeContents ( ) ; } if ( this . fPreviousNode == null ) { this . fParent . fFirstChild = node ; } else { this . fPreviousNode . fNextNode = node ; } node . fParent = this . fParent ; node . fPreviousNode = this . fPreviousNode ; node . fNextNode = this ; this . fPreviousNode = node ; if ( node . getNodeType ( ) == IDOMNode . METHOD && ( ( IDOMMethod ) node ) . isConstructor ( ) ) { node . fragment ( ) ; } else { this . fParent . fragment ( ) ; } } public boolean isAllowableChild ( IDOMNode node ) { return false ; } protected boolean isContentMergableWith ( DOMNode node ) { return ! node . isFragmented ( ) && ! isFragmented ( ) && node . getDocument ( ) == getDocument ( ) && node . getEndPosition ( ) + 1 == getStartPosition ( ) ; } protected boolean isDetailed ( ) { return getMask ( MASK_DETAILED_SOURCE_INDEXES ) ; } protected boolean isFragmented ( ) { return this . fIsFragmented ; } protected boolean isNameAltered ( ) { return getMask ( MASK_NAME_ALTERED ) ; } public boolean isSignatureEqual ( IDOMNode node ) { return getNodeType ( ) == node . getNodeType ( ) && getName ( ) . equals ( node . getName ( ) ) ; } protected void localizeContents ( ) { DOMNode clone = ( DOMNode ) clone ( ) ; shareContents ( clone ) ; } protected abstract DOMNode newDOMNode ( ) ; void normalize ( ILineStartFinder finder ) { if ( getPreviousNode ( ) == null ) normalizeStartPosition ( getParentEndDeclaration ( ) , finder ) ; if ( canHaveChildren ( ) ) { Enumeration children = getChildren ( ) ; while ( children . hasMoreElements ( ) ) ( ( DOMNode ) children . nextElement ( ) ) . normalize ( finder ) ; } normalizeEndPosition ( finder , ( DOMNode ) getNextNode ( ) ) ; } void normalizeEndPosition ( ILineStartFinder finder , DOMNode next ) { if ( next == null ) { DOMNode parent = ( DOMNode ) getParent ( ) ; if ( parent == null || parent instanceof DOMCompilationUnit ) { setSourceRangeEnd ( this . fDocument . length - 1 ) ; } else { int temp = ( ( DOMType ) parent ) . getCloseBodyPosition ( ) - 1 ; setSourceRangeEnd ( temp ) ; this . fInsertionPosition = Math . max ( finder . getLineStart ( temp + 1 ) , getEndPosition ( ) ) ; } } else { int temp = next . getStartPosition ( ) - 1 ; this . fInsertionPosition = Math . max ( finder . getLineStart ( temp + 1 ) , getEndPosition ( ) ) ; next . normalizeStartPosition ( getEndPosition ( ) , finder ) ; setSourceRangeEnd ( next . getStartPosition ( ) - 1 ) ; } } void normalizeStartPosition ( int previousEnd , ILineStartFinder finder ) { int nodeStart = getStartPosition ( ) ; int lineStart = finder . getLineStart ( nodeStart ) ; if ( nodeStart > lineStart && ( lineStart > previousEnd || ( previousEnd == 0 && lineStart == 0 ) ) ) setStartPosition ( lineStart ) ; } protected void offset ( int offset ) { offsetRange ( this . fNameRange , offset ) ; offsetRange ( this . fSourceRange , offset ) ; } protected void offsetRange ( int [ ] range , int offset ) { for ( int i = 0 ; i < range . length ; i ++ ) { range [ i ] += offset ; if ( range [ i ] < 0 ) { range [ i ] = - 1 ; } } } protected int [ ] rangeCopy ( int [ ] range ) { int [ ] copy = new int [ range . length ] ; for ( int i = 0 ; i < range . length ; i ++ ) { copy [ i ] = range [ i ] ; } return copy ; } public void remove ( ) { if ( this . fParent != null ) { this . fParent . fragment ( ) ; } if ( this . fNextNode != null ) { this . fNextNode . fPreviousNode = this . fPreviousNode ; } if ( this . fPreviousNode != null ) { this . fPreviousNode . fNextNode = this . fNextNode ; } if ( this . fParent != null ) { if ( this . fParent . fFirstChild == this ) { this . fParent . fFirstChild = this . fNextNode ; } if ( this . fParent . fLastChild == this ) { this . fParent . fLastChild = this . fPreviousNode ; } } this . fParent = null ; this . fNextNode = null ; this . fPreviousNode = null ; } protected void setMask ( int mask , boolean on ) { if ( on ) { this . fStateMask |= mask ; } else { this . fStateMask &= ~ mask ; } } public void setName ( String name ) { this . fName = name ; setNameAltered ( true ) ; fragment ( ) ; } protected void setNameAltered ( boolean altered ) { setMask ( MASK_NAME_ALTERED , altered ) ; } protected void setSourceRangeEnd ( int end ) { this . fSourceRange [ 1 ] = end ; } protected void setStartPosition ( int start ) { this . fSourceRange [ 0 ] = start ; } protected void shareContents ( DOMNode node ) { this . fDocument = node . fDocument ; this . fIsFragmented = node . fIsFragmented ; this . fName = node . fName ; this . fNameRange = rangeCopy ( node . fNameRange ) ; this . fSourceRange = rangeCopy ( node . fSourceRange ) ; this . fStateMask = node . fStateMask ; if ( canHaveChildren ( ) ) { Enumeration myChildren = getChildren ( ) ; Enumeration otherChildren = node . getChildren ( ) ; DOMNode myChild , otherChild ; while ( myChildren . hasMoreElements ( ) ) { myChild = ( DOMNode ) myChildren . nextElement ( ) ; otherChild = ( DOMNode ) otherChildren . nextElement ( ) ; myChild . shareContents ( otherChild ) ; } } } public abstract String toString ( ) ; } </s>