1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.river.reggie.proxy;
19
20 import java.io.IOException;
21 import java.io.ObjectOutputStream;
22 import java.io.ObjectStreamField;
23 import java.io.Serializable;
24 import java.lang.reflect.Proxy;
25 import java.rmi.MarshalException;
26 import java.rmi.NoSuchObjectException;
27 import java.rmi.Remote;
28 import java.rmi.RemoteException;
29 import java.rmi.server.RemoteObject;
30 import java.util.List;
31 import java.util.logging.Level;
32 import java.util.logging.Logger;
33 import net.jini.core.lookup.ServiceID;
34 import net.jini.core.lookup.ServiceItem;
35 import net.jini.security.Security;
36 import org.apache.river.action.GetBooleanAction;
37 import org.apache.river.api.io.AtomicSerial;
38 import org.apache.river.api.io.AtomicSerial.GetArg;
39 import org.apache.river.api.io.Valid;
40 import org.apache.river.logging.Levels;
41 import org.apache.river.proxy.MarshalledWrapper;
42 import org.apache.river.proxy.Bootstrap;
43
44
45
46
47
48
49
50
51
52
53
54
55
56 @AtomicSerial
57 public final class Item implements Serializable, Cloneable {
58
59 private static final long serialVersionUID = 2L;
60 private static final ObjectStreamField[] serialPersistentFields =
61 {
62
63 new ObjectStreamField("serviceID", ServiceID.class),
64
65 new ObjectStreamField("serviceType", ServiceType.class),
66
67 new ObjectStreamField("codebase", String.class),
68
69 new ObjectStreamField("service", MarshalledWrapper.class),
70
71 new ObjectStreamField("attributeSets", EntryRep[].class),
72
73 new ObjectStreamField("bootstrapProxy", Proxy.class)
74 };
75
76
77 private static final Logger logger =
78 Logger.getLogger("org.apache.river.reggie");
79
80
81
82
83
84 private static final boolean enableImplToStubReplacement;
85 static {
86 Boolean b;
87 try {
88 b = (Boolean) Security.doPrivileged(new GetBooleanAction(
89 "org.apache.river.reggie.enableImplToStubReplacement"));
90 } catch (SecurityException e) {
91 logger.log(Levels.HANDLED, "failed to read system property", e);
92 b = Boolean.FALSE;
93 }
94 enableImplToStubReplacement = b.booleanValue();
95 }
96
97
98
99
100
101
102 private ServiceID serviceID;
103
104
105
106
107
108 public final ServiceType serviceType;
109
110
111
112
113
114 public final String codebase;
115
116
117
118
119
120 public final MarshalledWrapper service;
121
122
123
124
125
126 private EntryRep[] attributeSets;
127
128
129
130
131
132 Proxy bootstrapProxy;
133
134
135
136
137
138
139
140
141
142 private static boolean check(GetArg arg) throws IOException{
143 arg.get("serviceID", null, ServiceID.class);
144
145 arg.get("serviceType", null, ServiceType.class);
146
147 arg.get("codebase", null, String.class);
148
149 Valid.notNull(
150 arg.get("service", null, MarshalledWrapper.class),
151 "service cannot be null");
152
153 arg.get("attributeSets", null, EntryRep[].class);
154 Proxy bootstrapProxy = arg.get("bootstrapProxy", null, Proxy.class);
155 if (bootstrapProxy != null) {
156 if (Proxy.isProxyClass(bootstrapProxy.getClass())) return true;
157 }
158 return true;
159 }
160
161
162
163
164
165
166
167 public Item(GetArg arg) throws IOException{
168 this(arg, check(arg));
169 };
170
171 private Item(GetArg arg, boolean check) throws IOException{
172 super();
173 serviceID = arg.get("serviceID", null, ServiceID.class);
174 serviceType = arg.get("serviceType", null, ServiceType.class);
175 codebase = arg.get("codebase", null, String.class);
176 service = arg.get("service", null, MarshalledWrapper.class);
177 attributeSets = Valid.copy(arg.get("attributeSets", null, EntryRep[].class));
178 bootstrapProxy = arg.get("bootstrapProxy", null, Proxy.class);
179 }
180
181
182
183
184
185 public Item(ServiceItem item) throws RemoteException {
186 Object svc = item.service;
187 if (enableImplToStubReplacement && svc instanceof Remote) {
188 try {
189 svc = RemoteObject.toStub((Remote) svc);
190 if (logger.isLoggable(Level.FINER)) {
191 logger.log(Level.FINER, "replacing {0} with {1}",
192 new Object[]{ item.service, svc });
193 }
194 } catch (NoSuchObjectException e) {
195 }
196 }
197
198 bootstrapProxy = Bootstrap.create(svc);
199 serviceID = item.serviceID;
200 ServiceTypeBase stb = ClassMapper.toServiceTypeBase(svc.getClass());
201 serviceType = stb.type;
202 codebase = stb.codebase;
203 try {
204 service = new MarshalledWrapper(svc);
205 } catch (IOException e) {
206 throw new MarshalException("error marshalling arguments", e);
207 }
208 attributeSets = EntryRep.toEntryRep(item.attributeSets, true);
209 }
210
211 public Item(ServiceID serviceID, ServiceType serviceType, String codebase, MarshalledWrapper service, EntryRep[] attrSets, Proxy bootstrap)
212 {
213 this.serviceID = serviceID;
214 this.serviceType = serviceType;
215 this.codebase = codebase;
216 this.service = service;
217 attributeSets = attrSets != null ? attrSets.clone() : new EntryRep[0];
218 this.bootstrapProxy = bootstrap;
219 }
220
221
222
223
224
225
226
227 public ServiceItem get() {
228 Object obj = null;
229 try {
230 obj = service.get();
231 } catch (Throwable e) {
232 RegistrarProxy.handleException(e);
233 }
234 synchronized (this){
235 return new ServiceItem(serviceID,
236 obj,
237 EntryRep.toEntry(attributeSets));
238 }
239 }
240
241 public Proxy getProxy() {
242 return bootstrapProxy;
243 }
244
245
246
247
248
249 @Override
250 public Object clone() {
251 EntryRep[] attrSets = (EntryRep[])attributeSets.clone();
252 for (int i = attrSets.length; --i >= 0; ) {
253 attrSets[i] = (EntryRep)attrSets[i].clone();
254 }
255 return new Item(serviceID, serviceType, codebase, service, attrSets, null);
256 }
257
258
259
260
261 public static ServiceItem[] toServiceItem(List reps)
262 {
263 ServiceItem[] items = null;
264 if (reps != null) {
265 items = new ServiceItem[reps.size()];
266 for (int i = items.length; --i >= 0; ) {
267 items[i] = ((Item)reps.get(i)).get();
268 }
269 }
270 return items;
271 }
272
273 private synchronized void writeObject(ObjectOutputStream out) throws IOException {
274 out.defaultWriteObject();
275 }
276
277
278
279
280 public synchronized ServiceID getServiceID() {
281 return serviceID;
282 }
283
284
285
286
287 public synchronized void setServiceID(ServiceID serviceID) {
288 this.serviceID = serviceID;
289 }
290
291
292
293
294 public synchronized EntryRep[] getAttributeSets() {
295 return attributeSets == null ? null : attributeSets.clone();
296 }
297
298 public synchronized EntryRep getAttributeSetAtIndex(int i){
299 return attributeSets == null ? null : attributeSets[i];
300 }
301
302 public synchronized int getAttributeSetsLength(){
303 return attributeSets == null ? 0 : attributeSets.length;
304 }
305
306
307
308
309 public synchronized void setAttributeSets(EntryRep[] attributeSets) {
310 this.attributeSets = attributeSets;
311 }
312 }