/[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.19 - (show annotations)
Fri Apr 18 16:21:37 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.18: +23 -1 lines
fixed commit comment - the last one caused a syntax error!!!

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

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