Author: abroekhuis
Date: Tue Jul  5 09:17:58 2011
New Revision: 1142936

URL: http://svn.apache.org/viewvc?rev=1142936&view=rev
Log:
Updated framework to support service factories

Added:
    incubator/celix/trunk/framework/private/include/service_factory.h   (with 
props)
Modified:
    incubator/celix/trunk/framework/private/include/bundle_context.h
    incubator/celix/trunk/framework/private/include/framework.h
    incubator/celix/trunk/framework/private/include/headers.h
    incubator/celix/trunk/framework/private/include/service_registration.h
    incubator/celix/trunk/framework/private/include/service_registry.h
    incubator/celix/trunk/framework/private/src/bundle_context.c
    incubator/celix/trunk/framework/private/src/framework.c
    incubator/celix/trunk/framework/private/src/service_registration.c
    incubator/celix/trunk/framework/private/src/service_registry.c

Modified: incubator/celix/trunk/framework/private/include/bundle_context.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/bundle_context.h?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/bundle_context.h (original)
+++ incubator/celix/trunk/framework/private/include/bundle_context.h Tue Jul  5 
09:17:58 2011
@@ -27,6 +27,7 @@
 #define BUNDLE_CONTEXT_H_
 
 #include "headers.h"
+#include "service_factory.h"
 
 celix_status_t bundleContext_create(FRAMEWORK framework, BUNDLE bundle, 
BUNDLE_CONTEXT *bundle_context);
 celix_status_t bundleContext_destroy(BUNDLE_CONTEXT context);
@@ -39,6 +40,8 @@ celix_status_t bundleContext_installBund
 
 celix_status_t bundleContext_registerService(BUNDLE_CONTEXT context, char * 
serviceName, void * svcObj,
         PROPERTIES properties, SERVICE_REGISTRATION *service_registration);
+celix_status_t bundleContext_registerServiceFactory(BUNDLE_CONTEXT context, 
char * serviceName, service_factory_t factory,
+        PROPERTIES properties, SERVICE_REGISTRATION *service_registration);
 
 celix_status_t bundleContext_getServiceReferences(BUNDLE_CONTEXT context, char 
* serviceName, char * filter, ARRAY_LIST *service_references);
 celix_status_t bundleContext_getServiceReference(BUNDLE_CONTEXT context, char 
* serviceName, SERVICE_REFERENCE *service_reference);

Modified: incubator/celix/trunk/framework/private/include/framework.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/framework.h?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/framework.h (original)
+++ incubator/celix/trunk/framework/private/include/framework.h Tue Jul  5 
09:17:58 2011
@@ -32,6 +32,7 @@
 #include "hash_map.h"
 #include "array_list.h"
 #include "celix_errno.h"
+#include "service_factory.h"
 
 celix_status_t framework_create(FRAMEWORK *framework, apr_pool_t *memoryPool);
 celix_status_t framework_destroy(FRAMEWORK framework);
