1 4 package com.tc.net.protocol.tcm; 5 6 import org.apache.commons.lang.ArrayUtils; 7 8 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; 9 10 import com.tc.bytes.TCByteBuffer; 11 import com.tc.io.TCByteBufferOutput; 12 import com.tc.io.TCByteBufferOutputStream; 13 import com.tc.object.session.SessionID; 14 import com.tc.object.session.SessionProvider; 15 16 import java.lang.reflect.Constructor ; 17 import java.util.Map ; 18 19 public class TCMessageFactoryImpl implements TCMessageFactory { 20 private static final Class [] SIG1 = new Class [] { MessageMonitor.class, TCByteBufferOutput.class, 21 MessageChannel.class, TCMessageType.class }; 22 private static final Class [] SIG2 = new Class [] { SessionID.class, MessageMonitor.class, 23 MessageChannel.class, TCMessageHeader.class, TCByteBuffer[].class }; 24 private static final TCMessageFinalizer NULL_FINALIZER = new NullFinalizer(); 25 26 private final Map typeOnlyCstr = new ConcurrentReaderHashMap(); 27 private final Map typeAndDataCstr = new ConcurrentReaderHashMap(); 28 private final TCMessageFinalizer finalizer; 29 private final MessageMonitor monitor; 30 private final SessionProvider sessionProvider; 31 32 public TCMessageFactoryImpl(SessionProvider sessionProvider, MessageMonitor monitor) { 33 this(sessionProvider, monitor, NULL_FINALIZER); 34 } 35 36 public TCMessageFactoryImpl(SessionProvider sessionProvider, MessageMonitor monitor, TCMessageFinalizer finalizer) { 37 this.sessionProvider = sessionProvider; 38 this.monitor = monitor; 39 this.finalizer = finalizer; 40 } 41 42 public TCMessage createMessage(MessageChannel source, TCMessageType type) throws UnsupportedMessageTypeException { 43 return createMessage(lookupConstructor(type, typeOnlyCstr), new Object [] { monitor, 44 new TCByteBufferOutputStream(4, 4096, false), source, type }); 45 } 46 47 public TCMessage createMessage(MessageChannel source, TCMessageType type, TCMessageHeader header, TCByteBuffer[] data) { 48 return createMessage(lookupConstructor(type, typeAndDataCstr), new Object [] { sessionProvider.getSessionID(), monitor, source, header, data }); 49 } 50 51 public void addClassMapping(TCMessageType type, Class msgClass) { 52 if ((type == null) || (msgClass == null)) { throw new IllegalArgumentException (); } 53 54 Constructor cstr1 = getConstructor(msgClass, SIG1); 55 Constructor cstr2 = getConstructor(msgClass, SIG2); 56 57 synchronized (this) { 58 typeOnlyCstr.put(type, cstr1); 59 typeAndDataCstr.put(type, cstr2); 60 } 61 } 62 63 private static Constructor lookupConstructor(TCMessageType type, Map map) { 64 Constructor rv = (Constructor ) map.get(type); 65 if (rv == null) { throw new RuntimeException ("No class registerted for type " + type); } 66 return rv; 67 } 68 69 private static Constructor getConstructor(Class msgClass, Class [] signature) { 70 try { 71 return msgClass.getDeclaredConstructor(signature); 72 } catch (Exception e) { 73 throw new IllegalArgumentException (e.getClass().getName() + ": " + e.getMessage()); 74 } 75 } 76 77 private TCMessage createMessage(Constructor cstr, Object [] args) { 78 try { 79 TCMessage rv = (TCMessage) cstr.newInstance(args); 80 finalizer.finalizeMessage(rv); 81 return rv; 82 } catch (Exception e) { 83 System.err.println("Args; " + ArrayUtils.toString(args)); 84 throw new RuntimeException (e); 85 } 86 } 87 88 private static final class NullFinalizer implements TCMessageFinalizer { 89 public final void finalizeMessage(TCMessage message) { 90 return; 91 } 92 } 93 94 } 95 | Popular Tags |