Package com.lightcrafts.mediax.jai.remote

Source Code of com.lightcrafts.mediax.jai.remote.PlanarImageServerProxy

/*
* $RCSfile: PlanarImageServerProxy.java,v $
*
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* Use is subject to license terms.
*
* $Revision: 1.1 $
* $Date: 2005/02/11 04:57:51 $
* $State: Exp $
*/package com.lightcrafts.mediax.jai.remote;

import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.ColorModel;
import java.awt.image.renderable.ParameterBlock;
import java.util.Vector;
import com.lightcrafts.mediax.jai.ImageLayout;
import com.lightcrafts.mediax.jai.JAI;
import com.lightcrafts.mediax.jai.OperationRegistry;
import com.lightcrafts.mediax.jai.PlanarImage;
import com.lightcrafts.mediax.jai.TileCache;
import com.lightcrafts.mediax.jai.util.ImagingListener;

/**
* A subclass of <code>PlanarImage</code> which represents an image on a
* remote server machine. This class is also an implementation of the
* <code>RemoteRenderedImage</code> interface. This class allows processing
* to occur on the remote server machine.
*
* <p>Conceptually this class is like a No-op, all it provides is a mechanism
* allowing the processing to occur on a server. Note that this class does
* not mandate that the client-server communication rely on any particular
* wire protocol or communication protocol. A subclass can choose any wire
* or communication protocol to communicate with its server. This is
* accomplished by having the subclass implement the methods declared to
* be abstract in this class. All functionality in this class is then
* implemented in terms of these abstract methods.
*
* <p>Network errors (detected via throws of
* <code>RemoteImagingException</code>) are dealt with through the use of
* retry intervals and retries. Retries refers to the maximum number of
* times a remote operation will be retried. The retry interval refers to
* the amount of time in milliseconds between two consecutive retries. If
* errors are encountered at each retry and the number of specified retries
* has been exhausted, a <code>RemoteImagingException</code> will be thrown.
* Time outs (When the amount of time taken to get a response or
* the result of an operation from the remote machine exceeds a limit) are
* not dealt with, and must be taken care of by the network
* imaging protocol implementation. The implementation must be responsible
* for monitoring time outs, but on encountering one can deal with it by
* throwing a <code>RemoteImagingException</code>, which will then be dealt
* with using retries and retry intervals.
*
* <p> The resultant image layout is computed and provided by the concrete
* subclass by implementing the abstract method <code>getImageLayout</code>.
* All the accessor methods dealing with the layout variables namely
* <code>getMinX()</code>, <code>getMinY()</code>, <code>getWidth()</code>,
* <code>getHeight()</code>, <code>getMaxX()</code>, <code>getMaxY()</code>,
* <code>getTileWidth()</code>, <code>getTileHeight()</code>,
* <code>getTileGridXOffset()</code>, <code>getTileGridYOffset()</code>,
* <code>getColorModel()</code> and <code>getSampleModel()</code> are
* implemented in terms of the <code>getImageLayout()</code> method. The
* implementation of these methods uses retries and retry intervals to
* deal with Network errors, such that the subclass implementing
* <code>getImageLayout()</code> does not need to worry about Network errors
* except to signal them by throwing a <code>RemoteImagingException</code>.
* The same applies to the other abstract methods implemented by sub-classes
* namely <code>getRemoteProperty()</code>,
* <code>getRemotePropertyNames()</code> and <code>computeTile()</code>.
*
* <p> The <code>getTile</code> method (abstract in this class' superclass),
* is implemented in terms of the <code>computeTile</code> method. It provides
* the additional functionality of caching the tiles on the client, as well
* as that of dealing with Network errors as mentioned above.
*
* @see RemoteImagingException
*
* @since JAI 1.1
*/
public abstract class PlanarImageServerProxy extends PlanarImage implements RemoteRenderedImage {

    /** Time in milliseconds between retries. */
    protected int retryInterval;

    /** The number of retries. */
    protected int numRetries;

    /** A reference to a centralized TileCache object. */
    protected transient TileCache cache;

    /**
     * Metric used to produce an ordered list of tiles.  This determines
     * which tiles are removed from the cache first if a memory control
     * operation is required.
     */
    protected Object tileCacheMetric;

