Return-Path: X-Original-To: apmail-celix-commits-archive@www.apache.org Delivered-To: apmail-celix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E5EF418674 for ; Fri, 15 May 2015 19:40:34 +0000 (UTC) Received: (qmail 31237 invoked by uid 500); 15 May 2015 19:40:34 -0000 Delivered-To: apmail-celix-commits-archive@celix.apache.org Received: (qmail 31210 invoked by uid 500); 15 May 2015 19:40:34 -0000 Mailing-List: contact commits-help@celix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@celix.apache.org Delivered-To: mailing list commits@celix.apache.org Received: (qmail 31200 invoked by uid 99); 15 May 2015 19:40:34 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 May 2015 19:40:34 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 769E7E2F6F; Fri, 15 May 2015 19:40:34 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pnoltes@apache.org To: commits@celix.apache.org Message-Id: <1ce2eaefc89949539965381936938dde@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: celix git commit: CELIX-236: Initial drop of celix-bootstrap Date: Fri, 15 May 2015 19:40:34 +0000 (UTC) Repository: celix Updated Branches: refs/heads/feature/CELIX-236_celix-boostrap [created] 5d703d3ae CELIX-236: Initial drop of celix-bootstrap Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5d703d3a Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5d703d3a Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5d703d3a Branch: refs/heads/feature/CELIX-236_celix-boostrap Commit: 5d703d3ae9949072d433f3893c49316b6ccf4eaf Parents: e2598c1 Author: Pepijn Noltes Authored: Fri May 15 21:33:15 2015 +0200 Committer: Pepijn Noltes Committed: Fri May 15 21:33:15 2015 +0200 ---------------------------------------------------------------------- celix-bootstrap/README.md | 56 +++ celix-bootstrap/celix/__init__.py | 2 + celix-bootstrap/celix/bootstrap/__init__.py | 0 celix-bootstrap/celix/bootstrap/__main__.py | 4 + .../celix/bootstrap/argument_parser.py | 73 +++ celix-bootstrap/celix/bootstrap/generators.py | 163 +++++++ .../bootstrap/templates/bundle/CMakeLists.txt | 55 +++ .../bootstrap/templates/bundle/bundle.json | 18 + .../templates/bundle/bundle_activator.c | 471 +++++++++++++++++++ .../bootstrap/templates/bundle/component.c | 174 +++++++ .../bootstrap/templates/bundle/component.h | 69 +++ .../bootstrap/templates/bundle/deploy.cmake | 18 + .../bootstrap/templates/project/CMakeLists.txt | 30 ++ .../bootstrap/templates/project/project.json | 4 + .../bootstrap/templates/services/service.h | 48 ++ .../bootstrap/templates/services/services.json | 4 + celix-bootstrap/scripts/celix-bootstrap | 5 + celix-bootstrap/setup.py | 31 ++ 18 files changed, 1225 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/README.md ---------------------------------------------------------------------- diff --git a/celix-bootstrap/README.md b/celix-bootstrap/README.md new file mode 100644 index 0000000..ef63c8a --- /dev/null +++ b/celix-bootstrap/README.md @@ -0,0 +1,56 @@ +# celix-bootstrap +A (python based) code generation tool for [Apache Celix](https://celix.apache.org/) projects and bundles. + +##Installation + +###Option 1 (install with distutils) + +* Download Cog from https://pypi.python.org/pypi/cogapp +* Unpack and run `python setup.py install' in the cogapp directory +* Clone this repository +* Run `python setup.py install` in the celix-bootstrap directory + +###Option 2 (configure with alias) +* Download Cog from https://pypi.python.org/pypi/cogapp +* Unpack it in a convenient directory +* Clone this repository +* Create a celix-bootstrap alias: +``` +alias celix-bootstrap='PYTHONPATH=${cog_dir}:${celix-boostrap_dir} python -m celix-bootstrap' +``` + +#Concept +The idea behind celix-boostrap is to enable users of Apache Celix to very fast setup of Apache Celix bundle projects. And after that to be able to generate and update the initial bundle code based on some declaritive attributes. + +celix-boostrap is build on top of [Cog](https://celix.apache.org/). "Cog is a file generation tool. It lets you use pieces of Python code as generators in your source files to generate whatever text you need." + +The code generation code is added in the comments of the source code (in this case C or CMake syntax). This enables a +source files which contains manual code and generated code to coexists and to able to rerun code generation after manual editing source files. + +Is good to known that you should not edit anything between the following comments. +``` +{{ +{{end}} +``` + +#Usage + +You can setup a new Apache Celix project by executing following steps: +* Choose a project directory and cd to it +* Run `celix-bootstrap create_project .` +* Edit the project.json file and ensure that the celix_install_dir points to the directory where Apache Celix is installed +* Run `celix-bootstrap update .` to generate the needed files +* (Optional) Update the project.json file and run `celix-bootstrap update .` again to update the generated files +* (Optional) Run `celix-bootstrap update . -e` to update the project source files one more time and remove the code generation parts + +You can create a new bundle by executing the following steps: +* cd to the project directory +* Run `celix-bootstrap create_bundle mybundle` +* Edit the `mybundle/bundle.json` file to declare which components you like to create and what services those components depends on and/or provide +* Run `celix-bootstrap update mybundle` to generate the neccesary files +* Add the bundle to the project CMakeLists.txt file by adding the `add_subdirectory(mybundle)` line +* Add code to the component and when providing service also add the necesarry code to the bundle activator +* (Optional) Run `celix-bootstrap update . -e` to update the bundle source files one more time and remove the code generation parts + +Additional Info +* You can use the -t argument to use a different set of template (project & bundle) files. The original template files can be found at ${celix-bootstrap_dir}/templates http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/__init__.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/__init__.py b/celix-bootstrap/celix/__init__.py new file mode 100644 index 0000000..139597f --- /dev/null +++ b/celix-bootstrap/celix/__init__.py @@ -0,0 +1,2 @@ + + http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/__init__.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/__init__.py b/celix-bootstrap/celix/bootstrap/__init__.py new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/__main__.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/__main__.py b/celix-bootstrap/celix/bootstrap/__main__.py new file mode 100644 index 0000000..0701ac8 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/__main__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from . import argument_parser + +argument_parser.main() http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/argument_parser.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/argument_parser.py b/celix-bootstrap/celix/bootstrap/argument_parser.py new file mode 100644 index 0000000..6919e9a --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/argument_parser.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +import os +import argparse +from . import generators + +#TODO add support to add licence text to all created files +#TODO add support to select pthread or celix_threads + +def main() : + parser = argparse.ArgumentParser("celix-bootstrap") + + CREATE_PROJECT_COMMAND = "create_project" + CREATE_BUNDLE_COMMAND = "create_bundle" + CREATE_SERVICE_COMMAND = "create_services" + + UPDATE_COMMAND = "update" + + #positional + parser.add_argument("command", help="The command to executee", choices=(CREATE_PROJECT_COMMAND, CREATE_BUNDLE_COMMAND, CREATE_SERVICE_COMMAND, UPDATE_COMMAND)) + parser.add_argument("directory", help="The directory to work on") + + #optional + parser.add_argument("-e", "--erase", help="erase cog code when updating", action="store_true") + parser.add_argument("-t", "--template_dir", help="define which template directory to use. Default is '%s/templates'" % os.path.dirname(__file__), action="store") + + args = parser.parse_args() + + gm = GeneratorMediator(args.directory, args.erase, args.template_dir) + + if args.command == CREATE_BUNDLE_COMMAND : + gm.createBundle() + elif args.command == CREATE_PROJECT_COMMAND : + gm.createProject() + elif args.command == CREATE_SERVICE_COMMAND : + gm.createServices() + elif args.command == UPDATE_COMMAND : + gm.update() + else : + sys.exit() + + +class GeneratorMediator : + + gendir = None + bundleGenerator = None + projectGenerator = None + servicesGenerator = None + + def __init__(self, gendir, erase, template_dir) : + self.gendir = gendir + self.bundleGenerator = generators.Bundle(gendir, erase, template_dir) + self.projectGenerator = generators.Project(gendir, erase, template_dir) + self.servicesGenerator = generators.Services(gendir, erase, template_dir) + + def createBundle(self) : + self.bundleGenerator.create() + + def createProject(self) : + self.projectGenerator.create() + + def createServices(self) : + self.servicesGenerator.create() + + def update(self) : + if os.path.isfile(os.path.join(self.gendir, "bundle.json")) : + print("Generating/updating bundle code") + self.bundleGenerator.update() + if os.path.isfile(os.path.join(self.gendir, "project.json")) : + print("Generating/updating project code") + self.projectGenerator.update() + if os.path.isfile(os.path.join(self.gendir, "services.json")) : + print("Generating/updating services code") + self.servicesGenerator.update() http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/generators.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/generators.py b/celix-bootstrap/celix/bootstrap/generators.py new file mode 100644 index 0000000..58e13df --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/generators.py @@ -0,0 +1,163 @@ +import shutil +import os +import sys +import json +import cogapp + +class BaseGenerator: + gendir = None + descriptor = None + erase_cog = False + template_dir = None + profile= None + gen_code_suffix = "do not edit, generated code" + markers="{{ }} {{end}}" + + def __init__(self, gendir, profile, erase, template_dir) : + self.gendir = gendir + self.descriptor = "%s/%s.json" % (gendir, profile) + self.template_dir = os.path.join(os.getcwd(), os.path.dirname(__file__), "templates") + self.profile = profile + self.erase_cog = erase + if template_dir is not None : + self.template_dir = template_dir + + def set_erase_cog(self, erase) : + self.erase_cog = erase + + def set_template_dir(self, tdir) : + self.template_dir = tdir + + def set_gen_cod_suffic(self, suffix) : + self.gen_code_suffic = suffix + + def set_cog_markers(markers) : + self.markers = markers + + def create(self) : + if os.path.exists(self.descriptor) : + print("%s Already exists. Will not override existing %s.json" % (self.descriptor, self.profile)) + else : + if not os.path.exists(self.gendir) : + os.makedirs(self.gendir) + shutil.copyfile(os.path.join(self.template_dir, self.profile, "%s.json" % self.profile), self.descriptor) + + print("Edit the %s file and run 'celix-bootstrap update %s' to generate the source files" % (self.descriptor, self.gendir)) + + def read_descriptor(self) : + if os.path.isdir(self.gendir) and os.path.exists(self.descriptor) : + with open(self.descriptor) as inputFile : + try : + return json.load(inputFile) + except ValueError as e: + print("ERROR: %s is not a valid json file: %s" % (self.descriptor, e)) + sys.exit(1) + + def update_file(self, template, targetFile, options=[], commentsPrefix="//") : + cog_file = os.path.join(self.gendir, targetFile) + if not os.path.exists(cog_file) : + print("Creating file %s" % cog_file) + if not os.path.exists(os.path.dirname(cog_file)) : + os.makedirs(os.path.dirname(cog_file)) + template_abs = os.path.join(self.template_dir, self.profile, template) + shutil.copyfile(template_abs, cog_file) + + backup_cog_file = "%s/.cog/%s" % (self.gendir, targetFile) + if self.erase_cog : + if os.path.exists(backup_cog_file) : + print("Will not erase cog code, backup file (%s) for source already exists." % backup_cog_file) + sys.exit(1) + else : + if not os.path.exists(os.path.dirname(backup_cog_file)) : + os.makedirs(os.path.dirname(backup_cog_file)) + shutil.copy(cog_file, backup_cog_file) + + cog = cogapp.Cog() + cog_options = ["cog", "--markers=%s" % self.markers] + options + if self.erase_cog : + cog_options += ["-d", "-o", cog_file, backup_cog_file] + else : + cog_options += ["-r", "-e", "-s", " %s%s" %(commentsPrefix, self.gen_code_suffix), cog_file] + cog.main(cog_options) + + +class Bundle(BaseGenerator): + + def __init__(self, gendir, erase, template_dir) : + BaseGenerator.__init__(self, gendir, "bundle", erase, template_dir) + #python3 super(Bundle, self).__init__(gendir, "bundle") + + def update_cmakelists(self) : + options = ["-D", "bundleFile=%s" % self.descriptor] + self.update_file("CMakeLists.txt", "CMakeLists.txt", options, "#") + + def update_deploy_file(self) : + options = ["-D", "bundleFile=%s" % self.descriptor] + self.update_file("deploy.cmake", "deploy.cmake", options, "#") + + def update_activator(self) : + options = ["-D", "bundleFile=%s" % self.descriptor] + self.update_file("bundle_activator.c", "private/src/bundle_activator.c", options) + + def update_component_header(self, componentName) : + genfile = "private/include/%s.h" % componentName + options = ["-D", "bundleFile=%s" % self.descriptor, "-D", "componentName=%s" % componentName] + self.update_file("component.h", genfile, options) + + def update_component_source(self, componentName) : + genfile = "private/src/%s.c" % componentName + options = ["-D", "bundleFile=%s" % self.descriptor, "-D", "componentName=%s" % componentName] + self.update_file("component.c", genfile, options) + + def update(self) : + bd = self.read_descriptor() + if bd is None : + print("%s does not exist or does not contain a bundle.json file" % self.gendir) + else : + self.update_cmakelists() + self.update_deploy_file() + self.update_activator() + for comp in bd['components'] : + self.update_component_header(comp['name']) + self.update_component_source(comp['name']) + +class Project(BaseGenerator): + + def __init__(self, gendir, erase, template_dir) : + BaseGenerator.__init__(self, gendir, "project", erase, template_dir) + #python3 super(Project, self).__init__(gendir, "project") + + def update_cmakelists(self) : + options = ["-D", "projectFile=%s" % self.descriptor] + self.update_file("CMakeLists.txt", "CMakeLists.txt", options, "#") + + def update(self) : + descriptor = self.read_descriptor() + if descriptor is None : + print("%s does not exist or does not contain a project.json file" % self.gendir) + else : + self.update_cmakelists() + + +class Services(BaseGenerator): + + def __init__(self, gendir, erase, template_dir) : + BaseGenerator.__init__(self, gendir, "services", erase, template_dir) + #python3 super(Services, self).__init__(gendir, "services") + + def update_cmakelists(self) : + options = ["-D", "projectFile=%s" % self.descriptor] + self.update_file("CMakeLists.txt", "CMakeLists.txt", options, "#") + + def update_service_header(self, serviceName) : + genfile = "public/include/%s.h" % serviceName + options = ["-D", "descriptorFile=%s" % self.descriptor, "-D", "serviceName=%s" % serviceName] + self.update_file("service.h", genfile, options) + + def update(self) : + descriptor = self.read_descriptor() + if descriptor is None : + print("%s does not exist or does not contain a services.json file" % self.gendir) + else : + for serv in descriptor : + self.update_service_header(serv['name']) http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/CMakeLists.txt b/celix-bootstrap/celix/bootstrap/templates/bundle/CMakeLists.txt new file mode 100644 index 0000000..5bc1979 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/CMakeLists.txt @@ -0,0 +1,55 @@ +#{{ +#import json +#bundle = None +#with open(bundleFile) as input : +# bundle = json.load(input) +#}} +#{{end}} + + +SET( + BUNDLE_NAME +#{{ +#cog.outl("\t\"%s\"" % bundle['name']) +#}} +"mybundle" #do not edit, generated code +#{{end}} +) + +SET( + BUNDLE_SYMBOLICNAME +#{{ +#cog.outl("\t\"%s\"" % bundle['symbolicName']) +#}} +"org.example.mybundle" #do not edit, generated code +#{{end}} +) + +SET(BUNDLE_VERSION "0.0.1") + +include_directories( + "private/include" + "public/include" +) + +bundle( +#{{ +#cog.outl("\t%s SOURCES" % bundle['name']) +#cog.outl("\t\tprivate/src/bundle_activator") +#for comp in bundle['components'] : +# cog.outl("\t\tprivate/src/%s" % comp['name']) +#}} +mybundle SOURCES #do not edit, generated code + private/src/bundle_activator #do not edit, generated code + private/src/example #do not edit, generated code +#{{end}} +) + + +#{{ +#cog.outl("SET(BUNDLE_LIB \"%s\")" % bundle['name']) +#}} +SET(BUNDLE_LIB "mybundle") #do not edit, generated code +#{{end}} + +target_link_libraries(${BUNDLE_LIB} ${CELIX_FRAMEWORK_LIBRARY} ${CELIX_UTILS_LIBRARY}) http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/bundle.json ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/bundle.json b/celix-bootstrap/celix/bootstrap/templates/bundle/bundle.json new file mode 100644 index 0000000..558bd72 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/bundle.json @@ -0,0 +1,18 @@ +{ + "name" : "mybundle", + "symbolicName": "org.example.mybundle", + "components" : [ + { + "name" : "example", + "serviceDependencies" : [ + { "include" : "log_service/log_service.h" , "name" : "logger", "service_name" : "OSGI_LOGSERVICE_NAME", "type" : "log_service_pt", "cardinality" : "one" }, + { "include" : "log_service/log_service.h" , "name" : "loggerOptional", "service_name" : "OSGI_LOGSERVICE_NAME", "type" : "log_service_pt", "cardinality" : "optional" }, + { "include" : "log_service/log_service.h" , "name" : "loggerMany", "filter" : "(objectClass=log_service)", "type" : "log_service_pt", "cardinality" : "many" } + ], + "providedServices" : [ + { "include" : "shell/command.h" , "name" : "command", "service_name" : "\"commandService\"", "type" : "command_service_pt" }, + { "include" : "shell/command.h" , "name" : "command2", "service_name" : "\"commandService\"", "type" : "command_service_pt" } + ] + } + ] +} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/bundle_activator.c ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/bundle_activator.c b/celix-bootstrap/celix/bootstrap/templates/bundle/bundle_activator.c new file mode 100644 index 0000000..b946961 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/bundle_activator.c @@ -0,0 +1,471 @@ +//TODO update fields from Type to ForType +//TODO improve names to camel case (e.g. from _add_logger_for_example to _addLoggerToExample) +//{{ +//import json +//bundle = None +//with open(bundleFile) as input : +// bundle = json.load(input) +//}} +//{{end}} +#include + +#include + +#include +#include +#include +#include + +//Includes for the services / components +//{{ +//for comp in bundle['components'] : +// cog.outl("#include \"%s.h\"" % comp['name']) +// for service in comp['serviceDependencies'] : +// cog.outl("#include <%s>" % service['include']) +// for service in comp['providedServices'] : +// cog.outl("#include <%s>" % service['include']) +//}} +#include "example.h" //do not edit, generated code +#include //do not edit, generated code +#include //do not edit, generated code +#include //do not edit, generated code +#include //do not edit, generated code +#include //do not edit, generated code +//{{end}} + + + +//Private (static) function declarations +//{{ +//for comp in bundle['components'] : +// cog.outl("static bundleActivator_resolveState_for_%s(struct activator *activator);" % comp['name']) +// for service in comp['serviceDependencies'] : +// cog.outl("static celix_status_t bundleActivator_add_%s_for_%s(void *handle, service_reference_pt ref, void *service);" % (service['name'], comp['name'])) +// cog.outl("static celix_status_t bundleActivator_remove_%s_for_%s(void *handle, service_reference_pt ref, void *service);" % (service['name'], comp['name'])) +//}} +static bundleActivator_resolveState_for_example(struct activator *activator); //do not edit, generated code +static celix_status_t bundleActivator_add_logger_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +static celix_status_t bundleActivator_remove_logger_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +static celix_status_t bundleActivator_add_loggerOptional_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +static celix_status_t bundleActivator_remove_loggerOptional_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +static celix_status_t bundleActivator_add_loggerMany_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +static celix_status_t bundleActivator_remove_loggerMany_for_example(void *handle, service_reference_pt ref, void *service); //do not edit, generated code +//{{end}} +static celix_status_t bundleActivator_getFirst(hash_map_pt services, void **result); + +typedef enum component_state { + COMPONENT_STATE_UNKNOWN = 0, + COMPONENT_STATE_CREATED = 1, + COMPONENT_STATE_STARTED = 2, + COMPONENT_STATE_STOPPED = 3, + COMPONENT_STATE_DESTROYED = 4 +} component_state_type; + +struct activator { + bundle_context_pt context; +//Fields for components, service structs, service registries and trackers +//{{ +//cog.outl("//no indent marker") +//for comp in bundle['components'] : +// cog.outl("\t%s_pt %s;" % (comp['name'], comp['name'])) +// cog.outl("\tpthread_mutex_t %sLock;" % comp['name']) +// cog.outl("\tcomponent_state_type %sState;" % comp['name']) +// for service in comp['serviceDependencies'] : +// cog.outl("\tservice_tracker_customizer_pt %sCustomizer;" % service['name']) +// cog.outl("\tservice_tracker_pt %sServiceTracker;" % service['name']) +// if service['cardinality'] == "one" or service['cardinality'] == "optional" : +// cog.outl("\thash_map_pt %s_services_for_%s;" % (service['name'], comp['name'])) +// cog.outl("\t%s current_%s_service_for_%s;" % (service['type'], service['name'], comp['name'])) +// for service in comp['providedServices'] : +// cog.outl("\t%s %s;" % (service['type'], service['name'])) +// cog.outl("\tservice_registration_pt %sServiceRegistry;" % service['name']) +// cog.outl("") +//}} +//no indent marker //do not edit, generated code + example_pt example; //do not edit, generated code + pthread_mutex_t exampleLock; //do not edit, generated code + component_state_type exampleState; //do not edit, generated code + service_tracker_customizer_pt loggerCustomizer; //do not edit, generated code + service_tracker_pt loggerServiceTracker; //do not edit, generated code + hash_map_pt logger_services_for_example; //do not edit, generated code + log_service_pt current_logger_service_for_example; //do not edit, generated code + service_tracker_customizer_pt loggerOptionalCustomizer; //do not edit, generated code + service_tracker_pt loggerOptionalServiceTracker; //do not edit, generated code + hash_map_pt loggerOptional_services_for_example; //do not edit, generated code + log_service_pt current_loggerOptional_service_for_example; //do not edit, generated code + service_tracker_customizer_pt loggerManyCustomizer; //do not edit, generated code + service_tracker_pt loggerManyServiceTracker; //do not edit, generated code + command_service_pt command; //do not edit, generated code + service_registration_pt commandServiceRegistry; //do not edit, generated code + command_service_pt command2; //do not edit, generated code + service_registration_pt command2ServiceRegistry; //do not edit, generated code + +//{{end}} +}; + +celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = calloc(1, sizeof(struct activator)); + if (activator != NULL) { + (*userData) = activator; +//{{ +//for comp in bundle['components'] : +// cog.outl("//no indent marker") +// cog.outl("\t\tactivator->%s = NULL;" % comp['name']) +// cog.outl("\t\t%s_create(&activator->%s);" % (comp['name'], comp['name'])) +// cog.outl("\t\tactivator->%sState = COMPONENT_STATE_CREATED;" % (comp['name'])) +// cog.outl("\t\tpthread_mutex_init(&activator->%sLock, NULL);" % comp['name']) +// for service in comp['serviceDependencies'] : +// cog.outl("\t\tactivator->%sServiceTracker = NULL;" % service['name']) +// cog.outl("\t\tserviceTrackerCustomizer_create(activator, NULL, bundleActivator_add_%s_for_%s, NULL, bundleActivator_remove_%s_for_%s, &activator->%sCustomizer);" % (service['name'], comp['name'], service['name'], comp['name'], service['name'])) +// if 'service_name' in service : +// cog.outl("\t\tserviceTracker_create(context, (char *) %s, activator->%sCustomizer, &activator->%sServiceTracker);" % (service['service_name'], service['name'], service['name'])) +// else : +// cog.outl("\t\tserviceTracker_createWithService(context, \"%s\", activator->%sCustomizer, &activator->%sServiceTracker);" % (service['filter'], service['name'], service['name'])) +// if service['cardinality'] == "one" or service['cardinality'] == "optional" : +// cog.outl("\t\tactivator->%s_services_for_%s = hashMap_create(NULL, NULL, NULL, NULL);" % (service['name'], comp['name'])) +// cog.outl("\t\tactivator->current_%s_service_for_%s = NULL;" % (service['name'], comp['name'])) +// for service in comp['providedServices'] : +// cog.outl("\t\tactivator->%s = NULL;" % service['name']) +// cog.outl("\t\tactivator->%sServiceRegistry = NULL;" % service['name']) +// cog.outl("") +//}} +//no indent marker //do not edit, generated code + activator->example = NULL; //do not edit, generated code + example_create(&activator->example); //do not edit, generated code + activator->exampleState = COMPONENT_STATE_CREATED; //do not edit, generated code + pthread_mutex_init(&activator->exampleLock, NULL); //do not edit, generated code + activator->loggerServiceTracker = NULL; //do not edit, generated code + serviceTrackerCustomizer_create(activator, NULL, bundleActivator_add_logger_for_example, NULL, bundleActivator_remove_logger_for_example, &activator->loggerCustomizer); //do not edit, generated code + serviceTracker_create(context, (char *) OSGI_LOGSERVICE_NAME, activator->loggerCustomizer, &activator->loggerServiceTracker); //do not edit, generated code + activator->logger_services_for_example = hashMap_create(NULL, NULL, NULL, NULL); //do not edit, generated code + activator->current_logger_service_for_example = NULL; //do not edit, generated code + activator->loggerOptionalServiceTracker = NULL; //do not edit, generated code + serviceTrackerCustomizer_create(activator, NULL, bundleActivator_add_loggerOptional_for_example, NULL, bundleActivator_remove_loggerOptional_for_example, &activator->loggerOptionalCustomizer); //do not edit, generated code + serviceTracker_create(context, (char *) OSGI_LOGSERVICE_NAME, activator->loggerOptionalCustomizer, &activator->loggerOptionalServiceTracker); //do not edit, generated code + activator->loggerOptional_services_for_example = hashMap_create(NULL, NULL, NULL, NULL); //do not edit, generated code + activator->current_loggerOptional_service_for_example = NULL; //do not edit, generated code + activator->loggerManyServiceTracker = NULL; //do not edit, generated code + serviceTrackerCustomizer_create(activator, NULL, bundleActivator_add_loggerMany_for_example, NULL, bundleActivator_remove_loggerMany_for_example, &activator->loggerManyCustomizer); //do not edit, generated code + serviceTracker_create(context, (char *) OSGI_LOGSERVICE_NAME, activator->loggerManyCustomizer, &activator->loggerManyServiceTracker); //do not edit, generated code + activator->command = NULL; //do not edit, generated code + activator->commandServiceRegistry = NULL; //do not edit, generated code + activator->command2 = NULL; //do not edit, generated code + activator->command2ServiceRegistry = NULL; //do not edit, generated code + +//{{end}} + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t bundleActivator_start(void *userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + //TODO allocate and assign all declared provided services + //e.g: + //activator->command = calloc(1, sizeof(*activator->command)); + //activator->command->command = activator->example; + //activator->command->getName = example_getStateCommandName; + //activator->command->getUsage = example_getUsage; + //activator->command->getShortDescription = example_getStateCommandShortDescription; + //activator->command->executeCommand = example_executeStateCommand; + +//Start compnent, register service if the service struct is allocated +//{{ +//cog.outl("//indent marker") +//for comp in bundle['components'] : +// cog.outl("\t%s_start(activator->%s);" % (comp['name'], comp['name'])) +// for service in comp['serviceDependencies'] : +// cog.outl("\tserviceTracker_open(activator->%sServiceTracker);" % service['name']) +// for service in comp['providedServices'] : +// cog.outl("\tif (activator->%s != NULL) {" % service['name']) +// cog.outl("\t\tbundleContext_registerService(context, (char *)%s, activator->%s, NULL, &activator->%sServiceRegistry);" % (service['service_name'], service['name'], service['name'])) +// cog.outl("\t}") +//}} +//indent marker //do not edit, generated code + example_start(activator->example); //do not edit, generated code + serviceTracker_open(activator->loggerServiceTracker); //do not edit, generated code + serviceTracker_open(activator->loggerOptionalServiceTracker); //do not edit, generated code + serviceTracker_open(activator->loggerManyServiceTracker); //do not edit, generated code + if (activator->command != NULL) { //do not edit, generated code + bundleContext_registerService(context, (char *)"commandService", activator->command, NULL, &activator->commandServiceRegistry); //do not edit, generated code + } //do not edit, generated code + if (activator->command2 != NULL) { //do not edit, generated code + bundleContext_registerService(context, (char *)"commandService", activator->command2, NULL, &activator->command2ServiceRegistry); //do not edit, generated code + } //do not edit, generated code +//{{end}} + + return status; +} + +celix_status_t bundleActivator_stop(void *userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + +//Stop compnent, unregister service if the service struct is allocated +//{{ +//cog.outl("//indent marker") +//for comp in bundle['components'] : +// for service in comp['providedServices'] : +// cog.outl("\tif (activator->%s != NULL) {" % service['name']) +// cog.outl("\t\tserviceRegistration_unregister(activator->%sServiceRegistry);" % (service['name'])) +// cog.outl("\t}") +// for service in comp['serviceDependencies'] : +// cog.outl("\tserviceTracker_close(activator->%sServiceTracker);" % service['name']) +// cog.outl("\t%s_stop(activator->%s);" % (comp['name'], comp['name'])) +//}} +//indent marker //do not edit, generated code + if (activator->command != NULL) { //do not edit, generated code + serviceRegistration_unregister(activator->commandServiceRegistry); //do not edit, generated code + } //do not edit, generated code + if (activator->command2 != NULL) { //do not edit, generated code + serviceRegistration_unregister(activator->command2ServiceRegistry); //do not edit, generated code + } //do not edit, generated code + serviceTracker_close(activator->loggerServiceTracker); //do not edit, generated code + serviceTracker_close(activator->loggerOptionalServiceTracker); //do not edit, generated code + serviceTracker_close(activator->loggerManyServiceTracker); //do not edit, generated code + example_stop(activator->example); //do not edit, generated code +//{{end}} + + return status; +} + +celix_status_t bundleActivator_destroy(void *userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + +//Stop compnent, unregister service if the service struct is allocated +//{{ +//cog.outl("//indent marker") +//for comp in bundle['components'] : +// cog.outl("\t%s_destroy(activator->%s);" % (comp['name'], comp['name'])) +// for service in comp['serviceDependencies'] : +// cog.outl("\tserviceTracker_destroy(activator->%sServiceTracker);" % service['name']) +// for service in comp['providedServices'] : +// cog.outl("\tif (activator->%s != NULL) {" % service['name']) +// cog.outl("\t\tfree(activator->%s);" % (service['name'])) +// cog.outl("\t\tactivator->%sState = COMPONENT_STATE_DESTROYED;" % comp['name']) +// cog.outl("\t}") +//}} +//indent marker //do not edit, generated code + example_destroy(activator->example); //do not edit, generated code + serviceTracker_destroy(activator->loggerServiceTracker); //do not edit, generated code + serviceTracker_destroy(activator->loggerOptionalServiceTracker); //do not edit, generated code + serviceTracker_destroy(activator->loggerManyServiceTracker); //do not edit, generated code + if (activator->command != NULL) { //do not edit, generated code + free(activator->command); //do not edit, generated code + activator->exampleState = COMPONENT_STATE_DESTROYED; //do not edit, generated code + } //do not edit, generated code + if (activator->command2 != NULL) { //do not edit, generated code + free(activator->command2); //do not edit, generated code + activator->exampleState = COMPONENT_STATE_DESTROYED; //do not edit, generated code + } //do not edit, generated code +//{{end}} + + return status; +} + + +static celix_status_t bundleActivator_getFirst(hash_map_pt services, void **result) { + celix_status_t status = CELIX_SUCCESS; + void *highestPrio = NULL; + int highestPrioRanking = -1; + int highestPrioServiceId = -1; + char *rankingStr; + int ranking; + char *serviceIdStr; + int serviceId; + + hash_map_iterator_pt iter = hashMapIterator_create(services); + while (hashMapIterator_hasNext(iter)) { + service_reference_pt ref = hashMapIterator_nextKey(iter); + rankingStr = NULL; + serviceIdStr = NULL; + serviceReference_getProperty(ref, (char *)OSGI_FRAMEWORK_SERVICE_RANKING, &rankingStr); + if (rankingStr != NULL) { + ranking = atoi(rankingStr); + } else { + ranking = 0; + } + serviceReference_getProperty(ref, (char *)OSGI_FRAMEWORK_SERVICE_RANKING, &serviceIdStr); + serviceId = atoi(serviceIdStr); + + if (ranking > highestPrioRanking) { + highestPrio = hashMap_get(services, ref); + } else if (ranking == highestPrioRanking && serviceId < highestPrioServiceId) { + highestPrio = hashMap_get(services, ref); + } + } + + if (highestPrio != NULL) { + (*result) = highestPrio; + } + return status; +} + + +//ResolveNewState +//{{ +//for comp in bundle['components'] : +// cog.outl("static bundleActivator_resolveState_for_%s(struct activator *activator) {" % comp['name']) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// +// cog.out("\tif (activator->%sState == COMPONENT_STATE_CREATED && " % comp['name']) +// conditions = [("activator->current_%s_service_for_%s != NULL" % (serv['name'], comp['name'])) for serv in comp['serviceDependencies'] if serv['cardinality'] == "one"] +// cog.out(" && ".join(conditions)) +// cog.outl(") {") +// cog.outl("\t\t%s_start(activator->%s);" % (comp['name'], comp['name'])) +// cog.outl("\t}") +// +// cog.out("\tif (activator->%sState == COMPONENT_STATE_STARTED && (" % comp['name']) +// conditions = [("activator->current_%s_service_for_%s == NULL" % (serv['name'], comp['name'])) for serv in comp['serviceDependencies'] if serv['cardinality'] == "one"] +// cog.out(" || ".join(conditions)) +// cog.outl(")) {") +// cog.outl("\t\t%s_stop(activator->%s);" % (comp['name'], comp['name'])) +// cog.outl("\t}") +// +// cog.outl("\treturn status;") +// cog.outl("}") +//}} +static bundleActivator_resolveState_for_example(struct activator *activator) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + if (activator->exampleState == COMPONENT_STATE_CREATED && activator->current_logger_service_for_example != NULL) { //do not edit, generated code + example_start(activator->example); //do not edit, generated code + } //do not edit, generated code + if (activator->exampleState == COMPONENT_STATE_STARTED && (activator->current_logger_service_for_example == NULL)) { //do not edit, generated code + example_stop(activator->example); //do not edit, generated code + } //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code +//{{end}} + +//Add/Remove functions for the trakkers +//{{ +//for comp in bundle['components'] : +// for service in comp['serviceDependencies'] : +// cog.outl("static celix_status_t bundleActivator_add_%s_for_%s(void *handle, service_reference_pt ref, void *service) {" % (service['name'], comp['name'])) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// cog.outl("\tstruct activator *activator = handle;") +// cog.outl("\t%s %s = service;" % (service['type'], service['name'])) +// if service['cardinality'] == "many" : +// cog.outl("\t%s_add_%s(activator->%s, %s);" % (comp['name'], service['name'], comp['name'], service['name'])) +// else : +// cog.outl("\tpthread_mutex_lock(&activator->%sLock);" % comp['name']); +// cog.outl("\t%s highest = NULL;" % service['type']); +// cog.outl("\tbundleActivator_getFirst(activator->%s_services_for_%s, (void **)&highest);" % (service['name'], comp['name'])) +// cog.outl("\tif (highest != activator->current_%s_service_for_%s) {" % (service['name'], comp['name'])) +// cog.outl("\t\tactivator->current_%s_service_for_%s = highest;" % (service['name'], comp['name'])) +// cog.outl("\t\t%s_set_%s(activator->%s, highest);" % (comp['name'], service['name'], comp['name'])) +// cog.outl("\t\tbundleActivator_resolveState_for_%s(activator);" % comp['name']); +// cog.outl("\t}") +// cog.outl("\tpthread_mutex_unlock(&activator->%sLock);" % comp['name']); +// cog.outl("\treturn status;") +// cog.outl("}") +// cog.outl("") +// cog.outl("static celix_status_t bundleActivator_remove_%s_for_%s(void *handle, service_reference_pt ref, void *service) {" % (service['name'], comp['name'])) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// cog.outl("\tstruct activator *activator = handle;") +// cog.outl("\t%s %s = service;" % (service['type'], service['name'])) +// if service['cardinality'] == "many" : +// cog.outl("\t%s_remove_%s(activator->%s, %s);" % (comp['name'], service['name'], comp['name'], service['name'])) +// else : +// cog.outl("\tpthread_mutex_lock(&activator->%sLock);" % comp['name']); +// cog.outl("\thashMap_remove(activator->%s_services_for_%s, ref);" % (service['name'], comp['name'])) +// cog.outl("\tif (activator->current_%s_service_for_%s == service) { " % (service['name'], comp['name'])) +// cog.outl("\t\t%s highest = NULL;" % service['type']); +// cog.outl("\t\tbundleActivator_getFirst(activator->%s_services_for_%s, (void **)&highest);" % (service['name'], comp['name'])) +// cog.outl("\t\tactivator->current_%s_service_for_%s = highest;" % (service['name'], comp['name'])) +// cog.outl("\t\tbundleActivator_resolveState_for_%s(activator);" % comp['name']); +// cog.outl("\t\t%s_set_%s(activator->%s, highest);" % (comp['name'], service['name'], comp['name'])) +// cog.outl("\t}") +// cog.outl("\tpthread_mutex_unlock(&activator->%sLock);" % comp['name']); +// cog.outl("\treturn status;") +// cog.outl("}") +// cog.outl("") +//}} +static celix_status_t bundleActivator_add_logger_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt logger = service; //do not edit, generated code + pthread_mutex_lock(&activator->exampleLock); //do not edit, generated code + log_service_pt highest = NULL; //do not edit, generated code + bundleActivator_getFirst(activator->logger_services_for_example, (void **)&highest); //do not edit, generated code + if (highest != activator->current_logger_service_for_example) { //do not edit, generated code + activator->current_logger_service_for_example = highest; //do not edit, generated code + example_set_logger(activator->example, highest); //do not edit, generated code + bundleActivator_resolveState_for_example(activator); //do not edit, generated code + } //do not edit, generated code + pthread_mutex_unlock(&activator->exampleLock); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +static celix_status_t bundleActivator_remove_logger_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt logger = service; //do not edit, generated code + pthread_mutex_lock(&activator->exampleLock); //do not edit, generated code + hashMap_remove(activator->logger_services_for_example, ref); //do not edit, generated code + if (activator->current_logger_service_for_example == service) { //do not edit, generated code + log_service_pt highest = NULL; //do not edit, generated code + bundleActivator_getFirst(activator->logger_services_for_example, (void **)&highest); //do not edit, generated code + activator->current_logger_service_for_example = highest; //do not edit, generated code + bundleActivator_resolveState_for_example(activator); //do not edit, generated code + example_set_logger(activator->example, highest); //do not edit, generated code + } //do not edit, generated code + pthread_mutex_unlock(&activator->exampleLock); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +static celix_status_t bundleActivator_add_loggerOptional_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt loggerOptional = service; //do not edit, generated code + pthread_mutex_lock(&activator->exampleLock); //do not edit, generated code + log_service_pt highest = NULL; //do not edit, generated code + bundleActivator_getFirst(activator->loggerOptional_services_for_example, (void **)&highest); //do not edit, generated code + if (highest != activator->current_loggerOptional_service_for_example) { //do not edit, generated code + activator->current_loggerOptional_service_for_example = highest; //do not edit, generated code + example_set_loggerOptional(activator->example, highest); //do not edit, generated code + bundleActivator_resolveState_for_example(activator); //do not edit, generated code + } //do not edit, generated code + pthread_mutex_unlock(&activator->exampleLock); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +static celix_status_t bundleActivator_remove_loggerOptional_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt loggerOptional = service; //do not edit, generated code + pthread_mutex_lock(&activator->exampleLock); //do not edit, generated code + hashMap_remove(activator->loggerOptional_services_for_example, ref); //do not edit, generated code + if (activator->current_loggerOptional_service_for_example == service) { //do not edit, generated code + log_service_pt highest = NULL; //do not edit, generated code + bundleActivator_getFirst(activator->loggerOptional_services_for_example, (void **)&highest); //do not edit, generated code + activator->current_loggerOptional_service_for_example = highest; //do not edit, generated code + bundleActivator_resolveState_for_example(activator); //do not edit, generated code + example_set_loggerOptional(activator->example, highest); //do not edit, generated code + } //do not edit, generated code + pthread_mutex_unlock(&activator->exampleLock); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +static celix_status_t bundleActivator_add_loggerMany_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt loggerMany = service; //do not edit, generated code + example_add_loggerMany(activator->example, loggerMany); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +static celix_status_t bundleActivator_remove_loggerMany_for_example(void *handle, service_reference_pt ref, void *service) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + struct activator *activator = handle; //do not edit, generated code + log_service_pt loggerMany = service; //do not edit, generated code + example_remove_loggerMany(activator->example, loggerMany); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +//{{end}} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/component.c ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/component.c b/celix-bootstrap/celix/bootstrap/templates/bundle/component.c new file mode 100644 index 0000000..4be4e9a --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/component.c @@ -0,0 +1,174 @@ +//{{ +//import json +//bundle = None +//component = None +//with open(bundleFile) as input : +// bundle = json.load(input) +//for comp in bundle['components'] : +// if comp['name'] == componentName : +// component = comp +// break +//}} +//{{end}} + + +#include + +#include + +//Component Struct +//{{ +//cog.outl("#include \"%s.h\"" % componentName); +//cog.outl("") +//cog.outl("struct %s {" % componentName) +//for service in component['serviceDependencies'] : +// if service['cardinality'] == "many" : +// cog.outl("\tarray_list_pt %sServices;" % (service['name'])) +// cog.outl("\tpthread_mutex_t mutex_for_%sServices;" % service['name']); +// else : +// cog.outl("\t%s %s;" % (service['type'], service['name'])) +// cog.outl("\tpthread_mutex_t mutex_for_%s;" % service['name']); +//}} +#include "example.h" //do not edit, generated code + +struct example { //do not edit, generated code + log_service_pt logger; //do not edit, generated code + pthread_mutex_t mutex_for_logger; //do not edit, generated code + log_service_pt loggerOptional; //do not edit, generated code + pthread_mutex_t mutex_for_loggerOptional; //do not edit, generated code + array_list_pt loggerManyServices; //do not edit, generated code + pthread_mutex_t mutex_for_loggerManyServices; //do not edit, generated code +//{{end}} +}; + +//Create function +//{{ +//cog.outl("celix_status_t %s_create(%s_pt *result) {" % (componentName, componentName)) +//cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +//cog.outl("\t%s_pt component = calloc(1, sizeof(*component));" % componentName) +//cog.outl("\tif (component != NULL) {") +//for service in component['serviceDependencies'] : +// if service['cardinality'] == "many" : +// cog.outl("\t\tcomponent->%sServices = NULL;" % service['name']) +// cog.outl("\t\tstatus = arrayList_create(&component->%sServices);" % service['name']) +// cog.outl("\t\tpthread_mutex_init(&component->mutex_for_%sServices, NULL);" % service['name']) +// else : +// cog.outl("\t\tcomponent->%s = NULL;" % service['name']) +// cog.outl("\t\tpthread_mutex_init(&component->mutex_for_%s, NULL);" % service['name']) +//}} +celix_status_t example_create(example_pt *result) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + example_pt component = calloc(1, sizeof(*component)); //do not edit, generated code + if (component != NULL) { //do not edit, generated code + component->logger = NULL; //do not edit, generated code + pthread_mutex_init(&component->mutex_for_logger, NULL); //do not edit, generated code + component->loggerOptional = NULL; //do not edit, generated code + pthread_mutex_init(&component->mutex_for_loggerOptional, NULL); //do not edit, generated code + component->loggerManyServices = NULL; //do not edit, generated code + status = arrayList_create(&component->loggerManyServices); //do not edit, generated code + pthread_mutex_init(&component->mutex_for_loggerManyServices, NULL); //do not edit, generated code +//{{end}} + (*result) = component; + } else { + status = CELIX_ENOMEM; + } + return status; +} + + +//Destroy function +//{{ +//cog.outl("celix_status_t %s_destroy(%s_pt component) {" % (componentName,componentName)) +//}} +celix_status_t example_destroy(example_pt component) { //do not edit, generated code +//{{end}} + celix_status_t status = CELIX_SUCCESS; + if (component != NULL) { + free(component); + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + return status; +} + +//Start function +//{{ +//cog.outl("celix_status_t %s_start(%s_pt component) {" % (componentName,componentName)) +//}} +celix_status_t example_start(example_pt component) { //do not edit, generated code +//{{end}} + celix_status_t status = CELIX_SUCCESS; + return status; +} + +//Stop function +//{{ +//cog.outl("celix_status_t %s_stop(%s_pt component) {" % (componentName,componentName)) +//}} +celix_status_t example_stop(example_pt component) { //do not edit, generated code +//{{end}} + celix_status_t status = CELIX_SUCCESS; + return status; +} + +//{{ +//for service in component['serviceDependencies'] : +// if service['cardinality'] == "many" : +// cog.outl("celix_status_t %s_add_%s(%s_pt component, %s %s) {" % (componentName, service['name'], componentName, service['type'], service['name'])) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// cog.outl("\tpthread_mutex_lock(&component->mutex_for_%sServices);" % service['name']) +// cog.outl("\tarrayList_add(component->%sServices, %s);" % (service['name'], service['name'])) +// cog.outl("\tpthread_mutex_unlock(&component->mutex_for_%sServices);" % service['name']) +// cog.outl("\treturn status;") +// cog.outl("}") +// cog.outl("") +// cog.outl("celix_status_t %s_remove_%s(%s_pt component, %s %s) {" % (componentName, service['name'], componentName, service['type'], service['name'])) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// cog.outl("\tpthread_mutex_lock(&component->mutex_for_%sServices);" % service['name']) +// cog.outl("\tarrayList_removeElement(component->%sServices, %s);" % (service['name'], service['name'])) +// cog.outl("\tpthread_mutex_unlock(&component->mutex_for_%sServices);" % service['name']) +// cog.outl("\treturn status;") +// cog.outl("}") +// else : +// cog.outl("celix_status_t %s_set_%s(%s_pt component, %s %s) {" % (componentName, service['name'], componentName, service['type'], service['name'])) +// cog.outl("\tcelix_status_t status = CELIX_SUCCESS;") +// cog.outl("\tpthread_mutex_lock(&component->mutex_for_%s);" % service['name']) +// cog.outl("\tcomponent->%s == %s;" % (service['name'], service['name'])) +// cog.outl("\tpthread_mutex_unlock(&component->mutex_for_%s);" % service['name']) +// cog.outl("\treturn status;") +// cog.outl("}") +// cog.outl("") +//}} +celix_status_t example_set_logger(example_pt component, log_service_pt logger) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + pthread_mutex_lock(&component->mutex_for_logger); //do not edit, generated code + component->logger == logger; //do not edit, generated code + pthread_mutex_unlock(&component->mutex_for_logger); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +celix_status_t example_set_loggerOptional(example_pt component, log_service_pt loggerOptional) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + pthread_mutex_lock(&component->mutex_for_loggerOptional); //do not edit, generated code + component->loggerOptional == loggerOptional; //do not edit, generated code + pthread_mutex_unlock(&component->mutex_for_loggerOptional); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +celix_status_t example_add_loggerMany(example_pt component, log_service_pt loggerMany) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + pthread_mutex_lock(&component->mutex_for_loggerManyServices); //do not edit, generated code + arrayList_add(component->loggerManyServices, loggerMany); //do not edit, generated code + pthread_mutex_unlock(&component->mutex_for_loggerManyServices); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +celix_status_t example_remove_loggerMany(example_pt component, log_service_pt loggerMany) { //do not edit, generated code + celix_status_t status = CELIX_SUCCESS; //do not edit, generated code + pthread_mutex_lock(&component->mutex_for_loggerManyServices); //do not edit, generated code + arrayList_removeElement(component->loggerManyServices, loggerMany); //do not edit, generated code + pthread_mutex_unlock(&component->mutex_for_loggerManyServices); //do not edit, generated code + return status; //do not edit, generated code +} //do not edit, generated code + +//{{end}} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/component.h ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/component.h b/celix-bootstrap/celix/bootstrap/templates/bundle/component.h new file mode 100644 index 0000000..15fdfba --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/component.h @@ -0,0 +1,69 @@ +//{{ +//import json +//bundle = None +//component = None +//with open(bundleFile) as input : +// bundle = json.load(input) +//for comp in bundle['components'] : +// if comp['name'] == componentName : +// component = comp +// break +// +//cog.outl("#ifndef __%s_H_" % componentName.upper()) +//cog.outl("#define __%s_H_" % componentName.upper()) +//cog.outl("") +// +//for service in component['serviceDependencies'] : +// cog.outl("#include <%s>" % service['include']) +//cog.outl("") +// +//}} +#ifndef __EXAMPLE_H_ //do not edit, generated code +#define __EXAMPLE_H_ //do not edit, generated code + +#include //do not edit, generated code +#include //do not edit, generated code +#include //do not edit, generated code + +//{{end}} + +#include +#include + +//{{ +//cog.outl("typedef struct %s *%s_pt;" % (componentName, componentName)) +//cog.outl("") +//cog.outl("celix_status_t %s_create(%s_pt *component);" % (componentName, componentName)) +//cog.outl("celix_status_t %s_start(%s_pt component);" % (componentName, componentName)) +//cog.outl("celix_status_t %s_stop(%s_pt component);" % (componentName, componentName)) +//cog.outl("celix_status_t %s_destroy(%s_pt component);" % (componentName, componentName)) +// +//#TODO add remote of service dependencies +//}} +typedef struct example *example_pt; //do not edit, generated code + +celix_status_t example_create(example_pt *component); //do not edit, generated code +celix_status_t example_start(example_pt component); //do not edit, generated code +celix_status_t example_stop(example_pt component); //do not edit, generated code +celix_status_t example_destroy(example_pt component); //do not edit, generated code +//{{end}} + +//{{ +//for service in component['serviceDependencies'] : +// if service['cardinality'] == "many" : +// cog.outl("celix_status_t %s_add_%s(%s_pt component, %s %s);" % (componentName, service['name'], componentName, service['type'], service['name'])) +// cog.outl("celix_status_t %s_remove_%s(%s_pt component, %s %s);" % (componentName, service['name'], componentName, service['type'], service['name'])) +// else : +// cog.outl("celix_status_t %s_set_%s(%s_pt component, %s %s);" % (componentName, service['name'], componentName, service['type'], service['name'])) +//}} +celix_status_t example_set_logger(example_pt component, log_service_pt logger); //do not edit, generated code +celix_status_t example_set_loggerOptional(example_pt component, log_service_pt loggerOptional); //do not edit, generated code +celix_status_t example_add_loggerMany(example_pt component, log_service_pt loggerMany); //do not edit, generated code +celix_status_t example_remove_loggerMany(example_pt component, log_service_pt loggerMany); //do not edit, generated code +//{{end}} + +//{{ +//cog.outl("#endif //__%s_H_" % componentName.upper()) +//}} +#endif //__EXAMPLE_H_ //do not edit, generated code +//{{end}} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/bundle/deploy.cmake ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/bundle/deploy.cmake b/celix-bootstrap/celix/bootstrap/templates/bundle/deploy.cmake new file mode 100644 index 0000000..6157f1d --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/bundle/deploy.cmake @@ -0,0 +1,18 @@ +#{{ +#import json +#bundle = None +#with open(bundleFile) as input : +# bundle = json.load(input) +#cog.outl("deploy( \"%s\" BUNDLES" % bundle['name']) +#cog.outl("\t${CELIX_BUNDLES_DIR}/shell.zip") +#cog.outl("\t${CELIX_BUNDLES_DIR}/shell_tui.zip") +#cog.outl("\t${CELIX_BUNDLES_DIR}/log_service.zip") +#cog.outl("\t%s" % bundle['name']) +#}} +deploy( "mybundle" BUNDLES #do not edit, generated code + ${CELIX_BUNDLES_DIR}/shell.zip #do not edit, generated code + ${CELIX_BUNDLES_DIR}/shell_tui.zip #do not edit, generated code + ${CELIX_BUNDLES_DIR}/log_service.zip #do not edit, generated code + mybundle #do not edit, generated code +#{{end}} +) http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/project/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/project/CMakeLists.txt b/celix-bootstrap/celix/bootstrap/templates/project/CMakeLists.txt new file mode 100644 index 0000000..04fea0b --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/project/CMakeLists.txt @@ -0,0 +1,30 @@ +#{{ +# import json +# project = None +# with open(projectFile) as input : +# project = json.load(input) +#}} +#{{end}} + +cmake_minimum_required(VERSION 2.8) + +#{{ +# cog.outl("project(%s C)" % project['name']) +#}} +project(myproject C) #do not edit, generated code +#{{end}} + +#{{ +# cog.outl("set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} \"%s/share/celix/cmake/modules\")" % project['celix_install_dir']) +#}} +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/usr/local/share/celix/cmake/modules") #do not edit, generated code +#{{end}} + +find_package(CELIX REQUIRED) +include_directories(${CELIX_INCLUDE_DIRS}) + +#TODO add sub directory for every bundle +#e.g. +#add_subdirectory(mybundle) + +deploy_targets() http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/project/project.json ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/project/project.json b/celix-bootstrap/celix/bootstrap/templates/project/project.json new file mode 100644 index 0000000..db48217 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/project/project.json @@ -0,0 +1,4 @@ +{ + "name" : "myproject", + "celix_install_dir": "/usr/local" +} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/services/service.h ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/services/service.h b/celix-bootstrap/celix/bootstrap/templates/services/service.h new file mode 100644 index 0000000..9a8aae9 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/services/service.h @@ -0,0 +1,48 @@ +//{{ +//import json +//services = None +//service = None +//with open(descriptorFile) as input : +// services = json.load(input) +//for serv in services : +// if serv['name'] == serviceName : +// service = serv +// break +// +//cog.outl("#ifndef __%s_H_" % serviceName.upper()) +//cog.outl("#define __%s_H_" % serviceName.upper()) +//cog.outl("") +// +//}} +#ifndef __EXAMPLE_H_ //do not edit, generated code +#define __EXAMPLE_H_ //do not edit, generated code +//{{end}} + +//TODO add needed includes + +//{{ +//cog.outl("#define %s_SERVICE_NAME \"%s_service\"" % (serviceName.upper(), serviceName)) +//cog.outl("") +//cog.outl("typedef struct %s_service *%s_service_pt;" % (serviceName, serviceName)) +//cog.outl("") +//cog.outl("struct %s_service {" % serviceName) +//cog.outl("\tvoid *handle;") +//}} +#define BENCHMARK_SERVICE_NAME "benchmark_service" +typedef struct benchmark_service *benchmark_service_pt; + +struct benchmark_service { + benchmark_handler_pt handler; +//{{end}}} + + //TODO add service methods + +//{{ +//cog.outl("};") +//cog.outl("") +//cog.outl("") +//cog.outl("#endif /* __%s_H_ */" % serviceName) +//}} +}; +#endif /* BENCHMARK_SERVICE_H_ */ +//{{end}} http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/celix/bootstrap/templates/services/services.json ---------------------------------------------------------------------- diff --git a/celix-bootstrap/celix/bootstrap/templates/services/services.json b/celix-bootstrap/celix/bootstrap/templates/services/services.json new file mode 100644 index 0000000..f6efc03 --- /dev/null +++ b/celix-bootstrap/celix/bootstrap/templates/services/services.json @@ -0,0 +1,4 @@ +[ + { "name" : "example1" }, + { "name" : "example2" } +] http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/scripts/celix-bootstrap ---------------------------------------------------------------------- diff --git a/celix-bootstrap/scripts/celix-bootstrap b/celix-bootstrap/scripts/celix-bootstrap new file mode 100755 index 0000000..22d43ec --- /dev/null +++ b/celix-bootstrap/scripts/celix-bootstrap @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +import celix.bootstrap.argument_parser + +celix.bootstrap.argument_parser.main() http://git-wip-us.apache.org/repos/asf/celix/blob/5d703d3a/celix-bootstrap/setup.py ---------------------------------------------------------------------- diff --git a/celix-bootstrap/setup.py b/celix-bootstrap/setup.py new file mode 100644 index 0000000..f8245d2 --- /dev/null +++ b/celix-bootstrap/setup.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +""" Setup.py for Cog + http://nedbatchelder.com/code/cog + + Copyright 2004-2015, Ned Batchelder. +""" + +from distutils.core import setup + +setup( + name = 'celix-bootstrap', + version = '0.1.0', + url = '', + author = '', + author_email = '', + description = + 'celix-bootstrap: A code generator / project generator for Apache Celix.', + + license = 'Apache License, Version 2.0', + + packages = [ + 'celix', + 'celix/bootstrap' + ], + + scripts = [ + 'scripts/celix-bootstrap', + ], + + package_data={'celix' : ['bootstrap/templates/**/*']}, +)