1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
46 protected static ServiceProvider sInstance;
47
48
49 protected List mServices;
50 protected List mTunnels;
51 protected Hashtable mProxyHandlers;
52
53
54 public static ServiceProvider getInstance()
55 {
56 if (sInstance == null)
57 sInstance = new ServiceProvider();
58 return sInstance;
59 }
60
61
62 protected ServiceProvider()
63 {
64 mServices = new ArrayList();
65 mTunnels = new ArrayList();
66 mProxyHandlers = new Hashtable();
67 }
68
69
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
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
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
148 public static interface IServiceProviderMessage extends java.io.Serializable
149 {
150 }
151
152 protected static class GetServiceMessage implements IServiceProviderMessage
153 {
154
155 protected Class mServiceInterfaceClass;
156 protected Object mServiceType;
157 protected Object mServiceIdentity;
158
159
160 public GetServiceMessage(Class serviceInterfaceClass, Object serviceType, Object serviceIdentity)
161 {
162 mServiceInterfaceClass = serviceInterfaceClass;
163 mServiceType = serviceType;
164 mServiceIdentity = serviceIdentity;
165 }
166
167
168 public String toString()
169 {
170 return "GetServiceMessage: " + mServiceInterfaceClass.getName() + ", " + mServiceType + ", " + mServiceIdentity;
171 }
172 }
173 }