001: /*
002: * $RCSfile: RenderableRMIServerProxy.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:56:53 $
010: * $State: Exp $
011: */package com.sun.media.jai.rmi;
012:
013: import java.awt.Image;
014: import java.awt.RenderingHints;
015: import java.awt.image.RenderedImage;
016: import java.awt.image.renderable.ParameterBlock;
017: import java.awt.image.renderable.RenderableImage;
018: import java.awt.image.renderable.RenderContext;
019: import java.net.InetAddress;
020: import java.rmi.Naming;
021: import java.rmi.RemoteException;
022: import java.util.Vector;
023: import javax.media.jai.remote.JAIRMIDescriptor;
024: import javax.media.jai.remote.RemoteImagingException;
025: import javax.media.jai.remote.SerializerFactory;
026: import javax.media.jai.remote.SerializableState;
027: import javax.media.jai.util.ImagingListener;
028: import com.sun.media.jai.util.ImageUtil;
029:
030: /**
031: * A class that represents and allows access to a
032: * <code>RenderableOp</code> on a remote machine.
033: */
034: public class RenderableRMIServerProxy implements RenderableImage {
035:
036: /** The name of the server where the <code>RenderableOp</code> exists. */
037: private String serverName;
038:
039: /** The name of the operation that is represented by this class. */
040: private String operationName;
041:
042: /** The <code>ParameterBlock</code> for the operation. */
043: private ParameterBlock paramBlock;
044:
045: /** A reference to the ImageServer object */
046: private ImageServer imageServer;
047:
048: /** The ID that refers to the <code>RenderableOp</code> on the server. */
049: public Long id;
050:
051: // The class of the serializable representation of a NULL property.
052: private static final Class NULL_PROPERTY_CLASS = com.sun.media.jai.rmi.JAIRMIImageServer.NULL_PROPERTY
053: .getClass();
054:
055: // Cache the imaging listener
056: private ImagingListener listener;
057:
058: /**
059: * Creates a <code>RenderableRMIServerProxy</code> to access the
060: * <code>RenderableOp</code> on the server identified by the
061: * supplied <code>opID</code>.
062: */
063: public RenderableRMIServerProxy(String serverName,
064: String operationName, ParameterBlock paramBlock, Long opID) {
065:
066: this .serverName = serverName;
067: this .operationName = operationName;
068: this .paramBlock = paramBlock;
069: imageServer = getImageServer(serverName);
070: this .id = opID;
071: listener = ImageUtil.getImagingListener((RenderingHints) null);
072: }
073:
074: /**
075: * Returns a vector of RenderableImages that are the sources of
076: * image data for this RenderableImage. Note that this method may
077: * return an empty vector, to indicate that the image has no sources,
078: * or null, to indicate that no information is available.
079: *
080: * @return a (possibly empty) Vector of RenderableImages, or null.
081: */
082: public Vector getSources() {
083: return null;
084: }
085:
086: /**
087: * Gets a property from the property set of this image.
088: * If the property name is not recognized, java.awt.Image.UndefinedProperty
089: * will be returned.
090: *
091: * @param name the name of the property to get, as a String.
092: * @return a reference to the property Object, or the value
093: * java.awt.Image.UndefinedProperty.
094: */
095: public Object getProperty(String name)
096: throws RemoteImagingException {
097:
098: try {
099: Object property = imageServer.getProperty(id, name);
100: if (NULL_PROPERTY_CLASS.isInstance(property)) {
101: property = Image.UndefinedProperty;
102: }
103: return property;
104: } catch (RemoteException re) {
105: String message = JaiI18N.getString("JAIRMICRIF7");
106: listener.errorOccurred(message, new RemoteImagingException(
107: message, re), this , false);
108: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
109: }
110: return null;
111: }
112:
113: /**
114: * Returns a list of names recognized by getProperty.
115: * @return a list of property names.
116: */
117: public String[] getPropertyNames() throws RemoteImagingException {
118: try {
119: return imageServer.getPropertyNames(id);
120: } catch (RemoteException re) {
121: String message = JaiI18N.getString("JAIRMICRIF8");
122: listener.errorOccurred(message, new RemoteImagingException(
123: message, re), this , false);
124: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
125: }
126: return null;
127: }
128:
129: /**
130: * Returns true if successive renderings (that is, calls to
131: * createRendering() or createScaledRendering()) with the same arguments
132: * may produce different results. This method may be used to
133: * determine whether an existing rendering may be cached and
134: * reused. It is always safe to return true.
135: * @return <code>true</code> if successive renderings with the
136: * same arguments might produce different results;
137: * <code>false</code> otherwise.
138: */
139: public boolean isDynamic() throws RemoteImagingException {
140: try {
141: return imageServer.isDynamic(id);
142: } catch (RemoteException re) {
143: String message = JaiI18N.getString("JAIRMICRIF9");
144: listener.errorOccurred(message, new RemoteImagingException(
145: message, re), this , false);
146: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
147: }
148: return true;
149: }
150:
151: /**
152: * Gets the width in user coordinate space. By convention, the
153: * usual width of a RenderableImage is equal to the image's aspect
154: * ratio (width divided by height).
155: *
156: * @return the width of the image in user coordinates.
157: */
158: public float getWidth() throws RemoteImagingException {
159: try {
160: return imageServer.getRenderableWidth(id);
161: } catch (RemoteException re) {
162: String message = JaiI18N
163: .getString("RenderableRMIServerProxy0");
164: listener.errorOccurred(message, new RemoteImagingException(
165: message, re), this , false);
166: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
167: }
168: return 0;
169: }
170:
171: /**
172: * Gets the height in user coordinate space. By convention, the
173: * usual height of a RenderedImage is equal to 1.0F.
174: *
175: * @return the height of the image in user coordinates.
176: */
177: public float getHeight() throws RemoteImagingException {
178: try {
179: return imageServer.getRenderableHeight(id);
180: } catch (RemoteException re) {
181: String message = JaiI18N
182: .getString("RenderableRMIServerProxy0");
183: listener.errorOccurred(message, new RemoteImagingException(
184: message, re), this , false);
185: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
186: }
187: return 0;
188: }
189:
190: /**
191: * Gets the minimum X coordinate of the rendering-independent image data.
192: * @return the minimum X coordinate of the rendering-independent image
193: * data.
194: */
195: public float getMinX() throws RemoteImagingException {
196: try {
197: return imageServer.getRenderableMinX(id);
198: } catch (RemoteException re) {
199: String message = JaiI18N
200: .getString("RenderableRMIServerProxy1");
201: listener.errorOccurred(message, new RemoteImagingException(
202: message, re), this , false);
203: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
204: }
205: return 0;
206: }
207:
208: /**
209: * Gets the minimum Y coordinate of the rendering-independent image data.
210: * @return the minimum Y coordinate of the rendering-independent image
211: * data.
212: */
213: public float getMinY() throws RemoteImagingException {
214: try {
215: return imageServer.getRenderableMinY(id);
216: } catch (RemoteException re) {
217: String message = JaiI18N
218: .getString("RenderableRMIServerProxy1");
219: listener.errorOccurred(message, new RemoteImagingException(
220: message, re), this , false);
221: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
222: }
223: return 0;
224: }
225:
226: /**
227: * Returns the ID that refers to the <code>RenderableOp</code> on the
228: * server.
229: */
230: public Long getRMIID() {
231: return id;
232: }
233:
234: /**
235: * Returns the name of the server on which the RenderableOp exists.
236: */
237: public String getServerName() {
238: return serverName;
239: }
240:
241: /**
242: * Returns the operation name.
243: */
244: public String getOperationName() {
245: return operationName;
246: }
247:
248: /**
249: * Creates a RenderedImage instance of this image with width w, and
250: * height h in pixels. The RenderContext is built automatically
251: * with an appropriate usr2dev transform and an area of interest
252: * of the full image. All the rendering hints come from hints
253: * passed in.
254: *
255: * <p> If w == 0, it will be taken to equal
256: * Math.round(h*(getWidth()/getHeight())).
257: * Similarly, if h == 0, it will be taken to equal
258: * Math.round(w*(getHeight()/getWidth())). One of
259: * w or h must be non-zero or else an IllegalArgumentException
260: * will be thrown.
261: *
262: * <p> The created RenderedImage may have a property identified
263: * by the String HINTS_OBSERVED to indicate which RenderingHints
264: * were used to create the image. In addition any RenderedImages
265: * that are obtained via the getSources() method on the created
266: * RenderedImage may have such a property.
267: *
268: * @param w the width of rendered image in pixels, or 0.
269: * @param h the height of rendered image in pixels, or 0.
270: * @param hints a RenderingHints object containg hints.
271: * @return a RenderedImage containing the rendered data.
272: */
273: public RenderedImage createScaledRendering(int w, int h,
274: RenderingHints hints) throws RemoteImagingException {
275:
276: SerializableState ss = SerializerFactory.getState(hints, null);
277:
278: try {
279: return imageServer.createScaledRendering(id, w, h, ss);
280: } catch (RemoteException re) {
281: String message = JaiI18N.getString("RMIServerProxy10");
282: listener.errorOccurred(message, new RemoteImagingException(
283: message, re), this , false);
284: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
285: }
286: return null;
287: }
288:
289: /**
290: * Returns a RenderedImage instance of this image with a default
291: * width and height in pixels. The RenderContext is built
292: * automatically with an appropriate usr2dev transform and an area
293: * of interest of the full image. The rendering hints are
294: * empty. createDefaultRendering may make use of a stored
295: * rendering for speed.
296: *
297: * @return a RenderedImage containing the rendered data.
298: */
299: public RenderedImage createDefaultRendering()
300: throws RemoteImagingException {
301: try {
302: return imageServer.createDefaultRendering(id);
303: } catch (RemoteException re) {
304: String message = JaiI18N.getString("RMIServerProxy10");
305: listener.errorOccurred(message, new RemoteImagingException(
306: message, re), this , false);
307: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
308: }
309: return null;
310: }
311:
312: /**
313: * Creates a RenderedImage that represented a rendering of this image
314: * using a given RenderContext. This is the most general way to obtain a
315: * rendering of a RenderableImage.
316: *
317: * <p> The created RenderedImage may have a property identified
318: * by the String HINTS_OBSERVED to indicate which RenderingHints
319: * (from the RenderContext) were used to create the image.
320: * In addition any RenderedImages
321: * that are obtained via the getSources() method on the created
322: * RenderedImage may have such a property.
323: *
324: * @param renderContext the RenderContext to use to produce the rendering.
325: * @return a RenderedImage containing the rendered data.
326: */
327: public RenderedImage createRendering(RenderContext renderContext)
328: throws RemoteImagingException {
329:
330: SerializableState ss = SerializerFactory.getState(
331: renderContext, null);
332: try {
333: return imageServer.createRendering(id, ss);
334: } catch (RemoteException re) {
335: String message = JaiI18N.getString("RMIServerProxy10");
336: listener.errorOccurred(message, new RemoteImagingException(
337: message, re), this , false);
338: // throw new RemoteImagingException(ImageUtil.getStackTraceString(re));
339: }
340: return null;
341: }
342:
343: /**
344: * Construct an ImageServer on the indicated server.
345: *
346: * <p> The name of the server must be supplied in the form
347: * <pre>
348: * host:port
349: * </pre>
350: * where the port number is optional and may be supplied only if
351: * the host name is supplied. If this parameter is null the default
352: * is to search for the ImageServer service on the local host at the
353: * default <i>rmiregistry</i> port (1099).
354: *
355: * <p> The result is cached in the instance variable "remoteImage".
356: *
357: * @param serverName The name of the server in the format described.
358: */
359: protected synchronized ImageServer getImageServer(String serverName) {
360:
361: if (imageServer == null) {
362:
363: if (serverName == null) {
364: try {
365: serverName = InetAddress.getLocalHost()
366: .getHostAddress();
367: } catch (Exception e) {
368: String message = JaiI18N
369: .getString("RMIServerProxy11");
370: listener.errorOccurred(message,
371: new RemoteImagingException(message, e),
372: this , false);
373: // throw new RemoteImagingException(ImageUtil.getStackTraceString(e));
374: }
375: }
376:
377: // Derive the service name.
378: String serviceName = new String("rmi://" + serverName + "/"
379: + JAIRMIDescriptor.IMAGE_SERVER_BIND_NAME);
380:
381: // Look up the remote object.
382: imageServer = null;
383: try {
384: imageServer = (ImageServer) Naming.lookup(serviceName);
385: } catch (Exception e) {
386: String message = JaiI18N.getString("RMIServerProxy12");
387: listener.errorOccurred(message,
388: new RemoteImagingException(message, e), this ,
389: false);
390: // throw new RemoteImagingException(ImageUtil.getStackTraceString(e));
391: }
392: }
393:
394: return imageServer;
395: }
396: }
|