/[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.18 - (show annotations)
Fri Apr 18 15:27:06 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.17: +140 -29 lines
NEW: XML Trees in data area
  new ecom module: DataTree
  introduced new query argument: 'filter' (purpose: xml/tree filtering)
    $filter = array(
      dotted => $val['ecom_data_filter'],
      ident => $val['ecom_data_ident'],
    );
    A Data::Lift module translates this filter-query into a XPath-query ...
    $filter = array(
      xpq => '*/*[@name="cli"]',
    );
    ... which finally is propagated to the backend.
NEW: AbstractExplorer - standalone version
  enhanced set_e_state: now can overwrite internal state to arguments from outside
  enhanced get_com: also capable of propagating additional args through _load_ecom to _prepare_component_args
  enhanced _prepare_component_args: now able to dispatch to a "transparent navigation ecom" (e.g. YAA::JobGroups)
MISC:
  added some pre-flight checks throughout the module, especially at the core dispatcher inside _prepare_component_args
  error checking: added some more croaks via 'user_error'
  cosmetic updates

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

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