~ubuntu-branches/ubuntu/wily/steam/wily

« back to all changes in this revision

Viewing changes to server/modules/xml_converter.pike

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2013-10-29 19:51:18 UTC
  • mfrom: (1.1.4) (0.1.4 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20131029195118-b9bxciz5hwx5z459
Tags: 1:1.0.0.39-2ubuntu1
Add an epoch to the version number as there was an unrelated steam package
in the archive with a higher version number.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2004  Thomas Bopp, Thorsten Hampel, Ludger Merkens
2
 
 *
3
 
 *  This program is free software; you can redistribute it and/or modify
4
 
 *  it under the terms of the GNU General Public License as published by
5
 
 *  the Free Software Foundation; either version 2 of the License, or
6
 
 *  (at your option) any later version.
7
 
 *
8
 
 *  This program is distributed in the hope that it will be useful,
9
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
 *  GNU General Public License for more details.
12
 
 *
13
 
 *  You should have received a copy of the GNU General Public License
14
 
 *  along with this program; if not, write to the Free Software
15
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
 
 * 
17
 
 * $Id: xml_converter.pike,v 1.4 2006/09/28 09:50:38 astra Exp $
18
 
 */
19
 
 
20
 
constant cvs_version="$Id: xml_converter.pike,v 1.4 2006/09/28 09:50:38 astra Exp $";
21
 
 
22
 
inherit "/kernel/module";
23
 
inherit "/base/xml_data";
24
 
 
25
 
import XMLCodegen;
26
 
import httplib;
27
 
 
28
 
#include <macros.h>
29
 
#include <database.h>
30
 
#include <attributes.h>
31
 
#include <classes.h>
32
 
#include <types.h>
33
 
#include <access.h>
34
 
#include <events.h>
35
 
#include <client.h>
36
 
#include <config.h>
37
 
 
38
 
//#define XML_DEBUG
39
 
 
40
 
#ifdef XML_DEBUG
41
 
#define DEBUG_XML(s) werror(s+"\n")
42
 
#else
43
 
#define DEBUG_XML(s)
44
 
#endif
45
 
 
46
 
#define ID_OBJECT 0
47
 
#define ID_FUNC   1
48
 
#define ID_PARAMS 2
49
 
#define ID_CONV   3
50
 
 
51
 
#define ID_THIS      1
52
 
#define ID_THIS_USER 2
53
 
 
54
 
#ifdef RESTRICTED_NAMES
55
 
#define OBJ_DESC_OR_NAME OBJ_DESC
56
 
#else
57
 
#define OBJ_DESC_OR_NAME OBJ_NAME
58
 
#endif
59
 
 
60
 
class OBJECT {
61
 
    int       id;
62
 
    object   obj;
63
 
    mapping vars;
64
 
    void create(int i, void|object o) { id = i; obj = o; }
65
 
    object this() { return obj; }
66
 
    string get_identifier() { return obj->get_identifier(); }
67
 
    function find_function(string f) { return obj->find_function(f); }
68
 
};
69
 
 
70
 
class Param {
71
 
    mixed val;
72
 
    mixed def; // the default value
73
 
    string name;
74
 
   
75
 
    mixed cast(string castto) {
76
 
        switch(castto) {
77
 
        case "int":
78
 
            return (int)val; 
79
 
        case "string":
80
 
            return (string)val;
81
 
        default:
82
 
            return val;
83
 
        }
84
 
    }
85
 
    mixed this() { return val; }
86
 
};
87
 
 
88
 
OBJECT THIS = OBJECT(ID_THIS);
89
 
OBJECT THIS_USER = OBJECT(ID_THIS_USER);
90
 
OBJECT CONV = OBJECT(0);
91
 
OBJECT LAST = OBJECT(0);
92
 
OBJECT ACTIVE = OBJECT(0);
93
 
OBJECT XSL = OBJECT(0);
94
 
OBJECT ENV = OBJECT(0);
95
 
 
96
 
class KEYVALUE {
97
 
    mixed key;
98
 
    mixed val;
99
 
    object this() { return this_object(); }
100
 
};
101
 
 
102
 
static mapping activeThreadMap = ([ ]);
103
 
static mapping params = ([ ]);
104
 
 
105
 
KEYVALUE ENTRY = KEYVALUE();
106
 
 
107
 
 
108
 
mapping objXML = ([ CLASS_OBJECT: ([
109
 
    "name":          ({ THIS, "query_attribute", ({ OBJ_NAME }), show }), 
110
 
    "icon":          ({ THIS, "get_icon", ({  }), show_object_ext }),
111
 
    "environment":   ({ THIS, "get_environment", ({          }), show }),
112
 
    "id":            ({ THIS, "get_object_id",   ({          }), show }),
113
 
    "last-modified": ({ CONV, "get_last_modified", ({ THIS,  }), get_time }),
114
 
    "modified-by":   ({ THIS, "query_attribute", ({DOC_USER_MODIFIED }),show}),
115
 
    "created":       ({ THIS, "query_attribute", 
116
 
                            ({OBJ_CREATION_TIME }), get_time }),
117
 
    "owner":         ({ THIS, "get_creator", ({ }), show }),
118
 
    "URL":           ({ THIS, "get_identifier", ({ }), no_uml }),
119
 
    "content":       ({ CONV, "show_content", ({ THIS }), 0 }),
120
 
    "annotated":     ({ CONV, "show_annotations_size", ({ THIS }), 0 }),
121
 
    ]), 
122
 
]);
123
 
 
124
 
mapping annotationXML = ([ CLASS_OBJECT: objXML[CLASS_OBJECT] + 
125
 
([  "mime-headers": ({ THIS, "query_attribute", ({ MAIL_MIMEHEADERS }),
126
 
     show_mapping }),
127
 
   "description":  ({ THIS, "query_attribute", ({OBJ_DESC_OR_NAME}), show })
128
 
]), ]);
129
 
 
130
 
mapping linkXML = ([ CLASS_LINK: ([
131
 
    "link":   ({ THIS, "get_link_object", ({ }), show_object_ext }),
132
 
    "action": ({ THIS, "get_link_action", ({ }), show }),
133
 
    ]), ]);
134
 
 
135
 
mapping exitXML = ([ CLASS_EXIT: ([
136
 
    "exit": ({ THIS, "get_exit", ({ }), show_exit }),
137
 
    ]), ]);
138
 
 
139
 
 
140
 
mapping userXML = ([ CLASS_USER: ([
141
 
    "email":        ({ THIS, "query_attribute", ({ USER_EMAIL }), show }),
142
 
    "inventory":    ({ THIS, "get_inventory",   ({       }), show_size}),
143
 
    "mailbox-size": ({ THIS, "get_annotations", ({  }), show_mailbox_size }), 
144
 
    "trail":        ({ THIS, "query_attribute", ({ "trail" }), show_trail }),
145
 
    "id":            ({ THIS, "get_object_id",   ({          }), show }),
146
 
    "fullname":     ({ THIS, "query_attribute", ({USER_FULLNAME}),show}),
147
 
    "firstname":    ({ THIS, "query_attribute", ({USER_FIRSTNAME}), show}),
148
 
    "name":          ({ THIS, "query_attribute", ({ OBJ_NAME }), 0 }), 
149
 
    "identifier":    ({ THIS, "get_user_name",   ({ }), show }),
150
 
    "icon":          ({ THIS, "query_attribute", ({ OBJ_ICON }), show }),
151
 
    "environment":   ({ THIS, "get_environment", ({          }), show }),
152
 
    "description":   ({ THIS, "query_attribute", ({ OBJ_DESC }), show }),
153
 
    "carry":         ({ CONV, "show_carry",      ({ }), 0 }),
154
 
    "admin":         ({ (MODULE_GROUPS ? MODULE_GROUPS->lookup("admin") : 0),"is_member", ({ THIS }), show_truefalse }),
155
 
    "active-group":  ({ THIS, "get_active_group", ({ }), show }),
156
 
    "status":        ({ THIS, "get_status", ({ }), show_status }),
157
 
    "language":      ({ THIS, "query_attribute", ({ USER_LANGUAGE }), show }),
158
 
    ]), ]);    
159
 
 
160
 
mapping userInvXML = ([ CLASS_USER: ([
161
 
    "id":            ({ THIS, "get_object_id",   ({          }), show }),
162
 
    "name":          ({ THIS, "query_attribute", ({ OBJ_NAME }), 0 }), 
163
 
    "icon":          ({ THIS, "query_attribute", ({ OBJ_ICON }), show }),
164
 
    "status":        ({ THIS, "get_status", ({ }), show_status }),
165
 
  ]), ]);
166
 
  
167
 
 
168
 
mapping annotationsXML = ([ CLASS_OBJECT: ([
169
 
    "annotations": ({ THIS, "get_annotations_for", ({ THIS_USER }),
170
 
                          show_annotations }),
171
 
    "active-content": ({ ACTIVE, "get_content", ({ }), show }),
172
 
    ]), ]);
173
 
 
174
 
mapping userDetailsXML = ([ CLASS_USER: ([
175
 
    "groups": ({ THIS, "get_groups", ({ }), show }),
176
 
    "access":        ({ CONV, "get_basic_access", ({ THIS }), 0 }),
177
 
    "user":      ({ 0,    this_user,       ({      }), userXML }),
178
 
    "attributes": ({ THIS, "get_attributes", ({ }), ([
179
 
        "attribute": ({ CONV, "show_attribute", ({ ENTRY }),0})
180
 
        ]), })
181
 
    ]) + userXML[CLASS_USER], ]);
182
 
    
183
 
    
184
 
mapping containerXML = ([
185
 
    CLASS_CONTAINER: ([
186
 
        "description":   ({ THIS, "query_attribute", ({ OBJ_DESC }), show }),
187
 
        "inventory": ({ THIS, "get_inventory", ({ }), show_size }),
188
 
        ]),
189
 
    ]);
190
 
        
191
 
 
192
 
mapping mailboxXML = ([ 
193
 
    CLASS_OBJECT: 
194
 
    ([
195
 
        "path":      ({ CONV, "get_path",      ({ THIS }), 0 }),
196
 
        "user":      ({ 0,    this_user,       ({      }), userXML }),
197
 
        ])+objXML[CLASS_OBJECT],
198
 
    CLASS_CONTAINER: 
199
 
    ([
200
 
        "inventory": ({ THIS, "get_inventory", ({      }),
201
 
                            objXML+exitXML+linkXML+userInvXML+containerXML }),
202
 
        ]),
203
 
    ]);
204
 
 
205
 
mapping iconsXML = ([
206
 
    CLASS_OBJECT:
207
 
    ([ "icons": ({ THIS, "get_icons", ({ }), show }),
208
 
       "user":      ({ 0,    this_user,       ({      }), userXML }),
209
 
     ])+objXML[CLASS_OBJECT], ]);
210
 
    
211
 
mapping contentXML = ([ 
212
 
    CLASS_OBJECT: 
213
 
    ([
214
 
        "path":      ({ CONV, "get_path",      ({ THIS }), 0 }),
215
 
        "user":      ({ 0,    this_user,       ({      }), userXML }),
216
 
        ])+objXML[CLASS_OBJECT],
217
 
    CLASS_CONTAINER: 
218
 
    ([
219
 
        "inventory": ({ THIS, "get_inventory", ({      }),
220
 
                            objXML+exitXML+linkXML+userInvXML+containerXML}),
221
 
        ]),
222
 
    ]);
223
 
 
224
 
    
225
 
 
226
 
array(string) __sanction;
227
 
static mapping mXML = ([ ]);
228
 
static mapping mSelection = ([ ]);
229
 
static array(object) selection;
230
 
 
231
 
 
232
 
static mapping entities = ([
233
 
    "�": "&#228;",
234
 
    "�": "&#196;",
235
 
    "�": "&#252;",
236
 
    "�": "&#220;",
237
 
    "�": "&#246;",
238
 
    "�": "&#214;",
239
 
    "<": "&lt;",
240
 
    ">": "&gt;",
241
 
    ]);
242
 
 
243
 
/**
244
 
 * Initialize the module, this function is called when the module is loaded.
245
 
 *  
246
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
247
 
 */
248
 
static void load_module()
249
 
{
250
 
    if ( objectp(_SECURITY) )
251
 
        __sanction = _SECURITY->get_sanction_strings();
252
 
    CONV->obj = this();
253
 
    // if the state of an object changed, we have to update cache !
254
 
}
255
 
 
256
 
string no_uml(string str)
257
 
{
258
 
    return httplib.no_uml(str);
259
 
}
260
 
 
261
 
 
262
 
 
263
 
/**
264
 
 * Exchange some entities to fix the html sources. Especially umlaute.
265
 
 *  
266
 
 * @param string txt - the text where to exchange Umlaute, etc.
267
 
 * @return the replaced text.
268
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
269
 
 * @see 
270
 
 */
271
 
string htmlize(string txt)
272
 
{
273
 
    string html = replace(txt, indices(entities), values(entities));
274
 
    return html;
275
 
}
276
 
 
277
 
/**
278
 
 * Show function to bring a config mapping in xml format.
279
 
 * It will have each configuration listed as config name='config-name'
280
 
 * with the value as container data.
281
 
 *  
282
 
 * @param mapping configs - the configuration mapping to bring to xml.
283
 
 * @return the converted mapping.
284
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
285
 
 */
286
 
string show_configs(mapping configs)
287
 
{
288
 
    string xml = "";
289
 
    foreach(indices(configs), mixed index) {
290
 
        if ( stringp(configs[index]) || intp(configs[index]) )
291
 
            xml += "\t<config name=\""+index+"\">"+configs[index]+"</config>\n";
292
 
    }
293
 
    return xml;
294
 
}
295
 
 
296
 
string show_ports(array ports)
297
 
{
298
 
    string xml = "";
299
 
    foreach(ports, object port) {
300
 
        xml += "<port nr='"+port->get_port()+"'>"+port->describe()+"</port>";
301
 
    }
302
 
    return xml;
303
 
}
304
 
 
305
 
/**
306
 
 * Time function just calls time().
307
 
 *  
308
 
 * @return the current timestamp (unix-time).
309
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
310
 
 */
311
 
int gettime() 
312
 
313
 
    return time(); 
314
 
}
315
 
 
316
 
int cmp_names(object obj1, object obj2)
317
 
{
318
 
  return lower_case(obj1->get_identifier())>lower_case(obj2->get_identifier());
319
 
}
320
 
 
321
 
int cmp_size(object obj1, object obj2)
322
 
{
323
 
  if ( obj1->get_object_class() & CLASS_CONTAINER )
324
 
    return sizeof(obj1->get_inventory()) > sizeof(obj2->get_inventory());
325
 
  return obj1->get_content_size() > obj2->get_content_size();
326
 
}
327
 
 
328
 
int cmp_date(object obj1, object obj2)
329
 
{
330
 
  return get_last_modified(obj1) > 
331
 
     get_last_modified(obj2);
332
 
}
333
 
 
334
 
int cmp_names_rev(object obj1, object obj2)
335
 
{
336
 
  return lower_case(obj1->get_identifier())<lower_case(obj2->get_identifier());
337
 
}
338
 
 
339
 
int cmp_size_rev(object obj1, object obj2)
340
 
{
341
 
  if ( obj1->get_object_class() & CLASS_CONTAINER )
342
 
    return sizeof(obj1->get_inventory()) < sizeof(obj2->get_inventory());
343
 
  return obj1->get_content_size() < obj2->get_content_size();
344
 
}
345
 
 
346
 
int cmp_date_rev(object obj1, object obj2)
347
 
{
348
 
  return  get_last_modified(obj1) <
349
 
     get_last_modified(obj2);
350
 
}
351
 
 
352
 
/**
353
 
 * Get the inventory of a container, parameters have to include
354
 
 * an object range, optionally the container can bhe sorted with
355
 
 * "name", "reverse-name", "size", "reverse-size", "modified" or
356
 
 * "reverse-modified".
357
 
 *  
358
 
 * @param object cont - the container to show
359
 
 * @param int from_obj - the start of the object range
360
 
 * @param int to_obj - the end of the object range.
361
 
 * @param string sort - sort option.
362
 
 * @return (sorted) array of objects
363
 
 */
364
 
array(object) 
365
 
get_cont_inventory(object cont, int from_obj, int to_obj, void|string sort)
366
 
{
367
 
    array(object) inv = cont->get_inventory();
368
 
    array(object) arr = ({ });
369
 
    array(object) obj_arr = ({ });
370
 
    array(object) cont_arr = ({ });
371
 
 
372
 
    foreach( inv, object obj ) {
373
 
        if ( obj->get_object_class() & CLASS_EXIT || 
374
 
             obj->get_object_class() & CLASS_ROOM ||
375
 
             obj->get_object_class() & CLASS_USER )
376
 
            arr += ({ obj });
377
 
        else if ( obj->get_object_class() & CLASS_CONTAINER )
378
 
          cont_arr += ({ obj });
379
 
        else if ( !(obj->get_object_class() & CLASS_DRAWING) )
380
 
          obj_arr += ({ obj });
381
 
    }
382
 
    if ( !stringp(sort) || sort == "none" ) {
383
 
        sort = cont->query_attribute("web:sort:objects");
384
 
        if ( sort == "last-modified/time" )
385
 
            sort = "modified";
386
 
    }
387
 
 
388
 
    // sort the array of objects
389
 
    if ( stringp(sort) ) {
390
 
      switch ( sort ) {
391
 
      case "name":
392
 
        obj_arr = Array.sort_array(obj_arr, cmp_names);
393
 
        cont_arr = Array.sort_array(cont_arr, cmp_names);
394
 
        break;
395
 
      case "size":
396
 
        obj_arr = Array.sort_array(obj_arr, cmp_size);
397
 
        cont_arr = Array.sort_array(cont_arr, cmp_size);
398
 
        break;
399
 
      case "modified":
400
 
        obj_arr = Array.sort_array(obj_arr, cmp_date);
401
 
        cont_arr = Array.sort_array(cont_arr, cmp_date);
402
 
        break;
403
 
      case "reverse-name":
404
 
        obj_arr = Array.sort_array(obj_arr, cmp_names_rev);
405
 
        cont_arr = Array.sort_array(cont_arr, cmp_names_rev);
406
 
        break;
407
 
      case "reverse-size":
408
 
        obj_arr = Array.sort_array(obj_arr, cmp_size_rev);
409
 
        cont_arr = Array.sort_array(cont_arr, cmp_size_rev);
410
 
        break;
411
 
      case "reverse-modified":
412
 
        obj_arr = Array.sort_array(obj_arr, cmp_date_rev);
413
 
        cont_arr = Array.sort_array(cont_arr, cmp_date_rev);
414
 
        break;
415
 
      }
416
 
    }
417
 
    obj_arr = cont_arr + obj_arr;
418
 
    if ( to_obj == 0 ) to_obj = sizeof(obj_arr);
419
 
    
420
 
    return obj_arr[from_obj-1..to_obj-1] + arr;
421
 
}
422
 
 
423
 
string show_inventory_size(object cont)
424
 
{
425
 
    string xml = "";
426
 
    int docs, conts, rooms, exits, sz, users;
427
 
 
428
 
 
429
 
    // fixme: use this function ?
430
 
    array(object) inv = cont->get_inventory();
431
 
    foreach(inv, object o) {
432
 
        if ( o->get_object_class() & CLASS_USER )
433
 
            users++;
434
 
        else if ( o->get_object_class() & CLASS_ROOM )
435
 
            rooms++;
436
 
        else if ( o->get_object_class() & CLASS_EXIT )
437
 
            exits++;
438
 
        else if ( o->get_object_class() & CLASS_CONTAINER )
439
 
            conts++;
440
 
        else if ( o->get_object_class() & CLASS_DOCUMENT )
441
 
            docs++;
442
 
    }
443
 
    return xml;
444
 
}
445
 
 
446
 
/**
447
 
 *
448
 
 *  
449
 
 * @param 
450
 
 * @return 
451
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
452
 
 * @see 
453
 
 */
454
 
int get_last_modified(object obj)
455
 
{
456
 
    if ( obj->get_object_class() & CLASS_DOCUMENT )
457
 
        return obj->query_attribute(DOC_LAST_MODIFIED);
458
 
    else if ( obj->get_object_class() & CLASS_CONTAINER )
459
 
        return obj->query_attribute(CONT_LAST_MODIFIED);
460
 
    else
461
 
        return obj->query_attribute(OBJ_LAST_CHANGED);
462
 
}
463
 
 
464
 
/**
465
 
 * Get the name for an object class. This function queries the factory
466
 
 * of the object to get the name.
467
 
 *  
468
 
 * @param int id - the class id
469
 
 * @return the class-name string
470
 
 * @author Thomas Bopp (astra@upb.de) 
471
 
 */
472
 
string class_id_to_name(int id)
473
 
{
474
 
    if ( id & CLASS_SCRIPT )
475
 
      return "\"Script\"";
476
 
 
477
 
    object factory = _Server->get_factory(id);
478
 
    if ( objectp(factory) ) 
479
 
        return "\""+factory->get_class_name()+"\"";
480
 
    else
481
 
        return "\"Object\"";
482
 
}
483
 
 
484
 
/**
485
 
 * Show extended object information.
486
 
 * <object type='Object'><name/><id/><path/><description/></object>
487
 
 *  
488
 
 * @param object obj - the object to show.
489
 
 * @return extended object information xml code.
490
 
 */
491
 
string show_object_ext(object obj)
492
 
{
493
 
    if ( !objectp(obj) )
494
 
        return "";
495
 
 
496
 
    return "<object type="+class_id_to_name(obj->get_object_class())+
497
 
        "><name><![CDATA["+obj->query_attribute(OBJ_NAME)+"]]></name>"+
498
 
        "<id>"+obj->get_object_id()+"</id><path><![CDATA["+
499
 
      (obj->get_object_class() & CLASS_DOCEXTERN ?
500
 
       obj->query_attribute(DOC_EXTERN_URL):
501
 
        replace_uml(_FILEPATH->object_to_filename(obj)))+
502
 
        "]]></path><description><![CDATA["+
503
 
        obj->query_attribute(OBJ_DESC)+"]]></description></object>";
504
 
}
505
 
 
506
 
 
507
 
string show_objects_ext(array(object) objs)
508
 
{
509
 
    string xml = "<array>";
510
 
    foreach(objs, object obj)
511
 
        xml += show_object_ext(obj);
512
 
    xml += "</array>\n";
513
 
    return xml;
514
 
}
515
 
 
516
 
string show_trail(array(object) trail, int|void sz)
517
 
{
518
 
    array walk = ({ });
519
 
    int i, way;
520
 
 
521
 
    if ( sz == 0 )
522
 
        sz = 4;
523
 
    string xml = "";
524
 
 
525
 
    // try to detect loop in trail, only A,B,A,B
526
 
    way = 0;
527
 
 
528
 
 
529
 
    xml = "<array>";
530
 
    for ( i = sizeof(trail) - 1 - sz; i < sizeof(trail); i++ ) {
531
 
        if ( i < 0 ) continue;
532
 
        xml += show_object_ext(trail[i]);
533
 
    }
534
 
    xml += "</array>";
535
 
        
536
 
    return xml; 
537
 
}
538
 
 
539
 
 
540
 
/**
541
 
 * Show extended information for XSL objects in this converter.
542
 
 *  
543
 
 * @param mixed s - the value to show in xml
544
 
 * @return the value in xml
545
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
546
 
 * @see show
547
 
 */
548
 
string compose_scalar(mixed s)
549
 
{
550
 
    if ( objectp(s) && s->get_object_class() & CLASS_DOCXSL) {
551
 
        return "<object><name>"+s->get_identifier()+"</name>"+
552
 
            "<id>"+s->get_object_id()+"</id><path>"+
553
 
            _FILEPATH->object_to_filename(s)+"</path></object>";
554
 
    }
555
 
    return ::compose_scalar(s);
556
 
}
557
 
 
558
 
/**
559
 
 *
560
 
 *  
561
 
 * @param 
562
 
 * @return 
563
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
564
 
 * @see 
565
 
 */
566
 
array(object) get_filtered_inventory(object obj, mixed key, mixed val)
567
 
{
568
 
    array inv = obj->get_inventory();
569
 
    array res = ({ });
570
 
    foreach ( inv, object o ) {
571
 
        mixed v = o->query_attribute(key);
572
 
        if ( objectp(val) )
573
 
          val = val->this();
574
 
        if ( !v )
575
 
            res += ({ o });
576
 
        else if ( arrayp(v) && !arrayp(val) && search(v,val) >= 0 )
577
 
            res += ({ o });
578
 
        else if ( val == v )
579
 
            res += ({ o });
580
 
    }
581
 
    return res;
582
 
}
583
 
 
584
 
/**
585
 
 * Show an attribute. This is done without the basic conversion to
586
 
 * xml with string|int, because for example the data type of
587
 
 * name or id tags is already known.
588
 
 *  
589
 
 * @param mixed val - the value to convert
590
 
 * @return the converted value
591
 
 */
592
 
string show(string|int|object|mapping|program|array val)
593
 
{
594
 
    DEBUG_XML("show:"+sprintf("%O", val));
595
 
    if ( stringp(val) )
596
 
        return "<![CDATA["+val+"]]>";
597
 
    else if ( intp(val) )
598
 
        return (string)val;
599
 
    else if ( objectp(val) && stringp(val->query_attribute(OBJ_NAME)) &&
600
 
              !xml.utf8_check(val->query_attribute(OBJ_NAME)) )
601
 
      return "<invalid_object_utf8>"+val->get_object_id()+"</invalid_object_utf8>";
602
 
    return compose(val);
603
 
}
604
 
 
605
 
/**
606
 
 * Show xml code for an exit - that is the destination.
607
 
 *  
608
 
 * @param object exit - the exit to show.
609
 
 * @return xml string representation.
610
 
 * @see show
611
 
 */
612
 
string show_exit(object exit)
613
 
614
 
    string p =  _FILEPATH->object_to_filename(exit);
615
 
    if ( p[-1] != '/' )
616
 
        p+="/";
617
 
    p = no_uml(p);
618
 
    return "<object><id>"+exit->get_object_id()+"</id><path>"+p+"</path>"+
619
 
        "<name>"+exit->get_identifier()+"</name></object>\n";
620
 
}
621
 
 
622
 
/**
623
 
 * Gives xml code for the creator of an object.
624
 
 *  
625
 
 * @param object creator - the creator.
626
 
 * @return xml code for creator object.
627
 
 */
628
 
string show_creator(object creator)
629
 
{
630
 
    // show also type
631
 
    return "<object type="+class_id_to_name(creator->get_object_class())+"><id>"+creator->get_object_id()+"</id>"+
632
 
        "<name>"+creator->get_identifier()+"</name></object>\n";
633
 
}
634
 
 
635
 
 
636
 
/**
637
 
 * Show the status status in terms of CLIENT_FEATURES_*
638
 
 *  
639
 
 * @param int status - the status to xmlize.
640
 
 * @return the xml converted status.
641
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
642
 
 */
643
 
string show_status(int status)
644
 
{
645
 
    string xml = "";
646
 
    
647
 
    if ( status & CLIENT_FEATURES_CHAT )
648
 
        xml += "<chat>true</chat>";
649
 
    else
650
 
        xml += "<chat>false</chat>";
651
 
 
652
 
    if ( status & CLIENT_STATUS_CONNECTED )
653
 
        xml += "<connected>true</connected>";
654
 
    else
655
 
        xml += "<connected>false</connected>";
656
 
    return xml;
657
 
}
658
 
 
659
 
/**
660
 
 * Return false for value 0 and otherwise true.
661
 
 *  
662
 
 * @param mixed val - the value for true or false
663
 
 * @return true or false as a string
664
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
665
 
 */
666
 
string show_truefalse(mixed val)
667
 
{
668
 
    if ( val == 0 )
669
 
        return "false";
670
 
    return "true";
671
 
}
672
 
 
673
 
/**
674
 
 * Show the size of an array or the inventory size of an container.
675
 
 * an container ?
676
 
 *  
677
 
 * @param object|array o - the array or container to show its size.
678
 
 * @return size of container or array.
679
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
680
 
 */
681
 
string show_size(object|array o)
682
 
{
683
 
    if ( arrayp(o) )
684
 
        return (string)sizeof(o);
685
 
    else if ( objectp(o) && o->get_object_class() & CLASS_CONTAINER )
686
 
        return (string)sizeof(o->get_inventory());
687
 
    return 0;
688
 
}
689
 
 
690
 
string show_size_unread(object|array o)
691
 
{
692
 
    object trd = _Server->get_module("table:read-documents");
693
 
    if ( arrayp(o) ){
694
 
        int sz = 0;
695
 
        int msgs = 0;
696
 
        foreach(o, object obj) {
697
 
            o += obj->get_annotations();
698
 
            if ( objectp(trd) ) {
699
 
                if ( !trd->is_reader(obj, this_user()) )
700
 
                    sz++;
701
 
            }
702
 
            msgs++;
703
 
        }
704
 
        return"<unread>"+sz+"</unread><messages>"+msgs+"</messages>";
705
 
    }
706
 
    return "<unread>0</unread><messages>0</messages>";
707
 
}
708
 
 
709
 
string show_mailbox_size(object|array o)
710
 
{
711
 
  return show_size_unread(o);
712
 
}
713
 
 
714
 
string show_annotations_size(object o)
715
 
{
716
 
  if ( o->get_object_class() & CLASS_USER )
717
 
    return "<unread>0</unread><messages>0</messages>";
718
 
  return show_size_unread(o->get_annotations());
719
 
}
720
 
 
721
 
 
722
 
/**
723
 
 * Get the permission role for some access bit array or an object.
724
 
 *  
725
 
 * @param int|object access - the access integer or access object
726
 
 * @return string description of the objects access permissions.
727
 
 * @author Thomas Bopp (astra@upb.de) 
728
 
 */
729
 
string get_role(int|object access)
730
 
{
731
 
    if ( objectp(access) )
732
 
        access = LAST->obj->query_sanction(access);
733
 
    
734
 
    if ( (access & SANCTION_ALL)==SANCTION_ALL ) 
735
 
        return "admin";
736
 
    else if ( access & SANCTION_READ && access & SANCTION_WRITE ) 
737
 
        return "author";
738
 
    else if ( (access & SANCTION_READ) && (access & SANCTION_ANNOTATE) )
739
 
        return "reviewer";
740
 
    else if ( access & (SANCTION_READ) ) 
741
 
        return "reader";
742
 
    return "nothing";
743
 
}
744
 
 
745
 
/**
746
 
 * Check the access of an object for a given access bit.
747
 
 *  
748
 
 * @param object obj - the object to check access.
749
 
 * @param object caller - the calling object.
750
 
 * @param int accBit - the access Bit to test.
751
 
 * @return true or false.
752
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
753
 
 */
754
 
bool check_access(object obj, object caller, int accBit)
755
 
{
756
 
    return _SECURITY->check_user_access(obj, caller, accBit, accBit, false);
757
 
}
758
 
 
759
 
/**
760
 
 * Get the time string for a given timestamp 't'.
761
 
 *  
762
 
 * @param int tt - timestamp to get a string description for.
763
 
 * @return string description of timestamp in "month date year/time".
764
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
765
 
 */
766
 
string get_time(int tt)
767
 
