protected void copyDependencies(List<DependencyContext> dependencies, Component component) { dependencies.stream().map(dc -> dc.createCopy()).forEach(component::add); }
private void invokeAutoConfigDependencies() { for (DependencyContext d : m_dependencies) { if (d.isAutoConfig() && !d.isInstanceBound()) { configureImplementation(d.getAutoConfigType(), d, d.getAutoConfigName()); } } }
/** * Invokes a swap callback, except if the dependency is optional and the component is * not started (optional dependencies are always injected while the component is started). */ private void invokeSwapCallback(DependencyContext dc, Event oldEvent, Event newEvent) { if (! dc.isRequired() && ! m_startCalled) { return; } dc.invokeCallback(EventType.SWAPPED, oldEvent, newEvent); }
/** * Updates the component instance(s). * @param dc the dependency context for the updating dependency service * @param event the event holding the updating service (service + properties) * @param update true if dependency service properties are updating, false if not. If false, it means * that a dependency service is being added or removed. (see the "add" flag). * @param add true if the dependency service has been added, false if it has been removed. This flag is * ignored if the "update" flag is true (because the dependency properties are just being updated). */ private void updateInstance(DependencyContext dc, Event event, boolean update, boolean add) { if (dc.isAutoConfig()) { updateImplementation(dc.getAutoConfigType(), dc, dc.getAutoConfigName(), event, update, add); } if (dc.isPropagated() && m_registration != null) { m_registration.setProperties(calculateServiceProperties()); } }
private Dictionary<String, Object> calculateServiceProperties() { Dictionary<String, Object> properties = new Hashtable<>(); // First add propagated dependency service properties which don't override our component service properties Predicate<DependencyContext> dependencyPropagated = (dc) -> dc.isPropagated() && dc.isAvailable(); m_dependencies.stream() .filter(dc -> dependencyPropagated.test(dc) && ! dc.overrideServiceProperties()) .forEach(dc -> addTo(properties, dc.getProperties())); // Now add our component service properties, which override previously added propagated dependency service properties addTo(properties, m_serviceProperties); // Finally, add dependency service properties which override our component service properties m_dependencies.stream() .filter(dc -> dependencyPropagated.test(dc) && dc.overrideServiceProperties()) .forEach(dc -> addTo(properties, dc.getProperties())); return properties; // FELIX-5683: now we never return null }
@Override public ComponentImpl add(final Dependency ... dependencies) { getExecutor().execute(() -> { List<DependencyContext> instanceBoundDeps = new ArrayList<>(); for (Dependency d : dependencies) { DependencyContext dc = (DependencyContext) d; if (dc.getComponentContext() != null) { m_logger.err("%s can't be added to %s (dependency already added to component %s).", dc, ComponentImpl.this, dc.getComponentContext()); continue; } m_dependencyEvents.put(dc, new ConcurrentSkipListSet<Event>()); m_dependencies.add(dc); generateNameBasedOnServiceAndProperties(); dc.setComponentContext(ComponentImpl.this); if (!(m_state == ComponentState.INACTIVE)) { dc.setInstanceBound(true); instanceBoundDeps.add(dc); } } startDependencies(instanceBoundDeps); handleChange(); }); return this; }
configureAutoConfigState(clone, ComponentImpl.this); getDependencies().stream().filter(dc -> ! dc.isInstanceBound()).map(dc -> dc.createCopy()).forEach(clone::add); clone.setCallbacks(m_callbackInit, m_callbackStart, m_callbackStop, m_callbackDestroy); m_listeners.forEach(clone::add);
public void injectField(Field f, Object target) { try { f.setAccessible(true); f.set(target, dc.getService().getEvent()); } catch (Throwable e) { logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class " + target.getClass().getName(), e); } }
@SuppressWarnings("unchecked") public void injectIterableField(Field f, Object target) { f.setAccessible(true); try { Iterable<Object> iter = (Iterable<Object>) f.get(target); if (iter == null) { iter = new ConcurrentLinkedQueue<Object>(); f.set(target, iter); } dc.copyToCollection((Collection<Object>) iter); } catch (Throwable e) { logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class " + target.getClass().getName(), e); } }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void injectMapField(Field f, Object target) { f.setAccessible(true); try { Map<Object, Dictionary<?, ?>> map = (Map) f.get(target); if (map == null) { map = new ConcurrentHashMap<>(); f.set(target, map); } dc.copyToMap(map); } catch (Throwable e) { logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class " + target.getClass().getName(), e); } } });
final DependencyContext dc, final Logger logger) final Event event = dc.getService(); if (event == null) { return true; // TODO check why event can be null
private void invokeAutoConfigInstanceBoundDependencies() { for (DependencyContext d : m_dependencies) { if (d.isAutoConfig() && d.isInstanceBound()) { configureImplementation(d.getAutoConfigType(), d, d.getAutoConfigName()); } } }
if (! dc.isRequired() && ! m_startCalled) { return; dc.invokeCallback(type, event);
/** * Add a Dependency to all already instantiated services. */ public void addDependency(Dependency ... dependencies) { for (Component component : m_services.values()) { Dependency[] copy = Stream.of(dependencies) .map(d -> (DependencyContext) d) .map(dc -> dc.createCopy()) .toArray(Dependency[]::new); for (int i = 0; i < dependencies.length; i ++) { m_depclones.put(dependencies[i], copy[i]); } component.add(copy); } }