/[cvs]/nfo/php/libs/org.netfrag.app/WebExplorer/AbstractExplorer.php
ViewVC logotype

Contents of /nfo/php/libs/org.netfrag.app/WebExplorer/AbstractExplorer.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (show annotations)
Sat Apr 19 16:24:49 2003 UTC (21 years, 4 months ago) by jonen
Branch: MAIN
Changes since 1.19: +23 -7 lines
+ added two more GUI modules to default registry initiation,
   relating to new navigation module 'NavigationTree'
+ added prepartion of needed args for abstract navigation tree
   and concret UserManagment 'UMnav' tree

1 <?
2 /*
3 ## -----------------------------------------------------------------------------
4 ## $Id: AbstractExplorer.php,v 1.19 2003/04/18 16:21:37 joko Exp $
5 ## -----------------------------------------------------------------------------
6 ## $Log: AbstractExplorer.php,v $
7 ## Revision 1.19 2003/04/18 16:21:37 joko
8 ## fixed commit comment - the last one caused a syntax error!!!
9 ##
10 ## Revision 1.18 2003/04/18 15:27:06 joko
11 ## NEW: XML Trees in data area
12 ## new ecom module: DataTree
13 ## introduced new query argument: 'filter' (purpose: xml/tree filtering)
14 ## $filter = array(
15 ## dotted => $val['ecom_data_filter'],
16 ## ident => $val['ecom_data_ident'],
17 ## );
18 ## A Data::Lift module translates this filter-query into a XPath-query ...
19 ## $filter = array(
20 ## xpq => '*\/*[@name="cli"]',
21 ## );
22 ## ... which finally is propagated to the backend.
23 ## NEW: AbstractExplorer - standalone version
24 ## enhanced set_e_state: now can overwrite internal state to arguments from outside
25 ## enhanced get_com: also capable of propagating additional args through _load_ecom to _prepare_component_args
26 ## enhanced _prepare_component_args: now able to dispatch to a "transparent navigation ecom" (e.g. YAA::JobGroups)
27 ## MISC:
28 ## added some pre-flight checks throughout the module, especially at the core dispatcher inside _prepare_component_args
29 ## error checking: added some more croaks via 'user_error'
30 ## cosmetic updates
31 ##
32 ## Revision 1.17 2003/04/18 13:46:15 jonen
33 ## + add hidden elements(items) now to the constructor arguments of each ecom
34 ##
35 ## Revision 1.16 2003/04/10 06:00:58 joko
36 ## ALPHA: Item.Delete
37 ##
38 ## Revision 1.15 2003/04/09 02:08:20 joko
39 ## CHANGE: renamed key 'classname' through 'nodename'
40 ##
41 ## Revision 1.14 2003/04/09 00:31:27 jonen
42 ## + added arguments for data list ecom
43 ##
44 ## Revision 1.13 2003/04/09 00:03:11 jonen
45 ## disabled form rendering for inheritanced items at 'list'
46 ##
47 ## Revision 1.12 2003/04/08 17:52:12 joko
48 ## CHANGE: renamed property 'datasource' to 'transport'
49 ## NEW: Module 'RemoteAction'
50 ##
51 ## Revision 1.11 2003/04/07 22:31:51 jonen
52 ## + added switch of ecom label (e.g. nav, chooser) at ecom type switch 'nav'
53 ## - removed recent added ecom type chooser
54 ##
55 ## Revision 1.10 2003/04/05 20:32:04 joko
56 ## added Chooser
57 ##
58 ## Revision 1.9 2003/04/04 02:22:37 joko
59 ## minor fix: querySchema now issues argument
60 ##
61 ## Revision 1.8 2003/04/04 01:16:03 jonen
62 ## + integrated different mode's for 'DataItem'
63 ##
64 ## Revision 1.7 2003/03/29 07:49:55 joko
65 ## show boxes in DEBUG-mode only!
66 ##
67 ## Revision 1.6 2003/03/28 06:42:37 joko
68 ## fix: propagating rpc-debugging-options to constants here
69 ##
70 ## Revision 1.5 2003/03/27 01:24:29 jonen
71 ## + enabled navigation ecom (only list yet)
72 ##
73 ## Revision 1.4 2003/03/20 08:02:11 jonen
74 ## + purged code
75 ##
76 ## Revision 1.3 2003/03/20 07:54:52 jonen
77 ## + added docu
78 ##
79 ## Revision 1.2 2003/03/20 07:44:31 jonen
80 ## + removed dumper
81 ##
82 ## Revision 1.1 2003/03/20 03:48:46 jonen
83 ## + initial commit
84 ##
85 ## Revision 1.1 2003/03/08 02:36:17 cvsmax
86 ## + moved from *.inc
87 ## + mungled namespace with WebExplorer
88 ##
89 ## Revision 1.3 2003/03/03 22:25:21 joko
90 ## fixed minor typos
91 ## namespace mungling
92 ##
93 ## Revision 1.2 2003/03/02 00:48:49 cvsmax
94 ## + set up gui module registry
95 ## - purged old/sample code
96 ##
97 ## Revision 1.1 2003/03/01 22:57:32 cvsmax
98 ## + inital commit
99 ##
100 ##
101 ## -----------------------------------------------------------------------------
102 */
103
104 /**
105 * WebExplorer::AbstractExplorer - this can be simple compared to a container,
106 * which modular GUI classes can be register, manipulated and rendered...
107 *
108 * @author Sebastian Utz <seut@tunemedia.de>
109 * @package org.netfrag.app
110 * @name WebExplorer::AbstractExplorer
111 */
112
113
114 class WebExplorer_AbstractExplorer {
115
116 /**
117 * container holds meta information of data locators
118 */
119 var $_data_locators = array();
120
121 /**
122 * container for registered modules
123 */
124 var $_module = array();
125
126 /**
127 * container holds references to each ecom
128 */
129 var $_ecom = array();
130
131 /**
132 * holds the whole page state
133 */
134 var $_state = array();
135
136 /**
137 * holds state variables only needed for explorer
138 */
139 var $_e_state = array();
140
141
142 function WebExplorer_AbstractExplorer($data_locators=array()) {
143 $this->_data_locators = $data_locators;
144 $this->init_default_gui_modules();
145 $this->set_e_state();
146
147 //debug
148 //print "State: " . Dumper($this->_state) ."<br>";
149 $div = html_div();
150 $div->add( html_b(get_class($this)), html_hr(), "Explorer_State: " . Dumper($this->_e_state));
151 $div->set_style('background: #adadad; border: 2px black groove; width:640px; padding:10px; margin:40px;');
152 if (constants::get('DEBUG')) {
153 print $div->render();
154 }
155 }
156
157
158 function add_data_locator($label, $args) {
159 $this->_data_locators[$label] = $args;
160 }
161
162 function set_data_locator($label, $new_args=array() ) {
163 global $app;
164
165 // pre-flight checks
166 if (!$label) {
167 user_error("AbstractExplorer::set_data_locator - label was empty.");
168 return;
169 }
170
171 if ($label == "rpc") {
172 $rpcinfo = $app->getConfig("rpcinfo");
173 define('RPC_HOSTNAME', $rpcinfo[Host]);
174 define('RPC_PORT', $rpcinfo[Port]);
175 define('RPC_DEBUG', $rpcinfo[DEBUG]);
176 define('RPC_TRACE', $rpcinfo[TRACE]);
177 define('RPC_DISCONNECT_ON_ERROR', $rpcinfo[DISCONNECT_ON_ERROR]);
178 } else {
179 user_error("AbstractExplorer::set_data_locator - Could not dispatch data_locator_key label '$label'!");
180 }
181 }
182
183 function get_data_locator($label) {
184 }
185
186 function get_page_state() {
187 $requestTracker = mkObject("Application::Request::Tracker");
188 //print Dumper($this->_state);
189 $this->_state = $requestTracker->getPointer();
190 }
191
192 function set_e_state($state = null) {
193 // NEW [2003-04-18]: now has two modes
194 // 1. inject page state from argument passed to us
195 // 2. (was) get page state from request tracker
196 if ($state) {
197 $this->_e_state = $state;
198 } else {
199 $this->get_page_state();
200 $this->_e_state = $this->_state[options][options];
201 }
202 // print "Setting Explorer state:" . Dumper($this->_e_state);
203 }
204
205 function set_page_state() {
206 user_error("AbstractExplorer::set_page_state - please implement me....");
207 }
208
209 function init_default_gui_modules() {
210
211 // format of parameters: label, ecom_type, abstract_type, module_name
212
213 // 2003-03-02 - First ecom modules/components
214 //$this->register_gui_module("n_tree", "nav", array( 'name' => "NavigationTree", 'type' => "tree") );
215 $this->register_gui_module("nav", "nav", "list", "WebExplorer::Module::NavigationList" );
216 $this->register_gui_module("content", "data", "list", "WebExplorer::Module::DataList" );
217 $this->register_gui_module("content", "data", "item", "WebExplorer::Module::DataItem" );
218
219 // 2003-04-05 - Chooser (a Nav.List)
220 $this->register_gui_module("chooser", "nav", "list", "WebExplorer::Module::Chooser");
221
222 // 2003-04-07 - RemoteAction
223 $this->register_gui_module("phase_startup", "call", "auto", "WebExplorer::Module::RemoteAction");
224
225 // 2003-04-09 - Data.Item: DeleteAction
226 $this->register_gui_module("phase_startup", "data", "item", "WebExplorer::Module::DataItem");
227 //$this->register_gui_module("phase_startup", "data", "auto", "WebExplorer::Module::RemoteAction");
228 //$this->register_gui_module("phase_startup", "data", "auto", "WebExplorer::Module::DataItem");
229
230 // 2003-04-12 - Data.Tree
231 $this->register_gui_module("content", "data", "tree", "WebExplorer::Module::DataTree" );
232
233 // 2003-04-18 - Nav.Tree
234 $this->register_gui_module("nav", "nav", "tree", "WebExplorer::Module::NavigationTree" );
235
236 // 2003-04-18 - UserManagment Nav.Tree (we need only a different 'label' as Nav.Tree yet..)
237 $this->register_gui_module("UMnav", "nav", "tree", "WebExplorer::Module::NavigationTree" );
238
239 }
240
241 function register_source_module($label, $args) {
242 $this->_module['source'][$label] = $args;
243 }
244
245 function register_gui_module($label, $ecom_type, $abstract_type, $module_name) {
246 $this->_module['gui'][$label][$ecom_type][$abstract_type] = $module_name;
247 }
248
249
250 function &get_ecom($label, $args = array()) {
251
252 // the very first - strongly hardcoded - Hello World ecom
253 //return "Hello World";
254
255 // that's better ...
256 $this->_load_ecom($label, $args);
257 return $this->_ecom[$label];
258
259 }
260
261
262 function _load_ecoms() {
263 //trace("_load_ecoms: " . Dumper($this->_e_state[ecoms]) . "<br/>");
264 foreach($this->_e_state[ecoms] as $label => $val) {
265 $this->_load_ecom($label);
266 }
267 }
268
269
270
271 function _load_ecom($label, $args = array()) {
272
273 // fetch values from state
274 $val = $this->_e_state['ecoms'][$label];
275 debug::info("_load_ecom($label): " . Dumper($val) . "<br/>");
276
277 // NEW [2003-04-10]: ecom-RESET-condition
278 if (!is_array($val) && $val == 'RESET') {
279 debug::info("Resetting component: $label");
280 return;
281 }
282
283 // find right ecom gui module
284 $ecom_type = $val['ecom_type'];
285 $abstract_type = $val['ecom_abstract_type'];
286 $gui_module = $this->_module['gui'][$label][$ecom_type][$abstract_type];
287 //print Dumper($gui_module);
288 if(!$gui_module) {
289 user_error("_load_ecom: No GUI module found for [label='$label', ecom type='$val[ecom_type]', abstract type='$val[ecom_abstract_type]'].");
290 return;
291 }
292
293 // get arguments needed for ecom gui module
294 $args = $this->_prepare_component_args($label, $args);
295
296 // trace
297 //print "raw-args: " . Dumper($args) . "<br/>";
298
299 // get ecom GUI module
300 if (!$ecom = php::mkComponent($gui_module, $args)) {
301 user_error("AbstractExplorer::_load_component - Error while instantiating ecom gui component. [label='$label', abstract type='$val[ecom_abstract_type]', ecom type='$val[ecom_type]']");
302 return;
303 }
304 //print Dumper($ecom);
305
306 // NEW[2003-04-18] done via args(prepare args!) passed at constructor
307 // (needed for non-real objects instanced at some child of AbstractGUIModule, eg. NavigationList)
308 /*
309 // add hidden vars, needed for explorer control
310 $hidden_items = $this->_get_hidden_items($label);
311 if(is_array($hidden_items) ) {
312 $ecom->add_hidden_items($hidden_items);
313 print "Hidden: " . Dumper($hidden_items);
314 }
315 */
316
317 // load phphtmllib GUI object
318 $gui_ecom = &$ecom->get();
319
320 // attempt:
321 //$gui_ecom->make_transparent();
322
323 // store phphtmllib GUI object
324 $this->_ecom[$label] = &$gui_ecom;
325 }
326
327
328
329 function _get_hidden_items($label) {
330 $ecom_state = $this->_e_state['ecoms'][$label];
331 if($ecom_state['ecom_type'] == "data") {
332 if($ecom_state['ecom_abstract_type'] == "list") {
333 $hidden_items = array(
334 'ecl' => $label,
335 'ecat' => "item",
336 'ecmod' => "view",
337 );
338 }
339 elseif($ecom_state['ecom_abstract_type'] == "item") {
340 $hidden_items = array(
341 'ecl' => $label,
342 'ecat' => "item",
343 'ecmod' => "view",
344 );
345 }
346 }
347 elseif($ecom_state['ecom_type'] == "nav") {
348 // Switching abstract make no real sense here,
349 // because hidden_items(link_vars) for Naviagtion-Ecoms
350 // are more label specified!!
351 // OLD:
352 //if($ecom_state['ecom_abstract_type'] == "list") {
353 // NEW:
354 if($label == "nav") {
355 $hidden_items = array(
356 'ecl' => "content",
357 'ecat' => "list",
358 'ecmod' => "view",
359 'ect' => "data",
360 'ecdlk' => "rpc",
361 );
362
363 }
364 elseif($label == "chooser") {
365 $hidden_items = array(
366 'ecl' => "phase_startup",
367 'ecdlk' => "rpc",
368 );
369
370 }
371 }
372 // add page idents
373 foreach($this->_e_state[idents] as $label => $value) {
374 $hidden_items[$label] = $value;
375 }
376 return $hidden_items;
377 }
378
379
380
381 function _prepare_component_args($label, $args = array()) {
382 $val = $this->_e_state['ecoms'][$label];
383
384 // pre-flight checks
385 if (!$val['ecom_data_locator_key']) {
386 user_error("_prepare_component_args: Key 'ecom_data_locator_key' was empty, should be one of 'rpc'.");
387 return;
388 }
389
390 if (!$val['ecom_type']) {
391 user_error("WebExplorer::AbstractExplorer: Key 'ecom_type' was empty, should be one of 'data|nav|call'.");
392 }
393
394 if (!$val['ecom_abstract_type']) {
395 user_error("_prepare_component_args: Key 'ecom_abstract_type' was empty, should be one of 'item|list|tree|auto'.");
396 return;
397 }
398
399 // trace
400 //print "YAI1<br/>";
401 //print Dumper($val);
402
403 $this->set_data_locator($val['ecom_data_locator_key']);
404
405 // detect and execute 'selectSource' action
406 // FIXME: this is a HACK!!! move to a module 'BackendAction' or s.th.l.th.
407 //print Dumper($this->_e_state['sources']);
408 if ($source = $this->_e_state['main']['ecom_data_source_key']) {
409 //print "selectSource: $source<br/>";
410 //global $app;
411 //print Dumper($backend);
412 //$app->backend->do();
413 }
414
415 // switch component type
416 if($val['ecom_type'] == "data") {
417 // switch abstract type
418 if($val['ecom_abstract_type'] == "list") {
419 if($val['ecom_data_locator_key'] == "rpc") {
420 //$data_locator_meta = array( transport => 'rpc', metatype => 'data', vartype => 'objects', nodename => $val['ecom_data_ident']);
421 $data_locator_meta = array( transport => 'rpc', metatype => 'data', abstract_type => 'list', nodename => $val['ecom_data_ident'], list_meta => $val['ecom_data_meta']);
422 } else {
423 user_error("AbstractExplorer::_prepare_component_args - Cannot build query for data_locator_key $val[ecom_data_locator_key] !");
424 }
425 $args = array(
426 'caption' => $val['ecom_data_ident'],
427 'orderby' => "Guid",
428 'options' => array(
429 'data_locator_meta' => $data_locator_meta,
430 'decode' => 1,
431 'decode_args' => array(
432 'seperator' => "_",
433 //'form' => 1,
434 ),
435 'actionbar' => array(
436 'name' => "ecdfa",
437 'list' => array(
438 "View" => 'view',
439 "Edit" => 'edit',
440 "Delete" => 'delete',
441 "Add new" => 'add',
442 ),
443 ),
444 ),
445 );
446
447 // switch abstract type
448 } elseif ($val['ecom_abstract_type'] == "item") {
449 if($val['ecom_data_locator_key'] == "rpc") {
450 //$data_locator_meta = array( transport => 'rpc', metatype => 'data', vartype => 'objects', nodename => $val['ecom_data_ident']);
451
452 // NEW: 'filter' - 2003-04-14 - required for filtering xml-nodes
453 // this propagates the full identifier to reach through all parent nodes
454 $filter = array(
455 dotted => $val['ecom_data_filter'],
456 ident => $val['ecom_data_ident'],
457 //xpq => '*/*[@name="cli"]',
458 //xpq => '*/*',
459 );
460 // lift filter from dotted format to xpq format
461 $lift = mkObject('Data::Lift', $filter, array( metatype => 'filter' ) );
462 $filter = $lift->to('XPath');
463
464 $data_locator_meta = array(
465 transport => 'rpc', metatype => 'data', abstract_type => 'item',
466 ident => $val['ecom_data_ident'], nodename => $val['ecom_data_meta'], filter => $filter,
467 );
468 } else {
469 user_error("AbstractExplorer::_prepare_component_args - Cannot build query for data_locator_key $val[ecom_data_locator_key] !");
470 }
471
472 // defaults
473 if (!$val['ecom_mode']) { $val['ecom_mode'] = "view"; }
474 //$val['ecom_mode'] = "view";
475
476 // debugging
477 print "Mode: $val[ecom_mode]<br>";
478
479 // prepare some arguments...
480 $args = array(
481 'caption' => $val['ecom_data_meta'],
482 'mode' => $val['ecom_mode'],
483 'options' => array(
484 'data_locator_meta' => $data_locator_meta,
485 'decode' => 1,
486 'decode_args' => array(
487 'seperator' => "_",
488 ),
489 ),
490 );
491 if ($val['ecom_mode'] == "edit") { $args['adapter'] = 'FormProcessor'; }
492
493 // FIXME: (see WebExplorer::Module::AbstractGUIModule)
494 //if ($val['ecom_mode'] == "delete") { $args['adapter'] = 'GenericNegotiation'; }
495 if ($val['ecom_mode'] == "delete") { $args['adapter'] = 'NonValidatingFormProcessor'; }
496
497 // switch abstract type
498 } elseif ($val['ecom_abstract_type'] == "tree") {
499 //print "TREE!<br/>";
500
501 // FIXME: shouldn't this (dispatching by transport-key) be done very *outside* of this scope?
502 // or: do it outside per default, let a possibility to modify it inside the lower levels of the dispatcher (here)
503 if ($val['ecom_data_locator_key'] == "rpc") {
504 //$data_locator_meta = array( transport => 'rpc', metatype => 'data', vartype => 'objects', nodename => $val['ecom_data_ident']);
505 $args[options][data_locator_meta] = array( transport => 'rpc', metatype => 'data', abstract_type => 'tree', ident => $val['ecom_data_ident'], nodename => $val['ecom_data_meta']);
506 }
507
508 } else {
509 user_error("_prepare_component_args: Could not dispatch ecom_abstract_type='$val[ecom_abstract_type]'.");
510
511 }
512
513 // switch component type
514 } elseif ($val['ecom_type'] == "nav") {
515
516 // switch abstract type
517 // list
518 if ($val['ecom_abstract_type'] == "list") {
519 $args = array();
520 if($val['ecom_data_locator_key'] == "rpc") {
521
522 // switch component label
523 // TODO: should we really dispatch by label inside here?
524
525 if ($label == "nav") {
526 $data_locator_meta = array( transport => 'rpc', metatype => 'schema', filter => 'nodes.root:concrete' );
527 $args['caption'] = "Objekt Typen";
528 }
529 // NEW [2003-04-05]: DataSource.Chooser
530 elseif ($label == "chooser") {
531 $data_locator_meta = array( transport => 'rpc', metatype => 'schema', filter => 'sources.all' );
532 $args['caption'] = "Datenquellen";
533 }
534 // NEW [2003-04-18]: croak if label empty
535 else {
536 user_error("_prepare_component_args: Dispatching for nav.list.rpc failed. \$label was empty.");
537 }
538 $args['options']['data_locator_meta'] = $data_locator_meta;
539
540 } else {
541 user_error("AbstractExplorer::_prepare_component_args - Cannot build schema query for data_locator_key $val[ecom_data_locator_key] !");
542 }
543
544 // NEW [2003-04-18]: Abstract navigation tree
545 } elseif ($val['ecom_abstract_type'] == "tree") {
546 $args = array();
547 if($label == "nav") {
548 //$args[options][data_locator_meta] = array( transport => 'rpc', metatype => 'schema', abstract_type => 'tree', ident => $val['ecom_data_ident'], nodename => $val['ecom_data_meta']);
549 $args[options][data_locator_meta] = array( transport => 'rpc', metatype => 'schema', filter => 'nodes.root:concrete' );
550 $args['caption'] = $val['ecom_data_source_key'];
551 } elseif($label == "UMnav") {
552 //$args[options][data_locator_meta] = array( transport => 'rpc', metatype => 'schema', abstract_type => 'tree', ident => $val['ecom_data_ident'], nodename => $val['ecom_data_meta']);
553 $args[options][data_locator_meta] = array( transport => 'rpc', metatype => 'method', method => 'UserManagmentSchema' );
554 $args['caption'] = "Benutzerverwaltung";
555 }
556
557 // NEW [2003-04-18]: transparent nav - argument pass-through mode
558 } elseif ($val['ecom_abstract_type'] == "transparent") {
559
560 // You are responsible for all arguments passed through.
561 // Where are these arguments from?
562 // They are propagated transparently to this place from a new optional
563 // parameter ($args) introduced for the methods 'get_com', 'load_com'
564 // and '_prepare_component_args' (this one).
565 // This means full control over ecoms from outside.
566
567 // TODO: maybe add some additional pre-flight checks here!?
568
569 // croak
570 } else {
571 user_error("_prepare_component_args: Could not dispatch ecom_abstract_type='$val[ecom_abstract_type]'.");
572 }
573
574 // NEW [2003-04-08]: RemoteAction (e.g.: result of a selection inside a Chooser)
575 // switch component type
576 } elseif ($val['ecom_type'] == "call") {
577
578 // responses of RemoteActions are not predictable!
579 if ($val['ecom_abstract_type'] == "auto") {
580
581 // Dispatching by $label is not done here. RemoteAction-ecoms can appear anywhere!
582
583 // Just define the RemoteQuery using a declaration to use DataSource::Generic most transparently.
584 // Really - just a remote call is issued, no data-/schema-structures or similar are expected.
585
586 // The RemoteMethod 'method' is called directly with arguments in 'args'!
587 // As response (important for widget assignement!) you may expect an arbitrary payload.
588 $args['options']['data_locator_meta'] = array(
589 transport => 'rpc',
590 metatype => 'method',
591 method => $val['ecom_call_method'],
592 args => $val['ecom_call_args']
593 );
594
595 } else {
596 // FIXME: implement automatic re-dispatching to available ecoms here!
597 user_error("WebExplorer::AbstractExplorer: results of RemoteActions can only be handled automatically. Who knows what comes back?");
598 }
599
600 }
601
602 // NEW[2003-04-18]: add hidden items to args
603 $args['hidden_elements'] = $this->_get_hidden_items($label);
604
605 return $args;
606 }
607
608
609
610 function get_msg($label) {
611 if($label == "welcome") {
612 $msg = "Welcome to the Explorer.";
613 }
614 return $msg;
615 }
616
617
618
619 function render() {
620 user_error("AbstractExplorer::render - please implement me....");
621 }
622
623 }
624
625
626 ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed