Hi,

The following is a quick summary of P5EEx::Blue with lots 
of references to the web documentation.

Stephen

--------------------------------
INTRODUCTION TO P5EEX::BLUE
--------------------------------

I. Getting Started

Before digging in to the code of P5EEx::Blue, it is good to look
around the P5EE web site.

   http://www.officevision.com/pub/p5ee/

Then explore the API documentation (which is of course not 
complete, but nonetheless very informative).

   http://www.officevision.com/pub/p5ee/software/htdocs/api/

In particular, the various services that form the building blocks
of P5EE applications are summarized.


http://www.officevision.com/pub/p5ee/software/htdocs/api/overview-summary.html

A quick look at the list of classes which represent *interfaces*
to the P5EE services and the various completed (and planned)
*implementations* of those service tell a great deal about
what each service is supposed to do.  You can, of course,
explored the detailed API of each service if you choose.


http://www.officevision.com/pub/p5ee/software/htdocs/api/allclasses-frame.html

The inheritance relationship of the classes can be seen at a
glance.

   http://www.officevision.com/pub/p5ee/software/htdocs/api/overview-tree.html

II. Architectural Principles

 * Pluggable Services
   The P5EEx::Blue is like a software backplane
   for many services required by an enterprise application.  Into that
   backplane plug the P5EE Services.  There may be many implementations
   of each of the P5EE Services, making for an almost limitless array
   of possible combinations.  (Hopefully, favorites will emerge.)

 * Separation of User Interface, Business Logic, and Data Storage
   These three layers of software need to be distinct and separate
   for maximum leverage of enterprise assets and maximum flexibility 
   of growth of the software. For web applications, the user interface
   is implemented with Widgets and Templates.  The business logic
   is coded in Entity Widgets and Procedures.  The data storage 
   logic, including locking and transactional facilities, is 
   controlled by the Repository.

 * Universal Access
   Any Business Logic coded anywhere in the Enterprise should be
   accessible from everywhere in the Enterprise.  Similarly, any
   Data stored anywhere in the Enterprise should be accessible
   from everywhere in the Enterprise.  SOAP is the primary
   protocol envisioned for this task, although others are also
   possible.  This allows for the User Interface, Business Logic,
   and Data Access components to be located on different machines.
   It also provides for sharing of data and logic with programs
   written in other languages.

 * Component-Based, Data-Driven Programming
   A large amount of the application development should be done
   by assembling pre-programmed application components merely 
   by configuring them in a configuration file.  The development
   may be completed by extending existing components with
   custom programming or creating entirely new components
   under the same programming model.

III. Core Services

There are three "Core Services": Context, Session, and Config.
A Core Service is one that is not derived from P5EEx::Blue::Service
but maintains the concept of "a pluggable implementation of an 
abstract service".

 * Context - abstracts all of the details of the runtime environment
     so that the same application can be deployed in a CGI Context,
     a mod_perl Context, or even FastCGI/PPerl/etc.
     The Context is responsible for maintaining the Session and
     dispatching events from the "event loop".  In a stateless
     (i.e. HTTP) environment, this means restoring and saving the
     Session for each request and dispatching events from multiple
     requests, while masking this complexity from the rest of the
     application.

 * Config - configuration data may be stored anywhere, although
     a simple configuration file is the most common. The job of
     the Config service is to retrieve the configuration
     information from whatever sources (XML file, INI file,
     Properties file, perl file) with the desired level of
     validation/caching/etc. and return a perl data structure
     of the appropriate form.

 * Session - All runtime data is stored in the Session object,
     which is implemented as a deeply-nested perl data structure.
     The differences between the different types of Session 
     implementations is how they store themselves. The Session
     data structure is made up of two branches: the "store" and
     the "cache".  The "store" is the minimum amount of 
     information that, along with the Config, can recreate the
     "cache".  The "cache" represents the runtime state of
     all Services, including Widgets (UI and Entity).

IV. Standard Services

