1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hivelock; |
16 | |
17 | import java.lang.reflect.InvocationHandler; |
18 | import java.lang.reflect.InvocationTargetException; |
19 | import java.lang.reflect.Method; |
20 | import java.lang.reflect.Proxy; |
21 | import java.security.Principal; |
22 | import java.util.HashMap; |
23 | import java.util.Map; |
24 | |
25 | import org.apache.hivemind.ApplicationRuntimeException; |
26 | import org.apache.hivemind.Discardable; |
27 | import org.apache.hivemind.impl.ConstructableServicePoint; |
28 | import org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl; |
29 | import org.apache.hivemind.internal.Module; |
30 | import org.apache.hivemind.util.ToStringBuilder; |
31 | |
32 | public class UserServiceModel |
33 | extends AbstractServiceModelImpl |
34 | implements UserEventListener |
35 | { |
36 | public UserServiceModel(ConstructableServicePoint servicePoint) |
37 | { |
38 | super(servicePoint); |
39 | Module module = servicePoint.getModule(); |
40 | _loader = module.getClassResolver().getClassLoader(); |
41 | _security = (SecurityService) module.getService( |
42 | "hivelock.core.SecurityService", SecurityService.class); |
43 | _security.addUserEventListener(this); |
44 | } |
45 | |
46 | public synchronized Object getService() |
47 | { |
48 | if (_proxy == null) |
49 | { |
50 | _proxy = createUserProxy(); |
51 | } |
52 | return _proxy; |
53 | } |
54 | |
55 | //CSOFF: IllegalCatchCheck |
56 | protected Object createUserProxy() |
57 | { |
58 | try |
59 | { |
60 | Object proxy = Proxy.newProxyInstance( |
61 | _loader, |
62 | new Class[] {getServicePoint().getServiceInterface()}, |
63 | new UserServiceProxy()); |
64 | return addInterceptors(proxy); |
65 | } |
66 | catch (Exception ex) |
67 | { |
68 | throw new ApplicationRuntimeException(ex); |
69 | } |
70 | } |
71 | //CSON: IllegalCatchCheck |
72 | |
73 | public void instantiateService() |
74 | { |
75 | // Just create the proxy |
76 | getService(); |
77 | // Do nothing else |
78 | } |
79 | |
80 | protected synchronized Object getServiceForUser() |
81 | { |
82 | Principal user = _security.getCurrentUser(); |
83 | Object service = _implementations.get(user); |
84 | if (service == null) |
85 | { |
86 | // Instantiate service |
87 | service = constructCoreServiceImplementation(); |
88 | _implementations.put(user, service); |
89 | } |
90 | return service; |
91 | } |
92 | |
93 | // Proxy for any service in "user" model |
94 | protected class UserServiceProxy implements InvocationHandler |
95 | { |
96 | //CSOFF: IllegalThrowsCheck |
97 | public Object invoke(Object proxy, Method method, Object[] args) |
98 | throws Throwable |
99 | { |
100 | if ("toString".equals(method.getName())) |
101 | { |
102 | ToStringBuilder builder = new ToStringBuilder(this); |
103 | builder.append("serviceId", getServicePoint().getExtensionPointId()); |
104 | return builder.toString(); |
105 | } |
106 | |
107 | Object service = getServiceForUser(); |
108 | |
109 | try |
110 | { |
111 | return method.invoke(service, args); |
112 | } |
113 | catch (InvocationTargetException e) |
114 | { |
115 | throw e.getTargetException(); |
116 | } |
117 | } |
118 | //CSON: IllegalThrowsCheck |
119 | } |
120 | |
121 | public void userConnected(Principal user) |
122 | { |
123 | } |
124 | |
125 | synchronized public void userDisconnected(Principal user, boolean forced) |
126 | { |
127 | Object service = _implementations.remove(user); |
128 | if (service != null && service instanceof Discardable) |
129 | { |
130 | ((Discardable) service).threadDidDiscardService(); |
131 | } |
132 | } |
133 | |
134 | final protected ClassLoader _loader; |
135 | final protected SecurityService _security; |
136 | final protected Map<Principal, Object> _implementations = new HashMap<Principal, Object>(); |
137 | protected Object _proxy; |
138 | } |