← Prev in month ← Prev in thread

Comparing ServiceRefernces and CallbackReferences using equals() method

From
Mark Combellack <>
Date
2008-05-20T10:19:19+00:00
ID
Thread
Comparing ServiceRefernces and CallbackReferences using equals() method
Hi,

 

One of our SCA users has just asked whether it is OK to call
equals() on ServiceReferences and CallbackReferences to compare whether two
references refer to the same target. I had a quick skim through the Java Specifications
but I did not find anything.

 

I’m interested as to whether the equals() method on
ServiceReferences has been previously discussed and whether the TC feels that
it is worth opening an issue for it.

 

 

 

I’ve distilled the main points of what the user wanted
to do and illustrated it with a small sample as described below.

 
There is a DownloadService
     which you can use to asynchronously download files.

 
The client of the DownloadService
     can optionally register for download progress notifications

 
The client of the
     DownloadService can unregister for download progress notifications.

 
The DownloadService should
     ignore multiple requests from the same client to register for Download
     Service progress notifications

 
More than one client may
     register for download progress notifications for a particular download

 

 

The problem is to make sure that a client does not register
more than once to receive progress notifications, the DownloadService implementation
needs to be able to compare ServiceReferences using the standard Java equals() method as
shown by the code below:

 

 

public class DownloadServiceImpl implements
DownloadService {

 

    private final Map<String,
List<ServiceReference<DownloadServiceNotification>>> listeners 

        = new
HashMap<String,
List<ServiceReference<DownloadServiceNotification>>>();

    

    public synchronized void
addListener(

           
String downloadID, ServiceReference<DownloadServiceNotification>
newListener) {

        

        final
List<ServiceReference<DownloadServiceNotification>>
downloadListeners 

           
= listeners.get(downloadID);

        if
(downloadListeners == null) {

           
// listener for a download that has no listeners so add one.

           
// Code not shown.....

        } else {

           
// Is the listener already registered

           
for (ServiceReference<DownloadServiceNotification> l : downloadListeners)
{

 

// *********

// PROBLEM IS HERE. Can I
call equals() on a ServiceReference?

// *********

               
if (l.equals(newListener)) {

                   
// Already registered so ignore request

                   
return;

               
}

           
}

           

           
// Not registered so add

           
downloadListeners.add(newListener);

        }

    }

 

 

 

 

I believe what the user wants the equals() method to do is
the following. Two ServiceReferences/CallbackReferences are equal if:

 

 
For Stateless, they refer to
     the same target

 
For Conversational, they refer
     to the same target and Conversation.

 

 

 

 

 

Below this point, I have included some sample code fragments
that may or may not be useful in illustrating what the user wants to do. Feel
free to skip the rest of the email if you feel the problem is already well
defined.

 

 

 

 

 

The Download Service interface would end up being something
like:

 

public interface DownloadService {

 

    // Returns a downloadID

    String download(URL url);

    

    void addListener(String
downloadID, ServiceReference<DownloadServiceNotification> listener);

    

    void removeListener(String
downloadID, ServiceReference<DownloadServiceNotification> listener);

    

    boolean
isDownloadCompleted(String downloadID);

}

 

 

The DownloadServiceNotification interface would be something
like:

 

public interface DownloadServiceNotification {

 

    // Download is waiting in queue
to be downloaded

    void queued(String id);

    

    // Download has started

    void started(String id);

    

    // Download progress notification

    void progress(String id, int
percentageComplete);

    

    // Download completed

    void completed(String id);

}

 

 

 

The client code would want to do something similar to:

 

public class Client implements
DownloadServiceNotification {

    @Context

    protected ComponentContext
componentContext;

 

    @Reference

    protected DownloadService
downloadService;

    

    public void download(URL url) {

        final
String downloadID = downloadService.download(url);

        

        // wait
10 seconds to see if the download is completed

       
sleep(10);

        

        if
(downloadService.isDownloadCompleted(downloadID)) {

           
// Download completed

           
return;

        }

     

        // Download
not complete so register a listener and handle asynchronously

        final
ServiceReference<DownloadServiceNotification> self 

           
= componentContext.createSelfReference(DownloadServiceNotification.class);

       
downloadService.addListener(downloadID, self);

    }

}

 

 

 

Thanks,

 

Mark
← Prev in month ← Prev in thread