Skip to content

Commit

Permalink
implements extender example
Browse files Browse the repository at this point in the history
Signed-off-by: Juergen Albert <j.albert@data-in-motion.biz>
  • Loading branch information
juergen-albert committed Jan 15, 2024
1 parent 8704964 commit e02f60d
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 0 deletions.
11 changes: 11 additions & 0 deletions org.gecko.playground.extender.example/.classpath
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
<classpathentry kind="src" output="bin" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
23 changes: 23 additions & 0 deletions org.gecko.playground.extender.example/.project
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.gecko.playground.extender.example</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>bndtools.core.bndbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>bndtools.core.bndnature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
encoding/bnd.bnd=UTF-8
@@ -0,0 +1,14 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=17
1 change: 1 addition & 0 deletions org.gecko.playground.extender.example/bnd.bnd
@@ -0,0 +1 @@
-buildpath: org.gecko.playground
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2012 - 2024 Data In Motion and others.
* All rights reserved.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Data In Motion - initial API and implementation
*/
package org.gecko.playground.extender.example;

import org.osgi.annotation.bundle.Header;
import org.gecko.playground.log.Log;

/**
*
* @author Juergen Albert
* @since 15 Jan 2024
*/
@Header(name = "Stupid-DS-Class", value = "org.gecko.playground.extender.example.StupidDSComponent;test=blub")
public class StupidDSComponent implements Log{

/**
* Creates a new instance.
*/
public StupidDSComponent() {
System.out.println("Hello World");
}

/*
* (non-Javadoc)
* @see org.gecko.playground.log.Log#logMessage(java.lang.String)
*/
@Override
public void logMessage(String message) {
// TODO Auto-generated method stub

}

/*
* (non-Javadoc)
* @see org.gecko.playground.log.Log#info(java.lang.String)
*/
@Override
public String info(String message) {
// TODO Auto-generated method stub
return null;
}

}
11 changes: 11 additions & 0 deletions org.gecko.playground.extender/.classpath
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
<classpathentry kind="src" output="bin" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
23 changes: 23 additions & 0 deletions org.gecko.playground.extender/.project
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.gecko.playground.extender</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>bndtools.core.bndbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>bndtools.core.bndnature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
encoding/bnd.bnd=UTF-8
14 changes: 14 additions & 0 deletions org.gecko.playground.extender/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=17
3 changes: 3 additions & 0 deletions org.gecko.playground.extender/bnd.bnd
@@ -0,0 +1,3 @@
-buildpath: \
org.osgi.framework,\
org.osgi.util.tracker
14 changes: 14 additions & 0 deletions org.gecko.playground.extender/hello-component.bndrun
@@ -0,0 +1,14 @@
-runfw: org.apache.felix.framework;version='[7.0.5,7.0.5]'
-runee: JavaSE-17
-runrequires: \
bnd.identity;id='org.apache.felix.gogo.command',\
bnd.identity;id='org.apache.felix.gogo.shell',\
bnd.identity;id='org.gecko.playground.extender',\
bnd.identity;id='org.gecko.playground.extender.example'
-runbundles: \
org.apache.felix.gogo.command;version='[1.1.2,1.1.3)',\
org.apache.felix.gogo.runtime;version='[1.1.6,1.1.7)',\
org.apache.felix.gogo.shell;version='[1.1.4,1.1.5)',\
org.gecko.playground.extender;version=snapshot,\
org.gecko.playground.extender.example;version=snapshot,\
org.gecko.playground;version=snapshot
@@ -0,0 +1,144 @@
/**
* Copyright (c) 2012 - 2024 Data In Motion and others.
* All rights reserved.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Data In Motion - initial API and implementation
*/
package org.gecko.playground.extender.activator;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.osgi.annotation.bundle.Header;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;

@Header(name = "Bundle-Activator", value = "org.gecko.playground.extender.activator.Activator")
public class Activator implements BundleActivator {

final Map<Bundle, ServiceRegistration<?>> registrations = new ConcurrentHashMap<>();


private BundleTracker tracker;

/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
@Override
public void start(BundleContext context) throws Exception {
System.out.println("Activating Stupid Component Service Runtime");
tracker = new BundleTracker<>(context, Bundle.ACTIVE|Bundle.STARTING|Bundle.STOPPING, new BundleTrackerCustomizer<Bundle>() {


@Override
public Bundle addingBundle(Bundle bundle, BundleEvent event) {
String instruction = bundle.getHeaders().get("Stupid-DS-Class");
if(instruction != null) {
System.out.println("Header " + instruction);
String[] split = instruction.split(";");
String clazzName = split[0];
Dictionary<String, String> properties = new Hashtable<>();
if(split.length > 1) {
for(int i = 1; i < split.length; i++) {
String prop = split[i];
String[] strings = prop.split("=");
if(strings.length == 2) {
properties.put(strings[0], strings[1]);
} else {
System.err.println("Property " + prop + " is unparsable");
}

}
}

BundleWiring adapt = bundle.adapt(BundleWiring.class);
try {
Class<?> clazz = adapt.getClassLoader().loadClass(clazzName);
Constructor<?> constructor = clazz.getConstructor();
Object newInstance = constructor.newInstance(null);
Class<?>[] interfaces = clazz.getInterfaces();
String[] services = new String[] {clazzName};
if(interfaces.length > 0) {
List<String> list = Arrays.asList(interfaces).stream().map(Class::getName).collect(Collectors.toList());
services = list.toArray(new String[interfaces.length]);
}
ServiceRegistration<?> registerService = bundle.getBundleContext().registerService(services, newInstance, properties);
registrations.put(bundle, registerService);
} catch (ClassNotFoundException e) {
System.err.println(instruction + " not found in " + bundle.getSymbolicName());
} catch (NoSuchMethodException e) {
System.err.println(instruction + " does not have a no Args constructor");
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return bundle;
}
return null;
}

@Override
public void modifiedBundle(Bundle bundle, BundleEvent event, Bundle object) {
// TODO Auto-generated method stub

}

@Override
public void removedBundle(Bundle bundle, BundleEvent event, Bundle object) {
ServiceRegistration<?> registration = registrations.remove(bundle);
if(registration != null) {
registration.unregister();
}
}
});

tracker.open();
}

/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception {
tracker.close();
registrations.values().forEach(ServiceRegistration::unregister);
registrations.clear();
}

}

0 comments on commit e02f60d

Please sign in to comment.