You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2006/06/14 17:22:08 UTC
svn commit: r414287 [4/6] - in /incubator/felix/trunk:
org.apache.felix.ipojo.arch/ org.apache.felix.ipojo.arch/src/
org.apache.felix.ipojo.arch/src/main/
org.apache.felix.ipojo.arch/src/main/java/
org.apache.felix.ipojo.arch/src/main/java/org/ org.apa...
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.ComponentManager;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Represent a service dependency either for a componenet dependency either for
+ * a provided service dependency. Date : 3 déc. 2005
+ * @author clément
+ */
+public class Dependency implements ServiceListener {
+
+ /**
+ * Dependency State : RESOLVED.
+ */
+ public static final int RESOLVED = 1;
+
+ /**
+ * Dependency State : UNRESOLVED.
+ */
+ public static final int UNRESOLVED = 2;
+
+ /**
+ * Link to the Component Manager.
+ * m_handler : ComponentManager
+ */
+ private DependencyHandler m_handler;
+
+
+ /**
+ * Metadata of the dependency.
+ * m_metadata : dependency metadata
+ */
+ private DependencyMetadata m_metadata;
+
+ /**
+ * Array of Service Objects.
+ * When cardinality = 1 : just the first element is returned
+ * When cardinality = ?..n : all the array is returned
+ * m_services : Array
+ */
+ private Object[] m_services = new Object[0];
+
+ /**
+ * Array of service references.
+ * m_ref : Array
+ */
+ private ServiceReference[] m_ref = new ServiceReference[0];
+
+ /**
+ * State of the dependency.
+ * 0 : stopped, 1 : valid, 2 : invalid.
+ * m_state : int
+ */
+ private int m_state;
+
+ /**
+ * True if the reference list change after the creation of a service object array.
+ */
+ private boolean m_change;
+
+ /**
+ * Class of the dependency.
+ * Usefull to create in the case of multiple dependency
+ */
+ private Class m_clazz;
+
+
+ /**
+ * Dependency contructor. After the creation the dependency is not started.
+ * @param dh : the dependency handler managing this dependency
+ * @param dm : the depednency metadata
+ */
+ public Dependency(DependencyHandler dh, DependencyMetadata dm) {
+ m_handler = dh;
+ m_metadata = dm;
+ }
+
+ /**
+ * @return the dependency metadata.
+ */
+ public DependencyMetadata getMetadata() { return m_metadata; }
+
+ /**
+ * @return the dependency handler of this dependency.
+ */
+ public DependencyHandler getDependencyHandler() { return m_handler; }
+
+ /**
+ * @return the used service.
+ */
+ public HashMap getUsedServices() {
+ HashMap hm = new HashMap();
+ if (m_metadata.isMultiple()) {
+ for (int i = 0; i < m_ref.length; i++) {
+ if (i < m_services.length) { hm.put(((Object)m_services[i]).toString(), m_ref[i]); }
+ }
+ } else {
+ if (m_ref.length != 0 && m_services.length != 0) { hm.put(((Object)m_services[0]).toString(), m_ref[0]); }
+ }
+ return hm;
+ }
+
+ /**
+ * A dependency is satisfied if it is optional of ref.length != 0.
+ * @return true is the dependency is satified
+ */
+ protected boolean isSatisfied() {
+ return m_metadata.isOptional() || m_ref.length != 0;
+ }
+
+ /**
+ * This method is called by the replaced code in the component implementation class.
+ * Construct the service object list is necessary.
+ * @return null or a service object or a list of service object according to the dependency.
+ */
+ protected Object get() {
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Call get for a dependency on : " + m_metadata.getServiceSpecification()
+ + " Multiple : " + m_metadata.isMultiple() + " Optional : " + m_metadata.isOptional());
+ try {
+
+ // 1 : Test if there is any change in the reference list :
+ if (!m_change) {
+ if (!m_metadata.isMultiple()) {
+ if (m_services.length > 0) {
+ return m_services[0]; }
+ }
+ else {
+ return m_services;
+ }
+ }
+
+ // 2 : Else there is a change in the list -> recompute the m_services array
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create a service array of " + m_clazz.getName());
+ m_services = (Object[])Array.newInstance(m_clazz, m_ref.length);
+
+ for (int i = 0; i < m_ref.length; i++) {
+ m_services[i] = m_handler.getComponentManager().getContext().getService(m_ref[i]);
+ }
+
+ m_change = false;
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create an array with the size " + m_services.length);
+
+
+ // 3 : The service object list is populated, I return either the first service object, either the array.
+ // Return null or an empty array if no service are found.
+ if (!m_metadata.isMultiple()) {
+ if (m_services.length > 0) {
+ return m_services[0];
+ } else {
+ // Load the nullable class
+ String[] segment = m_metadata.getServiceSpecification().split("[.]");
+ String className = "org.apache.felix.ipojo." + segment[segment.length - 1] + "Nullable";
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Try to load the nullable class for " + getMetadata().getServiceSpecification() + " -> " + className);
+ Class nullableClazz = m_handler.getNullableClass(className);
+
+ if (nullableClazz == null) {
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_metadata.getField() + " -> " + m_metadata.getServiceSpecification());
+ return null;
+ }
+
+ // The nullable class is loaded, create the object and return it
+ Object instance = nullableClazz.newInstance();
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Nullable object created for " + getMetadata().getServiceSpecification() + " -> " + instance);
+ return instance;
+ }
+ }
+ else { // Multiple dependency
+ return m_services;
+ }
+ } catch (Exception e) {
+ // There is a problem in the dependency resolving (like in stopping method)
+ if (!m_metadata.isMultiple()) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return null, an exception was throwed in the get method -> " + e.getMessage());
+ return null; }
+ else {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return an empty array, an exception was throwed in the get method" + e.getMessage());
+ return Array.newInstance(m_clazz, 0); }
+ }
+ }
+
+ /**
+ * Method calld when a service event is throwed.
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ * @param event : the received service event
+ */
+ public void serviceChanged(ServiceEvent event) {
+ synchronized (this) {
+
+ // If a service goes way.
+ if (event.getType() == ServiceEvent.UNREGISTERING) {
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A service is gone -> " + event.getServiceReference().getBundle());
+ if (containsSR(event.getServiceReference())) {
+ // Call unbind method
+ callUnbindMethod(event.getServiceReference());
+ // Unget the service reference
+ m_handler.getComponentManager().getContext().ungetService(event.getServiceReference());
+ int index = removeReference(event.getServiceReference());
+
+ // Is the state valid or invalid
+ if (m_ref.length == 0 && !m_metadata.isOptional()) {
+ m_state = UNRESOLVED;
+ }
+ if (m_ref.length == 0 && m_metadata.isOptional()) {
+ m_state = RESOLVED;
+ }
+ // Is there any change ?
+ if (!m_metadata.isMultiple() && index == 0) { m_change = true; }
+ if (!m_metadata.isMultiple() && index != 0) { m_change = false; }
+ if (m_metadata.isMultiple()) { m_change = true; }
+ }
+ m_handler.checkContext();
+ return;
+ }
+
+ // If a service arrives
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ // Add the new service inside the ref list
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Add a service for a dependency");
+ addReference(event.getServiceReference());
+ if (isSatisfied()) {
+ m_state = RESOLVED;
+ if (m_metadata.isMultiple() || m_ref.length == 1) { m_change = true; }
+ callBindMethod(event.getServiceReference());
+ }
+ m_handler.checkContext();
+ }
+
+ }
+ }
+
+ private void callUnbindMethod(ServiceReference ref) {
+ if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+ for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+ if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.UNBIND) {
+ // Try to call the bind method with a service reference inside
+ try {
+ m_metadata.getCallbacks()[i].call(new Object[] {ref});
+ } catch (NoSuchMethodException e) {
+ // The method was not found : try without service reference
+ try {
+ m_metadata.getCallbacks()[i].call();
+ } catch (NoSuchMethodException e1) {
+ // The method was not found : try with the service object
+ try {
+ m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+ } catch (NoSuchMethodException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Unbind method not found : " + e1.getMessage());
+ return;
+ } catch (IllegalAccessException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e2.getMessage());
+ return;
+ } catch (InvocationTargetException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e2.getMessage());
+ return;
+ }
+ } catch (IllegalAccessException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e1.getMessage());
+ return;
+ } catch (InvocationTargetException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e1.getMessage());
+ return;
+ }
+
+ } catch (IllegalAccessException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+ return;
+ } catch (InvocationTargetException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ private void callBindMethod(ServiceReference ref) {
+ // call bind method :
+ if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+ for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+ if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.BIND) {
+ // Try to call the bind method with a service reference inside
+ try {
+ m_metadata.getCallbacks()[i].call(new Object[] {ref});
+ } catch (NoSuchMethodException e) {
+ // The method was not found : try without service reference
+ try {
+ m_metadata.getCallbacks()[i].call();
+ } catch (NoSuchMethodException e1) {
+ // The method was not found : try with the service object
+ try {
+ m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+ } catch (NoSuchMethodException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Bind method not found : " + e1.getMessage());
+ return;
+ } catch (IllegalAccessException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e2.getMessage());
+ return;
+ } catch (InvocationTargetException e2) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e2.getMessage());
+ return;
+ }
+ } catch (IllegalAccessException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e1.getMessage());
+ return;
+ } catch (InvocationTargetException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e1.getMessage());
+ return;
+ }
+
+ } catch (IllegalAccessException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+ return;
+ } catch (InvocationTargetException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Start the dependency.
+ */
+ public void start() {
+ // Construct the filter with the objectclass + filter
+ String classnamefilter = "(objectClass=" + m_metadata.getServiceSpecification() + ")";
+ String filter = "";
+ if (!m_metadata.getFilter().equals("")) {
+ filter = "(&" + classnamefilter + m_metadata.getFilter() + ")";
+ }
+ else {
+ filter = classnamefilter;
+ }
+
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Start a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+ m_state = UNRESOLVED;
+
+ try {
+ m_clazz = m_handler.getComponentManager().getContext().getBundle().loadClass(m_metadata.getServiceSpecification());
+ } catch (ClassNotFoundException e) {
+ System.err.println("Cannot load the interface class for the dependency " + m_metadata.getField() + " [" + m_metadata.getServiceSpecification() + "]");
+ e.printStackTrace();
+ }
+
+ try {
+ // Look if the service is already present :
+ ServiceReference[] sr = m_handler.getComponentManager().getContext().getServiceReferences(
+ m_metadata.getServiceSpecification(), filter);
+ if (sr != null) {
+ for (int i = 0; i < sr.length; i++) { addReference(sr[i]); }
+ m_state = RESOLVED;
+ }
+ // Register a listener :
+ m_handler.getComponentManager().getContext().addServiceListener(this, filter);
+ m_change = true;
+ }
+ catch (InvalidSyntaxException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A filter is malformed : " + filter);
+ e1.printStackTrace();
+ }
+ }
+
+ /**
+ * Stop the dependency.
+ */
+ public void stop() {
+ Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Stop a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+ m_state = UNRESOLVED;
+
+ // Unget all services references
+ for (int i = 0; i < m_ref.length; i++) {
+ m_handler.getComponentManager().getContext().ungetService(m_ref[i]);
+ }
+
+ m_ref = new ServiceReference[0];
+ m_handler.getComponentManager().getContext().removeServiceListener(this);
+ m_clazz = null;
+ m_services = null;
+ }
+
+ /**
+ * Return the state of the dependency.
+ * @return the state of the dependency (1 : valid, 2 : invalid)
+ */
+ public int getState() {
+ return m_state;
+ }
+
+ /**
+ * Return the list of service reference.
+ * @return the service reference list.
+ */
+ public ServiceReference[] getServiceReferences() {
+ return m_ref;
+ }
+
+ /**
+ * Add a service reference in the current list.
+ * @param r : the new service reference to add
+ */
+ private void addReference(ServiceReference r) {
+ for (int i = 0; (m_ref != null) && (i < m_ref.length); i++) {
+ if (m_ref[i] == r) {
+ return;
+ }
+ }
+
+ if (m_ref != null) {
+ ServiceReference[] newSR = new ServiceReference[m_ref.length + 1];
+ System.arraycopy(m_ref, 0, newSR, 0, m_ref.length);
+ newSR[m_ref.length] = r;
+ m_ref = newSR;
+ }
+ else {
+ m_ref = new ServiceReference[] {r};
+ }
+ }
+
+ /**
+ * Find if a service registration il already registred.
+ * @param sr : the service registration to find.
+ * @return true if the service registration is already in the array
+ */
+ private boolean containsSR(ServiceReference sr) {
+ for (int i = 0; i < m_ref.length; i++) {
+ if (m_ref[i] == sr) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Remove a service reference in the current list.
+ * @param r : the new service reference to remove
+ * @return the index of the founded element, or -1 if the element is not found
+ */
+ private int removeReference(ServiceReference r) {
+ if (m_ref == null) {
+ m_ref = new ServiceReference[0];
+ }
+
+ int idx = -1;
+ for (int i = 0; i < m_ref.length; i++) {
+ if (m_ref[i] == r) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx >= 0) {
+ // If this is the module, then point to empty list.
+ if ((m_ref.length - 1) == 0) {
+ m_ref = new ServiceReference[0];
+ }
+ // Otherwise, we need to do some array copying.
+ else {
+ ServiceReference[] newSR = new ServiceReference[m_ref.length - 1];
+ System.arraycopy(m_ref, 0, newSR, 0, idx);
+ if (idx < newSR.length) {
+ System.arraycopy(
+ m_ref, idx + 1, newSR, idx, newSR.length - idx);
+ }
+ m_ref = newSR;
+ }
+ }
+ return idx;
+ }
+
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.felix.ipojo.Callback;
+
+
+/**
+ * This class allwos the creation of callback when service dependency arrives or disappear.
+ * @author escoffie
+ *
+ */
+public class DependencyCallback {
+
+ /**
+ * Bind method (called when a service arrives).
+ */
+ public static final int BIND = 0;
+
+ /**
+ * Unbind method (called when a service disappears).
+ */
+ public static final int UNBIND = 1;
+
+ /**
+ * Is the method a bind method or an unbind method ?
+ */
+ private int m_methodType;
+
+ /**
+ * Callback object.
+ */
+ private Callback m_callback;
+
+
+ /**
+ * Constructor.
+ * @param dep : the dependency attached to this depednency callback
+ * @param method : the method to call
+ * @param methodType : is the method to call a bind method or an unbind method
+ * @param isStatic : is the method to call static ?
+ */
+ public DependencyCallback(Dependency dep, String method, int methodType, boolean isStatic) {
+ m_methodType = methodType;
+ m_callback = new Callback(method, isStatic, dep.getDependencyHandler().getComponentManager());
+ }
+
+ /**
+ * @return the method type.
+ */
+ public int getMethodType() { return m_methodType; }
+
+ /**
+ * Call the callback method.
+ * @throws NoSuchMethodException : Method is not found in the class
+ * @throws InvocationTargetException : The method is not static
+ * @throws IllegalAccessException : The method can not be invoked
+ */
+ protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ m_callback.call();
+ }
+
+ /**
+ * Call the callback method.
+ * @throws NoSuchMethodException : Method is not found in the class
+ * @throws InvocationTargetException : The method is not static
+ * @throws IllegalAccessException : The method can not be invoked
+ */
+ protected void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ m_callback.call(arg);
+ }
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * The dependency handler manages a list of dependencies.
+ * @author clément
+ */
+public class DependencyHandler implements Handler {
+
+ /**
+ * The component manager using this handler.
+ */
+ private ComponentManager m_componentManager;
+
+ /**
+ * List of depednencies of the component.
+ */
+ private Dependency[] m_dependencies = new Dependency[0];
+
+ /**
+ * List of nullable class for optional dependencies.
+ */
+ private Class[] m_nullableClasses = new Class[0];
+
+ /**
+ * Classloader to use to load nullable classes.
+ */
+ private NullableClassloader m_classloader;
+
+ /**
+ * State of the handler.
+ */
+ private int m_state;
+
+// ===================== Fields getters & setters =====================
+
+ private void addDependency(Dependency dep) {
+ for (int i = 0; (m_dependencies != null) && (i < m_dependencies.length); i++) {
+ if (m_dependencies[i] == dep) {
+ return;
+ }
+ }
+ if (m_dependencies.length > 0) {
+ Dependency[] newDep = new Dependency[m_dependencies.length + 1];
+ System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+ newDep[m_dependencies.length] = dep;
+ m_dependencies = newDep;
+ }
+ else {
+ m_dependencies = new Dependency[] {dep};
+ }
+ }
+
+ private void addNullableClass(Class clazz) {
+ for (int i = 0; (m_nullableClasses != null) && (i < m_nullableClasses.length); i++) {
+ if (m_nullableClasses[i] == clazz) {
+ return;
+ }
+ }
+ if (m_nullableClasses.length > 0) {
+ Class[] newClass = new Class[m_nullableClasses.length + 1];
+ System.arraycopy(m_nullableClasses, 0, newClass, 0, m_nullableClasses.length);
+ newClass[m_nullableClasses.length] = clazz;
+ m_nullableClasses = newClass;
+ }
+ else {
+ m_nullableClasses = new Class[] {clazz};
+ }
+ }
+
+ /**
+ * @return the dependency list
+ */
+ public Dependency[] getDependencies() { return m_dependencies; }
+
+ /**
+ * @return the component manager
+ */
+ protected ComponentManager getComponentManager() { return m_componentManager; }
+
+// ===================== Handler implementation =====================
+
+ /**
+ * Check the validity of the dependencies.
+ */
+ protected void checkContext() {
+
+ synchronized (this) {
+
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Check Context ...");
+
+ // Store the initial state
+ int initialState = m_state;
+
+ // Check the component dependencies
+ if (!validateComponentDependencies()) {
+ // The dependencies are not valid
+ if (initialState == ComponentManager.VALID) {
+ //There is a state change
+ m_state = ComponentManager.INVALID;
+ m_componentManager.check();
+ }
+ // Else do nothing, the component state stay UNRESOLVED
+ }
+ else {
+ // The dependencies are valid
+ if (initialState == ComponentManager.INVALID) {
+ //There is a state change
+ m_state = ComponentManager.VALID;
+ m_componentManager.check();
+ }
+ // Else do nothing, the component state stay VALID
+ }
+
+ }
+ }
+
+ private boolean checkDependency(Dependency dep) {
+ // Check the internal type of dependency
+ String field = dep.getMetadata().getField();
+
+ Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+ String type = null;
+ for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+ if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+ type = manipulation.getElements("Field")[i].getAttribute("type");
+ break;
+ }
+ }
+
+ if (type == null) {
+ Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] A declared dependency was not found in the class : " + dep.getMetadata().getField());
+ return false;
+ }
+
+ if (type != null) {
+ if (type.endsWith("[]")) {
+ // Set the dependency to multiple
+ dep.getMetadata().setMultiple();
+ type = type.substring(0, type.length() - 2);
+ }
+
+ if (dep.getMetadata().getServiceSpecification() == null) { dep.getMetadata().setServiceSpecification(type); }
+
+ if (!dep.getMetadata().getServiceSpecification().equals(type)) {
+ Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the needed service interface [" + dep.getMetadata().getServiceSpecification() + "] are not the same");
+ dep.getMetadata().setServiceSpecification(type);
+ }
+ }
+ else {
+ Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The declared dependency " + dep.getMetadata().getField() + " does not exist in the code");
+ }
+ return true;
+ }
+
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+ */
+ public void configure(ComponentManager cm, Element componentMetadata) {
+ // Fix the component manager
+ m_componentManager = cm;
+ m_dependencies = new Dependency[0];
+ m_nullableClasses = new Class[0];
+
+ // Create the dependency according to the component metadata
+ Element[] deps = componentMetadata.getElements("Dependency");
+ for (int i = 0; i < deps.length; i++) {
+ // Create the dependency metadata
+ String field = deps[i].getAttribute("field");
+ String serviceSpecification = null;
+ if (deps[i].containsAttribute("interface")) { serviceSpecification = deps[i].getAttribute("interface"); }
+ String filter = "";
+ if (deps[i].containsAttribute("filter")) { filter = deps[i].getAttribute("filter"); }
+ boolean optional = false;
+ if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) { optional = true; }
+ DependencyMetadata dm = new DependencyMetadata(field, serviceSpecification, filter, optional);
+
+
+ Dependency dep = new Dependency(this, dm);
+ // Check the dependency :
+ if (checkDependency(dep)) { addDependency(dep); }
+ else { Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The dependency on " + dep.getMetadata().getField() + " is not valid"); }
+
+ // Look for dependency callback :
+ for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
+ String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
+ String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+ int methodType = 0;
+ if (type.equals("bind")) { methodType = DependencyCallback.BIND; }
+ else { methodType = DependencyCallback.UNBIND; }
+ boolean isStatic = false;
+ if (deps[i].getElements("Callback", "")[j].containsAttribute("isStatic") && deps[i].getElements("Callback", "")[j].getAttribute("isStatic").equals("true")) { isStatic = true; }
+ DependencyCallback dc = new DependencyCallback(dep, method, methodType, isStatic);
+ dep.getMetadata().addDependencyCallback(dc);
+ }
+ }
+
+ if (deps.length > 0) {
+ m_componentManager.register(this);
+
+ // Create the nullable classloader
+ m_classloader = new NullableClassloader(m_componentManager.getContext().getBundle());
+
+ }
+ }
+
+ private void createNullableClass(Dependency dep) {
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Try to load the nullable class for " + dep.getMetadata().getServiceSpecification());
+ // Try to load the nullable object :
+ String[] segment = dep.getMetadata().getServiceSpecification().split("[.]");
+ String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+ String resource = dep.getMetadata().getServiceSpecification().replace('.', '/') + ".class";
+ URL url = m_componentManager.getContext().getBundle().getResource(resource);
+
+ try {
+ byte[] b = NullableObjectWriter.dump(url, dep.getMetadata().getServiceSpecification());
+
+// // DEBUG :
+// try {
+// File file = new File("P:\\workspace\\iPOJO\\adapted\\" + className.replace('/', '.') + ".class");
+// file.createNewFile();
+// FileOutputStream fos = new FileOutputStream(file);
+// fos.write(b);
+// fos.close();
+// } catch (Exception e3) {
+// System.err.println("Problem to write the adapted class on the file system : " + e3.getMessage());
+//
+// }
+
+ addNullableClass(m_classloader.defineClass(className.replace('/', '.'), b, null));
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Nullable class created for " + dep.getMetadata().getServiceSpecification());
+
+ } catch (IOException e1) {
+ Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot open a stream of an interface to generate the nullable class for " + dep.getMetadata().getServiceSpecification() + " -> " + e1.getMessage());
+ } catch (Exception e2) {
+ Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot load the nullable class for " + dep.getMetadata().getServiceSpecification() + " -> " + e2.getMessage());
+ }
+ }
+
+ /**
+ * Return the nullable class corresponding to the given name.
+ * @param name the needed type
+ * @return the class correspondig to the name, or null if the class does not exist.
+ */
+ protected Class getNullableClass(String name) {
+ for (int i = 0; i < m_nullableClasses.length; i++) {
+ Class c = m_nullableClasses[i];
+ if (c.getName().equals(name)) {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+ */
+ public Object getterCallback(String fieldName, Object value) {
+ for (int i = 0; i < m_dependencies.length; i++) {
+ Dependency dep = m_dependencies[i];
+ if (dep.getMetadata().getField().equals(fieldName)) {
+ // The field name is a dependency, return the get
+ return dep.get();
+ }
+ }
+ // Else return the value
+ return value;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#isValid()
+ */
+ public boolean isValid() {
+ return (m_state == ComponentManager.VALID);
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+ */
+ public void setterCallback(String fieldName, Object value) {
+ // Do nothing
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#start()
+ */
+ public void start() {
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Start the dependency handler");
+
+ // Start the dependencies, for optional dependencies create Nullable class
+ for (int i = 0; i < m_dependencies.length; i++) {
+ Dependency dep = m_dependencies[i];
+ if (dep.getMetadata().isOptional() && !dep.getMetadata().isMultiple()) { createNullableClass(dep); }
+ dep.start();
+ }
+ // Check the state
+ m_state = m_componentManager.getState();
+ checkContext();
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+ */
+ public void stateChanged(int state) {
+ // Another handler or the component manager itself change the state
+ if (m_state == ComponentManager.VALID && state == ComponentManager.INVALID) {
+ // The component is stopped => Stop the dependency tracking
+ stop();
+ }
+ m_state = state;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#stop()
+ */
+ public void stop() {
+ for (int i = 0; i < m_dependencies.length; i++) { m_dependencies[i].stop(); }
+ }
+
+ private boolean validateComponentDependencies() {
+ boolean valide = true;
+ for (int i = 0; i < m_dependencies.length; i++) {
+ Dependency dep = m_dependencies[i];
+ valide = valide & dep.isSatisfied();
+ if (!valide) {
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are not valid : " + dep.getMetadata().getServiceSpecification());
+ return false;
+ }
+ }
+ Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are valid");
+ return valide;
+ }
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency;
+
+/**
+ * Dependency Metadata.
+ * @author Clement Escoffier
+ */
+public class DependencyMetadata {
+
+ /**
+ * Service Specification <=> Service contract (or interface in OSGi).
+ */
+ private String m_serviceSpecification;
+
+ /**
+ * LDAP filter.
+ */
+ private String m_filter;
+
+ /**
+ * is the dependency optional ?
+ */
+ private boolean m_isOptional;
+
+ /**
+ * is the dependency multiple ?
+ */
+ private boolean m_isMultiple = false;
+
+ /**
+ * List of dependency callbacks attached to this dependency.
+ */
+ private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+
+ /**
+ * The field linking the metadata and the component implementation.
+ */
+ private String m_field;
+
+ // Constructor
+
+ /**
+ * Constructor.
+ * @param field : the field name
+ * @param service : the interface name.
+ * @param filter : the filter of the dependency
+ * @param isOptional : is the dependency optional
+ */
+ public DependencyMetadata(String field, String service, String filter, boolean isOptional) {
+ m_field = field;
+ m_serviceSpecification = service;
+ m_isOptional = isOptional;
+ m_filter = filter;
+ }
+
+ /**
+ * Add a callback to the dependency.
+ * @param cb : callback to add
+ */
+ public void addDependencyCallback(DependencyCallback cb) {
+ for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+ if (m_callbacks[i] == cb) { return; }
+ }
+
+ if (m_callbacks.length > 0) {
+ DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
+ System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
+ newCallbacks[m_callbacks.length] = cb;
+ m_callbacks = newCallbacks;
+ }
+ else {
+ m_callbacks = new DependencyCallback[] {cb};
+ }
+ }
+
+ // Getter
+
+ /**
+ * @return Returns the m_field.
+ */
+ public String getField() {
+ return m_field;
+ }
+
+ /**
+ * @return Returns the m_filter.
+ */
+ public String getFilter() {
+ return m_filter;
+ }
+
+ /**
+ * @return Returns the m_isMultiple.
+ */
+ public boolean isMultiple() {
+ return m_isMultiple;
+ }
+
+ /**
+ * @return Returns the m_isOptional.
+ */
+ public boolean isOptional() {
+ return m_isOptional;
+ }
+
+ /**
+ * @return Returns the m_serviceSpecification.
+ */
+ public String getServiceSpecification() {
+ return m_serviceSpecification;
+ }
+
+ /**
+ * return true if the dependency is multiple.
+ */
+ public void setMultiple() {
+ m_isMultiple = true;
+ }
+
+ /**
+ * Set the service specification.
+ * @param serviceSpecification : the dependency service specification
+ */
+ public void setServiceSpecification(String serviceSpecification) {
+ m_serviceSpecification = serviceSpecification;
+ }
+
+ /**
+ * @return the list of the callbacks
+ */
+ public DependencyCallback[] getCallbacks() { return m_callbacks; }
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * iPOJO Classloader.
+ * This classloadert is used to load manipulated class.
+ * @author Clement Escoffier
+ */
+public class NullableClassloader extends ClassLoader {
+
+ /**
+ * The owner bundle.
+ * m_bundle : Bundle
+ */
+ private Bundle m_bundle;
+
+ /**
+ * Constructor.
+ * @param b : the owner bundle
+ */
+ public NullableClassloader(Bundle b) {
+ m_bundle = b;
+ }
+
+ /**
+ * load the class.
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ * @param name : the name of the class
+ * @param resolve : should be the class resolve now ?
+ * @return : the loaded class
+ * @throws ClassNotFoundException : the class to load is not found
+ */
+ protected synchronized Class loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
+
+ Class clazz = null;
+ //Activator.getLogger().log(Level.WARNING, "Bundle " + m_bundle.getBundleId() + " -> Try to load : " + name);
+
+ if (m_bundle != null) { clazz = m_bundle.loadClass(name); }
+
+ return clazz;
+ }
+
+
+ /**
+ * Return the URL of the asked ressource.
+ * @param arg : the name of the resource to find.
+ * @return the URL of the resource.
+ * @see java.lang.ClassLoader#getResource(java.lang.String)
+ */
+ public URL getResource(String arg) {
+ return m_bundle.getResource(arg);
+ }
+
+ /**
+ * .
+ * @param arg : resource to find
+ * @return : the enumeration found
+ * @throws IOException : if the lookup failed.
+ * @see java.lang.ClassLoader#getResources(java.lang.String)
+ */
+ public Enumeration getRessources(String arg) throws IOException {
+ return m_bundle.getResources(arg);
+ }
+
+ /**
+ * The defineClass method for GenClassLoader.
+ * @param name : name of the class
+ * @param b : the byte array of the class
+ * @param domain : the protection domain
+ * @return : the defined class.
+ * @throws Exception : if a problem is detected during the loading
+ */
+ public Class defineClass(String name, byte[] b,
+ ProtectionDomain domain) throws Exception {
+ Class clazz = super.defineClass(name, b, 0, b.length, domain);
+ return clazz;
+ }
+
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency.nullable;
+
+/**
+ * Reprensent of method description.
+ * The goal of this class, is to be able to generate a proxy class, or a nullable class from an interface.
+ * @author Clement Escoffier
+ *
+ */
+public class MethodSignature {
+
+ /**
+ * Nmae of the method.
+ */
+ private String m_name;
+
+ /**
+ * Descriptor of the method.
+ */
+ private String m_desc;
+
+ /**
+ * Signature of the method.
+ */
+ private String m_signature;
+
+ /**
+ * Exception thored by the method.
+ */
+ private String[] m_exception;
+
+ /**
+ * MethodSignature constructor.
+ * Describe a method.
+ * @param name : name of the method
+ * @param desc : descriptor of the method
+ * @param sign : signature of the method
+ * @param exc : exception throwed by the method
+ */
+ public MethodSignature(String name, String desc, String sign, String[] exc) {
+ m_name = name;
+ m_desc = desc;
+ m_signature = sign;
+ m_exception = exc;
+ }
+
+ /**
+ * @return the description of the method.
+ */
+ public String getDesc() {
+ return m_desc;
+ }
+
+ /**
+ * @return the String array of exception throwed by the method.
+ */
+ public String[] getException() {
+ return m_exception;
+ }
+
+ /**
+ * @return the name of the method.
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * @return the signature of the method.
+ */
+ public String getSignature() {
+ return m_signature;
+ }
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency.nullable;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/** This class implement a class visitor. It store all method signature of
+ * the visited interface. Then it returns these class signatures for the proxy
+ * generation or the nullable class.
+ * Date : 4/9/2005
+ * @author Clement Escoffier
+ */
+public class MethodSignatureVisitor implements ClassVisitor, Opcodes {
+
+ /**
+ * Array of method signature.
+ */
+ private MethodSignature[] m_methods;
+
+
+ /**
+ * Constructor.
+ */
+ public MethodSignatureVisitor() { }
+
+ /**
+ * Visit a method, store the information about the method.
+ * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+ * @param access : Access modifier
+ * @param name : name of the visited method
+ * @param signature : singature of the visited element (null if not generic)
+ * @param desc : descriptor of the method
+ * @param exceptions : execption clause
+ * @return always null (not code visitor needed)
+ */
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ //Store method signature for each visited method
+ m_methods = addMethod(m_methods, new MethodSignature(name, desc, signature, exceptions));
+ return null;
+ }
+
+ /**
+ * @return the mthod signature array.
+ */
+ public MethodSignature[] getMethods() {
+ return m_methods;
+ }
+
+ /**
+ * Return the new array of Method Signature by adding the given list and the given element.
+ * @param list : the current array
+ * @param method : the element to add
+ * @return the new array
+ */
+ public static MethodSignature[] addMethod(MethodSignature[] list, MethodSignature method) {
+ if (list != null) {
+ MethodSignature[] newList = new MethodSignature[list.length + 1];
+ System.arraycopy(list, 0, newList, 0, list.length);
+ newList[list.length] = method;
+ return newList;
+ }
+ else {
+ list = new MethodSignature[] {method};
+ return list;
+ }
+
+ }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+ */
+ public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+ */
+ public void visitSource(String arg0, String arg1) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void visitOuterClass(String arg0, String arg1, String arg2) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+ */
+ public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { return null; }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+ */
+ public void visitAttribute(Attribute arg0) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)
+ */
+ public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) { }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+ */
+ public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) { return null; }
+
+ /**
+ * @see org.objectweb.asm.ClassVisitor#visitEnd()
+ */
+ public void visitEnd() { }
+
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.dependency.nullable;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/** Create the proxy class.
+ * @author clément
+ */
+public class NullableObjectWriter implements Opcodes {
+
+ /** Return the proxy classname for the contract contractname
+ * on the service object soc.
+ * @param url URL of the needed contract
+ * @param contractName String
+ * @return byte[]
+ */
+ public static byte[] dump(URL url,
+ String contractName) {
+
+ ClassReader cr = null;
+ InputStream is = null;
+ byte[] b = null;
+ try {
+ is = url.openStream();
+ cr = new ClassReader(is);
+ MethodSignatureVisitor msv = new MethodSignatureVisitor();
+ cr.accept(msv, true);
+ is.close();
+
+ ClassWriter cw = new ClassWriter(true);
+
+ String[] segment = contractName.split("[.]");
+ String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+
+ // Create the class
+ cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, className, null,
+ "java/lang/Object", new String[]{contractName.replace('.', '/'), "org/apache/felix/ipojo/Nullable"});
+
+ // Inject a constructor <INIT>()V
+ MethodVisitor cst = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ cst.visitVarInsn(ALOAD, 0);
+ cst.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ cst.visitInsn(RETURN);
+ cst.visitMaxs(0, 0);
+ cst.visitEnd();
+
+ // Methods Generation :
+ MethodSignature[] methods = msv.getMethods();
+
+ for (int i = 0; i < methods.length; ++i) {
+ MethodSignature method = methods[i];
+ String desc = method.getDesc();
+ String name = method.getName();
+ String sign = method.getSignature();
+ String[] exc = method.getException();
+
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, sign, exc);
+
+ Type returnType = Type.getReturnType(desc);
+ // TODO : manage the other type primitive
+ // Primitive type :
+ switch (returnType.getSort()) {
+ case Type.BOOLEAN:
+ case Type.INT:
+ // Integer or Boolean : return 0 ( false)
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(IRETURN);
+ break;
+ case Type.DOUBLE:
+ // Double : return 0.0
+ mv.visitInsn(DCONST_0);
+ mv.visitInsn(DRETURN);
+ break;
+ case Type.ARRAY :
+ case Type.OBJECT :
+ // Return always null for array and object
+ mv.visitInsn(ACONST_NULL);
+ mv.visitInsn(ARETURN);
+ break;
+ case Type.VOID :
+ mv.visitInsn(RETURN);
+ break;
+ default :
+ System.err.println("Type not yet managed : " + returnType);
+ }
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ // End process
+ cw.visitEnd();
+ b = cw.toByteArray();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return b;
+ }
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import org.apache.felix.ipojo.Callback;
+
+/**
+ * This class is the implementation of callback on lifecycle transition.
+ * @author Clement Escoffier
+ *
+ */
+public class LifecycleCallback {
+
+
+ /**
+ * Metadata of the callback.
+ */
+ private LifecycleCallbackMetadata m_metadata;
+
+ /**
+ * Callback object.
+ */
+ private Callback m_callback;
+
+ /**
+ * LifecycleCallback constructor.
+ * @param hh : the callback handler calling the callback
+ * @param hm : the callback metadata
+ */
+ public LifecycleCallback(LifecycleCallbackHandler hh, LifecycleCallbackMetadata hm) {
+ m_metadata = hm;
+ m_callback = new Callback(hm.getMethod(), hm.isStatic(), hh.getComponentManager());
+ }
+
+ /**
+ * @return : the metadata of the hook
+ */
+ public LifecycleCallbackMetadata getMetadata() {
+ return m_metadata;
+ }
+
+ /**
+ * Call the hook method when the transition from inital to final state is detected.
+ * @throws NoSuchMethodException : Method is not found in the class
+ * @throws InvocationTargetException : The method is not static
+ * @throws IllegalAccessException : The method can not be invoked
+ */
+ protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ m_callback.call();
+ }
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Lifecycle callback handler.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackHandler implements Handler {
+
+ /**
+ * The list of the callback of the component.
+ */
+ private LifecycleCallback[] m_callbacks = new LifecycleCallback[0];
+
+ /**
+ * State of the component manager (unresolved at the beginning).
+ */
+ private int m_state = ComponentManager.INVALID;
+
+ /**
+ * The component manager.
+ */
+ private ComponentManager m_componentManager;
+
+ /**
+ * Add the given Hook to the hook list.
+ * @param hk : the element to add
+ */
+ private void addCallback(LifecycleCallback hk) {
+ for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+ if (m_callbacks[i] == hk) { return; }
+ }
+
+ if (m_callbacks.length > 0) {
+ LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
+ System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
+ newHk[m_callbacks.length] = hk;
+ m_callbacks = newHk;
+ }
+ else {
+ m_callbacks = new LifecycleCallback[] {hk};
+ }
+
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+ */
+ public void configure(ComponentManager cm, Element metadata) {
+ m_componentManager = cm;
+ m_callbacks = new LifecycleCallback[0];
+
+ Element[] hooksMetadata = metadata.getElements("callback");
+ for (int i = 0; i < hooksMetadata.length; i++) {
+ // Create an HookMetadata object
+ String initialState = hooksMetadata[i].getAttribute("initial");
+ String finalState = hooksMetadata[i].getAttribute("final");
+ String method = hooksMetadata[i].getAttribute("method");
+ boolean isStatic = false;
+ if (hooksMetadata[i].containsAttribute("isStatic") && hooksMetadata[i].getAttribute("isStatic").equals("true")) { isStatic = true; }
+
+ LifecycleCallbackMetadata hm = new LifecycleCallbackMetadata(initialState, finalState, method, isStatic);
+
+ LifecycleCallback hk = new LifecycleCallback(this, hm);
+ addCallback(hk);
+ }
+ if (m_callbacks.length > 0) { m_componentManager.register(this); }
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#stop()
+ */
+ public void stop() {
+ m_state = ComponentManager.INVALID;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#start()
+ */
+ public void start() {
+ Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the life cycle callback handler");
+ }
+
+ /**
+ * Do nothing.
+ * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+ */
+ public void setterCallback(String fieldName, Object value) {
+ // Do nothing
+ }
+
+ /**
+ * Do nothing, return the initial value.
+ * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+ */
+ public Object getterCallback(String fieldName, Object value) {
+ return value;
+ }
+
+ /**
+ * Return true.
+ * @see org.apache.felix.ipojo.Handler#isValid()
+ */
+ public boolean isValid() {
+ return true;
+ }
+
+ /**
+ * @return the component manager
+ */
+ protected ComponentManager getComponentManager() { return m_componentManager; }
+
+ /**
+ * When the state change call the associated hooks.
+ * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+ */
+ public void stateChanged(int state) {
+ Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] State changed in callback handler, check " + m_callbacks.length + " callbacks. Transition : " + m_state + " -> " + state);
+ for (int i = 0; i < m_callbacks.length; i++) {
+ if (m_callbacks[i].getMetadata().getInitialState() == m_state && m_callbacks[i].getMetadata().getFinalState() == state) {
+ try {
+ Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Call the callback : " + m_callbacks[i].getMetadata().getMethod());
+ m_callbacks[i].call();
+ } catch (NoSuchMethodException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not found : " + e.getMessage());
+ } catch (IllegalAccessException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not accessible : " + e.getMessage());
+ } catch (InvocationTargetException e) {
+ Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " has throws an exception : " + e.getMessage() + " -> " + e.getCause());
+ }
+ }
+ }
+ // Update to internal state
+ m_state = state;
+ }
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.callback;
+
+import org.apache.felix.ipojo.ComponentManager;
+
+/**
+ * Lifecycle callback metadata.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackMetadata {
+
+ /**
+ * Initial state of the transition.
+ */
+ private int m_initialState;
+
+ /**
+ * Final state of the transition.
+ */
+ private int m_finalState;
+
+ /**
+ * Method to call.
+ */
+ private String m_method;
+
+ /**
+ * is the method a static method ?
+ */
+ private boolean m_isStatic;
+
+ // Constructor
+
+ /**
+ * Constructor.
+ * @param initialState : initial state
+ * @param finalState : final state
+ * @param method : method name
+ * @param isStatic : is the method a static method ?
+ */
+ public LifecycleCallbackMetadata(String initialState, String finalState, String method, boolean isStatic) {
+ if (initialState.equals("VALID")) { m_initialState = ComponentManager.VALID; }
+ if (initialState.equals("INVALID")) { m_initialState = ComponentManager.INVALID; }
+ if (finalState.equals("VALID")) { m_finalState = ComponentManager.VALID; }
+ if (finalState.equals("INVALID")) { m_finalState = ComponentManager.INVALID; }
+
+ m_method = method;
+ m_isStatic = isStatic;
+ }
+
+ // Getters
+
+ /**
+ * @return Returns the m_finalState.
+ */
+ public int getFinalState() {
+ return m_finalState;
+ }
+
+ /**
+ * @return Returns the m_initialState.
+ */
+ public int getInitialState() {
+ return m_initialState;
+ }
+
+ /**
+ * @return Returns the m_isStatic.
+ */
+ public boolean isStatic() {
+ return m_isStatic;
+ }
+
+ /**
+ * @return Returns the m_method.
+ */
+ public String getMethod() {
+ return m_method;
+ }
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.providedService;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Represent a property i.e. a set : [name, type, value].
+ * A property can be attached to a field.
+ * The value of the property is thefield value.
+ * When the value change, the published value change too.
+ * Date : 5 févr. 2006
+ * @author clément
+ */
+public class Property {
+
+ /**
+ * A property is link with a service.
+ * This field represent this provided service.
+ * m_providedService : ProvidedService
+ */
+ private ProvidedService m_providedService;
+
+ /**
+ * Value of the property (before we know the type).
+ */
+ private Object m_value;
+
+ /**
+ * Metadata of the property.
+ */
+ private PropertyMetadata m_metadata;
+
+ /**
+ * Property constructor.
+ * @param ps : the provided service
+ * @param pm : metadata of the property
+ */
+ public Property(ProvidedService ps, PropertyMetadata pm) {
+ m_providedService = ps;
+ m_metadata = pm;
+
+ // Fix the type of the property if null
+ if (pm.getType() == null) {
+ // If the type is not found, it is a dynamic property
+ Element manipulation = m_providedService.getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+ String type = null;
+ String field = m_metadata.getField();
+ for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+ if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+ type = manipulation.getElements("Field")[i].getAttribute("type");
+ break;
+ }
+ }
+
+ pm.setType(type);
+ }
+
+ if (pm.getValue() != null) { setValue(pm.getValue()); }
+ }
+
+ /**
+ * @return the Object value of the property
+ */
+ protected Object get() {
+ if (m_value == null) {
+ Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] A property " + m_metadata.getName() + " can not be returned : no value assigned");
+ }
+ return m_value;
+ }
+
+
+ /**
+ * @return the property metadata.
+ */
+ public PropertyMetadata getMetadata() {
+ return m_metadata;
+ }
+
+ /**
+ * This method is automaticaly called when the value of the property is changed.
+ * Set the value of a property.
+ * @param s : the new value of the property (in String)
+ */
+ protected void set(String s) {
+ setValue(s);
+ m_providedService.update();
+ }
+
+ /**
+ * This method is called when the value of the property is changed.
+ * Set the value of a property.
+ * @param o : the new value of the property (object)
+ */
+ protected void set(Object o) {
+ m_value = o;
+ m_providedService.update();
+ }
+
+ /**
+ * Set the provided service of this property.
+ * @param ps : the provided service to attached.
+ */
+ void setProvidedService(ProvidedService ps) {
+ m_providedService = ps;
+ }
+
+ /**
+ * Set the value of the property.
+ * @param value : value of the property (String)
+ */
+ private void setValue(String value) {
+ String type = m_metadata.getType();
+
+ Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] Set the value of the property " + m_metadata.getName() + " [" + m_metadata.getType() + "] " + " with the value : " + value);
+
+ if (type.equals("string") || type.equals("String")) { m_value = new String(value); return; }
+ if (type.equals("boolean")) { m_value = new Boolean(value); return; }
+ if (type.equals("byte")) { m_value = new Byte(value); return; }
+ if (type.equals("short")) { m_value = new Short(value); return; }
+ if (type.equals("int")) { m_value = new Integer(value); return; }
+ if (type.equals("long")) { m_value = new Long(value); return; }
+ if (type.equals("float")) { m_value = new Float(value); return; }
+ if (type.equals("double")) { m_value = new Double(value); return; }
+
+ // Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+ try {
+ Class c = m_providedService.getComponentManager().getContext().getBundle().loadClass(type);
+ //Class string = m_providedService.getComponentManager().getContext().getBundle().loadClass("java.lang.String");
+ Constructor cst = c.getConstructor(new Class[] {String.class});
+ m_value = cst.newInstance(new Object[] {value});
+ } catch (ClassNotFoundException e) {
+ System.err.println("Class not found exception in setValue on " + type);
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ System.err.println("Constructor not found exeption in setValue on " + type);
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ System.err.println("Argument problem to call the constructor of the type " + type);
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ System.err.println("Instantiation problem " + type);
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ System.err.println("Invocation problem " + type);
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return the value of the property.
+ */
+ public Object getValue() { return m_value; }
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.providedService;
+
+/**
+ * Property metadata : either static either dynamic.
+ * @author Clement Escoffier
+ */
+public class PropertyMetadata {
+
+ /**
+ * Field of the property.
+ */
+ private String m_field;
+
+ /**
+ * Name of the property.
+ */
+ private String m_name;
+
+ /**
+ * Type of the property.
+ */
+ private String m_type;
+
+ /**
+ * String value of the property (initial value).
+ */
+ private String m_value;
+
+ //Constructor
+
+ /**
+ * Constructor.
+ * @param name : name of the property
+ * @param field : field of the property
+ * @param type : type of the property
+ * @param value : initial value of the property
+ */
+ public PropertyMetadata(String name, String field, String type, String value) {
+ m_name = name;
+ m_field = field;
+ m_type = type;
+ m_value = value;
+
+ // Dynamic property case :
+ if (m_field != null) {
+ if (m_name == null) { m_name = m_field; }
+ }
+ }
+
+ /**
+ * @return the field name.
+ */
+ public String getField() { return m_field; };
+
+ /**
+ * @return the property name.
+ */
+ public String getName() { return m_name; };
+
+ /**
+ * @return the type of the property.
+ */
+ public String getType() { return m_type; };
+
+ /**
+ * @return the initial value.
+ */
+ public String getValue() { return m_value; }
+
+ /**
+ * Set the type of the property (dynamic property only).
+ * @param type : the type of the property.
+ */
+ public void setType(String type) { m_type = type; }
+
+
+}
Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
------------------------------------------------------------------------------
svn:eol-style = native