{
768
 
    int t = 0;
769
 
    if ( intp(tt) ) t = tt;
770
 
    string ti = ctime(t);
771
 
    string  month, year;
772
 
    string date, hour, minute;
773
 
   
774
 
    if (sscanf(ti,"%*s %s %s %s:%s:%*d %s\n",month,date,hour,minute,year) != 5)
775
 
        sscanf(ti,"%*s %s  %s %s:%s:%*d %s\n", month,date,hour,minute,year);
776
 
    string gettime = month + "/"+ date + "/" + (year[2..3]) + "/" + hour +
777
 
        ":" + minute;
778
 
    return "<date>"+gettime+"</date><time>"+t+"</time>";
779
 
}
780
 
 
781
 
/**
782
 
 * Get the standard ctime output format. <date>ctime(t)</date><time>t</time>.
783
 
 *  
784
 
 * @param int t - the timestamp (unix)
785
 
 */
786
 
string get_ctime(int tt)
787
 
{
788
 
    int t = 0;
789
 
    if ( intp(tt) ) t = tt;
790
 
    return "<date>"+ctime(t)+"</date><time>"+t+"</time>";
791
 
}
792
 
 
793
 
/**
794
 
 * Get the content of an object.
795
 
 *  
796
 
 * @param object obj - the object to get the content for.
797
 
 * @return the content of the object.
798
 
 */
799
 
string
800
 
get_obj_content(object obj)
801
 
{
802
 
    if ( !objectp(obj) )
803
 
        return "";
804
 
    if ( search(obj->query_attribute(DOC_MIME_TYPE), "txt") >= 0 ||
805
 
         search(obj->query_attribute(DOC_MIME_TYPE), "text") >= 0 ) 
806
 
    {
807
 
        string content = obj->get_content();
808
 
        if ( obj->query_attribute(DOC_MIME_TYPE) == "text/plain" )
809
 
            content = text_to_html(content);
810
 
        if ( !stringp(content) )
811
 
            content = "";
812
 
 
813
 
        return "<![CDATA["+string_to_utf8(content)+"]]>";
814
 
    }
815
 
    return "";
816
 
}
817
 
 
818
 
string get_obj_content_detect(object obj)
819
 
{
820
 
  if ( !objectp(obj) )
821
 
    return "";
822
 
  if ( search(obj->query_attribute(DOC_MIME_TYPE), "txt") >= 0 ||
823
 
       search(obj->query_attribute(DOC_MIME_TYPE), "text") >= 0 ) 
824
 
  {
825
 
    string content = obj->get_content();
826
 
    string encoding = obj->query_attribute(DOC_ENCODING);
827
 
    if ( !stringp(encoding) && 
828
 
         search(obj->query_attribute(DOC_MIME_TYPE), "html") >= 0 )
829
 
      encoding = detect_encoding(content);
830
 
 
831
 
    if ( !stringp(content) )
832
 
        content = "";
833
 
 
834
 
    if ( encoding != "utf-8" )
835
 
      return "<![CDATA["+string_to_utf8(content)+"]]>";
836
 
    else
837
 
      return "<![CDATA["+content+"]]>";
838
 
  }
839
 
  return "";
840
 
}
841
 
 
842
 
string
843
 
get_obj_content_raw(object obj)
844
 
{
845
 
    if ( !objectp(obj) )
846
 
        return "";
847
 
    if ( search(obj->query_attribute(DOC_MIME_TYPE), "txt") >= 0 ||
848
 
         search(obj->query_attribute(DOC_MIME_TYPE), "text") >= 0 ) 
849
 
    {
850
 
        string content = obj->get_content();
851
 
        if ( !stringp(content) )
852
 
            content = "";
853
 
        if ( obj->query_attribute(DOC_MIME_TYPE) == "text/plain" )
854
 
            content = text_to_html(content);
855
 
        
856
 
        if ( obj->query_attribute(DOC_ENCODING) == "iso-8859-1" )
857
 
            content = string_to_utf8(content);
858
 
        if ( !xml.utf8_check(content) )
859
 
            content = string_to_utf8(content);
860
 
 
861
 
        return "<![CDATA["+content+"]]>";
862
 
    }
863
 
    return "";
864
 
}
865
 
 
866
 
class xsltTag {
867
 
    object get_object(string o) {
868
 
        if ( (int)o > 0 )
869
 
            return find_object((int)o);
870
 
        else
871
 
            return find_object(o);
872
 
    }
873
 
 
874
 
    string execute(mapping vars) {
875
 
        object obj;
876
 
        object xsl;
877
 
        
878
 
        obj = get_object(vars->args->object);
879
 
        if ( !objectp(obj) )
880
 
            return "<!-- xslt: no object found ("+vars->args->object+")-->";
881
 
        xsl = get_object(vars->args->xsl);
882
 
        if ( !objectp(xsl) )
883
 
            return "<!-- xslt: no xsl Stylesheet found ("+
884
 
                vars->args->xsl+")-->";
885
 
        return run_xml(obj, xsl, vars);
886
 
    }
887
 
 
888
 
    int get_object_class() { return 0; }
889
 
}
890
 
 
891
 
/**
892
 
 * Get the content of a given object and parse all rxml tag
893
 
 * inside the well formed html or text content.
894
 
 *  
895
 
 * @param object obj - the object to get the content for.
896
 
 * @return the resulting code
897
 
 */
898
 
string get_obj_content_rxml(object obj)
899
 
{
900
 
    if ( !objectp(obj) )
901
 
        return "";
902
 
 
903
 
    return "<!-- this function is no longer available !-->";
904
 
 
905
 
    if ( search(obj->query_attribute(DOC_MIME_TYPE), "txt") >= 0 ||
906
 
         search(obj->query_attribute(DOC_MIME_TYPE), "text") >= 0 ) 
907
 
    {
908
 
      string content = obj->get_content();
909
 
      mapping tags = ([ "xslt": xsltTag()->execute, ]);
910
 
      string result;
911
 
      mixed err = catch {
912
 
        result = htmllib.parse_rxml(string_to_utf8(content), 
913
 
                                    XSL->vars, tags, "utf-8");
914
 
      };
915
 
      if ( err != 0 ) {
916
 
        werror("Got error upon get_obj_content_rxml:\n%O", err);
917
 
        result = err[0];
918
 
      }
919
 
      return "<![CDATA["+result+"]]>";
920
 
    }
921
 
    steam_error("Cannot parse rxml in non-text content !");
922
 
}
923
 
 
924
 
 
925
 
/**
926
 
 * Describe the params of an attribute. The function gets the attribute
927
 
 * registration array which is available from the factory.
928
 
 *  
929
 
 * @param array reg - the registered attribute data.
930
 
 * @return string description of the registered type.
931
 
 * @author Thomas Bopp (astra@upb.de) 
932
 
 */
933
 
string describe_params(mixed reg)
934
 
{
935
 
    int type = reg[REGISTERED_TYPE];
936
 
    
937
 
    if ( type == CMD_TYPE_ARRAY )
938
 
        return "array";
939
 
    else if ( type == CMD_TYPE_FLOAT )
940
 
        return "float";
941
 
    else if ( type == CMD_TYPE_MAPPING )
942
 
        return "mapping";
943
 
    else if ( type == CMD_TYPE_STRING )
944
 
        return "string";
945
 
    else if ( type == CMD_TYPE_TIME )
946
 
       return "time";
947
 
    else if ( type == CMD_TYPE_INT )
948
 
        return "int";
949
 
    else if ( type == CMD_TYPE_OBJECT )
950
 
        return "object";
951
 
    return "mixed";
952
 
}
953
 
 
954
 
array 
955
 
_get_annotations_thread(object obj, object user , int d, int|void active_flag)
956
 
{
957
 
    string xml;
958
 
    int   read;
959
 
    
960
 
    if ( !active_flag )
961
 
        active_flag = activeThreadMap[obj];
962
 
 
963
 
    read =(search(
964
 
        _Server->get_module("table:read-documents")->get_readers(obj),
965
 
        user) >= 0 );
966
 
    xml = "<thread>\n"+
967
 
        "<depth>"+d+"</depth>\n"+
968
 
        "<subject><![CDATA["+obj->query_attribute(OBJ_DESC_OR_NAME) +"]]></subject>"+
969
 
        "<accessed>"+obj->query_attribute(DOC_TIMES_READ)+"</accessed>\n"+
970
 
        "<id>"+obj->get_object_id() + "</id>\n"+
971
 
        "<created>"+get_time(obj->query_attribute(OBJ_CREATION_TIME))+"</created>\n"+
972
 
        "<modified>"+get_time(obj->query_attribute(DOC_LAST_MODIFIED))+"</modified>\n"+
973
 
        "<active-thread>"+active_flag+"</active-thread>\n"+
974
 
        "<read>"+read+"</read>\n"+
975
 
        "<author>"+compose_scalar(obj->get_creator())+"</author>\n";
976
 
    
977
 
    array(object) annotations = obj->get_annotations_for(user);
978
 
    if ( arrayp(annotations) ) {
979
 
        foreach(annotations, object ann) {
980
 
            if ( !objectp(ann) ) continue;
981
 
            array res;
982
 
            res = _get_annotations_thread(ann, user, d+1, active_flag);
983
 
            xml += res[0];
984
 
            read = (read || res[1]);
985
 
        }
986
 
    }
987
 
    xml += "<read_thread>"+read+"</read_thread>\n";
988
 
    xml += "</thread>\n";
989
 
    return ({ xml, read });
990
 
}
991
 
 
992
 
/**
993
 
 * Convert an annotation thread into xml. This function is called
994
 
 * recursively. Dont call this function directly, use show_annotations
995
 
 * instead.
996
 
 *  
997
 
 * @param object obj - the current annotation object.
998
 
 * @param object user - the user reading the annotations.
999
 
 * @param int d - the current depth in the thread.
1000
 
 * @return xml string representation of an annotation thread.
1001
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1002
 
 * @see show_annotations
1003
 
 */
1004
 
string 
1005
 
get_annotations_thread(object obj, object user, int d, int|void active_flag)
1006
 
{
1007
 
    return _get_annotations_thread(obj, user, d, active_flag)[0];
1008
 
}
1009
 
 
1010
 
/**
1011
 
 * Recursively insert annotations in the annotation array. This just
1012
 
 * builds an array which is used by show_annotations. The user object
1013
 
 * parameter is used for calling the get_annotations_for() function.
1014
 
 *  
1015
 
 * @param object ann - the current annotation
1016
 
 * @param object user - the user reading the anntotations.
1017
 
 * @return 
1018
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1019
 
 * @see show_annotations
1020
 
 */
1021
 
array(object) insert_annotations(object ann, object user)
1022
 
{
1023
 
    array(object) annotations = ann->get_annotations_for(user);
1024
 
    if ( arrayp(annotations) ) {
1025
 
        foreach ( annotations, object a) {
1026
 
            annotations += insert_annotations(a, user);
1027
 
        }
1028
 
    }
1029
 
    else {
1030
 
        return ({ });
1031
 
    }
1032
 
    return annotations;
1033
 
}
1034
 
 
1035
 
