[FELIX-4507] Implement new style component factory with modify method (turned off, no tests)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1591418 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/component/ExtFactoryComponentInstance.java b/scr/src/main/java/org/apache/felix/scr/component/ExtFactoryComponentInstance.java
new file mode 100644
index 0000000..1c4c695
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/component/ExtFactoryComponentInstance.java
@@ -0,0 +1,30 @@
+/*
+ * 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.component;
+
+import java.util.Dictionary;
+
+import org.osgi.service.component.ComponentInstance;
+
+public interface ExtFactoryComponentInstance extends ComponentInstance
+{
+
+ void modify( Dictionary<String, ?> properties );
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index 6709d45..010454e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -28,6 +28,7 @@
import java.util.Map;
import org.apache.felix.scr.Component;
+import org.apache.felix.scr.component.ExtFactoryComponentInstance;
import org.apache.felix.scr.impl.BundleComponentActivator;
import org.apache.felix.scr.impl.TargetedPID;
import org.apache.felix.scr.impl.config.ComponentHolder;
@@ -93,14 +94,30 @@
protected TargetedPID m_targetedPID;
+ /**
+ * True if this is a R5 spec component factory
+ * False if this is a persistent component factory.
+ */
+ private boolean m_nonPersistentFactory;
+
public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata )
{
super( activator, metadata, new ComponentMethods() );
m_componentInstances = new IdentityHashMap<SingleComponentManager<S>, SingleComponentManager<S>>();
m_configuration = new Hashtable<String, Object>();
+ m_nonPersistentFactory = true;
}
+ protected boolean verifyDependencyManagers()
+ {
+ if (m_nonPersistentFactory)
+ {
+ return super.verifyDependencyManagers();
+ }
+ return true;
+ }
+
@Override
public boolean isFactory()
{
@@ -126,7 +143,7 @@
cm.activateInternal( getTrackingCount().get() );
instance = cm.getComponentInstance();
- if ( instance == null || instance.getInstance() == null )
+ if ( instance == null || (m_nonPersistentFactory && instance.getInstance() == null) )
{
// activation failed, clean up component manager
cm.dispose( ComponentConstants.DEACTIVATION_REASON_DISPOSED );
@@ -137,9 +154,43 @@
{
m_componentInstances.put( cm, cm );
}
+
+ if ( !m_nonPersistentFactory )
+ {
+ instance = new ModifyComponentInstance(cm);
+ }
return instance;
}
+
+ private static class ModifyComponentInstance implements ExtFactoryComponentInstance
+ {
+ private final SingleComponentManager cm;
+ private long changeCount = 0;
+
+ public ModifyComponentInstance(SingleComponentManager cm)
+ {
+ this.cm = cm;
+ }
+
+ public void dispose()
+ {
+ cm.getComponentInstance().dispose();
+ }
+
+ public Object getInstance()
+ {
+ final ComponentInstance componentInstance = cm.getComponentInstance();
+ return componentInstance == null? null: componentInstance.getInstance();
+ }
+
+ public void modify(Dictionary<String, ?> properties)
+ {
+ cm.setFactoryProperties( properties );
+ cm.reconfigure();
+ }
+
+ }
/**
* Compares this {@code ComponentFactoryImpl} object to another object.
@@ -153,7 +204,7 @@
* {@code ComponentFactoryImpl} and is equal to this object;
* {@code false} otherwise.
*/
- public boolean equals(Object object)
+ public boolean equals(Object object)
{
if (!(object instanceof ComponentFactoryImpl))
{
@@ -234,7 +285,7 @@
return props;
}
- public void setServiceProperties( Dictionary serviceProperties )
+ public void setServiceProperties( Dictionary<String, Object> serviceProperties )
{
throw new IllegalStateException( "ComponentFactory service properties are immutable" );
}
@@ -492,7 +543,7 @@
*/
private SingleComponentManager<S> createComponentManager()
{
- return new ComponentFactoryNewInstance<S>( getActivator(), this, getComponentMetadata(), getComponentMethods() );
+ return new SingleComponentManager<S>( getActivator(), this, getComponentMetadata(), getComponentMethods(), m_nonPersistentFactory );
}
@@ -507,16 +558,6 @@
}
}
- static class ComponentFactoryNewInstance<S> extends SingleComponentManager<S> {
-
- public ComponentFactoryNewInstance( BundleComponentActivator activator, ComponentHolder componentHolder,
- ComponentMetadata metadata, ComponentMethods componentMethods )
- {
- super( activator, componentHolder, metadata, componentMethods, true );
- }
-
- }
-
public TargetedPID getConfigurationTargetedPID(TargetedPID pid)
{
return m_targetedPID;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
index 9536ede..9ddcdce 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
@@ -551,39 +551,44 @@
*/
public void reconfigure( Dictionary<String, Object> configuration, long changeCount, TargetedPID targetedPID )
{
+ if ( targetedPID == null || !targetedPID.equals( m_targetedPID ) )
+ {
+ m_targetedPID = targetedPID;
+ m_changeCount = -1;
+ }
+ if ( configuration != null )
+ {
+ if ( changeCount <= m_changeCount )
+ {
+ log( LogService.LOG_DEBUG,
+ "ImmediateComponentHolder out of order configuration updated for pid {0} with existing count {1}, new count {2}",
+ new Object[] { getConfigurationPid(), m_changeCount, changeCount }, null );
+ return;
+ }
+ m_changeCount = changeCount;
+ }
+ else
+ {
+ m_changeCount = -1;
+ }
+ // nothing to do if there is no configuration (see FELIX-714)
+ if ( configuration == null && m_configurationProperties == null )
+ {
+ log( LogService.LOG_DEBUG, "No configuration provided (or deleted), nothing to do", null );
+ return;
+ }
+
+ // store the properties
+ m_configurationProperties = configuration;
+
+ reconfigure();
+ }
+
+ void reconfigure()
+ {
CountDownLatch enableLatch = enableLatchWait();
try
{
- if ( targetedPID == null || !targetedPID.equals( m_targetedPID ) )
- {
- m_targetedPID = targetedPID;
- m_changeCount = -1;
- }
- if ( configuration != null )
- {
- if ( changeCount <= m_changeCount )
- {
- log( LogService.LOG_DEBUG,
- "ImmediateComponentHolder out of order configuration updated for pid {0} with existing count {1}, new count {2}",
- new Object[] { getConfigurationPid(), m_changeCount, changeCount }, null );
- return;
- }
- m_changeCount = changeCount;
- }
- else
- {
- m_changeCount = -1;
- }
- // nothing to do if there is no configuration (see FELIX-714)
- if ( configuration == null && m_configurationProperties == null )
- {
- log( LogService.LOG_DEBUG, "No configuration provided (or deleted), nothing to do", null );
- return;
- }
-
- // store the properties
- m_configurationProperties = configuration;
-
// clear the current properties to force using the configuration data
m_properties = null;
@@ -600,7 +605,7 @@
// if the configuration has been deleted but configuration is required
// this component must be deactivated
- if ( configuration == null && getComponentMetadata().isConfigurationRequired() )
+ if ( m_configurationProperties == null && getComponentMetadata().isConfigurationRequired() )
{
//deactivate and remove service listeners
deactivateInternal( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED, true, false );
@@ -628,7 +633,7 @@
{
// SCR 112.7.1 - deactivate if configuration is deleted or no modified method declared
log( LogService.LOG_DEBUG, "Deactivating and Activating to reconfigure from configuration", null );
- int reason = ( configuration == null ) ? ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED
+ int reason = ( m_configurationProperties == null ) ? ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED
: ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_MODIFIED;
// FELIX-2368: cycle component immediately, reconfigure() is
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
index 3bc3081..edf7bb1 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentFactoryTest.java
@@ -667,5 +667,11 @@
s1.drop();
}
+
+ private Object getComponentManagerFromExtComponentInstance( Object extIinstance )
+ {
+ return getFieldValue( extIinstance, "cm");
+ }
+
}