    /** A reference to the OperationRegistry object. */
    protected transient OperationRegistry registry;

    /** The String representing the remote server machine. */
    protected String serverName;

    /** The name of the protocol to be used for remote communication. */
    protected String protocolName;

    /** The name of the operation to be performed remotely. */
    protected String operationName;

    /** The sources and/or arguments to the operation. */
    protected ParameterBlock paramBlock;

    /** The RenderingHints for the operation. */
    protected RenderingHints hints;

    // The layout of the image
    private ImageLayout layout = null;

    /** The preferences to be utilized in the negotiation. */
    protected NegotiableCapabilitySet preferences;

    /**
     * The set of properties agreed upon after the negotiation process
     * between the client and the server has been completed.
     */
    protected NegotiableCapabilitySet negotiated;

    /** The server capabilities. */
    NegotiableCapabilitySet serverCapabilities;

    /** The client capabilities. */
    NegotiableCapabilitySet clientCapabilities;

    /**
     * Checks that all the layout parameters have been specified.
     *
     * @throws IllegalArgumentException if layout is null.
     * @throws Error if all the layout fields are not initialized.
     */
    private static void checkLayout(ImageLayout layout) {

  if (layout == null) {
      throw new IllegalArgumentException("layout is null.");
  }

  if (layout.getValidMask() != 0x3ff) {
       throw new Error(JaiI18N.getString("PlanarImageServerProxy3"));
  }
    }

    /**
     * Constructs a <code>PlanarImageServerProxy</code> using the specified
     * name of the server to perform the specified operation on, using the
     * sources and parameters specified by the supplied
     * <code>ParameterBlock</code> and supplied <code>RenderingHints</code>.
     * If hints relating to the <code>OperationRegistry</code>,
     * <code>TileCache</code>, retry interval, number of retries,
     * tile caching metric or negotiation preferences are included in the
     * specified <code>RenderingHints</code> object, they will be honored.
     *
     * <p> An <code>IllegalArgumentException</code> may
     * be thrown by the protocol specific classes at a later point, if
     * null is provided as the serverName argument and null is not
     * considered a valid server name by the specified protocol.
     *
     * @param serverName    The <code>String</code> identifying the remote
     *                      server machine.
     * @param protocolName  The name of the remote imaging protocol.
     * @param operationName The name of the operation.
     * @param paramBlock    The source(s) and/or parameter(s) for the operation.
     * @param hints         The hints for the operation.
     *
     * @throws IllegalArgumentException if operationName is null.
     */
    public PlanarImageServerProxy(String serverName,
          String protocolName,
          String operationName,
          ParameterBlock paramBlock,
          RenderingHints hints) {

  // To initialize property and event management stuff, as done by
  // superclass PlanarImage constructor.
  super (null, null, null);

  if (operationName == null) {
      throw new IllegalArgumentException(
        JaiI18N.getString("PlanarImageServerProxy1"));
  }

  this.serverName = serverName;
  this.protocolName = protocolName;
  this.operationName = operationName;
  this.paramBlock = paramBlock;
  this.hints = hints;

  if (hints == null) {
      // If there are no hints specified, use default values
      registry = JAI.getDefaultInstance().getOperationRegistry();
      cache = JAI.getDefaultInstance().getTileCache();
      retryInterval = RemoteJAI.DEFAULT_RETRY_INTERVAL;
      numRetries = RemoteJAI.DEFAULT_NUM_RETRIES;

      // Do negotiation even though there are no preferences, so that
      // negotiation takes place between the client and the server.
      setNegotiationPreferences(null);
  } else {

      registry =
    (OperationRegistry)hints.get(JAI.KEY_OPERATION_REGISTRY);
      if (registry == null) {
    registry = JAI.getDefaultInstance().getOperationRegistry();
      }

      cache = (TileCache)hints.get(JAI.KEY_TILE_CACHE);
      if (cache == null) {
    cache = JAI.getDefaultInstance().getTileCache();
      }

      Integer integer = (Integer)hints.get(JAI.KEY_RETRY_INTERVAL);
      if (integer == null) {
    retryInterval = RemoteJAI.DEFAULT_RETRY_INTERVAL;
      } else {
    retryInterval = integer.intValue();
      }

      integer = (Integer)hints.get(JAI.KEY_NUM_RETRIES);
      if (integer == null) {
    numRetries = RemoteJAI.DEFAULT_NUM_RETRIES;
      } else {
    numRetries = integer.intValue();
      }

      tileCacheMetric = (Object)hints.get(JAI.KEY_TILE_CACHE_METRIC);

      // Cause negotiation to take place.
      setNegotiationPreferences((NegotiableCapabilitySet)
           hints.get(JAI.KEY_NEGOTIATION_PREFERENCES));
  }

  if (paramBlock != null) {
      setSources(paramBlock.getSources());
  }
     }

