You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2007/08/17 09:53:41 UTC
svn commit: r566960 - in /felix/trunk/ipojo/core: ./
src/main/java/org/apache/felix/ipojo/
src/main/java/org/apache/felix/ipojo/handlers/configuration/
src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/
src/main/java/org/apache/felix/i...
Author: clement
Date: Fri Aug 17 00:53:40 2007
New Revision: 566960
URL: http://svn.apache.org/viewvc?view=rev&rev=566960
Log:
Add the lifecycle controller handler.
Solve a bug when InstanceManager.setState is reentrant (in the same thread).
Some comestic bug fixes in provided service.
Added:
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
Modified:
felix/trunk/ipojo/core/pom.xml
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
Modified: felix/trunk/ipojo/core/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/pom.xml?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/pom.xml (original)
+++ felix/trunk/ipojo/core/pom.xml Fri Aug 17 00:53:40 2007
@@ -59,6 +59,7 @@
org.apache.felix.ipojo.handlers.configuration,
org.apache.felix.ipojo.handlers.dependency.nullable,
org.apache.felix.ipojo.handlers.lifecycle.callback,
+ org.apache.felix.ipojo.handlers.lifecycle.controller,
org.objectweb.asm,
org.objectweb.asm.commons,
org.objectweb.asm.tree <!-- to remove -->
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java Fri Aug 17 00:53:40 2007
@@ -25,12 +25,12 @@
import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
import org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler;
+import org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler;
import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
import org.apache.felix.ipojo.util.Logger;
/**
- * Activator Basic Configuration. - Log Level - Available handlers
- *
+ * iPOJO Configuration : Default Log Level - Available (core) handlers.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class IPojoConfiguration {
@@ -47,8 +47,9 @@
DependencyHandler.class,
ProvidedServiceHandler.class,
ConfigurationHandler.class,
- LifecycleCallbackHandler.class,
- ArchitectureHandler.class
+ LifecycleCallbackHandler.class,
+ ControllerHandler.class,
+ ArchitectureHandler.class
};
/**
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Fri Aug 17 00:53:40 2007
@@ -20,8 +20,10 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -94,15 +96,23 @@
/**
* Instance State Listener List.
*/
- private InstanceStateListener[] m_instanceListeners = new InstanceStateListener[0];
+ private List m_instanceListeners = new ArrayList();
/**
* Component type information.
*/
private ComponentDescription m_componentDesc;
+ /**
+ * Is the component instance state changing?
+ */
+ private boolean m_inTransition = false;
+
+ /**
+ * Queue of stored state changed.
+ */
+ private List m_stateQueue = new ArrayList();
- // Constructor
/**
* Construct a new Component Manager.
*
@@ -275,8 +285,8 @@
m_pojoObjects = new Object[0];
m_state = STOPPED;
- for (int i = 0; i < m_instanceListeners.length; i++) {
- m_instanceListeners[i].stateChanged(this, STOPPED);
+ for (int i = 0; i < m_instanceListeners.size(); i++) {
+ ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
}
}
@@ -289,8 +299,8 @@
stop();
}
- for (int i = 0; i < m_instanceListeners.length; i++) {
- m_instanceListeners[i].stateChanged(this, DISPOSED);
+ for (int i = 0; i < m_instanceListeners.size(); i++) {
+ ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
}
m_factory.disposed(this);
@@ -300,7 +310,7 @@
m_fieldRegistration = new HashMap();
m_clazz = null;
m_pojoObjects = new Object[0];
- m_instanceListeners = new InstanceStateListener[0];
+ m_instanceListeners.clear();
}
/**
@@ -312,8 +322,8 @@
stop();
}
- for (int i = 0; i < m_instanceListeners.length; i++) {
- m_instanceListeners[i].stateChanged(this, DISPOSED);
+ for (int i = 0; i < m_instanceListeners.size(); i++) {
+ ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
}
// Cleaning
@@ -322,16 +332,24 @@
m_fieldRegistration = new HashMap();
m_clazz = null;
m_pojoObjects = new Object[0];
- m_instanceListeners = new InstanceStateListener[0];
+ m_instanceListeners.clear();
}
-
+
/**
* Set the state of the component instance.
- * Ff the state changed call the stateChanged(int) method on the handlers.
+ * if the state changed call the stateChanged(int) method on the handlers.
+ * This method has a reentrant mechanism. If in the flow of the first call the method is called another times,
+ * the second call is stored and executed after the first one is finished.
* @param state : the new state
*/
- public void setState(int state) {
+ private synchronized void setState(int state) {
+ if (m_inTransition) {
+ m_stateQueue.add(new Integer(state));
+ return;
+ }
+
if (m_state != state) {
+ m_inTransition = true;
// Log the state change
if (state == INVALID) {
@@ -347,10 +365,16 @@
m_handlers[i].stateChanged(state);
}
- for (int i = 0; i < m_instanceListeners.length; i++) {
- m_instanceListeners[i].stateChanged(this, state);
+ for (int i = 0; i < m_instanceListeners.size(); i++) {
+ ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
}
}
+
+ m_inTransition = false;
+ if (! m_stateQueue.isEmpty()) {
+ int newState = ((Integer) (m_stateQueue.remove(0))).intValue();
+ setState(newState);
+ }
}
/**
@@ -372,53 +396,21 @@
}
/**
- * Add an instance to the created instance list.
- * @param listener : the instance state listener to add.
+ * Register an instance state listener.
+ * @param listener : listener to register.
* @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
*/
public void addInstanceStateListener(InstanceStateListener listener) {
- for (int i = 0; (m_instanceListeners != null) && (i < m_instanceListeners.length); i++) {
- if (m_instanceListeners[i] == listener) {
- return;
- }
- }
-
- if (m_instanceListeners.length > 0) {
- InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length + 1];
- System.arraycopy(m_instanceListeners, 0, newInstances, 0, m_instanceListeners.length);
- newInstances[m_instanceListeners.length] = listener;
- m_instanceListeners = newInstances;
- } else {
- m_instanceListeners = new InstanceStateListener[] { listener };
- }
+ m_instanceListeners.add(listener);
}
-
+
/**
- * Remove an instance state listener.
- * @param listener : the listener to remove
+ * Unregister an instance state listener.
+ * @param listener : listener to unregister.
* @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
*/
public void removeInstanceStateListener(InstanceStateListener listener) {
- int idx = -1;
- for (int i = 0; i < m_instanceListeners.length; i++) {
- if (m_instanceListeners[i] == listener) {
- idx = i;
- break;
- }
- }
-
- if (idx >= 0) {
- if ((m_instanceListeners.length - 1) == 0) {
- m_instanceListeners = new InstanceStateListener[0];
- } else {
- InstanceStateListener[] newInstances = new InstanceStateListener[m_instanceListeners.length - 1];
- System.arraycopy(m_instanceListeners, 0, newInstances, 0, idx);
- if (idx < newInstances.length) {
- System.arraycopy(m_instanceListeners, idx + 1, newInstances, idx, newInstances.length - idx);
- }
- m_instanceListeners = newInstances;
- }
- }
+ m_instanceListeners.remove(listener);
}
// ===================== end Lifecycle management =====================
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java Fri Aug 17 00:53:40 2007
@@ -67,18 +67,12 @@
* Configurable Property Constructor. At least the method or the field need
* to be referenced.
*
- * @param name :
- * name of the property (optional)
- * @param field :
- * name of the field
- * @param method :
- * method name
- * @param value :
- * initial value of the property (optional)
- * @param type :
- * the type of the property
- * @param ch :
- * configuration handler managing this configurable property
+ * @param name : name of the property (optional)
+ * @param field : name of the field
+ * @param method : method name
+ * @param value : initial value of the property (optional)
+ * @param type : the type of the property
+ * @param ch : configuration handler managing this configurable property
*/
public ConfigurableProperty(String name, String field, String method, String value, String type,
ConfigurationHandler ch) {
@@ -107,14 +101,13 @@
/**
* Set the value of the property.
*
- * @param strValue :
- * value of the property (String)
- * @param type :
- * type of the property
+ * @param strValue : value of the property (String)
+ * @param type : type of the property
*/
private void setValue(String strValue, String type) {
Object value = null;
-
+
+ // Syntactic sugar to avoid writing java.lang.String
if (type.equals("string") || type.equals("String")) {
value = new String(strValue);
m_type = java.lang.String.class;
@@ -202,10 +195,8 @@
/**
* Set array value to the current property.
*
- * @param internalType :
- * type of the property
- * @param values :
- * new property value
+ * @param internalType : type of the property
+ * @param values : new property value
*/
private void setArrayValue(String internalType, String[] values) {
if (internalType.equals("string") || internalType.equals("String")) {
@@ -345,8 +336,7 @@
/**
* Fix the value of the property.
*
- * @param value :
- * the new value.
+ * @param value : the new value.
*/
public void setValue(Object value) {
m_value = value;
@@ -406,7 +396,7 @@
m_handler.getInstanceManager().getFactory().getLogger().log(
Logger.ERROR,
"The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName()
- + "thorws an exception : " + e.getMessage());
+ + "throws an exception : " + e.getMessage());
return;
}
}
Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java?view=auto&rev=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java Fri Aug 17 00:53:40 2007
@@ -0,0 +1,140 @@
+/*
+ * 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.ipojo.handlers.lifecycle.controller;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.ManipulationMetadata;
+import org.apache.felix.ipojo.util.Logger;
+
+/**
+ * Lifecycle Controller handler.
+ * This handler allow a POJO to vote for the instance state. By setting a boolean field to true or false, the handler state changed.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ControllerHandler extends Handler {
+
+ /**
+ * Instance Manager.
+ */
+ private InstanceManager m_manager;
+
+ /**
+ * Actual handler (i.e. field value) state
+ */
+ private boolean m_state;
+
+ /**
+ * Configure method.
+ * Look for the first 'controller' element.
+ * @param im : instance manager
+ * @param metadata : metadata
+ * @param configuration : configuration
+ * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+ */
+ public void configure(InstanceManager im, Element metadata, Dictionary configuration) {
+ m_manager = im;
+ String field = null;
+ Element[] lc = metadata.getElements("controller");
+ if (lc.length > 0) {
+ // Use only the first controller
+ if (lc[0].containsAttribute("field")) {
+ field = lc[0].getAttribute("field");
+ } else {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "A lifecycle controler needs to contain a field attribute");
+ return;
+ }
+ } else {
+ return;
+ }
+
+ ManipulationMetadata mm = new ManipulationMetadata(metadata);
+ FieldMetadata fm = mm.getField(field);
+ if (fm == null) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "The field " + field + " does not exist in the class");
+ return;
+ }
+
+ if (!fm.getFieldType().equalsIgnoreCase("boolean")) {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");
+ return;
+ }
+
+ im.register(this, new FieldMetadata[] {fm}, null);
+ }
+
+ /**
+ * Start method.
+ * Nothing to do.
+ * @see org.apache.felix.ipojo.Handler#start()
+ */
+ public void start() {
+ m_state = true;
+ }
+
+ /**
+ * Stop method.
+ * Nothing to do.
+ * @see org.apache.felix.ipojo.Handler#stop()
+ */
+ public void stop() { }
+
+ /**
+ * Return the field value.
+ * @return the field value (i.e. the handler state)
+ * @see org.apache.felix.ipojo.Handler#isValid()
+ */
+ public boolean isValid() {
+ return m_state;
+ }
+
+ /**
+ * GetterCallback.
+ * Return the stored value.
+ * @param field : field name.
+ * @param o : value given by the previous handler.
+ * @return : the handler state.
+ */
+ public Object getterCallback(String field, Object o) {
+ return new Boolean(m_state);
+ }
+
+ /**
+ * SetterCallback.
+ * Store the new field value & invalidate / validate the handler is required.
+ * @param field : field name.
+ * @param o : new value.
+ */
+ public void setterCallback(String field, Object o) {
+ if (o instanceof Boolean) {
+ boolean nv = ((Boolean) o).booleanValue();
+ if (nv != m_state) {
+ m_state = nv;
+ m_manager.checkInstanceState();
+ }
+ } else {
+ m_manager.getFactory().getLogger().log(Logger.ERROR, "Boolean expected");
+ }
+ }
+
+}
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java Fri Aug 17 00:53:40 2007
@@ -228,7 +228,7 @@
for (int i = 0; i < m_serviceSpecification.length; i++) {
spec = spec + m_serviceSpecification[i] + ", ";
}
- // Contruct the service properties list
+ // Build the service properties list
Properties serviceProperties = getServiceProperties();
m_serviceRegistration = m_handler.getInstanceManager().getContext().registerService(m_serviceSpecification, this, serviceProperties);
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?view=diff&rev=566960&r1=566959&r2=566960
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Fri Aug 17 00:53:40 2007
@@ -382,7 +382,7 @@
* java.lang.Object)
*/
public void setterCallback(String fieldName, Object value) {
- // Verify that the field name coreespond to a dependency
+ // Verify that the field name correspond to a dependency
for (int i = 0; i < m_providedServices.length; i++) {
ProvidedService ps = m_providedServices[i];
boolean update = false;
@@ -433,7 +433,7 @@
* @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
*/
public void stateChanged(int state) {
- // If the new state is UNRESOLVED => unregister all the services
+ // If the new state is INVALID => unregister all the services
if (state == InstanceManager.INVALID) {
for (int i = 0; i < m_providedServices.length; i++) {
m_providedServices[i].unregisterService();
@@ -441,14 +441,13 @@
return;
}
- // If the new state is VALID => regiter all the services
+ // If the new state is VALID => register all the services
if (state == InstanceManager.VALID) {
for (int i = 0; i < m_providedServices.length; i++) {
m_providedServices[i].registerService();
}
return;
}
-
}
/**