/[cvs]/nfo/php/libs/org.netfrag.glib/DesignPattern/RemoteProxy.php
ViewVC logotype

Diff of /nfo/php/libs/org.netfrag.glib/DesignPattern/RemoteProxy.php

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by joko, Mon Mar 3 22:06:46 2003 UTC revision 1.18 by jonen, Thu May 13 19:17:55 2004 UTC
# Line 1  Line 1 
1  <?php  <?php
2    /**
3     * This file contains the DesignPattern::RemoteProxy class
4     *
5     * @author Andreas Motl <andreas.motl@ilo.de>
6     * @package org.netfrag.glib
7     * @name DesignPattern::RemoteProxy
8     *
9     *
10     */
11    
12    
13  /**  /**
14     * <b>Cvs-Log:</b>
15     *
16     * <pre>
17   * -------------------------------------------------------------------------   * -------------------------------------------------------------------------
18   *    $Id$   *    $Id$
19   * -------------------------------------------------------------------------   * -------------------------------------------------------------------------
20   *    $Log$   *    $Log$
21     *    Revision 1.18  2004/05/13 19:17:55  jonen
22     *    + bugfix: utf8 conversion was missing at some backend-calls
23     *
24     *    Revision 1.17  2003/07/14 10:05:23  jonen
25     *    bugfix: added *needed* function 'getAttributes'
26     *
27     *    Revision 1.16  2003/07/02 13:51:38  jonen
28     *    removed debug dumper
29     *
30     *    Revision 1.15  2003/04/11 01:32:21  joko
31     *    renamed logging function
32     *
33     *    Revision 1.14  2003/04/09 02:06:45  joko
34     *    errormessage now shown preformatted
35     *
36     *    Revision 1.13  2003/04/04 17:38:03  joko
37     *    modifications regarding error-/exception-handling and -tracing
38     *
39     *    Revision 1.12  2003/03/29 08:01:21  joko
40     *    modified ErrorBoxing
41     *
42     *    Revision 1.11  2003/03/28 06:44:51  joko
43     *    VERBOSE mode
44     *
45     *    Revision 1.10  2003/03/28 03:05:54  joko
46     *    more fancy debugging-output
47     *
48     *    Revision 1.9  2003/03/10 23:05:25  joko
49     *    + fixed metadata for phpDocumentor
50     *
51     *    Revision 1.8  2003/03/10 22:31:56  joko
52     *    + fixed metadata for phpDocumentor
53     *
54     *    Revision 1.7  2003/03/09 15:51:44  joko
55     *    + additional metadata for Autodia
56     *
57     *    Revision 1.6  2003/03/05 17:28:43  joko
58     *    updated docu (phpDocumentor testing....)
59     *
60     *    Revision 1.5  2003/03/05 17:02:22  joko
61     *    updated docu (phpDocumentor testing....)
62     *
63     *    Revision 1.4  2003/03/05 16:32:19  joko
64     *    updated docu (phpDocumentor testing....)
65     *
66     *    Revision 1.3  2003/03/05 16:10:17  joko
67     *    updated docu (phpDocumentor testing....)
68     *
69     *    Revision 1.2  2003/03/05 12:14:02  joko
70     *    renamed method
71     *    constructor argument expansion
72     *
73   *    Revision 1.1  2003/03/03 22:06:46  joko   *    Revision 1.1  2003/03/03 22:06:46  joko
74   *    refactored from Data::Driver::Proxy   *    refactored from Data::Driver::Proxy
75   *   *
# Line 92  Line 157 
157   *    Revision 1.1  2002/10/09 00:51:39  cvsjoko   *    Revision 1.1  2002/10/09 00:51:39  cvsjoko
158   *    + new   *    + new
159   * -------------------------------------------------------------------------   * -------------------------------------------------------------------------
160     * </pre>
161     *
162   */   */
163    
164    
165    
166    
167  /**  /**
168     * Load required modules:
169   *   *
170   * Data::Driver::Proxy  --  Multiple stage data fetching and caching   */
171    loadModule('DesignPattern::Proxy');
172    
173    
174    /**
175     * DesignPattern::RemoteProxy  --  Multiple stage data fetching and caching
176   *   *
177   *   *
178   * This class (Data::Driver::Proxy) provides an abstract framework   * This class (DesignPattern::RemoteProxy) provides an abstract framework
179   * for loading/saving arbitrary data from/to data storages interfaced   * for loading/saving arbitrary data from/to data storages interfaced
180   * by storage *proxy*-drivers.   * by storage *proxy*-drivers.
181   * Don't mix these up with the concrete storage *handle*-drivers   * Don't mix these up with the concrete storage *handle*-drivers
# Line 108  Line 184 
184   * providing a more highlevel, consistent API making   * providing a more highlevel, consistent API making
185   * it easier for Data::Driver::Proxy to do its main work:   * it easier for Data::Driver::Proxy to do its main work:
186   *   *
187     * quote from: http://home.earthlink.net/~huston2/dp/proxy.html
188     * "A remote proxy provides a local representative for an
189     * object that resides in a different address space. This is
190     * what the "stub" code in RPC and CORBA provides."
191     *
192     *
193   * Multiple stage data fetching and caching:   * Multiple stage data fetching and caching:
194   *   *
195     * <pre>
196     *
197   * DATA, ...   * DATA, ...
198   *    ... also refered to as data, should be handled as   *    ... also refered to as data, should be handled as
199   *    something called data.   *    something called data.
# Line 152  Line 236 
236   *    o Data::Driver::PEAR::DB   *    o Data::Driver::PEAR::DB
237   *    x Data::Driver::PEAR::Tree (via Data::Lift)   *    x Data::Driver::PEAR::Tree (via Data::Lift)
238   *   *
239   */   * </pre>
   
 /**  
  * Todo:  
  *  x extend options to en-/disable caching via a) session and/or b) database  
  *    o make feature available via runtime setter-method to these options  
  *  o use PEAR::Cache for caching purposes!!!  
  *  o refactor database access: use PEAR for this! no more 'connectdb' here!!!  
  *  o make database connection more flexible to make possible  
  *      to have different (probably named) proxy databases (besides a "main database")  
  *  o rename this to Data::Proxy? or split into Data::Query, Data::Result and Data::Wrapper?  
240   *   *
241   */   *
242     * An attempt to implement some software design patterns
243  /**   * --- RemoteProxyPattern
244   * Load required modules:   *
245     * @link http://www.agcs.com/supportv2/techpapers/patterns/papers/tutnotes/sld017.htm
246     * @link http://home.earthlink.net/~huston2/dp/proxy.html
247     * @link http://wiki.cs.uiuc.edu/PatternStories/RemoteObject
248     * @link http://c2.com/cgi-bin/wiki?ProxyPattern
249     * @link http://c2.com/cgi-bin/wiki?LazyProxies
250     *
251     * @author Andreas Motl <andreas.motl@ilo.de>
252     * @link http://www.netfrag.org/~joko/
253     *
254     * @copyright (c) 2003 - All Rights reserved.
255     * @license GNU LGPL (GNU Lesser General Public License)
256     * @link http://www.gnu.org/licenses/lgpl.txt
257     *
258     * @package org.netfrag.glib
259     * @subpackage DesignPattern
260     * @name DesignPattern::RemoteProxy
261     *
262     *
263     * @todo extend options to en-/disable caching via a) session and/or b) database
264     *           make feature available via runtime setter-method to these options
265     * @todo PEAR::Cache for caching purposes!!!
266     * @todo refactor database access: use PEAR for this! no more 'connectdb' here!!!
267     * @todo make database connection more flexible to make possible
268     *           to have different (probably named) proxy databases (besides a "main database")
269     * @todo rename this to Data::Proxy? or split into Data::Query, Data::Result and Data::Wrapper?
270     * @todo refactor this to a "RemoteObject" class!!! (inheriting from DesignPattern::RemoteObject)
271     * @todo rename this to "DesignPattern::LazyRemoteProxy"???
272   *   *
273   */   */
 loadModule('DesignPattern::Proxy');  
   
