1 /*
2  * $RCSfile: JAIRMIUtil.java,v $
3  *
4  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5  *
6  * Use is subject to license terms.
7  *
8  * $Revision: 1.1 $
9  * $Date: 2005/02/11 04:56:51 $
10  * $State: Exp $
11  */package com.lightcrafts.media.jai.rmi;
12 
13 import java.awt.RenderingHints;
14 import java.awt.image.RenderedImage;
15 import java.awt.image.renderable.ParameterBlock;
16 import java.io.Serializable;
17 import java.util.Vector;
18 import java.util.Hashtable;
19 import com.lightcrafts.mediax.jai.RenderedOp;
20 import com.lightcrafts.mediax.jai.PlanarImage;
21 import com.lightcrafts.mediax.jai.remote.RemoteRenderedOp;
22 import com.lightcrafts.mediax.jai.remote.SerializableRenderedImage;
23 
24 /**
25  * A class containing utility methods used for the implementation of
26  * the "jairmi" protocol.
27  */
28 public final class JAIRMIUtil {
29 
30     /**
31      * Replaces any element in the source Vector which is an ID
32      * with the server-side node that is associated with the
33      * given ID.
34      */
replaceIdWithSources(Vector srcs, Hashtable nodes, String opName, RenderingHints hints)35     public static Vector replaceIdWithSources(Vector srcs,
36 					      Hashtable nodes,
37 					      String opName,
38 					      RenderingHints hints) {
39 
40 	Vector replacedSrcs = new Vector();
41 	Object obj;
42 	for (int i=0; i<srcs.size(); i++) {
43 	    obj = srcs.elementAt(i);
44 	    if (obj instanceof String){
45 		String serverNodeDesc = (String)obj;
46 		int index = serverNodeDesc.indexOf("::");
47 		boolean diffServer = index != -1;
48 		if (diffServer){
49 		    // If the source is on a different server, create
50 		    // a RMIServerProxy to access it.
51 		    replacedSrcs.add(new RMIServerProxy(serverNodeDesc,
52 							opName,
53 							hints));
54 		} else {
55 		    // If the source is on the same server, get it
56 		    // from the nodes Hashtable and set it as a source
57 		    // in the sources Vector.
58 		    replacedSrcs.add(nodes.get(Long.valueOf(serverNodeDesc)));
59 		}
60 	    } else {
61 		PlanarImage pi =
62 		    PlanarImage.wrapRenderedImage((RenderedImage)obj);
63 		replacedSrcs.add(pi);
64 	    }
65 	}
66 
67 	return replacedSrcs;
68     }
69 
70     /**
71      * Replaces any source that is an <code>RMIServerProxy</code> with
72      * the id of the server-side node that is represented by the
73      * <code>RMIServerProxy</code>.
74      */
replaceSourcesWithId(Vector srcs, String serverName)75     public static  Vector replaceSourcesWithId(Vector srcs,
76 					       String serverName) {
77 
78 	Vector replacedSrcs = new Vector();
79 	Object obj;
80 	for (int i=0; i<srcs.size(); i++) {
81 	    obj = srcs.elementAt(i);
82 	    if (obj instanceof RMIServerProxy) {
83 		RMIServerProxy rmisp = (RMIServerProxy)obj;
84 		if (rmisp.getServerName().equalsIgnoreCase(serverName)){
85 		    replacedSrcs.add(rmisp.getRMIID().toString());
86 		} else {
87 		    String str =
88 			new String(rmisp.getServerName()+
89 				   "::"+rmisp.getRMIID());
90 		    replacedSrcs.add(str);
91 		}
92 	    } else if (obj instanceof RemoteRenderedOp){
93 		RemoteRenderedOp rrop = (RemoteRenderedOp)obj;
94 		Object ai = rrop.getRendering();
95 		if (ai instanceof RMIServerProxy) {
96 		    RMIServerProxy rmisp = (RMIServerProxy)ai;
97 		    if (rmisp.getServerName().equalsIgnoreCase(serverName)){
98 			replacedSrcs.add(rmisp.getRMIID().toString());
99 		    } else {
100 			String str =
101 			    new String(rmisp.getServerName()+
102 				       "::"+rmisp.getRMIID());
103 			replacedSrcs.add(str);
104 		    }
105 		} else {
106 		    RenderedImage ri = (RenderedImage)ai;
107 		    replacedSrcs.add(new SerializableRenderedImage(ri));
108 		}
109 	    } else if (obj instanceof RenderedOp){
110 		RenderedOp rop = (RenderedOp)obj;
111 		replacedSrcs.add(new SerializableRenderedImage(
112 					  (RenderedImage)rop.getRendering()));
113 	    } else if (obj instanceof Serializable) {
114 		replacedSrcs.add(obj);
115 	    } else if (obj instanceof RenderedImage) {
116 		RenderedImage ri = (RenderedImage)obj;
117 		replacedSrcs.add(new SerializableRenderedImage(ri));
118 	    }
119 	}
120 
121 	return replacedSrcs;
122     }
123 
124     /**
125      * Replace an image with an equivalent representation that can be accessed
126      * on the server.
127      */
replaceImage(RenderedImage obj, String thisServerName)128     public static Object replaceImage(RenderedImage obj,
129 				      String thisServerName) {
130 
131 	if (obj instanceof RMIServerProxy) {
132 
133 	    RMIServerProxy rmisp = (RMIServerProxy)obj;
134 	    if (rmisp.getServerName().equalsIgnoreCase(thisServerName))
135 		return "::" + rmisp.getRMIID();
136 	    else
137 		return rmisp.getServerName() + "::" + rmisp.getRMIID() +
138 		    ";;" + rmisp.getOperationName();
139 
140 	} else if (obj instanceof RenderedOp) {
141 
142 	    RenderedImage rendering = ((RenderedOp)obj).getRendering();
143 	    return replaceImage(rendering, thisServerName);
144 
145 	} else if (obj instanceof RenderedImage) {
146 
147 	    if (obj instanceof Serializable)
148 		return obj;
149 	    else
150 		return new SerializableRenderedImage(obj);
151 	}
152 
153 	return obj;
154     }
155 
checkClientParameters(ParameterBlock pb, String thisServerName)156     public static void checkClientParameters(ParameterBlock pb,
157 					     String thisServerName) {
158 
159 	// XXX 07/18/01, aastha TODO
160 	// This code should check every parameter to test Serializability
161 	// If parameter is Serializable, then keep it as is
162 	// If not serializable then use SerializerFactory to serialize it
163 	// If that doesn't work, throw an Exception
164 	// Note that parameters that are images may still need to be treated
165 	// differently as in the code below.
166 
167 	if (pb == null)
168 	    return;
169 
170 	int numParams = pb.getNumParameters();
171 	Vector params = pb.getParameters();
172 
173 	Object obj;
174 	for (int i=0; i<numParams; i++) {
175 	    obj = params.elementAt(i);
176 
177 	    if (obj == null) {
178 
179 		continue;
180 
181 	    } else if (obj instanceof RenderedImage) {
182 
183 		pb.set(replaceImage((RenderedImage)obj, thisServerName), i);
184 
185 	    }
186 	}
187     }
188 
checkClientParameters(Vector parameters, String thisServerName)189     public static void checkClientParameters(Vector parameters,
190 					     String thisServerName) {
191 
192 	// XXX 07/18/01, aastha TODO
193 	// This code should check every parameter to test Serializability
194 	// If parameter is Serializable, then keep it as is
195 	// If not serializable then use SerializerFactory to serialize it
196 	// If that doesn't work, throw an Exception
197 	// Note that parameters that are images may still need to be treated
198 	// differently as in the code below.
199 
200 	if (parameters == null)
201 	    return;
202 
203 	Object obj;
204 	for (int i=0; i<parameters.size(); i++) {
205 	    obj = parameters.elementAt(i);
206 
207 	    if (obj == null) {
208 
209 		continue;
210 
211 	    } else if (obj instanceof RenderedImage) {
212 
213 		parameters.set(i, replaceImage((RenderedImage)obj,
214 					       thisServerName));
215 
216 	    }
217 	}
218     }
219 
220     /**
221      * Method to convert a String representation of an image into the
222      * image itself. The String representation is supplied by the client
223      * generally as a parameter in the ParameterBlock.
224      */
replaceStringWithImage(String s, Hashtable nodes)225     public static Object replaceStringWithImage(String s, Hashtable nodes) {
226 	String paramServerName, opName;
227 	int index1 = s.indexOf("::");
228 	int index2 = s.indexOf(";;");
229 	Long id;
230 
231 	if (index1 == -1) {
232 	    return s;
233 	} else if (index2 == -1) {
234 	    id = Long.valueOf(s.substring(index1 + 2));
235 	    return nodes.get(id);
236 
237 	} else {
238 	    // Extract the RMI ID from the servername string and
239 	    // replace the original serverName string with one of
240 	    // the usual type.
241 	    id = Long.valueOf(s.substring(index1+2, index2));
242 	    paramServerName = s.substring(0, index1);
243 	    opName = s.substring(index2+2);
244 
245 	    // Create an RMIServerProxy to access the image on
246 	    // the other server.
247 	    return new RMIServerProxy((paramServerName + "::" + id),
248 				      opName,
249 				      null);
250 	}
251     }
252 
253     /**
254      * Method to check whether any of the parameters in the ParameterBlock
255      * are replacement representations of images.
256      */
checkServerParameters(ParameterBlock pb, Hashtable nodes)257     public static void checkServerParameters(ParameterBlock pb,
258 					     Hashtable nodes) {
259 
260 	if (pb == null)
261 	    return;
262 
263 	int numParams = pb.getNumParameters();
264 	Vector params = pb.getParameters();
265 
266 	Object obj;
267 	for (int i=0; i<numParams; i++) {
268 	    obj = params.elementAt(i);
269 
270 	    if (obj == null) {
271 		continue;
272 	    } else if (obj instanceof String) {
273 		pb.set(replaceStringWithImage((String)obj, nodes), i);
274 	    }
275 	}
276     }
277 
278     /**
279      * Method to check whether any of the parameters in the ParameterBlock
280      * are replacement representations of images.
281      */
checkServerParameters(Vector parameters, Hashtable nodes)282     public static void checkServerParameters(Vector parameters,
283 					     Hashtable nodes) {
284 
285 	if (parameters == null)
286 	    return;
287 
288 	Object obj;
289 	for (int i=0; i<parameters.size(); i++) {
290 	    obj = parameters.elementAt(i);
291 
292 	    if (obj == null) {
293 		continue;
294 	    } else if (obj instanceof String) {
295 		parameters.set(i, replaceStringWithImage((String)obj, nodes));
296 	    }
297 	}
298     }
299 
300 }
301