Guillaume Nodet created KARAF-5757:
--------------------------------------

             Summary: Improve shell reflection capabilities
                 Key: KARAF-5757
                 URL: https://issues.apache.org/jira/browse/KARAF-5757
             Project: Karaf
          Issue Type: New Feature
            Reporter: Guillaume Nodet
             Fix For: 4.3.0


Writing karaf scripts can be very tedious when dealing with reflection and 
classes.
 It needs to be simplified a lot.
 Below is a script definining a command to create a service tracker:
{code:java}
create-tracker = {
        trackingContext = $1
        trackedClass = $2
        serviceAdded = $3
        serviceRemoved = $4
        shellClassLoader = (($.session class) getClassLoader)
        arrayClass = ($shellClassLoader loadClass java.lang.reflect.Array)
        handler = {
                proxy = $1
                method = $2
                arguments = $3
                name = ($method name)
                # echo "Invoking $name"
                if { $name equals "addingService" } \
                then {
                        ref = ($arrayClass get $arguments 0)
                        svc = ($.context getService $ref)
                        $serviceAdded execute $.commandSession [ $svc ]
                        $svc
                } elif { $name equals "removedService" } \
                then {
                        ref = ($arrayClass get $arguments 0)
                        svc = ($arrayClass get $arguments 1)
                        $serviceRemoved execute $.commandSession [ $svc ]
                        $.context ungetService $ref
                }
        }
        # create handler
        customizerClass = ($shellClassLoader loadClass 
org.osgi.util.tracker.ServiceTrackerCustomizer)
        array = ([ $customizerClass ] toArray ($arrayClass newInstance 
"java.lang.Class" 1))
        proxyClass = ($shellClassLoader loadClass java.lang.reflect.Proxy)
        customizer = ($proxyClass newProxyInstance $shellClassLoader $array 
$handler)
        # create tracker
        trackerClass = ($shellClassLoader loadClass 
org.osgi.util.tracker.ServiceTracker)
        constructor = ($trackerClass constructor 
org.osgi.framework.BundleContext java.lang.String 
org.osgi.util.tracker.ServiceTrackerCustomizer)
        if { "java.lang.Class" equals ($trackedClass class) } \
        then {
                trackedClass = ($trackedClass name)
        }
        tracker = ($constructor newInstance $trackingContext $trackedClass 
$customizer)
        $tracker
}

tracker = (create-tracker $.context "org.osgi.service.cm.ManagedService" { s = 
(($1 class) toString); echo "service-added $s" } { s = (($1 class) toString); 
echo "service-removed $s" })
$tracker open true
{code}
Also, the Gogo Runtime expander does not support subscripts in java arrays. It 
has to be a {{List}}. This should be fixed, see 
[https://github.com/apache/felix/blob/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Expander.java#L1483].

Conversion from list to array would be needed too.

In order to be more user-friendly, we need helper methods to define a context 
class loader, load classes (the String -> Class conversion needs to leverage 
it).



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to