| /* |
| * 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.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Dictionary; |
| import java.util.List; |
| |
| import org.apache.felix.cm.impl.CaseInsensitiveDictionary; |
| import org.apache.felix.cm.impl.ConfigurationImpl; |
| import org.apache.felix.cm.impl.ConfigurationManager; |
| import org.apache.felix.cm.impl.RankingComparator; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.log.LogService; |
| import org.osgi.util.tracker.ServiceTracker; |
| |
| /** |
| * The <code>BaseTracker</code> is the base class for tracking |
| * <code>ManagedService</code> and <code>ManagedServiceFactory</code> |
| * services. It maps their <code>ServiceRegistration</code> to the |
| * {@link ConfigurationMap} mapping their service PIDs to provided |
| * configuration. |
| */ |
| public abstract class BaseTracker<S> extends ServiceTracker<S, ConfigurationMap> |
| { |
| protected final ConfigurationManager cm; |
| |
| |
| protected BaseTracker( ConfigurationManager cm, Class<S> type ) |
| { |
| super( cm.getBundleContext(), type.getName(), null ); |
| this.cm = cm; |
| open(); |
| } |
| |
| |
| public ConfigurationMap addingService( ServiceReference<S> reference ) |
| { |
| final String[] pids = getServicePid( reference ); |
| configure( reference, pids ); |
| return new ConfigurationMap( pids ); |
| } |
| |
| |
| @Override |
| public void modifiedService( ServiceReference<S> reference, ConfigurationMap service ) |
| { |
| String[] pids = getServicePid( reference ); |
| if ( service.isDifferentPids( pids ) ) |
| { |
| configure( reference, pids ); |
| service.setConfiguredPids( pids ); |
| } |
| } |
| |
| |
| // public void removedService( ServiceReference<ManagedServiceFactory> reference, |
| // ServiceHolder<ManagedServiceFactory> holder ) |
| // { |
| // // nothing really to do |
| // } |
| |
| |
| // cm.configure( pids, reference, msf); |
| protected void configure( ServiceReference<S> reference, String[] pids ) |
| { |
| if ( pids != null ) |
| { |
| S service = getRealService( reference ); |
| if ( service != null ) |
| { |
| try |
| { |
| if ( this.cm.isLogEnabled( LogService.LOG_DEBUG ) ) |
| { |
| this.cm.log( LogService.LOG_DEBUG, "configure(ManagedService {0})", new Object[] |
| { ConfigurationManager.toString( reference ) } ); |
| } |
| |
| for ( int i = 0; i < pids.length; i++ ) |
| { |
| this.cm.configure( pids[i], reference, service, isFactory() ); |
| } |
| } |
| finally |
| { |
| ungetRealService( reference ); |
| } |
| } |
| } |
| } |
| |
| |
| public final List<ServiceReference<S>> getServices( final TargetedPID pid ) |
| { |
| ServiceReference<S>[] refs = this.getServiceReferences(); |
| if ( refs != null ) |
| { |
| ArrayList<ServiceReference<S>> result = new ArrayList<ServiceReference<S>>( refs.length ); |
| for ( ServiceReference<S> ref : refs ) |
| { |
| if ( pid.matchesTarget( ref ) ) |
| { |
| ConfigurationMap map = this.getService( ref ); |
| if ( map != null && map.accepts( pid.getServicePid() ) ) |
| { |
| result.add( ref ); |
| } |
| } |
| } |
| |
| if ( result.size() > 1 ) |
| { |
| Collections.sort( result, RankingComparator.SRV_RANKING ); |
| } |
| |
| return result; |
| } |
| |
| return Collections.emptyList(); |
| } |
| |
| |
| protected abstract boolean isFactory(); |
| |
| // Updates |
| public abstract void provideConfiguration( ServiceReference<S> service, ConfigurationImpl config, Dictionary<String, ?> properties ); |
| |
| |
| public abstract void removeConfiguration( ServiceReference<S> service, ConfigurationImpl config ); |
| |
| |
| protected final S getRealService( ServiceReference<S> reference ) |
| { |
| return this.context.getService( reference ); |
| } |
| |
| |
| protected final void ungetRealService( ServiceReference<S> reference ) |
| { |
| this.context.ungetService( reference ); |
| } |
| |
| protected final Dictionary getProperties( Dictionary<String, ?> rawProperties, String targetPid, ServiceReference service ) |
| { |
| Dictionary props = new CaseInsensitiveDictionary( rawProperties ); |
| this.cm.callPlugins( props, targetPid, service, null /* config */ ); |
| return props; |
| } |
| |
| /** |
| * Returns the <code>service.pid</code> property of the service reference as |
| * an array of strings or <code>null</code> if the service reference does |
| * not have a service PID property. |
| * <p> |
| * The service.pid property may be a single string, in which case a single |
| * element array is returned. If the property is an array of string, this |
| * array is returned. If the property is a collection it is assumed to be a |
| * collection of strings and the collection is converted to an array to be |
| * returned. Otherwise (also if the property is not set) <code>null</code> |
| * is returned. |
| * |
| * @throws NullPointerException |
| * if reference is <code>null</code> |
| * @throws ArrayStoreException |
| * if the service pid is a collection and not all elements are |
| * strings. |
| */ |
| private static String[] getServicePid( ServiceReference reference ) |
| { |
| Object pidObj = reference.getProperty( Constants.SERVICE_PID ); |
| if ( pidObj instanceof String ) |
| { |
| return new String[] |
| { ( String ) pidObj }; |
| } |
| else if ( pidObj instanceof String[] ) |
| { |
| return ( String[] ) pidObj; |
| } |
| else if ( pidObj instanceof Collection ) |
| { |
| Collection pidCollection = ( Collection ) pidObj; |
| return ( String[] ) pidCollection.toArray( new String[pidCollection.size()] ); |
| } |
| |
| return null; |
| } |
| |
| } |