~motu-torrent/azureus/upstream-stable

« back to all changes in this revision

Viewing changes to org/gudy/azureus2/ui/webplugin/remoteui/xml/server/XMLRequestProcessor.java

  • Committer: John Dong
  • Date: 2007-10-22 04:54:13 UTC
  • Revision ID: john.dong@gmail.com-20071022045413-3ovb11u82rrcokxx
Commit 3.0.3.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * File    : XMLRequestProcessor.java
3
 
 * Created : 15-Mar-2004
4
 
 * By      : parg
5
 
 * 
6
 
 * Azureus - a Java Bittorrent client
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2 of the License.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details ( see the LICENSE file ).
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 */
21
 
 
22
 
package org.gudy.azureus2.ui.webplugin.remoteui.xml.server;
23
 
 
24
 
/**
25
 
 * @author parg
26
 
 *
27
 
 */
28
 
 
29
 
import java.util.*;
30
 
import java.io.*;
31
 
import java.net.*;
32
 
import java.lang.reflect.*;
33
 
 
34
 
import org.gudy.azureus2.core3.util.ByteFormatter;
35
 
import org.gudy.azureus2.core3.util.Debug;
36
 
import org.gudy.azureus2.core3.xml.simpleparser.*;
37
 
import org.gudy.azureus2.core3.xml.util.*;
38
 
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocument;
39
 
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentAttribute;
40
 
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
41
 
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentNode;
42
 
import org.gudy.azureus2.pluginsimpl.remote.*;
43
 
 
44
 
public class 
45
 
XMLRequestProcessor
46
 
        extends XUXmlWriter
47
 
