private boolean updateConfiguration ( EvaluationResult result , ConfigurationInfo info , Collection < ConfigurationInfo > infos , boolean encourageUpdates ) throws ConfigUpdateException { //encourageUpdates is overruled by metatype declining nested notifications. encourageUpdates &= ! ! ! ( result . getRegistryEntry ( ) != null && result . getRegistryEntry ( ) . supportsHiddenExtensions ( ) ) ; // nestedUpdates is true if there are any updates to child elements that are not hidden boolean nestedUpdates = false ; // propertiesUpdated is true if the properties of this configuration are updated boolean propertiesUpdated = false ; // process nested configuration first Map < ConfigID , EvaluationResult > nested = result . getNested ( ) ; for ( Map . Entry < ConfigID , EvaluationResult > entry : nested . entrySet ( ) ) { EvaluationResult nestedResult = entry . getValue ( ) ; ExtendedConfiguration nestedConfig = caSupport . findConfiguration ( nestedResult . getPid ( ) ) ; if ( nestedConfig == null ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Configuration not found: " + nestedResult . getPid ( ) ) ; } } else { ConfigurationInfo nestedInfo = new ConfigurationInfo ( nestedResult . getConfigElement ( ) , nestedConfig , nestedResult . getRegistryEntry ( ) , false ) ; // updated will be true if there was a nested properties update boolean updated = updateConfiguration ( nestedResult , nestedInfo , infos , encourageUpdates ) ; // If the nested update should be hidden, set updated to false so that it won't appear as a child properties update if ( updated && ( result . getRegistryEntry ( ) != null && result . getRegistryEntry ( ) . supportsHiddenExtensions ( ) ) ) { updated = false ; } // If updated is true, set nestedUpdates to true to signify that there are unhidden nested updates nestedUpdates |= updated ; } } ExtendedConfiguration config = info . config ; // update configuration on disk config . setInOverridesFile ( true ) ; Set < ConfigID > oldReferences = config . getReferences ( ) ; Set < ConfigID > newReferences = result . getReferences ( ) ; Dictionary < String , Object > oldProperties = config . getReadOnlyProperties ( ) ; Dictionary < String , Object > newProperties = result . getProperties ( ) ; // Update the cache if either the properties have changed or if there was a nested, non-hidden update. // We force the update when there are nested updates because DS will not process an event unless the // change count is updated. This keeps DS behavior in sync with MS/MSF behavior with nested updates. if ( encourageUpdates || nestedUpdates || ! equalConfigProperties ( oldProperties , newProperties , encourageUpdates ) || ! equalConfigReferences ( oldReferences , newReferences ) ) { propertiesUpdated = true ; crossReference ( oldProperties , newProperties ) ; variableRegistry . updateVariableCache ( result . getVariables ( ) ) ; Dictionary < String , Object > newProp = massageNewConfig ( oldProperties , newProperties ) ; Set < String > newUniques = updateUniqueVariables ( info , oldProperties , newProp ) ; try { config . updateCache ( newProp , newReferences , newUniques ) ; } catch ( IOException ex ) { throw new ConfigUpdateException ( ex ) ; } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Updated configuration: " + toTraceString ( config , result . getConfigElement ( ) ) ) ; } // (1) If there are unhidden nested updates of any kind, add the config info // (2) If this element has its properties updated, add the config info // if ( infos != null ) { infos . add ( info ) ; } } // Create supertype config if necessary extendedMetatypeManager . createSuperTypes ( info ) ; // Return a boolean to indicate whether we updated anything here return ( propertiesUpdated || nestedUpdates ) ; }
Recursively updates the configuration in config admin