View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESSS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.jini;
20  
21  import java.io.IOException;
22  import java.rmi.RMISecurityManager;
23  import java.rmi.RemoteException;
24  import java.util.LinkedList;
25  import java.util.List;
26  
27  import net.jini.core.entry.Entry;
28  import net.jini.core.lookup.ServiceRegistrar;
29  import net.jini.core.lookup.ServiceTemplate;
30  import net.jini.discovery.DiscoveryEvent;
31  import net.jini.discovery.DiscoveryGroupManagement;
32  import net.jini.discovery.DiscoveryListener;
33  import net.jini.discovery.LookupDiscovery;
34  import net.jini.lookup.entry.Name;
35  
36  /**
37   * The LookupManager class can be used to interrogate a 
38   * lookup service in order to obtain a proxy for a service.
39   * LookupManager is only a convenience class, which 
40   * invokes the discovery protocol in order to obtain a
41   * proxy for the lookup service and then interrogate it
42   * opportunely. The Jgroup programmer can use different
43   * techniques to perform the lookup, as illustrated in
44   * the Jini specification.
45   * <p>
46   * In order to search for a group which has joined the
47   * Jini federation, a GroupEntry entry containing the
48   * group name must be included in the template.
49   *
50   * @author  Alberto Montresor
51   * @author  Rohnny Moland
52   * @since   Jgroup 1.1
53   */
54  public class LookupManager
55    implements DiscoveryListener
56  {
57  
58    ////////////////////////////////////////////////////////////////////////////////////////////
59    // Static section
60    ////////////////////////////////////////////////////////////////////////////////////////////
61  
62    /** Singleton manager */
63    private static LookupManager manager; 
64    
65  
66    /**
67     * Perform a lookup in the lookup service, searching for the
68     * specified object with the specified attributes.
69     * @param template template of the service to be searched
70     * @return a proxy for the service, or null is no service can be
71     *  found with the specified template
72     * @throws IOException an error occurred in doing lookup
73     */
74    public static Object lookup(ServiceTemplate template)
75      throws IOException
76    {
77      return lookup(template, 5000);
78    }
79  
80    /**
81     * Perform a lookup in the lookup service, searching for the
82     * specified object with the specified attributes.
83     * @param template template of the service to be searched
84     * @param timeout maximum time allowed for the lookup operation
85     * @return a proxy for the service, or null is no service can be
86     *  found with the specified template
87     * @throws IOException an error occurred in doing lookup
88     */
89    public static Object lookup(ServiceTemplate template, int timeout)
90      throws IOException
91    {
92      if (manager == null) 
93        manager = new LookupManager();
94      return manager.searchDiscovered(template, timeout);
95    }
96  
97    /**
98     * Perform a lookup in the lookup service, searching for the given
99     * service name.
100    * 
101    * @param serviceName the service name to lookup
102    * @return the proxy for the service
103    * @throws IOException
104    */
105   public static Object lookup(String serviceName)
106     throws IOException
107   {
108     Entry[] attr = new Entry[] { new GroupEntry(serviceName) };
109     ServiceTemplate template = new ServiceTemplate(null, null, attr);
110     return lookup(template);
111   }
112 
113   
114  /**
115   * Perform a lookup for the given <code>Name</code>.
116   * 
117   * @param name attribute name to lookup
118   * @return the proxy for the service
119   */ 
120  public static Object lookup(Name name)
121    throws IOException
122  {
123    Entry[] attr = new Entry[]{name};
124    ServiceTemplate template = new ServiceTemplate(null, null, attr);
125    return lookup(template);
126  }
127   
128   
129   ////////////////////////////////////////////////////////////////////////////////////////////
130   // Fields
131   ////////////////////////////////////////////////////////////////////////////////////////////
132 
133   private List<ServiceRegistrar> registrars = new LinkedList<ServiceRegistrar>();
134 
135 
136   ////////////////////////////////////////////////////////////////////////////////////////////
137   // Constructor
138   ////////////////////////////////////////////////////////////////////////////////////////////
139 
140   /**
141    * Private constructor for singleton use
142    * @throws IOException an error occurred in starting discovery
143    */
144   private LookupManager()
145     throws IOException
146   {
147     if (System.getSecurityManager() == null)
148       System.setSecurityManager(new RMISecurityManager());
149 
150     // Create lookup discovery object and have it notify us
151     LookupDiscovery ld = new LookupDiscovery(DiscoveryGroupManagement.ALL_GROUPS);
152     ld.addDiscoveryListener(this);
153   }
154 
155   
156   ////////////////////////////////////////////////////////////////////////////////////////////
157   // Methods from DiscoveryListener
158   ////////////////////////////////////////////////////////////////////////////////////////////
159 
160   public synchronized void discovered(DiscoveryEvent ev)
161   {
162     ServiceRegistrar[] regs = ev.getRegistrars();
163     for (int i=0; i < regs.length; i++)
164       registrars.add(regs[i]);
165     notifyAll();
166   }
167 
168   public synchronized void discarded(DiscoveryEvent ev)
169   {
170     ServiceRegistrar[] regs = ev.getRegistrars();
171     for (int i=0; i < regs.length; i++)
172       registrars.remove(regs[i]);
173     notifyAll();
174   }
175 
176   
177   ////////////////////////////////////////////////////////////////////////////////////////////
178   // Private Method
179   ////////////////////////////////////////////////////////////////////////////////////////////
180 
181   private synchronized Object searchDiscovered(ServiceTemplate template, int timeout)
182     throws RemoteException
183   {
184     long end = System.currentTimeMillis() + timeout;
185     long timeLeft = end - System.currentTimeMillis();
186     while (timeLeft > 0 && registrars.isEmpty()) {
187       try { wait(timeLeft); } catch (InterruptedException e) { }
188       timeLeft = end - System.currentTimeMillis();
189     }
190     if (!registrars.isEmpty()) {
191       ServiceRegistrar reg = (ServiceRegistrar) registrars.get(0);
192       return reg.lookup(template);
193     } else {
194       return null;
195     }
196   }
197   
198 } // END LookupManager