/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.cm.impl.helper; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Dictionary; import org.apache.felix.cm.impl.ConfigurationManager; import org.osgi.framework.ServiceReference; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; public class ManagedServiceFactoryTracker extends BaseTracker<ManagedServiceFactory> { public ManagedServiceFactoryTracker( ConfigurationManager cm ) { super( cm, true ); } @Override protected ConfigurationMap<?> createConfigurationMap( String[] pids ) { return new ManagedServiceFactoryConfigurationMap( pids ); } /** * Always returns the raw PID because for a ManagedServiceFactory * the configuration's PID is automatically generated and is not a * real targeted PID. */ @Override public String getServicePid( ServiceReference<ManagedServiceFactory> service, TargetedPID pid ) { return pid.getRawPid(); } @Override public void provideConfiguration( ServiceReference<ManagedServiceFactory> reference, TargetedPID configPid, TargetedPID factoryPid, Dictionary<String, ?> properties, long revision, ConfigurationMap<?> configs ) { // Get the ManagedServiceFactory and terminate here if already // unregistered from the framework concurrently ManagedServiceFactory service = getRealService( reference ); if (service == null) { return; } // Get the Configuration-to-PID map from the parameter or from // the service tracker. If not available, the service tracker // already unregistered this service concurrently if ( configs == null ) { configs = this.getService( reference ); if ( configs == null ) { return; } } // Both the ManagedService to update and the Configuration-to-PID // are available, so the service can be updated with the // configuration (which may be null) if ( configs.shallTake( configPid, factoryPid, revision ) ) { try { Dictionary props = getProperties( properties, reference, configPid.toString(), factoryPid.toString() ); updated( reference, service, configPid.toString(), props ); configs.record( configPid, factoryPid, revision ); } catch ( Throwable t ) { this.handleCallBackError( t, reference, configPid ); } finally { this.ungetRealService( reference ); } } } @Override public void removeConfiguration( ServiceReference<ManagedServiceFactory> reference, TargetedPID configPid, TargetedPID factoryPid ) { final ManagedServiceFactory service = this.getRealService( reference ); final ConfigurationMap configs = this.getService( reference ); if ( service != null && configs != null) { if ( configs.removeConfiguration( configPid, factoryPid ) ) { try { deleted( reference, service, configPid.toString() ); configs.record( configPid, factoryPid, -1 ); } catch ( Throwable t ) { this.handleCallBackError( t, reference, configPid ); } finally { this.ungetRealService( reference ); } } } } private void updated( final ServiceReference<ManagedServiceFactory> reference, final ManagedServiceFactory service, final String pid, final Dictionary properties ) throws ConfigurationException { if ( System.getSecurityManager() != null ) { try { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws ConfigurationException { service.updated( pid, properties ); return null; } }, getAccessControlContext( reference.getBundle() ) ); } catch ( PrivilegedActionException e ) { throw ( ConfigurationException ) e.getException(); } } else { service.updated( pid, properties ); } } private void deleted( final ServiceReference<ManagedServiceFactory> reference, final ManagedServiceFactory service, final String pid ) { if ( System.getSecurityManager() != null ) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { service.deleted( pid ); return null; } }, getAccessControlContext( reference.getBundle() ) ); } else { service.deleted( pid ); } } }