Você está na página 1de 8

technical stream � j2ee

code logic & problem statement:

a service is required to support receiving, parsing and saving message data into
database.
the message data needs to be associated with the user (sender) and datetimestamp
at which
data is received. the service should also be able to support retrieval of message
data
based on the user name (sender) and datetimestamp range as input.

following are the message structure and associated processing rules.

1. message data is made up of series of bytes


2. start element (0x4): denotes start of the message
3. end element (0x2): denotes end of the message
4. start and end element encloses the message which can contain any number of
bytes.
5. the last byte of the data will provide lcr value.
lcr value evaluates to xor (^) of bytes of message and end element (0x2).
it does not include start element of the data

for example,

start element message end element lcr


0x4 0x32 0x31 0x28 0x2 0x32^0x31^0x28^0x2
6. the service should store start element and the message from the data.
(exclude end element)
7. if start element or end element be part of message then it should be pre-
tagged with a 0x10. (refer example below)
8. if the 0x10 is part of message, the 0x10 element should be repeated twice.

for example,

start element message end element lcr


0x4 0x10 0x4 0x32 0x10 0x10 0x31 0x2 0x32^0x10^0x31^0x2

9. in cases receiving multiple messages as part of same data, the last message
should be considered.

0x4 0x3 0x2 0x3^0x2 0x4 0x31 0x2 0x31^0x2

in the above example, 0x31 is valid message and 0x3 is invalid.

10. in case message stream, not exactly matching the message rules mentioned
above,
only the relevant information (as per the message rules defined above)
should be
processed as per the rules defined earlier.

for example,
0x4 0x3 0x21 0x4 0x31 0x2 0x31^0x2 0x2

the element greyed out in the above table is the valid data and the valid message
is 0x31.

in the above example following values will be stored


0x4 0x31

please find the code below with the line #s on the left hand side.

respondents need to write the line #�s and the details of the bugs in the
respective spaces provided in the response form in knet.

