View Javadoc

1   /* (c) Copyright 2003 Caleigo AB, All rights reserved. 
2    * 
3    * This library is free software; you can redistribute it and/or
4    * modify it under the terms of the GNU Lesser General Public
5    * License as published by the Free Software Foundation; either
6    * version 2.1 of the License, or (at your option) any later version.
7    * 
8    * This library is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   * Lesser General Public License for more details.
12   * 
13   * You should have received a copy of the GNU Lesser General Public
14   * License along with this library; if not, write to the Free Software
15   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16   *  
17   */
18  
19  package org.caleigo.service;
20  
21  
22  import java.lang.reflect.Proxy;
23  import java.util.*;
24  
25  import org.caleigo.toolkit.log.*;
26  import org.caleigo.toolkit.tunnel.*;
27  
28  /*** ServiceProvider is a singleton class that provides a single point of access
29   * for IServices. Local services are added to the ServiceProvider by using the
30   * <code>addService</code> method. The <code>addTunnel</code> method is used to
31   * add connections to remote ServiceProviderServers that are used to connect to
32   * remote services.
33   *
34   * @author  Mattias Hagstrand
35   * @version 1.00
36   * 
37   *//* 
38   *
39   * WHEN        WHO               WHY & WHAT
40   * -----------------------------------------------------------------------------
41   * 2002-07-29  Mattias Hagstrand    Creation
42   */
43  public class ServiceProvider
44  {
45      // Static data members -----------------------------------------------------
46      protected static ServiceProvider sInstance;
47      
48      // Data members ------------------------------------------------------------
49      protected List mServices;
50      protected List mTunnels;
51      protected Hashtable mProxyHandlers;
52      
53      // Static methods ----------------------------------------------------------
54      public static ServiceProvider getInstance()
55      {
56          if (sInstance == null)
57              sInstance = new ServiceProvider();
58          return sInstance;
59      }
60      
61      // Constructors ------------------------------------------------------------
62      protected ServiceProvider()
63      {
64          mServices = new ArrayList();
65          mTunnels = new ArrayList();
66          mProxyHandlers = new Hashtable();
67      }
68      
69      // Access methods ----------------------------------------------------------
70      
71      /*** Adds a local service to this ServiceProvider.
72       */
73      public void addService(IService service)
74      {
75          mServices.add(service);
76      }
77      
78      /*** Removes a local service from this ServiceProvider.
79       */
80      public void removeService(IService service)
81      {
82          mServices.remove(service);
83      }
84      
85      /*** Adds a tunnel that can be used by this ServiceProvider to access remote
86       * service providers.
87       */
88      public void addTunnel(ITunnel tunnel)
89      {
90          mTunnels.add(tunnel);
91          mProxyHandlers.put(tunnel, new ProxyHandler(tunnel));
92      }
93      
94      public void removeTunnel(ITunnel tunnel)
95      {
96          mTunnels.remove(tunnel);
97          mProxyHandlers.remove(tunnel);
98      }
99      
100     /*** Returns a service that is identified by the provided parameters, or
101      * <code>null</code> if no service was found.
102      * First the ServiceProvider tries to find a local service. If that fails
103      * it tries to locate a remote service by sending out a request for the service
104      * on the tunnels. The request is sent to the tunnels in the order that they
105      * were added.
106      * 
107      * @param serviceInterfaceClass  the interface class of the service
108      * @param serviceType            the type of the service.
109      * @param serviceIdentity        the identity of the service.
110      * @return  the requested service if found, otherwise <code>null</code>.
111      */
112     public IService getService(Class serviceInterfaceClass, Object serviceType, Object serviceIdentity)
113     {
114         // Try to find a local service
115         IService service = null;
116         for (int i = 0; i < mServices.size() && service == null; i++)
117             if (((IService) mServices.get(i)).getServiceInterfaceClass().equals(serviceInterfaceClass) &&
118                 ((IService) mServices.get(i)).getServiceType().equals(serviceType) &&
119                 ((IService) mServices.get(i)).getServiceIdentity().equals(serviceIdentity))
120                 service = (IService) mServices.get(i);
121 
122         // If no local service was found try to find a remote service
123         if (service == null)
124         {
125             GetServiceMessage message = new GetServiceMessage(serviceInterfaceClass, serviceType, serviceIdentity);
126             for (int i = 0; i < mTunnels.size() && service == null; i++)
127             {
128                 try
129                 {
130                     service = (IService) ((ITunnel) mTunnels.get(i)).ask(message);
131                     if (service != null && service instanceof IProxyService)
132                         ((IProxyService) service).setServiceTunnel((ITunnel) mTunnels.get(i));
133                     else if (service != null && Proxy.isProxyClass(service.getClass()) && Proxy.getInvocationHandler(service) instanceof DynamicRemoteProxy)
134                         ((DynamicRemoteProxy) Proxy.getInvocationHandler(service)).setProxyHandler((ProxyHandler) mProxyHandlers.get((ITunnel) mTunnels.get(i)));
135                 }
136                 catch (Exception e)
137                 {
138                     Log.printError(this, "Couldn't get service", e);
139                     service = null;
140                 }
141             }
142         }
143         
144         return service;
145     }
146     
147     // Nested classes ----------------------------------------------------------
148     public static interface IServiceProviderMessage extends java.io.Serializable
149     {
150     }
151     
152     protected static class GetServiceMessage implements IServiceProviderMessage
153     {
154         // Data members --------------------------------------------------------
155         protected Class mServiceInterfaceClass;
156         protected Object mServiceType;
157         protected Object mServiceIdentity;
158         
159         // Constructors --------------------------------------------------------
160         public GetServiceMessage(Class serviceInterfaceClass, Object serviceType, Object serviceIdentity)
161         {
162             mServiceInterfaceClass = serviceInterfaceClass;
163             mServiceType = serviceType;
164             mServiceIdentity = serviceIdentity;
165         }
166         
167         // Superclass overrides ------------------------------------------------
168         public String toString()
169         {
170             return "GetServiceMessage: " + mServiceInterfaceClass.getName() + ", " + mServiceType + ", " + mServiceIdentity;
171         }
172     }
173 }