    /**
     * Returns the <code>String</code> that identifies the server.
     */
    public String getServerName() {
  return serverName;
    }

    /**
     * Returns the <code>String</code> that identifies the remote imaging
     * protocol.
     */
    public String getProtocolName() {
  return protocolName;
    }

    /**
     * Returns the operation name as a <code>String</code>.
     */
    public String getOperationName() {
  return operationName;
    }

    /**
     * Returns the <code>ParameterBlock</code> that specifies the
     * sources and parameters for the operation to be performed by
     * this <code>PlanarImageServerProxy</code>.
     */
    public ParameterBlock getParameterBlock() {
  return paramBlock;
    }

    /**
     * Returns the <code>RenderingHints</code> associated with the
     * operation to be performed by this <code>PlanarImageServerProxy</code>.
     */
    public RenderingHints getRenderingHints() {
  return hints;
    }

    /**
     * Returns the tile cache object of this image by reference.
     * If this image does not have a tile cache, this method returns
     * <code>null</code>.
     */
    public TileCache getTileCache() {
        return cache;
    }

    /**
     * Sets the tile cache object of this image.  A <code>null</code>
     * input indicates that this image should have no tile cache and
     * subsequently computed tiles will not be cached.
     *
     * <p> The existing cache object is informed to release all the
     * currently cached tiles of this image.
     *
     * @param cache  A cache object to be used for caching this image's
     *        tiles, or <code>null</code> if no tile caching is desired.
     */
    public void setTileCache(TileCache cache) {
        if (this.cache != null) {
            this.cache.removeTiles(this);
        }
        this.cache = cache;
    }

    /**
     * Returns the <code>tileCacheMetric</code> instance variable by reference.
     */
    public Object getTileCacheMetric() {
        return tileCacheMetric;
    }

    /**
     * Get the layout of the image. This could be implemented by either
     * asking the server to specify the layout, or have the client compute
     * the image layout. The <code>ImageLayout</code> object returned must
     * have all its fields initialized, else an <code>Error</code> will be
     * thrown. Network errors encountered should be signalled
     * by throwing a <code>RemoteImagingException</code>.
     *
     * @throws RemoteImagingException if an error condition during remote
     *         image processing occurs
     * @throws Error if all the fields in the ImageLayout are not initialized.
     */
    public abstract ImageLayout getImageLayout() throws RemoteImagingException;

    /**
     * Returns a property from the property set generated on the remote
     * server machine. Network errors encountered should be signalled
     * by throwing a <code>RemoteImagingException</code>. If the property
     * name is not recognized, java.awt.Image.UndefinedProperty will be
     * returned.
     *
     * @throws RemoteImagingException if an error condition during remote
     *         image processing occurs
     * @throws IllegalArgumentException if name is null.
     */
    public abstract Object getRemoteProperty(String name)
  throws RemoteImagingException;

    /**
     * Returns a list of names recognized by the <code>getRemoteProperty</code>
     * method. Network errors encountered should be signalled by
     * throwing a <code>RemoteImagingException</code>.
     *
     * @throws RemoteImagingException if an error condition during remote
     *         image processing occurs
     */
    public abstract String[] getRemotePropertyNames()
  throws RemoteImagingException;

