001: /*
002: * $RCSfile: InterfaceState.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:56:51 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.rmi;
013:
014: import java.awt.RenderingHints;
015: import java.io.IOException;
016: import java.io.ObjectInputStream;
017: import java.io.ObjectOutputStream;
018: import java.lang.reflect.Proxy;
019: import java.lang.reflect.InvocationHandler;
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.util.Hashtable;
023: import javax.media.jai.JAI;
024: import javax.media.jai.remote.SerializableState;
025: import javax.media.jai.remote.Serializer;
026: import javax.media.jai.remote.SerializerFactory;
027:
028: /**
029: * Class enabling serialization of an object which implements multiple
030: * interfacs supported by SerializerFactory.
031: *
032: * @since 1.1
033: */
034: public class InterfaceState implements SerializableState {
035: // The object before serialization, the Proxy afterwards.
036: private transient Object theObject;
037: private transient Serializer[] theSerializers; // Not deserialized.
038: private transient RenderingHints hints; // Not deserialized.
039:
040: public InterfaceState(Object o, Serializer[] serializers,
041: RenderingHints h) {
042: if (o == null || serializers == null) {
043: throw new IllegalArgumentException(JaiI18N
044: .getString("Generic0"));
045: }
046: theObject = o;
047: theSerializers = serializers;
048: hints = h == null ? null : (RenderingHints) h.clone();
049: }
050:
051: public Object getObject() {
052: return theObject;
053: }
054:
055: public Class getObjectClass() {
056: return theObject.getClass();
057: }
058:
059: /**
060: * Serialize the <code>InterfaceState</code>.
061: *
062: * @param out The <code>ObjectOutputStream</code>.
063: */
064: private void writeObject(ObjectOutputStream out) throws IOException {
065:
066: int numSerializers = theSerializers.length;
067: out.writeInt(numSerializers);
068: for (int i = 0; i < numSerializers; i++) {
069: Serializer s = theSerializers[i];
070: out.writeObject(s.getSupportedClass());
071: out.writeObject(s.getState(theObject, hints));
072: }
073: }
074:
075: /**
076: * Deserialize the <code>InterfaceState</code>.
077: *
078: * @param out The <code>ObjectInputStream</code>.
079: */
080: private void readObject(ObjectInputStream in) throws IOException,
081: ClassNotFoundException {
082:
083: int numInterfaces = in.readInt();
084: Class[] interfaces = new Class[numInterfaces];
085: SerializableState[] implementations = new SerializableState[numInterfaces];
086: for (int i = 0; i < numInterfaces; i++) {
087: interfaces[i] = (Class) in.readObject();
088: implementations[i] = (SerializableState) in.readObject();
089: }
090:
091: InvocationHandler handler = new InterfaceHandler(interfaces,
092: implementations);
093:
094: theObject = Proxy.newProxyInstance(JAI.class.getClassLoader(),
095: interfaces, handler);
096: }
097: }
098:
099: class InterfaceHandler implements InvocationHandler {
100: private Hashtable interfaceMap;
101:
102: public InterfaceHandler(Class[] interfaces,
103: SerializableState[] implementations) {
104: if (interfaces == null || implementations == null) {
105: throw new IllegalArgumentException(JaiI18N
106: .getString("Generic0"));
107: } else if (interfaces.length != implementations.length) {
108: throw new IllegalArgumentException(JaiI18N
109: .getString("InterfaceHandler0"));
110: }
111:
112: int numInterfaces = interfaces.length;
113: interfaceMap = new Hashtable(numInterfaces);
114: for (int i = 0; i < numInterfaces; i++) {
115: Class iface = interfaces[i];
116: SerializableState state = implementations[i];
117:
118: if (!iface.isAssignableFrom(state.getObjectClass())) {
119: throw new RuntimeException(JaiI18N
120: .getString("InterfaceHandler1"));
121: }
122:
123: Object impl = state.getObject();
124: interfaceMap.put(iface, impl);
125: }
126: }
127:
128: public Object invoke(Object proxy, Method method, Object[] args)
129: throws IllegalAccessException, InvocationTargetException {
130: Class key = method.getDeclaringClass();
131: if (!interfaceMap.containsKey(key)) {
132: Class[] classes = (Class[]) interfaceMap.keySet().toArray(
133: new Class[0]);
134: for (int i = 0; i < classes.length; i++) {
135: Class aClass = classes[i];
136: if (key.isAssignableFrom(aClass)) {
137: interfaceMap.put(key, interfaceMap.get(aClass));
138: break;
139: }
140: }
141: if (!interfaceMap.containsKey(key)) {
142: throw new RuntimeException(key.getName()
143: + JaiI18N.getString("InterfaceHandler2"));
144: }
145: }
146:
147: Object result = null;
148: try {
149: Object impl = interfaceMap.get(key);
150: result = method.invoke(impl, args);
151: } catch (IllegalAccessException e) {
152: throw new RuntimeException(method.getName()
153: + JaiI18N.getString("InterfaceHandler3"));
154: }
155:
156: return result;
157: }
158: }
|