274  class DesignPattern_RemoteProxy extends DesignPattern_Proxy {  class DesignPattern_RemoteProxy extends DesignPattern_Proxy {
275    
276    var $objectId;    var $objectId;
# Line 182  class DesignPattern_RemoteProxy extends Line 281  class DesignPattern_RemoteProxy extends
281    var $backend;    var $backend;
282    
283    function DesignPattern_RemoteProxy($objectId = "", $options = array() ) {    function DesignPattern_RemoteProxy($objectId = "", $options = array() ) {
284      logp(get_class($this) . "->new()", PEAR_LOG_INFO);      php::log(get_class($this) . "->new()", PEAR_LOG_INFO);
285      global $proxy;      global $proxy;
286    
287        // 2003-03-05 - modified constructor
288        // expand objectId
289        if (is_array($objectId)) {
290          $options = $objectId[1];
291          $objectId = $objectId[0];
292        }
293    
294      // trace      // trace
295        //print Dumper($objectId, $options);        //print Dumper($objectId, $options);
296    
# Line 193  class DesignPattern_RemoteProxy extends Line 299  class DesignPattern_RemoteProxy extends
299        $this->_init_caching();        $this->_init_caching();
300        $this->_init_load();        $this->_init_load();
301    
302        //print Dumper($this);
303    
304    }    }
305    
306    function _init_meta_options( $objectId="", $options = array() ) {    function _init_meta_options( $objectId="", $options = array() ) {
# Line 215  class DesignPattern_RemoteProxy extends Line 323  class DesignPattern_RemoteProxy extends
323        session_register_safe("proxy");        session_register_safe("proxy");
324      }        }  
325    
326        /**
327         * <!-- Autodia -->
328         * can do: (this is metadata supplied for Autodia, don't delete!)
329         *  $this->backend = new DataSource_Proxy_XMLRPC()
330         *
331         */
332    
333      if ($this->meta[remote]) {      if ($this->meta[remote]) {
334        //$this->backend = mkObject('Data::Driver::RPC::Remote', $this->meta[rpcinfo]);        //$this->backend = mkObject('Data::Driver::RPC::Remote', $this->meta[rpcinfo]);
335        $this->backend = mkObject('DataSource::Proxy::XMLRPC', $this->meta[rpcinfo]);        $this->backend = php::mkComponent('DataSource::Proxy::XMLRPC', $this->meta[rpcinfo]);
336      }      }
337    }    }
338    
# Line 230  class DesignPattern_RemoteProxy extends Line 345  class DesignPattern_RemoteProxy extends
345    
346    
347    function load() {    function load() {
348      logp(get_class($this) . "->load()", PEAR_LOG_INFO);      php::log(get_class($this) . "->load()", PEAR_LOG_INFO);
349      if (!$this->_loadState()) {      if (!$this->_loadState()) {
350        if (!$this->_loadProxy()) {        if (!$this->_loadProxy()) {
351    
# Line 275  class DesignPattern_RemoteProxy extends Line 390  class DesignPattern_RemoteProxy extends
390    }      }  
391    */    */
392    
393    function getAttributes() {    function getResult() {
394      if (!$this->meta[decoded]) {      if (!$this->meta[decoded]) {
395        $this->_decode();        $this->_decode();
396        $this->_saveState();        $this->_saveState();
# Line 287  class DesignPattern_RemoteProxy extends Line 402  class DesignPattern_RemoteProxy extends
402      $this->attributes = $data;      $this->attributes = $data;
403    }    }
404    
405      function getAttributes() {
406        return $this->attributes;
407      }
408    
409    function flushProxy() {    function flushProxy() {
410          connectdb();          connectdb();
411      $sql = "DELETE FROM f_proxy WHERE oid='$this->objectId'";      $sql = "DELETE FROM f_proxy WHERE oid='$this->objectId'";
# Line 306  class DesignPattern_RemoteProxy extends Line 425  class DesignPattern_RemoteProxy extends
425        //print Dumper($this);        //print Dumper($this);
426    
427      // debug      // debug
428        logp(get_class($this) . "->_loadState()");        php::log(get_class($this) . "->_loadState()");
429                
430      if ($this->attributes = $proxy[$this->objectId]) {      if ($this->attributes = $proxy[$this->objectId]) {
431        //print "_loadState:" . dumpVar($this->attributes);        //print "_loadState:" . dumpVar($this->attributes);
# Line 318  class DesignPattern_RemoteProxy extends Line 437  class DesignPattern_RemoteProxy extends
437    
438    function _saveState() {    function _saveState() {
439      global $proxy;      global $proxy;
440      logp(get_class($this) . "->_saveState()");      php::log(get_class($this) . "->_saveState()");
441      $proxy[$this->objectId] = $this->attributes;      $proxy[$this->objectId] = $this->attributes;
442      //print "_saveState: " . dumpVar($this->attributes);      //print "_saveState: " . dumpVar($this->attributes);
443      // TODO: throw exception-message back to user if operation fails      // TODO: throw exception-message back to user if operation fails
# Line 331  class DesignPattern_RemoteProxy extends Line 450  class DesignPattern_RemoteProxy extends
450            
451      // trace & debug      // trace & debug
452        //print Dumper($this);        //print Dumper($this);
453        logp(get_class($this) . "->_loadProxy()");        php::log(get_class($this) . "->_loadProxy()");
454                
455      connectdb();      connectdb();
456      $sql = "SELECT payload FROM f_proxy WHERE oid='$this->objectId'";      $sql = "SELECT payload FROM f_proxy WHERE oid='$this->objectId'";
# Line 351  class DesignPattern_RemoteProxy extends Line 470  class DesignPattern_RemoteProxy extends
470      // FIXME!      // FIXME!
471      if (!$this->meta[cache][db]) { return; }      if (!$this->meta[cache][db]) { return; }
472    
473      logp(get_class($this) . "->_saveProxy()");      php::log(get_class($this) . "->_saveProxy()");
474          connectdb();          connectdb();
475          if ($this->payload) {          if ($this->payload) {
476        //$sql = "INSERT INTO f_proxy SET payload='$this->payload' WHERE oid='$this->objectId'";        //$sql = "INSERT INTO f_proxy SET payload='$this->payload' WHERE oid='$this->objectId'";
# Line 364  class DesignPattern_RemoteProxy extends Line 483  class DesignPattern_RemoteProxy extends
483    }    }
484        
485    function _loadRemote() {    function _loadRemote() {
486      logp(get_class($this) . "->_loadRemote()");      php::log(get_class($this) . "->_loadRemote()");
487            
488      // trace      // trace
489        //print Dumper($this->meta);        //print Dumper($this->meta);
# Line 373  class DesignPattern_RemoteProxy extends Line 492  class DesignPattern_RemoteProxy extends
492            
493      // 1. check backend-handle      // 1. check backend-handle
494      if (!$this->backend) {      if (!$this->backend) {
495        logp(get_class($this) . "->_loadRemote: no backend handle, please check argument 'rpcinfo'", PEAR_LOG_CRIT);        php::log(get_class($this) . "->_loadRemote: no backend handle, please check argument 'rpcinfo'", PEAR_LOG_CRIT);
496        return;        return;
497      }      }
498            
# Line 381  class DesignPattern_RemoteProxy extends Line 500  class DesignPattern_RemoteProxy extends
500        // check for guid or oid        // check for guid or oid
501        if ($this->meta[guid]) {        if ($this->meta[guid]) {
502          if (!$this->objectId) {          if (!$this->objectId) {
503            logp(get_class($this) . "->_loadRemote: argument 'guid' requires valid objectId", PEAR_LOG_WARNING);            php::log(get_class($this) . "->_loadRemote: argument 'guid' requires valid objectId", PEAR_LOG_WARNING);
504            return;            return;
505          }          }
506          if (!$this->meta[classname]) {          if (!$this->meta[classname]) {
507            logp(get_class($this) . "->_loadRemote: argument 'guid' requires 'classname'", PEAR_LOG_WARNING);            php::log(get_class($this) . "->_loadRemote: argument 'guid' requires 'classname'", PEAR_LOG_WARNING);
508            return;            return;
509          }          }
510            php::log(get_class($this) . "->_loadRemote: getObjectByGuid", PEAR_LOG_DEBUG);
511          $args = array( guid => $this->objectId, classname => $this->meta[classname] );          $args = array( guid => $this->objectId, classname => $this->meta[classname] );
512          $result = $this->backend->send('getObjectByGuid', $args );          $result = $this->backend->send('getObjectByGuid', $args, array( utf8 => 1)  );
513    
514        } elseif ($this->meta[oid]) {        } elseif ($this->meta[oid]) {
515          if (!$this->objectId) {          if (!$this->objectId) {
516            logp(get_class($this) . "->_loadRemote: argument 'oid' requires valid objectId", PEAR_LOG_WARNING);            php::log(get_class($this) . "->_loadRemote: argument 'oid' requires valid objectId", PEAR_LOG_WARNING);
517            return;            return;
518          }          }
519          $result = $this->backend->send('getObject', $this->objectId);          php::log(get_class($this) . "->_loadRemote: getObject", PEAR_LOG_DEBUG);
520            $result = $this->backend->send('getObject', $this->objectId, array( utf8 => 1) );
521    
522        } elseif ($this->meta[key]) {        } elseif ($this->meta[key]) {
523          if (!$this->meta[command]) {          if (!$this->meta[command]) {
524            logp(get_class($this) . "->_loadRemote: argument 'key' requires 'command'", PEAR_LOG_WARNING);            php::log(get_class($this) . "->_loadRemote: argument 'key' requires 'command'", PEAR_LOG_WARNING);
525            return;            return;
526          }          }
527          /*          /*
528          if (!$this->meta[query]) {          if (!$this->meta[query]) {
529            logp(get_class($this) . "->_loadRemote: argument 'key' requires 'query'", PEAR_LOG_WARNING);            php::log(get_class($this) . "->_loadRemote: argument 'key' requires 'query'", PEAR_LOG_WARNING);
530            return;            return;
531          }          }
532          */          */
533          $result = $this->backend->send($this->meta[command], $this->meta[query]);          //php::log(get_class($this) . "->_loadRemote: $this->meta[command](" . join(' ', $this->meta[query]) . ")", PEAR_LOG_DEBUG);
534            //print Dumper(array($this->meta[command], $this->meta[query]));
535            $result = $this->backend->send($this->meta[command], $this->meta[query], array( utf8 => 1) );
536                    
537        }        }
538    
539        //print "result: " . dumpVar($result) . "<br>";
540    
541        $status = $this->backend->status();
542        //print Dumper($status);
543            
544      if ($result) {      $good = is_array($result) && sizeof($result) && $status[connected];
545        //print "result: " . dumpVar($result) . "<br>";  
546        if (count($result) == 0) { return; }      if ($good) {
547                
548        // FIXME: this is dangerous!        // FIXME: this is dangerous!
549          /*
550        if ($_GET[debug]) {        if ($_GET[debug]) {
551          print Dumper($result);          print Dumper($result);
552        }        }
553          */
554                
555        $this->payload = serialize($result);        $this->payload = serialize($result);
556        // ----- move this to _encode some times        // ----- move this to _encode some times
# Line 430  class DesignPattern_RemoteProxy extends Line 558  class DesignPattern_RemoteProxy extends
558        $this->_saveProxy();        $this->_saveProxy();
559        //print "oid: $this->objectId<br>";        //print "oid: $this->objectId<br>";
560        $this->flushState();        $this->flushState();
561        
562      } else {      } else {
563        //print "Error in _loadRemote!!!<br>";        
564        logp(get_class($this) . "->_loadRemote: error while trying to talk to remote side", PEAR_LOG_CRIT);        if (constants::get('APP_MODE_DEBUG')) {
565            $this->draw_error_box($status);
566          } else {
567            php::maintenance('rpc', array( status => $status ) );
568          }
569        
570      }      }
571            
572    }    }
573    
574    function draw_error_box($status) {
575      $style = html_style("text/css", '.boxlabel_yellow { color: yellow; font-weight:bold; }');
576      $statusbox = html_div();
577      $statusbox->set_style('background: red; border: 2px black groove; width:640px; padding:10px; margin:40px;');
578      $statusbox->add( html_span('boxlabel_yellow', "Method:"), get_class($this) . "->_loadRemote", html_br() );
579      $statusbox->add( html_span('boxlabel_yellow', "Connected:"), $status[connected], html_br() );
580      $statusbox->add( html_span('boxlabel_yellow', "RPCSESSID:"), $status[RPCSESSID], html_br() );
581      foreach ($status[errors] as $error) {
582        $msg = html_pre($error[message]);
583        $statusbox->add( html_span('boxlabel_yellow', "Error($error[code]):"), $msg );
584      }
585        
586      $message = "Error while talking to remote side. Please check wire, socket or api.";
587      php::log($message, PEAR_LOG_CRIT);
588      $statusbox->add( html_span('boxlabel_yellow', "Critical:"), $message, html_br() );
589    
590      // V1
591      /*
592      if (constants::get('VERBOSE') || constants::get('ERRORS_ONLY')) {
593        print $style->render();
594        print $statusbox->render();
595      } else {
596        foreach ($status[errors] as $error) {
597          print Dumper($error);
598        }
599      }
600      */
601    
602      // V2
603      trace( container($style, $statusbox) );
604    
605    }  
606    
607    
608    function _saveBackend($result) {    function _saveBackend($result) {
609      logp(get_class($this) . "->_saveBackend()");      php::log(get_class($this) . "->_saveBackend()");
610    
611      //$encoder = new TextEncode($result);      //$encoder = new TextEncode($result);
612      //$encoder->toUTF8();      //$encoder->toUTF8();
# Line 469  class DesignPattern_RemoteProxy extends Line 637  class DesignPattern_RemoteProxy extends
637    
638  }  }
639    
 ?>  
640    ?>

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.18

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