| /* |
| * 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.scr.impl.compat; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import java.util.List; |
| |
| import org.apache.felix.scr.Component; |
| import org.apache.felix.scr.Reference; |
| import org.apache.felix.scr.ScrService; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.dto.ServiceReferenceDTO; |
| import org.osgi.service.component.ComponentInstance; |
| import org.osgi.service.component.runtime.ServiceComponentRuntime; |
| import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO; |
| import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO; |
| import org.osgi.service.component.runtime.dto.ReferenceDTO; |
| import org.osgi.service.component.runtime.dto.SatisfiedReferenceDTO; |
| |
| public class ScrServiceImpl implements ScrService |
| { |
| |
| private static final String[] EMPTY = {}; |
| |
| private final BundleContext context; |
| private final ServiceComponentRuntime runtime; |
| |
| |
| public ScrServiceImpl(BundleContext context, final ServiceComponentRuntime runtime) |
| { |
| // we always use the system bundle to avoid problems if subsystems etc. |
| // are used and the SCR implemented extends those "invisible" bundles |
| this.context = context.getBundle(0).getBundleContext(); |
| this.runtime = runtime; |
| } |
| |
| |
| // ScrService |
| |
| /** |
| * @see org.apache.felix.scr.ScrService#getComponents() |
| */ |
| public Component[] getComponents() |
| { |
| return this.getComponents((Bundle)null); |
| } |
| |
| |
| /** |
| * @see org.apache.felix.scr.ScrService#getComponents(org.osgi.framework.Bundle) |
| */ |
| public Component[] getComponents( final Bundle bundle ) |
| { |
| List<Component> result = new ArrayList<Component>(); |
| |
| final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs(bundle); |
| for(final ComponentDescriptionDTO descDTO : descriptions ) |
| { |
| final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO); |
| ComponentConfigurationDTO configDTO = null; |
| if ( !configs.isEmpty() ) |
| { |
| configDTO = configs.iterator().next(); |
| } |
| result.add(new ComponentWrapper(this.context, this.runtime, descDTO, configDTO)); |
| } |
| |
| return result.isEmpty() ? null : result.toArray( new Component[result.size()] ); |
| } |
| |
| |
| /** |
| * @see org.apache.felix.scr.ScrService#getComponent(long) |
| */ |
| public Component getComponent( long componentId ) |
| { |
| final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs(); |
| for(final ComponentDescriptionDTO descDTO : descriptions ) |
| { |
| final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO); |
| for(final ComponentConfigurationDTO configDTO : configs) |
| { |
| if ( configDTO.id == componentId ) |
| { |
| return new ComponentWrapper(this.context, this.runtime, descDTO, configDTO); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @see org.apache.felix.scr.ScrService#getComponents(java.lang.String) |
| */ |
| public Component[] getComponents( final String componentName ) |
| { |
| List<Component> result = new ArrayList<Component>(); |
| |
| final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs(); |
| for(final ComponentDescriptionDTO descDTO : descriptions ) |
| { |
| if ( descDTO.name.equals(componentName) ) { |
| final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO); |
| ComponentConfigurationDTO configDTO = null; |
| if ( !configs.isEmpty() ) |
| { |
| configDTO = configs.iterator().next(); |
| } |
| result.add(new ComponentWrapper(this.context, this.runtime, descDTO, configDTO)); |
| } |
| } |
| |
| return result.isEmpty() ? null : result.toArray( new Component[result.size()] ); |
| } |
| |
| |
| private static final class ComponentWrapper implements Component |
| { |
| private final ComponentDescriptionDTO description; |
| |
| private final ComponentConfigurationDTO configuration; |
| |
| private final BundleContext bundleContext; |
| |
| private final ServiceComponentRuntime runtime; |
| |
| public ComponentWrapper(final BundleContext bundleContext, |
| final ServiceComponentRuntime runtime, |
| final ComponentDescriptionDTO description, |
| final ComponentConfigurationDTO configuration) |
| { |
| this.bundleContext = bundleContext; |
| this.description = description; |
| this.configuration = configuration; |
| this.runtime = runtime; |
| } |
| |
| public long getId() |
| { |
| return configuration != null ? configuration.id : -1; |
| } |
| |
| public String getName() |
| { |
| return description.name; |
| } |
| |
| public int getState() |
| { |
| if ( configuration == null ) |
| { |
| return Component.STATE_UNSATISFIED; // TODO Check! |
| } |
| final int s = configuration.state; |
| switch ( s ) |
| { |
| case ComponentConfigurationDTO.ACTIVE : return Component.STATE_ACTIVE; |
| case ComponentConfigurationDTO.SATISFIED : return Component.STATE_ENABLED; |
| case ComponentConfigurationDTO.UNSATISFIED_CONFIGURATION : return Component.STATE_UNSATISFIED; |
| case ComponentConfigurationDTO.UNSATISFIED_REFERENCE : return Component.STATE_UNSATISFIED; |
| default: // satisfied |
| return Component.STATE_ENABLED; |
| } |
| } |
| |
| public Bundle getBundle() |
| { |
| return this.bundleContext.getBundle(this.description.bundle.id); |
| } |
| |
| public String getFactory() |
| { |
| return this.description.factory; |
| } |
| |
| public boolean isServiceFactory() |
| { |
| return !"singleton".equals(this.description.scope); |
| } |
| |
| public String getClassName() |
| { |
| return this.description.implementationClass; |
| } |
| |
| public boolean isDefaultEnabled() |
| { |
| return this.description.defaultEnabled; |
| } |
| |
| public boolean isImmediate() |
| { |
| return this.description.immediate; |
| } |
| |
| public String[] getServices() |
| { |
| return this.description.serviceInterfaces; |
| } |
| |
| public Dictionary getProperties() |
| { |
| return new Hashtable<String, Object>(this.description.properties); |
| } |
| |
| public Reference[] getReferences() |
| { |
| if ( this.configuration == null ) |
| { |
| return null; |
| } |
| |
| final List<Reference> result = new ArrayList<Reference>(); |
| for(final ReferenceDTO dto : this.description.references) |
| { |
| SatisfiedReferenceDTO sRef = null; |
| for(final SatisfiedReferenceDTO r : this.configuration.satisfiedReferences) |
| { |
| if ( r.name.equals(dto.name) ) |
| { |
| sRef = r; |
| break; |
| } |
| } |
| result.add(new ReferenceWrapper(this.bundleContext, dto, sRef)); |
| } |
| |
| if ( result.isEmpty() ) |
| { |
| return null; |
| } |
| |
| return result.toArray(new Reference[result.size()]); |
| } |
| |
| public ComponentInstance getComponentInstance() |
| { |
| // returning null as we should have never returned this in the first place |
| return null; |
| } |
| |
| public String getActivate() |
| { |
| return this.description.activate; |
| } |
| |
| public boolean isActivateDeclared() |
| { |
| return this.description.activate != null; |
| } |
| |
| public String getDeactivate() |
| { |
| return this.description.deactivate; |
| } |
| |
| public boolean isDeactivateDeclared() |
| { |
| return this.description.deactivate != null; |
| } |
| |
| public String getModified() |
| { |
| return this.description.modified; |
| } |
| |
| public String getConfigurationPolicy() |
| { |
| return this.description.configurationPolicy; |
| } |
| |
| public String getConfigurationPid() |
| { |
| final String[] pids = this.description.configurationPid; |
| return pids[0]; |
| } |
| |
| public boolean isConfigurationPidDeclared() |
| { |
| return true; |
| } |
| |
| public void enable() |
| { |
| // noop as the old model was broken |
| } |
| |
| public void disable() |
| { |
| // noop as the old model was broken |
| } |
| } |
| |
| private static final class ReferenceWrapper implements Reference |
| { |
| // constant for option single reference - 0..1 |
| private static final String CARDINALITY_0_1 = "0..1"; |
| |
| // constant for option multiple reference - 0..n |
| private static final String CARDINALITY_0_N = "0..n"; |
| |
| // constant for required multiple reference - 1..n |
| private static final String CARDINALITY_1_N = "1..n"; |
| |
| // constant for static policy |
| private static final String POLICY_STATIC = "static"; |
| |
| // constant for reluctant policy option |
| private static final String POLICY_OPTION_RELUCTANT = "reluctant"; |
| |
| private final ReferenceDTO dto; |
| |
| private final SatisfiedReferenceDTO satisfiedDTO; |
| |
| private final BundleContext bundleContext; |
| |
| public ReferenceWrapper( |
| final BundleContext bundleContext, |
| final ReferenceDTO dto, |
| final SatisfiedReferenceDTO satisfied) |
| { |
| this.bundleContext = bundleContext; |
| this.dto = dto; |
| this.satisfiedDTO = satisfied; |
| } |
| |
| public String getName() |
| { |
| return dto.name; |
| } |
| |
| public String getServiceName() |
| { |
| return dto.interfaceName; |
| } |
| |
| public ServiceReference[] getServiceReferences() |
| { |
| if ( this.satisfiedDTO == null ) |
| { |
| return null; |
| } |
| final List<ServiceReference<?>> refs = new ArrayList<ServiceReference<?>>(); |
| for(ServiceReferenceDTO dto : this.satisfiedDTO.boundServices) |
| { |
| try |
| { |
| final ServiceReference<?>[] serviceRefs = this.bundleContext.getServiceReferences((String)null, |
| "(" + Constants.SERVICE_ID + "=" + String.valueOf(dto.id) + ")"); |
| if ( serviceRefs != null && serviceRefs.length > 0 ) |
| { |
| refs.add(serviceRefs[0]); |
| } |
| } |
| catch ( final InvalidSyntaxException ise) |
| { |
| // ignore |
| } |
| } |
| return refs.toArray(new ServiceReference<?>[refs.size()]); |
| } |
| |
| public ServiceReference<?>[] getBoundServiceReferences() |
| { |
| return this.getServiceReferences(); |
| } |
| |
| public boolean isSatisfied() |
| { |
| return this.satisfiedDTO != null; |
| } |
| |
| public boolean isOptional() |
| { |
| return CARDINALITY_0_1.equals(dto.cardinality) || CARDINALITY_0_N.equals(dto.cardinality); |
| } |
| |
| public boolean isMultiple() |
| { |
| return CARDINALITY_1_N.equals(dto.cardinality) || CARDINALITY_0_N.equals(dto.cardinality); |
| } |
| |
| public boolean isStatic() |
| { |
| return POLICY_STATIC.equals(dto.policy); |
| } |
| |
| public boolean isReluctant() |
| { |
| return POLICY_OPTION_RELUCTANT.equals(dto.policyOption); |
| } |
| |
| public String getTarget() |
| { |
| return this.dto.target; |
| } |
| |
| public String getBindMethodName() |
| { |
| return this.dto.bind; |
| } |
| |
| public String getUnbindMethodName() |
| { |
| return this.dto.unbind; |
| } |
| |
| public String getUpdatedMethodName() |
| { |
| return this.dto.unbind; |
| } |
| } |
| } |