114.

previous chapter table of contents next chapter
  

File Classifier with Events

Let's make this discussion more concrete by looking at a new file classifier application that can have its set of mappings dynamically updated.

The first thing to be modified is the FileClassifier interface. This needs to be extended to a MutableFileClassifier interface, known to all objects. This new interface adds methods that will add and remove types, and that will also register listeners for events. The event types are labeled with two constants. The listener model is simple, and does not include handbacks or leases. The sequence identifier must be increasing, so we just add 1 on each event generation, although we don't really need it here: it is easy for a listener to just make MIME type queries again.

 package common; import java.io.Serializable; /**  * MutableFileClassifier.java  */ import net.jini.core.event.RemoteEventListener; import net.jini.core.event.EventRegistration; public interface MutableFileClassifier extends FileClassifier {     static final public long ADD_TYPE = 1;     static final public long REMOVE_TYPE = 2;     /*      * Add the MIME type for the given suffix.      * The suffix does not contain '.' e.g. "gif".      * Overrides any previous MIME type for that suffix      */     public void addType(String suffix, MIMEType type)         throws java.rmi.RemoteException;    /*     * Delete the MIME type for the given suffix.     * The suffix does not contain '.' e.g. "gif".     * Does nothing if the suffix is not known     */     public void removeMIMEType(String suffix, MIMEType type)         throws java.rmi.RemoteException;     public EventRegistration addRemoteListener(RemoteEventListener listener)         throws java.rmi.RemoteException; } // MutableFileClasssifier 

The RemoteFileClassifier interface is known only to services, and it just changes its package and inheritance for any service implementation:

 package mutable; import common.MutableFileClassifier; import java.rmi.Remote; /**  * RemoteFileClassifier.java  */ public interface RemoteFileClassifier extends MutableFileClassifier, Remote { } // RemoteFileClasssifier 

Previous implementations of file classifier services (such as in Chapter 8) use a static list of if...then statements because they deal with a fixed set of types. For this implementation, where the set of mappings can change, we change the implementation to a dynamic map keyed on file suffixes. It manages the event listener list for multiple listeners in the simple way discussed earlier in this chapter, and it generates events whenever a new suffix/type is added or successfully removed. The following code is an implementation of the file classifier service with this alternative implementation and an event list:

 package mutable; import java.rmi.server.UnicastRemoteObject; import java.rmi.MarshalledObject; import net.jini.core.event.RemoteEventListener; import net.jini.core.event.RemoteEvent; import net.jini.core.event.EventRegistration; import java.rmi.RemoteException; import net.jini.core.event.UnknownEventException ; import javax.swing.event.EventListenerList; import common.MIMEType; import common.MutableFileClassifier; import java.util.Map; import java.util.HashMap; /**  * FileClassifierImpl.java   */ public class FileClassifierImpl extends UnicastRemoteObject                                 implements RemoteFileClassifier {     /**      * Map of String extensions to MIME types      */     protected Map map = new HashMap();     /**      * Listeners for change events      */     protected EventListenerList listenerList = new EventListenerList();     protected long seqNum = 0L;     public MIMEType getMIMEType(String fileName)         throws java.rmi.RemoteException {         System.out.println("Called with " + fileName);         MIMEType type;         String fileExtension;         int dotIndex = fileName.lastIndexOf('.');         if (dotIndex == 1  dotIndex + 1 == fileName.length()) {             // can't find suitable suffix             return null;         }         fileExtension= fileName.substring(dotIndex + 1);         type = (MIMEType) map.get(fileExtension);         return type;     }     public void addType(String suffix, MIMEType type)         throws java.rmi.RemoteException {         map.put(suffix, type);         fireNotify(ADD_TYPE);     }     public void removeMIMEType(String suffix, MIMEType type)         throws java.rmi.RemoteException {         if (map.remove(suffix) != null) {             fireNotify(REMOVE_TYPE);         }     }       public EventRegistration addRemoteListener(RemoteEventListener listener)         throws java.rmi.RemoteException {         listenerList.add(RemoteEventListener.class, listener);         return new EventRegistration(0, this, null, 0);     }     // Notify all listeners that have registered interest for     // notification on this event type. The event instance     // is lazily created using the parameters passed into     // the fire method.     protected void fireNotify(long eventID) {         RemoteEvent remoteEvent = null;         // Guaranteed to return a non-null array         Object[] listeners = listenerList.getListenerList();         // Process the listeners last to first, notifying         // those that are interested in this event         for (int i = listeners.length - 2; i >= 0; i -= 2) {             if (listeners[i] == RemoteEventListener.class) {                RemoteEventListener listener = (RemoteEventListener) listeners[i+1];                 if (remoteEvent == null) {                     remoteEvent = new RemoteEvent(this, eventID,                                                   seqNum++, null);             }             try {                 listener.notify(remoteEvent);             } catch(UnknownEventException e) {                 e.printStackTrace();             } catch(RemoteException e) {                 e.printStackTrace();                 }              }          }      }     public FileClassifierImpl() throws java.rmi.RemoteException {         // load a predefined set of MIME type mappings         map.put("gif", new MIMEType("image", "gif"));         map.put("jpeg", new MIMEType("image", "jpeg"));         map.put("mpg", new MIMEType("video", "mpeg"));         map.put("txt", new MIMEType("text", "plain"));         map.put("html", new MIMEType("text", "html"));     } } // FileClassifierImpl 

The proxy changes its inheritance, and as a result has more methods to implement, which it just delegates to its server object. The following class is for the proxy:

 package mutable; import common.MutableFileClassifier; import common.MIMEType; import java.io.Serializable; import java.io.IOException; import java.rmi.Naming; import net.jini.core.event.EventRegistration; import net.jini.core.event.RemoteEventListener; /**  * FileClassifierProxy  */ public class FileClassifierProxy implements MutableFileClassifier, Serializable {     RemoteFileClassifier server = null;     public FileClassifierProxy(FileClassifierImpl serv) {         this.server = serv;         if (serv==null) System.err.println("server is null");     }     public MIMEType getMIMEType(String fileName)         throws java.rmi.RemoteException {         return server.getMIMEType(fileName);     }     public void addType(String suffix, MIMEType type)         throws java.rmi.RemoteException {         server.addType(suffix, type);     }       public void removeMIMEType(String suffix, MIMEType type)         throws java.rmi.RemoteException {         server.removeMIMEType(suffix, type);     }     public EventRegistration addRemoteListener(RemoteEventListener listener)         throws java.rmi.RemoteException {         return server.addRemoteListener(listener);     } } // FileClassifierProxy 
  


A Programmer[ap]s Guide to Jini Technology
A Programmer[ap]s Guide to Jini Technology
ISBN: 1893115801
EAN: N/A
Year: 2000
Pages: 189

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net