/**
1036
 
 * Bring the given array of annotation objects to XML.
1037
 
 *  
1038
 
 * @param array(object) annotations - array of annotation documents.
1039
 
 * @return xml presentation of the annotations and their sub-annotations.
1040
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1041
 
 * @see insert_annotations
1042
 
 * @see get_annotations_thread
1043
 
 */
1044
 
string show_annotations(array(object) annotations)
1045
 
{
1046
 
    string xml = "";
1047
 
    for ( int i = 0; i < sizeof(annotations); i++ ) {
1048
 
        if ( !objectp(annotations[i]) ) continue;
1049
 
        xml += get_annotations_thread(annotations[i], this_user(), 0);
1050
 
    }
1051
 
    foreach ( annotations, object ann ) {
1052
 
        annotations += insert_annotations(ann, this_user());
1053
 
    }
1054
 
    foreach(annotations, object annotation) {
1055
 
        xml += serialize_xml_object(
1056
 
            annotation, annotationXML, true);
1057
 
    }
1058
 
    return xml;
1059
 
}
1060
 
 
1061
 
/**
1062
 
 *
1063
 
 *  
1064
 
 * @param 
1065
 
 * @return 
1066
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1067
 
 * @see 
1068
 
 */
1069
 
string do_show_attribute(object obj, mixed key, mixed val, mixed attrReg)
1070
 
{
1071
 
    return 
1072
 
        "\t\t\t<locked>"+(obj->is_locked(key) ? "true":"false")+"</locked>\n"+
1073
 
        "\t\t\t<type>"+describe_params(attrReg)+"</type>\n"+
1074
 
        "\t\t\t<key>"+compose(key) + "</key>\n"+
1075
 
        "\t\t\t<acquire>"+describe_acquire(val[1])+ "</acquire>\n"+
1076
 
        "\t\t\t<description>"+attrReg[REGISTERED_DESC]+"</description>\n"+
1077
 
        "\t\t\t<data>"+compose(val[0])+"</data>\n";
1078
 
}
1079
 
 
1080
 
/**
1081
 
 * Show the registered data of an attribute and its value. This is
1082
 
 * used by attributes.xsl.
1083
 
 *  
1084
 
 * @param KEYVALUE k - key/value pair from a mapping.
1085
 
 * @return xml presentation of the attribute data.
1086
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1087
 
 */
1088
 
string show_attribute(KEYVALUE k)
1089
 
{
1090
 
    object obj = THIS->this();
1091
 
    mixed key = k->key;
1092
 
    mixed attrReg = k->val;
1093
 
    mixed val= ({ obj->query_attribute(key), obj->get_acquire_attribute(key) });
1094
 
    return do_show_attribute(obj, key, val, attrReg);
1095
 
}
1096
 
 
1097
 
/**
1098
 
 *
1099
 
 *  
1100
 
 * @param 
1101
 
 * @return 
1102
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1103
 
 * @see 
1104
 
 */
1105
 
string show_attribute_reg(KEYVALUE k)
1106
 
{
1107
 
    object obj = THIS->this();
1108
 
    mixed key = k->key;
1109
 
    mixed attrReg = k->val;
1110
 
    mixed val= obj->get_attribute_default(key);
1111
 
    return do_show_attribute(obj, key, val, attrReg);
1112
 
}
1113
 
 
1114
 
/**
1115
 
 * Show how many objects a user carries.
1116
 
 *  
1117
 
 * @return the size of the current user selection.
1118
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1119
 
 */
1120
 
string show_carry()
1121
 
{
1122
 
    return (string)sizeof(selection);
1123
 
}
1124
 
 
1125
 
/**
1126
 
 * Get the objects this() pointer, or 0 if its an invalid object.
1127
 
 * This checks if there is a valid proxy.
1128
 
 *  
1129
 
 * @param object o - the object.
1130
 
 * @return the proxy of the object
1131
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1132
 
 * @see 
1133
 
 */
1134
 
object get_local_object(object o)
1135
 
{
1136
 
    if ( objectp(o) && objectp(o->this()) )
1137
 
        return o->this();
1138
 
    return 0;
1139
 
}
1140
 
 
1141
 
/**
1142
 
 * Describe a sanction bit array as a number of 'permission' tags.
1143
 
 *  
1144
 
 * @param int saction - the permission bit array.
1145
 
 * @return xml presentation of access permissions.
1146
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1147
 
 */
1148
 
string show_access(int sanction)
1149
 
{
1150
 
    string xml = "";
1151
 
 
1152
 
    int sz = sizeof(__sanction);
1153
 
    for ( int i = 0; i < sz; i++ ) {
1154
 
        if ( __sanction[i] == "free" ) continue;
1155
 
        
1156
 
        if ( sanction & ((1<<i)<<16) )
1157
 
            xml += "\t\t\t<permission type=\""+__sanction[i]+
1158
 
                "\">2</permission>\n";
1159
 
        else if ( sanction & (1<<i) )
1160
 
            xml += "\t\t\t<permission type=\""+__sanction[i]+
1161
 
                "\">1</permission>\n";
1162
 
        else
1163
 
            xml += "\t\t\t<permission type=\""+__sanction[i]+
1164
 
                "\">0</permission>\n";
1165
 
    }
1166
 
    return xml;
1167
 
}
1168
 
 
1169
 
/**
1170
 
 * Get basic access permissions for an object. Checks whether the
1171
 
 * user can read,write,execute and annotate the object and if the
1172
 
 * steam-group is able to read. Finally its checked if also everyone
1173
 
 * can read the object.
1174
 
 *  
1175
 
 * @param objcet obj - the object to check.
1176
 
 * @return the xml access string.
1177
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1178
 
 */
1179
 
string get_basic_access(object obj)
1180
 
{
1181
 
    string xml;
1182
 
 
1183
 
    int access  = _SECURITY->get_user_permissions(obj, this_user(), SANCTION_READ|SANCTION_WRITE|SANCTION_EXECUTE|SANCTION_ANNOTATE|SANCTION_INSERT);
1184
 
    int gaccess = _SECURITY->get_user_permissions(obj, _WORLDUSER, SANCTION_READ|SANCTION_WRITE|SANCTION_EXECUTE|SANCTION_ANNOTATE|SANCTION_INSERT);
1185
 
    int saccess = _SECURITY->get_user_permissions(obj, _STEAMUSER, SANCTION_READ);
1186
 
    if ( obj == this_user() )
1187
 
        access = saccess = SANCTION_ALL;
1188
 
    
1189
 
    xml = "";
1190
 
    if ( gaccess & SANCTION_READ )
1191
 
        xml += "<readable guest=\"true\" user=\"true\" steam=\"true\"/>";
1192
 
    else
1193
 
        xml += "\t<readable guest=\"false\" user=\""+
1194
 
            ((access & SANCTION_READ) ?   "true":"false") + "\" steam=\""+
1195
 
            ((saccess&SANCTION_READ)  ?   "true":"false") + "\" />\n";
1196
 
    if ( gaccess & SANCTION_WRITE )
1197
 
        xml += "<writeable guest=\"true\" user=\"true\" steam=\"true\"/>";
1198
 
    else
1199
 
        xml += "\t<writeable guest=\"false\" user=\""+
1200
 
            ((access&SANCTION_WRITE)  ?   "true":"false") + "\"/>\n";
1201
 
 
1202
 
    if ( gaccess & SANCTION_EXECUTE )
1203
 
        xml += "<executeable guest=\"true\" user=\"true\" steam=\"true\"/>";
1204
 
    else
1205
 
        xml += "\t<executeable guest=\"false\" user=\""+
1206
 
            ((access&SANCTION_EXECUTE)?   "true":"false") + "\"/>\n";
1207
 
    if ( gaccess & SANCTION_ANNOTATE )
1208
 
        xml += "<annotateable guest=\"true\" user=\"true\" steam=\"true\"/>";
1209
 
    else
1210
 
        xml += "\t<annotateable guest=\"false\" user=\""+
1211
 
            ((access&SANCTION_ANNOTATE) ? "true":"false") + "\"/>\n";
1212
 
    if ( gaccess & SANCTION_INSERT )
1213
 
        xml += "<insertable guest=\"true\" user=\"true\" steam=\"true\"/>";
1214
 
    else
1215
 
        xml += "\t<insertable guest=\"false\" user=\""+
1216
 
            ((access&SANCTION_INSERT) ? "true":"false") + "\"/>\n";
1217
 
    return xml;
1218
 
}
1219
 
 
1220
 
/**
1221
 
 * Describe the acquired access of an object.
1222
 
 *  
1223
 
 * @param object obj - the object to describe its acquiring.
1224
 
 * @return xml string about acquired access permission.
1225
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1226
 
 */
1227
 
string get_acquired_access(object obj)
1228
 
{
1229
 
    string   xml = "";
1230
 
    mapping mSanction;
1231
 
    int            sz;
1232
 
 
1233
 
    //DEBUG_XML("get_acquired_access("+obj->get_identifier()+")");
1234
 
    object|function acquire = obj->get_acquire();
1235
 
    
1236
 
    if ( functionp(acquire) )
1237
 
        acquire = acquire();
1238
 
 
1239
 
    while ( acquire != 0  ) {
1240
 
        mSanction = acquire->get_sanction();
1241
 
        foreach(indices(mSanction), object sanctioned) {
1242
 
            if ( !objectp(sanctioned) ) continue;
1243
 
            xml += "\t\t\t<Object "+
1244
 
                "type="+class_id_to_name(sanctioned->get_object_class())+
1245
 
                ">\n";
1246
 
            xml += "\t\t\t\t<from>"+compose(acquire)+"</from>\n";
1247
 
            xml += "\t\t\t\t<id>"+sanctioned->get_object_id() + "</id>\n"+
1248
 
                "\t\t\t\t<name>"+sanctioned->get_identifier()+"</name>\n";
1249
 
            sz = sizeof(__sanction);
1250
 
            for ( int i = 0; i < sz; i++ ) {
1251
 
                if ( __sanction[i] == "free" ) continue;
1252
 
                
1253
 
                if ( mSanction[sanctioned] & ((1<<i)<<16) )
1254
 
                    xml += "\t\t\t\t\t<permission type=\""+__sanction[i]+
1255
 
                        "\">2</permission>\n";
1256
 
                else if ( mSanction[sanctioned] & (1<<i) )
1257
 
                    xml += "\t\t\t\t<permission type=\""+__sanction[i]+
1258
 
                        "\">1</permission>\n";
1259
 
                else
1260
 
                    xml += "\t\t\t\t<permission type=\""+__sanction[i]+
1261
 
                        "\">0</permission>\n";
1262
 
            }
1263
 
            xml +="\t\t\t</Object>\n";
1264
 
        }
1265
 
        acquire = acquire->get_acquire();
1266
 
        if ( functionp(acquire) ) 
1267
 
            acquire = acquire();
1268
 
    }
1269
 
    return xml;
1270
 
}
1271
 
 
1272
 