1 /*
2 * class basedao (this will be extended by all other dao
3 */
4
5 package com.wipro.knet.codetest.util;
6
7
8 import com.wipro.knet.codetest.dao.*;
9 import com.wipro.knet.codetest.util.messageexception;
10 import java.sql.connection;
11 import java.sql.sqlexception;
12 import java.util.logging.level;
13 import java.util.logging.logger;
14 import javax.sql.datasource;
15 import javax.naming.initialcontext;
16 import javax.naming.namingexception;
17
18 //oracle driver import
19
20
#'s 21 public final class basedao {//this should not be final
22
23 private static string datasourcenamestr="datasourcename";
24 private static logger
logger=logger.getlogger(basedao.class.getname());
25
26
27 protected final connection getconnection() throws messageexception{
28
29 initialcontext ctx = null;
30
31 try{
32 ctx = new initialcontext();
33 return
((datasource)ctx.lookup(system.getproperty(datasourcenamestr)
34 )).getconnection();
35 }catch(sqlexception sqlexp){
36 logger.log(level.severe,"failed to obtain db
connection"+sqlexp.getmessage());
37 throw new messageexception(sqlexp);
38 }catch(namingexception namingexp){
39 logger.log(level.severe,"failed to obtain data
source"+namingexp.getmessage());
40 throw new messageexception(namingexp);
41 }
42 }
43
44 }
45
46 // end of class basedao
47
48 /*
49 * class messagedao
50 */
51
52 package com.wipro.knet.codetest.dao;
#`s 53 //this should import the basedao class
54 import com.wipro.knet.codetest.util.messageexception;
55 import java.sql.statement;
56 import java.sql.connection;
57 import java.sql.preparedstatement;
58 import java.sql.resultset;
59 import java.sql.sqlexception;
60 import java.text.simpledateformat;
61 import java.util.calendar;
62 import java.util.logging.level;
63 import java.util.logging.logger;
64
65 /**
66 *
67 * @author
68 */
69 public class messagedao extends basedao {
70
71 private static logger
logger=logger.getlogger(messagedao.class.getname());
72 private connection conn=null;
73
74 public messagedao(){
75 }
76
77
78 // saveing message in db
79 public void savemessage(byte [] message,string username) throws
messageexception{
80
81 preparedstatement ps=null;
82 try{
83 conn = this.getconnection();
84 ps=conn.preparestatement("insert into tbl_messages values
(?,?,sysdate)");
85 for(int i=0; i<message.length; i++){
86 ps.setstring(1, username);
87 ps.setbyte(2, message[i]);
88
89 }
90 ps.execute();
91 }catch(sqlexception sqlexp){
92 logger.log(level.severe,sqlexp.getmessage());
93 throw new messageexception(sqlexp);
94 }finally{
95 if(ps != null){
96 try{
97 ps.close();
98 }catch(sqlexception sqlexp){
99 logger.log(level.warning,sqlexp.getmessage());
100 }
101 }
102 if(conn != null ){
103 try{
104 if(conn.isclosed()) conn.close();
105 }catch(sqlexception sqlexp){
106 logger.log(level.warning,sqlexp.getmessage());
107 }
108 }
109 }
110 }
111
112
113 //retrieving latest message from database for give user
114 public byte[] getmessage(calendar startdate, calendar enddate,
115 string username) throws messageexception {
116 byte [] message=null;
117 statement stmt=null;
118 resultset rs=null;
119 int i=0;
120 //message from the give user between two dates
121 string sql="select message from tbl_messages where
user_name='"+username
122 +"' and created_dt>='"+getsqldate(startdate) +"'"
123 +"' and created_dt < '"+getsqldate(enddate)+"'";
124 try{
125 stmt=(this.getconnection()).createstatement();
126 rs=stmt.executequery(sql);
127
128 //calculating total number of records
129 //pls assume that moving back and forth in result set is
supported
130 //by the database driver
131
132 if(rs.next()){ //atleast one record is there
133 rs.last();
134 message= new byte[rs.getrow()];
135 }
136 rs.beforefirst();
137
138
139 while(rs.next()){
140 message[i]=rs.getbyte(1);
141 i++;
142 }
143
144 }catch(sqlexception sqlexp){
145 logger.log(level.severe,sqlexp.getmessage());
146 throw new messageexception(sqlexp);
147 }finally{
148 if( stmt != null){
149 try{
150 stmt.close();
151 }catch(sqlexception sqlexp){
152 logger.log(level.warning,sqlexp.getmessage());
153 }
154 }
155 if(conn != null ){
156 try{
157 if(conn.isclosed()) conn.close();
158 }catch(sqlexception sqlexp){
159 logger.log(level.warning,sqlexp.getmessage());
160 }
161 }
162 }
163 return message;
164 }
165
166 //this method is expected to return data is sql date string
167 // sql data needs to be in dd-mon-yyyy hh24:mi:ss format
168 // example 03-feb-2008 21:00:01
169 public string getsqldate(calendar date){
170 simpledateformat dateformat =new simpledateformat("dd-mmm-yyyy
hh:mm:ss");
171 return " to_date('"+dateformat.format(date.gettime())
172 +"','dd-mon-yyyy hh24:mi:ss')";
173 }
174 }
175
176 // end of class messagedao
177
178 /*
179 * interface messageservicelocal
180 */
181
182 package com.wipro.knet.codetest.ejb;
183
184 import com.wipro.knet.codetest.util.messageexception;
185 import javax.ejb.local;
186
187
188 @local
189 public interface messageservicelocal {
190
191 //parse and save message from a user
#`s 192 public boolean processnewmessge(byte[] message,
193 java.lang.string username);// this should throw a message
exception
194
195 //get message from a user for any give duration
196 public byte[] getmessage(java.util.calendar startdate,
197 java.util.calendar enddate,
198 java.lang.string username) throws messageexception;
199
200 }
201
202 //end of class
203 /*
204 * class messageservicebean
205 */
206
207 package com.wipro.knet.codetest.ejb;
208
209 import com.wipro.knet.codetest.util.messageexception;
210 import javax.ejb.stateless;
211 import com.wipro.knet.codetest.handler.messagehandler;
212 import java.util.calendar;
213
214
215
216 @stateless
217 public class messageservicebean implements messageservicelocal {
218
219 //message exception should be passed backed to the caller
220 public boolean processnewmessge(byte[] message, string username)
221 throws messageexception{
222 messagehandler handler= new messagehandler(message);
223 if(handler.isvalid()){
224 handler.savemessage(username);
225 return true;
226 }else{
227 return false;
228 }
229 return false;
230 }
231
232 public byte[] getmessage(calendar startdate, calendar enddate,
233 string username) throws messageexception{
234 messagehandler handler= new messagehandler();
#`s 235 return
handler.getmessage(startdate,username,enddate);//,enddate);//the getmessage should
contain calendar,calendar,string
236 }
237
238 }
239
240 // end of class
241
242 /*
243 * this just a dummy class for message incapsulation
244 */
245
246 package com.wipro.knet.codetest.util;
247
248 public class messageexception extends exception{
249
250 public messageexception(exception exp) {
251 super(exp);
252 }
253
254 }
255
256 // end of the class
257
258
259 /*
260 * helper class to handle message
261 * start of message (s) 0x4
262 * end of message(e) 0x2
263 * escape char(\) 0x10
264 * lcr xor for data including end of message char and excluding s
265 * message structure
266 * s data e lcr (please note there is no blank space)
267 * example
268 *
269 * 0x40x310x320x20x31^0x32^0x2
270 * data is 0x310x32
271 * pls check the spec for details
272 *
273 */
274
275 package com.wipro.knet.codetest.handler;
276
277 import com.wipro.knet.codetest.dao.messagedao;
278 import com.wipro.knet.codetest.util.messageexception;
279 import java.util.calendar;
280
281 public class messagehandler {
282
283
284 private byte[] data=null;
285
286 private boolean isvalid=false;
287
288 private int intendindex=-1;
289
290 private int intstartindex=-1;
291
292 public messagehandler(){
293 this.data=null;
294 this.intendindex=-1;
295 this.intstartindex=-1;
296 }
297
298 public messagehandler(byte[] data){
299 this.data=data;
300 parsedata(data.length-1);
301 }
302
303 /**
304 * @todo implement this method
305 * @return boolean
306 */
307 public boolean isvalid() {
308 return this.isvalid;
309 }
310
311 public void savemessage(string username) throws messageexception{
312 byte[] message= new byte[intendindex-intstartindex];
313 messagedao dao=new messagedao();
314 for(int i=intstartindex; i<intendindex; i++){
315 message[i-intstartindex]=this.data[i];
316 }
317 dao.savemessage(message,username);
318 //return data;
319 }
320
321 public void setdata(byte[] data){
322 this.data=data;
323 parsedata(data.length-1);
324 }
325
326 //get data from a valid message
327 // if message is not valid this message will return false
328 private boolean processdata(int startindex, int endindex){
329
330 byte tmpvalue=0;
331 for(int i=startindex+1; i<endindex; i++){
332
333 switch(this.data[i]) {
334
335 case 0x10: tmpvalue ^= this.data[i+1];
336 i++;
337
338 case 0x2: tmpvalue ^= this.data[i];
339 this.intstartindex=startindex;
340 this.intendindex=i+1;
341 if(tmpvalue==this.data[i+1])
342 this.isvalid=true;
343 else this.isvalid=false;
344 return true;
345
346 default: tmpvalue ^= this.data[i];
347 break;
348 }
349 }
350 return false;
351 }
352
353 //parse message
354 private void parsedata(int endindex){
355 for(int i=endindex; i>=0; i--){
356 if(this.data[i]==0x4) {
357 if(this.data[i-1]!=0x10){
358 if(processdata(i,endindex)){
359 break;
360 }else if(i>3) parsedata(endindex);
361 }
362 }
363 }
364 }
365
366 // get message from database
367 public byte[] getmessage(calendar startdate, calendar enddate,
368 string username) throws messageexception{
369 messagedao dao= new messagedao();
370 return dao.getmessage(startdate,enddate,username);
371 }
372 }
373
374 //end of message class

Você também pode gostar