    /**
     * Returns a conservative estimate of the destination region that
     * can potentially be affected by the pixels of a rectangle of a
     * given source. This can be implemented by either asking the server
     * to compute the destination region, or by having the client compute
     * the destination region. Network errors encountered should be
     * signalled by throwing a <code>RemoteImagingException</code>.
     *
     * @param sourceRect  The <code>Rectangle</code> in source coordinates.
     * @param sourceIndex  The index of the source image.
     *
     * @return A <code>Rectangle</code> indicating the potentially
     *         affected destination region, or <code>null</code> if
     *         the region is unknown.
     *
     * @throws IllegalArgumentException  If the source index is
     *         negative or greater than that of the last source.
     * @throws IllegalArgumentException  If <code>sourceRect</code> is
     *         <code>null</code>.
     */
    public abstract Rectangle mapSourceRect(Rectangle sourceRect,
                                            int sourceIndex)
  throws RemoteImagingException;

    /**
     * Returns a conservative estimate of the region of a specified
     * source that is required in order to compute the pixels of a
     * given destination rectangle. Either the server or the client can
     * compute the source region to implement this method. Network errors
     * encountered should be signalled by throwing a
     * <code>RemoteImagingException</code>.
     *
     * @param destRect  The <code>Rectangle</code> in destination coordinates.
     * @param sourceIndex  The index of the source image.
     *
     * @return A <code>Rectangle</code> indicating the required source region.
     *
     * @throws IllegalArgumentException  If the source index is
     *         negative or greater than that of the last source.
     * @throws IllegalArgumentException  If <code>destRect</code> is
     *         <code>null</code>.
     */
    public abstract Rectangle mapDestRect(Rectangle destRect,
                                          int sourceIndex)
  throws RemoteImagingException;

    /**
     * Returns tile (tileX, tileY) as computed on the remote server machine.
     * Note that tileX and tileY are indices into the tile array, not pixel
     * locations. The <code>Raster</code> that is returned is a copy.
     * Network errors encountered should be signalled by throwing a
     * <code>RemoteImagingException</code>.
     *
     * <p> Subclasses must implement this method to return a
     * non-<code>null</code> value for all tile indices between
     * <code>getMinTile{X,Y}</code> and <code>getMaxTile{X,Y}</code>,
     * inclusive.  Tile indices outside of this region should result
     * in a return value of <code>null</code>.
     *
     * @param tileX the X index of the requested tile in the tile array.
     * @param tileY the Y index of the requested tile in the tile array.
     * @throws RemoteImagingException if an error condition during remote
     *         image processing occurs
     */
    public abstract Raster computeTile(int tileX, int tileY)
  throws RemoteImagingException;

    /**
     * Returns the amount of time between retries in milliseconds.
     */
    public int getRetryInterval() {
  return retryInterval;
    }

    /**
     * Sets the amount of time between retries in milliseconds.
     *
     * @param retryInterval The amount of time (in milliseconds) to wait
     *                      between retries.
     * @throws IllegalArgumentException if retryInterval is negative.
     */
    public void setRetryInterval(int retryInterval) {
  if (retryInterval < 0) {
            throw new IllegalArgumentException(JaiI18N.getString("Generic3"));
        }
  this.retryInterval = retryInterval;
    }

    /**
     * Returns the number of retries.
     */
    public int getNumRetries() {
  return numRetries;
    }