/**
1273
 
 * Describe the acquire situation of an object.
1274
 
 *  
1275
 
 * @param function|object acquire the acquire setting
1276
 
 * @return xml description of the given function or object.
1277
 
 * @author Thomas Bopp (astra@upb.de) 
1278
 
 */
1279
 
string describe_acquire(function|object|int acquire)
1280
 
{
1281
 
    if ( functionp(acquire) && acquire == THIS->obj->get_environment ) 
1282
 
    {
1283
 
        acquire = acquire();
1284
 
        if ( objectp(acquire) ) 
1285
 
            return "<function><name>get_environment</name><id>"+
1286
 
                acquire->get_object_id()+ "</id></function>\n";
1287
 
    }
1288
 
    else if ( intp(acquire) && acquire == REG_ACQ_ENVIRONMENT )
1289
 
        return "<function><name>get_environment</name></function>";
1290
 
    else if ( objectp(acquire) )
1291
 
        return compose_scalar(acquire);
1292
 
    return "<object><name/><id>0</id></object>";
1293
 
}
1294
 
 
1295
 
/**
1296
 
 * Serialize an XML tag with serialization data 'data'.
1297
 
 *  
1298
 
 * @param string tag - the name of the tag to serialize.
1299
 
 * @param array data - the data for the tag.
1300
 
 * @return tag and data in XML.
1301
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1302
 
 */
1303
 
string serialize_xml_tag(string tag, array data)
1304
 
{
1305
 
    function   f;
1306
 
    object     o;
1307
 
    mixed      v;
1308
 
    array params;
1309
 
    
1310
 
    DEBUG_XML("<"+tag+">");
1311
 
 
1312
 
    string xml = "<"+tag+">";
1313
 
 
1314
 
    if ( !arrayp(data) )
1315
 
      return xml + "</"+tag+">";
1316
 
 
1317
 
    if ( functionp(data[ID_FUNC]) ) {
1318
 
        f = data[ID_FUNC];
1319
 
    }
1320
 
    else {
1321
 
        o = get_local_object(data[ID_OBJECT]);
1322
 
        if ( objectp(o) )
1323
 
            f = o->find_function(data[ID_FUNC]);
1324
 
    }
1325
 
 
1326
 
    params = ({ });
1327
 
    for ( int i = 0; i < sizeof(data[ID_PARAMS]); i++ ) {
1328
 
        if ( objectp(data[ID_PARAMS][i]) ) 
1329
 
            params += ({ data[ID_PARAMS][i]->this() });
1330
 
        else
1331
 
            params += ({ data[ID_PARAMS][i] });
1332
 
    }       
1333
 
 
1334
 
    mixed err;
1335
 
 
1336
 
    if ( functionp(f) ) {
1337
 
        err = catch {
1338
 
            v = f(@params);
1339
 
        };
1340
 
    }
1341
 
    else
1342
 
        v = -1;
1343
 
 
1344
 
    if ( functionp(data[ID_CONV]) ) {
1345
 
        err = catch {
1346
 
            xml += data[ID_CONV](v);
1347
 
        };
1348
 
        if ( err != 0 ) {
1349
 
            FATAL("While serializing XML:\n"+err[0]+
1350
 
                sprintf("%O", err[1]));
1351
 
        }
1352
 
    }
1353
 
    else if ( mappingp(data[ID_CONV]) ) 
1354
 
    {
1355
 
        if ( arrayp(v) ) {
1356
 
            foreach( v, object obj) {
1357
 
                if ( data[ID_CONV]->name == "none" )
1358
 
                    xml += serialize_xml_object(obj, data[ID_CONV], false);
1359
 
                else
1360
 
                    xml += serialize_xml_object(obj, data[ID_CONV], true);
1361
 
            }
1362
 
        }
1363
 
        else if ( mappingp(v) ) {
1364
 
            foreach( indices(v), mixed ind ) {
1365
 
                ENTRY->key = ind;
1366
 
                ENTRY->val = v[ind];
1367
 
                if ( objectp(ind) && intp(data[ID_CONV][0]) ) {
1368
 
                  LAST->obj = THIS->obj;
1369
 
                  if ( data[ID_CONV]->name == "none" )
1370
 
                    xml += serialize_xml_object(ind, data[ID_CONV], false);
1371
 
                  else
1372
 
                    xml += serialize_xml_object(ind, data[ID_CONV], true);
1373
 
                  
1374
 
                }
1375
 
                else {
1376
 
                    foreach(indices(data[ID_CONV]), mixed idx) {
1377
 
                        xml += serialize_xml_tag(idx, data[ID_CONV][idx]);
1378
 
                    }
1379
 
                }
1380
 
            }
1381
 
        }
1382
 
        else if ( objectp(v) ) {
1383
 
            LAST->obj = THIS->obj;
1384
 
            xml += serialize_xml_object(v, data[ID_CONV], false);
1385
 
        }
1386
 
    }
1387
 
    else if ( objectp(v) ) {
1388
 
        xml += compose(v);
1389
 
    }
1390
 
    else if ( stringp(v) || intp(v) )
1391
 
        xml += v;
1392
 
    
1393
 
    xml += "</"+tag+">\n";
1394
 
    DEBUG_XML("</"+tag+">");
1395
 
    return xml;
1396
 
    
1397
 
}
1398
 
 
1399
 
/**
1400
 
 * Serialize an object to XML using the xml description mapping 'mXML'.
1401
 
 * The mapping defines what the xml code for the object should look like.
1402
 
 *  
1403
 
 * @param object obj - the object to serialize.
1404
 
 * @param mapping mXML - xml description mapping.
1405
 
 * @return xml code for object 'obj'.
1406
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1407
 
 * @see serialize_xml_tag
1408
 
 */
1409
 
string 
1410
 
serialize_xml_object(object obj, mapping mXML, bool|void obj_tag )
1411
 
{
1412
 
    object xml = String.Buffer();
1413
 
    
1414
 
    if ( !objectp(obj) )
1415
 
        return "<!-- Null Object cannot be serialized -->";
1416
 
    
1417
 
    if ( !mappingp(mXML) )
1418
 
        return "";
1419
 
 
1420
 
    if (obj->status()<PSTAT_DISK) // broken instance already loaded
1421
 
        return "<!-- Unable to load broken instance from DB -->";
1422
 
 
1423
 
    if (!functionp(obj->this))    // broken instance on first load
1424
 
        return "";
1425
 
 
1426
 
    THIS->obj = obj->this();
1427
 
    ENV->obj  = obj->get_environment();
1428
 
    
1429
 
    DEBUG_XML("serialize_xml_object(THIS="+THIS->obj->get_identifier()+",LAST="+
1430
 
                (objectp(LAST->obj) ? LAST->obj->get_identifier():"NULL")+")");
1431
 
 
1432
 
    string tagname = mXML->name;
1433
 
    if ( !stringp(tagname) ) 
1434
 
        tagname = "Object";
1435
 
    if ( obj_tag )
1436
 
        xml->add("<"+tagname+" type="+
1437
 
                 class_id_to_name(obj->get_object_class())+
1438
 
                 (mSelection[obj] ? 
1439
 
                  " selected=\"true\"":" selected=\"false\"")+
1440
 
                 ">");
1441
 
 
1442
 
    for ( int i = 31; i >= 0; i-- ) {
1443
 
        int idx = (1<<i);
1444
 
        if ( (idx & obj->get_object_class()) && mappingp(mXML[idx]) ) 
1445
 
        {
1446
 
            foreach(indices(mXML[idx]), string tag) {
1447
 
                THIS->obj = obj->this();
1448
 
                xml->add(serialize_xml_tag(tag, mXML[idx][tag]));
1449
 
            }
1450
 
        }
1451
 
    }
1452
 
    if ( obj_tag ) 
1453
 
        xml->add("</"+tagname+">\n");
1454
 
    return xml->get();
1455
 
}
1456
 
 
1457
 
/**
1458
 
 * Show the content description of an object 'p'. For Documents it
1459
 
 * will list the size and the mime-type. For Containers it lists the
1460
 
 * html:index atribute for the containers index file.
1461
 
 *  
1462
 
 * @param object p - the content object
1463
 
 * @return content description for the object.
1464
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1465
 
 */
1466
 
string show_content(object p)
1467
 
{
1468
 
    if ( p->get_object_class() & CLASS_DOCUMENT )
1469
 
        return "<size>"+p->get_content_size()+"</size>"+
1470
 
            "<mime-type>"+p->query_attribute(DOC_MIME_TYPE) + "</mime-type>";
1471
 
    if ( p->get_object_class() & CLASS_CONTAINER ) 
1472
 
        return "<index>"+p->query_attribute("html:index") + "</index>";
1473
 
    return "";
1474
 
}
1475
 
 
1476
 
 
1477
 
/**
1478
 
 * show a simple mapping in compact form
1479
 
 * each key is a tag, and the value its content
1480
 
 *  
1481
 
 * @param mapping of strings
1482
 
 * @return xml form of the mapping
1483
 
 * @author Martin B�hr
1484
 
 */
1485
 
string show_mapping(mapping(string:string) data)
1486
 
{
1487
 
  string xml="";
1488
 
  if(mappingp(data))
1489
 
    foreach(data; string key; string value)
1490
 
      foreach(value/"\0";; string part)
1491
 
        xml += sprintf("<%s><![CDATA[%s]]></%s>\n", key, part, key);
1492
 
  return xml;
1493
 
}
1494
 
 
1495
 
/**
1496
 
 * Get a path as a series of object tags in XML.
1497
 
 *  
1498
 
 * @param object p - the object to get the path for.
1499
 
 * @return xml path description for the object.
1500
 
 * @author <a href="mailto:astra@upb.de">Thomas Bopp</a>) 
1501
 
 */
1502
 
string get_path(object p)
1503
 