The "Standard Services" are different types of application
components used to build an application.  They are all derived
from the Service class.

 * Serializer - transforms a perl struct to a scalar and back 
 * Security - provides authentication and authorization 
 * Widget - a user interface component or a business logic
     component 
 * Repository - a data store (RDBMS, File, Berkeley DB, etc.) 
 * TemplateEngine - encapsulates template system details,
     allowing P5EE to be used with any popular template engine 
 * LogChannel - a logging channel through which messages may 
     be logged.
 * Messaging - an asynchronous message queue with configurable
     quality of service. may be broadcast to many recipients
     and may be replied to multiple times by each recipient.
 * Procedure - a (potentially remote and/or asynchronous) 
     procedure which may be executed. Every procedure has
     only one set of results (i.e. one "reply").
 * SharedDatastore - a simple data storage area which is shared 
     between processes (like MLDBM)
 * SharedResourceSet - implements locking for synchronizing access
     and modification of shared resources

When the application wishes to use a Service, it simply requests
it by name from the Context.

   $w = $context->widget("users.table");

   or

   $w = $context->service("Widget", "users.table");

The application does not need to know what actual class implements
the widget.  It just trusts that the call interface for the specific
type of Service will be honored by the implementation.

The framework allows for new Services to be added easily.

V. Application Example

A quick CGI application using standard components can consist of:

  * p5ee.conf (in the cgi-bin directory)
  * app.pl    (in the cgi-bin directory)
  * SQL files (DDL to create tables in the database)

The files themselves are largely self-explanatory and illustrate the
power of the framework, transforming complex programming tasks into
assembly and configuration tasks.  (Of course, someone has to program
the complex components!) ;-)

The "p5ee.conf" file in the P5EEx::Blue distribution looks like
this.

#############################################################################
# $Id: p5ee.conf,v 1.1 2002/04/14 03:56:24 spadkins Exp $
#############################################################################

perlinc       = /usr/ov/acoc/dev/src/P5EEx-Blue,
/usr/ov/acoc/dev/lib/perl5/5.6.0
debugmode     = record
showsession   = 1
gzip          = 1
configFile    = demo.pl
defaultWname  = report
debug         = 0
debugfile     = debug.out
scriptUrlDir  = /cgi-bin/pub/p5ee
scriptDir     = /usr/ov/acoc/dev/p5ee/P5EEx/Blue/cgi-bin
htmlUrlDir    = /pub/p5ee/software/htdocs
htmlDir       = /usr/ov/acoc/dev/p5ee/P5EEx/Blue/htdocs
ttTemplateDir = /usr/ov/acoc/dev/p5ee/P5EEx/Blue/template/ttdemo

The "demo.pl" file in the P5EEx::Blue distribution could be narrowed down
to the following.

$data = {
  #########################################################################
  # $Id: demo.pl,v 1.3 2002/04/19 14:38:44 spadkins Exp $
  # NOTE: this is after the "$data = {" line for a reason
  #########################################################################
  WidgetType => {
    table => {
      widgetClass => 'P5EEx::Blue::Widget::HTML::DataTable',
      repository  => 'db',
      table       => 'person',
      headings    => [ "ID", "Last Name", "First Name", "Address", "City",
"State", "Home Phone", "Sex", "Birth Date" ],
      columns => [ "person_id", "last_name", "first_name", "address",
"city", "state", "home_phone", "gender", "birth_dt" ],
      keycolidx   => [ 0 ],
      scrollable  => 1,
      sortable    => 1,
      filterable  => 1,
      editable    => 1,
    },
    app => {
      widgetClass => 'P5EEx::Blue::Widget::HTML::AppFrame',
      title => "P5EE Reporting and Data Maintenance",
      bgcolor => "#cccccc",
      text => "#000000",
      link => "#996600",
      vlink => "#996600",
      alink => "#996600",
      leftmargin => "0",
      topmargin => "0",
      rightmargin => "0",
      bottommargin => "0",
    },
  },
  Repository => {
    default => {
      repositoryClass => 'P5EEx::Blue::Repository::DBI',
      dbidriver => "mysql",
      dbname => "p5ee_demo",
      dbuser => "dbuser",
      dbpass => "dbuser7",
      table => {
        person => {
          prikey => [ "person_id" ],
        },
      },
    },
  },
  Widget => {
    report => {
      widgetType => 'app',
    },
    'report.selector' => {
      widgetClass => 'P5EEx::Blue::Widget::HTML::SelectorView',
      selected => "1.1",
      node => {
        1 =>       { open => 1, value => 'Reports',
       icon => 'calendar.gif' },
        1.1 =>     { open => 1, value => 'People',               wname =>
'table',                        },
      },
    },
    table => { widgetType => 'table', },
  },
};



Reply via email to