<s> package org . eclipse . jdt . internal . core ; import java . io . InputStream ; import java . util . ArrayList ; import java . util . HashMap ; import org . eclipse . core . resources . * ; import org . eclipse . core . runtime . * ; import org . eclipse . core . runtime . jobs . ISchedulingRule ; import org . eclipse . jdt . core . * ; import org . eclipse . jdt . internal . core . util . Messages ; import org . eclipse . jface . text . BadLocationException ; import org . eclipse . jface . text . IDocument ; import org . eclipse . text . edits . TextEdit ; public abstract class JavaModelOperation implements IWorkspaceRunnable , IProgressMonitor { protected interface IPostAction { String getID ( ) ; void run ( ) throws JavaModelException ; } protected static final int APPEND = 1 ; protected static final int REMOVEALL_APPEND = 2 ; protected static final int KEEP_EXISTING = 3 ; protected static boolean POST_ACTION_VERBOSE ; protected IPostAction [ ] actions ; protected int actionsStart = 0 ; protected int actionsEnd = - 1 ; protected HashMap attributes ; public static final String HAS_MODIFIED_RESOURCE_ATTR = "" ; public static final String TRUE = JavaModelManager . TRUE ; protected IJavaElement [ ] elementsToProcess ; protected IJavaElement [ ] parentElements ; protected static final IJavaElement [ ] NO_ELEMENTS = new IJavaElement [ ] { } ; protected IJavaElement [ ] resultElements = NO_ELEMENTS ; public IProgressMonitor progressMonitor = null ; protected boolean isNested = false ; protected boolean force = false ; protected static final ThreadLocal OPERATION_STACKS = new ThreadLocal ( ) ; protected JavaModelOperation ( ) { } protected JavaModelOperation ( IJavaElement [ ] elements ) { this . elementsToProcess = elements ; } protected JavaModelOperation ( IJavaElement [ ] elementsToProcess , IJavaElement [ ] parentElements ) { this . elementsToProcess = elementsToProcess ; this . parentElements = parentElements ; } protected JavaModelOperation ( IJavaElement [ ] elementsToProcess , IJavaElement [ ] parentElements , boolean force ) { this . elementsToProcess = elementsToProcess ; this . parentElements = parentElements ; this . force = force ; } protected JavaModelOperation ( IJavaElement [ ] elements , boolean force ) { this . elementsToProcess = elements ; this . force = force ; } protected JavaModelOperation ( IJavaElement element ) { this . elementsToProcess = new IJavaElement [ ] { element } ; } protected void addAction ( IPostAction action ) { int length = this . actions . length ; if ( length == ++ this . actionsEnd ) { System . arraycopy ( this . actions , 0 , this . actions = new IPostAction [ length * 2 ] , 0 , length ) ; } this . actions [ this . actionsEnd ] = action ; } protected void addDelta ( IJavaElementDelta delta ) { JavaModelManager . getJavaModelManager ( ) . getDeltaProcessor ( ) . registerJavaModelDelta ( delta ) ; } protected void addReconcileDelta ( ICompilationUnit workingCopy , IJavaElementDelta delta ) { HashMap reconcileDeltas = JavaModelManager . getJavaModelManager ( ) . getDeltaProcessor ( ) . reconcileDeltas ; JavaElementDelta previousDelta = ( JavaElementDelta ) reconcileDeltas . get ( workingCopy ) ; if ( previousDelta != null ) { IJavaElementDelta [ ] children = delta . getAffectedChildren ( ) ; for ( int i = 0 , length = children . length ; i < length ; i ++ ) { JavaElementDelta child = ( JavaElementDelta ) children [ i ] ; previousDelta . insertDeltaTree ( child . getElement ( ) , child ) ; } if ( ( delta . getFlags ( ) & IJavaElementDelta . F_AST_AFFECTED ) != 0 ) { previousDelta . changedAST ( delta . getCompilationUnitAST ( ) ) ; } } else { reconcileDeltas . put ( workingCopy , delta ) ; } } protected void removeReconcileDelta ( ICompilationUnit workingCopy ) { JavaModelManager . getJavaModelManager ( ) . getDeltaProcessor ( ) . reconcileDeltas . remove ( workingCopy ) ; } protected void applyTextEdit ( ICompilationUnit cu , TextEdit edits ) throws JavaModelException { try { edits . apply ( getDocument ( cu ) ) ; } catch ( BadLocationException e ) { throw new JavaModelException ( e , IJavaModelStatusConstants . INVALID_CONTENTS ) ; } } public void beginTask ( String name , int totalWork ) { if ( this . progressMonitor != null ) { this . progressMonitor . beginTask ( name , totalWork ) ; } } protected boolean canModifyRoots ( ) { return false ; } protected void checkCanceled ( ) { if ( isCanceled ( ) ) { throw new OperationCanceledException ( Messages . operation_cancelled ) ; } } protected IJavaModelStatus commonVerify ( ) { if ( this . elementsToProcess == null || this . elementsToProcess . length == 0 ) { return new JavaModelStatus ( IJavaModelStatusConstants . NO_ELEMENTS_TO_PROCESS ) ; } for ( int i = 0 ; i < this . elementsToProcess . length ; i ++ ) { if ( this . elementsToProcess [ i ] == null ) { return new JavaModelStatus ( IJavaModelStatusConstants . NO_ELEMENTS_TO_PROCESS ) ; } } return JavaModelStatus . VERIFIED_OK ; } protected void copyResources ( IResource [ ] resources , IPath container ) throws JavaModelException { IProgressMonitor subProgressMonitor = getSubProgressMonitor ( resources . length ) ; IWorkspaceRoot root = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; try { for ( int i = 0 , length = resources . length ; i < length ; i ++ ) { IResource resource = resources [ i ] ; IPath destination = container . append ( resource . getName ( ) ) ; if ( root . findMember ( destination ) == null ) { resource . copy ( destination , false , subProgressMonitor ) ; } } setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } protected void createFile ( IContainer folder , String name , InputStream contents , boolean forceFlag ) throws JavaModelException { IFile file = folder . getFile ( new Path ( name ) ) ; try { file . create ( contents , forceFlag ? IResource . FORCE | IResource . KEEP_HISTORY : IResource . KEEP_HISTORY , getSubProgressMonitor ( 1 ) ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } protected void createFolder ( IContainer parentFolder , String name , boolean forceFlag ) throws JavaModelException { IFolder folder = parentFolder . getFolder ( new Path ( name ) ) ; try { folder . create ( forceFlag ? IResource . FORCE | IResource . KEEP_HISTORY : IResource . KEEP_HISTORY , true , getSubProgressMonitor ( 1 ) ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } protected void deleteEmptyPackageFragment ( IPackageFragment fragment , boolean forceFlag , IResource rootResource ) throws JavaModelException { IContainer resource = ( IContainer ) ( ( JavaElement ) fragment ) . resource ( ) ; try { resource . delete ( forceFlag ? IResource . FORCE | IResource . KEEP_HISTORY : IResource . KEEP_HISTORY , getSubProgressMonitor ( 1 ) ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; while ( resource instanceof IFolder ) { resource = resource . getParent ( ) ; if ( ! resource . equals ( rootResource ) && resource . members ( ) . length == 0 ) { resource . delete ( forceFlag ? IResource . FORCE | IResource . KEEP_HISTORY : IResource . KEEP_HISTORY , getSubProgressMonitor ( 1 ) ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } } } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } protected void deleteResource ( IResource resource , int flags ) throws JavaModelException { try { resource . delete ( flags , getSubProgressMonitor ( 1 ) ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } protected void deleteResources ( IResource [ ] resources , boolean forceFlag ) throws JavaModelException { if ( resources == null || resources . length == 0 ) return ; IProgressMonitor subProgressMonitor = getSubProgressMonitor ( resources . length ) ; IWorkspace workspace = resources [ 0 ] . getWorkspace ( ) ; try { workspace . delete ( resources , forceFlag ? IResource . FORCE | IResource . KEEP_HISTORY : IResource . KEEP_HISTORY , subProgressMonitor ) ; setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } public void done ( ) { if ( this . progressMonitor != null ) { this . progressMonitor . done ( ) ; } } protected boolean equalsOneOf ( IPath path , IPath [ ] otherPaths ) { for ( int i = 0 , length = otherPaths . length ; i < length ; i ++ ) { if ( path . equals ( otherPaths [ i ] ) ) { return true ; } } return false ; } public void executeNestedOperation ( JavaModelOperation operation , int subWorkAmount ) throws JavaModelException { IJavaModelStatus status = operation . verify ( ) ; if ( ! status . isOK ( ) ) { throw new JavaModelException ( status ) ; } IProgressMonitor subProgressMonitor = getSubProgressMonitor ( subWorkAmount ) ; try { operation . setNested ( true ) ; operation . run ( subProgressMonitor ) ; } catch ( CoreException ce ) { if ( ce instanceof JavaModelException ) { throw ( JavaModelException ) ce ; } else { if ( ce . getStatus ( ) . getCode ( ) == IResourceStatus . OPERATION_FAILED ) { Throwable e = ce . getStatus ( ) . getException ( ) ; if ( e instanceof JavaModelException ) { throw ( JavaModelException ) e ; } } throw new JavaModelException ( ce ) ; } } } protected abstract void executeOperation ( ) throws JavaModelException ; protected static Object getAttribute ( Object key ) { ArrayList stack = getCurrentOperationStack ( ) ; if ( stack . size ( ) == 0 ) return null ; JavaModelOperation topLevelOp = ( JavaModelOperation ) stack . get ( 0 ) ; if ( topLevelOp . attributes == null ) { return null ; } else { return topLevelOp . attributes . get ( key ) ; } } protected ICompilationUnit getCompilationUnitFor ( IJavaElement element ) { return ( ( JavaElement ) element ) . getCompilationUnit ( ) ; } protected static ArrayList getCurrentOperationStack ( ) { ArrayList stack = ( ArrayList ) OPERATION_STACKS . get ( ) ; if ( stack == null ) { stack = new ArrayList ( ) ; OPERATION_STACKS . set ( stack ) ; } return stack ; } protected IDocument getDocument ( ICompilationUnit cu ) throws JavaModelException { IBuffer buffer = cu . getBuffer ( ) ; if ( buffer instanceof IDocument ) return ( IDocument ) buffer ; return new DocumentAdapter ( buffer ) ; } protected IJavaElement getElementToProcess ( ) { if ( this . elementsToProcess == null || this . elementsToProcess . length == 0 ) { return null ; } return this . elementsToProcess [ 0 ] ; } public IJavaModel getJavaModel ( ) { return JavaModelManager . getJavaModelManager ( ) . getJavaModel ( ) ; } protected IPath [ ] getNestedFolders ( IPackageFragmentRoot root ) throws JavaModelException { IPath rootPath = root . getPath ( ) ; IClasspathEntry [ ] classpath = root . getJavaProject ( ) . getRawClasspath ( ) ; int length = classpath . length ; IPath [ ] result = new IPath [ length ] ; int index = 0 ; for ( int i = 0 ; i < length ; i ++ ) { IPath path = classpath [ i ] . getPath ( ) ; if ( rootPath . isPrefixOf ( path ) && ! rootPath . equals ( path ) ) { result [ index ++ ] = path ; } } if ( index < length ) { System . arraycopy ( result , 0 , result = new IPath [ index ] , 0 , index ) ; } return result ; } protected IJavaElement getParentElement ( ) { if ( this . parentElements == null || this . parentElements . length == 0 ) { return null ; } return this . parentElements [ 0 ] ; } protected IJavaElement [ ] getParentElements ( ) { return this . parentElements ; } public IJavaElement [ ] getResultElements ( ) { return this . resultElements ; } protected ISchedulingRule getSchedulingRule ( ) { return ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; } protected IProgressMonitor getSubProgressMonitor ( int workAmount ) { IProgressMonitor sub = null ; if ( this . progressMonitor != null ) { sub = new SubProgressMonitor ( this . progressMonitor , workAmount , SubProgressMonitor . PREPEND_MAIN_LABEL_TO_SUBTASK ) ; } return sub ; } public boolean hasModifiedResource ( ) { return ! isReadOnly ( ) && getAttribute ( HAS_MODIFIED_RESOURCE_ATTR ) == TRUE ; } public void internalWorked ( double work ) { if ( this . progressMonitor != null ) { this . progressMonitor . internalWorked ( work ) ; } } public boolean isCanceled ( ) { if ( this . progressMonitor != null ) { return this . progressMonitor . isCanceled ( ) ; } return false ; } public boolean isReadOnly ( ) { return false ; } protected boolean isTopLevelOperation ( ) { ArrayList stack ; return ( stack = getCurrentOperationStack ( ) ) . size ( ) > 0 && stack . get ( 0 ) == this ; } protected int firstActionWithID ( String id , int start ) { for ( int i = start ; i <= this . actionsEnd ; i ++ ) { if ( this . actions [ i ] . getID ( ) . equals ( id ) ) { return i ; } } return - 1 ; } protected void moveResources ( IResource [ ] resources , IPath container ) throws JavaModelException { IProgressMonitor subProgressMonitor = null ; if ( this . progressMonitor != null ) { subProgressMonitor = new SubProgressMonitor ( this . progressMonitor , resources . length , SubProgressMonitor . PREPEND_MAIN_LABEL_TO_SUBTASK ) ; } IWorkspaceRoot root = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) ; try { for ( int i = 0 , length = resources . length ; i < length ; i ++ ) { IResource resource = resources [ i ] ; IPath destination = container . append ( resource . getName ( ) ) ; if ( root . findMember ( destination ) == null ) { resource . move ( destination , false , subProgressMonitor ) ; } } setAttribute ( HAS_MODIFIED_RESOURCE_ATTR , TRUE ) ; } catch ( CoreException e ) { throw new JavaModelException ( e ) ; } } public JavaElementDelta newJavaElementDelta ( ) { return new JavaElementDelta ( getJavaModel ( ) ) ; } protected JavaModelOperation popOperation ( ) { ArrayList stack = getCurrentOperationStack ( ) ; int size = stack . size ( ) ; if ( size > 0 ) { if ( size == 1 ) { OPERATION_STACKS . set ( null ) ; } return ( JavaModelOperation ) stack . remove ( size - 1 ) ; } else { return null ; } } protected void postAction ( IPostAction action , int insertionMode ) { if ( POST_ACTION_VERBOSE ) { System . out . print ( "(" + Thread . currentThread ( ) + "" + action . getID ( ) ) ; switch ( insertionMode ) { case REMOVEALL_APPEND : System . out . println ( "" ) ; break ; case KEEP_EXISTING : System . out . println ( "" ) ; break ; case APPEND : System . out . println ( " (APPEND)" ) ; break ; } } JavaModelOperation topLevelOp = ( JavaModelOperation ) getCurrentOperationStack ( ) . get ( 0 ) ; IPostAction [ ] postActions = topLevelOp . actions ; if ( postActions == null ) { topLevelOp . actions = postActions = new IPostAction [ 1 ] ; postActions [ 0 ] = action ; topLevelOp . actionsEnd = 0 ; } else { String id = action . getID ( ) ; switch ( insertionMode ) { case REMOVEALL_APPEND : int index = this . actionsStart - 1 ; while ( ( index = topLevelOp . firstActionWithID ( id , index + 1 ) ) >= 0 ) { System . arraycopy ( postActions , index + 1 , postActions , index , topLevelOp . actionsEnd - index ) ; postActions [ topLevelOp . actionsEnd -- ] = null ; } topLevelOp . addAction ( action ) ; break ; case KEEP_EXISTING : if ( topLevelOp . firstActionWithID ( id , 0 ) < 0 ) { topLevelOp . addAction ( action ) ; } break ; case APPEND : topLevelOp . addAction ( action ) ; break ; } } } protected boolean prefixesOneOf ( IPath path , IPath [ ] otherPaths ) { for ( int i = 0 , length = otherPaths . length ; i < length ; i ++ ) { if ( path . isPrefixOf ( otherPaths [ i ] ) ) { return true ; } } return false ; } protected void pushOperation ( JavaModelOperation operation ) { getCurrentOperationStack ( ) . add ( operation ) ; } protected void removeAllPostAction ( String actionID ) { if ( POST_ACTION_VERBOSE ) { System . out . println ( "(" + Thread . currentThread ( ) + "" + actionID ) ; } JavaModelOperation topLevelOp = ( JavaModelOperation ) getCurrentOperationStack ( ) . get ( 0 ) ; IPostAction [ ] postActions = topLevelOp . actions ; if ( postActions == null ) return ; int index = this . actionsStart - 1 ; while ( ( index = topLevelOp . firstActionWithID ( actionID , index + 1 ) ) >= 0 ) { System . arraycopy ( postActions , index + 1 , postActions , index , topLevelOp . actionsEnd - index ) ; postActions [ topLevelOp . actionsEnd -- ] = null ; } } public void run ( IProgressMonitor monitor ) throws CoreException { JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; DeltaProcessor deltaProcessor = manager . getDeltaProcessor ( ) ; int previousDeltaCount = deltaProcessor . javaModelDeltas . size ( ) ; try { this . progressMonitor = monitor ; pushOperation ( this ) ; try { if ( canModifyRoots ( ) ) { JavaModelManager . getDeltaState ( ) . initializeRoots ( false ) ; } executeOperation ( ) ; } finally { if ( isTopLevelOperation ( ) ) { runPostActions ( ) ; } } } finally { try { deltaProcessor = manager . getDeltaProcessor ( ) ; for ( int i = previousDeltaCount , size = deltaProcessor . javaModelDeltas . size ( ) ; i < size ; i ++ ) { deltaProcessor . updateJavaModel ( ( IJavaElementDelta ) deltaProcessor . javaModelDeltas . get ( i ) ) ; } for ( int i = 0 , length = this . resultElements . length ; i < length ; i ++ ) { IJavaElement element = this . resultElements [ i ] ; Openable openable = ( Openable ) element . getOpenable ( ) ; if ( ! ( openable instanceof CompilationUnit ) || ! ( ( CompilationUnit ) openable ) . isWorkingCopy ( ) ) { ( ( JavaElement ) openable . getParent ( ) ) . close ( ) ; } switch ( element . getElementType ( ) ) { case IJavaElement . PACKAGE_FRAGMENT_ROOT : case IJavaElement . PACKAGE_FRAGMENT : deltaProcessor . projectCachesToReset . add ( element . getJavaProject ( ) ) ; break ; } } deltaProcessor . resetProjectCaches ( ) ; if ( isTopLevelOperation ( ) ) { if ( ( deltaProcessor . javaModelDeltas . size ( ) > previousDeltaCount || ! deltaProcessor . reconcileDeltas . isEmpty ( ) ) && ! hasModifiedResource ( ) ) { deltaProcessor . fire ( null , DeltaProcessor . DEFAULT_CHANGE_EVENT ) ; } } } finally { popOperation ( ) ; } } } public void runOperation ( IProgressMonitor monitor ) throws JavaModelException { IJavaModelStatus status = verify ( ) ; if ( ! status . isOK ( ) ) { throw new JavaModelException ( status ) ; } try { if ( isReadOnly ( ) ) { run ( monitor ) ; } else { ResourcesPlugin . getWorkspace ( ) . run ( this , getSchedulingRule ( ) , IWorkspace . AVOID_UPDATE , monitor ) ; } } catch ( CoreException ce ) { if ( ce instanceof JavaModelException ) { throw ( JavaModelException ) ce ; } else { if ( ce . getStatus ( ) . getCode ( ) == IResourceStatus . OPERATION_FAILED ) { Throwable e = ce . getStatus ( ) . getException ( ) ; if ( e instanceof JavaModelException ) { throw ( JavaModelException ) e ; } } throw new JavaModelException ( ce ) ; } } } protected void runPostActions ( ) throws JavaModelException { while ( this . actionsStart <= this . actionsEnd ) { IPostAction postAction = this . actions [ this . actionsStart ++ ] ; if ( POST_ACTION_VERBOSE ) { System . out . println ( "(" + Thread . currentThread ( ) + "" + postAction . getID ( ) ) ; } postAction . run ( ) ; } } protected static void setAttribute ( Object key , Object attribute ) { ArrayList operationStack = getCurrentOperationStack ( ) ; if ( operationStack . size ( ) == 0 ) return ; JavaModelOperation topLevelOp = ( JavaModelOperation ) operationStack . get ( 0 ) ; if ( topLevelOp . attributes == null ) { topLevelOp . attributes = new HashMap ( ) ; } topLevelOp . attributes . put ( key , attribute ) ; } public void setCanceled ( boolean b ) { if ( this . progressMonitor != null ) { this . progressMonitor . setCanceled ( b ) ; } } protected void setNested ( boolean nested ) { this . isNested = nested ; } public void setTaskName ( String name ) { if ( this . progressMonitor != null ) { this . progressMonitor . setTaskName ( name ) ; } } public void subTask ( String name ) { if ( this . progressMonitor != null ) { this . progressMonitor . subTask ( name ) ; } } protected IJavaModelStatus verify ( ) { return commonVerify ( ) ; } public void worked ( int work ) { if ( this . progressMonitor != null ) { this . progressMonitor . worked ( work ) ; checkCanceled ( ) ; } } } </s>