{
1504
 
    object xml = String.Buffer();
1505
 
    
1506
 
    array(object|string) paths = ({ });
1507
 
    string path = "";
1508
 
    string s;
1509
 
    while ( p != null ) {
1510
 
        if ( stringp(s=_FILEPATH->check_tilde(p)) ) {
1511
 
            paths = ({ p, s }) + paths;
1512
 
            p = null;
1513
 
        }
1514
 
        else {
1515
 
            paths = ({ p, p->get_identifier() }) + paths;
1516
 
            p = p->get_environment();
1517
 
        }
1518
 
    }
1519
 
    for ( int i = 0; i < sizeof(paths)-2; i+=2 ) {
1520
 
        xml->add("<object><id>");
1521
 
        xml->add((string)paths[i]->get_object_id());
1522
 
        xml->add("</id><name><![CDATA[");
1523
 
        xml->add(paths[i+1]);
1524
 
        xml->add("]]></name>");
1525
 
        path += paths[i+1] + "/";
1526
 
        xml->add("<path>"+no_uml(path)+"</path></object>");
1527
 
    }
1528
 
    if ( paths[-2]->get_object_class() & CLASS_CONTAINER )
1529
 
        path += paths[-1] + "/";
1530
 
    else
1531
 
        path += paths[-1];
1532
 
 
1533
 
    xml += "<path>"+no_uml(path)+"</path>\n";
1534
 
    return xml->get();
1535
 
}
1536
 
 
1537
 
/**
1538
 
 * Get a path as a series of object tags in XML.
1539
 
 *
1540
 
 * XML Description of returned value
1541
 
 * <!Element path (object*)>               <!-- sequence of objects in path -->
1542
 
 * <!Element object (name, description, relpath)>      <!-- data per object -->
1543
 
 * <!Element name (#cdata)>                         <!-- attribute OBJ_NAME -->
1544
 
 * <!Element description (#cdata)>                  <!-- attribute OBJ_DESC -->
1545
 
 * <!Element relpath (#cdata)>               <!-- relative path to object p -->
1546
 
 *
1547
 
 * @param object p - the object to get the path for.
1548
 
 * @return xml path description for the object.
1549
 
 * @author <a href="mailto:balduin@upb.de">Ludger Merkens</a>)
1550
 
 */
1551
 
string get_rel_path(object p, void|int fsname)
1552
 
{
1553
 
    object xml = String.Buffer();
1554
 
 
1555
 
    array(object|string) paths = ({ });
1556
 
    string path = "";
1557
 
    string s;
1558
 
    while ( p != null ) {
1559
 
        if ( stringp(s=_FILEPATH->check_tilde(p)) ) {
1560
 
            paths = ({ p, s }) + paths;
1561
 
            p = null;
1562
 
        }
1563
 
        else {
1564
 
            paths = ({ p,
1565
 
                       (fsname ?
1566
 
                        p->query_attribute("fs_name") : p->get_identifier())
1567
 
            }) + paths;
1568
 
            p = p->get_environment();
1569
 
        }
1570
 
    }
1571
 
    for ( int i = 0; i < sizeof(paths)-2; i+=2 ) {
1572
 
        xml->add("<object><id>");
1573
 
        xml->add((string)paths[i]->get_object_id());
1574
 
        xml->add("</id><name><![CDATA[");
1575
 
        xml->add(paths[i+1]);
1576
 
        xml->add("]]></name><description><![CDATA[");
1577
 
        xml->add(paths[i]->query_attribute(OBJ_DESC));
1578
 
        xml->add("]]></description><relpath>");
1579
 
        xml->add("../"*((sizeof(paths)-i)/2)+paths[i+1]);
1580
 
        xml->add("</relpath></object>");
1581
 
        path += paths[i+1] + "/";
1582
 
    }
1583
 
    if ( paths[-2]->get_object_class() & CLASS_CONTAINER )
1584
 
        path += paths[-1] + "/";
1585
 
    else
1586
 
        path += paths[-1];
1587
 
 
1588
 
    xml += "<path>"+no_uml(path)+"</path>\n";
1589
 
    return xml->get();
1590
 
}
1591
 
 
1592
 
/**
1593
 
 * Get the neighbours of an object.
1594
 
 * This function returns a XML part containing the left and right neighbours of
1595
 
 * the object. The optional argument filterclass allows to find the neighbours
1596
 
 * of the same objectclass only. (previous/next image, container)
1597
 
 *
1598
 
 * XML Description of returned value
1599
 
 * <!Element left (object*)>                  <!-- left neighbour -->
1600
 
 * <!Element right (object*)>                 <!-- right neighbour -->
1601
 
 * <!Element object (id, name, description)>  <!-- information per object -->
1602
 
 * <!Element id (#cdata)>                     <!-- decimal object id -->
1603
 
 * <!Element name (#cdata)>                   <!-- attribute OBJ_NAME -->
1604
 
 * <!Element description (#cdata)>            <!-- attribute OBJ_DESC -->
1605
 
 *
1606
 
 * @param object o - The object to calculate the neighbours for.
1607
 
 * @param void|int filterclass - (bool)
1608
 
 * @caveats This function doesn't regard the currently active sorting option of
1609
 
 *          the user but uses unsorted inventory always.
1610
 
 *
1611
 
 * @author <a href="mailto:balduin@upb.de">Ludger Merkens</a>)
1612
 
 */
1613
 
string get_neighbours(object p, void|int filterclass, void|int fsname)
1614
 
{
1615
 
    DEBUG_XML(sprintf("get_neighbours %O, %d\n", p, filterclass));
1616
 
    object env = p->get_environment();
1617
 
    array(object) inv;
1618
 
    if (!filterclass)
1619
 
        inv = env->get_inventory();
1620
 
    else
1621
 
    {
1622
 
        inv = env->get_inventory_by_class(p->get_object_class());
1623
 
        DEBUG_XML(sprintf("inv is %O\n", inv));
1624
 
    }
1625
 
    int i = search(inv, p);
1626
 
    object xml = String.Buffer();
1627
 
 
1628
 
    object left, right;
1629
 
    if (i>0) left = inv[i-1];
1630
 
    if ((i!=-1) && (i<sizeof(inv)-1)) right = inv[i+1];
1631
 
 
1632
 
    xml->add("<left>");
1633
 
    if (objectp(left))
1634
 
    {
1635
 
        xml->add("<object><id>");
1636
 
        xml->add((string)left->get_object_id());
1637
 
        xml->add("</id><name><![CDATA[");
1638
 
        xml->add((string)left->get_identifier());
1639
 
        xml->add("]]></name>");
1640
 
        if (fsname)
1641
 
        {
1642
 
            xml->add("<fsname>");
1643
 
            xml->add((string)left->query_attribute("fs_name"));
1644
 
            xml->add("</fsname>");
1645
 
        }
1646
 
        xml->add("<description><![CDATA[");
1647
 
        xml->add(left->query_attribute(OBJ_DESC));
1648
 
        xml->add("]]></description></object>");
1649
 
    }
1650
 
    xml->add("</left><right>");
1651
 
    if (objectp(right))
1652
 
    {
1653
 
        xml->add("<object><id>");
1654
 
        xml->add((string)right->get_object_id());
1655
 
        xml->add("</id><name><![CDATA[");
1656
 
        xml->add((string)right->get_identifier());
1657
 
        xml->add("]]></name>");
1658
 
        if (fsname)
1659
 
        {
1660
 
            xml->add("<fsname>");
1661
 
            xml->add((string)right->query_attribute("fs_name"));
1662
 
            xml->add("</fsname>");
1663
 
        }
1664
 
        xml->add("<description><![CDATA[");
1665
 
        xml->add(right->query_attribute(OBJ_DESC));
1666
 
        xml->add("]]></description></object>");
1667
 
    }
1668
 
    xml->add("</right>");
1669
 
 
1670
 
    return xml->get();
1671
 
}
1672
 
 
1673
 
private
1674
 
void xml_describe(object node, int selected, int depth, string url,
1675
 
                  String.Buffer xml)
1676
 
{
1677
 
    string fsname;
1678
 
    object o = node->get_object();
1679
 
    function qa = o->query_attribute;
1680
 
    
1681
 
    xml->add("<id>");
1682
 
    xml->add((string)o->get_object_id());
1683
 
    xml->add("</id>\n<name><![CDATA[");
1684
 
    xml->add((string)o->get_identifier());
1685
 
    xml->add("]]></name>\n");
1686
 
    if (fsname = qa("fs_name"))
1687
 
    {
1688
 
        xml->add("<fsname>");
1689
 
        xml->add(fsname);
1690
 
        xml->add("</fsname>\n");
1691
 
    }
1692
 
    xml->add("<description><![CDATA[");
1693
 
    xml->add(qa(OBJ_DESC));
1694
 
    xml->add("]]></description>\n<selected>");
1695
 
    if (selected)
1696
 
        xml->add("yes");
1697
 
    else
1698
 
        xml->add("no");
1699
 
    xml->add("</selected>\n<depth>");
1700
 
    xml->add((string)depth);
1701
 
    xml->add("</depth>\n<url><![CDATA[");
1702
 
    xml->add(url+"/");
1703
 
    xml->add("]]></url>\n");
1704
 
}
1705
 
 
1706
 
private
1707
 
void xml_recurse(object root, int depth, int level, string url, int filter,
1708
 
                 String.Buffer xml)
1709
 
{
1710
 
    xml->add("<object>\n");
1711
 
    xml_describe(root, 0, level, url, xml);
1712
 
    array(object) inv = root->get_inventory_by_class(filter);
1713
 
    foreach(inv, object node)
1714
 
    {
1715
 
        if (depth==0) {
1716
 
            xml->add("<object>\n");
1717
 
            xml_describe(node, 0, level,
1718
 
                         url + "/" + root->query_attribute(OBJ_NAME),
1719
 
                         xml);
1720
 
            xml->add("</object>\n");
1721
 
        }
1722
 
        else
1723
 
            xml_recurse(node, depth-1, level+1,
1724
 
                        url + "/" + root->query_attribute(OBJ_NAME),
1725
 
                        filter, xml);
1726
 
    }
1727
 
    xml->add("</object>\n");
1728
 
}
1729
 
 
1730
 
private
1731
 
void xml_subtree(array(object) path, String.Buffer xml,
1732
 
                 int depth, int level, string url, int filter)
1733
 
{
1734
 
    object root = path[0];
1735
 
    path = path[1..];
1736
 
 
1737
 
    xml->add("<object>\n");
1738
 
    xml_describe(root, 1, level, url, xml);
1739
 
 
1740
 
    object nextnode = sizeof(path) ? path[0] : 0;
1741
 
    array(object) inv = root->get_inventory_by_class(filter);
1742
 
    foreach(inv, object node)
1743
 
    {
1744
 
        if (node == nextnode)
1745
 
            xml_subtree(path, xml, depth-1, level+1,
1746
 
                        url+"/"+node->query_attribute(OBJ_NAME), filter);
1747
 
        else
1748
 
            if (depth==0) {
1749
 
                xml->add("<object>\n");
1750
 
                xml_describe(node, 0, level+1,
1751
 
                             url + "/" + node->query_attribute(OBJ_NAME),
1752
 
                             xml);
1753
 
                xml->add("</object>\n");
1754
 
            }
1755
 
            else
1756
 
                xml_recurse(node, depth-1 , level+1,
1757
 
                            url + "/" + node->query_attribute(OBJ_NAME),
1758
 
                            filter, xml);
1759
 
    }
1760
 
    xml->add("</object>\n");
1761
 
}
1762
 
 
1763
 
