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 org.apache.river.proxy.MarshalledWrapper;
21 import org.apache.river.reggie.proxy.ClassMapper.EntryField;
22 import java.io.IOException;
23 import java.io.InvalidObjectException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.io.ObjectStreamField;
27 import java.io.Serializable;
28 import java.lang.reflect.Field;
29 import java.rmi.MarshalException;
30 import java.rmi.RemoteException;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
34 import net.jini.core.entry.Entry;
35 import org.apache.river.api.io.AtomicSerial;
36 import org.apache.river.api.io.AtomicSerial.GetArg;
37 import org.apache.river.api.io.Valid;
38
39
40
41
42
43
44
45
46
47
48
49
50
51 @AtomicSerial
52 public final class EntryRep implements Serializable, Cloneable {
53
54 private static final long serialVersionUID = 2L;
55 private static final ObjectStreamField[] serialPersistentFields =
56 {
57
58 new ObjectStreamField("eclass", EntryClass.class),
59
60 new ObjectStreamField("codebase", String.class),
61
62
63
64 new ObjectStreamField("fields", Object[].class)
65 };
66
67
68
69
70
71
72 public final EntryClass eclass;
73
74
75
76
77
78 public final String codebase;
79
80
81
82
83
84
85
86 private final Object[] fields;
87
88 transient List flds;
89
90 public List fields(){
91 return flds;
92 }
93
94 private static boolean check(GetArg arg)
95 throws IOException, ClassNotFoundException{
96 EntryClass eclass = Valid.notNull(
97 arg.get("eclass", null, EntryClass.class),
98 "eclass cannot be null"
99 );
100 String codebase = arg.get("codebase", null, String.class);
101 Object [] fields = Valid.notNull(
102 arg.get("fields", null, Object[].class),
103 "fields array cannot be null"
104 );
105 return true;
106 }
107
108 EntryRep(GetArg arg) throws IOException, ClassNotFoundException{
109 this(arg, check(arg));
110 }
111
112 private EntryRep(GetArg arg, boolean check)
113 throws IOException, ClassNotFoundException{
114 eclass = arg.get("eclass", null, EntryClass.class);
115 codebase = arg.get("codebase", null, String.class);
116 fields = Valid.copy(arg.get("fields", null, Object[].class));
117 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
118 }
119
120 private void writeObject(ObjectOutputStream out) throws IOException{
121 synchronized (fields){
122 out.defaultWriteObject();
123 }
124 }
125
126
127
128
129 public EntryRep(EntryRep copy, boolean replaceEntryClass){
130 eclass = replaceEntryClass ? copy.eclass.getReplacement(): copy.eclass;
131 codebase = copy.codebase;
132 synchronized (copy.fields){
133 fields = copy.fields.clone();
134 }
135 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
136 }
137
138
139
140
141
142 private EntryRep(Entry entry, boolean needCodebase) throws RemoteException {
143 EntryClassBase ecb = ClassMapper.toEntryClassBase(entry.getClass());
144 eclass = ecb.eclass;
145 codebase = needCodebase ? ecb.codebase : null;
146 try {
147 EntryField[] efields = ClassMapper.getFields(entry.getClass());
148 fields = new Object[efields.length];
149 for (int i = efields.length; --i >= 0; ) {
150 EntryField f = efields[i];
151 Object val = f.field.get(entry);
152 if (f.marshal && val != null)
153 val = new MarshalledWrapper(val);
154 fields[i] = val;
155 }
156 } catch (IOException e) {
157 throw new MarshalException("error marshalling arguments", e);
158 } catch (IllegalAccessException e) {
159 throw new MarshalException("error marshalling arguments", e);
160 }
161 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
162 }
163
164
165
166
167
168
169 public Entry get() {
170 try {
171 Class clazz = eclass.toClass(codebase);
172 EntryField[] efields = ClassMapper.getFields(clazz);
173 Entry entry = (Entry)clazz.newInstance();
174 for (int i = efields.length; --i >= 0; ) {
175 Object val = flds.get(i);
176 EntryField f = efields[i];
177 Field rf = f.field;
178 try {
179 if (f.marshal && val != null)
180 val = ((MarshalledWrapper) val).get();
181 rf.set(entry, val);
182 } catch (Throwable e) {
183 if (e instanceof IllegalArgumentException) {
184
185 String msg = "unable to assign " +
186 ((val != null) ?
187 "value of type " + val.getClass().getName() :
188 "null") +
189 " to field " + rf.getDeclaringClass().getName() +
190 "." + rf.getName() + " of type " +
191 rf.getType().getName();
192 e = new ClassCastException(msg).initCause(e);
193 }
194 RegistrarProxy.handleException(e);
195 }
196 }
197 return entry;
198 } catch (Throwable e) {
199 RegistrarProxy.handleException(e);
200 }
201 return null;
202 }
203
204
205
206
207
208 public int hashCode() {
209 return eclass.hashCode();
210 }
211
212
213
214
215
216
217 public boolean equals(Object obj) {
218 if (obj instanceof EntryRep) {
219 EntryRep entry = (EntryRep)obj;
220 if (!eclass.equals(entry.eclass) ||
221 flds.size() != entry.flds.size())
222 return false;
223 for (int i = flds.size(); --i >= 0; ) {
224 if ((flds.get(i) == null && entry.flds.get(i) != null) ||
225 (flds.get(i) != null && !flds.get(i).equals(entry.flds.get(i))))
226 return false;
227 }
228 return true;
229 }
230 return false;
231 }
232
233
234
235
236 public boolean matchEntry(EntryRep tmpl) {
237 if (!tmpl.eclass.isAssignableFrom(eclass) ||
238 tmpl.flds.size() > flds.size())
239 return false;
240 for (int i = tmpl.flds.size(); --i >= 0; ) {
241 if (tmpl.flds.get(i) != null &&
242 !tmpl.flds.get(i).equals(flds.get(i)))
243 return false;
244 }
245 return true;
246 }
247
248
249
250
251
252
253 @Override
254 public Object clone() {
255 return new EntryRep(this, false);
256 }
257
258
259
260
261
262 public static EntryRep[] toEntryRep(Entry[] entries, boolean needCodebase)
263 throws RemoteException
264 {
265 EntryRep[] reps = null;
266 if (entries != null) {
267 reps = new EntryRep[entries.length];
268 for (int i = entries.length; --i >= 0; ) {
269 if (entries[i] != null) {
270 reps[i] = new EntryRep(entries[i], needCodebase);
271 }
272 }
273 }
274 return reps;
275 }
276
277
278 public static Entry[] toEntry(EntryRep[] reps) {
279 Entry[] entries = null;
280 if (reps != null) {
281 entries = new Entry[reps.length];
282 for (int i = reps.length; --i >= 0; ) {
283 entries[i] = reps[i].get();
284 }
285 }
286 return entries;
287 }
288
289 private void readObject(ObjectInputStream in)
290 throws IOException, ClassNotFoundException
291 {
292 in.defaultReadObject();
293 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
294 }
295 }