cvsuser     02/07/12 14:01:13

  Added:       P5EEx/Blue/P5EEx/Blue/Context HTTPHTML.pm
  Log:
  new file - moves distinctions between CGI and mod_perl out of the Context into the 
Request
  
  Revision  Changes    Path
  1.1                  p5ee/P5EEx/Blue/P5EEx/Blue/Context/HTTPHTML.pm
  
  Index: HTTPHTML.pm
  ===================================================================
  
  #############################################################################
  ## $Id: HTTPHTML.pm,v 1.1 2002/07/12 21:01:13 spadkins Exp $
  #############################################################################
  
  package P5EEx::Blue::Context::HTTPHTML;
  
  use P5EEx::Blue::P5EE;
  use P5EEx::Blue::Context;
  @ISA = ( "P5EEx::Blue::Context" );
  
  use strict;
  
  =head1 NAME
  
  P5EEx::Blue::Context::HTTPHTML - context in which we are currently running
  
  =head1 SYNOPSIS
  
     # ... official way to get a Context object ...
     use P5EEx::Blue::P5EE;
     $context = P5EEx::Blue::P5EE->context();
     $config = $context->config();   # get the configuration
     $config->dispatch_events();     # dispatch events
  
     # ... alternative way (used internally) ...
     use P5EEx::Blue::Context::HTTPHTML;
     $context = P5EEx::Blue::Context::HTTPHTML->new();
  
  =cut
  
  #############################################################################
  # DESCRIPTION
  #############################################################################
  
  =head1 DESCRIPTION
  
  A Context class models the environment (aka "context)
  in which the current process is running.
  For the P5EEx::Blue::Context::HTTPHTML class, this models any of the
  web application runtime environments which employ the HTTP protocol
  and produce HTML pages as output.  This includes CGI, mod_perl, FastCGI,
  etc.  The difference between these environments is not in the Context
  but in the implementation of the Request and Response objects.
  
  =cut
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  The following methods are intended to be called by subclasses of the
  current class.
  
  =cut
  
  #############################################################################
  # init()
  #############################################################################
  
  =head2 init()
  
  The init() method is called from within the standard Context constructor.
  
  The init() method sets debug flags.
  
      * Signature: $context->init($args)
      * Param:     $args            hash{string} [in]
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->init($args);
  
  =cut
  
  sub init {
      my ($self, $args) = @_;
      $args = {} if (!defined $args);
  
      #################################################################
      # DEBUGGING
      #################################################################
  
      # Supports the following command-line usage:
      #    -debug=1                                                (global debug)
      #    -debug=1,P5EEx::Blue::Context                       (debug class only)
      #    -debug=3,P5EEx::Blue::Context,P5EEx::Blue::Session  (multiple classes)
      #    -debug=6,P5EEx::Blue::Repository::DBI.select_rows (individual methods)
      my ($debug, $pkg);
      $debug = $args->{debug};
      if (defined $debug && $debug ne "") {
          if ($debug =~ s/^([0-9]+),?//) {
              $P5EEx::Blue::DEBUG = $1;
          }
          if ($debug) {
              foreach $pkg (split(/,/,$debug)) {
                  $self->{debugscope}{$pkg} = 1;
              }
          }
      }
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods
  
  These methods are considered protected because no class is ever supposed
  to call them.  They may however be called by the context-specific drivers.
  
  =cut
  
  #############################################################################
  # dispatch_events()
  #############################################################################
  
  =head2 dispatch_events()
  
  The dispatch_events() method is called by the CGI script
  in order to get the Context object rolling.  It causes the program to
  process the CGI request, interpret and dispatch encoded events in the 
  request and exit.
  
  In concept, the dispatch_events() method would not return until all
  events for a Session were dispatched.  However, the reality of the CGI
  context is that events associated with a Session occur in many different
  processes over different CGI requests.  Therefore, the CGI Context
  implements the dispatch_events() method to return after processing
  all of the events of a single request, assuming that it will be called
  again when the next CGI request is received.
  
      * Signature: $context->dispatch_events()
      * Param:     void
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->dispatch_events();
  
  =cut
  
  sub dispatch_events {
      my ($self) = @_;
  
      $self->request()->process_request();
  
      eval {
          $self->display_current_widget();
      };
      if ($@) {
          print <<EOF;
  Content-type: text/plain
  
  -----------------------------------------------------------------------------
  AN ERROR OCCURRED in P5EEx::Blue::Context::CGI->display_current_widget()
  -----------------------------------------------------------------------------
  $@
  
  -----------------------------------------------------------------------------
  Additional messages from earlier stages may be relevant if they exist below.
  -----------------------------------------------------------------------------
  $self->{messages}
  EOF
      }
  
      $self->shutdown();
  }
  
  #############################################################################
  # request()
  #############################################################################
  
  =head2 request()
  
      * Signature: $context->request()
      * Param:     void
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->request();
  
  The request() method gets the current Request being handled in the Context.
  
  =cut
  
  sub request {
      my $self = shift;
  
      return $self->{request} if (defined $self->{request});
  
      #################################################################
      # REQUEST
      #################################################################
  
      my $request_class = $self->iget("requestClass", "P5EEx::Blue::Request::CGI");
  
      eval {
          $self->{request} = P5EEx::Blue::P5EE->new($request_class, "new", $self, 
$self->{initconfig});
      };
      $self->add_message($@) if ($@);
  
      return $self->{request};
  }
  
  #############################################################################
  # response()
  #############################################################################
  
  =head2 response()
  
      * Signature: $context->response()
      * Param:     void
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->response();
  
  The response() method gets the current Request being handled in the Context.
  
  =cut
  
  sub response {
      my $self = shift;
  
      return $self->{response} if (defined $self->{response});
  
      #################################################################
      # RESPONSE
      #################################################################
  
      my $response_class = $self->iget("responseClass", "P5EEx::Blue::Response::CGI");
  
      eval {
          $self->{response} = P5EEx::Blue::P5EE->new($response_class, "new", $self, 
$self->{initconfig});
      };
      $self->add_message($@) if ($@);
  
      return $self->{response};
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods
  
  These methods are considered protected because no class is ever supposed
  to call them.  They may however be called by the context-specific drivers.
  
  =cut
  
  #############################################################################
  # display_current_widget()
  #############################################################################
  
  =head2 display_current_widget()
  
      * Signature: $context->display_current_widget()
      * Param:     void
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->display_current_widget();
  
  The display_current_widget() method searches the "session widget" for an
  attribute of "current_widget" and uses that as the name of the widget which should
  be displayed in the browser.
  
  =cut
  
  sub display_current_widget {
      my $self = shift;
  
      my ($current_widget, $w);
      $current_widget = $self->wget("session","current_widget");
  
      if (!$current_widget) {  # no current widget is defined
  
          # see if the Request can suggest a default
          $current_widget = $self->request()->get_default_widget();
          $self->wset("session","current_widget",$current_widget) if ($current_widget);
  
          # maybe we can find it in the {initconfig}
          if (!$current_widget && defined $self->{initconfig}{defaultWname}) {
              $current_widget = $self->{initconfig}{defaultWname};
              $self->wset("session","current_widget",$current_widget) if 
($current_widget);
          }
  
          # oh well. just use "default".
          if (!$current_widget) {
              $current_widget = "default";
              $self->wset("session","current_widget",$current_widget);
          }
      }
  
      $w = $self->widget($current_widget);
      $self->display_items($w);
  }
  
  #############################################################################
  # display_items()
  #############################################################################
  
  =head2 display_items()
  
  The display_items() method takes an array of arguments and puts them all
  out to STDOUT with the appropriate headers.
  
      * Signature: $context->display_items(@items)
      * Param:     @items      @
      * Return:    void
      * Throws:    P5EEx::Blue::Exception
      * Since:     0.01
  
      Sample Usage: 
  
      $context->display_items("Hello world!");
  
  =cut
  
  sub display_items {
      my $self = shift;
  
      my $html = $self->html(@_);
  
      my ($title, $bodyoptions, $w, $var, $value, $context_body, $context_head);
  
      $title = "Perl 5 Enterprise Environment";
      $bodyoptions = "";
      $w = $_[0] if ($#_ > -1);
      if ($w && ref($w) && $w->isa("P5EEx::Blue::Widget")) {
          $title = $w->get("title");
          $title = $w->get("name") if (!$title);
          foreach $var ('bgcolor', 'text', 'link', 'vlink', 'alink',
                        'leftmargin', 'topmargin', 'rightmargin', 'bottommargin', 
'class') {
              $value = $w->get($var);
              if (defined $value && $value ne "") {
                  $bodyoptions .= " $var=\"$value\"";
              }
              elsif ($var eq "bgcolor") {
                  $bodyoptions .= " $var=\"#ffffff\"";
              }
          }
      }
  
      $context_body = $self->body_html(\%main::conf);
      $context_head = $self->head_html();
  
      my ($user_agent, $gzip_ok, $header, $data);
  
      $header = "Content-type: text/html\n";
      $data = <<EOF;
  <html>
  <head>
  <title>${title}</title>
  $context_head</head>
  <body${bodyoptions}>
  <form method="POST">
  $context_body
  $html</form>
  </body>
  </html>
  EOF
  
      if (defined $self->{headers}) {
          $header .= $self->{headers};
          delete $self->{headers}
      }
  
      if ($main::conf{gzip}) {
          $user_agent = $self->user_agent();
          $gzip_ok = $user_agent->supports("http.header.accept-encoding.x-gzip");
  
          if ($gzip_ok) {
              $header .= "Content-encoding: gzip\n";
              use Compress::Zlib;
              $data = Compress::Zlib::memGzip($data);
          }
      }
  
      print $header, "\n", $data;
  }
  
  sub html {
     my $self = shift;
     my ($item, $elem, $ref, @html, @elem);
  
     @html = ();
     foreach $item (@_) {
        next if (!defined $item);
        $ref = ref($item);
        $self->dbgprint("Context->html() $item => ref=[$ref]") if 
($P5EEx::Blue::DEBUG);
        next if ($ref eq "CODE" || $ref eq "GLOB");   # TODO: are there others?
  
        if ($ref eq "" || $ref eq "SCALAR") {
           $elem = ($ref eq "") ? $item : $$item;
           # borrowed from CGI::Util::simple_escape() ...
           $elem =~ s{&}{&amp;}gso;
           $elem =~ s{<}{&lt;}gso;
           $elem =~ s{>}{&gt;}gso;
           $elem =~ s{\"}{&quot;}gso;
           push(@html, $elem);
        }
        elsif ($ref eq "ARRAY") {
           push(@html, $self->html(@$item));
        }
        elsif ($ref eq "HASH") {
           @elem = ();
           foreach (sort keys %$item) {
              push(@elem, $item->{$_});
           }
           push(@html, $self->html(@elem));
        }
        else {
           push(@html, $item->html());  # assume if it's an object, that it has an 
html() method
        }
     }
     return join("",@html);
  }
  
  sub body_html {
      my ($self, $conf) = @_;
      $self->{session}->html();
  }
  
  sub head_html {
      my ($self) = @_;
      my ($html, $key, $keys);
      $keys = $self->{head}{keys};
      $html = "";
      if (defined $keys && ref($keys) eq "ARRAY") {
          foreach $key (sort @$keys) {
              $html .= $self->{head}{$key};
          }
      }
      $html;
  }
  
  sub set_head_html {
      my ($self, $key, $html) = @_;
      my ($keys);
      if (!defined $self->{head}{$key}) {
          $self->dbgprint(ref($self), "->set_head_html(): $key=[$html]")
              if ($P5EEx::Blue::DEBUG && $self->dbg(2));
          $self->{head}{$key} = $html;
          $keys = $self->{head}{keys};
          if (defined $keys && ref($keys) eq "ARRAY") {
              push(@$keys, $key);
          }
          else {
              $self->{head}{keys} = [ $key ];
          }
      }
      else {
          $self->dbgprint(ref($self), "->set_head_html(): $key=[repeat]")
              if ($P5EEx::Blue::DEBUG >= 3 && $self->dbg(3));
      }
  }
  
  sub set_header {
      my ($self, $header) = @_;
      if (defined $self->{headers}) {
          $self->{headers} .= $header;
      }
      else {
          $self->{headers} = $header;
      }
  }
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # log()
  #############################################################################
  
  =head2 log()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"log()">.
  
  =cut
  
  #############################################################################
  # user()
  #############################################################################
  
  =head2 user()
  
  The user() method returns the username of the authenticated user.
  The special name, "guest", refers to the unauthenticated (anonymous) user.
  
      * Signature: $username = $self->user();
      * Param:  void
      * Return: string
      * Throws: <none>
      * Since:  0.01
  
      Sample Usage: 
  
      $username = $context->user();
  
  In a request/response environment, this turns out to be a convenience
  method which gets the authenticated user from the current Request object.
  
  =cut
  
  sub user {
      my $self = shift;
      return $self->request()->user();
  }
  
  #############################################################################
  # config()
  #############################################################################
  
  =head2 config()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"config()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods: Debugging
  
  =cut
  
  #############################################################################
  # dbg()
  #############################################################################
  
  =head2 dbg()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"dbg()">.
  
  =cut
  
  #############################################################################
  # dbgprint()
  #############################################################################
  
  =head2 dbgprint()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"dbgprint()">.
  
  =cut
  
  #############################################################################
  # dbglevel()
  #############################################################################
  
  =head2 dbglevel()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"dbglevel()">.
  
  =cut
  
  #############################################################################
  # dbgscope()
  #############################################################################
  
  =head2 dbgscope()
  
  This method is inherited from
  L<C<P5EEx::Blue::Context>|P5EEx::Blue::Context/"dbgscope()">.
  
  =cut
  
  1;
  
  
  
  


Reply via email to