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 }