http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/attribute.c
----------------------------------------------------------------------
diff --git a/framework/src/attribute.c b/framework/src/attribute.c
new file mode 100644
index 0000000..318d8f5
--- /dev/null
+++ b/framework/src/attribute.c
@@ -0,0 +1,71 @@
+/**
+ *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.
+ */
+/*
+ * attribute.c
+ *
+ *  \date       Jul 27, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "attribute_private.h"
+#include "celix_log.h"
+
+celix_status_t attribute_create(char * key, char * value, attribute_pt 
*attribute) {
+       celix_status_t status = CELIX_SUCCESS;
+       char *error = NULL;
+
+       if (key == NULL || value == NULL || *attribute != NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+           error = "Missing required arguments and/or values";
+       } else {
+               attribute_pt attr = malloc(sizeof(*attr));
+               if (!attr) {
+                       status = CELIX_ENOMEM;
+               } else {
+                       attr->key = key;
+                       attr->value = value;
+
+                       *attribute = attr;
+               }
+       }
+
+       framework_logIfError(logger, status, error, "Could not create 
attribute: [key=%s;value=%s]", key, value);
+
+       return status;
+}
+
+celix_status_t attribute_destroy(attribute_pt attribute) {
+    free(attribute->key);
+    free(attribute->value);
+    free(attribute);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t attribute_getKey(attribute_pt attribute, char **key) {
+       *key = attribute->key;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t attribute_getValue(attribute_pt attribute, char **value) {
+       *value = attribute->value;
+       return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/attribute.h
----------------------------------------------------------------------
diff --git a/framework/src/attribute.h b/framework/src/attribute.h
new file mode 100644
index 0000000..6f41f0c
--- /dev/null
+++ b/framework/src/attribute.h
@@ -0,0 +1,39 @@
+/**
+ *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.
+ */
+/*
+ * attribute.h
+ *
+ *  \date       Jul 27, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#ifndef ATTRIBUTE_H_
+#define ATTRIBUTE_H_
+
+#include "celix_errno.h"
+
+typedef struct attribute *attribute_pt;
+
+celix_status_t attribute_create(char * key, char * value, attribute_pt 
*attribute);
+celix_status_t attribute_destroy(attribute_pt attribute);
+
+celix_status_t attribute_getKey(attribute_pt attribute, char **key);
+celix_status_t attribute_getValue(attribute_pt attribute, char **value);
+
+#endif /* ATTRIBUTE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/attribute_private.h
----------------------------------------------------------------------
diff --git a/framework/src/attribute_private.h 
b/framework/src/attribute_private.h
new file mode 100644
index 0000000..339833f
--- /dev/null
+++ b/framework/src/attribute_private.h
@@ -0,0 +1,39 @@
+/**
+ *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.
+ */
+/*
+ * attribute_private.h
+ *
+ *  \date       Feb 11, 2013
+ *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#ifndef ATTRIBUTE_PRIVATE_H_
+#define ATTRIBUTE_PRIVATE_H_
+
+#include "attribute.h"
+
+struct attribute {
+       char * key;
+       char * value;
+};
+
+
+#endif /* ATTRIBUTE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle.c b/framework/src/bundle.c
new file mode 100644
index 0000000..a0e6b3d
--- /dev/null
+++ b/framework/src/bundle.c
@@ -0,0 +1,695 @@
+/**
+ *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.
+ */
+/*
+ * bundle.c
+ *
+ *  \date       Mar 23, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "framework_private.h"
+#include "bundle_private.h"
+#include "resolver.h"
+#include "utils.h"
+
+celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module);
+celix_status_t bundle_closeRevisions(bundle_pt bundle);
+
+celix_status_t bundle_create(bundle_pt * bundle) {
+    celix_status_t status;
+    bundle_archive_pt archive = NULL;
+
+       *bundle = (bundle_pt) malloc(sizeof(**bundle));
+       if (*bundle == NULL) {
+               return CELIX_ENOMEM;
+       }
+       status = bundleArchive_createSystemBundleArchive(&archive);
+       if (status == CELIX_SUCCESS) {
+        module_pt module;
+
+        (*bundle)->archive = archive;
+        (*bundle)->activator = NULL;
+        (*bundle)->context = NULL;
+        (*bundle)->framework = NULL;
+        (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+        (*bundle)->modules = NULL;
+        arrayList_create(&(*bundle)->modules);
+        (*bundle)->handle = NULL;
+        (*bundle)->manifest = NULL;
+
+        module = module_createFrameworkModule((*bundle));
+        bundle_addModule(*bundle, module);
+
+        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
+        if (status != CELIX_SUCCESS) {
+               status = CELIX_ILLEGAL_STATE;
+        } else {
+                       (*bundle)->lockCount = 0;
+                       (*bundle)->lockThread = celix_thread_default;
+        }
+       }
+       framework_logIfError(logger, status, NULL, "Failed to create bundle");
+
+       return status;
+}
+
+celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt 
framework, bundle_archive_pt archive) {
+    module_pt module;
+       
+       celix_status_t status;
+
+       *bundle = (bundle_pt) malloc(sizeof(**bundle));
+       if (*bundle == NULL) {
+               return CELIX_ENOMEM;
+       }
+       (*bundle)->archive = archive;
+       (*bundle)->activator = NULL;
+       (*bundle)->context = NULL;
+       (*bundle)->handle = NULL;
+       (*bundle)->manifest = NULL;
+       (*bundle)->framework = framework;
+       (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+       (*bundle)->modules = NULL;
+       arrayList_create(&(*bundle)->modules);
+       
+       status = bundle_createModule(*bundle, &module);
+       if (status == CELIX_SUCCESS) {
+               bundle_addModule(*bundle, module);
+        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
+        if (status != CELIX_SUCCESS) {
+                       status = CELIX_ILLEGAL_STATE;
+               } else {
+                       (*bundle)->lockCount = 0;
+                       (*bundle)->lockThread = celix_thread_default;
+               }
+       } else {
+           status = CELIX_FILE_IO_EXCEPTION;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to create bundle");
+
+       return status;
+}
+
+celix_status_t bundle_destroy(bundle_pt bundle) {
+       array_list_iterator_pt iter = arrayListIterator_create(bundle->modules);
+       while (arrayListIterator_hasNext(iter)) {
+               module_pt module = arrayListIterator_next(iter);
+               module_destroy(module);
+       }
+       arrayListIterator_destroy(iter);
+       arrayList_destroy(bundle->modules);
+       celixThreadMutex_destroy(&bundle->lock);
+
+       free(bundle);
+
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) 
{
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (bundle != NULL && *archive == NULL) {
+               *archive = bundle->archive;
+       } else {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get bundle 
archive");
+
+       return status;
+}
+
+celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (bundle == NULL || arrayList_size(bundle->modules)==0 ) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *module = arrayList_get(bundle->modules, 
arrayList_size(bundle->modules) - 1);
+       }
+
+       return status;
+}
+
+array_list_pt bundle_getModules(bundle_pt bundle) {
+    return bundle->modules;
+}
+
+void * bundle_getHandle(bundle_pt bundle) {
+       return bundle->handle;
+}
+
+void bundle_setHandle(bundle_pt bundle, void * handle) {
+       bundle->handle = handle;
+}
+
+activator_pt bundle_getActivator(bundle_pt bundle) {
+       return bundle->activator;
+}
+
+celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) {
+       bundle->activator = activator;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) 
{
+       *context = bundle->context;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) {
+       bundle->context = context;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** 
entry) {
+       return framework_getBundleEntry(bundle->framework, bundle, name, entry);
+}
+
+celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) {
+       if(bundle==NULL){
+               *state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
+               return CELIX_BUNDLE_EXCEPTION;
+       }
+       *state = bundle->state;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) {
+       bundle->state = state;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) {
+       celix_status_t status = CELIX_SUCCESS;
+       bundle_archive_pt archive = NULL;
+       bundle_revision_pt revision = NULL;
+       manifest_pt headerMap = NULL;
+
+       status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
+       status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, 
&revision));
+       status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, 
&headerMap));
+       if (status == CELIX_SUCCESS) {
+               long bundleId = 0;
+        status = bundleArchive_getId(bundle->archive, &bundleId);
+        if (status == CELIX_SUCCESS) {
+                       int revision = 0;
+                       char moduleId[512];
+
+                       snprintf(moduleId, sizeof(moduleId), "%ld.%d", 
bundleId, revision);
+                       *module = module_create(headerMap, moduleId, bundle);
+
+                       if (*module != NULL) {
+                               version_pt bundleVersion = 
module_getVersion(*module);
+                               const char * symName = NULL;
+                               status = module_getSymbolicName(*module, 
&symName);
+                               if (status == CELIX_SUCCESS) {
+                                       array_list_pt bundles = 
framework_getBundles(bundle->framework);
+                                       unsigned int i;
+                                       for (i = 0; i < 
arrayList_size(bundles); i++) {
+                                               bundle_pt check = (bundle_pt) 
arrayList_get(bundles, i);
+
+                                               long id;
+                                               if 
(bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) {
+                                                       if (id != bundleId) {
+                                                               module_pt mod = 
NULL;
+                                                               const char * 
sym = NULL;
+                                                               version_pt 
version;
+                                                               int cmp;
+                                                               status = 
bundle_getCurrentModule(check, &mod);
+                                                               status = 
module_getSymbolicName(mod, &sym);
+
+                                                               version = 
module_getVersion(mod);
+                                                               
version_compareTo(bundleVersion, version, &cmp);
+                                                               if ((symName != 
NULL) && (sym != NULL) && !strcmp(symName, sym) &&
+                                                                               
!cmp) {
+                                                                       char 
*versionString = NULL;
+                                                                       
version_toString(version, &versionString);
+                                                                       
printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, 
versionString);
+                                                                       
free(versionString);
+                                                                       status 
= CELIX_BUNDLE_EXCEPTION;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       arrayList_destroy(bundles);
+                               }
+                       }
+        }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to create module");
+
+       return status;
+}
+
+celix_status_t bundle_start(bundle_pt bundle) {
+       return bundle_startWithOptions(bundle, 0);
+}
+
+celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) {
+       celix_status_t status = CELIX_SUCCESS;
+    if (bundle != NULL) {
+       bool systemBundle = false;
+       status = bundle_isSystemBundle(bundle, &systemBundle);
+       if (status == CELIX_SUCCESS) {
+               if (systemBundle) {
+                       framework_start(bundle->framework);
+               } else {
+                       status = fw_startBundle(bundle->framework, bundle, 
options);
+               }
+       }
+    }
+
+       framework_logIfError(logger, status, NULL, "Failed to start bundle");
+
+    return status;
+}
+
+celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (bundle != NULL) {
+               bool systemBundle = false;
+               status = bundle_isSystemBundle(bundle, &systemBundle);
+               if (status == CELIX_SUCCESS) {
+                       if (systemBundle) {
+                               // #TODO: Support framework update
+                               status = CELIX_BUNDLE_EXCEPTION;
+                       } else {
+                               status = 
framework_updateBundle(bundle->framework, bundle, inputFile);
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to update bundle");
+
+       return status;
+}
+
+celix_status_t bundle_stop(bundle_pt bundle) {
+       return bundle_stopWithOptions(bundle, 0);
+}
+
+celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (bundle != NULL) {
+               bool systemBundle = false;
+               status = bundle_isSystemBundle(bundle, &systemBundle);
+               if (status == CELIX_SUCCESS) {
+                       if (systemBundle) {
+                               framework_stop(bundle->framework);
+                       } else {
+                               status = fw_stopBundle(bundle->framework, 
bundle, options);
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to stop bundle");
+
+       return status;
+}
+
+celix_status_t bundle_uninstall(bundle_pt bundle) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (bundle != NULL) {
+               bool systemBundle = false;
+               status = bundle_isSystemBundle(bundle, &systemBundle);
+               if (status == CELIX_SUCCESS) {
+                       if (systemBundle) {
+                               status = CELIX_BUNDLE_EXCEPTION;
+                       } else {
+                               status = fw_uninstallBundle(bundle->framework, 
bundle);
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to uninstall 
bundle");
+
+       return status;
+}
+
+celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) {
+       celix_status_t status;
+       bool systemBundle;
+
+       status = bundle_isSystemBundle(bundle, &systemBundle);
+       if (status == CELIX_SUCCESS) {
+               if (!systemBundle) {
+                       status = 
bundleArchive_setPersistentState(bundle->archive, 
OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to set persistent 
state to inactive");
+
+       return status;
+}
+
+celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) {
+       celix_status_t status;
+       bool systemBundle;
+
+       status = bundle_isSystemBundle(bundle, &systemBundle);
+       if (status == CELIX_SUCCESS) {
+               if (!systemBundle) {
+                       status = 
bundleArchive_setPersistentState(bundle->archive, 
OSGI_FRAMEWORK_BUNDLE_UNINSTALLED);
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to set persistent 
state to uninstalled");
+
+    return status;
+}
+
+celix_status_t bundle_revise(bundle_pt bundle, const char * location, const 
char *inputFile) {
+       celix_status_t status;
+
+       bundle_archive_pt archive = NULL;
+       status = bundle_getArchive(bundle, &archive);
+       if (status == CELIX_SUCCESS) {
+               status = bundleArchive_revise(archive, location, inputFile);
+               if (status == CELIX_SUCCESS) {
+                       module_pt module;
+                       status = bundle_createModule(bundle, &module);
+                       if (status == CELIX_SUCCESS) {
+                               status = bundle_addModule(bundle, module);
+                       } else {
+                               bool rolledback;
+                               status = bundleArchive_rollbackRevise(archive, 
&rolledback);
+                               if (status == CELIX_SUCCESS) {
+                                       status = CELIX_BUNDLE_EXCEPTION;
+                               }
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to revise bundle");
+
+       return status;
+}
+
+//bool bundle_rollbackRevise(bundle_pt bundle) {
+//     module_pt module = arrayList_remove(bundle->modules, 
arrayList_set(bundle->modules) - 1);
+//     return resolver_removeModule(module);
+//}
+
+celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) {
+       arrayList_add(bundle->modules, module);
+       resolver_addModule(module);
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) {
+       celix_status_t status;
+       long bundleId;
+       bundle_archive_pt archive = NULL;
+
+       status = bundle_getArchive(bundle, &archive);
+       if (status == CELIX_SUCCESS) {
+               status = bundleArchive_getId(archive, &bundleId);
+               if (status == CELIX_SUCCESS) {
+                       *systemBundle = (bundleId == 0);
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to check if bundle 
is the systembundle");
+
+       return status;
+}
+
+celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) {
+       celix_status_t status;
+
+       status = celixThreadMutex_lock(&bundle->lock);
+       if (status != CELIX_SUCCESS) {
+               status = CELIX_BUNDLE_EXCEPTION;
+       } else {
+               bool equals;
+               status = thread_equalsSelf(bundle->lockThread, &equals);
+               if (status == CELIX_SUCCESS) {
+                       *lockable = (bundle->lockCount == 0) || (equals);
+               }
+
+               status = celixThreadMutex_unlock(&bundle->lock);
+               if (status != CELIX_SUCCESS) {
+                       status = CELIX_BUNDLE_EXCEPTION;
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to check if bundle 
is lockable");
+
+       return status;
+}
+
+celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t 
*thread) {
+       celix_status_t status;
+
+       status = celixThreadMutex_lock(&bundle->lock);
+       if (status != CELIX_SUCCESS) {
+               status = CELIX_BUNDLE_EXCEPTION;
+       } else {
+               *thread = bundle->lockThread;
+
+               status = celixThreadMutex_unlock(&bundle->lock);
+               if (status != CELIX_SUCCESS) {
+                       status = CELIX_BUNDLE_EXCEPTION;
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get locking 
thread");
+
+       return status;
+}
+
+celix_status_t bundle_lock(bundle_pt bundle, bool *locked) {
+       celix_status_t status;
+       bool equals;
+
+       celixThreadMutex_lock(&bundle->lock);
+
+       status = thread_equalsSelf(bundle->lockThread, &equals);
+       if (status == CELIX_SUCCESS) {
+               if ((bundle->lockCount > 0) && !equals) {
+                       *locked = false;
+               } else {
+                       bundle->lockCount++;
+                       bundle->lockThread = celixThread_self();
+                       *locked = true;
+               }
+       }
+
+       celixThreadMutex_unlock(&bundle->lock);
+
+       framework_logIfError(logger, status, NULL, "Failed to lock bundle");
+
+       return status;
+}
+
+celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       bool equals;
+
+       celixThreadMutex_lock(&bundle->lock);
+
+       if (bundle->lockCount == 0) {
+               *unlocked = false;
+       } else {
+               status = thread_equalsSelf(bundle->lockThread, &equals);
+               if (status == CELIX_SUCCESS) {
+                       if ((bundle->lockCount > 0) && !equals) {
+                               *unlocked = false;
+                       }
+                       else{
+                          bundle->lockCount--;
+                          if (bundle->lockCount == 0) {
+                               bundle->lockThread = celix_thread_default;
+                          }
+                          *unlocked = true;
+                  }
+          }
+       }
+
+       celixThreadMutex_unlock(&bundle->lock);
+
+       framework_logIfError(logger, status, NULL, "Failed to unlock bundle");
+
+       return status;
+}
+
+celix_status_t bundle_close(bundle_pt bundle) {
+       bundle_archive_pt archive = NULL;
+       
+       celix_status_t status;
+
+    bundle_closeModules(bundle);
+    bundle_closeRevisions(bundle);
+    status = bundle_getArchive(bundle, &archive);
+    if (status == CELIX_SUCCESS) {
+               bundleArchive_close(archive);
+    }
+
+       framework_logIfError(logger, status, NULL, "Failed to close bundle");
+
+    return status;
+}
+
+celix_status_t bundle_closeAndDelete(bundle_pt bundle) {
+       celix_status_t status;
+
+       bundle_archive_pt archive = NULL;
+
+    bundle_closeModules(bundle);
+    bundle_closeRevisions(bundle);
+    status = bundle_getArchive(bundle, &archive);
+    if (status == CELIX_SUCCESS) {
+       bundleArchive_closeAndDelete(archive);
+    }
+
+       framework_logIfError(logger, status, NULL, "Failed to close and delete 
bundle");
+
+    return status;
+}
+
+celix_status_t bundle_closeRevisions(bundle_pt bundle) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    // TODO implement this
+    return status;
+}
+
+celix_status_t bundle_closeModules(bundle_pt bundle) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    unsigned int i = 0;
+    for (i = 0; i < arrayList_size(bundle->modules); i++) {
+        module_pt module = (module_pt) arrayList_get(bundle->modules, i);
+        resolver_removeModule(module);
+        module_setWires(module, NULL);
+    }
+
+    return status;
+}
+
+celix_status_t bundle_refresh(bundle_pt bundle) {
+       celix_status_t status;
+       module_pt module;
+
+       status = bundle_closeModules(bundle);
+       if (status == CELIX_SUCCESS) {
+               arrayList_clear(bundle->modules);
+               status = bundle_createModule(bundle, &module);
+               if (status == CELIX_SUCCESS) {
+                       status = bundle_addModule(bundle, module);
+                       if (status == CELIX_SUCCESS) {
+                               bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to refresh bundle");
+
+    return status;
+}
+
+celix_status_t bundle_getBundleId(bundle_pt bundle, long *id) {
+       celix_status_t status;
+       bundle_archive_pt archive = NULL;
+       status = bundle_getArchive(bundle, &archive);
+       if (status == CELIX_SUCCESS) {
+               status = bundleArchive_getId(archive, id);
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get bundle id");
+
+       return status;
+}
+
+celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt 
*list) {
+       celix_status_t status;
+
+       status = fw_getBundleRegisteredServices(bundle->framework, bundle, 
list);
+
+       framework_logIfError(bundle->framework->logger, status, NULL, "Failed 
to get registered services");
+
+       return status;
+}
+
+celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) {
+       celix_status_t status;
+
+       status = fw_getBundleServicesInUse(bundle->framework, bundle, list);
+
+       framework_logIfError(logger, status, NULL, "Failed to get in use 
services");
+
+       return status;
+}
+
+celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (bundle != NULL && framework != NULL) {
+               bundle->framework = framework;
+       } else {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to set framework");
+
+       return status;
+}
+
+celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (bundle != NULL && *framework == NULL) {
+               *framework = bundle->framework;
+       } else {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get framework");
+
+       return status;
+}
+
+celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char 
**location){
+
+       celix_status_t status;
+
+       bundle_archive_pt archive = NULL;
+
+       status = bundle_getArchive(bundle, &archive);
+       if (status != CELIX_SUCCESS){
+               printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) 
\n");
+               return status;
+       }
+
+       status =  bundleArchive_getLocation(archive, location);
+       if (status != CELIX_SUCCESS){
+               printf("[ ERROR ]:  Bundle - getBundleLocation 
(BundleArchiveLocation) \n");
+               return status;
+       }
+
+       return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_archive.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_archive.c b/framework/src/bundle_archive.c
new file mode 100644
index 0000000..cde727e
--- /dev/null
+++ b/framework/src/bundle_archive.c
@@ -0,0 +1,792 @@
+/**
+ *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.
+ */
+/*
+ * bundle_archive.c
+ *
+ *  \date       Aug 8, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include "bundle_archive.h"
+#include "linked_list_iterator.h"
+
+struct bundleArchive {
+       long id;
+       char * location;
+       DIR *archiveRootDir;
+       char * archiveRoot;
+       linked_list_pt revisions;
+       long refreshCount;
+       time_t lastModified;
+
+       bundle_state_e persistentState;
+};
+
+static celix_status_t bundleArchive_getRevisionLocation(bundle_archive_pt 
archive, long revNr, char **revision_location);
+static celix_status_t bundleArchive_setRevisionLocation(bundle_archive_pt 
archive, const char * location, long revNr);
+
+static celix_status_t bundleArchive_initialize(bundle_archive_pt archive);
+
+static celix_status_t bundleArchive_deleteTree(bundle_archive_pt archive, 
const char * directory);
+
+static celix_status_t 
bundleArchive_createRevisionFromLocation(bundle_archive_pt archive, const char 
*location, const char *inputFile, long revNr, bundle_revision_pt 
*bundle_revision);
+static celix_status_t bundleArchive_reviseInternal(bundle_archive_pt archive, 
bool isReload, long revNr, const char * location, const char *inputFile);
+
+static celix_status_t bundleArchive_readLastModified(bundle_archive_pt 
archive, time_t *time);
+static celix_status_t bundleArchive_writeLastModified(bundle_archive_pt 
archive);
+
+celix_status_t bundleArchive_createSystemBundleArchive(bundle_archive_pt 
*bundle_archive) {
+       celix_status_t status = CELIX_SUCCESS;
+       char *error = NULL;
+       bundle_archive_pt archive = NULL;
+
+       if (*bundle_archive != NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+               error = "Missing required arguments and/or incorrect values";
+       } else {
+               archive = (bundle_archive_pt) calloc(1,sizeof(*archive));
+               if (archive == NULL) {
+                       status = CELIX_ENOMEM;
+               } else {
+                       status = linkedList_create(&archive->revisions);
+                       if (status == CELIX_SUCCESS) {
+                               archive->id = 0l;
+                               archive->location = strdup("System Bundle");
+                               archive->archiveRoot = NULL;
+                               archive->archiveRootDir = NULL;
+                               archive->refreshCount = -1;
+                               archive->persistentState = 
OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
+                               time(&archive->lastModified);
+
+                               *bundle_archive = archive;
+                       }
+               }
+       }
+
+       if(status != CELIX_SUCCESS && archive != NULL){
+               bundleArchive_destroy(archive);
+       }
+
+       framework_logIfError(logger, status, error, "Could not create archive");
+
+       return status;
+}
+
+celix_status_t bundleArchive_create(const char *archiveRoot, long id, const 
char * location, const char *inputFile, bundle_archive_pt *bundle_archive) {
+       celix_status_t status = CELIX_SUCCESS;
+       char *error = NULL;
+       bundle_archive_pt archive = NULL;
+
+       if (*bundle_archive != NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+               error = "bundle_archive_pt must be NULL";
+       } else {
+               archive = (bundle_archive_pt) calloc(1,sizeof(*archive));
+               if (archive == NULL) {
+                       status = CELIX_ENOMEM;
+               } else {
+                       status = linkedList_create(&archive->revisions);
+                       if (status == CELIX_SUCCESS) {
+                               archive->id = id;
+                               archive->location = strdup(location);
+                               archive->archiveRootDir = NULL;
+                               archive->archiveRoot = strdup(archiveRoot);
+                               archive->refreshCount = -1;
+                               time(&archive->lastModified);
+
+                               status = bundleArchive_initialize(archive);
+                               if (status == CELIX_SUCCESS) {
+                                       status = bundleArchive_revise(archive, 
location, inputFile);
+
+                                       if (status == CELIX_SUCCESS) {
+                                               *bundle_archive = archive;
+                                       }
+                                       else{
+                                               
bundleArchive_closeAndDelete(archive);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(status != CELIX_SUCCESS && archive != NULL){
+               bundleArchive_destroy(archive);
+       }
+
+       framework_logIfError(logger, status, error, "Could not create archive");
+
+       return status;
+}
+
+celix_status_t bundleArchive_destroy(bundle_archive_pt archive) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if(archive != NULL){
+               if (archive->revisions != NULL) {
+                       linked_list_iterator_pt iter = 
linkedListIterator_create(archive->revisions, 0);
+                       while(linkedListIterator_hasNext(iter)) {
+                               bundle_revision_pt rev = 
linkedListIterator_next(iter);
+                               bundleRevision_destroy(rev);
+                       }
+                       linkedListIterator_destroy(iter);
+                       linkedList_destroy(archive->revisions);
+               }
+               if (archive->archiveRoot != NULL) {
+                       free(archive->archiveRoot);
+               }
+               if (archive->location != NULL) {
+                       free(archive->location);
+               }
+
+               free(archive);
+               archive = NULL;
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not create archive");
+
+       return status;
+}
+
+celix_status_t bundleArchive_recreate(const char * archiveRoot, 
bundle_archive_pt *bundle_archive) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       bundle_archive_pt archive = NULL;
+
+       archive = (bundle_archive_pt) calloc(1,sizeof(*archive));
+       if (archive == NULL) {
+               status = CELIX_ENOMEM;
+       } else {
+               status = linkedList_create(&archive->revisions);
+               if (status == CELIX_SUCCESS) {
+                       archive->archiveRoot = strdup(archiveRoot);
+                       archive->archiveRootDir = NULL;
+                       archive->id = -1;
+                       archive->persistentState = -1;
+                       archive->location = NULL;
+                       archive->refreshCount = -1;
+                       archive->lastModified = (time_t) NULL;
+
+                       archive->archiveRootDir = opendir(archiveRoot);
+                       if (archive->archiveRootDir == NULL) {
+                               status = CELIX_FRAMEWORK_EXCEPTION;
+                       } else {
+
+                               long idx = 0;
+                               long highestId = -1;
+                               char *location = NULL;
+
+                               struct dirent *dent = NULL;
+                               struct stat st;
+
+                errno = 0;
+                dent = readdir(archive->archiveRootDir);
+                               while (errno == 0 && dent != NULL) {
+                                       char subdir[512];
+                                       snprintf(subdir, 512, "%s/%s", 
archiveRoot, dent->d_name);
+                                       int rv = stat(subdir, &st);
+                                       if (rv == 0 && S_ISDIR(st.st_mode) && 
(strncmp(dent->d_name, "version", 7) == 0)) {
+                                               sscanf(dent->d_name, 
"version%*d.%ld", &idx);
+                                               if (idx > highestId) {
+                                                       highestId = idx;
+                                               }
+                                       }
+                    errno = 0;
+                    dent = readdir(archive->archiveRootDir);
+                               }
+
+                               status = CELIX_DO_IF(status, 
bundleArchive_getRevisionLocation(archive, 0, &location));
+                               status = CELIX_DO_IF(status, 
bundleArchive_reviseInternal(archive, true, highestId, location, NULL));
+                               if (location) {
+                                       free(location);
+                               }
+                               if (status == CELIX_SUCCESS) {
+                                       *bundle_archive = archive;
+                               }
+                               closedir(archive->archiveRootDir);
+                       }
+               }
+       }
+
+       if(status != CELIX_SUCCESS && archive != NULL){
+               bundleArchive_destroy(archive);
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not create archive");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getId(bundle_archive_pt archive, long *id) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (archive->id < 0) {
+               FILE *bundleIdFile;
+               char id[256];
+               char bundleId[512];
+               snprintf(bundleId, sizeof(bundleId), "%s/bundle.id", 
archive->archiveRoot);
+
+               bundleIdFile = fopen(bundleId, "r");
+               if(bundleIdFile!=NULL){
+                       fgets(id, sizeof(id), bundleIdFile);
+                       fclose(bundleIdFile);
+                       sscanf(id, "%ld", &archive->id);
+               }
+               else{
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+       }
+
+       if (status == CELIX_SUCCESS) {
+               *id = archive->id;
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not get archive id");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getLocation(bundle_archive_pt archive, const char 
**location) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (archive->location == NULL) {
+               FILE *bundleLocationFile;
+               char bundleLocation[512];
+               char loc[256];
+
+               snprintf(bundleLocation, sizeof(bundleLocation), 
"%s/bundle.location", archive->archiveRoot);
+
+               bundleLocationFile = fopen(bundleLocation, "r");
+               if(bundleLocationFile!=NULL){
+                       fgets(loc, sizeof(loc), bundleLocationFile);
+                       fclose(bundleLocationFile);
+                       archive->location = strdup(loc);
+               }
+               else{
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+       }
+
+       if (status == CELIX_SUCCESS) {
+               *location = archive->location;
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not get archive 
location");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getArchiveRoot(bundle_archive_pt archive, const 
char **archiveRoot) {
+       *archiveRoot = archive->archiveRoot;
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt 
archive, long *revisionNumber) {
+       celix_status_t status = CELIX_SUCCESS;
+       bundle_revision_pt revision;
+       *revisionNumber = -1;
+
+       status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, 
&revision));
+       status = CELIX_DO_IF(status, bundleRevision_getNumber(revision, 
revisionNumber));
+
+       framework_logIfError(logger, status, NULL, "Could not get current 
revision number");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, 
bundle_revision_pt *revision) {
+       *revision = linkedList_isEmpty(archive->revisions) ? NULL : 
linkedList_getLast(archive->revisions);
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleArchive_getRevision(bundle_archive_pt archive, long 
revNr, bundle_revision_pt *revision) {
+       *revision = linkedList_get(archive->revisions, revNr);
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleArchive_getPersistentState(bundle_archive_pt archive, 
bundle_state_e *state) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (archive->persistentState != OSGI_FRAMEWORK_BUNDLE_UNKNOWN) {
+               *state = archive->persistentState;
+       } else {
+               FILE *persistentStateLocationFile;
+               char persistentStateLocation[512];
+               char stateString[256];
+               snprintf(persistentStateLocation, 
sizeof(persistentStateLocation), "%s/bundle.state", archive->archiveRoot);
+
+               persistentStateLocationFile = fopen(persistentStateLocation, 
"r");
+               if (persistentStateLocationFile == NULL) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               } else {
+                       if (fgets(stateString, sizeof(stateString), 
persistentStateLocationFile) == NULL) {
+                               status = CELIX_FILE_IO_EXCEPTION;
+                       }
+                       fclose(persistentStateLocationFile);
+               }
+
+               if (status == CELIX_SUCCESS) {
+                       if (strncmp(stateString, "active", 256) == 0) {
+                               archive->persistentState = 
OSGI_FRAMEWORK_BUNDLE_ACTIVE;
+                       } else if (strncmp(stateString, "starting", 256) == 0) {
+                               archive->persistentState = 
OSGI_FRAMEWORK_BUNDLE_STARTING;
+                       } else if (strncmp(stateString, "uninstalled", 256) == 
0) {
+                               archive->persistentState = 
OSGI_FRAMEWORK_BUNDLE_UNINSTALLED;
+                       } else {
+                               archive->persistentState = 
OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+                       }
+
+                       *state = archive->persistentState;
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not get persistent 
state");
+
+       return status;
+}
+
+celix_status_t bundleArchive_setPersistentState(bundle_archive_pt archive, 
bundle_state_e state) {
+       celix_status_t status = CELIX_SUCCESS;
+       char persistentStateLocation[512];
+       FILE *persistentStateLocationFile;
+
+       snprintf(persistentStateLocation, sizeof(persistentStateLocation), 
"%s/bundle.state", archive->archiveRoot);
+
+       persistentStateLocationFile = fopen(persistentStateLocation, "w");
+       if (persistentStateLocationFile == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+               char * s;
+               switch (state) {
+               case OSGI_FRAMEWORK_BUNDLE_ACTIVE:
+                       s = "active";
+                       break;
+               case OSGI_FRAMEWORK_BUNDLE_STARTING:
+                       s = "starting";
+                       break;
+               case OSGI_FRAMEWORK_BUNDLE_UNINSTALLED:
+                       s = "uninstalled";
+                       break;
+               default:
+                       s = "installed";
+                       break;
+               }
+               fprintf(persistentStateLocationFile, "%s", s);
+               if (fclose(persistentStateLocationFile) ==  0) {
+                       archive->persistentState = state;
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not set persistent 
state");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getRefreshCount(bundle_archive_pt archive, long 
*refreshCount) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (archive->refreshCount == -1) {
+               FILE *refreshCounterFile;
+               char refreshCounter[512];
+               snprintf(refreshCounter, sizeof(refreshCounter), 
"%s/refresh.counter", archive->archiveRoot);
+
+               refreshCounterFile = fopen(refreshCounter, "r");
+               if (refreshCounterFile == NULL) {
+                       archive->refreshCount = 0;
+               } else {
+                       char counterStr[256];
+                       if (fgets(counterStr, sizeof(counterStr), 
refreshCounterFile) == NULL) {
+                               status = CELIX_FILE_IO_EXCEPTION;
+                       }
+                       fclose(refreshCounterFile);
+                       if (status == CELIX_SUCCESS) {
+                               sscanf(counterStr, "%ld", 
&archive->refreshCount);
+                       }
+               }
+       }
+
+       if (status == CELIX_SUCCESS) {
+               *refreshCount = archive->refreshCount;
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not get refresh 
count");
+
+       return status;
+}
+
+celix_status_t bundleArchive_setRefreshCount(bundle_archive_pt archive) {
+       FILE *refreshCounterFile;
+       celix_status_t status = CELIX_SUCCESS;
+       char refreshCounter[512];
+
+       snprintf(refreshCounter, sizeof(refreshCounter), "%s/refresh.counter", 
archive->archiveRoot);
+
+       refreshCounterFile = fopen(refreshCounter, "w");
+       if (refreshCounterFile == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+               fprintf(refreshCounterFile, "%ld", archive->refreshCount);
+               if (fclose(refreshCounterFile) ==  0) {
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not set refresh 
count");
+
+       return status;
+}
+
+celix_status_t bundleArchive_getLastModified(bundle_archive_pt archive, time_t 
*lastModified) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (archive->lastModified == (time_t) NULL) {
+               status = CELIX_DO_IF(status, 
bundleArchive_readLastModified(archive, &archive->lastModified));
+       }
+
+       if (status == CELIX_SUCCESS) {
+               *lastModified = archive->lastModified;
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not get last 
modified");
+
+       return status;
+}
+
+celix_status_t bundleArchive_setLastModified(bundle_archive_pt archive, time_t 
lastModifiedTime) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       archive->lastModified = lastModifiedTime;
+       status = CELIX_DO_IF(status, bundleArchive_writeLastModified(archive));
+
+       framework_logIfError(logger, status, NULL, "Could not set last 
modified");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_readLastModified(bundle_archive_pt 
archive, time_t *time) {
+       FILE *lastModifiedFile;
+       char lastModified[512];
+
+       celix_status_t status = CELIX_SUCCESS;
+
+       snprintf(lastModified, sizeof(lastModified), "%s/bundle.lastmodified", 
archive->archiveRoot);
+
+       lastModifiedFile = fopen(lastModified, "r");
+       if (lastModifiedFile == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+               char timeStr[20];
+               int year, month, day, hours, minutes, seconds;
+               struct tm tm_time;
+               memset(&tm_time,0,sizeof(struct tm));
+
+               if (fgets(timeStr, sizeof(timeStr), lastModifiedFile) == NULL) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+               fclose(lastModifiedFile);
+               if (status == CELIX_SUCCESS) {
+                       sscanf(timeStr, "%d %d %d %d:%d:%d", &year, &month, 
&day, &hours, &minutes, &seconds);
+                       tm_time.tm_year = year - 1900;
+                       tm_time.tm_mon = month - 1;
+                       tm_time.tm_mday = day;
+                       tm_time.tm_hour = hours;
+                       tm_time.tm_min = minutes;
+                       tm_time.tm_sec = seconds;
+
+                       *time = mktime(&tm_time);
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not read last 
modified");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_writeLastModified(bundle_archive_pt 
archive) {
+       celix_status_t status = CELIX_SUCCESS;
+       FILE *lastModifiedFile;
+       char lastModified[512];
+
+       snprintf(lastModified, sizeof(lastModified), "%s/bundle.lastmodified", 
archive->archiveRoot);
+       lastModifiedFile = fopen(lastModified, "w");
+       if (lastModifiedFile == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+               char timeStr[20];
+               strftime(timeStr, 20, "%Y %m %d %H:%M:%S", 
localtime(&archive->lastModified));
+               fprintf(lastModifiedFile, "%s", timeStr);
+               fclose(lastModifiedFile);
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not write last 
modified");
+
+       return status;
+}
+
+celix_status_t bundleArchive_revise(bundle_archive_pt archive, const char * 
location, const char *inputFile) {
+       celix_status_t status = CELIX_SUCCESS;
+       long revNr = 0l;
+       if (!linkedList_isEmpty(archive->revisions)) {
+               long revisionNr;
+               status = 
bundleRevision_getNumber(linkedList_getLast(archive->revisions), &revisionNr);
+               revNr = revisionNr + 1;
+       }
+       if (status == CELIX_SUCCESS) {
+               status = bundleArchive_reviseInternal(archive, false, revNr, 
location, inputFile);
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not revise bundle 
archive");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_reviseInternal(bundle_archive_pt archive, 
bool isReload, long revNr, const char * location, const char *inputFile) {
+       celix_status_t status = CELIX_SUCCESS;
+       bundle_revision_pt revision = NULL;
+
+       if (inputFile != NULL) {
+               location = "inputstream:";
+       }
+
+       status = bundleArchive_createRevisionFromLocation(archive, location, 
inputFile, revNr, &revision);
+
+       if (status == CELIX_SUCCESS) {
+               if (!isReload) {
+                       status = bundleArchive_setRevisionLocation(archive, 
location, revNr);
+               }
+
+               linkedList_addElement(archive->revisions, revision);
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not revise bundle 
archive");
+
+       return status;
+}
+
+celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool 
*rolledback) {
+       *rolledback = true;
+       return CELIX_SUCCESS;
+}
+
+static celix_status_t 
bundleArchive_createRevisionFromLocation(bundle_archive_pt archive, const char 
*location, const char *inputFile, long revNr, bundle_revision_pt 
*bundle_revision) {
+       celix_status_t status = CELIX_SUCCESS;
+       char root[256];
+       long refreshCount;
+
+       status = bundleArchive_getRefreshCount(archive, &refreshCount);
+       if (status == CELIX_SUCCESS) {
+               bundle_revision_pt revision = NULL;
+
+               sprintf(root, "%s/version%ld.%ld", archive->archiveRoot, 
refreshCount, revNr);
+               status = bundleRevision_create(root, location, revNr, 
inputFile, &revision);
+
+               if (status == CELIX_SUCCESS) {
+                       *bundle_revision = revision;
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Could not create revision 
[location=%s,inputFile=%s]", location, inputFile);
+
+       return status;
+}
+
+static celix_status_t bundleArchive_getRevisionLocation(bundle_archive_pt 
archive, long revNr, char **revision_location) {
+       celix_status_t status = CELIX_SUCCESS;
+       char revisionLocation[256];
+       long refreshCount;
+
+       status = bundleArchive_getRefreshCount(archive, &refreshCount);
+       if (status == CELIX_SUCCESS) {
+               FILE *revisionLocationFile;
+
+               snprintf(revisionLocation, sizeof(revisionLocation), 
"%s/version%ld.%ld/revision.location", archive->archiveRoot, refreshCount, 
revNr);
+
+               revisionLocationFile = fopen(revisionLocation, "r");
+               if (revisionLocationFile != NULL) {
+                       char location[256];
+                       fgets(location , sizeof(location) , 
revisionLocationFile);
+                       fclose(revisionLocationFile);
+
+                       *revision_location = strdup(location);
+                       status = CELIX_SUCCESS;
+               } else {
+                       // revision file not found
+                       printf("Failed to open revision file at: %s\n", 
revisionLocation);
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+       }
+
+
+       framework_logIfError(logger, status, NULL, "Failed to get revision 
location");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_setRevisionLocation(bundle_archive_pt 
archive, const char * location, long revNr) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       char revisionLocation[256];
+       long refreshCount;
+
+       status = bundleArchive_getRefreshCount(archive, &refreshCount);
+       if (status == CELIX_SUCCESS) {
+               FILE * revisionLocationFile;
+
+               snprintf(revisionLocation, sizeof(revisionLocation), 
"%s/version%ld.%ld/revision.location", archive->archiveRoot, refreshCount, 
revNr);
+
+               revisionLocationFile = fopen(revisionLocation, "w");
+               if (revisionLocationFile == NULL) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               } else {
+                       fprintf(revisionLocationFile, "%s", location);
+                       fclose(revisionLocationFile);
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to set revision 
location");
+
+       return status;
+}
+
+celix_status_t bundleArchive_close(bundle_archive_pt archive) {
+       // close revision
+       // not yet needed/possible
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleArchive_closeAndDelete(bundle_archive_pt archive) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       status = bundleArchive_close(archive);
+       if (status == CELIX_SUCCESS) {
+               status = bundleArchive_deleteTree(archive, 
archive->archiveRoot);
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to close and delete 
archive");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_initialize(bundle_archive_pt archive) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (archive->archiveRootDir == NULL) {
+               int err = mkdir(archive->archiveRoot, S_IRWXU) ;
+               if (err != 0) {
+                       char *errmsg = strerror(errno);
+                       fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error mkdir: 
%s\n", errmsg);
+                       status = CELIX_FILE_IO_EXCEPTION;
+               } else {
+                       archive->archiveRootDir = opendir(archive->archiveRoot);
+                       if (archive->archiveRootDir == NULL) {
+                               status = CELIX_FILE_IO_EXCEPTION;
+                       } else {
+                               FILE *bundleIdFile;
+                               char bundleId[512];
+
+                               snprintf(bundleId, sizeof(bundleId), 
"%s/bundle.id", archive->archiveRoot);
+                               bundleIdFile = fopen(bundleId, "w");
+
+                               if (bundleIdFile == NULL) {
+                                       status = CELIX_FILE_IO_EXCEPTION;
+                               } else {
+                                       FILE *bundleLocationFile;
+                                       char bundleLocation[512];
+
+                                       fprintf(bundleIdFile, "%ld", 
archive->id);
+                                       // Ignore close status, let it fail if 
needed again
+                                       fclose(bundleIdFile);
+
+                                       snprintf(bundleLocation, 
sizeof(bundleLocation), "%s/bundle.location", archive->archiveRoot);
+                                       bundleLocationFile = 
fopen(bundleLocation, "w");
+
+                                       if (bundleLocationFile == NULL) {
+                                               status = 
CELIX_FILE_IO_EXCEPTION;
+                                       } else {
+                                               fprintf(bundleLocationFile, 
"%s", archive->location);
+                                               // Ignore close status, let it 
fail if needed again
+                                               fclose(bundleLocationFile);
+
+                                               status = 
bundleArchive_writeLastModified(archive);
+                                       }
+                               }
+                               closedir(archive->archiveRootDir);
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to initialize 
archive");
+
+       return status;
+}
+
+static celix_status_t bundleArchive_deleteTree(bundle_archive_pt archive, 
const char * directory) {
+       DIR *dir;
+       celix_status_t status = CELIX_SUCCESS;
+       dir = opendir(directory);
+       if (dir == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+
+               struct dirent* dent = NULL;
+
+        errno = 0;
+        dent = readdir(dir);
+               while (errno == 0 && dent != NULL) {
+                       if ((strcmp((dent->d_name), ".") != 0) && 
(strcmp((dent->d_name), "..") != 0)) {
+                               char subdir[512];
+                               snprintf(subdir, 512, "%s/%s", directory, 
dent->d_name);
+
+                               struct stat st;
+                               if (stat(subdir, &st) == 0) {
+                                       if (S_ISDIR (st.st_mode)) {
+                                               status = 
bundleArchive_deleteTree(archive, subdir);
+                                       } else {
+                                               if (remove(subdir) != 0) {
+                                                       status = 
CELIX_FILE_IO_EXCEPTION;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+            errno = 0;
+            dent = readdir(dir);
+               }
+
+        if (errno != 0) {
+            status = CELIX_FILE_IO_EXCEPTION;
+        } else if (closedir(dir) != 0) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               } else if (status == CELIX_SUCCESS) {
+                       if (rmdir(directory) != 0) {
+                               status = CELIX_FILE_IO_EXCEPTION;
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to delete tree");
+
+       return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_cache.c b/framework/src/bundle_cache.c
new file mode 100644
index 0000000..39875b5
--- /dev/null
+++ b/framework/src/bundle_cache.c
@@ -0,0 +1,218 @@
+/**
+ *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.
+ */
+/*
+ * bundle_cache.c
+ *
+ *  \date       Aug 6, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include "bundle_cache_private.h"
+#include "bundle_archive.h"
+#include "constants.h"
+#include "celix_log.h"
+
+static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * 
directory);
+
+celix_status_t bundleCache_create(properties_pt configurationMap, 
bundle_cache_pt *bundle_cache) {
+       celix_status_t status;
+       bundle_cache_pt cache;
+
+       if (configurationMap == NULL || *bundle_cache != NULL) {
+               return CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       cache = (bundle_cache_pt) calloc(1, sizeof(*cache));
+       if (cache == NULL) {
+               status = CELIX_ENOMEM;
+       } else {
+               char* cacheDir = (char*)properties_get(configurationMap, (char 
*) OSGI_FRAMEWORK_FRAMEWORK_STORAGE);
+               cache->configurationMap = configurationMap;
+               if (cacheDir == NULL) {
+                       cacheDir = ".cache";
+               }
+               cache->cacheDir = cacheDir;
+
+               *bundle_cache = cache;
+               status = CELIX_SUCCESS;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to create bundle 
cache");
+
+       return status;
+}
+
+celix_status_t bundleCache_destroy(bundle_cache_pt *cache) {
+
+       free(*cache);
+       *cache = NULL;
+
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleCache_delete(bundle_cache_pt cache) {
+       return bundleCache_deleteTree(cache, cache->cacheDir);
+}
+
+celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt 
*archives) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       DIR *dir;
+       struct stat st;
+
+       dir = opendir(cache->cacheDir);
+
+       if (dir == NULL && errno == ENOENT) {
+               if(mkdir(cache->cacheDir, S_IRWXU) == 0 ){
+                       dir = opendir(cache->cacheDir);
+               }
+       }
+
+       if (dir != NULL) {
+               array_list_pt list = NULL;
+               arrayList_create(&list);
+
+               struct dirent* dent = NULL;
+
+               errno = 0;
+               dent = readdir(dir);
+               while (errno == 0 && dent != NULL) {
+                       char archiveRoot[512];
+
+                       snprintf(archiveRoot, sizeof(archiveRoot), "%s/%s", 
cache->cacheDir, dent->d_name);
+
+                       if (stat (archiveRoot, &st) == 0) {
+                               if (S_ISDIR (st.st_mode)
+                                               && (strcmp((dent->d_name), ".") 
!= 0)
+                                               && (strcmp((dent->d_name), 
"..") != 0)
+                                               && (strncmp(dent->d_name, 
"bundle", 6) == 0)
+                                               && (strcmp(dent->d_name, 
"bundle0") != 0)) {
+
+                                       bundle_archive_pt archive = NULL;
+                                       status = 
bundleArchive_recreate(archiveRoot, &archive);
+                                       if (status == CELIX_SUCCESS) {
+                                               arrayList_add(list, archive);
+                                       }
+                               }
+                       }
+
+                       errno = 0;
+                       dent = readdir(dir);
+               }
+
+               if (errno != 0) {
+                       fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error reading 
dir");
+                       status = CELIX_FILE_IO_EXCEPTION;
+               } else {
+                       status = CELIX_SUCCESS;
+               }
+
+               closedir(dir);
+
+               if (status == CELIX_SUCCESS) {
+                       *archives = list;
+               }
+               else{
+                       int idx = 0;
+                       for(;idx<arrayList_size(list);idx++){
+                               
bundleArchive_destroy((bundle_archive_pt)arrayList_get(list,idx));
+                       }
+                       arrayList_destroy(list);
+                       *archives = NULL;
+               }
+
+       } else {
+               status = CELIX_FILE_IO_EXCEPTION;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get bundle 
archives");
+
+       return status;
+}
+
+celix_status_t bundleCache_createArchive(bundle_cache_pt cache, long id, const 
char * location, const char *inputFile, bundle_archive_pt *bundle_archive) {
+       celix_status_t status = CELIX_SUCCESS;
+       char archiveRoot[512];
+
+       if (cache && location) {
+               snprintf(archiveRoot, sizeof(archiveRoot), "%s/bundle%ld",  
cache->cacheDir, id);
+               status = bundleArchive_create(archiveRoot, id, location, 
inputFile, bundle_archive);
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to create archive");
+
+       return status;
+}
+
+static celix_status_t bundleCache_deleteTree(bundle_cache_pt cache, char * 
directory) {
+       DIR *dir;
+       celix_status_t status = CELIX_SUCCESS;
+       struct stat st;
+
+       errno = 0;
+       dir = opendir(directory);
+       if (dir == NULL) {
+               status = CELIX_FILE_IO_EXCEPTION;
+       } else {
+               struct dirent* dent = NULL;
+               dent = readdir(dir);
+               while (errno == 0 && dent != NULL) {
+                       if ((strcmp((dent->d_name), ".") != 0) && 
(strcmp((dent->d_name), "..") != 0)) {
+                               char subdir[512];
+                               snprintf(subdir, sizeof(subdir), "%s/%s", 
directory, dent->d_name);
+
+                               if (stat(subdir, &st) == 0) {
+                                       if (S_ISDIR (st.st_mode)) {
+                                               status = 
bundleCache_deleteTree(cache, subdir);
+                                       } else {
+                                               if (remove(subdir) != 0) {
+                                                       status = 
CELIX_FILE_IO_EXCEPTION;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       errno = 0;
+                       dent = readdir(dir);
+               }
+
+               if (errno != 0) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+               else if (closedir(dir) != 0) {
+                       status = CELIX_FILE_IO_EXCEPTION;
+               }
+               if (status == CELIX_SUCCESS) {
+                       if (rmdir(directory) != 0) {
+                               status = CELIX_FILE_IO_EXCEPTION;
+                       }
+               }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to delete tree at 
dir '%s'", directory);
+
+       return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_cache.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_cache.h b/framework/src/bundle_cache.h
new file mode 100644
index 0000000..350f33b
--- /dev/null
+++ b/framework/src/bundle_cache.h
@@ -0,0 +1,115 @@
+/**
+ *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.
+ */
+/*
+ * bundle_cache.h
+ *
+ *  \date       Aug 8, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+
+#ifndef BUNDLE_CACHE_H_
+#define BUNDLE_CACHE_H_
+
+/**
+ * @defgroup BundleCache BundleCache
+ * @ingroup framework
+ * @{
+ */
+
+#include "properties.h"
+#include "array_list.h"
+#include "bundle_archive.h"
+#include "celix_log.h"
+
+/**
+ * Type definition for the bundle_cache_pt abstract data type.
+ */
+typedef struct bundleCache *bundle_cache_pt;
+
+/**
+ * Creates the bundle cache using the supplied configuration map.
+ *
+ * @param configurationMap Set with properties to use for this cache
+ * @param mp The memory pool to use for allocation the cache
+ * @param bundle_cache Output parameter for the created cache
+ * @return Status code indication failure or success:
+ *             - CELIX_SUCCESS when no errors are encountered.
+ *             - CELIX_ILLEGAL_ARGUMENT If <code>bundle_cache</code> not is 
null.
+ *             - CELIX_ENOMEM If allocating memory for 
<code>bundle_cache</code> failed.
+ */
+celix_status_t bundleCache_create(properties_pt configurationMap, 
bundle_cache_pt *bundle_cache);
+
+/**
+ * Frees the bundle_cache memory allocated in bundleCache_create
+ *
+ * @param bundle_cache Output parameter for the created cache
+ * @return Status code indication failure or success:
+ *      - CELIX_SUCCESS when no errors are encountered.
+ */
+celix_status_t bundleCache_destroy(bundle_cache_pt *cache);
+
+/**
+ * Recreates and retrieves the list of archives for the given bundle cache.
+ * Archives are recreated on the bundle cache memory pool, the list for the 
results is created on the suplied pool, and is owned by the caller.
+ *
+ * @param cache The cache to recreate archives out
+ * @param pool The pool on which the list of archives is created
+ * @param archives List with recreated archives
+ * @return Status code indication failure or success:
+ *             - CELIX_SUCCESS when no errors are encountered.
+ *             - CELIX_ILLEGAL_ARGUMENT If <code>archives</code> not is null.
+ *             - CELIX_ENOMEM If allocating memory for <code>archives</code> 
failed.
+ *             - CELIX_FILE_IO_EXCEPTION If the cache cannot be opened or read.
+ */
+celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt 
*archives);
+
+/**
+ * Creates a new archive for the given bundle (using the id and location). The 
archive is created on the supplied bundlePool.
+ *
+ * @param cache The cache to create an archive in
+ * @param bundlePool The pool to use for the archive creation
+ * @param id The id of the bundle
+ * @param location The location identifier of the bundle
+ * @param inputFile Input identifier to read the bundle data from
+ * @param archive The archive to create
+ *
+ * @return Status code indication failure or success:
+ *             - CELIX_SUCCESS when no errors are encountered.
+ *             - CELIX_ILLEGAL_ARGUMENT If <code>bundle_archive</code> not is 
null.
+ *             - CELIX_ENOMEM If allocating memory for 
<code>bundle_archive</code> failed.
+ */
+celix_status_t bundleCache_createArchive(bundle_cache_pt cache, long id, const 
char* location, const char* inputFile, bundle_archive_pt *archive);
+
+/**
+ * Deletes the entire bundle cache.
+ *
+ * @param cache the cache to delete
+ * @return Status code indication failure or success:
+ *             - CELIX_SUCCESS when no errors are encountered.
+ *             - CELIX_ILLEGAL_ARGUMENT If the cache is invalid
+ *             - CELIX_FILE_IO_EXCEPTION If the cache cannot be opened or read.
+ */
+celix_status_t bundleCache_delete(bundle_cache_pt cache);
+
+/**
+ * @}
+ */
+
+#endif /* BUNDLE_CACHE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_cache_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_cache_private.h 
b/framework/src/bundle_cache_private.h
new file mode 100644
index 0000000..69e26ee
--- /dev/null
+++ b/framework/src/bundle_cache_private.h
@@ -0,0 +1,39 @@
+/**
+ *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.
+ */
+/*
+ * bundle_cache_private.h
+ *
+ *  \date       Feb 12, 2013
+ *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#ifndef BUNDLE_CACHE_PRIVATE_H_
+#define BUNDLE_CACHE_PRIVATE_H_
+
+#include "bundle_cache.h"
+
+struct bundleCache {
+       properties_pt configurationMap;
+       char * cacheDir;
+};
+
+
+#endif /* BUNDLE_CACHE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
new file mode 100644
index 0000000..face85d
--- /dev/null
+++ b/framework/src/bundle_context.c
@@ -0,0 +1,384 @@
+/**
+ *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.
+ */
+/*
+ * bundle_context.c
+ *
+ *  \date       Mar 26, 2010
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bundle_context_private.h"
+#include "framework_private.h"
+#include "bundle.h"
+#include "celix_log.h"
+
+celix_status_t bundleContext_create(framework_pt framework, 
framework_logger_pt logger, bundle_pt bundle, bundle_context_pt 
*bundle_context) {
+       celix_status_t status = CELIX_SUCCESS;
+       bundle_context_pt context = NULL;
+
+       if (*bundle_context != NULL && framework == NULL && bundle == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+        context = malloc(sizeof(*context));
+        if (!context) {
+            status = CELIX_ENOMEM;
+        } else {
+            context->framework = framework;
+            context->bundle = bundle;
+
+            *bundle_context = context;
+        }
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to create context");
+
+       return status;
+}
+
+celix_status_t bundleContext_destroy(bundle_context_pt context) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (context != NULL) {
+           free(context);
+               context = NULL;
+       } else {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to destroy context");
+
+       return status;
+}
+
+celix_status_t bundleContext_getBundle(bundle_context_pt context, bundle_pt 
*bundle) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (context == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *bundle = context->bundle;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get bundle");
+
+       return status;
+}
+
+celix_status_t bundleContext_getFramework(bundle_context_pt context, 
framework_pt *framework) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (context == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *framework = context->framework;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get framework");
+
+       return status;
+}
+
+celix_status_t bundleContext_installBundle(bundle_context_pt context, const 
char * location, bundle_pt *bundle) {
+       return bundleContext_installBundle2(context, location, NULL, bundle);
+}
+
+celix_status_t bundleContext_installBundle2(bundle_context_pt context, const 
char * location, const char *inputFile, bundle_pt *bundle) {
+       celix_status_t status = CELIX_SUCCESS;
+       bundle_pt b = NULL;
+
+       if (context != NULL && *bundle == NULL) {
+               if (fw_installBundle(context->framework, &b, location, 
inputFile) != CELIX_SUCCESS) {
+            status = CELIX_FRAMEWORK_EXCEPTION;
+               } else {
+                       *bundle = b;
+               }
+       } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to install bundle");
+
+       return status;
+}
+
+celix_status_t bundleContext_registerService(bundle_context_pt context, const 
char * serviceName, const void * svcObj,
+        properties_pt properties, service_registration_pt 
*service_registration) {
+       service_registration_pt registration = NULL;
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (context != NULL) {
+           fw_registerService(context->framework, &registration, 
context->bundle, serviceName, svcObj, properties);
+           *service_registration = registration;
+       } else {
+           status = CELIX_ILLEGAL_ARGUMENT;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to register service. 
serviceName '%s'", serviceName);
+
+       return status;
+}
+
+celix_status_t bundleContext_registerServiceFactory(bundle_context_pt context, 
const char * serviceName, service_factory_pt factory,
+        properties_pt properties, service_registration_pt 
*service_registration) {
+    service_registration_pt 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;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to register service 
factory");
+
+    return status;
+}
+
+celix_status_t bundleContext_getServiceReferences(bundle_context_pt context, 
const char * serviceName, const char * filter, array_list_pt 
*service_references) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && *service_references == NULL) {
+        fw_getServiceReferences(context->framework, service_references, 
context->bundle, serviceName, filter);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get service 
references");
+
+       return status;
+}
+
+celix_status_t bundleContext_getServiceReference(bundle_context_pt context, 
const char * serviceName, service_reference_pt *service_reference) {
+    service_reference_pt reference = NULL;
+    array_list_pt services = NULL;
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (serviceName != NULL) {
+        if (bundleContext_getServiceReferences(context, serviceName, NULL, 
&services) == CELIX_SUCCESS) {
+            reference = (arrayList_size(services) > 0) ? 
arrayList_get(services, 0) : NULL;
+            arrayList_destroy(services);
+            *service_reference = reference;
+        } else {
+            status = CELIX_ILLEGAL_ARGUMENT;
+        }
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get service 
reference");
+
+       return status;
+}
+
+FRAMEWORK_EXPORT celix_status_t 
bundleContext_retainServiceReference(bundle_context_pt context, 
service_reference_pt ref) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && ref != NULL) {
+        serviceRegistry_retainServiceReference(context->framework->registry, 
context->bundle, ref);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get service 
references");
+
+    return status;
+}
+
+celix_status_t bundleContext_ungetServiceReference(bundle_context_pt context, 
service_reference_pt reference) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && reference != NULL) {
+        status = framework_ungetServiceReference(context->framework, 
context->bundle, reference);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to unget 
service_reference");
+
+    return status;
+}
+
+celix_status_t bundleContext_getService(bundle_context_pt context, 
service_reference_pt reference, void** service_instance) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && reference != NULL && *service_instance == NULL) {
+        /*NOTE argument service_instance should be considerd a 'const void**'. 
+        To ensure backwards compatiblity a cast is made instead.
+        */
+           status = fw_getService(context->framework, context->bundle, 
reference, (const void**) service_instance);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get service");
+
+    return status;
+}
+
+celix_status_t bundleContext_ungetService(bundle_context_pt context, 
service_reference_pt reference, bool *result) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && reference != NULL) {
+        status = framework_ungetService(context->framework, context->bundle, 
reference, result);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to unget service");
+
+    return status;
+}
+
+celix_status_t bundleContext_getBundles(bundle_context_pt context, 
array_list_pt *bundles) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       if (context == NULL || *bundles != NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *bundles = framework_getBundles(context->framework);
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get bundles");
+
+       return status;
+}
+
+celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, 
bundle_pt *bundle) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context == NULL || *bundle != NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        *bundle = framework_getBundleById(context->framework, id);
+        if (*bundle == NULL) {
+            status = CELIX_BUNDLE_EXCEPTION;
+        }
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get bundle 
[id=%ld]", id);
+
+       return status;
+}
+
+celix_status_t bundleContext_addServiceListener(bundle_context_pt context, 
service_listener_pt listener, const char* filter) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_addServiceListener(context->framework, context->bundle, listener, 
filter);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to add service 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_removeServiceListener(bundle_context_pt context, 
service_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_removeServiceListener(context->framework, context->bundle, 
listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to remove service 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_addBundleListener(bundle_context_pt context, 
bundle_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_addBundleListener(context->framework, context->bundle, listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to add bundle 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_removeBundleListener(bundle_context_pt context, 
bundle_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_removeBundleListener(context->framework, context->bundle, listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to remove bundle 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_addFrameworkListener(bundle_context_pt context, 
framework_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_addFrameworkListener(context->framework, context->bundle, listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to add framework 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_removeFrameworkListener(bundle_context_pt 
context, framework_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_removeFrameworkListener(context->framework, context->bundle, 
listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to remove framework 
listener");
+
+    return status;
+}
+
+celix_status_t bundleContext_getProperty(bundle_context_pt context, const char 
*name, const char** value) {
+       return bundleContext_getPropertyWithDefault(context, name, NULL, value);
+}
+
+celix_status_t bundleContext_getPropertyWithDefault(bundle_context_pt context, 
const char* name, const char* defaultValue, const char** value) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context == NULL || name == NULL || *value != NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        fw_getProperty(context->framework, name, defaultValue, value);
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get property 
[name=%s]", name);
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_context_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context_private.h 
b/framework/src/bundle_context_private.h
new file mode 100644
index 0000000..3810cd0
--- /dev/null
+++ b/framework/src/bundle_context_private.h
@@ -0,0 +1,43 @@
+/**
+ *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.
+ */
+/*
+ * bundle_context_private.h
+ *
+ *  \date       Feb 12, 2013
+ *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#ifndef BUNDLE_CONTEXT_PRIVATE_H_
+#define BUNDLE_CONTEXT_PRIVATE_H_
+
+#include "bundle_context.h"
+#include "celix_log.h"
+
+struct bundleContext {
+#ifdef WITH_APR
+    apr_pool_t *pool;
+#endif
+       struct framework * framework;
+       struct bundle * bundle;
+};
+
+
+#endif /* BUNDLE_CONTEXT_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_private.h b/framework/src/bundle_private.h
new file mode 100644
index 0000000..8085609
--- /dev/null
+++ b/framework/src/bundle_private.h
@@ -0,0 +1,48 @@
+/**
+ *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.
+ */
+/*
+ * bundle_private.h
+ *
+ *  \date       Feb 18, 2011
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+
+#ifndef BUNDLE_PRIVATE_H_
+#define BUNDLE_PRIVATE_H_
+
+#include "bundle.h"
+
+struct bundle {
+       bundle_context_pt context;
+       activator_pt activator;
+       bundle_state_e state;
+       void * handle;
+       bundle_archive_pt archive;
+       array_list_pt modules;
+       manifest_pt manifest;
+
+       celix_thread_mutex_t lock;
+       int lockCount;
+       celix_thread_t lockThread;
+
+       struct framework * framework;
+};
+
+#endif /* BUNDLE_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_revision.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_revision.c b/framework/src/bundle_revision.c
new file mode 100644
index 0000000..cfa10aa
--- /dev/null
+++ b/framework/src/bundle_revision.c
@@ -0,0 +1,153 @@
+/**
+ *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.
+ */
+/*
+ * bundle_revision.c
+ *
+ *  \date       Apr 12, 2011
+ *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
+ *  \copyright Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <archive.h>
+#include <string.h>
+
+#include "bundle_revision_private.h"
+
+celix_status_t bundleRevision_create(const char *root, const char *location, 
long revisionNr, const char *inputFile, bundle_revision_pt *bundle_revision) {
+    celix_status_t status = CELIX_SUCCESS;
+       bundle_revision_pt revision = NULL;
+
+       revision = (bundle_revision_pt) malloc(sizeof(*revision));
+    if (!revision) {
+       status = CELIX_ENOMEM;
+    } else {
+       // TODO: This overwrites an existing revision, is this supposed to 
happen?
+        int state = mkdir(root, S_IRWXU);
+        if ((state != 0) && (errno != EEXIST)) {
+            free(revision);
+            status = CELIX_FILE_IO_EXCEPTION;
+        } else {
+            if (inputFile != NULL) {
+                status = extractBundle(inputFile, root);
+            } else if (strcmp(location, "inputstream:") != 0) {
+               // TODO how to handle this correctly?
+               // If location != inputstream, extract it, else ignore it and 
assume this is a cache entry.
+                status = extractBundle(location, root);
+            }
+
+            status = CELIX_DO_IF(status, 
arrayList_create(&(revision->libraryHandles)));
+            if (status == CELIX_SUCCESS) {
+                revision->revisionNr = revisionNr;
+                revision->root = strdup(root);
+                revision->location = strdup(location);
+
+                *bundle_revision = revision;
+
+                char manifest[512];
+                snprintf(manifest, sizeof(manifest), 
"%s/META-INF/MANIFEST.MF", revision->root);
+                               status = manifest_createFromFile(manifest, 
&revision->manifest);
+            }
+            else {
+               free(revision);
+            }
+
+        }
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to create revision");
+
+       return status;
+}
+
+celix_status_t bundleRevision_destroy(bundle_revision_pt revision) {
+    arrayList_destroy(revision->libraryHandles);
+    manifest_destroy(revision->manifest);
+    free(revision->root);
+    free(revision->location);
+    free(revision);
+       return CELIX_SUCCESS;
+}
+
+celix_status_t bundleRevision_getNumber(bundle_revision_pt revision, long 
*revisionNr) {
+       celix_status_t status = CELIX_SUCCESS;
+    if (revision == NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+       *revisionNr = revision->revisionNr;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get revision 
number");
+
+       return status;
+}
+
+celix_status_t bundleRevision_getLocation(bundle_revision_pt revision, const 
char **location) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (revision == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *location = revision->location;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get revision 
location");
+
+       return status;
+}
+
+celix_status_t bundleRevision_getRoot(bundle_revision_pt revision, const char 
**root) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (revision == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *root = revision->root;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get revision 
root");
+
+       return status;
+}
+
+celix_status_t bundleRevision_getManifest(bundle_revision_pt revision, 
manifest_pt *manifest) {
+       celix_status_t status = CELIX_SUCCESS;
+       if (revision == NULL) {
+               status = CELIX_ILLEGAL_ARGUMENT;
+       } else {
+               *manifest = revision->manifest;
+       }
+
+       framework_logIfError(logger, status, NULL, "Failed to get manifest");
+
+       return status;
+}
+
+celix_status_t bundleRevision_getHandles(bundle_revision_pt revision, 
array_list_pt *handles) {
+    celix_status_t status = CELIX_SUCCESS;
+    if (revision == NULL) {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        *handles = revision->libraryHandles;
+    }
+
+    framework_logIfError(logger, status, NULL, "Failed to get handles");
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/framework/src/bundle_revision_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_revision_private.h 
b/framework/src/bundle_revision_private.h
new file mode 100644
index 0000000..cb1dcd8
--- /dev/null
+++ b/framework/src/bundle_revision_private.h
@@ -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.
+ */
+/*
+ * bundle_revision_private.h
+ *
+ *  \date       Feb 12, 2013
+ *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#ifndef BUNDLE_REVISION_PRIVATE_H_
+#define BUNDLE_REVISION_PRIVATE_H_
+
+#include "bundle_revision.h"
+
+struct bundleRevision {
+       long revisionNr;
+       char *root;
+       char *location;
+       manifest_pt manifest;
+
+       array_list_pt libraryHandles;
+};
+
+#endif /* BUNDLE_REVISION_PRIVATE_H_ */

Reply via email to