@@ -50,6 +51,7 @@ celix_status_t framework_updateBundle(FR
 void fw_stopBundle(FRAMEWORK framework, BUNDLE bundle, bool record);
 
 celix_status_t fw_registerService(FRAMEWORK framework, SERVICE_REGISTRATION * 
registration, BUNDLE bundle, char * serviceName, void * svcObj, PROPERTIES 
properties);
+celix_status_t fw_registerServiceFactory(FRAMEWORK framework, 
SERVICE_REGISTRATION * registration, BUNDLE bundle, char * serviceName, 
service_factory_t factory, PROPERTIES properties);
 void fw_unregisterService(SERVICE_REGISTRATION registration);
 
 celix_status_t fw_getServiceReferences(FRAMEWORK framework, ARRAY_LIST 
*references, BUNDLE bundle, char * serviceName, char * filter);

Modified: incubator/celix/trunk/framework/private/include/headers.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/headers.h?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/headers.h (original)
+++ incubator/celix/trunk/framework/private/include/headers.h Tue Jul  5 
09:17:58 2011
@@ -30,6 +30,10 @@
 #include <dirent.h>
 #include <pthread.h>
 
+#include <apr_general.h>
+#include <apr_thread_cond.h>
+#include <apr_thread_mutex.h>
+
 #include "array_list.h"
 #include "properties.h"
 #include "linkedlist.h"
@@ -41,10 +45,6 @@
 #include "bundle_state.h"
 #include "bundle_cache.h"
 
-#include <apr_general.h>
-#include <apr_thread_cond.h>
-#include <apr_thread_mutex.h>
-
 #if defined(__GNUC__)
 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
 #else
@@ -159,6 +159,9 @@ struct serviceRegistration {
 
        pthread_mutex_t mutex;
        bool isUnregistering;
+
+       bool isServiceFactory;
+       void *serviceFactory;
 };
 
 typedef struct serviceRegistration * SERVICE_REGISTRATION;

Added: incubator/celix/trunk/framework/private/include/service_factory.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/service_factory.h?rev=1142936&view=auto
==============================================================================
--- incubator/celix/trunk/framework/private/include/service_factory.h (added)
+++ incubator/celix/trunk/framework/private/include/service_factory.h Tue Jul  
5 09:17:58 2011
@@ -0,0 +1,42 @@
+/**
+ *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.
+ */
+/*
+ * service_factory.h
+ *
+ *  Created on: Jun 26, 2011
+ *      Author: alexander
+ */
+
+#ifndef SERVICE_FACTORY_H_
+#define SERVICE_FACTORY_H_
+
+#include <apr_general.h>
+
+#include "celix_errno.h"
+#include "headers.h"
+
+struct service_factory {
+    void *factory;
+    celix_status_t (*getService)(void *factory, BUNDLE bundle, 
SERVICE_REGISTRATION registration, void **service);
+    celix_status_t (*ungetService)(void *factory, BUNDLE bundle, 
SERVICE_REGISTRATION registration);
+};
+
+typedef struct service_factory * service_factory_t;
+
+#endif /* SERVICE_FACTORY_H_ */

Propchange: incubator/celix/trunk/framework/private/include/service_factory.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/celix/trunk/framework/private/include/service_registration.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/service_registration.h?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/service_registration.h 
(original)
+++ incubator/celix/trunk/framework/private/include/service_registration.h Tue 
Jul  5 09:17:58 2011
@@ -32,10 +32,13 @@
 #include "service_registry.h"
 
 SERVICE_REGISTRATION serviceRegistration_create(SERVICE_REGISTRY registry, 
BUNDLE bundle, char * serviceName, long serviceId, void * serviceObject, 
PROPERTIES dictionary);
+SERVICE_REGISTRATION serviceRegistration_createServiceFactory(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, long serviceId, void * 
serviceObject, PROPERTIES dictionary);
 void serviceRegistration_destroy(SERVICE_REGISTRATION registration);
 
 bool serviceRegistration_isValid(SERVICE_REGISTRATION registration);
 void serviceRegistration_invalidate(SERVICE_REGISTRATION registration);
 void serviceRegistration_unregister(SERVICE_REGISTRATION registration);
 
+celix_status_t serviceRegistration_getService(SERVICE_REGISTRATION 
registration, BUNDLE bundle, void **service);
+
 #endif /* SERVICE_REGISTRATION_H_ */

Modified: incubator/celix/trunk/framework/private/include/service_registry.h
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/service_registry.h?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/service_registry.h 
(original)
+++ incubator/celix/trunk/framework/private/include/service_registry.h Tue Jul  
5 09:17:58 2011
@@ -31,11 +31,13 @@
 #include "headers.h"
 #include "properties.h"
 #include "filter.h"
+#include "service_factory.h"
 
 SERVICE_REGISTRY serviceRegistry_create(FRAMEWORK framework, void 
(*serviceChanged)(FRAMEWORK, SERVICE_EVENT, PROPERTIES));
 celix_status_t serviceRegistry_destroy(SERVICE_REGISTRY registry);
 ARRAY_LIST serviceRegistry_getRegisteredServices(SERVICE_REGISTRY registry, 
BUNDLE bundle);
 SERVICE_REGISTRATION serviceRegistry_registerService(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES 
dictionary);
+SERVICE_REGISTRATION serviceRegistry_registerServiceFactory(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, service_factory_t factory, 
PROPERTIES dictionary);
 void serviceRegistry_unregisterService(SERVICE_REGISTRY registry, BUNDLE 
bundle, SERVICE_REGISTRATION registration);
 void serviceRegistry_unregisterServices(SERVICE_REGISTRY registry, BUNDLE 
bundle);
 ARRAY_LIST serviceRegistry_getServiceReferences(SERVICE_REGISTRY registry, 
char * serviceName, FILTER filter);

Modified: incubator/celix/trunk/framework/private/src/bundle_context.c
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/bundle_context.c?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/bundle_context.c (original)
+++ incubator/celix/trunk/framework/private/src/bundle_context.c Tue Jul  5 
09:17:58 2011
@@ -149,6 +149,21 @@ celix_status_t bundleContext_registerSer
        return status;
 }
 
