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) throws IOException{
95 EntryClass eclass = Valid.notNull(
96 arg.get("eclass", null, EntryClass.class),
97 "eclass cannot be null"
98 );
99 String codebase = arg.get("codebase", null, String.class);
100 Object [] fields = Valid.notNull(
101 arg.get("fields", null, Object[].class),
102 "fields array cannot be null"
103 );
104 return true;
105 }
106
107 EntryRep(GetArg arg) throws IOException{
108 this(arg, check(arg));
109 }
110
111 private EntryRep(GetArg arg, boolean check) throws IOException{
112 eclass = arg.get("eclass", null, EntryClass.class);
113 codebase = arg.get("codebase", null, String.class);
114 fields = Valid.copy(arg.get("fields", null, Object[].class));
115 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
116 }
117
118 private void writeObject(ObjectOutputStream out) throws IOException{
119 synchronized (fields){
120 out.defaultWriteObject();
121 }
122 }
123
124
125
126
127 public EntryRep(EntryRep copy, boolean replaceEntryClass){
128 eclass = replaceEntryClass ? copy.eclass.getReplacement(): copy.eclass;
129 codebase = copy.codebase;
130 synchronized (copy.fields){
131 fields = copy.fields.clone();
132 }
133 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
134 }
135
136
137
138
139
140 private EntryRep(Entry entry, boolean needCodebase) throws RemoteException {
141 EntryClassBase ecb = ClassMapper.toEntryClassBase(entry.getClass());
142 eclass = ecb.eclass;
143 codebase = needCodebase ? ecb.codebase : null;
144 try {
145 EntryField[] efields = ClassMapper.getFields(entry.getClass());
146 fields = new Object[efields.length];
147 for (int i = efields.length; --i >= 0; ) {
148 EntryField f = efields[i];
149 Object val = f.field.get(entry);
150 if (f.marshal && val != null)
151 val = new MarshalledWrapper(val);
152 fields[i] = val;
153 }
154 } catch (IOException e) {
155 throw new MarshalException("error marshalling arguments", e);
156 } catch (IllegalAccessException e) {
157 throw new MarshalException("error marshalling arguments", e);
158 }
159 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
160 }
161
162
163
164
165
166
167 public Entry get() {
168 try {
169 Class clazz = eclass.toClass(codebase);
170 EntryField[] efields = ClassMapper.getFields(clazz);
171 Entry entry = (Entry)clazz.newInstance();
172 for (int i = efields.length; --i >= 0; ) {
173 Object val = flds.get(i);
174 EntryField f = efields[i];
175 Field rf = f.field;
176 try {
177 if (f.marshal && val != null)
178 val = ((MarshalledWrapper) val).get();
179 rf.set(entry, val);
180 } catch (Throwable e) {
181 if (e instanceof IllegalArgumentException) {
182
183 String msg = "unable to assign " +
184 ((val != null) ?
185 "value of type " + val.getClass().getName() :
186 "null") +
187 " to field " + rf.getDeclaringClass().getName() +
188 "." + rf.getName() + " of type " +
189 rf.getType().getName();
190 e = new ClassCastException(msg).initCause(e);
191 }
192 RegistrarProxy.handleException(e);
193 }
194 }
195 return entry;
196 } catch (Throwable e) {
197 RegistrarProxy.handleException(e);
198 }
199 return null;
200 }
201
202
203
204
205
206 public int hashCode() {
207 return eclass.hashCode();
208 }
209
210
211
212
213
214
215 public boolean equals(Object obj) {
216 if (obj instanceof EntryRep) {
217 EntryRep entry = (EntryRep)obj;
218 if (!eclass.equals(entry.eclass) ||
219 flds.size() != entry.flds.size())
220 return false;
221 for (int i = flds.size(); --i >= 0; ) {
222 if ((flds.get(i) == null && entry.flds.get(i) != null) ||
223 (flds.get(i) != null && !flds.get(i).equals(entry.flds.get(i))))
224 return false;
225 }
226 return true;
227 }
228 return false;
229 }
230
231
232
233
234 public boolean matchEntry(EntryRep tmpl) {
235 if (!tmpl.eclass.isAssignableFrom(eclass) ||
236 tmpl.flds.size() > flds.size())
237 return false;
238 for (int i = tmpl.flds.size(); --i >= 0; ) {
239 if (tmpl.flds.get(i) != null &&
240 !tmpl.flds.get(i).equals(flds.get(i)))
241 return false;
242 }
243 return true;
244 }
245
246
247
248
249
250
251 @Override
252 public Object clone() {
253 return new EntryRep(this, false);
254 }
255
256
257
258
259
260 public static EntryRep[] toEntryRep(Entry[] entries, boolean needCodebase)
261 throws RemoteException
262 {
263 EntryRep[] reps = null;
264 if (entries != null) {
265 reps = new EntryRep[entries.length];
266 for (int i = entries.length; --i >= 0; ) {
267 if (entries[i] != null) {
268 reps[i] = new EntryRep(entries[i], needCodebase);
269 }
270 }
271 }
272 return reps;
273 }
274
275
276 public static Entry[] toEntry(EntryRep[] reps) {
277 Entry[] entries = null;
278 if (reps != null) {
279 entries = new Entry[reps.length];
280 for (int i = reps.length; --i >= 0; ) {
281 entries[i] = reps[i].get();
282 }
283 }
284 return entries;
285 }
286
287 private void readObject(ObjectInputStream in)
288 throws IOException, ClassNotFoundException
289 {
290 in.defaultReadObject();
291 flds = Collections.synchronizedList(Arrays.asList(fields != null ? fields : new Object[0]));
292 }
293 }