FELIX-4785 : Incompatible SCR API
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1660095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
new file mode 100644
index 0000000..fe1416c
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
@@ -0,0 +1,107 @@
+/*
+ * 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.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.ScrInfo;
+import org.apache.felix.scr.ScrService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+
+public class Activator
+{
+ // tracker of the runtime service
+ private volatile ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime> runtimeTracker;
+
+ // the service registrations
+ private final Map<Long, ServiceRegistration<ScrService>> scrServiceRegMap = new ConcurrentHashMap<Long, ServiceRegistration<ScrService>>();
+
+ // the service registrations
+ private final Map<Long, ServiceRegistration<ScrInfo>> scrCommandRegMap = new ConcurrentHashMap<Long, ServiceRegistration<ScrInfo>>();
+
+ public void start( final BundleContext context ) throws Exception
+ {
+ this.runtimeTracker = new ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime>(context, ServiceComponentRuntime.class,
+ new ServiceTrackerCustomizer<ServiceComponentRuntime, ServiceComponentRuntime>()
+ {
+
+ public ServiceComponentRuntime addingService(
+ final ServiceReference<ServiceComponentRuntime> reference)
+ {
+ final ServiceComponentRuntime runtime = context.getService(reference);
+ if ( runtime != null )
+ {
+ Hashtable props = new Hashtable();
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat ScrService");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+
+ final ScrService service = new ScrServiceImpl(context, runtime);
+ scrServiceRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
+ context.registerService(ScrService.class, service, props));
+
+ props = new Hashtable();
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat SCR Info service");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ final ScrInfo info = new ScrCommand(context, service);
+ scrCommandRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
+ context.registerService(ScrInfo.class, info, props));
+ }
+ return runtime;
+ }
+
+ public void modifiedService(
+ final ServiceReference<ServiceComponentRuntime> reference,
+ final ServiceComponentRuntime service) {
+ // nothing to do
+ }
+
+ public void removedService(
+ final ServiceReference<ServiceComponentRuntime> reference,
+ final ServiceComponentRuntime service) {
+ final ServiceRegistration<ScrService> reg = scrServiceRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
+ if ( reg != null )
+ {
+ reg.unregister();
+ }
+ final ServiceRegistration<ScrInfo> reg2 = scrCommandRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
+ if ( reg2 != null )
+ {
+ reg2.unregister();
+ }
+ context.ungetService(reference);
+ }
+ });
+ this.runtimeTracker.open();
+ }
+
+ public void stop(final BundleContext context) throws Exception
+ {
+ this.runtimeTracker.close();
+ }
+}
\ No newline at end of file
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
new file mode 100644
index 0000000..785c344
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
@@ -0,0 +1,477 @@
+/*
+ * 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.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.Reference;
+import org.apache.felix.scr.ScrInfo;
+import org.apache.felix.scr.ScrService;
+import org.apache.felix.scr.impl.config.ScrConfiguration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ScrCommand</code> class provides the implementations for the
+ * Apache Felix Gogo and legacy Apache Felix Shell commands. The
+ * {@link #register(BundleContext, ScrService, ScrConfiguration)} method
+ * instantiates and registers the Gogo and Shell commands as possible.
+ */
+public class ScrCommand implements ScrInfo
+{
+
+ private final BundleContext bundleContext;
+ private final ScrService scrService;
+
+ public ScrCommand(final BundleContext bundleContext, final ScrService scrService)
+ {
+ this.scrService = scrService;
+ this.bundleContext = bundleContext;
+
+ }
+
+ static boolean isBundleActive( final Bundle bundle )
+ {
+ if ( bundle != null )
+ {
+ if ( bundle.getState() == Bundle.ACTIVE )
+ {
+ return true;
+ }
+
+ if ( bundle.getState() == Bundle.STARTING )
+ {
+ // according to the spec the activationPolicy header is only
+ // set to request a bundle to be lazily activated. So in this
+ // simple check we just verify the header is set to assume
+ // the bundle is considered a lazily activated bundle
+ return bundle.getHeaders().get( Constants.BUNDLE_ACTIVATIONPOLICY ) != null;
+ }
+ }
+
+ // fall back: bundle is not considered active
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.scr.impl.ScrInfo#list(java.lang.String, java.io.PrintStream, java.io.PrintStream)
+ */
+ public void list(final String bundleIdentifier, final PrintWriter out)
+ {
+ Component[] components;
+
+ if (bundleIdentifier != null)
+ {
+ Bundle bundle = null;
+ try
+ {
+ long bundleId = Long.parseLong(bundleIdentifier);
+ bundle = bundleContext.getBundle(bundleId);
+ }
+ catch (NumberFormatException nfe)
+ {
+ // might be a bundle symbolic name
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; i < bundles.length; i++)
+ {
+ if (bundleIdentifier.equals(bundles[i].getSymbolicName()))
+ {
+ bundle = bundles[i];
+ break;
+ }
+ }
+ }
+
+ if (bundle == null)
+ {
+ throw new IllegalArgumentException("Missing bundle with ID " + bundleIdentifier);
+ }
+ if (isBundleActive(bundle))
+ {
+ components = scrService.getComponents(bundle);
+ if (components == null)
+ {
+ out.println("Bundle " + bundleIdentifier + " declares no components");
+ return;
+ }
+ }
+ else
+ {
+ out.println("Bundle " + bundleIdentifier + " is not active");
+ return;
+ }
+ }
+ else
+ {
+ components = scrService.getComponents();
+ if (components == null)
+ {
+ out.println("No components registered");
+ return;
+ }
+ }
+
+ Arrays.sort( components, new Comparator<Component>()
+ {
+
+ public int compare(Component c1, Component c2)
+ {
+ return Long.signum(c1.getId() - c2.getId());
+ }
+
+ });
+
+ out.println(" Id State BundleId Name");
+ for ( Component component : components )
+ {
+ out.println( String.format( "[%1$4d] [%2$s] [%3$4d] %4$s", component.getId(), toStateString( component.getState() ), component.getBundle().getBundleId(), component.getName() ) );
+ }
+ out.flush();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.scr.impl.ScrInfo#info(java.lang.String, java.io.PrintStream, java.io.PrintStream)
+ */
+ public void info(final String componentId, PrintWriter out)
+ {
+ Component[] components = getComponentFromArg(componentId);
+ if (components == null)
+ {
+ return;
+ }
+
+ Arrays.sort( components, new Comparator<Component>()
+ {
+
+ public int compare(Component c1, Component c2)
+ {
+ long bundleId1 = c1.getBundle().getBundleId();
+ long bundleId2 = c2.getBundle().getBundleId();
+ int result = Long.signum(bundleId1 - bundleId2);
+ if (result == 0) {
+ result = Long.signum(c1.getId() - c2.getId());
+ }
+ return result;
+ }
+
+ });
+
+ long bundleId = -1;
+
+ for ( Component component : components )
+ {
+ if (components.length > 1)
+ {
+ if ( component.getBundle().getBundleId() != bundleId )
+ {
+ if ( bundleId != -1 )
+ {
+ out.println();
+ out.println();
+ }
+ bundleId = component.getBundle().getBundleId();
+ out.println(String.format("*** Bundle: %1$s (%2$d)", component.getBundle().getSymbolicName(), bundleId));
+ }
+ out.println();
+ }
+ out.print( "ID: " );
+ out.println( component.getId() );
+ out.print( "Name: " );
+ out.println( component.getName() );
+ out.print( "Bundle: " );
+ out.println( component.getBundle().getSymbolicName() + " (" + component.getBundle().getBundleId() + ")" );
+ out.print( "State: " );
+ out.println( toStateString( component.getState() ) );
+ out.print( "Default State: " );
+ out.println( component.isDefaultEnabled() ? "enabled" : "disabled" );
+ out.print( "Activation: " );
+ out.println( component.isImmediate() ? "immediate" : "delayed" );
+
+ // DS 1.1 new features
+ out.print( "Configuration Policy: " );
+ out.println( component.getConfigurationPolicy() );
+ out.print( "Activate Method: " );
+ out.print( component.getActivate() );
+ if ( component.isActivateDeclared() )
+ {
+ out.print( " (declared in the descriptor)" );
+ }
+ out.println();
+ out.print( "Deactivate Method: " );
+ out.print( component.getDeactivate() );
+ if ( component.isDeactivateDeclared() )
+ {
+ out.print( " (declared in the descriptor)" );
+ }
+ out.println();
+ out.print( "Modified Method: " );
+ if ( component.getModified() != null )
+ {
+ out.print( component.getModified() );
+ }
+ else
+ {
+ out.print( "-" );
+ }
+ out.println();
+
+ out.print( "Configuration Pid: " );
+ out.print( component.getConfigurationPid() );
+ if ( component.isConfigurationPidDeclared() )
+ {
+ out.print( " (declared in the descriptor)" );
+ }
+ out.println();
+
+ if ( component.getFactory() != null )
+ {
+ out.print( "Factory: " );
+ out.println( component.getFactory() );
+ }
+
+ String[] services = component.getServices();
+ if ( services != null )
+ {
+ out.print( "Services: " );
+ out.println( services[0] );
+ for ( int i = 1; i < services.length; i++ )
+ {
+ out.print( " " );
+ out.println( services[i] );
+ }
+ out.print( "Service Type: " );
+ out.println( component.isServiceFactory() ? "service factory" : "service" );
+ }
+
+ Reference[] refs = component.getReferences();
+ if ( refs != null )
+ {
+ for ( Reference ref : refs )
+ {
+ out.print( "Reference: " );
+ out.println( ref.getName() );
+ out.print( " Satisfied: " );
+ out.println( ref.isSatisfied() ? "satisfied" : "unsatisfied" );
+ out.print( " Service Name: " );
+ out.println( ref.getServiceName() );
+ if ( ref.getTarget() != null )
+ {
+ out.print( " Target Filter: " );
+ out.println( ref.getTarget() );
+ }
+ out.print( " Multiple: " );
+ out.println( ref.isMultiple() ? "multiple" : "single" );
+ out.print( " Optional: " );
+ out.println( ref.isOptional() ? "optional" : "mandatory" );
+ out.print( " Policy: " );
+ out.println( ref.isStatic() ? "static" : "dynamic" );
+ out.print( " Policy option: " );
+ out.println( ref.isReluctant() ? "reluctant" : "greedy" );
+ ServiceReference[] serviceRefs = ref.getServiceReferences();
+ if ( serviceRefs != null )
+ {
+ out.print( " Bound to:" );
+ for ( int k = 0; k < serviceRefs.length; k++ )
+ {
+ out.print( " " );
+ out.println( serviceRefs[k] );
+ }
+ }
+ else
+ {
+ out.println( " (unbound)" );
+ }
+ }
+ }
+
+ Dictionary props = component.getProperties();
+ if ( props != null )
+ {
+ out.println( "Properties:" );
+ TreeSet keys = new TreeSet( Collections.list( props.keys() ) );
+ for ( Object key : keys )
+ {
+ out.print( " " );
+ out.print( key );
+ out.print( " = " );
+
+ Object prop = props.get( key );
+ if ( prop.getClass().isArray() )
+ {
+ prop = Arrays.asList( ( Object[] ) prop );
+ }
+ out.print( prop );
+
+ out.println();
+ }
+ }
+ }
+ out.flush();
+ }
+
+ void change(final String componentIdentifier, PrintWriter out, boolean enable)
+ {
+ Component[] components = getComponentFromArg(componentIdentifier);
+ ArrayList<String> disposed = new ArrayList<String>();
+ if (components == null)
+ {
+ return;
+ }
+
+ for ( Component component : components )
+ {
+ if ( component.getState() == Component.STATE_DISPOSED )
+ {
+ disposed.add(component.getName());
+ }
+ else if ( enable )
+ {
+ if ( component.getState() == Component.STATE_DISABLED )
+ {
+ component.enable();
+ out.println( "Component " + component.getName() + " enabled" );
+ }
+ else
+ {
+ out.println( "Component " + component.getName() + " already enabled" );
+ }
+ }
+ else
+ {
+ if ( component.getState() != Component.STATE_DISABLED )
+ {
+ component.disable();
+ out.println( "Component " + component.getName() + " disabled" );
+ }
+ else
+ {
+ out.println( "Component " + component.getName() + " already disabled" );
+ }
+ }
+ }
+ out.flush();
+ if ( !disposed.isEmpty() )
+ {
+ throw new IllegalArgumentException( "Components " + disposed + " already disposed, cannot change state" );
+
+ }
+ }
+
+ private String toStateString(int state)
+ {
+ switch (state) {
+
+ case (Component.STATE_DISABLED):
+ return "disabled ";
+ case (Component.STATE_ENABLING):
+ return "enabling ";
+ case (Component.STATE_ENABLED):
+ return "enabled ";
+ case (Component.STATE_UNSATISFIED):
+ return "unsatisfied ";
+ case (Component.STATE_ACTIVATING):
+ return "activating ";
+ case (Component.STATE_ACTIVE):
+ return "active ";
+ case (Component.STATE_REGISTERED):
+ return "registered ";
+ case (Component.STATE_FACTORY):
+ return "factory ";
+ case (Component.STATE_DEACTIVATING):
+ return "deactivating";
+ case (Component.STATE_DISABLING):
+ return "disabling ";
+ case (Component.STATE_DISPOSING):
+ return "disposing ";
+ case (Component.STATE_DISPOSED):
+ return "disposed ";
+ default:
+ return "unkown: " + state;
+ }
+ }
+
+ private Component[] getComponentFromArg(final String componentIdentifier)
+ {
+ Component[] components = null;
+ if (componentIdentifier != null)
+ {
+ try
+ {
+ long componentId = Long.parseLong(componentIdentifier);
+ Component component = scrService.getComponent(componentId);
+ if (component == null)
+ {
+ throw new IllegalArgumentException("Missing Component with ID " + componentId);
+ }
+ else
+ {
+ return new Component[]
+ { component };
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+
+ // check whether it is a component name
+ components = scrService.getComponents(componentIdentifier);
+ }
+ }
+ if ( components == null)
+ {
+ components = scrService.getComponents();
+ if (componentIdentifier != null)
+ {
+ ArrayList<Component> cs = new ArrayList<Component>(components.length);
+ Pattern p = Pattern.compile(componentIdentifier);
+ for (Component component: components)
+ {
+ if ( p.matcher( component.getName()).matches() )
+ {
+ cs.add( component );
+ }
+ }
+ if (cs.isEmpty())
+ {
+ throw new IllegalArgumentException("No Component with ID or matching " + componentIdentifier);
+ }
+ components = cs.toArray( new Component[cs.size()] );
+ }
+ }
+
+ return components;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.felix.scr.impl.ScrInfo#config(java.io.PrintStream)
+ */
+ public void config(PrintWriter out)
+ {
+ out.println("Configuration not available.");
+ }
+}
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java
new file mode 100644
index 0000000..2ad5d64
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java
@@ -0,0 +1,437 @@
+/*
+ * 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 false; // TODO
+ }
+
+ 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()
+ {
+ // TODO - how do we want to enable this?
+ 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()
+ {
+ this.runtime.enableComponent(this.description);
+ }
+
+ public void disable()
+ {
+ this.runtime.disableComponent(this.description);
+ }
+ }
+
+ 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;
+ }
+ }
+}