private void complete ( final InstallationManager . InstallationModification modification , final FinalizeCallback callback ) { final List < File > processed = new ArrayList < File > ( ) ; List < File > reenabled = Collections . emptyList ( ) ; List < File > disabled = Collections . emptyList ( ) ; try { try { // Update the state to invalidate and process module resources if ( stateUpdater . compareAndSet ( this , State . PREPARED , State . INVALIDATE ) ) { if ( mode == PatchingTaskContext . Mode . APPLY ) { // Only invalidate modules when applying patches; on rollback files are immediately restored for ( final File invalidation : moduleInvalidations ) { processed . add ( invalidation ) ; PatchModuleInvalidationUtils . processFile ( this , invalidation , mode ) ; } if ( ! modulesToReenable . isEmpty ( ) ) { reenabled = new ArrayList < File > ( modulesToReenable . size ( ) ) ; for ( final File path : modulesToReenable ) { reenabled . add ( path ) ; PatchModuleInvalidationUtils . processFile ( this , path , PatchingTaskContext . Mode . ROLLBACK ) ; } } } else if ( mode == PatchingTaskContext . Mode . ROLLBACK ) { if ( ! modulesToDisable . isEmpty ( ) ) { disabled = new ArrayList < File > ( modulesToDisable . size ( ) ) ; for ( final File path : modulesToDisable ) { disabled . add ( path ) ; PatchModuleInvalidationUtils . processFile ( this , path , PatchingTaskContext . Mode . APPLY ) ; } } } } modification . complete ( ) ; callback . completed ( this ) ; state = State . COMPLETED ; } catch ( Exception e ) { this . moduleInvalidations . clear ( ) ; this . moduleInvalidations . addAll ( processed ) ; this . modulesToReenable . clear ( ) ; this . modulesToReenable . addAll ( reenabled ) ; this . modulesToDisable . clear ( ) ; this . moduleInvalidations . addAll ( disabled ) ; throw new RuntimeException ( e ) ; } } finally { if ( state != State . COMPLETED ) { try { modification . cancel ( ) ; } finally { try { undoChanges ( ) ; } finally { callback . operationCancelled ( this ) ; } } } else { try { if ( checkForGarbageOnRestart ) { final File cleanupMarker = new File ( installedImage . getInstallationMetadata ( ) , "cleanup-patching-dirs" ) ; cleanupMarker . createNewFile ( ) ; } storeFailedRenaming ( ) ; } catch ( IOException e ) { PatchLogger . ROOT_LOGGER . debugf ( e , "failed to create cleanup marker" ) ; } } } }
Complete the current operation and persist the current state to the disk . This will also trigger the invalidation of outdated modules .