Source Code Cross Referenced for JAIRMIImageServer.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » jai » rmi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » com.sun.media.jai.rmi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: JAIRMIImageServer.java,v $
0003:         *
0004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Use is subject to license terms.
0007:         *
0008:         * $Revision: 1.1 $
0009:         * $Date: 2005/02/11 04:56:51 $
0010:         * $State: Exp $
0011:         */package com.sun.media.jai.rmi;
0012:
0013:        import java.awt.Dimension;
0014:        import java.awt.Rectangle;
0015:        import java.awt.RenderingHints;
0016:        import java.awt.Shape;
0017:        import java.awt.geom.Rectangle2D;
0018:        import java.awt.image.ColorModel;
0019:        import java.awt.image.SampleModel;
0020:        import java.awt.image.Raster;
0021:        import java.awt.image.RenderedImage;
0022:        import java.awt.image.WritableRaster;
0023:        import java.awt.image.renderable.ContextualRenderedImageFactory;
0024:        import java.awt.image.renderable.ParameterBlock;
0025:        import java.awt.image.renderable.RenderContext;
0026:        import java.awt.image.renderable.RenderableImage;
0027:        import java.io.ByteArrayOutputStream;
0028:        import java.io.Serializable;
0029:        import java.net.InetAddress;
0030:        import java.rmi.Naming;
0031:        import java.rmi.Remote;
0032:        import java.rmi.RemoteException;
0033:        import java.rmi.RMISecurityManager;
0034:        import java.rmi.server.UnicastRemoteObject;
0035:        import java.util.Collection;
0036:        import java.util.Hashtable;
0037:        import java.util.List;
0038:        import java.util.Iterator;
0039:        import java.util.Vector;
0040:        import javax.media.jai.CollectionOp;
0041:        import javax.media.jai.CollectionImage;
0042:        import javax.media.jai.JAI;
0043:        import javax.media.jai.OperationDescriptor;
0044:        import javax.media.jai.OperationRegistry;
0045:        import javax.media.jai.OpImage;
0046:        import javax.media.jai.ParameterListDescriptor;
0047:        import javax.media.jai.PlanarImage;
0048:        import javax.media.jai.PropertyChangeEventJAI;
0049:        import javax.media.jai.PropertySource;
0050:        import javax.media.jai.RenderingChangeEvent;
0051:        import javax.media.jai.RenderableOp;
0052:        import javax.media.jai.RenderedOp;
0053:        import javax.media.jai.registry.CRIFRegistry;
0054:        import javax.media.jai.remote.JAIRMIDescriptor;
0055:        import javax.media.jai.remote.RemoteImagingException;
0056:        import javax.media.jai.remote.RemoteRenderedOp;
0057:        import javax.media.jai.remote.NegotiableCapability;
0058:        import javax.media.jai.remote.NegotiableCapabilitySet;
0059:        import javax.media.jai.remote.SerializableRenderedImage;
0060:        import javax.media.jai.remote.SerializableState;
0061:        import javax.media.jai.remote.SerializerFactory;
0062:        import javax.media.jai.tilecodec.TileCodecDescriptor;
0063:        import javax.media.jai.tilecodec.TileCodecParameterList;
0064:        import javax.media.jai.tilecodec.TileDecoderFactory;
0065:        import javax.media.jai.tilecodec.TileEncoder;
0066:        import javax.media.jai.tilecodec.TileEncoderFactory;
0067:        import javax.media.jai.util.ImagingListener;
0068:        import com.sun.media.jai.util.ImageUtil;
0069:        import com.sun.media.jai.util.Service;
0070:        import com.sun.media.jai.remote.JAIServerConfigurationSpi;
0071:
0072:        /**
0073:         * The server-side implementation of the ImageServer interface.  A
0074:         * JAIRMIImageServer has a RenderedImage source, acquired via one of three
0075:         * setSource() methods.  The first takes a RenderedImage directly as
0076:         * its parameter; this image is simply copied over the network using
0077:         * the normal RMI mechanisms.  Note that not every image can be
0078:         * transferred in this way -- for example, attempting to pass an
0079:         * OpImage that uses native code or that depends on the availability
0080:         * of a class not resident on the server as a parameter will cause an
0081:         * exception to be thrown.
0082:         *
0083:         * <p> The second and third ways of setting sources make use of the
0084:         * RenderedOp and RenderableOp classes to send a high-level
0085:         * description of an image chain based on operation names.  This
0086:         * chain will be copied over to the server using RMI, where it will be
0087:         * expanded into an OpImage chain using the server's registry.  This
0088:         * is the preferred method since it requires less data transfer and
0089:         * offers a better chance of success.  It may still fail if the
0090:         * sources or parameters of any operation in the chain are not
0091:         * serializable.
0092:         *
0093:         * <p> RMI requires all remote methods to declare `throws
0094:         * RemoteException' in their signatures.  It is up to the client to
0095:         * deal with errors.  A simple implementation of error handling may be
0096:         * found in the RemoteRenderedImage class.
0097:         *
0098:         * <p> This class contains a main() method that should be run on the
0099:         * server after starting the RMI registry.  The registry will then
0100:         * construct new instances of JAIRMIImageServer on demand.
0101:         *
0102:         * @see ImageServer
0103:         * @see RenderedOp
0104:         *
0105:         * @since 1.1
0106:         */
0107:        public class JAIRMIImageServer extends UnicastRemoteObject implements 
0108:                ImageServer {
0109:
0110:            private boolean DEBUG = true;
0111:
0112:            /** Tag to represent a null property. */
0113:            public static final Object NULL_PROPERTY = RMIImageImpl.NULL_PROPERTY;
0114:
0115:            /** Identifier counter for the remote images. */
0116:            private static long idCounter = 0;
0117:
0118:            /**
0119:             * The RenderedImage nodes hashed by an ID string which must be unique
0120:             * across all possible clients of this object.
0121:             */
0122:            private static Hashtable nodes = new Hashtable();
0123:
0124:            /**
0125:             * Hashtable to store the negotiated values for each id.
0126:             */
0127:            private static Hashtable negotiated = new Hashtable();
0128:
0129:            /**
0130:             * Hashtable to store the number of references existing to a
0131:             * particular id on this server.
0132:             */
0133:            private static Hashtable refCount = new Hashtable();
0134:
0135:            /**
0136:             * Retrieve a PlanarImage source from the Hashtable of sources.
0137:             *
0138:             * @param id The unique ID of the source.
0139:             * @return The source.
0140:             */
0141:            private static PlanarImage getSource(Long id)
0142:                    throws RemoteException {
0143:                Object obj = null;
0144:                if (nodes == null || (obj = nodes.get(id)) == null) {
0145:                    throw new RemoteException(JaiI18N
0146:                            .getString("RMIImageImpl2"));
0147:                }
0148:                return (PlanarImage) obj;
0149:            }
0150:
0151:            /**
0152:             * Retrieve a PropertySource from the Hashtable of PropertySources.
0153:             *
0154:             * @param id The unique ID of the source.
0155:             * @return The PropertySource.
0156:             */
0157:            private static PropertySource getPropertySource(Long id)
0158:                    throws RemoteException {
0159:
0160:                Object obj = nodes.get(id);
0161:                return (PropertySource) obj;
0162:            }
0163:
0164:            /**
0165:             * Constructs a JAIRMIImageServer with a source to be specified
0166:             * later.
0167:             */
0168:            public JAIRMIImageServer(int serverport) throws RemoteException {
0169:                super (serverport);
0170:            }
0171:
0172:            /**
0173:             * Returns the identifier of the remote image. This method should be
0174:             * called to return an identifier before any other methods are invoked.
0175:             * The same ID must be used in all subsequent references to the remote
0176:             * image.
0177:             */
0178:            public synchronized Long getRemoteID() throws RemoteException {
0179:                return new Long(++idCounter);
0180:            }
0181:
0182:            /**
0183:             * Disposes of any resouces allocated to the client object with
0184:             * the specified ID.
0185:             */
0186:            public synchronized void dispose(Long id) throws RemoteException {
0187:
0188:                int count = ((Integer) refCount.get(id)).intValue();
0189:
0190:                if (count == 1) {
0191:
0192:                    // If this was the last reference, remove all Objects
0193:                    // associated with this id in various Hashtables.
0194:                    if (nodes != null) {
0195:                        nodes.remove(id);
0196:                        negotiated.remove(id);
0197:                    }
0198:
0199:                    refCount.remove(id);
0200:
0201:                } else {
0202:
0203:                    // Decrement count of references to this id.
0204:                    count--;
0205:                    if (count == 0) {
0206:                        refCount.remove(id);
0207:                    }
0208:                    refCount.put(id, new Integer(count));
0209:                }
0210:            }
0211:
0212:            /**
0213:             * Increments the reference count for this id, i.e. increments the
0214:             * number of RMIServerProxy objects that currently reference this id.
0215:             */
0216:            public void incrementRefCount(Long id) throws RemoteException {
0217:                Integer iCount = (Integer) refCount.get(id);
0218:                int count = 0;
0219:                if (iCount != null) {
0220:                    count = iCount.intValue();
0221:                }
0222:                count++;
0223:                refCount.put(id, new Integer(count));
0224:            }
0225:
0226:            /** Gets a property from the property set of this image.  If the
0227:             *	property is undefined the constant NULL_PROPERTY is returned.
0228:             */
0229:            public Object getProperty(Long id, String name)
0230:                    throws RemoteException {
0231:
0232:                PropertySource ps = getPropertySource(id);
0233:                Object property = ps.getProperty(name);
0234:
0235:                if (property == null
0236:                        || property.equals(java.awt.Image.UndefinedProperty)) {
0237:                    property = NULL_PROPERTY;
0238:                }
0239:
0240:                return property;
0241:            }
0242:
0243:            /**
0244:             * Returns a list of names recognized by getProperty().
0245:             *
0246:             * @return an array of Strings representing property names.
0247:             */
0248:            public String[] getPropertyNames(Long id) throws RemoteException {
0249:
0250:                PropertySource ps = getPropertySource(id);
0251:                return ps.getPropertyNames();
0252:
0253:            }
0254:
0255:            /**
0256:             * Returns a list of names recognized by getProperty().
0257:             *
0258:             * @return an array of Strings representing property names.
0259:             */
0260:            public String[] getPropertyNames(String opName)
0261:                    throws RemoteException {
0262:
0263:                return (CRIFRegistry.get(null, opName)).getPropertyNames();
0264:            }
0265:
0266:            /** Returns the minimum X coordinate of the ImageServer. */
0267:            public int getMinX(Long id) throws RemoteException {
0268:                return getSource(id).getMinX();
0269:            }
0270:
0271:            /** Returns the smallest X coordinate to the right of the ImageServer. */
0272:            public int getMaxX(Long id) throws RemoteException {
0273:
0274:                return getSource(id).getMaxX();
0275:            }
0276:
0277:            /** Returns the minimum Y coordinate of the ImageServer. */
0278:            public int getMinY(Long id) throws RemoteException {
0279:
0280:                return getSource(id).getMinY();
0281:            }
0282:
0283:            /** Returns the smallest Y coordinate below the ImageServer. */
0284:            public int getMaxY(Long id) throws RemoteException {
0285:
0286:                return getSource(id).getMaxY();
0287:            }
0288:
0289:            /** Returns the width of the ImageServer. */
0290:            public int getWidth(Long id) throws RemoteException {
0291:
0292:                return getSource(id).getWidth();
0293:            }
0294:
0295:            /** Returns the height of the ImageServer. */
0296:            public int getHeight(Long id) throws RemoteException {
0297:
0298:                return getSource(id).getHeight();
0299:            }
0300:
0301:            /** Returns the width of a tile in pixels. */
0302:            public int getTileWidth(Long id) throws RemoteException {
0303:
0304:                return getSource(id).getTileWidth();
0305:            }
0306:
0307:            /** Returns the height of a tile in pixels. */
0308:            public int getTileHeight(Long id) throws RemoteException {
0309:
0310:                return getSource(id).getTileHeight();
0311:            }
0312:
0313:            /**
0314:             * Returns the X coordinate of the upper-left pixel of tile (0, 0).
0315:             */
0316:            public int getTileGridXOffset(Long id) throws RemoteException {
0317:
0318:                return getSource(id).getTileGridXOffset();
0319:            }
0320:
0321:            /**
0322:             * Returns the Y coordinate of the upper-left pixel of tile (0, 0).
0323:             */
0324:            public int getTileGridYOffset(Long id) throws RemoteException {
0325:
0326:                return getSource(id).getTileGridYOffset();
0327:            }
0328:
0329:            /** Returns the index of the leftmost column of tiles. */
0330:            public int getMinTileX(Long id) throws RemoteException {
0331:
0332:                return getSource(id).getMinTileX();
0333:            }
0334:
0335:            /**
0336:             * Returns the number of tiles along the tile grid in the horizontal
0337:             * direction.
0338:             */
0339:            public int getNumXTiles(Long id) throws RemoteException {
0340:
0341:                return getSource(id).getNumXTiles();
0342:            }
0343:
0344:            /** Returns the index of the uppermost row of tiles. */
0345:            public int getMinTileY(Long id) throws RemoteException {
0346:
0347:                return getSource(id).getMinTileY();
0348:            }
0349:
0350:            /**
0351:             * Returns the number of tiles along the tile grid in the vertical
0352:             * direction.
0353:             */
0354:            public int getNumYTiles(Long id) throws RemoteException {
0355:
0356:                return getSource(id).getNumYTiles();
0357:            }
0358:
0359:            /** Returns the index of the rightmost column of tiles. */
0360:            public int getMaxTileX(Long id) throws RemoteException {
0361:
0362:                return getSource(id).getMaxTileX();
0363:            }
0364:
0365:            /** Returns the index of the bottom row of tiles. */
0366:            public int getMaxTileY(Long id) throws RemoteException {
0367:
0368:                return getSource(id).getMaxTileY();
0369:            }
0370:
0371:            /** Returns the SampleModel associated with this image. */
0372:            public SerializableState getSampleModel(Long id)
0373:                    throws RemoteException {
0374:                return SerializerFactory.getState(getSource(id)
0375:                        .getSampleModel(), null);
0376:            }
0377:
0378:            /** Returns the ColorModel associated with this image. */
0379:            public SerializableState getColorModel(Long id)
0380:                    throws RemoteException {
0381:                return SerializerFactory.getState(
0382:                        getSource(id).getColorModel(), null);
0383:            }
0384:
0385:            /** Returns a Rectangle indicating the image bounds. */
0386:            public Rectangle getBounds(Long id) throws RemoteException {
0387:
0388:                return getSource(id).getBounds();
0389:            }
0390:
0391:            /**
0392:             * Returns tile (x, y).  Note that x and y are indices into the
0393:             * tile array, not pixel locations.  Unlike in the true RenderedImage
0394:             * interface, the Raster that is returned should be considered a copy.
0395:             *
0396:             * @param id An ID for the source which must be unique across all clients.
0397:             * @param tileX the X index of the requested tile in the tile array.
0398:             * @param tileY the Y index of the requested tile in the tile array.
0399:             * @return the tile as a Raster.
0400:             */
0401:            public SerializableState getTile(Long id, int tileX, int tileY)
0402:                    throws RemoteException {
0403:
0404:                Raster r = getSource(id).getTile(tileX, tileY);
0405:                return SerializerFactory.getState(r, null);
0406:            }
0407:
0408:            /**
0409:             * Compresses tile (x, y) and returns the compressed tile's contents
0410:             * as a byte array.  Note that x and y are indices into the
0411:             * tile array, not pixel locations.  Unlike in the true RenderedImage
0412:             * interface, the Raster that is returned should be considered a copy.
0413:             *
0414:             * @param id An ID for the source which must be unique across all clients.
0415:             * @param x the x index of the requested tile in the tile array
0416:             * @param y the y index of the requested tile in the tile array
0417:             * @return a byte array containing the compressed tile contents.
0418:             */
0419:            public byte[] getCompressedTile(Long id, int x, int y)
0420:                    throws RemoteException {
0421:
0422:                TileCodecParameterList tcpl = null;
0423:                TileEncoderFactory tef = null;
0424:                NegotiableCapability codecCap = null;
0425:
0426:                if (negotiated != null) {
0427:                    codecCap = ((NegotiableCapabilitySet) negotiated.get(id))
0428:                            .getNegotiatedValue("tileCodec");
0429:                }
0430:
0431:                if (codecCap != null) {
0432:
0433:                    String category = codecCap.getCategory();
0434:                    String capabilityName = codecCap.getCapabilityName();
0435:                    List generators = codecCap.getGenerators();
0436:
0437:                    Class factory;
0438:                    for (Iterator i = generators.iterator(); i.hasNext();) {
0439:
0440:                        factory = (Class) i.next();
0441:                        if (tef == null
0442:                                && TileEncoderFactory.class
0443:                                        .isAssignableFrom(factory)) {
0444:                            try {
0445:                                tef = (TileEncoderFactory) factory
0446:                                        .newInstance();
0447:                            } catch (InstantiationException ie) {
0448:                                throw new RuntimeException(ie.getMessage());
0449:                            } catch (IllegalAccessException iae) {
0450:                                throw new RuntimeException(iae.getMessage());
0451:                            }
0452:                        }
0453:                    }
0454:
0455:                    if (tef == null) {
0456:                        throw new RuntimeException(JaiI18N
0457:                                .getString("JAIRMIImageServer0"));
0458:                    }
0459:
0460:                    TileCodecDescriptor tcd = (TileCodecDescriptor) JAI
0461:                            .getDefaultInstance().getOperationRegistry()
0462:                            .getDescriptor("tileEncoder", capabilityName);
0463:
0464:                    if (tcd.includesSampleModelInfo() == false
0465:                            || tcd.includesLocationInfo() == false) {
0466:                        throw new RuntimeException(JaiI18N
0467:                                .getString("JAIRMIImageServer1"));
0468:                    }
0469:
0470:                    ParameterListDescriptor pld = tcd
0471:                            .getParameterListDescriptor("tileEncoder");
0472:
0473:                    tcpl = new TileCodecParameterList(capabilityName,
0474:                            new String[] { "tileEncoder" }, pld);
0475:
0476:                    if (pld != null) {
0477:
0478:                        String paramNames[] = pld.getParamNames();
0479:                        String currParam;
0480:                        Object currValue;
0481:
0482:                        if (paramNames != null) {
0483:                            for (int i = 0; i < paramNames.length; i++) {
0484:                                currParam = paramNames[i];
0485:                                try {
0486:                                    currValue = codecCap
0487:                                            .getNegotiatedValue(currParam);
0488:                                } catch (IllegalArgumentException iae) {
0489:                                    continue;
0490:                                }
0491:                                tcpl.setParameter(currParam, currValue);
0492:                            }
0493:                        }
0494:                    }
0495:
0496:                    Raster r = getSource(id).getTile(x, y);
0497:                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
0498:                    TileEncoder encoder = tef.createEncoder(stream, tcpl, r
0499:                            .getSampleModel());
0500:
0501:                    try {
0502:                        encoder.encode(r);
0503:                    } catch (java.io.IOException ioe) {
0504:                        throw new RuntimeException(ioe.getMessage());
0505:                    }
0506:
0507:                    return stream.toByteArray();
0508:                } else {
0509:                    throw new RuntimeException(JaiI18N
0510:                            .getString("JAIRMIImageServer2"));
0511:                }
0512:            }
0513:
0514:            /**
0515:             * Returns the entire image as a single Raster.
0516:             *
0517:             * @return a Raster containing a copy of this image's data.
0518:             */
0519:            public SerializableState getData(Long id) throws RemoteException {
0520:                return SerializerFactory
0521:                        .getState(getSource(id).getData(), null);
0522:            }
0523:
0524:            /**
0525:             * Returns an arbitrary rectangular region of the RenderedImage
0526:             * in a Raster.  The rectangle of interest will be clipped against
0527:             * the image bounds.
0528:             *
0529:             * @param id An ID for the source which must be unique across all clients.
0530:             * @param rect the region of the RenderedImage to be returned.
0531:             * @return a SerializableState containing a copy of the desired data.
0532:             */
0533:            public SerializableState getData(Long id, Rectangle bounds)
0534:                    throws RemoteException {
0535:                if (bounds == null) {
0536:                    return getData(id);
0537:                } else {
0538:                    bounds = bounds.intersection(getBounds(id));
0539:                    return SerializerFactory.getState(getSource(id).getData(
0540:                            bounds), null);
0541:                }
0542:            }
0543:
0544:            /**
0545:             * Returns the same result as getData(Rectangle) would for the
0546:             * same rectangular region.
0547:             */
0548:            public SerializableState copyData(Long id, Rectangle bounds)
0549:                    throws RemoteException {
0550:                return getData(id, bounds);
0551:            }
0552:
0553:            /**
0554:             * Creates a RenderedOp on the server side with a parameter block
0555:             * empty of sources. The sources are set by separate calls depending
0556:             * upon the type and serializabilty of the source.
0557:             */
0558:            public void createRenderedOp(Long id, String opName,
0559:                    ParameterBlock pb, SerializableState hints)
0560:                    throws RemoteException {
0561:
0562:                RenderingHints rh = (RenderingHints) hints.getObject();
0563:
0564:                // Check whether any of the parameters are Strings which represent
0565:                // images either on this server or another server.
0566:                JAIRMIUtil.checkServerParameters(pb, nodes);
0567:
0568:                RenderedOp node = new RenderedOp(opName, pb, rh);
0569:
0570:                // Remove all sinks so that no events are sent automatically
0571:                // to the sinks
0572:                node.removeSinks();
0573:
0574:                nodes.put(id, node);
0575:            }
0576:
0577:            /**
0578:             * Calls for Rendering of the Op and returns true if the RenderedOp
0579:             * could be rendered else false
0580:             */
0581:            public boolean getRendering(Long id) throws RemoteException {
0582:
0583:                RenderedOp op = getNode(id);
0584:                if (op.getRendering() == null) {
0585:                    return false;
0586:                } else {
0587:                    return true;
0588:                }
0589:            }
0590:
0591:            /**
0592:             * Retrieve a node from the hashtable
0593:             *
0594:             */
0595:            public RenderedOp getNode(Long id) throws RemoteException {
0596:                return (RenderedOp) nodes.get(id);
0597:            }
0598:
0599:            /**
0600:             *  Sets the source of the image as a RenderedImage on the server side
0601:             */
0602:            public synchronized void setRenderedSource(Long id,
0603:                    RenderedImage source, int index) throws RemoteException {
0604:
0605:                PlanarImage pi = PlanarImage.wrapRenderedImage(source);
0606:
0607:                Object obj = nodes.get(id);
0608:
0609:                if (obj instanceof  RenderedOp) {
0610:                    RenderedOp op = (RenderedOp) obj;
0611:                    op.setSource(pi, index);
0612:                    ((PlanarImage) op.getSourceObject(index)).removeSinks();
0613:                } else if (obj instanceof  RenderableOp) {
0614:                    ((RenderableOp) obj).setSource(pi, index);
0615:                }
0616:            }
0617:
0618:            /**
0619:             *  Sets the source of the image as a RenderedOp on the server side
0620:             */
0621:            public synchronized void setRenderedSource(Long id,
0622:                    RenderedOp source, int index) throws RemoteException {
0623:
0624:                Object obj = nodes.get(id);
0625:                if (obj instanceof  RenderedOp) {
0626:                    RenderedOp op = (RenderedOp) obj;
0627:                    op.setSource(source.getRendering(), index);
0628:                    ((PlanarImage) op.getSourceObject(index)).removeSinks();
0629:                } else if (obj instanceof  RenderableOp) {
0630:                    ((RenderableOp) obj)
0631:                            .setSource(source.getRendering(), index);
0632:                }
0633:            }
0634:
0635:            /**
0636:             * Sets the source of the image which is on the same
0637:             * server
0638:             */
0639:            public synchronized void setRenderedSource(Long id, Long sourceId,
0640:                    int index) throws RemoteException {
0641:
0642:                Object obj = nodes.get(id);
0643:                if (obj instanceof  RenderedOp) {
0644:                    RenderedOp op = (RenderedOp) obj;
0645:                    op.setSource(nodes.get(sourceId), index);
0646:                    ((PlanarImage) nodes.get(sourceId)).removeSinks();
0647:                } else if (obj instanceof  RenderableOp) {
0648:                    ((RenderableOp) obj).setSource(nodes.get(sourceId), index);
0649:                }
0650:            }
0651:
0652:            /**
0653:             * Sets the source of the image which is on a different
0654:             * server
0655:             */
0656:            public synchronized void setRenderedSource(Long id, Long sourceId,
0657:                    String serverName, String opName, int index)
0658:                    throws RemoteException {
0659:
0660:                Object obj = nodes.get(id);
0661:
0662:                if (obj instanceof  RenderedOp) {
0663:                    RenderedOp node = (RenderedOp) obj;
0664:                    node.setSource(new RMIServerProxy(
0665:                            (serverName + "::" + sourceId), opName, null),
0666:                            index);
0667:                    ((PlanarImage) node.getSourceObject(index)).removeSinks();
0668:                } else if (obj instanceof  RenderableOp) {
0669:                    ((RenderableOp) obj).setSource(new RMIServerProxy(
0670:                            (serverName + "::" + sourceId), opName, null),
0671:                            index);
0672:                }
0673:            }
0674:
0675:            /// Renderable Mode Methods
0676:
0677:            /**
0678:             * Gets the minimum X coordinate of the rendering-independent image
0679:             * stored against the given ID.
0680:             *
0681:             * @return the minimum X coordinate of the rendering-independent image
0682:             * data.
0683:             */
0684:            public float getRenderableMinX(Long id) throws RemoteException {
0685:
0686:                RenderableImage ri = (RenderableImage) nodes.get(id);
0687:                return ri.getMinX();
0688:            }
0689:
0690:            /**
0691:             * Gets the minimum Y coordinate of the rendering-independent image
0692:             * stored against the given ID.
0693:             *
0694:             * @return the minimum X coordinate of the rendering-independent image
0695:             * data.
0696:             */
0697:            public float getRenderableMinY(Long id) throws RemoteException {
0698:                RenderableImage ri = (RenderableImage) nodes.get(id);
0699:                return ri.getMinY();
0700:            }
0701:
0702:            /**
0703:             * Gets the width (in user coordinate space) of the
0704:             * <code>RenderableImage</code> stored against the given ID.
0705:             *
0706:             * @return the width of the renderable image in user coordinates.
0707:             */
0708:            public float getRenderableWidth(Long id) throws RemoteException {
0709:                RenderableImage ri = (RenderableImage) nodes.get(id);
0710:                return ri.getWidth();
0711:            }
0712:
0713:            /**
0714:             * Gets the height (in user coordinate space) of the
0715:             * <code>RenderableImage</code> stored against the given ID.
0716:             *
0717:             * @return the height of the renderable image in user coordinates.
0718:             */
0719:            public float getRenderableHeight(Long id) throws RemoteException {
0720:                RenderableImage ri = (RenderableImage) nodes.get(id);
0721:                return ri.getHeight();
0722:            }
0723:
0724:            /**
0725:             * Creates a RenderedImage instance of this image with width w, and
0726:             * height h in pixels.  The RenderContext is built automatically
0727:             * with an appropriate usr2dev transform and an area of interest
0728:             * of the full image.  All the rendering hints come from hints
0729:             * passed in.
0730:             *
0731:             * <p> If w == 0, it will be taken to equal
0732:             * Math.round(h*(getWidth()/getHeight())).
0733:             * Similarly, if h == 0, it will be taken to equal
0734:             * Math.round(w*(getHeight()/getWidth())).  One of
0735:             * w or h must be non-zero or else an IllegalArgumentException
0736:             * will be thrown.
0737:             *
0738:             * <p> The created RenderedImage may have a property identified
0739:             * by the String HINTS_OBSERVED to indicate which RenderingHints
0740:             * were used to create the image.  In addition any RenderedImages
0741:             * that are obtained via the getSources() method on the created
0742:             * RenderedImage may have such a property.
0743:             *
0744:             * @param w the width of rendered image in pixels, or 0.
0745:             * @param h the height of rendered image in pixels, or 0.
0746:             * @param hints a RenderingHints object containg hints.
0747:             * @return a RenderedImage containing the rendered data.
0748:             */
0749:            public RenderedImage createScaledRendering(Long id, int w, int h,
0750:                    SerializableState hintsState) throws RemoteException {
0751:
0752:                RenderableImage ri = (RenderableImage) nodes.get(id);
0753:                RenderingHints hints = (RenderingHints) hintsState.getObject();
0754:                RenderedImage rendering = ri.createScaledRendering(w, h, hints);
0755:                if (rendering instanceof  Serializable) {
0756:                    return rendering;
0757:                } else {
0758:                    return new SerializableRenderedImage(rendering);
0759:                }
0760:            }
0761:
0762:            /**
0763:             * Returnd a RenderedImage instance of this image with a default
0764:             * width and height in pixels.  The RenderContext is built
0765:             * automatically with an appropriate usr2dev transform and an area
0766:             * of interest of the full image.  The rendering hints are
0767:             * empty.  createDefaultRendering may make use of a stored
0768:             * rendering for speed.
0769:             *
0770:             * @return a RenderedImage containing the rendered data.
0771:             */
0772:            public RenderedImage createDefaultRendering(Long id)
0773:                    throws RemoteException {
0774:
0775:                RenderableImage ri = (RenderableImage) nodes.get(id);
0776:                RenderedImage rendering = ri.createDefaultRendering();
0777:                if (rendering instanceof  Serializable) {
0778:                    return rendering;
0779:                } else {
0780:                    return new SerializableRenderedImage(rendering);
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Creates a RenderedImage that represented a rendering of this image
0786:             * using a given RenderContext.  This is the most general way to obtain a
0787:             * rendering of a RenderableImage.
0788:             *
0789:             * <p> The created RenderedImage may have a property identified
0790:             * by the String HINTS_OBSERVED to indicate which RenderingHints
0791:             * (from the RenderContext) were used to create the image.
0792:             * In addition any RenderedImages
0793:             * that are obtained via the getSources() method on the created
0794:             * RenderedImage may have such a property.
0795:             *
0796:             * @param renderContext the RenderContext to use to produce the rendering.
0797:             * @return a RenderedImage containing the rendered data.
0798:             */
0799:            public RenderedImage createRendering(Long id,
0800:                    SerializableState renderContextState)
0801:                    throws RemoteException {
0802:
0803:                RenderableImage ri = (RenderableImage) nodes.get(id);
0804:                RenderContext renderContext = (RenderContext) renderContextState
0805:                        .getObject();
0806:                RenderedImage rendering = ri.createRendering(renderContext);
0807:                if (rendering instanceof  Serializable) {
0808:                    return rendering;
0809:                } else {
0810:                    return new SerializableRenderedImage(rendering);
0811:                }
0812:            }
0813:
0814:            /**
0815:             * Creates a RenderableOp on the server side with a parameter block
0816:             * empty of sources. The sources are set by separate calls depending
0817:             * upon the type and serializabilty of the source.
0818:             */
0819:            public synchronized void createRenderableOp(Long id, String opName,
0820:                    ParameterBlock pb) throws RemoteException {
0821:
0822:                // XXX Since RMIServerProxy does not do a checkClientParameters, this
0823:                // side obviously does not do the corresponding
0824:                // checkServerParameters. Look at RMIServerProxy's renderable
0825:                // constructor for reasoning. aastha, 09/26/01
0826:
0827:                RenderableOp node = new RenderableOp(opName, pb);
0828:                nodes.put(id, node);
0829:            }
0830:
0831:            /**
0832:             * Calls for rendering of a RenderableOp with the given SerializableState
0833:             */
0834:            public synchronized Long getRendering(Long id, SerializableState rcs)
0835:                    throws RemoteException {
0836:
0837:                RenderableOp op = (RenderableOp) nodes.get(id);
0838:                PlanarImage pi = PlanarImage.wrapRenderedImage(op
0839:                        .createRendering((RenderContext) rcs.getObject()));
0840:
0841:                Long renderingID = getRemoteID();
0842:                nodes.put(renderingID, pi);
0843:
0844:                // Put the op's negotiated result values for its rendering too.
0845:                setServerNegotiatedValues(renderingID,
0846:                        (NegotiableCapabilitySet) negotiated.get(id));
0847:                return renderingID;
0848:            }
0849:
0850:            /**
0851:             * Sets the source of the image which is on the same
0852:             * server
0853:             */
0854:            public synchronized void setRenderableSource(Long id,
0855:                    Long sourceId, int index) throws RemoteException {
0856:
0857:                RenderableOp node = (RenderableOp) nodes.get(id);
0858:                Object obj = nodes.get(sourceId);
0859:                if (obj instanceof  RenderableOp) {
0860:                    node.setSource((RenderableOp) obj, index);
0861:                } else if (obj instanceof  RenderedImage) {
0862:                    node.setSource(PlanarImage
0863:                            .wrapRenderedImage((RenderedImage) obj), index);
0864:                }
0865:            }
0866:
0867:            /**
0868:             * Sets the source of the image which is on a different
0869:             * server
0870:             */
0871:            public synchronized void setRenderableSource(Long id,
0872:                    Long sourceId, String serverName, String opName, int index)
0873:                    throws RemoteException {
0874:
0875:                RenderableOp node = (RenderableOp) nodes.get(id);
0876:                node.setSource(new RMIServerProxy(
0877:                        (serverName + "::" + sourceId), opName, null), index);
0878:
0879:            }
0880:
0881:            /**
0882:             * Sets the source of the image which is on a different
0883:             * server
0884:             */
0885:            public synchronized void setRenderableRMIServerProxyAsSource(
0886:                    Long id, Long sourceId, String serverName, String opName,
0887:                    int index) throws RemoteException {
0888:
0889:                RenderableOp node = (RenderableOp) nodes.get(id);
0890:                node.setSource(new RenderableRMIServerProxy(serverName, opName,
0891:                        null, sourceId), index);
0892:            }
0893:
0894:            /**
0895:             * when source is set to a  RenderableOp and isnt supposed to be
0896:             * rendered yet. like at the time of getBounds2D
0897:             *
0898:             * Sets the source of the image as a RenderableOp on the server side
0899:             *
0900:             */
0901:            public synchronized void setRenderableSource(Long id,
0902:                    RenderableOp source, int index) throws RemoteException {
0903:                RenderableOp op = (RenderableOp) nodes.get(id);
0904:                op.setSource(source, index);
0905:            }
0906:
0907:            /**
0908:             * Sets the source of the image as a RenderableImage on the server side
0909:             */
0910:            public synchronized void setRenderableSource(Long id,
0911:                    SerializableRenderableImage s, int index)
0912:                    throws RemoteException {
0913:                RenderableOp op = (RenderableOp) nodes.get(id);
0914:                op.setSource(s, index);
0915:            }
0916:
0917:            /**
0918:             *  Sets the source of the image as a RenderedImage on the server side
0919:             */
0920:            public synchronized void setRenderableSource(Long id,
0921:                    RenderedImage source, int index) throws RemoteException {
0922:
0923:                PlanarImage pi = PlanarImage.wrapRenderedImage(source);
0924:                RenderableOp op = (RenderableOp) nodes.get(id);
0925:                op.setSource(pi, index);
0926:            }
0927:
0928:            /**
0929:             * Maps the RenderContext for the remote Image
0930:             */
0931:            public SerializableState mapRenderContext(int id, Long nodeId,
0932:                    String operationName, SerializableState rcs)
0933:                    throws RemoteException {
0934:
0935:                // Retrieve the RenderableOp for the rendering of which
0936:                // the mapRenderContext call is being made.
0937:                RenderableOp rop = (RenderableOp) nodes.get(nodeId);
0938:
0939:                //Find the CRIF for the respective operation
0940:                ContextualRenderedImageFactory crif = CRIFRegistry.get(rop
0941:                        .getRegistry(), operationName);
0942:
0943:                if (crif == null) {
0944:                    throw new RuntimeException(JaiI18N
0945:                            .getString("JAIRMIImageServer3"));
0946:                }
0947:
0948:                RenderContext rc = crif.mapRenderContext(id,
0949:                        (RenderContext) rcs.getObject(), (ParameterBlock) rop
0950:                                .getParameterBlock(), rop);
0951:                return SerializerFactory.getState(rc, null);
0952:            }
0953:
0954:            /**
0955:             * Gets the Bounds2D of the specified Remote Image
0956:             */
0957:            public SerializableState getBounds2D(Long nodeId,
0958:                    String operationName) throws RemoteException {
0959:
0960:                // Retrieve the RenderableOp for whose RIF
0961:                // the mapRenderContext call is being made.
0962:                RenderableOp rop = (RenderableOp) nodes.get(nodeId);
0963:
0964:                //Find the CRIF for the respective operation
0965:                ContextualRenderedImageFactory crif = CRIFRegistry.get(rop
0966:                        .getRegistry(), operationName);
0967:
0968:                if (crif == null) {
0969:                    throw new RuntimeException(JaiI18N
0970:                            .getString("JAIRMIImageServer3"));
0971:                }
0972:
0973:                Rectangle2D r2D = crif.getBounds2D((ParameterBlock) rop
0974:                        .getParameterBlock());
0975:
0976:                return SerializerFactory.getState(r2D, null);
0977:            }
0978:
0979:            /**
0980:             * Returns <code>true</code> if successive renderings with the same
0981:             * arguments may produce different results for this opName
0982:             *
0983:             * @return <code>false</code> indicating that the rendering is static.
0984:             */
0985:            public boolean isDynamic(String opName) throws RemoteException {
0986:
0987:                return (CRIFRegistry.get(null, opName)).isDynamic();
0988:            }
0989:
0990:            /**
0991:             * Returns <code>true</code> if successive renderings with the same
0992:             * arguments may produce different results for the node represented
0993:             * by the given id.
0994:             */
0995:            public boolean isDynamic(Long id) throws RemoteException {
0996:
0997:                RenderableImage node = (RenderableImage) nodes.get(id);
0998:                return node.isDynamic();
0999:            }
1000:
1001:            /**
1002:             * Gets the operation names supported on the Server
1003:             */
1004:            public String[] getServerSupportedOperationNames()
1005:                    throws RemoteException {
1006:                return JAI.getDefaultInstance().getOperationRegistry()
1007:                        .getDescriptorNames(OperationDescriptor.class);
1008:            }
1009:
1010:            /**
1011:             * Gets the <code>OperationDescriptor</code>s of the operations
1012:             * supported on this server.
1013:             */
1014:            public List getOperationDescriptors() throws RemoteException {
1015:                return JAI.getDefaultInstance().getOperationRegistry()
1016:                        .getDescriptors(OperationDescriptor.class);
1017:            }
1018:
1019:            /**
1020:             * Calculates the region over which two distinct renderings
1021:             * of an operation may be expected to differ.
1022:             *
1023:             * <p> The class of the returned object will vary as a function of
1024:             * the nature of the operation.  For rendered and renderable two-
1025:             * dimensional images this should be an instance of a class which
1026:             * implements <code>java.awt.Shape</code>.
1027:             *
1028:             * @return The region over which the data of two renderings of this
1029:             *         operation may be expected to be invalid or <code>null</code>
1030:             *         if there is no common region of validity.
1031:             */
1032:            public synchronized SerializableState getInvalidRegion(Long id,
1033:                    ParameterBlock oldParamBlock, SerializableState oldRHints,
1034:                    ParameterBlock newParamBlock, SerializableState newRHints)
1035:                    throws RemoteException {
1036:
1037:                RenderingHints oldHints = (RenderingHints) oldRHints
1038:                        .getObject();
1039:                RenderingHints newHints = (RenderingHints) newRHints
1040:                        .getObject();
1041:
1042:                RenderedOp op = (RenderedOp) nodes.get(id);
1043:
1044:                OperationDescriptor od = (OperationDescriptor) JAI
1045:                        .getDefaultInstance().getOperationRegistry()
1046:                        .getDescriptor("rendered", op.getOperationName());
1047:
1048:                boolean samePBs = false;
1049:                if (oldParamBlock == newParamBlock)
1050:                    samePBs = true;
1051:
1052:                Vector oldSources = oldParamBlock.getSources();
1053:                oldParamBlock.removeSources();
1054:                Vector oldReplacedSources = JAIRMIUtil.replaceIdWithSources(
1055:                        oldSources, nodes, op.getOperationName(), op
1056:                                .getRenderingHints());
1057:                oldParamBlock.setSources(oldReplacedSources);
1058:
1059:                if (samePBs) {
1060:                    newParamBlock = oldParamBlock;
1061:                } else {
1062:                    Vector newSources = newParamBlock.getSources();
1063:                    newParamBlock.removeSources();
1064:                    Vector newReplacedSources = JAIRMIUtil
1065:                            .replaceIdWithSources(newSources, nodes, op
1066:                                    .getOperationName(), op.getRenderingHints());
1067:
1068:                    newParamBlock.setSources(newReplacedSources);
1069:                }
1070:
1071:                Object invalidRegion = od.getInvalidRegion("rendered",
1072:                        oldParamBlock, oldHints, newParamBlock, newHints, op);
1073:
1074:                SerializableState shapeState = SerializerFactory.getState(
1075:                        (Shape) invalidRegion, null);
1076:
1077:                return shapeState;
1078:            }
1079:
1080:            /**
1081:             * Returns a conservative estimate of the destination region that
1082:             * can potentially be affected by the pixels of a rectangle of a
1083:             * given source.
1084:             *
1085:             * @param id          A <code>Long</code> identifying the node for whom
1086:             *                    the destination region needs to be calculated .
1087:             * @param sourceRect  The <code>Rectangle</code> in source coordinates.
1088:             * @param sourceIndex The index of the source image.
1089:             *
1090:             * @return A <code>Rectangle</code> indicating the potentially
1091:             *         affected destination region, or <code>null</code> if
1092:             *         the region is unknown.
1093:             */
1094:            public Rectangle mapSourceRect(Long id, Rectangle sourceRect,
1095:                    int sourceIndex) throws RemoteException {
1096:
1097:                RenderedOp op = (RenderedOp) nodes.get(id);
1098:                OpImage rendering = (OpImage) (op.getRendering());
1099:                return rendering.mapSourceRect(sourceRect, sourceIndex);
1100:            }
1101:
1102:            /**
1103:             * Returns a conservative estimate of the region of a specified
1104:             * source that is required in order to compute the pixels of a
1105:             * given destination rectangle.
1106:             *
1107:             * @param id         A <code>Long</code> identifying the node for whom
1108:             *                   the source region needs to be calculated .
1109:             * @param destRect   The <code>Rectangle</code> in destination coordinates.
1110:             * @param sourceIndex The index of the source image.
1111:             *
1112:             * @return A <code>Rectangle</code> indicating the required source region.
1113:             */
1114:            public Rectangle mapDestRect(Long id, Rectangle destRect,
1115:                    int sourceIndex) throws RemoteException {
1116:
1117:                RenderedOp op = (RenderedOp) nodes.get(id);
1118:                OpImage rendering = (OpImage) (op.getRendering());
1119:                return rendering.mapDestRect(destRect, sourceIndex);
1120:            }
1121:
1122:            /**
1123:             * A method that handles the given event.
1124:             */
1125:            public synchronized Long handleEvent(Long renderedOpID,
1126:                    String propName, Object oldValue, Object newValue)
1127:                    throws RemoteException {
1128:
1129:                RenderedOp op = (RenderedOp) nodes.get(renderedOpID);
1130:                PlanarImage rendering = op.getRendering();
1131:
1132:                // Get a new unique ID
1133:                Long id = getRemoteID();
1134:                // Cache the old rendering against the new id
1135:                nodes.put(id, rendering);
1136:
1137:                // Put the op's negotiated result values for its rendering too.
1138:                setServerNegotiatedValues(id,
1139:                        (NegotiableCapabilitySet) negotiated.get(renderedOpID));
1140:
1141:                // A PropertyChangeEventJAI with name "operationregistry",
1142:                // "protocolname", "protocolandservername" or "servername" should
1143:                // never be received here, since it is handled entirely on the
1144:                // client side, so we don't handle those here.
1145:
1146:                if (propName.equals("operationname")) {
1147:
1148:                    op.setOperationName((String) newValue);
1149:
1150:                } else if (propName.equals("parameterblock")) {
1151:
1152:                    ParameterBlock newPB = (ParameterBlock) newValue;
1153:                    Vector newSrcs = newPB.getSources();
1154:                    newPB.removeSources();
1155:
1156:                    JAIRMIUtil.checkServerParameters(newPB, nodes);
1157:
1158:                    Vector replacedSources = JAIRMIUtil.replaceIdWithSources(
1159:                            newSrcs, nodes, op.getOperationName(), op
1160:                                    .getRenderingHints());
1161:                    newPB.setSources(replacedSources);
1162:
1163:                    op.setParameterBlock(newPB);
1164:
1165:                    // Remove the newly created sinks of the srcs in the newPB
1166:                    Vector newSources = newPB.getSources();
1167:                    if (newSources != null && newSources.size() > 0) {
1168:                        Iterator it = newSources.iterator();
1169:                        while (it.hasNext()) {
1170:                            Object src = it.next();
1171:                            if (src instanceof  PlanarImage) {
1172:                                ((PlanarImage) src).removeSinks();
1173:                            } else if (src instanceof  CollectionImage) {
1174:                                ((CollectionImage) src).removeSinks();
1175:                            }
1176:                        }
1177:                    }
1178:
1179:                } else if (propName.equals("sources")) {
1180:
1181:                    Vector replacedSources = JAIRMIUtil.replaceIdWithSources(
1182:                            (Vector) newValue, nodes, op.getOperationName(), op
1183:                                    .getRenderingHints());
1184:                    op.setSources(replacedSources);
1185:
1186:                    // Remove the newly created sinks for the replacedSources
1187:                    if (replacedSources != null && replacedSources.size() > 0) {
1188:                        Iterator it = replacedSources.iterator();
1189:                        while (it.hasNext()) {
1190:                            Object src = it.next();
1191:                            if (src instanceof  PlanarImage) {
1192:                                ((PlanarImage) src).removeSinks();
1193:                            } else if (src instanceof  CollectionImage) {
1194:                                ((CollectionImage) src).removeSinks();
1195:                            }
1196:                        }
1197:                    }
1198:
1199:                } else if (propName.equals("parameters")) {
1200:
1201:                    Vector parameters = (Vector) newValue;
1202:                    JAIRMIUtil.checkServerParameters(parameters, nodes);
1203:                    op.setParameters(parameters);
1204:
1205:                } else if (propName.equals("renderinghints")) {
1206:
1207:                    SerializableState newState = (SerializableState) newValue;
1208:                    op.setRenderingHints((RenderingHints) newState.getObject());
1209:                }
1210:
1211:                return id;
1212:            }
1213:
1214:            /**
1215:             * A method that handles a change in one of it's source's rendering,
1216:             * i.e. a change that would be signalled by RenderingChangeEvent.
1217:             */
1218:            public synchronized Long handleEvent(Long renderedOpID,
1219:                    int srcIndex, SerializableState srcInvalidRegion,
1220:                    Object oldRendering) throws RemoteException {
1221:
1222:                RenderedOp op = (RenderedOp) nodes.get(renderedOpID);
1223:                PlanarImage rendering = op.getRendering();
1224:
1225:                // Get a new unique ID
1226:                Long id = getRemoteID();
1227:                // Cache the old rendering against the new id
1228:                nodes.put(id, rendering);
1229:
1230:                // Put the op's negotiated result values for its rendering too.
1231:                setServerNegotiatedValues(id,
1232:                        (NegotiableCapabilitySet) negotiated.get(renderedOpID));
1233:
1234:                PlanarImage oldSrcRendering = null, newSrcRendering = null;
1235:                String serverNodeDesc = null;
1236:                Object src = null;
1237:
1238:                if (oldRendering instanceof  String) {
1239:
1240:                    serverNodeDesc = (String) oldRendering;
1241:                    int index = serverNodeDesc.indexOf("::");
1242:                    boolean diffServer = index != -1;
1243:
1244:                    if (diffServer) {
1245:                        // Create an RMIServerProxy to access the node on a
1246:                        // different server
1247:                        oldSrcRendering = new RMIServerProxy(serverNodeDesc, op
1248:                                .getOperationName(), op.getRenderingHints());
1249:                    } else {
1250:
1251:                        src = nodes.get(Long.valueOf(serverNodeDesc));
1252:
1253:                        if (src instanceof  RenderedOp) {
1254:                            oldSrcRendering = ((RenderedOp) src).getRendering();
1255:                        } else {
1256:                            oldSrcRendering = PlanarImage
1257:                                    .wrapRenderedImage((RenderedImage) src);
1258:                        }
1259:                    }
1260:
1261:                } else {
1262:                    oldSrcRendering = PlanarImage
1263:                            .wrapRenderedImage((RenderedImage) oldRendering);
1264:                }
1265:
1266:                Object srcObj = op.getSource(srcIndex);
1267:                if (srcObj instanceof  RenderedOp) {
1268:                    newSrcRendering = ((RenderedOp) srcObj).getRendering();
1269:                } else if (srcObj instanceof  RenderedImage) {
1270:                    newSrcRendering = PlanarImage
1271:                            .wrapRenderedImage((RenderedImage) srcObj);
1272:                }
1273:
1274:                Shape invalidRegion = (Shape) srcInvalidRegion.getObject();
1275:
1276:                RenderingChangeEvent rcEvent = new RenderingChangeEvent(
1277:                        (RenderedOp) op.getSource(srcIndex), oldSrcRendering,
1278:                        newSrcRendering, invalidRegion);
1279:                op.propertyChange(rcEvent);
1280:
1281:                return id;
1282:            }
1283:
1284:            /**
1285:             * Returns the server's capabilities. Currently the only capabilities
1286:             * that are reported are those dealing with TileCodecs.
1287:             */
1288:            public synchronized NegotiableCapabilitySet getServerCapabilities() {
1289:
1290:                OperationRegistry registry = JAI.getDefaultInstance()
1291:                        .getOperationRegistry();
1292:
1293:                // Note that only the tileEncoder capabilities are returned from
1294:                // this method since there is no way to distinguish between NC's
1295:                // for the encoder and the decoder.
1296:                String modeName = "tileEncoder";
1297:                String[] descriptorNames = registry
1298:                        .getDescriptorNames(modeName);
1299:                TileEncoderFactory tef = null;
1300:
1301:                // Only non-preference NC's can be added.
1302:                NegotiableCapabilitySet capabilities = new NegotiableCapabilitySet(
1303:                        false);
1304:
1305:                Iterator it;
1306:                for (int i = 0; i < descriptorNames.length; i++) {
1307:
1308:                    it = registry.getFactoryIterator(modeName,
1309:                            descriptorNames[i]);
1310:                    for (; it.hasNext();) {
1311:                        tef = (TileEncoderFactory) it.next();
1312:                        capabilities.add(tef.getEncodeCapability());
1313:                    }
1314:                }
1315:
1316:                return capabilities;
1317:            }
1318:
1319:            /**
1320:             * Informs the server of the negotiated values that are the result of
1321:             * a successful negotiation.
1322:             *
1323:             * @param negotiatedValues    The result of the negotiation.
1324:             */
1325:            public void setServerNegotiatedValues(Long id,
1326:                    NegotiableCapabilitySet negotiatedValues)
1327:                    throws RemoteException {
1328:                if (negotiatedValues != null)
1329:                    negotiated.put(id, negotiatedValues);
1330:                else
1331:                    negotiated.remove(id);
1332:            }
1333:
1334:            /**
1335:             * Starts a server on a given port.  The RMI registry must be running
1336:             * on the server host.
1337:             *
1338:             * <p> The usage of this class is
1339:             *
1340:             * <pre>
1341:             * java -Djava.rmi.server.codebase=file:$JAI/lib/jai.jar \
1342:             * -Djava.rmi.server.useCodebaseOnly=false \
1343:             * -Djava.security.policy=\
1344:             * file:`pwd`/policy com.sun.media.jai.rmi.JAIRMIImageServer \
1345:             * [-host hostName] [-port portNumber]
1346:             * </pre>
1347:             *
1348:             * The default host is the local host and the default port is 1099.
1349:             *
1350:             * @param args the port number as a command-line argument.
1351:             */
1352:            public static void main(String[] args) {
1353:
1354:                // Set the security manager.
1355:                if (System.getSecurityManager() == null) {
1356:                    System.setSecurityManager(new RMISecurityManager());
1357:                }
1358:
1359:                // Load all JAIServerConfigurationSpi implementations on the CLASSPATH
1360:                Iterator spiIter = Service
1361:                        .providers(JAIServerConfigurationSpi.class);
1362:                JAI jai = JAI.getDefaultInstance();
1363:
1364:                while (spiIter.hasNext()) {
1365:
1366:                    JAIServerConfigurationSpi serverSpi = (JAIServerConfigurationSpi) spiIter
1367:                            .next();
1368:                    serverSpi.updateServer(jai);
1369:                }
1370:
1371:                // Set the host name and port number.
1372:                String host = null;
1373:                int rmiRegistryPort = 1099; // default port is 1099
1374:                int serverport = 0;
1375:
1376:                if (args.length != 0) {
1377:
1378:                    String value;
1379:
1380:                    for (int i = 0; i < args.length; i++) {
1381:
1382:                        if (args[i].equalsIgnoreCase("-help")) {
1383:
1384:                            System.out
1385:                                    .println("Usage: java -Djava.rmi.server.codebase=file:$JAI/lib/jai.jar \\");
1386:                            System.out
1387:                                    .println("-Djava.rmi.server.useCodebaseOnly=false \\");
1388:                            System.out
1389:                                    .println("-Djava.security.policy=file:`pwd`/policy \\");
1390:                            System.out
1391:                                    .println("com.sun.media.jai.rmi.JAIRMIImageServer \\");
1392:                            System.out.println("\nwhere options are:");
1393:                            System.out
1394:                                    .println("\t-host <string> The server name or server IP address");
1395:                            System.out
1396:                                    .println("\t-port <integer> The port that rmiregistry is running on");
1397:                            System.out
1398:                                    .println("\t-rmiRegistryPort <integer> Same as -port option");
1399:                            System.out
1400:                                    .println("\t-serverPort <integer> The port that the server should listen on, for connections from clients");
1401:                            System.out
1402:                                    .println("\t-cacheMemCapacity <long> The memory capacity in bytes.");
1403:                            System.out
1404:                                    .println("\t-cacheMemThreshold <float> The memory threshold, which is the fractional amount of cache memory to retain during tile removal");
1405:                            System.out
1406:                                    .println("\t-disableDefaultCache Disable use of default tile cache. Tiles are not stored.");
1407:                            System.out
1408:                                    .println("\t-schedulerParallelism <integer> The degree of parallelism of the default TileScheduler");
1409:                            System.out
1410:                                    .println("\t-schedulerPrefetchParallelism <integer> The degree of parallelism of the default TileScheduler for tile prefetching");
1411:                            System.out
1412:                                    .println("\t-schedulerPriority <integer> The priority of tile scheduling for the default TileScheduler");
1413:                            System.out
1414:                                    .println("\t-schedulerPrefetchPriority <integer> The priority of tile prefetch scheduling for the default TileScheduler");
1415:                            System.out
1416:                                    .println("\t-defaultTileSize <integer>x<integer> The default tile dimensions in the form <xSize>x<ySize>");
1417:                            System.out
1418:                                    .println("\t-defaultRenderingSize <integer>x<integer> The default size to render a RenderableImage to, in the form <xSize>x<ySize>");
1419:                            System.out
1420:                                    .println("\t-serializeDeepCopy <boolean> Whether a deep copy of the image data should be used when serializing images");
1421:                            System.out
1422:                                    .println("\t-tileCodecFormat <string> The default format to be used for tile serialization via TileCodecs");
1423:                            System.out
1424:                                    .println("\t-retryInterval <integer> The retry interval value to be used for dealing with network errors during remote imaging");
1425:                            System.out
1426:                                    .println("\t-numRetries <integer> The number of retries to be used for dealing with network errors during remote imaging");
1427:
1428:                        } else if (args[i].equalsIgnoreCase("-host")) {
1429:
1430:                            host = args[++i];
1431:
1432:                        } else if (args[i].equalsIgnoreCase("-port")
1433:                                || args[i].equalsIgnoreCase("-rmiRegistryPort")) {
1434:
1435:                            rmiRegistryPort = Integer.parseInt(args[++i]);
1436:
1437:                        } else if (args[i].equalsIgnoreCase("-serverport")) {
1438:
1439:                            serverport = Integer.parseInt(args[++i]);
1440:
1441:                        } else if (args[i]
1442:                                .equalsIgnoreCase("-cacheMemCapacity")) {
1443:
1444:                            jai.getTileCache().setMemoryCapacity(
1445:                                    Long.parseLong(args[++i]));
1446:
1447:                        } else if (args[i]
1448:                                .equalsIgnoreCase("-cacheMemThreshold")) {
1449:
1450:                            jai.getTileCache().setMemoryThreshold(
1451:                                    Float.parseFloat(args[++i]));
1452:
1453:                        } else if (args[i]
1454:                                .equalsIgnoreCase("-disableDefaultCache")) {
1455:
1456:                            jai.disableDefaultTileCache();
1457:
1458:                        } else if (args[i]
1459:                                .equalsIgnoreCase("-schedulerParallelism")) {
1460:
1461:                            jai.getTileScheduler().setParallelism(
1462:                                    Integer.parseInt(args[++i]));
1463:
1464:                        } else if (args[i]
1465:                                .equalsIgnoreCase("-schedulerPrefetchParallelism")) {
1466:
1467:                            jai.getTileScheduler().setPrefetchParallelism(
1468:                                    Integer.parseInt(args[++i]));
1469:
1470:                        } else if (args[i]
1471:                                .equalsIgnoreCase("-schedulerPriority")) {
1472:
1473:                            jai.getTileScheduler().setPriority(
1474:                                    Integer.parseInt(args[++i]));
1475:
1476:                        } else if (args[i]
1477:                                .equalsIgnoreCase("-schedulerPrefetchPriority")) {
1478:
1479:                            jai.getTileScheduler().setPrefetchPriority(
1480:                                    Integer.parseInt(args[++i]));
1481:
1482:                        } else if (args[i].equalsIgnoreCase("-defaultTileSize")) {
1483:
1484:                            value = args[++i].toLowerCase();
1485:                            int xpos = value.indexOf("x");
1486:                            int xSize = Integer.parseInt(value.substring(0,
1487:                                    xpos));
1488:                            int ySize = Integer.parseInt(value
1489:                                    .substring(xpos + 1));
1490:
1491:                            jai.setDefaultTileSize(new Dimension(xSize, ySize));
1492:
1493:                        } else if (args[i]
1494:                                .equalsIgnoreCase("-defaultRenderingSize")) {
1495:
1496:                            value = args[++i].toLowerCase();
1497:                            int xpos = value.indexOf("x");
1498:                            int xSize = Integer.parseInt(value.substring(0,
1499:                                    xpos));
1500:                            int ySize = Integer.parseInt(value
1501:                                    .substring(xpos + 1));
1502:
1503:                            jai.setDefaultRenderingSize(new Dimension(xSize,
1504:                                    ySize));
1505:
1506:                        } else if (args[i]
1507:                                .equalsIgnoreCase("-serializeDeepCopy")) {
1508:
1509:                            jai.setRenderingHint(JAI.KEY_SERIALIZE_DEEP_COPY,
1510:                                    Boolean.valueOf(args[++i]));
1511:
1512:                        } else if (args[i].equalsIgnoreCase("-tileCodecFormat")) {
1513:
1514:                            jai.setRenderingHint(JAI.KEY_TILE_CODEC_FORMAT,
1515:                                    args[++i]);
1516:
1517:                        } else if (args[i].equalsIgnoreCase("-retryInterval")) {
1518:
1519:                            jai.setRenderingHint(JAI.KEY_RETRY_INTERVAL,
1520:                                    Integer.valueOf(args[++i]));
1521:
1522:                        } else if (args[i].equalsIgnoreCase("-numRetries")) {
1523:
1524:                            jai.setRenderingHint(JAI.KEY_NUM_RETRIES, Integer
1525:                                    .valueOf(args[++i]));
1526:                        }
1527:                    }
1528:                }
1529:
1530:                // Default to the local host if the host was not specified.
1531:                if (host == null) {
1532:                    try {
1533:                        host = InetAddress.getLocalHost().getHostAddress();
1534:                    } catch (java.net.UnknownHostException e) {
1535:                        String message = JaiI18N.getString("RMIImageImpl1");
1536:                        sendExceptionToListener(message,
1537:                                new RemoteImagingException(message, e));
1538:                        /*
1539:                         System.err.println(JaiI18N.getString("RMIImageImpl1") +
1540:                         e.getMessage());
1541:                         e.printStackTrace();
1542:                         */
1543:                    }
1544:                }
1545:
1546:                System.out.println(JaiI18N.getString("RMIImageImpl3") + " "
1547:                        + host + ":" + rmiRegistryPort);
1548:
1549:                try {
1550:                    JAIRMIImageServer im = new JAIRMIImageServer(serverport);
1551:                    String serverName = new String("rmi://" + host + ":"
1552:                            + rmiRegistryPort + "/"
1553:                            + JAIRMIDescriptor.IMAGE_SERVER_BIND_NAME);
1554:                    System.out.println(JaiI18N.getString("RMIImageImpl4")
1555:                            + " \"" + serverName + "\".");
1556:                    Naming.rebind(serverName, im);
1557:                    System.out.println(JaiI18N.getString("RMIImageImpl5"));
1558:                } catch (Exception e) {
1559:                    String message = JaiI18N.getString("RMIImageImpl1");
1560:                    sendExceptionToListener(message,
1561:                            new RemoteImagingException(message, e));
1562:                    /*
1563:                     System.err.println(JaiI18N.getString("RMIImageImpl0") +
1564:                     e.getMessage());
1565:                     e.printStackTrace();
1566:                     */
1567:                }
1568:            }
1569:
1570:            private static void sendExceptionToListener(String message,
1571:                    Exception e) {
1572:                ImagingListener listener = ImageUtil
1573:                        .getImagingListener((RenderingHints) null);
1574:                listener.errorOccurred(message, new RemoteImagingException(
1575:                        message, e), JAIRMIImageServer.class, false);
1576:            }
1577:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.