string get_rel_tree(object root, object leaf, int depth, int filter)
1764
 
{
1765
 
    array(object) path = ({ leaf });
1766
 
 
1767
 
    object node = leaf;
1768
 
    while (node && node!=root)
1769
 
    {
1770
 
        node = node->get_environment();
1771
 
        if (node)
1772
 
            path = ({ node }) + path;
1773
 
    }
1774
 
    if (node != root)
1775
 
        return "<relpath></relpath>";
1776
 
 
1777
 
    object xml = String.Buffer();
1778
 
    xml_subtree(path, xml, depth, 0, "", filter);
1779
 
    return xml->get();
1780
 
}
1781
 
 
1782
 
 
1783
 
 
1784
 
/**
1785
 
 * Get the public path of an object.
1786
 
 * This calculation uses the public "url" of its closest published parent and
1787
 
 * combines this with the relative path from this object to its published parent.
1788
 
 *
1789
 
 * @param object o - The object to get the path for.
1790
 
 * @return  (string) The public path of the object
1791
 
 * @author <a href="mailto:balduin@upb.de">Ludger Merkens</a>)
1792
 
 */
1793
 
string get_public_name(object o)
1794
 
{
1795
 
    string sPublicRoot;
1796
 
    string sPublicPath;
1797
 
    object x = o;
1798
 
 
1799
 
    sPublicPath = o->get_identifier();
1800
 
    while ((x=x->get_environment()) && !(sPublicRoot = x->query_attribute("url")))
1801
 
    {
1802
 
        if (objectp(x))
1803
 
            sPublicPath = x->get_identifier() + "/" + sPublicPath;
1804
 
    }
1805
 
 
1806
 
    if (sPublicRoot)
1807
 
        return combine_path(sPublicRoot, sPublicPath);
1808
 
 
1809
 
    return 0;
1810
 
}
1811
 
 
1812
 
 
1813
 
/**
1814
 
 * Get the XML representation of this object. To speed up things, the
1815
 
 * type selects which part of the data should be xmlified.
1816
 
 *  
1817
 
 * @param obj - the object to convert
1818
 
 * @param type - the type of the object
1819
 
 * @return the xml data
1820
 
 * @author Thomas Bopp (astra@upb.de) 
1821
 
 */
1822
 
string get_xml(object obj, object xsl, void|mapping vars, mixed|void active)
1823
 
{
1824
 
    object    xml = String.Buffer(32468);
1825
 
    int                                i;
1826
 
    array(object)                    inv;
1827
 
    object                          user;
1828
 
    mixed                            err;
1829
 
 
1830
 
 
1831
 
    if ( mappingp(vars) && vars->this_user > 0 )
1832
 
      user = find_object(vars->this_user);
1833
 
    else 
1834
 
      user = this_user();
1835
 
 
1836
 
    if ( !objectp(user) )
1837
 
      user = CALLER;
1838
 
 
1839
 
    object pike = xsl->query_attribute(DOC_XSL_PIKE);
1840
 
    if ( objectp(xsl) && objectp(pike) ) {
1841
 
        string res;
1842
 
 
1843
 
        object inst = pike->get_instance();
1844
 
        if ( objectp(inst) ) {
1845
 
            err = catch(res=inst->xmlify(obj, vars));
1846
 
            if ( err ) {
1847
 
              mixed errerr = catch {
1848
 
                array lines = pike->get_content() / "\n";
1849
 
                int line;
1850
 
                string func;
1851
 
                string outp = sprintf("%O", err[1][-1]);
1852
 
                sscanf(outp, "%*s.pike:%d, %s,%*s", line, func);
1853
 
                err[0] += (lines[line-3..line+3]*"\n");
1854
 
              };
1855
 
              if ( errerr ) {
1856
 
                FATAL("Error modifying error in xml_converter.pike: %O",
1857
 
                      errerr);
1858
 
              }
1859
 
 
1860
 
              throw(err);
1861
 
            }
1862
 
            return res;
1863
 
        }
1864
 
    }
1865
 
   
1866
 
 
1867
 
    selection = user->query_attribute(USER_SELECTION);
1868
 
    if ( !arrayp(selection) ) 
1869
 
        selection = ({ });
1870
 
    mSelection = mkmapping(selection, selection);
1871
 
 
1872
 
   
1873
 
   
1874
 
 
1875
 
    mapping mXML = 
1876
 
        ([ CLASS_OBJECT: 
1877
 
         ([
1878
 
             "path":      ({ CONV, "get_path",      ({ THIS }), 0 }),
1879
 
             "user":      ({ 0,    this_user,       ({      }), userXML }),
1880
 
             ])+objXML[CLASS_OBJECT],
1881
 
         CLASS_CONTAINER: 
1882
 
         ([
1883
 
             "inventory": ({ THIS, "get_inventory", ({      }),
1884
 
                                objXML+exitXML+linkXML+userXML+containerXML}),
1885
 
             ]),
1886
 
         ]);
1887
 
    
1888
 
    if ( objectp(xsl) && mappingp(xsl->get_xml_structure()) ) {
1889
 
        mXML = xsl->get_xml_structure();
1890
 
        if ( equal(mXML, ([ ])) ) {
1891
 
            xsl->load_xml_structure();
1892
 
            mXML = xsl->get_xml_structure();
1893
 
        }
1894
 
    }
1895
 
    if ( equal(mXML, ([ ])) ) 
1896
 
        THROW("No XML Description found for Stylesheet !", E_ERROR);
1897
 
    
1898
 
    THIS_USER->obj = user;
1899
 
    CONV->obj = this();
1900
 
    LAST->obj = obj;
1901
 
    XSL->obj = xsl;
1902
 
 
1903
 
    if (!mappingp(vars))
1904
 
        vars = ([]);
1905
 
    XSL->vars = vars;
1906
 
 
1907
 
    
1908
 
    foreach(indices(params), string p) {
1909
 
        if ( vars[p] ) {
1910
 
            int d;
1911
 
            sscanf(vars[p], "%d", d);
1912
 
            if ( (string)d == vars[p] ) {
1913
 
              if ( objectp(params[p]->val) )
1914
 
                params[p]->val = find_object(d);
1915
 
              else
1916
 
                params[p]->val = d;
1917
 
            }
1918
 
            else
1919
 
                params[p]->val = vars[p];
1920
 
        }
1921
 
        else
1922
 
            params[p]->val = params[p]->def;
1923
 
    }
1924
 
        
1925
 
 
1926
 
    if ( intp(active) && active > 0 ) {
1927
 
        ACTIVE->obj = find_object(active);
1928
 
    }
1929
 
    else {
1930
 
        if ( vars->type == "annotations" ||
1931
 
            obj->get_object_class() & CLASS_MESSAGEBOARD )
1932
 
        {
1933
 
            object from_obj = get_var("from_obj", 1);
1934
 
            array annotations = obj->get_annotations_for(
1935
 
                this_user(),
1936
 
                (int)get_var("from_obj", 1)->val,
1937
 
                (int)get_var("to_obj", 20)->val);
1938
 
            if ( sizeof(annotations) > 0 )
1939
 
                ACTIVE->obj = annotations[0];
1940
 
        }
1941
 
            
1942
 
    }
1943
 
    if ( objectp(ACTIVE->obj) ) {
1944
 
        activeThreadMap = ([ ACTIVE->obj: 1, ]);
1945
 
        object ann = ACTIVE->obj->get_annotating();
1946
 
        while ( objectp(ann) ) {
1947
 
            activeThreadMap[ann] = 1;
1948
 
            ann = ann->get_annotating();
1949
 
        }
1950
 
    }
1951
 
 
1952
 
    DEBUG_XML("XML:Convertor - Using\n"+sprintf("%O", mXML));
1953
 
    
1954
 
    xml->add(  "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1955
 
    xml->add(  serialize_xml_object(obj, mXML, true) );
1956
 
 
1957
 
    string result = xml->get();
1958
 
    return result;
1959
 
}
1960
 
 
1961
 
bool check_swap() { return false; }
1962
 
string get_identifier() { return "Converter:XML"; }
1963
 
function find_function(string f) { return this_object()[f]; }
1964
 
 
1965
 
object get_var(string name, mixed val)
1966
 
{
1967
 
    object param = params[name];
1968
 
    if ( !objectp(param) ) {
1969
 
        param = Param();
1970
 
        int v;
1971
 
        if ( !stringp(val) ) {
1972
 
          param->val = val;
1973
 
          param->def = val;
1974
 
        }
1975
 
        else {
1976
 
          sscanf(val, "%d", v);
1977
 
          if ( (string)v == val ) {
1978
 
            param->val = v;
1979
 
            param->def = v;
1980
 
          }
1981
 
          else {
1982
 
            param->val = val;
1983
 
            param->def = val;
1984
 
          }
1985
 
        }
1986
 
        param->name = name;
1987
 
        params[name] = param;
1988
 
    }
1989
 
    return param;
1990
 
}
1991
 
 
1992
 
mixed test()
1993
 
{
1994
 
    // try images folder...
1995
 
    object images = find_object("/images");
1996
 
    if ( !objectp(images) )
1997
 
        return 0;
1998
 
 
1999
 
    array inv;
2000
 
 
2001
 
    inv = get_cont_inventory(images, 1, 15);
2002
 
    if ( sizeof(inv) != 15 ) // no rooms in image container
2003
 
        error("Test failed - from 1 to 15 are not 15 objects");
2004
 
    int containers = 1;
2005
 
    foreach(inv, object obj) {
2006
 
        if ( !(obj->get_object_class() & CLASS_CONTAINER) )
2007
 
            containers = 0;
2008
 
        if ( !containers && obj->get_object_class() & CLASS_CONTAINER )
2009
 
            error("Containers not correctly sorted");
2010
 
    } 
2011
 
    
2012
 
    object rxml = get_factory(CLASS_DOCUMENT)->execute(
2013
 
        ([ "name": "rxml.html", ]));
2014
 
    rxml->set_content("<html><body><xslt object='/home/sTeam/bugs' "+
2015
 
                      "xsl='/stylesheets/annotations.xsl'/></body></html>");
2016
 
    XSL->vars = ([ "__internal": ([ ]), ]);
2017
 
    return get_obj_content_rxml(rxml);
2018
 
}
2019
 
 
2020