+celix_status_t bundleContext_registerServiceFactory(BUNDLE_CONTEXT context, 
char * serviceName, service_factory_t factory,
+        PROPERTIES properties, SERVICE_REGISTRATION *service_registration) {
+    SERVICE_REGISTRATION registration = NULL;
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && *service_registration == NULL) {
+        fw_registerServiceFactory(context->framework, &registration, 
context->bundle, serviceName, factory, properties);
+        *service_registration = registration;
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    return status;
+}
+
 celix_status_t bundleContext_getServiceReferences(BUNDLE_CONTEXT context, char 
* serviceName, char * filter, ARRAY_LIST *service_references) {
     ARRAY_LIST references = NULL;
     celix_status_t status = CELIX_SUCCESS;

Modified: incubator/celix/trunk/framework/private/src/framework.c
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/framework.c?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/framework.c (original)
+++ incubator/celix/trunk/framework/private/src/framework.c Tue Jul  5 09:17:58 
2011
@@ -889,6 +889,27 @@ celix_status_t fw_registerService(FRAMEW
        return CELIX_SUCCESS;
 }
 
+celix_status_t fw_registerServiceFactory(FRAMEWORK framework, 
SERVICE_REGISTRATION *registration, BUNDLE bundle, char * serviceName, 
service_factory_t factory, PROPERTIES properties) {
+    if (serviceName == NULL) {
+        printf("Service name cannot be null");
+        return CELIX_ILLEGAL_ARGUMENT;
+    } else if (factory == NULL) {
+        printf("Service factory cannot be null");
+        return CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    celix_status_t lock = framework_acquireBundleLock(framework, bundle, 
BUNDLE_STARTING|BUNDLE_ACTIVE);
+    if (lock != CELIX_SUCCESS) {
+        printf("Can only register services while bundle is active or 
starting");
+        framework_releaseBundleLock(framework, bundle);
+        return CELIX_ILLEGAL_STATE;
+    }
+    *registration = 
serviceRegistry_registerServiceFactory(framework->registry, bundle, 
serviceName, factory, properties);
+    framework_releaseBundleLock(framework, bundle);
+
+    return CELIX_SUCCESS;
+}
+
 celix_status_t fw_getServiceReferences(FRAMEWORK framework, ARRAY_LIST 
*references, BUNDLE bundle ATTRIBUTE_UNUSED, char * serviceName, char * 
sfilter) {
        FILTER filter = NULL;
        if (sfilter != NULL) {

Modified: incubator/celix/trunk/framework/private/src/service_registration.c
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/service_registration.c?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/service_registration.c 
(original)
+++ incubator/celix/trunk/framework/private/src/service_registration.c Tue Jul  
5 09:17:58 2011
@@ -28,12 +28,31 @@
 
 #include "service_registration.h"
 #include "constants.h"
+#include "service_factory.h"
+
+celix_status_t serviceRegistration_createInternal(SERVICE_REGISTRY registry, 
BUNDLE bundle, char * serviceName, long serviceId,
+        void * serviceObject, PROPERTIES dictionary, bool isFactory, 
SERVICE_REGISTRATION *registration);
 
 SERVICE_REGISTRATION serviceRegistration_create(SERVICE_REGISTRY registry, 
BUNDLE bundle, char * serviceName, long serviceId, void * serviceObject, 
PROPERTIES dictionary) {
-       SERVICE_REGISTRATION registration = (SERVICE_REGISTRATION) 
malloc(sizeof(*registration));
+    SERVICE_REGISTRATION registration = NULL;
+       serviceRegistration_createInternal(registry, bundle, serviceName, 
serviceId, serviceObject, dictionary, false, &registration);
+       return registration;
+}
+
+SERVICE_REGISTRATION serviceRegistration_createServiceFactory(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, long serviceId, void * 
serviceObject, PROPERTIES dictionary) {
+    SERVICE_REGISTRATION registration = NULL;
+    serviceRegistration_createInternal(registry, bundle, serviceName, 
serviceId, serviceObject, dictionary, true, &registration);
+    return registration;
+}
 
-       registration->registry = registry;
-       registration->className = serviceName;
+celix_status_t serviceRegistration_createInternal(SERVICE_REGISTRY registry, 
BUNDLE bundle, char * serviceName, long serviceId,
+        void * serviceObject, PROPERTIES dictionary, bool isFactory, 
SERVICE_REGISTRATION *registration) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *registration = (SERVICE_REGISTRATION) malloc(sizeof(**registration));
+    (*registration)->isServiceFactory = isFactory;
+    (*registration)->registry = registry;
+    (*registration)->className = serviceName;
 
        if (dictionary == NULL) {
                dictionary = properties_create();
@@ -44,21 +63,26 @@ SERVICE_REGISTRATION serviceRegistration
        properties_set(dictionary, (char *) SERVICE_ID, sId);
        properties_set(dictionary, (char *) OBJECTCLASS, serviceName);
 
-       registration->properties = dictionary;
+       (*registration)->properties = dictionary;
 
-       registration->serviceId = serviceId;
-       registration->svcObj = serviceObject;
+       (*registration)->serviceId = serviceId;
+       (*registration)->svcObj = serviceObject;
+       if (isFactory) {
+           (*registration)->serviceFactory = (service_factory_t) 
(*registration)->svcObj;
+       } else {
+           (*registration)->serviceFactory = NULL;
+       }
 
        SERVICE_REFERENCE reference = (SERVICE_REFERENCE) 
malloc(sizeof(*reference));
        reference->bundle = bundle;
-       reference->registration = registration;
+       reference->registration = *registration;
 
-       registration->reference = reference;
+       (*registration)->reference = reference;
 
-       registration->isUnregistering = false;
-       pthread_mutex_init(&registration->mutex, NULL);
+       (*registration)->isUnregistering = false;
+       pthread_mutex_init(&(*registration)->mutex, NULL);
 
-       return registration;
+       return CELIX_SUCCESS;
 }
 
 void serviceRegistration_destroy(SERVICE_REGISTRATION registration) {
@@ -102,3 +126,13 @@ void serviceRegistration_unregister(SERV
 //     registration->svcObj = NULL;
 //     pthread_mutex_unlock(&registration->mutex);
 }
+
+celix_status_t serviceRegistration_getService(SERVICE_REGISTRATION 
registration, BUNDLE bundle, void **service) {
+    if (registration->isServiceFactory) {
+        service_factory_t factory = registration->serviceFactory;
+        factory->getService(registration->serviceFactory, bundle, 
registration, service);
+    } else {
+        (*service) = registration->svcObj;
+    }
+    return CELIX_SUCCESS;
+}

Modified: incubator/celix/trunk/framework/private/src/service_registry.c
URL: 
http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/service_registry.c?rev=1142936&r1=1142935&r2=1142936&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/service_registry.c (original)
+++ incubator/celix/trunk/framework/private/src/service_registry.c Tue Jul  5 
09:17:58 2011
@@ -38,6 +38,8 @@ struct usageCount {
 
 typedef struct usageCount * USAGE_COUNT;
 
+celix_status_t serviceRegistry_registerServiceInternal(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES 
dictionary, bool isFactory, SERVICE_REGISTRATION *registration);
+
 USAGE_COUNT serviceRegistry_getUsageCount(SERVICE_REGISTRY registry, BUNDLE 
bundle, SERVICE_REFERENCE reference) {
        ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
        int i;
@@ -131,17 +133,31 @@ ARRAY_LIST serviceRegistry_getRegistered
 }
 
 SERVICE_REGISTRATION serviceRegistry_registerService(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES 
dictionary) {
-       SERVICE_REGISTRATION reg = NULL;
+    SERVICE_REGISTRATION registration = NULL;
+    serviceRegistry_registerServiceInternal(registry, bundle, serviceName, 
serviceObject, dictionary, false, &registration);
+    return registration;
+}
+
+SERVICE_REGISTRATION serviceRegistry_registerServiceFactory(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, service_factory_t factory, 
PROPERTIES dictionary) {
+    SERVICE_REGISTRATION registration = NULL;
+    serviceRegistry_registerServiceInternal(registry, bundle, serviceName, 
(void *) factory, dictionary, true, &registration);
+    return registration;
+}
 
+celix_status_t serviceRegistry_registerServiceInternal(SERVICE_REGISTRY 
registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES 
dictionary, bool isFactory, SERVICE_REGISTRATION *registration) {
        pthread_mutex_lock(&registry->mutex);
 
-       reg = serviceRegistration_create(registry, bundle, serviceName, 
++registry->currentServiceId, serviceObject, dictionary);
+       if (isFactory) {
+           *registration = serviceRegistration_createServiceFactory(registry, 
bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+       } else {
+           *registration = serviceRegistration_create(registry, bundle, 
serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+       }
 
        ARRAY_LIST regs = (ARRAY_LIST) 
hashMap_get(registry->serviceRegistrations, bundle);
        if (regs == NULL) {
                regs = arrayList_create();
        }
-       arrayList_add(regs, reg);
+       arrayList_add(regs, *registration);
        hashMap_put(registry->serviceRegistrations, bundle, regs);
 
        pthread_mutex_unlock(&registry->mutex);
@@ -149,13 +165,13 @@ SERVICE_REGISTRATION serviceRegistry_reg
        if (registry->serviceChanged != NULL) {
                SERVICE_EVENT event = (SERVICE_EVENT) malloc(sizeof(*event));
                event->type = REGISTERED;
-               event->reference = reg->reference;
+               event->reference = (*registration)->reference;
                registry->serviceChanged(registry->framework, event, NULL);
                free(event);
                event = NULL;
        }
 
-       return reg;
+       return CELIX_SUCCESS;
 }
 
 void serviceRegistry_unregisterService(SERVICE_REGISTRY registry, BUNDLE 
bundle, SERVICE_REGISTRATION registration) {
@@ -275,7 +291,7 @@ void * serviceRegistry_getService(SERVIC
 
        pthread_mutex_lock(&registry->mutex);
 
-       if (registration->svcObj != NULL) {
+       if (serviceRegistration_isValid(registration)) {
                usage = serviceRegistry_getUsageCount(registry, bundle, 
reference);
                if (usage == NULL) {
                        usage = serviceRegistry_addUsageCount(registry, bundle, 
reference);
@@ -286,10 +302,10 @@ void * serviceRegistry_getService(SERVIC
        pthread_mutex_unlock(&registry->mutex);
 
        if ((usage != NULL) && (service == NULL)) {
-               service = registration->svcObj;
+               serviceRegistration_getService(registration, bundle, &service);
        }
        pthread_mutex_lock(&registry->mutex);
-       if ((registration->svcObj == NULL) || (service == NULL)) {
+       if ((serviceRegistration_isValid(registration)) || (service == NULL)) {
                serviceRegistry_flushUsageCount(registry, bundle, reference);
        } else {
                usage->service = service;
@@ -314,7 +330,7 @@ bool serviceRegistry_ungetService(SERVIC
        usage->count--;
 
 
-       if ((registration->svcObj == NULL) || (usage->count <= 0)) {
+       if ((serviceRegistration_isValid(registration)) || (usage->count <= 0)) 
{
                usage->service = NULL;
                serviceRegistry_flushUsageCount(registry, bundle, reference);
        }


Reply via email to