    /**
     * Sets the number of retries.
     *
     * @param numRetries The number of times an operation should be retried
     *                   in case of a network error.
     * @throws IllegalArgumentException if numRetries is negative.
     */
    public void setNumRetries(int numRetries) {
        if (numRetries < 0) {
            throw new IllegalArgumentException(JaiI18N.getString("Generic4"));
        }
  this.numRetries = numRetries;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the X
     * coordinate of the leftmost column of the remote image.
     */
    public int getMinX() {
  requestLayout();
  return minX;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the X
     * coordinate of the column immediately to the right of the rightmost
     * column of the remote image.
     */
    public int getMaxX() {
  requestLayout();
  return minX + width;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the Y
     * coordinate of the uppermost row of the remote image.
     */
    public int getMinY() {
  requestLayout();
  return minY;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the Y
     * coordinate of the row immediately below the bottom row of the
     * remote image.
     */
    public int getMaxY() {
  requestLayout();
  return minY + height;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the width
     * of the remote image.
     */
    public int getWidth() {
  requestLayout();
  return width;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the height
     * of the remote image.
     */
    public int getHeight() {
  requestLayout();
  return height;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the width
     * of a tile remotely.
     */
    public int getTileWidth() {
  requestLayout();
  return tileWidth;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the height
     * of a tile remotely.
     */
    public int getTileHeight() {
  requestLayout();
  return tileHeight;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the X
     * coordinate of the upper-left pixel of tile (0, 0) remotely.
     */
    public int getTileGridXOffset() {
  requestLayout();
  return tileGridXOffset;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the Y
     * coordinate of the upper-left pixel of tile (0, 0) remotely.
     */
    public int getTileGridYOffset() {
  requestLayout();
  return tileGridYOffset;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the
     * <code>SampleModel</code> of the remote image.
     */
    public SampleModel getSampleModel() {
        requestLayout();
  return sampleModel;
    }

    /**
     * Overrides the method in <code>PlanarImage</code> to return the
     * <code>ColorModel</code> of the remote image.
     */
    public ColorModel getColorModel() {
  requestLayout();
  return colorModel;
    }

    /**
     * Cause the subclass' <code>getImageLayout</code> method to be called,
     * caching the <code>ImageLayout</code> object locally.
     *
     * @throws IllegalArgumentException if getImageLayout returns null.
     * @throws Error if all the fields of the layout are not initialized.
     * @throws RemoteImagingException if the limit of retries is exceeded.
     */
    private ImageLayout requestLayout() {

  if (layout != null)
      return layout;

  Exception rieSave = null;
        int count = 0;
        while (count++ < numRetries) {
            try {
    layout = getImageLayout();
    // Check that all the fields are initialized
    checkLayout(layout);

    // Set all the super class variables
    minX = layout.getMinX(null);
    minY = layout.getMinY(null);
    width = layout.getWidth(null);
    height = layout.getHeight(null);
    tileWidth = layout.getTileWidth(null);
    tileHeight = layout.getTileHeight(null);
    tileGridXOffset = layout.getTileGridXOffset(null);
    tileGridYOffset = layout.getTileGridYOffset(null);
    sampleModel = layout.getSampleModel(null);
    colorModel = layout.getColorModel(null);
    break;
            } catch (RemoteImagingException e) {
                System.err.println(
        JaiI18N.getString("PlanarImageServerProxy0"));
    rieSave = e;
    // Sleep for retryInterval milliseconds before retrying.
                try {
                    Thread.sleep(retryInterval);
                } catch (InterruptedException f) {
                }
            }
        }

  if (layout == null) {
            sendExceptionToListener(rieSave);
  }

  return layout;
    }

    /**
     * Gets a property from the property set of this image.  If the
     * property name is not recognized,
     * <code>java.awt.Image.UndefinedProperty</code> will be returned.
     * The property to be returned is first looked for in the set of
     * locally cached properties. If not found, the
     * <code>getRemoteProperty</code> method is called to retrieve the
     * property. Network errors that might be encountered during the
     * <code>getRemoteProperty</code> call are dealt with by retries and
     * retry intervals.
     *
     * @param name the name of the property to get, as a <code>String</code>.
     * @return a reference to the property <code>Object</code>, or the value
     * <code>java.awt.Image.UndefinedProperty</code>.
     *
     * @throws RemoteImagingException if the limit of retries is exceeded.
     */
    public Object getProperty(String name) {

  // Try to get property locally.
        Object property = super.getProperty(name);

        if (property == null || property == Image.UndefinedProperty) {

      Exception rieSave = null;
      int count=0;
      while(count++ < numRetries) {
    try {
        property = getRemoteProperty(name);
        if(property != Image.UndefinedProperty) {
      setProperty(name, property); // Cache property locally
        }
        return property;
    } catch (RemoteImagingException rie) {
        System.err.println(
        JaiI18N.getString("PlanarImageServerProxy0"));
        rieSave = rie;
        try {
      Thread.sleep(retryInterval);
        } catch (InterruptedException ie) {
        }
    }
      }

            sendExceptionToListener(rieSave);
            return property;
  } else {
      return property;
  }
    }

    /**
     * Returns a list of property names that are recognized by this image
     * or <code>null</code> if none are recognized. The list of recognized
     * property names consists of the locally cached property names
     * (retrieved via <code>super.getPropertyNames</code>) as well as
     * those that might be generated by the operations performed on the
     * remote server machine (retrieved via
     * <code>getRemotePropertyNames</code>). Network errors that might be
     * encountered during the <code>getRemotePropertyNames</code> method
     * are dealt with by retries and retry intervals.
     *
     * @return an array of <code>String</code>s containing valid
     *         property names.
     *
     * @throws RemoteImagingException if the limit of retries is exceeded.
     */
    public String[] getPropertyNames() {

  // Retrieve local property names.
        String[] localPropertyNames = super.getPropertyNames();

  Vector names = new Vector();
        // Put local names in a Vector, if any
  if (localPropertyNames != null) {
      for(int i = 0; i < localPropertyNames.length; i++) {
    names.add(localPropertyNames[i]);
      }
  }

  int count=0;
        String[] remotePropertyNames = null;
  Exception rieSave = null;

  while(count++ < numRetries) {
      try {
    remotePropertyNames = getRemotePropertyNames();
    break;
      } catch (RemoteImagingException rie) {
                System.err.println(
        JaiI18N.getString("PlanarImageServerProxy0"));
    rieSave = rie;
    try {
        Thread.sleep(retryInterval);
    } catch (InterruptedException ie) {
    }
      }
  }

  if (count > numRetries) {
            sendExceptionToListener(rieSave);
  }

  // Put the remote names, if any, in the Vector.
        if(remotePropertyNames != null) {
            for(int i = 0; i < remotePropertyNames.length; i++) {
                if(!names.contains(remotePropertyNames[i])) {
                    names.add(remotePropertyNames[i]);
                }
            }
        }

        // Set the return value from the vector.
        String propertyNames[] = names.size() == 0 ?
            null : (String[])names.toArray(new String[names.size()]);

        return propertyNames;
    }

    /**
     * Returns the tile (tileX, tileY). Note the tileX and tileY are indices
     * into the tile array and not pixel positions. This method is
     * implemented in terms of the <code>computeTile</code> method. This
     * method deals with Network errors (recognized as
     * <code>RemoteImagingExceptions</code>) through retries and retry
     * intervals. This method also performs caching of tiles, so that
     * an already computed tile does not need to be re-computed.
     *
     * @param tileX the X index of the tile.
     * @param tileY the Y index of the tile.
     * @throws RemoteImagingException if limit of retries is exceeded.
     */
    public Raster getTile(int tileX, int tileY) {

  Raster tile = null;

  // Make sure the requested tile is inside this image's boundary.
        if (tileX >= getMinTileX() && tileX <= getMaxTileX() &&
            tileY >= getMinTileY() && tileY <= getMaxTileY()) {

      // Check if tile is available in the cache.
      tile = cache != null ? cache.getTile(this, tileX, tileY) : null;

            if (tile == null) {         // tile not in cache
                // Ask the subclass for the tile
    int count = 0;
    Exception rieSave = null;
    while (count++ < numRetries) {
        try {
      tile = computeTile(tileX, tileY);
      break;
        } catch (RemoteImagingException rie) {
      System.err.println(
        JaiI18N.getString("PlanarImageServerProxy0"));
      rieSave = rie;
      try {
          Thread.sleep(retryInterval);
      } catch (InterruptedException ie) {

      }
        }
    }

    if (count > numRetries) {
                    sendExceptionToListener(rieSave);
    }

                // Cache the result tile.
    if (cache != null) {
        cache.add(this, tileX, tileY, tile, tileCacheMetric);
    }
            }
        }

        return tile;
    }

    /**
     * Uncaches all the tiles when this image is garbage collected.
     */
    protected void finalize() throws Throwable {
        if (cache != null) {
            cache.removeTiles(this);
        }
        super.finalize();
    }

    //
    // NEGOTIATION RELATED METHODS
    //

    /**
     * Returns the current negotiation preferences or null, if none were
     * set previously.
     */
    public NegotiableCapabilitySet getNegotiationPreferences() {
  return preferences;
    }

    /**
     * Sets the preferences to be used in the client-server
     * communication. These preferences are utilized in the negotiation
     * process. Note that preferences for more than one category can be
     * specified using this method. Also each preference can be a list
     * of values in decreasing order of preference, each value specified
     * as a <code>NegotiableCapability</code>. The
     * <code>NegotiableCapability</code> first (for a particular category)
     * in this list is given highest priority in the negotiation process
     * (for that category).
     *
     * <p> It may be noted that this method allows for multiple negotiation
     * cycles. Everytime this method is called, new preferences are
     * specified for the negotiation, which takes place anew to produce
     * a new set of negotiated resultant values to be used in the
     * remote communication. If the subclass wants to ignore the
     * negotiation preferences newly set, this method can be overridden to
     * do so.
     *
     * @param preferences The preferences to be used in the negotiation
     * process.
     */
    public void setNegotiationPreferences(NegotiableCapabilitySet preferences)
    {
  this.preferences = preferences;

  // Every time new preferences are set, invalidate old Negotiation
  // results and do the negotiation again.
  negotiated = null;

  getNegotiatedValues();
    }

    /**
     * Returns the results of the negotiation process. This will return null
     * if no negotiation preferences were set, and no negotiation was
     * performed, or if the negotiation failed.
     */
    public synchronized NegotiableCapabilitySet getNegotiatedValues()
  throws RemoteImagingException {

  // If negotiation was not performed before, or if new preferences
  // have invalidated the old negotiated results.
  if (negotiated == null) {

      // Initialize the clientCapabilities and serverCapabilities
      // variables
      getCapabilities();

      // Do the negotiation
      negotiated = RemoteJAI.negotiate(preferences,
               serverCapabilities,
               clientCapabilities);

      // Inform the server of the negotiated values.
      setServerNegotiatedValues(negotiated);
  }

  return negotiated;
    }

    /**
     * Returns the results of the negotiation process for the given category.
     * This will return null if no negotiation preferences were set, and
     * no negotiation was performed, or if the negotiation failed.
     *
     * @param category The category to return the negotiated results for.
     * @throws IllegalArgumentException if category is null.
     */
    public NegotiableCapability getNegotiatedValue(String category)
  throws RemoteImagingException {

  // We do not need to check for category being null, since that
  // check will be made by the methods called from within this method.

  // If negotiation was not performed before, or if new preferences
  // have invalidated the old negotiated results.
  if (negotiated == null) {

      getCapabilities();

      // Do the negotiation
      return RemoteJAI.negotiate(preferences,
               serverCapabilities,
               clientCapabilities,
               category);
  } else {
      // If negotiated is not null, then the negotiated results are
      // current and the result for the given category can just be
      // extracted from there and returned.
      return negotiated.getNegotiatedValue(category);
  }
    }

    // Get the client and server capabilities
    private void getCapabilities() {

  String mode = "remoteRendered";
  if (serverCapabilities == null) {

      RemoteDescriptor desc =
    (RemoteDescriptor)registry.getDescriptor(mode, protocolName);

      int count = 0;
      Exception rieSave = null;
      while (count++ < numRetries) {
    try {
        serverCapabilities =
      desc.getServerCapabilities(serverName);
        break;
    } catch (RemoteImagingException rie) {
        System.err.println(
        JaiI18N.getString("PlanarImageServerProxy0"));
        rieSave = rie;
        try {
      Thread.sleep(retryInterval);
        } catch (InterruptedException ie) {
        }
    }
      }

      if (count > numRetries) {
                sendExceptionToListener(rieSave);
      }
  }

  if (clientCapabilities == null) {
      RemoteRIF rrif =
    (RemoteRIF)registry.getFactory(mode, protocolName);

      clientCapabilities = rrif.getClientCapabilities();
  }
    }

    void sendExceptionToListener(Exception e) {
        ImagingListener listener = null;
        if (hints != null)
            listener = (ImagingListener)hints.get(JAI.KEY_IMAGING_LISTENER);
        else
            listener = JAI.getDefaultInstance().getImagingListener();
        String message = JaiI18N.getString("PlanarImageServerProxy2");
        listener.errorOccurred(message,
                               new RemoteImagingException(message, e),
                               this, false);
    }
}
TOP

Related Classes of com.lightcrafts.mediax.jai.remote.PlanarImageServerProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.