<s> package org . eclipse . jdt . internal . core ; import java . util . ArrayList ; import java . util . HashMap ; import java . util . HashSet ; import java . util . Iterator ; import java . util . Map ; import java . util . Set ; import org . eclipse . jdt . core . IAnnotation ; import org . eclipse . jdt . core . IJavaElement ; import org . eclipse . jdt . core . IJavaElementDelta ; import org . eclipse . jdt . core . IParent ; import org . eclipse . jdt . core . JavaModelException ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . core . util . Util ; public class JavaElementDeltaBuilder { IJavaElement javaElement ; int maxDepth = Integer . MAX_VALUE ; Map infos ; Map annotationInfos ; Map oldPositions ; Map newPositions ; public JavaElementDelta delta = null ; HashSet added ; HashSet removed ; static class ListItem { public IJavaElement previous ; public IJavaElement next ; public ListItem ( IJavaElement previous , IJavaElement next ) { this . previous = previous ; this . next = next ; } } public JavaElementDeltaBuilder ( IJavaElement javaElement ) { this . javaElement = javaElement ; initialize ( ) ; recordElementInfo ( javaElement , ( JavaModel ) this . javaElement . getJavaModel ( ) , 0 ) ; } public JavaElementDeltaBuilder ( IJavaElement javaElement , int maxDepth ) { this . javaElement = javaElement ; this . maxDepth = maxDepth ; initialize ( ) ; recordElementInfo ( javaElement , ( JavaModel ) this . javaElement . getJavaModel ( ) , 0 ) ; } private void added ( IJavaElement element ) { this . added . add ( element ) ; ListItem current = getNewPosition ( element ) ; ListItem previous = null , next = null ; if ( current . previous != null ) previous = getNewPosition ( current . previous ) ; if ( current . next != null ) next = getNewPosition ( current . next ) ; if ( previous != null ) previous . next = current . next ; if ( next != null ) next . previous = current . previous ; } public void buildDeltas ( ) { this . delta = new JavaElementDelta ( this . javaElement ) ; if ( this . javaElement . getElementType ( ) >= IJavaElement . COMPILATION_UNIT ) { this . delta . fineGrained ( ) ; } recordNewPositions ( this . javaElement , 0 ) ; findAdditions ( this . javaElement , 0 ) ; findDeletions ( ) ; findChangesInPositioning ( this . javaElement , 0 ) ; trimDelta ( this . delta ) ; if ( this . delta . getAffectedChildren ( ) . length == 0 ) { this . delta . contentChanged ( ) ; } } private boolean equals ( char [ ] [ ] [ ] first , char [ ] [ ] [ ] second ) { if ( first == second ) return true ; if ( first == null || second == null ) return false ; if ( first . length != second . length ) return false ; for ( int i = first . length ; -- i >= 0 ; ) if ( ! CharOperation . equals ( first [ i ] , second [ i ] ) ) return false ; return true ; } private void findAdditions ( IJavaElement newElement , int depth ) { JavaElementInfo oldInfo = getElementInfo ( newElement ) ; if ( oldInfo == null && depth < this . maxDepth ) { this . delta . added ( newElement ) ; added ( newElement ) ; } else { removeElementInfo ( newElement ) ; } if ( depth >= this . maxDepth ) { this . delta . changed ( newElement , IJavaElementDelta . F_CONTENT ) ; return ; } JavaElementInfo newInfo = null ; try { newInfo = ( JavaElementInfo ) ( ( JavaElement ) newElement ) . getElementInfo ( ) ; } catch ( JavaModelException npe ) { return ; } findContentChange ( oldInfo , newInfo , newElement ) ; if ( oldInfo != null && newElement instanceof IParent ) { IJavaElement [ ] children = newInfo . getChildren ( ) ; if ( children != null ) { int length = children . length ; for ( int i = 0 ; i < length ; i ++ ) { findAdditions ( children [ i ] , depth + 1 ) ; } } } } private void findChangesInPositioning ( IJavaElement element , int depth ) { if ( depth >= this . maxDepth || this . added . contains ( element ) || this . removed . contains ( element ) ) return ; if ( ! isPositionedCorrectly ( element ) ) { this . delta . changed ( element , IJavaElementDelta . F_REORDER ) ; } if ( element instanceof IParent ) { JavaElementInfo info = null ; try { info = ( JavaElementInfo ) ( ( JavaElement ) element ) . getElementInfo ( ) ; } catch ( JavaModelException npe ) { return ; } IJavaElement [ ] children = info . getChildren ( ) ; if ( children != null ) { int length = children . length ; for ( int i = 0 ; i < length ; i ++ ) { findChangesInPositioning ( children [ i ] , depth + 1 ) ; } } } } private void findAnnotationChanges ( IAnnotation [ ] oldAnnotations , IAnnotation [ ] newAnnotations , IJavaElement parent ) { ArrayList annotationDeltas = null ; for ( int i = 0 , length = newAnnotations . length ; i < length ; i ++ ) { IAnnotation newAnnotation = newAnnotations [ i ] ; Object oldInfo = this . annotationInfos . remove ( newAnnotation ) ; if ( oldInfo == null ) { JavaElementDelta annotationDelta = new JavaElementDelta ( newAnnotation ) ; annotationDelta . added ( ) ; if ( annotationDeltas == null ) annotationDeltas = new ArrayList ( ) ; annotationDeltas . add ( annotationDelta ) ; continue ; } else { AnnotationInfo newInfo = null ; try { newInfo = ( AnnotationInfo ) ( ( JavaElement ) newAnnotation ) . getElementInfo ( ) ; } catch ( JavaModelException npe ) { return ; } if ( ! Util . equalArraysOrNull ( ( ( AnnotationInfo ) oldInfo ) . members , newInfo . members ) ) { JavaElementDelta annotationDelta = new JavaElementDelta ( newAnnotation ) ; annotationDelta . changed ( IJavaElementDelta . F_CONTENT ) ; if ( annotationDeltas == null ) annotationDeltas = new ArrayList ( ) ; annotationDeltas . add ( annotationDelta ) ; } } } for ( int i = 0 , length = oldAnnotations . length ; i < length ; i ++ ) { IAnnotation oldAnnotation = oldAnnotations [ i ] ; if ( this . annotationInfos . remove ( oldAnnotation ) != null ) { JavaElementDelta annotationDelta = new JavaElementDelta ( oldAnnotation ) ; annotationDelta . removed ( ) ; if ( annotationDeltas == null ) annotationDeltas = new ArrayList ( ) ; annotationDeltas . add ( annotationDelta ) ; } } if ( annotationDeltas == null ) return ; int size = annotationDeltas . size ( ) ; if ( size > 0 ) { JavaElementDelta parentDelta = this . delta . changed ( parent , IJavaElementDelta . F_ANNOTATIONS ) ; parentDelta . annotationDeltas = ( IJavaElementDelta [ ] ) annotationDeltas . toArray ( new IJavaElementDelta [ size ] ) ; } } private void findContentChange ( JavaElementInfo oldInfo , JavaElementInfo newInfo , IJavaElement newElement ) { if ( oldInfo instanceof MemberElementInfo && newInfo instanceof MemberElementInfo ) { if ( ( ( MemberElementInfo ) oldInfo ) . getModifiers ( ) != ( ( MemberElementInfo ) newInfo ) . getModifiers ( ) ) { this . delta . changed ( newElement , IJavaElementDelta . F_MODIFIERS ) ; } if ( oldInfo instanceof AnnotatableInfo && newInfo instanceof AnnotatableInfo ) { findAnnotationChanges ( ( ( AnnotatableInfo ) oldInfo ) . annotations , ( ( AnnotatableInfo ) newInfo ) . annotations , newElement ) ; } if ( oldInfo instanceof SourceMethodElementInfo && newInfo instanceof SourceMethodElementInfo ) { SourceMethodElementInfo oldSourceMethodInfo = ( SourceMethodElementInfo ) oldInfo ; SourceMethodElementInfo newSourceMethodInfo = ( SourceMethodElementInfo ) newInfo ; if ( ! CharOperation . equals ( oldSourceMethodInfo . getReturnTypeName ( ) , newSourceMethodInfo . getReturnTypeName ( ) ) || ! CharOperation . equals ( oldSourceMethodInfo . getTypeParameterNames ( ) , newSourceMethodInfo . getTypeParameterNames ( ) ) || ! equals ( oldSourceMethodInfo . getTypeParameterBounds ( ) , newSourceMethodInfo . getTypeParameterBounds ( ) ) ) { this . delta . changed ( newElement , IJavaElementDelta . F_CONTENT ) ; } } else if ( oldInfo instanceof SourceFieldElementInfo && newInfo instanceof SourceFieldElementInfo ) { if ( ! CharOperation . equals ( ( ( SourceFieldElementInfo ) oldInfo ) . getTypeName ( ) , ( ( SourceFieldElementInfo ) newInfo ) . getTypeName ( ) ) ) { this . delta . changed ( newElement , IJavaElementDelta . F_CONTENT ) ; } } else if ( oldInfo instanceof SourceTypeElementInfo && newInfo instanceof SourceTypeElementInfo ) { SourceTypeElementInfo oldSourceTypeInfo = ( SourceTypeElementInfo ) oldInfo ; SourceTypeElementInfo newSourceTypeInfo = ( SourceTypeElementInfo ) newInfo ; if ( ! CharOperation . equals ( oldSourceTypeInfo . getSuperclassName ( ) , newSourceTypeInfo . getSuperclassName ( ) ) || ! CharOperation . equals ( oldSourceTypeInfo . getInterfaceNames ( ) , newSourceTypeInfo . getInterfaceNames ( ) ) ) { this . delta . changed ( newElement , IJavaElementDelta . F_SUPER_TYPES ) ; } if ( ! CharOperation . equals ( oldSourceTypeInfo . getTypeParameterNames ( ) , newSourceTypeInfo . getTypeParameterNames ( ) ) || ! equals ( oldSourceTypeInfo . getTypeParameterBounds ( ) , newSourceTypeInfo . getTypeParameterBounds ( ) ) ) { this . delta . changed ( newElement , IJavaElementDelta . F_CONTENT ) ; } HashMap oldTypeCategories = oldSourceTypeInfo . categories ; HashMap newTypeCategories = newSourceTypeInfo . categories ; if ( oldTypeCategories != null ) { Set elements ; if ( newTypeCategories != null ) { elements = new HashSet ( oldTypeCategories . keySet ( ) ) ; elements . addAll ( newTypeCategories . keySet ( ) ) ; } else elements = oldTypeCategories . keySet ( ) ; Iterator iterator = elements . iterator ( ) ; while ( iterator . hasNext ( ) ) { IJavaElement element = ( IJavaElement ) iterator . next ( ) ; String [ ] oldCategories = ( String [ ] ) oldTypeCategories . get ( element ) ; String [ ] newCategories = newTypeCategories == null ? null : ( String [ ] ) newTypeCategories . get ( element ) ; if ( ! Util . equalArraysOrNull ( oldCategories , newCategories ) ) { this . delta . changed ( element , IJavaElementDelta . F_CATEGORIES ) ; } } } else if ( newTypeCategories != null ) { Iterator elements = newTypeCategories . keySet ( ) . iterator ( ) ; while ( elements . hasNext ( ) ) { IJavaElement element = ( IJavaElement ) elements . next ( ) ; this . delta . changed ( element , IJavaElementDelta . F_CATEGORIES ) ; } } } } } private void findDeletions ( ) { Iterator iter = this . infos . keySet ( ) . iterator ( ) ; while ( iter . hasNext ( ) ) { IJavaElement element = ( IJavaElement ) iter . next ( ) ; this . delta . removed ( element ) ; removed ( element ) ; } } private JavaElementInfo getElementInfo ( IJavaElement element ) { return ( JavaElementInfo ) this . infos . get ( element ) ; } private ListItem getNewPosition ( IJavaElement element ) { return ( ListItem ) this . newPositions . get ( element ) ; } private ListItem getOldPosition ( IJavaElement element ) { return ( ListItem ) this . oldPositions . get ( element ) ; } private void initialize ( ) { this . infos = new HashMap ( 20 ) ; this . oldPositions = new HashMap ( 20 ) ; this . newPositions = new HashMap ( 20 ) ; this . oldPositions . put ( this . javaElement , new ListItem ( null , null ) ) ; this . newPositions . put ( this . javaElement , new ListItem ( null , null ) ) ; this . added = new HashSet ( 5 ) ; this . removed = new HashSet ( 5 ) ; } private void insertPositions ( IJavaElement [ ] elements , boolean isNew ) { int length = elements . length ; IJavaElement previous = null , current = null , next = ( length > 0 ) ? elements [ 0 ] : null ; for ( int i = 0 ; i < length ; i ++ ) { previous = current ; current = next ; next = ( i + 1 < length ) ? elements [ i + 1 ] : null ; if ( isNew ) { this . newPositions . put ( current , new ListItem ( previous , next ) ) ; } else { this . oldPositions . put ( current , new ListItem ( previous , next ) ) ; } } } private boolean isPositionedCorrectly ( IJavaElement element ) { ListItem oldListItem = getOldPosition ( element ) ; if ( oldListItem == null ) return false ; ListItem newListItem = getNewPosition ( element ) ; if ( newListItem == null ) return false ; IJavaElement oldPrevious = oldListItem . previous ; IJavaElement newPrevious = newListItem . previous ; if ( oldPrevious == null ) { return newPrevious == null ; } else { return oldPrevious . equals ( newPrevious ) ; } } private void recordElementInfo ( IJavaElement element , JavaModel model , int depth ) { if ( depth >= this . maxDepth ) { return ; } JavaElementInfo info = ( JavaElementInfo ) JavaModelManager . getJavaModelManager ( ) . getInfo ( element ) ; if ( info == null ) return ; this . infos . put ( element , info ) ; if ( element instanceof IParent ) { IJavaElement [ ] children = info . getChildren ( ) ; if ( children != null ) { insertPositions ( children , false ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) recordElementInfo ( children [ i ] , model , depth + 1 ) ; } } IAnnotation [ ] annotations = null ; if ( info instanceof AnnotatableInfo ) annotations = ( ( AnnotatableInfo ) info ) . annotations ; if ( annotations != null ) { if ( this . annotationInfos == null ) this . annotationInfos = new HashMap ( ) ; JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; for ( int i = 0 , length = annotations . length ; i < length ; i ++ ) { this . annotationInfos . put ( annotations [ i ] , manager . getInfo ( annotations [ i ] ) ) ; } } } private void recordNewPositions ( IJavaElement newElement , int depth ) { if ( depth < this . maxDepth && newElement instanceof IParent ) { JavaElementInfo info = null ; try { info = ( JavaElementInfo ) ( ( JavaElement ) newElement ) . getElementInfo ( ) ; } catch ( JavaModelException npe ) { return ; } IJavaElement [ ] children = info . getChildren ( ) ; if ( children != null ) { insertPositions ( children , true ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { recordNewPositions ( children [ i ] , depth + 1 ) ; } } } } private void removed ( IJavaElement element ) { this . removed . add ( element ) ; ListItem current = getOldPosition ( element ) ; ListItem previous = null , next = null ; if ( current . previous != null ) previous = getOldPosition ( current . previous ) ; if ( current . next != null ) next = getOldPosition ( current . next ) ; if ( previous != null ) previous . next = current . next ; if ( next != null ) next . previous = current . previous ; } private void removeElementInfo ( IJavaElement element ) { this . infos . remove ( element ) ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( ) ; buffer . append ( "" ) ; buffer . append ( this . delta == null ? "<null>" : this . delta . toString ( ) ) ; return buffer . toString ( ) ; } private void trimDelta ( JavaElementDelta elementDelta ) { if ( elementDelta . getKind ( ) == IJavaElementDelta . REMOVED ) { IJavaElementDelta [ ] children = elementDelta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { elementDelta . removeAffectedChild ( ( JavaElementDelta ) children [ i ] ) ; } } else { IJavaElementDelta [ ] children = elementDelta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { trimDelta ( ( JavaElementDelta ) children [ i ] ) ; } } } } </s>