{
48
 
        protected RPRequestHandler                              request_handler;
49
 
        protected SimpleXMLParserDocument               request;
50
 
        
51
 
        protected
52
 
        XMLRequestProcessor(
53
 
                RPRequestHandler                        _request_handler,
54
 
                RPRequestAccessController       _access_controller,
55
 
                String                                          _client_ip,
56
 
                InputStream                                     _request,
57
 
                OutputStream                            _reply )
58
 
        {
59
 
                super( _reply );
60
 
                        
61
 
                request_handler         = _request_handler;
62
 
                
63
 
                writeLineRaw( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
64
 
                
65
 
                try{
66
 
                        writeLineRaw( "<RESPONSE>" );
67
 
                        
68
 
                        indent();
69
 
                                                
70
 
                        request = SimpleXMLParserDocumentFactory.create( _request );
71
 
                                
72
 
                        process( _client_ip , _access_controller);
73
 
                        
74
 
                }catch( Throwable e ){
75
 
                                        
76
 
                        Debug.printStackTrace( e );
77
 
                        
78
 
                        if ( e instanceof SimpleXMLParserDocumentException ){
79
 
                                
80
 
                                writeTag("ERROR", "Invalid XML Plugin request received - " + exceptionToString(e));
81
 
                                
82
 
                        }else{
83
 
                                
84
 
                                writeTag("ERROR", e );
85
 
                                
86
 
                        }
87
 
 
88
 
                }finally{
89
 
                        
90
 
                        exdent();
91
 
                        
92
 
                        writeLineRaw( "</RESPONSE>" );
93
 
                        
94
 
                        flushOutputStream();
95
 
                }
96
 
        }
97
 
        
98
 
        protected void
99
 
        process(
100
 
                String                                          client_ip,
101
 
                RPRequestAccessController       access_controller )
102
 
        {
103
 
                // request.print();
104
 
                        
105
 
                RPRequest       req_obj = (RPRequest)deserialiseObject( request, RPRequest.class, "" );
106
 
                
107
 
                req_obj.setClientIP( client_ip );
108
 
                
109
 
                RPReply reply = request_handler.processRequest( req_obj, access_controller );
110
 
 
111
 
                        // void methods result in null return
112
 
 
113
 
                if ( reply != null ){
114
 
                        
115
 
                        Map     props = reply.getProperties();
116
 
                        
117
 
                        Iterator it = props.keySet().iterator();
118
 
                        
119
 
                        while( it.hasNext()){
120
 
                                
121
 
                                String  name    = (String)it.next();
122
 
                                String  value   = (String)props.get(name);
123
 
                                
124
 
                                writeTag( name, value );
125
 
                        }
126
 
                        
127
 
                        try{
128
 
                                Object  response = reply.getResponse();
129
 
                        
130
 
                                        // null responses are represented by no response
131
 
                                
132
 
                                if ( response != null ){
133
 
                                        
134
 
                                        serialiseObject( response, "", 0xffffffff );
135
 
                                }
136
 
                                
137
 
                        }catch( RPException e ){
138
 
                                
139
 
                                Debug.printStackTrace( e );
140
 
                                
141
 
                                writeTag("ERROR", e );
142
 
                                
143
 
                        }
144
 
                }
145
 
        }
146
 
        
147
 
        protected void
148
 
        writeTag(
149
 
                String          tag,
150
 
                Throwable       e )
151
 
        {
152
 
                writeLineRaw( "<ERROR>");
153
 
 
154
 
                writeLineEscaped( exceptionToString(e));
155
 
                
156
 
                if ( e instanceof RPException && e.getCause() != null ){
157
 
                        
158
 
                        e = e.getCause();
159
 
                }
160
 
                
161
 
                serialiseObject( e, "    ", ~Modifier.PRIVATE );
162
 
                
163
 
                writeLineRaw( "</ERROR>" );
164
 
        }
165
 
        
166
 
        protected String
167
 
        exceptionToString(
168
 
                Throwable e )
169
 
        {
170
 
                Throwable cause = e.getCause();
171
 
                
172
 
                if ( cause != null ){
173
 
                        
174
 
                        String  m = cause.getMessage();
175
 
                        
176
 
                        if ( m != null ){
177
 
                                
178
 
                                return( m );
179
 
                        }
180
 
                        
181
 
                        return( cause.toString());
182
 
                }
183
 
                
184
 
                String  m = e.getMessage();
185
 
                
186
 
                if ( m != null ){
187
 
                        
188
 
                        return( m );
189
 
                }
190
 
                
191
 
                return( e.toString());
192
 
        }
193
 
        
194
 
        protected Object
195
 
        deserialiseObject(
196
 
                SimpleXMLParserDocumentNode             node,
197
 
                Class                                                   cla,
198
 
                String                                                  indent )
199
 
        {
200
 
                        // hack I'm afraid, when deserialising request objects we need to use the
201
 
                        // method to correctly deserialise parameters
202
 
                
203
 
                String  request_method = null;
204
 
                
205
 
                if ( cla == RPRequest.class ){
206
 
                        
207
 
                        request_method = node.getChild( "METHOD" ).getValue().trim();
208
 
 
209
 
                }
210
 
                
211
 
                // System.out.println(indent + "deser:" + cla.getName());
212
 
                
213
 
                try{
214
 
                        Object  obj = cla.newInstance();
215
 
                        
216
 
                        Field[] fields = cla.getDeclaredFields();
217
 
                        
218
 
                        for (int i=0;i<fields.length;i++){
219
 
                                
220
 
                                Field   field = fields[i];
221
 
                                
222
 
                                int     modifiers = field.getModifiers();
223
 
                                
224
 
                                if (( modifiers & ( Modifier.TRANSIENT | Modifier.STATIC )) == 0 ){
225
 
                                        
226
 
                                        String  name = field.getName();
227
 
                                        
228
 
                                        Class   type = field.getType();
229
 
                                        
230
 
                                        SimpleXMLParserDocumentNode child = node.getChild( name );
231
 
                                        
232
 
                                                // System.out.println( indent + "  field:" + field.getName() + " -> " + child );
233
 
                                                
234
 
                                        if ( child != null ){
235
 
 
236
 
                                                if ( type.isArray()){
237
 
                                                
238
 
                                                        Class   sub_type = type.getComponentType();
239
 
                                        
240
 
                                                        SimpleXMLParserDocumentNode[] entries = child.getChildren();
241
 
                                                        
242
 
                                                        Object array = Array.newInstance( sub_type, entries.length );
243
 
                                                
244
 
                                                                // hack. for request objects we deserialise the parameters
245
 
                                                                // array by using the method signature
246
 
                                                        
247
 
                                                        if ( request_method != null  ){
248
 
                                                                
249
 
                                                                        // must be params
250
 
                                                
251
 
                                                                String[]        bits = new String[entries.length];
252
 
                                                                
253
 
                                                                int             method_pos = request_method.indexOf( '[' )+1;
254
 
 
255
 
                                                                for (int j=0;j<entries.length;j++){
256
 
                                                                                                                                                                                                                                
257
 
                                                                        int     p1 = request_method.indexOf(',',method_pos);
258
 
                                                                                
259
 
                                                                        String  bit;
260
 
                                                                                
261
 
                                                                        if ( p1 == -1 ){
262
 
                                                                                        
263
 
                                                                                bits[j] = request_method.substring( method_pos, request_method.length()-1).toLowerCase();
264
 
                                                                                        
265
 
                                                                                break;
266
 
                                                                        }else{
267
 
                                                                                        
268
 
                                                                                bits[j] = request_method.substring( method_pos, p1 ).toLowerCase();
269
 
                                                                                        
270
 
                                                                                method_pos = p1+1;
271
 
                                                                        }
272
 
                                                                }
273
 
                                        
274
 
                                                                for (int j=0;j<entries.length;j++){
275
 
                                                                        
276
 
                                                                        SimpleXMLParserDocumentNode     array_child = entries[j];
277
 
                                                                                
278
 
                                                                        SimpleXMLParserDocumentAttribute index_attr = array_child.getAttribute("index");
279
 
                                                                        
280
 
                                                                        String  index_str = index_attr==null?null:index_attr.getValue().trim();
281
 
                                                                        
282
 
                                                                        int     array_index = index_str==null?j:Integer.parseInt(index_str);
283
 
                                                                        
284
 
                                                                        String  bit = bits[array_index];
285
 
                                                                        
286
 
                                                                        String  sub_value = array_child.getValue().trim();
287
 
                                                                        
288
 
                                                                        if ( bit.equals("string")){
289
 
                                                                                
290
 
                                                                                Array.set( array, array_index, sub_value );
291
 
                                                                        
292
 
                                                                        }else if ( bit.equals("int")){
293
 
                                                                                
294
 
                                                                                Array.set( array, array_index, Integer.valueOf( sub_value));
295
 
                                                                        
296
 
                                                                        }else if ( bit.equals("boolean")){
297
 
                                                                                
298
 
                                                                                Array.set( array, array_index, Boolean.valueOf( sub_value ));
299
 
                                                                        
300
 
                                                                        }else if ( bit.equals("url")){
301
 
                                                                                
302
 
                                                                                Array.set( array, array_index, new URL(sub_value));
303
 
                                                                        
304
 
                                                                        }else if ( bit.equals("byte[]")){
305
 
                                                                                
306
 
                                                                                Array.set( array, array_index, ByteFormatter.decodeString( sub_value ));
307
 
                                                                        
308
 
                                                                        }else{
309
 
                                                                                        // see if its an object
310
 
                                                                                
311
 
                                                                                SimpleXMLParserDocumentNode     obj_node = array_child.getChild("OBJECT");
312
 
                                                                                
313
 
                                                                                if ( obj_node != null ){
314
 
                                                                                        
315
 
                                                                                        String  oid_str = obj_node.getChild("_object_id").getValue().trim();
316
 
                                                                                        
317
 
                                                                                        long oid = Long.parseLong( oid_str );
318
 
                                                                                        
319
 
                                                                                        RPObject        local_obj = RPObject._lookupLocal( oid );
320
 
                                                                                        
321
 
                                                                                        Array.set( array, array_index, local_obj );
322
 
                                                                                                                                                        
323
 
                                                                                }else{
324
 
                                                                                
325
 
                                                                                        throw( new RuntimeException( "not implemented"));                                                                               
326
 
                                                                                }
327
 
                                                                        }
328
 
                                                                }
329
 
 
330
 
                                                        }else{
331
 
                                                        
332
 
                                                                for (int j=0;j<entries.length;j++){
333
 
                                                                        
334
 
                                                                        SimpleXMLParserDocumentNode     array_child = entries[j];
335
 
                                                                        
336
 
                                                                        if ( sub_type == String.class ){
337
 
                                                                                
338
 
                                                                                Array.set( array, j, child.getValue().trim());
339
 
                                                                                
340
 
                                                                        }else{
341
 
                                                                        
342
 
                                                                                throw( new RuntimeException( "not implemented"));
343
 
                                                                        }
344
 
                                                                }
345
 
                                                        }
346
 
                                                        
347
 
                                                        field.set( obj, array );
348
 
                                                }else{
349
 
                                                        
350
 
                                                        String  value = child.getValue().trim();
351
 
                                                        
352
 
                                                        if ( type == String.class ){
353
 
                                                                
354
 
                                                                field.set( obj, value );
355
 
                                                                
356
 
                                                        }else if ( type == long.class ){
357
 
                                                                
358
 
                                                                field.setLong( obj,Long.parseLong( value ));
359
 
                                                                
360
 
                                                        }else if ( type == boolean.class ){
361
 
                                                                
362
 
                                                                throw( new RuntimeException( "not implemented"));
363
 
 
364
 
                                                                //field.set( obj, new Long(Long.parseLong( value )));
365
 
                                                                
366
 
                                                        }else if ( type == byte.class ){
367
 
 
368
 
                                                                throw( new RuntimeException( "not implemented"));
369
 
 
370
 
                                                                //field.set( obj, new Long(Long.parseLong( value )));
371
 
                                                                
372
 
                                                        }else if ( type == char.class ){
373
 
                                                                
374
 
                                                                field.setChar( obj, value.charAt(0));
375
 
                                                                
376
 
                                                        }else if ( type == double.class ){
377
 
                                                                
378
 
                                                                field.setDouble( obj, Double.parseDouble( value));
379
 
                                                                
380
 
                                                        }else if ( type == float.class ){
381
 
                                                                
382
 
                                                                field.setFloat( obj, Float.parseFloat( value));
383
 
                                                                
384
 
                                                        }else if ( type == int.class ){
385
 
                                                                
386
 
                                                                field.setInt( obj, Integer.parseInt( value));
387
 
                                                                
388
 
                                                        }else if ( type == short.class ){
389
 
                                                                
390
 
                                                                field.setShort( obj, (Short.parseShort( value )));
391
 
                                                
392
 
                                                        }else if ( type == Long.class || type == long.class ){
393
 
                                                                
394
 
                                                                field.set( obj, new Long(Long.parseLong( value )));
395
 
                                                                
396
 
                                                        }else{
397
 
                                                                
398
 
                                                                field.set( obj, deserialiseObject( child, type, indent + "    " ));
399
 
                                                        }
400
 
                                                }
401
 
                                        }
402
 
                                }
403
 
                        }
404
 
                        
405
 
                        return( obj );
406
 
                        
407
 
                }catch( Throwable e ){
408
 
                        
409
 
                        Debug.printStackTrace( e );
410
 
                        
411
 
                        throw( new RuntimeException( e.toString()));
412
 
                }
413
 
        }
414
 
        
415
 
        protected void
416
 
        serialiseObject(
417
 
                Object          obj,
418
 
                String          indent,
419
 
                int                     original_modifier_filter )
420
 
        {
421
 
                int modifier_filter = original_modifier_filter & (~(Modifier.TRANSIENT | Modifier.STATIC));
422
 
                
423
 
                Class   cla = obj.getClass();
424
 
                
425
 
                // System.out.println(indent + "ser:" + cla.getName());
426
 
                
427
 
                if ( cla.isArray()){
428
 
                        
429
 
                        int     len = Array.getLength( obj );
430
 
                        
431
 
                                // byte[] -> hex chars
432
 
                        
433
 
                        if ( cla.getComponentType() == byte.class ){
434
 
                        
435
 
                                byte[] data = (byte[])obj;
436
 
                                
437
 
                                writeLineEscaped( ByteFormatter.nicePrint( data, true ));
438
 
                                
439
 
                        }else{
440
 
                                
441
 
                                for (int i=0;i<len;i++){
442
 
                                        
443
 
                                        Object  entry = Array.get( obj, i );
444
 
                                        
445
 
                                        try{
446
 
                                                writeLineRaw( "<ENTRY index=\""+i+"\">" );
447
 
                                                
448
 
                                                indent();
449
 
                                        
450
 
                                                serialiseObject( entry, indent+"  ", original_modifier_filter);
451
 
                                                
452
 
                                        }finally{
453
 
                                                
454
 
                                                exdent();
455
 
                                                
456
 
                                                writeLineRaw( "</ENTRY>");
457
 
                                        }
458
 
                                }
459
 
                        }
460
 
                        
461
 
                        return;
462
 
                }
463
 
                
464
 
                if ( cla == String.class ){
465
 
                        
466
 
                        writeLineEscaped( "" + (String)obj);
467
 
                                
468
 
                }else if ( cla == Integer.class ){
469
 
                        
470
 
                        writeLineEscaped( "" + ((Integer)obj).intValue());
471
 
                                
472
 
                }else if ( cla == Boolean.class ){
473
 
                        
474
 
                        writeLineEscaped( "" + ((Boolean)obj).booleanValue());
475
 
                                        
476
 
                }else{
477
 
                        
478
 
                        while( cla != null ){
479
 
                                try{
480
 
                                        Field[] fields = cla.getDeclaredFields();
481
 
                                        
482
 
                                        for (int i=0;i<fields.length;i++){
483
 
                                                
484
 
                                                Field   field = fields[i];
485
 
                                                
486
 
                                                int     modifiers = field.getModifiers();
487
 
                                                
488
 
                                                if ((( modifiers | modifier_filter ) == modifier_filter )){
489
 
                                                        
490
 
                                                        String  name = field.getName();
491
 
                                                        
492
 
                                                        Class   type = field.getType();
493
 
                                                                                        
494
 
                                                        // System.out.println( indent + "  field:" + field.getName() + ", type = " + type );
495
 
                                                        
496
 
                                                        try{
497
 
                                                                writeLineRaw( "<" + name + ">" );
498
 
                                                                
499
 
                                                                indent();
500
 
                                                                                                                
501
 
                                                                if ( type == String.class ){
502
 
                                                                        
503
 
                                                                        writeLineEscaped( (String)field.get( obj ));
504
 
                                                                        
505
 
                                                                }else if ( type == File.class ){
506
 
                                                                        
507
 
                                                                        writeLineEscaped( "" + ((File)field.get( obj )).toString());
508
 
                                                                                        
509
 
                                                                }else if ( type == Integer.class ){
510
 
                                                                        
511
 
                                                                        writeLineEscaped( ""+((Integer)field.get( obj )).intValue());
512
 
                                                                
513
 
                                                                }else if ( type == Boolean.class ){
514
 
                                                                        
515
 
                                                                        writeLineEscaped( ""+((Boolean)field.get( obj )).booleanValue());
516
 
                                                                
517
 
                                                                }else if ( type == long.class ){
518
 
                                                                        
519
 
                                                                        writeLineEscaped( ""+field.getLong( obj ));
520
 
                                                                        
521
 
                                                                }else if ( type == boolean.class ){
522
 
                                                                        
523
 
                                                                        writeLineEscaped( ""+field.getBoolean( obj ));
524
 
                                                                        
525
 
                                                                }else if ( type == byte.class ){
526
 
                                                                        
527
 
                                                                        writeLineEscaped( ""+field.getByte( obj ));
528
 
                                                                        
529
 
                                                                }else if ( type == char.class ){
530
 
                                                                        
531
 
                                                                        writeLineEscaped( ""+field.getChar( obj ));
532
 
                                                                        
533
 
                                                                }else if ( type == double.class ){
534
 
                                                                        
535
 
                                                                        writeLineEscaped( ""+field.getDouble( obj ));
536
 
                                                                        
537
 
                                                                }else if ( type == float.class ){
538
 
                                                                        
539
 
                                                                        writeLineEscaped( ""+field.getFloat( obj ));
540
 
                                                                        
541
 
                                                                }else if ( type == int.class ){
542
 
                                                                        
543
 
                                                                        writeLineEscaped( ""+field.getInt( obj ));
544
 
                                                                        
545
 
                                                                }else if ( type == short.class ){
546
 
                                                                        
547
 
                                                                        writeLineEscaped( ""+field.getShort( obj ));
548
 
                                                                        
549
 
                                                                }else if ( type == Long.class ){
550
 
                                                                        
551
 
                                                                        writeLineEscaped( ""+field.get( obj ));
552
 
                                                                        
553
 
                                                                }else{
554
 
                                                                        
555
 
                                                                        serialiseObject( field.get(obj), indent + "    ", original_modifier_filter );
556
 
                                                                }
557
 
                                                                
558
 
                                                        }finally{
559
 
                                                                
560
 
                                                                exdent();
561
 
                                                                
562
 
                                                                writeLineRaw( "</" + name + ">" );
563
 
                                                        }
564
 
                                                }
565
 
                                        }
566
 
                                                                        
567
 
                                }catch( Throwable e ){
568
 
                                        
569
 
                                        Debug.printStackTrace( e );
570
 
                                        
571
 
                                        throw( new RuntimeException( e.toString()));
572
 
                                }
573
 
                                
574
 
                                cla = cla.getSuperclass();
575
 
                        }
576
 
                }
577
 
        }
578
 
}
 
1
/*
 
2
 * File    : XMLRequestProcessor.java
 
3
 * Created : 15-Mar-2004
 
4
 * By      : parg
 
5
 * 
 
6
 * Azureus - a Java Bittorrent client
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details ( see the LICENSE file ).
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 */
 
21
 
 
22
package org.gudy.azureus2.ui.webplugin.remoteui.xml.server;
 
23
 
 
24
/**
 
25
 * @author parg
 
26
 *
 
27
 */
 
28
 
 
29
import java.util.*;
 
30
import java.io.*;
 
31
import java.net.*;
 
32
import java.lang.reflect.*;
 
33
 
 
34
import org.gudy.azureus2.core3.util.ByteFormatter;
 
35
import org.gudy.azureus2.core3.util.Debug;
 
36
import org.gudy.azureus2.core3.xml.simpleparser.*;
 
37
import org.gudy.azureus2.core3.xml.util.*;
 
38
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocument;
 
39
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentAttribute;
 
40
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
 
41
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentNode;
 
42
import org.gudy.azureus2.pluginsimpl.remote.*;
 
43
 
 
44
public class 
 
45
XMLRequestProcessor
 
46
        extends XUXmlWriter
 
47
{
 
48
        protected RPRequestHandler                              request_handler;
 
49
        protected SimpleXMLParserDocument               request;
 
50
        
 
51
        protected
 
52
        XMLRequestProcessor(
 
53
                RPRequestHandler                        _request_handler,
 
54
                RPRequestAccessController       _access_controller,
 
55
                String                                          _client_ip,
 
56
                InputStream                                     _request,
 
57
                OutputStream                            _reply )
 
58
        {
 
59
                super( _reply );
 
60
                        
 
61
                request_handler         = _request_handler;
 
62
                
 
63
                writeLineRaw( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
 
64
                
 
65
                try{
 
66
                        writeLineRaw( "<RESPONSE>" );
 
67
                        
 
68
                        indent();
 
69
                                                
 
70
                        request = SimpleXMLParserDocumentFactory.create( _request );
 
71
                                
 
72
                        process( _client_ip , _access_controller);
 
73
                        
 
74
                }catch( Throwable e ){
 
75
                                        
 
76
                        Debug.printStackTrace( e );
 
77
                        
 
78
                        if ( e instanceof SimpleXMLParserDocumentException ){
 
79
                                
 
80
                                writeTag("ERROR", "Invalid XML Plugin request received - " + exceptionToString(e));
 
81
                                
 
82
                        }else{
 
83
                                
 
84
                                writeTag("ERROR", e );
 
85
                                
 
86
                        }
 
87
 
 
88
                }finally{
 
89
                        
 
90
                        exdent();
 
91
                        
 
92
                        writeLineRaw( "</RESPONSE>" );
 
93
                        
 
94
                        flushOutputStream();
 
95
                }
 
96
        }
 
97
        
 
98
        protected void
 
99
        process(
 
100
                String                                          client_ip,
 
101
                RPRequestAccessController       access_controller )
 
102
        {
 
103
                // request.print();
 
104
                        
 
105
                RPRequest       req_obj = (RPRequest)deserialiseObject( request, RPRequest.class, "" );
 
106
                
 
107
                req_obj.setClientIP( client_ip );
 
108
                
 
109
                RPReply reply = request_handler.processRequest( req_obj, access_controller );
 
110
 
 
111
                        // void methods result in null return
 
112
 
 
113
                if ( reply != null ){
 
114
                        
 
115
                        Map     props = reply.getProperties();
 
116
                        
 
117
                        Iterator it = props.keySet().iterator();
 
118
                        
 
119
                        while( it.hasNext()){
 
120
                                
 
121
                                String  name    = (String)it.next();
 
122
                                String  value   = (String)props.get(name);
 
123
                                
 
124
                                writeTag( name, value );
 
125
                        }
 
126
                        
 
127
                        try{
 
128
                                Object  response = reply.getResponse();
 
129
                        
 
130
                                        // null responses are represented by no response
 
131
                                
 
132
                                if ( response != null ){
 
133
                                        
 
134
                                        serialiseObject( response, "", 0xffffffff );
 
135
                                }
 
136
                                
 
137
                        }catch( RPException e ){
 
138
                                
 
139
                                Debug.printStackTrace( e );
 
140
                                
 
141
                                writeTag("ERROR", e );
 
142
                                
 
143
                        }
 
144
                }
 
145
        }
 
146
        
 
147
        protected void
 
148
        writeTag(
 
149
                String          tag,
 
150
                Throwable       e )
 
151
        {
 
152
                writeLineRaw( "<ERROR>");
 
153
 
 
154
                writeLineEscaped( exceptionToString(e));
 
155
                
 
156
                if ( e instanceof RPException && e.getCause() != null ){
 
157
                        
 
158
                        e = e.getCause();
 
159
                }
 
160
                
 
161
                serialiseObject( e, "    ", ~Modifier.PRIVATE );
 
162
                
 
163
                writeLineRaw( "</ERROR>" );
 
164
        }
 
165
        
 
166
        protected String
 
167
        exceptionToString(
 
168
                Throwable e )
 
169
        {
 
170
                Throwable cause = e.getCause();
 
171
                
 
172
                if ( cause != null ){
 
173
                        
 
174
                        String  m = cause.getMessage();
 
175
                        
 
176
                        if ( m != null ){
 
177
                                
 
178
                                return( m );
 
179
                        }
 
180
                        
 
181
                        return( cause.toString());
 
182
                }
 
183
                
 
184
                String  m = e.getMessage();
 
185
                
 
186
                if ( m != null ){
 
187
                        
 
188
                        return( m );
 
189
                }
 
190
                
 
191
                return( e.toString());
 
192
        }
 
193
        
 
194
        protected Object
 
195
        deserialiseObject(
 
196
                SimpleXMLParserDocumentNode             node,
 
197
                Class                                                   cla,
 
198
                String                                                  indent )
 
199
        {
 
200
                        // hack I'm afraid, when deserialising request objects we need to use the
 
201
                        // method to correctly deserialise parameters
 
202
                
 
203
                String  request_method = null;
 
204
                
 
205
                if ( cla == RPRequest.class ){
 
206
                        
 
207
                        request_method = node.getChild( "METHOD" ).getValue().trim();
 
208
 
 
209
                }
 
210
                
 
211
                // System.out.println(indent + "deser:" + cla.getName());
 
212
                
 
213
                try{
 
214
                        Object  obj = cla.newInstance();
 
215
                        
 
216
                        Field[] fields = cla.getDeclaredFields();
 
217
                        
 
218
                        for (int i=0;i<fields.length;i++){
 
219
                                
 
220
                                Field   field = fields[i];
 
221
                                
 
222
                                int     modifiers = field.getModifiers();
 
223
                                
 
224
                                if (( modifiers & ( Modifier.TRANSIENT | Modifier.STATIC )) == 0 ){
 
225
                                        
 
226
                                        String  name = field.getName();
 
227
                                        
 
228
                                        Class   type = field.getType();
 
229
                                        
 
230
                                        SimpleXMLParserDocumentNode child = node.getChild( name );
 
231
                                        
 
232
                                                // System.out.println( indent + "  field:" + field.getName() + " -> " + child );
 
233
                                                
 
234
                                        if ( child != null ){
 
235
 
 
236
                                                if ( type.isArray()){
 
237
                                                
 
238
                                                        Class   sub_type = type.getComponentType();
 
239
                                        
 
240
                                                        SimpleXMLParserDocumentNode[] entries = child.getChildren();
 
241
                                                        
 
242
                                                        Object array = Array.newInstance( sub_type, entries.length );
 
243
                                                
 
244
                                                                // hack. for request objects we deserialise the parameters
 
245
                                                                // array by using the method signature
 
246
                                                        
 
247
                                                        if ( request_method != null  ){
 
248
                                                                
 
249
                                                                        // must be params
 
250
                                                
 
251
                                                                String[]        bits = new String[entries.length];
 
252
                                                                
 
253
                                                                int             method_pos = request_method.indexOf( '[' )+1;
 
254
 
 
255
                                                                for (int j=0;j<entries.length;j++){
 
256
                                                                                                                                                                                                                                
 
257
                                                                        int     p1 = request_method.indexOf(',',method_pos);
 
258
                                                                                
 
259
                                                                        if ( p1 == -1 ){
 
260
                                                                                        
 
261
                                                                                bits[j] = request_method.substring( method_pos, request_method.length()-1).toLowerCase();
 
262
                                                                                        
 
263
                                                                                break;
 
264
                                                                        }else{
 
265
                                                                                        
 
266
                                                                                bits[j] = request_method.substring( method_pos, p1 ).toLowerCase();
 
267
                                                                                        
 
268
                                                                                method_pos = p1+1;
 
269
                                                                        }
 
270
                                                                }
 
271
                                        
 
272
                                                                for (int j=0;j<entries.length;j++){
 
273
                                                                        
 
274
                                                                        SimpleXMLParserDocumentNode     array_child = entries[j];
 
275
                                                                                
 
276
                                                                        SimpleXMLParserDocumentAttribute index_attr = array_child.getAttribute("index");
 
277
                                                                        
 
278
                                                                        String  index_str = index_attr==null?null:index_attr.getValue().trim();
 
279
                                                                        
 
280
                                                                        int     array_index = index_str==null?j:Integer.parseInt(index_str);
 
281
                                                                        
 
282
                                                                        String  bit = bits[array_index];
 
283
                                                                        
 
284
                                                                        String  sub_value = array_child.getValue().trim();
 
285
                                                                        
 
286
                                                                        if ( bit.equals("string")){
 
287
                                                                                
 
288
                                                                                Array.set( array, array_index, sub_value );
 
289
                                                                        
 
290
                                                                        }else if ( bit.equals("int")){
 
291
                                                                                
 
292
                                                                                Array.set( array, array_index, Integer.valueOf( sub_value));
 
293
                                                                        
 
294
                                                                        }else if ( bit.equals("boolean")){
 
295
                                                                                
 
296
                                                                                Array.set( array, array_index, Boolean.valueOf( sub_value ));
 
297
                                                                        
 
298
                                                                        }else if ( bit.equals("url")){
 
299
                                                                                
 
300
                                                                                Array.set( array, array_index, new URL(sub_value));
 
301
                                                                        
 
302
                                                                        }else if ( bit.equals("byte[]")){
 
303
                                                                                
 
304
                                                                                Array.set( array, array_index, ByteFormatter.decodeString( sub_value ));
 
305
                                                                        
 
306
                                                                        }else{
 
307
                                                                                        // see if its an object
 
308
                                                                                
 
309
                                                                                SimpleXMLParserDocumentNode     obj_node = array_child.getChild("OBJECT");
 
310
                                                                                
 
311
                                                                                if ( obj_node != null ){
 
312
                                                                                        
 
313
                                                                                        String  oid_str = obj_node.getChild("_object_id").getValue().trim();
 
314
                                                                                        
 
315
                                                                                        long oid = Long.parseLong( oid_str );
 
316
                                                                                        
 
317
                                                                                        RPObject        local_obj = RPObject._lookupLocal( oid );
 
318
                                                                                        
 
319
                                                                                        Array.set( array, array_index, local_obj );
 
320
                                                                                                                                                        
 
321
                                                                                }else{
 
322
                                                                                
 
323
                                                                                        throw( new RuntimeException( "not implemented"));                                                                               
 
324
                                                                                }
 
325
                                                                        }
 
326
                                                                }
 
327
 
 
328
                                                        }else{
 
329
                                                        
 
330
                                                                for (int j=0;j<entries.length;j++){
 
331
                                                                        
 
332
                                                                        SimpleXMLParserDocumentNode     array_child = entries[j];
 
333
                                                                        
 
334
                                                                        if ( sub_type == String.class ){
 
335
                                                                                
 
336
                                                                                Array.set( array, j, child.getValue().trim());
 
337
                                                                                
 
338
                                                                        }else{
 
339
                                                                        
 
340
                                                                                throw( new RuntimeException( "not implemented"));
 
341
                                                                        }
 
342
                                                                }
 
343
                                                        }
 
344
                                                        
 
345
                                                        field.set( obj, array );
 
346
                                                }else{
 
347
                                                        
 
348
                                                        String  value = child.getValue().trim();
 
349
                                                        
 
350
                                                        if ( type == String.class ){
 
351
                                                                
 
352
                                                                field.set( obj, value );
 
353
                                                                
 
354
                                                        }else if ( type == long.class ){
 
355
                                                                
 
356
                                                                field.setLong( obj,Long.parseLong( value ));
 
357
                                                                
 
358
                                                        }else if ( type == boolean.class ){
 
359
                                                                
 
360
                                                                throw( new RuntimeException( "not implemented"));
 
361
 
 
362
                                                                //field.set( obj, new Long(Long.parseLong( value )));
 
363
                                                                
 
364
                                                        }else if ( type == byte.class ){
 
365
 
 
366
                                                                throw( new RuntimeException( "not implemented"));
 
367
 
 
368
                                                                //field.set( obj, new Long(Long.parseLong( value )));
 
369
                                                                
 
370
                                                        }else if ( type == char.class ){
 
371
                                                                
 
372
                                                                field.setChar( obj, value.charAt(0));
 
373
                                                                
 
374
                                                        }else if ( type == double.class ){
 
375
                                                                
 
376
                                                                field.setDouble( obj, Double.parseDouble( value));
 
377
                                                                
 
378
                                                        }else if ( type == float.class ){
 
379
                                                                
 
380
                                                                field.setFloat( obj, Float.parseFloat( value));
 
381
                                                                
 
382
                                                        }else if ( type == int.class ){
 
383
                                                                
 
384
                                                                field.setInt( obj, Integer.parseInt( value));
 
385
                                                                
 
386
                                                        }else if ( type == short.class ){
 
387
                                                                
 
388
                                                                field.setShort( obj, (Short.parseShort( value )));
 
389
                                                
 
390
                                                        }else if ( type == Long.class || type == long.class ){
 
391
                                                                
 
392
                                                                field.set( obj, new Long(Long.parseLong( value )));
 
393
                                                                
 
394
                                                        }else{
 
395
                                                                
 
396
                                                                field.set( obj, deserialiseObject( child, type, indent + "    " ));
 
397
                                                        }
 
398
                                                }
 
399
                                        }
 
400
                                }
 
401
                        }
 
402
                        
 
403
                        return( obj );
 
404
                        
 
405
                }catch( Throwable e ){
 
406
                        
 
407
                        Debug.printStackTrace( e );
 
408
                        
 
409
                        throw( new RuntimeException( e.toString()));
 
410
                }
 
411
        }
 
412
        
 
413
        protected void
 
414
        serialiseObject(
 
415
                Object          obj,
 
416
                String          indent,
 
417
                int                     original_modifier_filter )
 
418
        {
 
419
                int modifier_filter = original_modifier_filter & (~(Modifier.TRANSIENT | Modifier.STATIC));
 
420
                
 
421
                Class   cla = obj.getClass();
 
422
                
 
423
                // System.out.println(indent + "ser:" + cla.getName());
 
424
                
 
425
                if ( cla.isArray()){
 
426
                        
 
427
                        int     len = Array.getLength( obj );
 
428
                        
 
429
                                // byte[] -> hex chars
 
430
                        
 
431
                        if ( cla.getComponentType() == byte.class ){
 
432
                        
 
433
                                byte[] data = (byte[])obj;
 
434
                                
 
435
                                writeLineEscaped( ByteFormatter.nicePrint( data, true ));
 
436
                                
 
437
                        }else{
 
438
                                
 
439
                                for (int i=0;i<len;i++){
 
440
                                        
 
441
                                        Object  entry = Array.get( obj, i );
 
442
                                        
 
443
                                        try{
 
444
                                                writeLineRaw( "<ENTRY index=\""+i+"\">" );
 
445
                                                
 
446
                                                indent();
 
447
                                        
 
448
                                                serialiseObject( entry, indent+"  ", original_modifier_filter);
 
449
                                                
 
450
                                        }finally{
 
451
                                                
 
452
                                                exdent();
 
453
                                                
 
454
                                                writeLineRaw( "</ENTRY>");
 
455
                                        }
 
456
                                }
 
457
                        }
 
458
                        
 
459
                        return;
 
460
                }
 
461
                
 
462
                if ( cla == String.class ){
 
463
                        
 
464
                        writeLineEscaped( "" + (String)obj);
 
465
                                
 
466
                }else if ( cla == Integer.class ){
 
467
                        
 
468
                        writeLineEscaped( "" + ((Integer)obj).intValue());
 
469
                                
 
470
                }else if ( cla == Boolean.class ){
 
471
                        
 
472
                        writeLineEscaped( "" + ((Boolean)obj).booleanValue());
 
473
                                        
 
474
                }else{
 
475
                        
 
476
                        while( cla != null ){
 
477
                                try{
 
478
                                        Field[] fields = cla.getDeclaredFields();
 
479
                                        
 
480
                                        for (int i=0;i<fields.length;i++){
 
481
                                                
 
482
                                                Field   field = fields[i];
 
483
                                                
 
484
                                                int     modifiers = field.getModifiers();
 
485
                                                
 
486
                                                if ((( modifiers | modifier_filter ) == modifier_filter )){
 
487
                                                        
 
488
                                                        String  name = field.getName();
 
489
                                                        
 
490
                                                        Class   type = field.getType();
 
491
                                                                                        
 
492
                                                        // System.out.println( indent + "  field:" + field.getName() + ", type = " + type );
 
493
                                                        
 
494
                                                        try{
 
495
                                                                writeLineRaw( "<" + name + ">" );
 
496
                                                                
 
497
                                                                indent();
 
498
                                                                                                                
 
499
                                                                if ( type == String.class ){
 
500
                                                                        
 
501
                                                                        writeLineEscaped( (String)field.get( obj ));
 
502
                                                                        
 
503
                                                                }else if ( type == File.class ){
 
504
                                                                        
 
505
                                                                        writeLineEscaped( "" + ((File)field.get( obj )).toString());
 
506
                                                                                        
 
507
                                                                }else if ( type == Integer.class ){
 
508
                                                                        
 
509
                                                                        writeLineEscaped( ""+((Integer)field.get( obj )).intValue());
 
510
                                                                
 
511
                                                                }else if ( type == Boolean.class ){
 
512
                                                                        
 
513
                                                                        writeLineEscaped( ""+((Boolean)field.get( obj )).booleanValue());
 
514
                                                                
 
515
                                                                }else if ( type == long.class ){
 
516
                                                                        
 
517
                                                                        writeLineEscaped( ""+field.getLong( obj ));
 
518
                                                                        
 
519
                                                                }else if ( type == boolean.class ){
 
520
                                                                        
 
521
                                                                        writeLineEscaped( ""+field.getBoolean( obj ));
 
522
                                                                        
 
523
                                                                }else if ( type == byte.class ){
 
524
                                                                        
 
525
                                                                        writeLineEscaped( ""+field.getByte( obj ));
 
526
                                                                        
 
527
                                                                }else if ( type == char.class ){
 
528
                                                                        
 
529
                                                                        writeLineEscaped( ""+field.getChar( obj ));
 
530
                                                                        
 
531
                                                                }else if ( type == double.class ){
 
532
                                                                        
 
533
                                                                        writeLineEscaped( ""+field.getDouble( obj ));
 
534
                                                                        
 
535
                                                                }else if ( type == float.class ){
 
536
                                                                        
 
537
                                                                        writeLineEscaped( ""+field.getFloat( obj ));
 
538
                                                                        
 
539
                                                                }else if ( type == int.class ){
 
540
                                                                        
 
541
                                                                        writeLineEscaped( ""+field.getInt( obj ));
 
542
                                                                        
 
543
                                                                }else if ( type == short.class ){
 
544
                                                                        
 
545
                                                                        writeLineEscaped( ""+field.getShort( obj ));
 
546
                                                                        
 
547
                                                                }else if ( type == Long.class ){
 
548
                                                                        
 
549
                                                                        writeLineEscaped( ""+field.get( obj ));
 
550
                                                                        
 
551
                                                                }else{
 
552
                                                                        
 
553
                                                                        serialiseObject( field.get(obj), indent + "    ", original_modifier_filter );
 
554
                                                                }
 
555
                                                                
 
556
                                                        }finally{
 
557
                                                                
 
558
                                                                exdent();
 
559
                                                                
 
560
                                                                writeLineRaw( "</" + name + ">" );
 
561
                                                        }
 
562
                                                }
 
563
                                        }
 
564
                                                                        
 
565
                                }catch( Throwable e ){
 
566
                                        
 
567
                                        Debug.printStackTrace( e );
 
568
                                        
 
569
                                        throw( new RuntimeException( e.toString()));
 
570
                                }
 
571
                                
 
572
                                cla = cla.getSuperclass();
 
573
                        }
 
574
                }
 
575
        }
 
576
}