Source code: marauroa/net/MessageFactory.java
1 /* $Id: MessageFactory.java,v 1.5 2003/12/08 15:38:54 arianne_rpg Exp $ */
2 /***************************************************************************
3 * (C) Copyright 2003 - Marauroa *
4 ***************************************************************************
5 ***************************************************************************
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 ***************************************************************************/
13 package marauroa.net;
14
15 import java.net.InetSocketAddress;
16 import java.io.*;
17 import java.util.*;
18
19 import marauroa.marauroad;
20
21 /** MessageFactory is the class that is in charge of building the messages from
22 * the stream of bytes.
23 */
24 public class MessageFactory
25 {
26 private static Map factoryArray;
27 private static MessageFactory messageFactory;
28
29 private MessageFactory()
30 {
31 factoryArray= new HashMap();
32 register();
33 }
34
35 /** This method returns an instance of MessageFactory
36 * @return A shared instance of MessageFactory */
37 public static MessageFactory getFactory()
38 {
39 if(messageFactory==null)
40 {
41 messageFactory=new MessageFactory();
42 }
43
44 return messageFactory;
45 }
46
47 private void register()
48 {
49 marauroad.trace("MessageFactory::register",">");
50 register(Message.TYPE_C2S_ACTION,MessageC2SAction.class);
51 register(Message.TYPE_C2S_CHOOSECHARACTER,MessageC2SChooseCharacter.class);
52 register(Message.TYPE_C2S_LOGIN,MessageC2SLogin.class);
53 register(Message.TYPE_C2S_LOGOUT,MessageC2SLogout.class);
54 register(Message.TYPE_S2C_ACTION_ACK,MessageS2CActionACK.class);
55 register(Message.TYPE_S2C_CHARACTERLIST,MessageS2CCharacterList.class);
56 register(Message.TYPE_S2C_CHOOSECHARACTER_ACK,MessageS2CChooseCharacterACK.class);
57 register(Message.TYPE_S2C_CHOOSECHARACTER_NACK,MessageS2CChooseCharacterNACK.class);
58 register(Message.TYPE_S2C_LOGIN_ACK,MessageS2CLoginACK.class);
59 register(Message.TYPE_S2C_LOGIN_NACK,MessageS2CLoginNACK.class);
60 register(Message.TYPE_S2C_LOGOUT_ACK,MessageS2CLogoutACK.class);
61 register(Message.TYPE_S2C_LOGOUT_NACK,MessageS2CLogoutNACK.class);
62 register(Message.TYPE_S2C_PERCEPTION,MessageS2CPerception.class);
63 register(Message.TYPE_C2S_PERCEPTION_ACK,MessageC2SPerceptionACK.class);
64 register(Message.TYPE_S2C_SERVERINFO,MessageS2CServerInfo.class);
65 marauroad.trace("MessageFactory::register","<");
66 }
67
68 private void register(int index,Class messageClass)
69 {
70 factoryArray.put(new Integer(index),messageClass);
71 }
72
73 /** Returns a object of the right class from a stream of serialized data.
74 @param data the serialized data
75 @param source the source of the message needed to build the object.
76
77 @throws IOException in case of problems with the message */
78 public Message getMessage(byte[] data, InetSocketAddress source) throws IOException
79 {
80 marauroad.trace("MessageFactory::getMessage",">");
81 try
82 {
83 if(data[0]==NetConst.NETWORK_PROTOCOL_VERSION)
84 {
85 if(factoryArray.containsKey(new Integer(data[1])))
86 {
87 Class messageType=(Class) factoryArray.get(new Integer(data[1]));
88 Message tmp=(Message) messageType.newInstance();
89
90 ByteArrayInputStream in=new ByteArrayInputStream(data);
91 InputSerializer s=new InputSerializer(in);
92
93 tmp.readObject(s);
94 tmp.setAddress(source);
95
96 marauroad.trace("MessageFactory::getMessage","<");
97 return tmp;
98 }
99 else
100 {
101 marauroad.trace("MessageFactory::getMessage","X","Message type ["+data[1]+"] is not registered in the MessageFactory");
102 throw new IOException("Message type ["+data[1]+"] is not registered in the MessageFactory");
103 }
104 }
105 else
106 {
107 marauroad.trace("MessageFactory::getMessage","X","Message has incorrect protocol version");
108 throw new IOException("Message has incorrect protocol version: "+data[0]+" ( expected "+NetConst.NETWORK_PROTOCOL_VERSION+")");
109 }
110 }
111 catch(Exception e)
112 {
113 marauroad.trace("MessageFactory::getMessage","X",e.getMessage());
114 throw new IOException(e.getMessage());
115 }
116 finally
117 {
118 marauroad.trace("MessageFactory::getMessage","<");
119 }
120 }
121 };