[Rt-commit] [svn] r779 - in experiments/Bamboo: . lib/Bamboo/Model lib/Bamboo/Model/ProxyObject lib/Bamboo/Model/ProxyObject/RT lib/Bamboo/View lib/Bamboo/View/ObjectType lib/Bamboo/View/Renderer lib/Bamboo/View/Renderer/Display lib/Bamboo/View/Renderer/Display/RT lib/Bamboo/View/Renderer/Edit lib/Bamboo/View/Renderer/Edit/RT lib/Bamboo/View/Renderer/Label lib/Bamboo/View/Validator mason mason/Bamboo mason/Bamboo/View mason/Bamboo/View/ObjectType mason/Bamboo/View/Renderer mason/Bamboo/View/Renderer/Display mason/Bamboo/View/Renderer/Display/RT mason/Bamboo/View/Renderer/Edit mason/Bamboo/View/Renderer/Edit/RT mason/Bamboo/View/Renderer/Label mason/Bamboo/View/Validator

jesse at pallas.eruditorum.org jesse at pallas.eruditorum.org
Fri Apr 30 14:26:09 EDT 2004


Author: jesse
Date: Fri Apr 30 14:26:08 2004
New Revision: 779

Added:
   experiments/Bamboo/lib/Bamboo/Model/ProxyObject/
   experiments/Bamboo/lib/Bamboo/Model/ProxyObject.pm
   experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/
   experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Queue.pm
   experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Ticket.pm
   experiments/Bamboo/lib/Bamboo/View/AttributeMap
   experiments/Bamboo/lib/Bamboo/View/Create
   experiments/Bamboo/lib/Bamboo/View/CreateOrUpdate
   experiments/Bamboo/lib/Bamboo/View/CreateOrUpdateAllObjects
   experiments/Bamboo/lib/Bamboo/View/Header
   experiments/Bamboo/lib/Bamboo/View/ListResults
   experiments/Bamboo/lib/Bamboo/View/ObjectSelect
   experiments/Bamboo/lib/Bamboo/View/ObjectType/
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Attachment
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__GroupMember
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Queue
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Ticket
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Transaction
   experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__User
   experiments/Bamboo/lib/Bamboo/View/Renderer/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Date
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/EmailMessage
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/HREF
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Minutes
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/GroupMembers
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/Queue
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/User
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/datetime
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/integer
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/scalar
   experiments/Bamboo/lib/Bamboo/View/Renderer/Display/varchar
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Date
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Minutes
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/RT/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/RT/Queue
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/_attribute_name
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/checkbox
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/int
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/integer
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/scalar
   experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/varchar
   experiments/Bamboo/lib/Bamboo/View/Renderer/Label/
   experiments/Bamboo/lib/Bamboo/View/Renderer/Label/Label
   experiments/Bamboo/lib/Bamboo/View/Update
   experiments/Bamboo/lib/Bamboo/View/Validator/
   experiments/Bamboo/lib/Bamboo/View/Validator/Boolean
   experiments/Bamboo/lib/Bamboo/View/Validator/Date
   experiments/Bamboo/lib/Bamboo/View/WebMethodCall
   experiments/Bamboo/mason/
   experiments/Bamboo/mason/Bamboo/
   experiments/Bamboo/mason/Bamboo/View/
   experiments/Bamboo/mason/Bamboo/View/AttributeMap
   experiments/Bamboo/mason/Bamboo/View/Create
   experiments/Bamboo/mason/Bamboo/View/CreateOrUpdate
   experiments/Bamboo/mason/Bamboo/View/CreateOrUpdateAllObjects
   experiments/Bamboo/mason/Bamboo/View/Header
   experiments/Bamboo/mason/Bamboo/View/ListResults
   experiments/Bamboo/mason/Bamboo/View/ObjectSelect
   experiments/Bamboo/mason/Bamboo/View/ObjectType/
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Attachment
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__GroupMember
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Queue
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Ticket
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Transaction
   experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__User
   experiments/Bamboo/mason/Bamboo/View/Renderer/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Date
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/EmailMessage
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/HREF
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Minutes
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/GroupMembers
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/Queue
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/User
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/datetime
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/integer
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/scalar
   experiments/Bamboo/mason/Bamboo/View/Renderer/Display/varchar
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Date
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Minutes
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/RT/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/RT/Queue
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/_attribute_name
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/checkbox
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/int
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/integer
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/scalar
   experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/varchar
   experiments/Bamboo/mason/Bamboo/View/Renderer/Label/
   experiments/Bamboo/mason/Bamboo/View/Renderer/Label/Label
   experiments/Bamboo/mason/Bamboo/View/Update
   experiments/Bamboo/mason/Bamboo/View/Validator/
   experiments/Bamboo/mason/Bamboo/View/Validator/Boolean
   experiments/Bamboo/mason/Bamboo/View/Validator/Date
   experiments/Bamboo/mason/Bamboo/View/WebMethodCall
Modified:
   experiments/Bamboo/   (props changed)
Log:
----------------------------------------------------------------------
r2079 at tinbook:  jesse | 2004-04-18T22:06:04.092422Z


----------------------------------------------------------------------
r2254 at tinbook:  jesse | 2004-04-30T18:24:23.920912Z

Bamboo isn't something that works or is expected to work yet. But I want it in svn, rather than just on my laptop

----------------------------------------------------------------------


Added: experiments/Bamboo/lib/Bamboo/Model/ProxyObject.pm
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/Model/ProxyObject.pm	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,245 @@
+use strict;
+package RT::Web::ProxyObject;
+use Params::Validate qw(:all);
+
+
+use vars qw($_RENDER $_METHODS $_ERRORS );
+
+=head2 new
+
+=item Type
+=item CurrentUser
+=item id
+
+=begin testing
+
+
+use lib qw(/opt/rt3/lib);
+
+use RT;
+RT::LoadConfig;
+RT::Init();
+
+use_ok(RT::Web::ProxyObject);
+my $blank =  RT::Web::ProxyObject->new();
+ok(!$blank,$blank);
+use_ok(RT::Queue);
+use_ok(RT::CurrentUser);
+my $rtuser = 'RT::Queue';
+my $foo = RT::Web::ProxyObject->new(
+    Type        => $rtuser,
+    id          => '1'
+);
+ok(!$foo,$foo);
+ $foo = RT::Web::ProxyObject->new(
+    CurrentUser => RT::CurrentUser->new('root'),
+    id          => '1'
+);
+ok(!$foo,$foo);
+ $foo = RT::Web::ProxyObject->new(
+    Type        => $rtuser,
+    CurrentUser => RT::CurrentUser->new('root'),
+);
+ok(!$foo,$foo);
+ $foo = RT::Web::ProxyObject->new(
+    Type        => $rtuser,
+    CurrentUser => RT::CurrentUser->new('root'),
+    id          => '1'
+);
+ok($foo, "Type is $rtuser, Currentuser is root and id is 1 - '$foo'");
+is(ref($foo), 'RT::Web::ProxyObject::RT::Queue');
+
+=end testing
+
+=cut
+
+sub new {
+  my $proto = shift;
+    my $self = {};
+    my %args;
+
+    eval {
+   %args = validate( @_, {
+                Type => {  type => SCALAR },
+                CurrentUser => {isa => 'RT::CurrentUser'},
+                id => { regex => qr/^\d+$/ }
+        });
+    };
+
+    if ($@) {
+        $RT::Logger->debug($@);
+        return ($@);
+    }
+
+
+        my $object_type = "RT::Web::ProxyObject::".$args{'Type'};
+       warn "OBject type is $object_type";
+        eval "require $object_type";
+    if ($@){
+        warn $@;
+        $RT::Logger->debug($@);
+    }
+        bless ($self, $object_type); 
+
+    return($self);
+
+}
+
+
+sub ProxyForObject {
+    my $self = shift;
+    if ($_[0]) {
+    my $object = shift;
+
+    $self->{_Object} = $object;
+    }
+    return ($self->{_Object});
+}
+
+
+sub HasMethod {    # should this be called 'can'
+    my $self   = shift;
+    my $method = shift;
+
+    if ( defined( $_METHODS->{$method} ) ) {
+        return 1;
+    }
+    else {
+        return undef;
+    }
+
+}
+
+=head2 MethodParameters METHOD
+
+Takes a scalar name of a method
+Returns a reference to a hash whose keys are the parameters this method takes.
+The value of each hash parameter points to a canonicalizer and validator for that parameter.
+
+
+=cut
+
+
+sub MethodParameters {
+    my $self   = shift;
+    my $method = shift;
+
+    #return the parameters this object expects for this method
+    return ( $_METHODS->{$method}->{params} );
+
+}
+
+sub MethodHasParameter {
+    my $self = shift;
+    my %args = (
+        Method    => undef,
+        Parameter => undef,
+        @_
+    );
+
+    if ( $self->MethodParameter( $args{'Method'} )->{ $args{'Parameter'} } ) {
+        return (1);
+    }
+    else {
+        return undef;
+    }
+
+}
+
+sub RendererForAttribute {
+    my $self = shift;
+    my %args = (
+        Attribute => undef,
+        Mode      => 'Display',
+        @_
+    );
+
+    my $renderer = $_RENDER->{ $args{'Attribute'} }->{ $args{'Mode'} };
+    if ( ref($renderer) ) {
+
+# if we get a reference, we have something more than a simple component renderer
+#  for example, RT::Ticket->Requestors should by default render as an unordered list of the Members of the requestors group
+
+    }
+
+    return ($renderer);
+}
+
+
+=head2 ValidateMethodCall { Method => SCALAR, Parameters => HASHREF }
+
+
+Takes a method name and a hashref to the proposed parameters for this method.
+Validates the method and proposed parameters. Returns true if the method call is safe to make and false if not.
+
+
+** This method canonicalizes and massages the parameters in place.
+
+
+=cut
+
+
+
+sub ValidateMethodCall {
+    my $self = shift;
+    my %args = (
+        Method     => undef,
+        Parameters => undef,
+        @_
+    );
+
+    # make sure it's an ok method
+    return undef unless ($self->HasMethod($args{'Method'}));  
+
+   
+    # canonicalize each parameter
+    $self->CanonicalizeMethodParameters(Parameters => $args{'Parameters'}, Method => $args{'Method'});  
+   
+    # make sure only known parameters are listed
+  
+    $self->PruneMethodParameters(Parameters => $args{'Parameters'}, Method => $args{'Method'});  
+    
+    # make sure that each of the parameters is valid
+
+    #XX Call the validate sub
+
+
+}
+
+
+sub PruneMethodParameters {
+    my $self = shift;
+    my %args = (
+        Parameters => undef,
+        Method     => undef,
+        @_
+    );
+
+
+}
+
+
+sub CanonicalizeMethodParameters {
+    my $self = shift;
+    my %args = (
+        Parameters => undef,
+        Method     => undef,
+        @_
+    );
+
+    foreach my $param (keys %{$args{'Parameters'}}) {
+        unless ($self->MethodHasParameter(Method => $args{'Method'}, Parameter => $param )) {
+            delete $args{'Parameters'}->{$param};
+        }
+
+    }
+
+
+}
+
+
+
+
+
+
+    1;

Added: experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Queue.pm
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Queue.pm	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,55 @@
+use strict;
+
+
+package RT::Web::ProxyObject::RT::Queue;
+
+use base qw/RT::Web::ProxyObject/;
+
+my $_RENDERERS = {
+    id                => { Render => 'integer' },
+    Name              => { Render => 'scalar', Edit => 1 },
+    Description       => { Render => 'scalar', Edit => 1 },
+    DefaultDueIn      => { Render => 'integer', Edit => 1 },
+    CommentAddress    => { Render => 'email_address', Edit => 1 },
+    CorrespondAddress => { Render => 'email_address', Edit => 1 },
+    InitialPriority   => { Render => 'integer', Edit => 1 },
+    FinalPriority     => { Render => 'integer', Edit => 1 },
+    Disabled => { Render   => 'checkbox', Validator => 'Boolean', Edit => 1 },
+    Cc       => { RenderAs => '' },
+    AdminCc  => { RenderAs => '' },
+
+};
+
+my $_METHOD = {
+
+    Create => {
+        params => {
+            Name        => { type => 'scalar', },
+            Description => { type => 'scalar' },
+            Disabled    => { type => 'boolean' },
+        }
+    },
+    SetName        => { params => { __1 => { type => 'scalar' } } },
+    SetDescription => { params => { __1 => { type => 'scalar' } } },
+    SetDisabled    => { params => { __1 => { type => 'boolean' } } },
+
+    AddWatcher => {
+        params => {
+            Type => { type => qw[Cc AdminCc] }
+            ,    # the type is an enumerated list of acceptable values
+            id           => { type => 'RT::Principal->Id' },
+            EmailAddress => { type => 'email_address' },
+        }
+    },
+    DeleteWatcher => {
+        params => {
+            Type => { type => qw[Cc AdminCc] },
+
+            # the type is an enumerated list of acceptable values
+            id           => { type => 'RT::Principal->Id' },
+            EmailAddress => { type => 'email_address' },
+        }
+    }
+};
+
+1;

Added: experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Ticket.pm
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/Model/ProxyObject/RT/Ticket.pm	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,93 @@
+
+use strict;
+package RT::Interface::Web::ObjectType::RT::Ticket;
+use base qw/RT::Interface::Web::ObjectType/;
+
+
+
+our $CALLABLE_METHODS = {
+
+        Create => {     
+                    Subject => { type => 'scalar'},
+                    Status => { type => 'RT::Status'}, # Do we want to do this
+                    InitialPriority => { type => 'integer'},
+                    FinalPriority => { type => 'integer'},
+
+
+                   },
+
+        Comment => { 
+                    Subject => { type => 'scalar'},
+                    TimeWorked => { type => 'integer'},
+                    Content => { type => 'scalar'},
+                    Attachments => { type => 'scalar-array'},
+                    },
+        Correspond => { 
+                    Subject => { type => 'scalar'},
+                    TimeWorked => { type => 'integer'},
+                    Content => { type => 'scalar'},
+                    Attachments => { type => 'scalar-array'},
+                    },
+
+        SetStatus => {
+                        _argument => {type => 'RT::Status'}
+                    },
+
+        SetSubject => {
+                        _argument => {type => 'scalar'}
+                    },
+        SetDue => {
+                        _argument => {type => 'date'}
+                    },
+
+    };
+
+our $RENDERERABLE = {
+
+        id => { Type => 'integer', Immutable => 1 },
+        EffectiveId => { Type => 'integer', Immutable => 1 },
+        Priority => { Type => 'integer' },
+        FinalPriority => { Type => 'integer' },
+        InitialPriority => { Type => 'integer' },
+        Queue => { Render=> 'RT/Queue'},
+        Status => { Type => 'scalar' },
+        Subject => { Type => 'scalar'},
+        Type => { Type => 'scalar',
+
+        TimeWorked => { Type => 'Minutes'},
+        TimeLeft => { Type => 'Minutes'},
+        TimeEstimated => { Type => 'Minutes'},
+        
+        LastUpdated => {  Type => 'Date', Immutable => 1 },
+        Created => {  Type => 'Date' ,  Immutable => 1},
+        Starts => {  Type => 'Date', Validator => 'Date'},
+        Started => {  Type => 'Date', Validator => 'Date'},
+        Told => {  Type => 'Date', Validator => 'Date'},
+        Resolved => {  Type => 'Date', Validator => 'Date'},
+        Due => {  Type => 'Date', Validator => 'Date'},
+        Owner => {  RenderAs => 'Attribute', Object => $Object->OwnerObj, Attribute => 'Name' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name' , Immutable => 1 },
+        LastUpdatedBy =>    {  RenderAs => 'Attribute', Object => $Object->LastUpdatedByObj, Attribute => 'Name' , Immutable => 1 },
+        Requestors => {  RenderAs => 'CollectionAsList' , Object => $Object->Requestors->MembersObj, Attribute => { Name => 'Name' }},
+        Ccs => {  Type => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        Cc => {  Type => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        AdminCcs => {  Type => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        AdminCc => {  Type => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        RefersTo =>  {RenderAs => 'CollectionAsList' , Object => $Object->RefersTo, Attribute => 'Target'},
+        DependsOn =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependsOn, Attribute => 'Target'},
+        ReferredToBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->ReferredToBy, Attribute => 'Target'},
+        MemberOf =>  {RenderAs => 'CollectionAsList' , Object => $Object->MemberOf, Attribute => 'Target'},
+        DependedOnBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependedOnBy, Attribute => 'Target'},
+        Members =>  {RenderAs => 'CollectionAsList' , Object => $Object->Members, Attribute => 'Target'}
+
+    }
+
+
+
+        my $cfs = $Object->QueueObj->CustomFields();
+        while (my $cf = $cfs->Next) {
+                $params->{$cf->Name} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+                $params->{'CustomField-'.$cf->id} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+        }
+
+        return ($params );

Added: experiments/Bamboo/lib/Bamboo/View/AttributeMap
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/AttributeMap	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,13 @@
+<%args>
+$Object => undef
+</%args>
+<%init>;
+my $ObjectType = ref($Object);
+$ObjectType =~ s/:/_/gi;
+my $AttributeMap;
+if ( $m->comp_exists("ObjectType/$ObjectType") ) {
+    $AttributeMap = $m->comp( "ObjectType/$ObjectType", %ARGS );
+}
+return $AttributeMap;
+
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Create
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Create	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,34 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+
+
+    my %attrs;
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name =$FormTag . "-Create-" . $attr;
+        $RT::Logger->crit( "Looking for $attr_uri_param_name");
+	
+        $attrs{$attr} = $ARGS{$attr_uri_param_name}
+          if ( $ARGS{$attr_uri_param_name} );
+    } 
+    use Data::Dumper;
+    $RT::Logger->crit(Dumper \%attrs);
+
+    my ( $id, $msg ) = $Object->Create(%attrs);
+    if ($id) {
+        $msg ||= loc("Object created");
+        $Messages->{'create'} = $msg;
+        $NewObjectIdMap->{$FormTag} = $id;
+    }
+    else {
+	$RT::Logger->error("Object creation failed for $FormTag / $Object");
+        $_ERRORS{$FormTag."-Create"} = $msg;
+    }
+
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/CreateOrUpdate
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/CreateOrUpdate	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,85 @@
+<%ARGS>
+$Object => undef
+$Messages => undef
+$Errors => undef
+</%ARGS>
+<%init>
+
+
+if ( $ARGS{'id'} eq 'new' ) {
+
+    my %attrs;
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name =
+          ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+        $attrs{$attr} = $ARGS{$attr_uri_param_name}
+          if ( $ARGS{$attr_uri_param_name} );
+    }
+    my ( $id, $msg ) = $Object->Create(%attrs);
+    if ($id) {
+        $msg ||= loc("Object created");
+        $Messages->{'create'} = $msg;
+        $session{'created_object'} = $id;
+    }
+    else {
+        $Errors->{'create'} = $msg;
+    }
+
+}
+elsif ( $ARGS{'id'} ) {
+    $Object->Load( $ARGS{'id'} );
+    unless ( $Object->id ) {
+        Abort("No such Object");
+    }
+
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name = ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+
+
+        my $value;
+        next unless ( exists $ARGS{$attr_uri_param_name}
+            || $ARGS{ $attr_uri_param_name . "-previous-value" } );
+
+   # If no value is set, but there was a value before, that means the user
+   # unclicked a checkbox. would be nice if html forms conveyed this information
+   # back to the server
+        if ( !exists $ARGS{$attr_uri_param_name} ) {
+            if ( $ARGS{ $attr_uri_param_name . "-previous-value" } == 1 ) {
+                $value = 0;
+            }
+
+        }
+        else {
+                $RT::Logger->debug("Found $attr_uri_param_name");
+             $value = $ARGS{$attr_uri_param_name};
+        }
+        my $AttributeMap = $m->comp( 'AttributeMap', Object => $Object );
+        if ( $AttributeMap->{$attr}->{Validator} ) {
+            if ( $m->comp_exists( "Validator/" . $AttributeMap->{$attr}->{Validator})) {
+                $value = $m->comp(
+                    "Validator/" . $AttributeMap->{$attr}->{Validator},
+                    Object        => $Object,
+                    AttributeName => $attr,
+                    Value         => $value
+                );
+            }
+            else {
+                $m->out( "Couldn't find " . $AttributeMap->{$attr}->{Validator} );
+            }
+        }
+        
+                $RT::Logger->debug("The value is finally $value");
+            next unless ( defined $value
+                && ( $Object->$attr() ne $value ) );
+            my $set = "Set$attr";
+            my ( $val, $msg ) = $Object->$set($value);
+            if ($val) {
+                $Messages->{$attr} = $msg;
+            }
+            else {
+                $Errors->{$attr} = $msg;
+            }
+
+    }
+}
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/CreateOrUpdateAllObjects
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/CreateOrUpdateAllObjects	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,99 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+use URI;
+use URI::QueryParam;
+
+# objects we're creating
+my $creates = {};
+
+# method calls we're performing
+my $calls = {};
+
+# Iterate through %ARGS and slice and dice into
+# Object we're working on
+#   Method calls for those objects
+#     Params for  those method calls
+foreach my $attr ( keys %ARGS ) {
+
+    next unless ( $attr =~ /^(.*?)-(.*?)-(.*?)-(.*?)/ );
+    my $object_type = $1;
+    my $object_id   = $2;
+    my $method      = $3;
+    my $param_name  = $4;
+    my $param_value = $ARGS{$attr};
+
+    push (
+        @{ $calls->{$object_type}->{$object_id}->{$method}->{$param_name} },
+        $param_value
+    );
+
+}
+
+# now that we have all the things we're doing, let's create the objects we need to and then perform all the updates to the other objects we're updating.
+
+# for each object type
+foreach my $object_type ( keys %$calls ) {
+
+    foreach my $object_id ( keys %{ $calls->{$object_type} } ) {
+
+        # Instantiate a proxy object
+        my $proxy = RT::ProxyObject->new(
+            CurrentUser => $session{'CurrentUser'},
+            Type        => $object_type,
+            id          => $object_id
+        );
+    
+        # XXX TODO this should handle Create then any other method
+        foreach my $method ( keys %{ $calls->{$object_type}->{$object_id} } ) {
+            
+            # Call the method on the proxy object with the params listed here
+            $RT::Logger->debug( "$object_type->new()->Load($object_id)->$method ( ");
+
+            my $params_ref = $calls->{$object_type}->{$object_id}->{$method};
+
+            $proxy->$method($params_ref);
+    
+            #XXX TODO get URL forwarding happening
+
+                #$NewObjectIdMap->{$FormTag} = $id;
+
+        }
+
+    }
+
+}
+
+my $new_obj_id_map = {};
+
+if ( ( !keys %_ERRORS ) && $ARGS{'_OnSuccessGotoPage'} ) {
+    my $goto = $ARGS{'_OnSuccessGotoPage'};
+    my $URI  = URI->new($goto);
+
+    my $goto_id = $URI->query_param('id');
+
+    if ( $goto_id =~ /^(.*?)-new-(.*?)$/ ) {
+        $URI->query_param( 'id' => $new_obj_id_map->{$goto_id} );
+    }
+
+    my $flow_id = time() . int( rand(1000) );
+
+    $URI->query_param( 'flow_id' => $flow_id );
+
+    %{ $session{ '_MESSAGES-' . $flow_id } } = %_MESSAGES;
+
+    # here we should deal with a way to preserve errors and messages when
+    # shoving off to the new page.
+    # I think the right answer is to stuff them in the session with a
+    # key that the new page can use to pull them out and clear them.
+
+    $m->redirect( $URI->as_string );
+}
+
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Header
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Header	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,63 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE><%$Title%></TITLE>
+% if ($Refresh > 0) {
+<META HTTP-EQUIV="REFRESH" CONTENT="<%$Refresh%>">
+% }
+
+<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png">
+<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css">
+</HEAD>
+<BODY BGCOLOR="<%$BgColor%>"
+% if ($Focus) {
+ONLOAD="
+    var tmp = (document.getElementsByName('<% $Focus %>'));
+    if (tmp.length > 0) tmp[tmp.length-1].focus();
+"
+% }
+>
+<%$m->content()|n%>
+</body>
+</html>
+<%INIT>
+
+$r->header_out('Pragma' => 'no-cache');
+$r->header_out('Cache-control' => 'no-cache');
+</%INIT>
+
+<%ARGS>
+$Prefs => '/User/Prefs.html'
+$Focus => 'focus'
+$Title => undef
+$Code => undef
+$Refresh => 0
+$Why => undef
+$BgColor => '#ffffff'
+$ShowBar => 1
+$LoggedIn => 1
+$URL => undef
+</%ARGS>

Added: experiments/Bamboo/lib/Bamboo/View/ListResults
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ListResults	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,27 @@
+<span class="system_messages">
+<ul>
+% if ($session{'_MESSAGES-'.$flow_id}) {
+% foreach my $message (%{$session{'_MESSAGES-'.$flow_id}}) {
+% next unless ($message);
+<li><% $session{'_MESSAGES-'.$flow_id}->{$message} %></li>
+% }
+%}
+% delete  $session{'_MESSAGES-'.$flow_id};
+
+% foreach my $message (keys %_MESSAGES){ 
+% next unless ($message);
+<li><% $_MESSAGES{$message} %></li>
+% }
+</ul>
+<ul>
+% foreach my $message (keys %_ERRORS){ 
+<li class="error"><%$_ERRORS{$message}%></li>
+% }
+</ul>
+</span>
+<%init>
+
+my $request_args = $m->request_args();
+my $flow_id = $request_args->{'flow_id'};
+
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectSelect
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectSelect	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,36 @@
+<select  <& ObjectInputName, Name => $Name, Object => $Object, Attribute => $Attribute&>>
+% foreach my $option (@Values) {
+% if (UNIVERSAL::isa($option, 'DBIx::SearchBuilder::Record')) {
+<option value="<%$option->Id%>" <%$option eq $Default && 'SELECTED'%>>
+%       if (UNIVERSAL::can($option, 'Name' )){
+<%$option->Name%>
+% } else {
+<%$option->id%>
+% }
+</option>
+% } else {
+<option value="<%$option%>" <%$option eq $Default && 'SELECTED'%>><%$option%></option>
+% }
+%}
+</select>
+<%init>
+
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+ at Values => undef
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Attachment
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Attachment	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return({ 
+        id => { Render => 'integer' },
+        BriefDescription => {Render => 'scalar'},
+        Created => {  Render => 'Date' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name'  },
+        Content =>  {Render => 'Scalar' }
+
+});
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__GroupMember
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__GroupMember	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,10 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { RenderAs => 'Attribute', Object => $Object->MemberObj->Object, Attribute => 'Name' },
+
+});
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { Render => 'scalar', Edit => undef, },
+        Disabled => { Render => 'checkbox', Validator => 'Boolean' },
+
+});
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Ticket
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Ticket	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,54 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+my $params = { 
+        id => { Render => 'integer', Immutable => 1 },
+        EffectiveId => { Render => 'integer', Immutable => 1 },
+        Priority => { Render => 'integer' },
+        FinalPriority => { Render => 'integer' },
+        InitialPriority => { Render => 'integer' },
+        Queue => { Render=> 'RT/Queue'},
+        Status => { Render => 'scalar' },
+        Subject => { Render => 'scalar', Edit => undef, },
+        Type => { Render => 'scalar', Edit => undef, },
+
+        TimeWorked => { Render => 'Minutes'},
+        TimeLeft => { Render => 'Minutes'},
+        TimeEstimated => { Render => 'Minutes'},
+        
+        LastUpdated => {  Render => 'Date', Immutable => 1 },
+        Created => {  Render => 'Date' ,  Immutable => 1},
+        Starts => {  Render => 'Date', Validator => 'Date'},
+        Started => {  Render => 'Date', Validator => 'Date'},
+        Told => {  Render => 'Date', Validator => 'Date'},
+        Resolved => {  Render => 'Date', Validator => 'Date'},
+        Due => {  Render => 'Date', Validator => 'Date'},
+        Owner => {  RenderAs => 'Attribute', Object => $Object->OwnerObj, Attribute => 'Name' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name' , Immutable => 1 },
+        LastUpdatedBy =>    {  RenderAs => 'Attribute', Object => $Object->LastUpdatedByObj, Attribute => 'Name' , Immutable => 1 },
+        Requestors => {  RenderAs => 'CollectionAsList' , Object => $Object->Requestors->MembersObj, Attribute => { Name => 'Name' }},
+        Ccs => {  Render => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        Cc => {  Render => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        AdminCcs => {  Render => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        AdminCc => {  Render => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        RefersTo =>  {RenderAs => 'CollectionAsList' , Object => $Object->RefersTo, Attribute => 'Target'},
+        DependsOn =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependsOn, Attribute => 'Target'},
+        ReferredToBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->ReferredToBy, Attribute => 'Target'},
+        MemberOf =>  {RenderAs => 'CollectionAsList' , Object => $Object->MemberOf, Attribute => 'Target'},
+        DependedOnBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependedOnBy, Attribute => 'Target'},
+        Members =>  {RenderAs => 'CollectionAsList' , Object => $Object->Members, Attribute => 'Target'}
+
+};
+
+
+        my $cfs = $Object->QueueObj->CustomFields();
+        while (my $cf = $cfs->Next) {
+                $params->{$cf->Name} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+                $params->{'CustomField-'.$cf->id} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+        }
+
+        return ($params );
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Transaction
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__Transaction	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return({ 
+        id => { Render => 'integer' },
+        BriefDescription => {Render => 'scalar'},
+        Created => {  Render => 'Date' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name'  },
+        Content =>  {RenderAs => 'CollectionAsList' , Object => $Object->Attachments, Attribute => 'Content'}
+
+});
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__User
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/ObjectType/RT__User	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,10 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { Render => 'scalar', Edit => undef, },
+
+});
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,19 @@
+<%args>
+$Value => undef
+$Attribute => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+# someday we may want to treat it differently
+ my $date_obj = RT::Date->new($session{'CurrentUser'});
+
+if ($Object && $AttributeName) {
+ $date_obj->Set( Format => 'ISO', Value => $Object->$AttributeName() );
+} else {
+ $date_obj->Set( Format => 'ISO', Value =>  $Value);
+}
+$m->out('<span class="date">');
+$m->comp('scalar', Value => $date_obj->AsString);
+$m->out('</span>');
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/EmailMessage
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/EmailMessage	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,51 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return unless ( $Object->ContentLength || $Object->Children->Count );
+
+my $content = $Object->Content;
+RT::Interface::Web::EscapeUTF8( \$content );
+
+my ( $headers, $quoted );
+if ( 0)  {
+    $headers = $Object->Headers;
+}
+else {
+    $headers = $Object->NiceHeaders;
+}
+chomp $headers;
+if ($headers) {
+    # localize the common headers (like 'Subject:'), too.
+    eval {
+        $headers =~ s/^([^:]+)(?=:)/loc($1)/em;
+      }    # we eval here to catch errors when 5.6 panics
+}
+
+# 13456 is a random # of about the biggest size we want to see inline text
+# It's here to catch anyone who hasn't updated RT_Config.pm since this
+# constant was moved out there.
+my $MAX_INLINE_BODY = $RT::MaxInlineBody || 13456;
+if (   $Object->ContentType =~ m{^(text/plain|Object|text$)}i
+    && $Object->ContentLength < $MAX_INLINE_BODY ) {
+    require Text::Quoted;
+    $quoted = Text::Quoted::extract( $Object->Content );
+}
+        
+$m->comp('/Elements/Callback', Name => 'MassageHeaders',  Headers => \$headers, %ARGS);
+</%init>
+<span class="Object">
+<table>
+% $headers =~ s/^\s+//gm;
+<span class="message-headers">
+% foreach my $header (split(/\n/,$headers)) {
+<%$header%><br>
+%}
+</span class="message-headers">
+</table>
+<PRE>
+<%$Object->Content%>
+</PRE>
+</span>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/HREF
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/HREF	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,20 @@
+<%ARGS>
+$Attribute => undef
+$Object => undef
+</%ARGS>
+<%init>
+unless (ref($Attribute) && $Attribute->{Link}) {
+        $m->out($m->content);
+        return
+}
+my $href = $Attribute->{'Link'};
+
+my $id = $Object->id;
+$href =~ s/##id##/$id/i;
+
+if ($href =~ /^\//) {
+        $href = $RT::WebPath .$href;
+}
+
+</%init>
+<A HREF="<%$href%>"><%$m->content|n%></A>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Minutes
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/Minutes	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+if (!$Value && ref($Object) && $Attribute && UNIVERSAL::can($Object, $Attribute)) {
+        $Value = $Object->$Attribute() ;
+}
+</%init>
+<&|/l, int($Value) &>[_1] minutes</&>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/GroupMembers
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/GroupMembers	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+$Attribute => undef
+$Value => undef
+</%args>
+% my $Group = &$Value;
+% my $Users = $Group->UserMembersObj;
+<ul>
+% while (my $user = $Users->Next) { 
+<li><%$user->Name%> 
+% if ($user->EmailAddress) {
+(<%$user->EmailAddress%>)
+% }
+% }
+</ul>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,9 @@
+<%args>
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+my $Queue = RT::Queue->new($session{'CurrentUser'});
+$Queue->Load($Object->$Attribute());
+</%init>
+<%$Queue->Name%> 

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/User
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/RT/User	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,12 @@
+<%args>
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+my $user = RT::User->new($session{'CurrentUser'});
+$user->Load($Object->$Attribute());
+</%init>
+<%$user->Name%> 
+% if ($user->EmailAddress) {
+(<%$user->EmailAddress%>)
+% }

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/datetime
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/datetime	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Value => undef
+$Attribute => undef
+$Object => undef
+</%args>
+%# someday we may want to treat it differently
+% my $date_obj = RT::Date->new($session{'CurrentUser'});
+% $date_obj->Set( Format => 'ISO', Value => ($Object->$Attribute() || $Value));
+%$m->out('<span class="date">');
+%$m->comp('scalar', Value => $date_obj->AsString);
+%$m->out('</span>');

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/integer
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/integer	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+%# someday we may want to treat it differently
+%$m->out('<span class="integer">');
+%$m->comp('scalar', %ARGS);
+%$m->out('</span>');

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/scalar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/scalar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,19 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+</%args>
+<%init>
+if ( ref($Object) && $Attribute && UNIVERSAL::can($Object, $AttributeName)) {
+        eval {$Value = $Object->$AttributeName()};
+        if ($@) {
+                $Value = $@;
+        } 
+
+ } 
+</%init>
+<&| HREF, %ARGS&><%$Value%></&>
+% if (1) {#$session{'DEBUG'}) {
+<!-- Rendering <%$Value%> as a scalar. Object was <%ref($Object)%> <%UNIVERSAL::can($Object, 'id') && $Object->id%> and Attribute was <%$AttributeName%> <%$Object && $AttributeName && $Object->$AttributeName()%> -->
+%}

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Display/varchar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Display/varchar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,18 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+if ( ref($Object) && $Attribute && UNIVERSAL::can($Object, $Attribute)) {
+        eval {$Value = $Object->$Attribute()};
+        if ($@) {
+                $Value = $@;
+        } 
+
+ } 
+</%init>
+<%$Value%>
+% if ($session{'DEBUG'}) {
+<!-- Rendering <%$Value%> as a scalar. Object was <%ref($Object)%> <%UNIVERSAL::can($Object, 'id') && $Object->id%> and Attribute was <%$Attribute%> -->
+%}

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,34 @@
+<input size="<%$Size%>"  <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+
+unless ($Attribute) {
+    Abort("Bad call to ObjectDateInput - no attribute");
+}
+
+unless ($Default) {
+
+    # someday we may want to treat it differently
+    my $date_obj = RT::Date->new( $session{'CurrentUser'} );
+
+    if ( $Object && $AttributeName ) {
+        $date_obj->Set( Format => 'ISO', Value => $Object->$AttributeName() );
+    }
+    elsif($Value) {
+        $date_obj->Set( Format => 'ISO', Value => $Value );
+    }
+   if ($date_obj->Unix >= 0) {    
+        $Default = $date_obj->ISO;
+   }
+}
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => 30
+$AttributeName => undef
+$Value => undef
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Minutes
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/Minutes	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,28 @@
+<input size="<%$Size%>" 
+        <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> 
+        value="<%$Default%>"> <&|/l&>minutes</&>
+%#XXX TODO: this component should be loced more cleverly, as this totally breaks
+%#XXX        in cases where "minutes" comes before the input
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+$Size = length($Default)+3;
+
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => undef
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/RT/Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/RT/Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,50 @@
+
+% if ($Lite) {
+<INPUT <& ../_attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> size=25 DEFAULT="<%$d->Name%>">
+% } else {
+<SELECT <& ../_attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> >
+% if ($ShowNullOption) {
+<OPTION VALUE="">-</OPTION>
+% }
+% while (my $queue=$q->Next) {
+% if ($ShowAllQueues || $queue->CurrentUserHasRight('CreateTicket')) {
+<OPTION VALUE="<%$queue->Id%>" <%($Default && ($queue->Id == $Default)) && 'SELECTED'%>><%$queue->Name%>
+%   if (($Verbose) and ($queue->Description) ){
+(<%$queue->Description%>)
+%  }
+</OPTION>
+% }
+% }
+</SELECT>
+% }
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$AttributeName();
+}
+my $q=new RT::Queues($session{'CurrentUser'});
+$q->UnLimit;
+
+my $d = new RT::Queue($session{'CurrentUser'});
+$d->Load($Default);
+
+</%init>
+
+<%args>
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => 30
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$Lite => 0
+$AttributeName => undef
+</%ARGS>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/_attribute_name
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/_attribute_name	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,25 @@
+NAME="<%$Name%>"
+<%init>
+my $AttributeName = ref($Attribute)? $Attribute->{'Name'} :$Attribute;
+unless ($Name) {
+        if (UNIVERSAL::isa($Object, 'DBIx::SearchBuilder::Record')) {
+            if ($Object->id) {
+                $Name = ref($Object)."-".$Object->id."-Set".$AttributeName."-Value";
+            } else {
+                $Name = ref($Object)."-new-".($Object+0)."-Create-".$AttributeName;
+            }
+        } else {
+                $Name = $AttributeName;
+        }        
+}
+if ($Suffix) {
+        $Name .= $Suffix;
+}
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Suffix => undef
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/checkbox
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/checkbox	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,23 @@
+<input type="Checkbox" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> <%$state%>>
+<input type="hidden" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute, Suffix => '-previous-value' &> value="<%$Object->$AttributeName()%>">
+<%init>
+my $state;
+
+if ($Default) {
+        $state = $Default;
+}
+elsif ($Object->$AttributeName) {
+        $state = 'CHECKED';
+} else {
+        $state = 'UNCHECKED';
+}
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+$Default=> undef
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/int
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/int	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%init>
+$m->comp('integer', %ARGS);
+return;
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/integer
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/integer	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,26 @@
+<input size="<%$Size%>" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+$Size = length($Default)+3;
+
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => undef
+
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/scalar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/scalar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,24 @@
+<input size="<%$Size%>" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $AttributeName)) {
+#        Abort("Bad call to ObjectInput - $AttributeName is an invalid attribute");
+}
+if  (!$Default && $AttributeName) {
+        $Default = $Object->$AttributeName();
+}
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+$Default=> undef
+$Size => 30
+
+</%args>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/varchar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Edit/varchar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%init>
+$m->comp('scalar', %ARGS);
+return;
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Renderer/Label/Label
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Renderer/Label/Label	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%args>
+$Value => undef
+</%args>
+<span class="label"><%loc($Value)%></span>

Added: experiments/Bamboo/lib/Bamboo/View/Update
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Update	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,57 @@
+<%ARGS>
+$Object => undef
+</%ARGS>
+<%init>
+    unless ( $Object->id ) {
+        Abort("No such Object");
+    }
+
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name = ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+
+
+        my $value;
+        next unless ( exists $ARGS{$attr_uri_param_name}
+            || $ARGS{ $attr_uri_param_name . "-previous-value" } );
+
+   # If no value is set, but there was a value before, that means the user
+   # unclicked a checkbox. would be nice if html forms conveyed this information
+   # back to the server
+        if ( !exists $ARGS{$attr_uri_param_name} ) {
+            if ( $ARGS{ $attr_uri_param_name . "-previous-value" } == 1 ) {
+                $value = 0;
+            }
+
+        }
+        else {
+                $RT::Logger->debug("Found $attr_uri_param_name");
+             $value = $ARGS{$attr_uri_param_name};
+        }
+        my $AttributeMap = $m->comp( 'AttributeMap', Object => $Object );
+        if ( $AttributeMap->{$attr}->{Validator} ) {
+            if ( $m->comp_exists( "Validator/" . $AttributeMap->{$attr}->{Validator})) {
+                $value = $m->comp(
+                    "Validator/" . $AttributeMap->{$attr}->{Validator},
+                    Object        => $Object,
+                    AttributeName => $attr,
+                    Value         => $value
+                );
+            }
+            else {
+                $m->out( "Couldn't find " . $AttributeMap->{$attr}->{Validator} );
+            }
+        }
+        
+                $RT::Logger->debug("The value is finally $value");
+            next unless ( defined $value && ( $Object->$attr() ne $value ) );
+            my $set = "Set$attr";
+            my ( $val, $msg ) = $Object->$set($value);
+            if ($val) {
+                $_MESSAGES{$attr_uri_param_name} = $msg;
+            }
+            else {
+                $_ERRORS{$attr_uri_param_name} = $msg;
+            }
+
+    }
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Validator/Boolean
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Validator/Boolean	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,12 @@
+<%args>
+$Value => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+if ($Value =~ /on|1|true|yes/i) {
+        return(1);
+} else {
+        return(0);
+}
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/Validator/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/Validator/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,26 @@
+<%args>
+$Value => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+my $value_iso;
+if ($Value) {
+        my $date_obj = RT::Date->new($session{'CurrentUser'});
+        $date_obj->Set(Format => 'Unknown', Value => $Value);
+        $value_iso = $date_obj->ISO(); 
+        $m->out("Setting $Value to ".$value_iso);
+}
+
+my $current_value;
+eval {$current_value = $Object->$AttributeName() };
+
+if (!$Value && !$current_value) {
+        return undef;
+} elsif ($value_iso  ne $current_value ) {
+        return ($value_iso);
+
+} else  {
+        return undef;
+}
+</%init>

Added: experiments/Bamboo/lib/Bamboo/View/WebMethodCall
==============================================================================
--- (empty file)
+++ experiments/Bamboo/lib/Bamboo/View/WebMethodCall	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,62 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+# objects we're creating
+my $creates = {};
+# method calls we're performing
+my $calls = {};
+
+# Iterate through %ARGS and slice and dice into
+# Object we're working on
+#   Method calls for those objects
+#     Params for  those method calls
+foreach my $attr (keys %ARGS) {
+
+        next unless ($attr =~ /^(.*?)-(.*?)-(.*?)-(.*?)/ );
+        my $object_type = $1;
+        my $object_id = $2;
+        my $method = $3;
+        my $param_name = $4;
+        my $param_value = $ARGS{$attr};
+
+
+        if ($method eq 'Create') {
+                push (@{$creates->{$object_type}->{$object_id}->{$method}->{$param_name}},         $param_value);
+ 
+        } else {
+
+        push (@{$calls->{$object_type}->{$object_id}->{$method}->{$param_name}},         $param_value);
+
+        }
+}
+
+
+# now that we have all the things we're doing, let's create the objects we need to and then perform all the updates to the other objects we're updating.
+
+# for each object type
+#  for each object identifier
+#   create the object with all its parameters
+
+# for each object type
+#  for each object identifier
+#   perform the method call with all its parameters
+
+
+my ( $id, $msg ) = $Object->Create(%attrs);
+if ($id) {
+    $msg ||= loc("Object created");
+    $Messages->{'create'} = $msg;
+    $NewObjectIdMap->{$FormTag} = $id;
+}
+else {
+    $RT::Logger->error("Object creation failed for $FormTag / $Object");
+    $_ERRORS{ $FormTag . "-Create" } = $msg;
+}
+
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/AttributeMap
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/AttributeMap	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,13 @@
+<%args>
+$Object => undef
+</%args>
+<%init>;
+my $ObjectType = ref($Object);
+$ObjectType =~ s/:/_/gi;
+my $AttributeMap;
+if ( $m->comp_exists("ObjectType/$ObjectType") ) {
+    $AttributeMap = $m->comp( "ObjectType/$ObjectType", %ARGS );
+}
+return $AttributeMap;
+
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Create
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Create	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,34 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+
+
+    my %attrs;
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name =$FormTag . "-Create-" . $attr;
+        $RT::Logger->crit( "Looking for $attr_uri_param_name");
+	
+        $attrs{$attr} = $ARGS{$attr_uri_param_name}
+          if ( $ARGS{$attr_uri_param_name} );
+    } 
+    use Data::Dumper;
+    $RT::Logger->crit(Dumper \%attrs);
+
+    my ( $id, $msg ) = $Object->Create(%attrs);
+    if ($id) {
+        $msg ||= loc("Object created");
+        $Messages->{'create'} = $msg;
+        $NewObjectIdMap->{$FormTag} = $id;
+    }
+    else {
+	$RT::Logger->error("Object creation failed for $FormTag / $Object");
+        $_ERRORS{$FormTag."-Create"} = $msg;
+    }
+
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/CreateOrUpdate
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/CreateOrUpdate	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,85 @@
+<%ARGS>
+$Object => undef
+$Messages => undef
+$Errors => undef
+</%ARGS>
+<%init>
+
+
+if ( $ARGS{'id'} eq 'new' ) {
+
+    my %attrs;
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name =
+          ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+        $attrs{$attr} = $ARGS{$attr_uri_param_name}
+          if ( $ARGS{$attr_uri_param_name} );
+    }
+    my ( $id, $msg ) = $Object->Create(%attrs);
+    if ($id) {
+        $msg ||= loc("Object created");
+        $Messages->{'create'} = $msg;
+        $session{'created_object'} = $id;
+    }
+    else {
+        $Errors->{'create'} = $msg;
+    }
+
+}
+elsif ( $ARGS{'id'} ) {
+    $Object->Load( $ARGS{'id'} );
+    unless ( $Object->id ) {
+        Abort("No such Object");
+    }
+
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name = ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+
+
+        my $value;
+        next unless ( exists $ARGS{$attr_uri_param_name}
+            || $ARGS{ $attr_uri_param_name . "-previous-value" } );
+
+   # If no value is set, but there was a value before, that means the user
+   # unclicked a checkbox. would be nice if html forms conveyed this information
+   # back to the server
+        if ( !exists $ARGS{$attr_uri_param_name} ) {
+            if ( $ARGS{ $attr_uri_param_name . "-previous-value" } == 1 ) {
+                $value = 0;
+            }
+
+        }
+        else {
+                $RT::Logger->debug("Found $attr_uri_param_name");
+             $value = $ARGS{$attr_uri_param_name};
+        }
+        my $AttributeMap = $m->comp( 'AttributeMap', Object => $Object );
+        if ( $AttributeMap->{$attr}->{Validator} ) {
+            if ( $m->comp_exists( "Validator/" . $AttributeMap->{$attr}->{Validator})) {
+                $value = $m->comp(
+                    "Validator/" . $AttributeMap->{$attr}->{Validator},
+                    Object        => $Object,
+                    AttributeName => $attr,
+                    Value         => $value
+                );
+            }
+            else {
+                $m->out( "Couldn't find " . $AttributeMap->{$attr}->{Validator} );
+            }
+        }
+        
+                $RT::Logger->debug("The value is finally $value");
+            next unless ( defined $value
+                && ( $Object->$attr() ne $value ) );
+            my $set = "Set$attr";
+            my ( $val, $msg ) = $Object->$set($value);
+            if ($val) {
+                $Messages->{$attr} = $msg;
+            }
+            else {
+                $Errors->{$attr} = $msg;
+            }
+
+    }
+}
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/CreateOrUpdateAllObjects
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/CreateOrUpdateAllObjects	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,99 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+use URI;
+use URI::QueryParam;
+
+# objects we're creating
+my $creates = {};
+
+# method calls we're performing
+my $calls = {};
+
+# Iterate through %ARGS and slice and dice into
+# Object we're working on
+#   Method calls for those objects
+#     Params for  those method calls
+foreach my $attr ( keys %ARGS ) {
+
+    next unless ( $attr =~ /^(.*?)-(.*?)-(.*?)-(.*?)/ );
+    my $object_type = $1;
+    my $object_id   = $2;
+    my $method      = $3;
+    my $param_name  = $4;
+    my $param_value = $ARGS{$attr};
+
+    push (
+        @{ $calls->{$object_type}->{$object_id}->{$method}->{$param_name} },
+        $param_value
+    );
+
+}
+
+# now that we have all the things we're doing, let's create the objects we need to and then perform all the updates to the other objects we're updating.
+
+# for each object type
+foreach my $object_type ( keys %$calls ) {
+
+    foreach my $object_id ( keys %{ $calls->{$object_type} } ) {
+
+        # Instantiate a proxy object
+        my $proxy = RT::ProxyObject->new(
+            CurrentUser => $session{'CurrentUser'},
+            Type        => $object_type,
+            id          => $object_id
+        );
+    
+        # XXX TODO this should handle Create then any other method
+        foreach my $method ( keys %{ $calls->{$object_type}->{$object_id} } ) {
+            
+            # Call the method on the proxy object with the params listed here
+            $RT::Logger->debug( "$object_type->new()->Load($object_id)->$method ( ");
+
+            my $params_ref = $calls->{$object_type}->{$object_id}->{$method};
+
+            $proxy->$method($params_ref);
+    
+            #XXX TODO get URL forwarding happening
+
+                #$NewObjectIdMap->{$FormTag} = $id;
+
+        }
+
+    }
+
+}
+
+my $new_obj_id_map = {};
+
+if ( ( !keys %_ERRORS ) && $ARGS{'_OnSuccessGotoPage'} ) {
+    my $goto = $ARGS{'_OnSuccessGotoPage'};
+    my $URI  = URI->new($goto);
+
+    my $goto_id = $URI->query_param('id');
+
+    if ( $goto_id =~ /^(.*?)-new-(.*?)$/ ) {
+        $URI->query_param( 'id' => $new_obj_id_map->{$goto_id} );
+    }
+
+    my $flow_id = time() . int( rand(1000) );
+
+    $URI->query_param( 'flow_id' => $flow_id );
+
+    %{ $session{ '_MESSAGES-' . $flow_id } } = %_MESSAGES;
+
+    # here we should deal with a way to preserve errors and messages when
+    # shoving off to the new page.
+    # I think the right answer is to stuff them in the session with a
+    # key that the new page can use to pull them out and clear them.
+
+    $m->redirect( $URI->as_string );
+}
+
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Header
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Header	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,63 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse at bestpractical.com>
+%# 
+%# (Except where explictly superceded by other copyright notices)
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%# 
+%# 
+%# END LICENSE BLOCK
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE><%$Title%></TITLE>
+% if ($Refresh > 0) {
+<META HTTP-EQUIV="REFRESH" CONTENT="<%$Refresh%>">
+% }
+
+<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png">
+<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css">
+</HEAD>
+<BODY BGCOLOR="<%$BgColor%>"
+% if ($Focus) {
+ONLOAD="
+    var tmp = (document.getElementsByName('<% $Focus %>'));
+    if (tmp.length > 0) tmp[tmp.length-1].focus();
+"
+% }
+>
+<%$m->content()|n%>
+</body>
+</html>
+<%INIT>
+
+$r->header_out('Pragma' => 'no-cache');
+$r->header_out('Cache-control' => 'no-cache');
+</%INIT>
+
+<%ARGS>
+$Prefs => '/User/Prefs.html'
+$Focus => 'focus'
+$Title => undef
+$Code => undef
+$Refresh => 0
+$Why => undef
+$BgColor => '#ffffff'
+$ShowBar => 1
+$LoggedIn => 1
+$URL => undef
+</%ARGS>

Added: experiments/Bamboo/mason/Bamboo/View/ListResults
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ListResults	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,27 @@
+<span class="system_messages">
+<ul>
+% if ($session{'_MESSAGES-'.$flow_id}) {
+% foreach my $message (%{$session{'_MESSAGES-'.$flow_id}}) {
+% next unless ($message);
+<li><% $session{'_MESSAGES-'.$flow_id}->{$message} %></li>
+% }
+%}
+% delete  $session{'_MESSAGES-'.$flow_id};
+
+% foreach my $message (keys %_MESSAGES){ 
+% next unless ($message);
+<li><% $_MESSAGES{$message} %></li>
+% }
+</ul>
+<ul>
+% foreach my $message (keys %_ERRORS){ 
+<li class="error"><%$_ERRORS{$message}%></li>
+% }
+</ul>
+</span>
+<%init>
+
+my $request_args = $m->request_args();
+my $flow_id = $request_args->{'flow_id'};
+
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectSelect
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectSelect	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,36 @@
+<select  <& ObjectInputName, Name => $Name, Object => $Object, Attribute => $Attribute&>>
+% foreach my $option (@Values) {
+% if (UNIVERSAL::isa($option, 'DBIx::SearchBuilder::Record')) {
+<option value="<%$option->Id%>" <%$option eq $Default && 'SELECTED'%>>
+%       if (UNIVERSAL::can($option, 'Name' )){
+<%$option->Name%>
+% } else {
+<%$option->id%>
+% }
+</option>
+% } else {
+<option value="<%$option%>" <%$option eq $Default && 'SELECTED'%>><%$option%></option>
+% }
+%}
+</select>
+<%init>
+
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+ at Values => undef
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Attachment
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Attachment	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return({ 
+        id => { Render => 'integer' },
+        BriefDescription => {Render => 'scalar'},
+        Created => {  Render => 'Date' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name'  },
+        Content =>  {Render => 'Scalar' }
+
+});
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__GroupMember
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__GroupMember	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,10 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { RenderAs => 'Attribute', Object => $Object->MemberObj->Object, Attribute => 'Name' },
+
+});
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { Render => 'scalar', Edit => undef, },
+        Disabled => { Render => 'checkbox', Validator => 'Boolean' },
+
+});
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Ticket
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Ticket	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,54 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+my $params = { 
+        id => { Render => 'integer', Immutable => 1 },
+        EffectiveId => { Render => 'integer', Immutable => 1 },
+        Priority => { Render => 'integer' },
+        FinalPriority => { Render => 'integer' },
+        InitialPriority => { Render => 'integer' },
+        Queue => { Render=> 'RT/Queue'},
+        Status => { Render => 'scalar' },
+        Subject => { Render => 'scalar', Edit => undef, },
+        Type => { Render => 'scalar', Edit => undef, },
+
+        TimeWorked => { Render => 'Minutes'},
+        TimeLeft => { Render => 'Minutes'},
+        TimeEstimated => { Render => 'Minutes'},
+        
+        LastUpdated => {  Render => 'Date', Immutable => 1 },
+        Created => {  Render => 'Date' ,  Immutable => 1},
+        Starts => {  Render => 'Date', Validator => 'Date'},
+        Started => {  Render => 'Date', Validator => 'Date'},
+        Told => {  Render => 'Date', Validator => 'Date'},
+        Resolved => {  Render => 'Date', Validator => 'Date'},
+        Due => {  Render => 'Date', Validator => 'Date'},
+        Owner => {  RenderAs => 'Attribute', Object => $Object->OwnerObj, Attribute => 'Name' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name' , Immutable => 1 },
+        LastUpdatedBy =>    {  RenderAs => 'Attribute', Object => $Object->LastUpdatedByObj, Attribute => 'Name' , Immutable => 1 },
+        Requestors => {  RenderAs => 'CollectionAsList' , Object => $Object->Requestors->MembersObj, Attribute => { Name => 'Name' }},
+        Ccs => {  Render => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        Cc => {  Render => 'RT/GroupMembers', Value => sub { $Object->Cc } },
+        AdminCcs => {  Render => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        AdminCc => {  Render => 'RT/GroupMembers', Value => sub { $Object->AdminCc } },
+        RefersTo =>  {RenderAs => 'CollectionAsList' , Object => $Object->RefersTo, Attribute => 'Target'},
+        DependsOn =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependsOn, Attribute => 'Target'},
+        ReferredToBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->ReferredToBy, Attribute => 'Target'},
+        MemberOf =>  {RenderAs => 'CollectionAsList' , Object => $Object->MemberOf, Attribute => 'Target'},
+        DependedOnBy =>  {RenderAs => 'CollectionAsList' , Object => $Object->DependedOnBy, Attribute => 'Target'},
+        Members =>  {RenderAs => 'CollectionAsList' , Object => $Object->Members, Attribute => 'Target'}
+
+};
+
+
+        my $cfs = $Object->QueueObj->CustomFields();
+        while (my $cf = $cfs->Next) {
+                $params->{$cf->Name} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+                $params->{'CustomField-'.$cf->id} = { Label => $cf->Name, RenderAs => 'CollectionAsList', Object => $Object->CustomFieldValues($cf->id), Attribute => 'Content'};
+        }
+
+        return ($params );
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Transaction
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__Transaction	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return({ 
+        id => { Render => 'integer' },
+        BriefDescription => {Render => 'scalar'},
+        Created => {  Render => 'Date' },
+        Creator => {    RenderAs => 'Attribute', Object => $Object->CreatorObj, Attribute => 'Name'  },
+        Content =>  {RenderAs => 'CollectionAsList' , Object => $Object->Attachments, Attribute => 'Content'}
+
+});
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__User
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/ObjectType/RT__User	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,10 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+return ( { 
+        id => { Render => 'integer' },
+        Name => { Render => 'scalar', Edit => undef, },
+
+});
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,19 @@
+<%args>
+$Value => undef
+$Attribute => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+# someday we may want to treat it differently
+ my $date_obj = RT::Date->new($session{'CurrentUser'});
+
+if ($Object && $AttributeName) {
+ $date_obj->Set( Format => 'ISO', Value => $Object->$AttributeName() );
+} else {
+ $date_obj->Set( Format => 'ISO', Value =>  $Value);
+}
+$m->out('<span class="date">');
+$m->comp('scalar', Value => $date_obj->AsString);
+$m->out('</span>');
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/EmailMessage
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/EmailMessage	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,51 @@
+<%args>
+$Object => undef
+</%args>
+<%init>
+
+
+return unless ( $Object->ContentLength || $Object->Children->Count );
+
+my $content = $Object->Content;
+RT::Interface::Web::EscapeUTF8( \$content );
+
+my ( $headers, $quoted );
+if ( 0)  {
+    $headers = $Object->Headers;
+}
+else {
+    $headers = $Object->NiceHeaders;
+}
+chomp $headers;
+if ($headers) {
+    # localize the common headers (like 'Subject:'), too.
+    eval {
+        $headers =~ s/^([^:]+)(?=:)/loc($1)/em;
+      }    # we eval here to catch errors when 5.6 panics
+}
+
+# 13456 is a random # of about the biggest size we want to see inline text
+# It's here to catch anyone who hasn't updated RT_Config.pm since this
+# constant was moved out there.
+my $MAX_INLINE_BODY = $RT::MaxInlineBody || 13456;
+if (   $Object->ContentType =~ m{^(text/plain|Object|text$)}i
+    && $Object->ContentLength < $MAX_INLINE_BODY ) {
+    require Text::Quoted;
+    $quoted = Text::Quoted::extract( $Object->Content );
+}
+        
+$m->comp('/Elements/Callback', Name => 'MassageHeaders',  Headers => \$headers, %ARGS);
+</%init>
+<span class="Object">
+<table>
+% $headers =~ s/^\s+//gm;
+<span class="message-headers">
+% foreach my $header (split(/\n/,$headers)) {
+<%$header%><br>
+%}
+</span class="message-headers">
+</table>
+<PRE>
+<%$Object->Content%>
+</PRE>
+</span>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/HREF
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/HREF	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,20 @@
+<%ARGS>
+$Attribute => undef
+$Object => undef
+</%ARGS>
+<%init>
+unless (ref($Attribute) && $Attribute->{Link}) {
+        $m->out($m->content);
+        return
+}
+my $href = $Attribute->{'Link'};
+
+my $id = $Object->id;
+$href =~ s/##id##/$id/i;
+
+if ($href =~ /^\//) {
+        $href = $RT::WebPath .$href;
+}
+
+</%init>
+<A HREF="<%$href%>"><%$m->content|n%></A>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Minutes
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/Minutes	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+if (!$Value && ref($Object) && $Attribute && UNIVERSAL::can($Object, $Attribute)) {
+        $Value = $Object->$Attribute() ;
+}
+</%init>
+<&|/l, int($Value) &>[_1] minutes</&>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/GroupMembers
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/GroupMembers	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,15 @@
+<%args>
+$Object => undef
+$Attribute => undef
+$Value => undef
+</%args>
+% my $Group = &$Value;
+% my $Users = $Group->UserMembersObj;
+<ul>
+% while (my $user = $Users->Next) { 
+<li><%$user->Name%> 
+% if ($user->EmailAddress) {
+(<%$user->EmailAddress%>)
+% }
+% }
+</ul>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,9 @@
+<%args>
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+my $Queue = RT::Queue->new($session{'CurrentUser'});
+$Queue->Load($Object->$Attribute());
+</%init>
+<%$Queue->Name%> 

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/User
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/RT/User	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,12 @@
+<%args>
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+my $user = RT::User->new($session{'CurrentUser'});
+$user->Load($Object->$Attribute());
+</%init>
+<%$user->Name%> 
+% if ($user->EmailAddress) {
+(<%$user->EmailAddress%>)
+% }

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/datetime
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/datetime	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,11 @@
+<%args>
+$Value => undef
+$Attribute => undef
+$Object => undef
+</%args>
+%# someday we may want to treat it differently
+% my $date_obj = RT::Date->new($session{'CurrentUser'});
+% $date_obj->Set( Format => 'ISO', Value => ($Object->$Attribute() || $Value));
+%$m->out('<span class="date">');
+%$m->comp('scalar', Value => $date_obj->AsString);
+%$m->out('</span>');

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/integer
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/integer	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+%# someday we may want to treat it differently
+%$m->out('<span class="integer">');
+%$m->comp('scalar', %ARGS);
+%$m->out('</span>');

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/scalar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/scalar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,19 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+</%args>
+<%init>
+if ( ref($Object) && $Attribute && UNIVERSAL::can($Object, $AttributeName)) {
+        eval {$Value = $Object->$AttributeName()};
+        if ($@) {
+                $Value = $@;
+        } 
+
+ } 
+</%init>
+<&| HREF, %ARGS&><%$Value%></&>
+% if (1) {#$session{'DEBUG'}) {
+<!-- Rendering <%$Value%> as a scalar. Object was <%ref($Object)%> <%UNIVERSAL::can($Object, 'id') && $Object->id%> and Attribute was <%$AttributeName%> <%$Object && $AttributeName && $Object->$AttributeName()%> -->
+%}

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Display/varchar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Display/varchar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,18 @@
+<%args>
+$Value => undef
+$Object => undef
+$Attribute => undef
+</%args>
+<%init>
+if ( ref($Object) && $Attribute && UNIVERSAL::can($Object, $Attribute)) {
+        eval {$Value = $Object->$Attribute()};
+        if ($@) {
+                $Value = $@;
+        } 
+
+ } 
+</%init>
+<%$Value%>
+% if ($session{'DEBUG'}) {
+<!-- Rendering <%$Value%> as a scalar. Object was <%ref($Object)%> <%UNIVERSAL::can($Object, 'id') && $Object->id%> and Attribute was <%$Attribute%> -->
+%}

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,34 @@
+<input size="<%$Size%>"  <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+
+unless ($Attribute) {
+    Abort("Bad call to ObjectDateInput - no attribute");
+}
+
+unless ($Default) {
+
+    # someday we may want to treat it differently
+    my $date_obj = RT::Date->new( $session{'CurrentUser'} );
+
+    if ( $Object && $AttributeName ) {
+        $date_obj->Set( Format => 'ISO', Value => $Object->$AttributeName() );
+    }
+    elsif($Value) {
+        $date_obj->Set( Format => 'ISO', Value => $Value );
+    }
+   if ($date_obj->Unix >= 0) {    
+        $Default = $date_obj->ISO;
+   }
+}
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => 30
+$AttributeName => undef
+$Value => undef
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Minutes
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/Minutes	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,28 @@
+<input size="<%$Size%>" 
+        <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> 
+        value="<%$Default%>"> <&|/l&>minutes</&>
+%#XXX TODO: this component should be loced more cleverly, as this totally breaks
+%#XXX        in cases where "minutes" comes before the input
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+$Size = length($Default)+3;
+
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => undef
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/RT/Queue
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/RT/Queue	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,50 @@
+
+% if ($Lite) {
+<INPUT <& ../_attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> size=25 DEFAULT="<%$d->Name%>">
+% } else {
+<SELECT <& ../_attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> >
+% if ($ShowNullOption) {
+<OPTION VALUE="">-</OPTION>
+% }
+% while (my $queue=$q->Next) {
+% if ($ShowAllQueues || $queue->CurrentUserHasRight('CreateTicket')) {
+<OPTION VALUE="<%$queue->Id%>" <%($Default && ($queue->Id == $Default)) && 'SELECTED'%>><%$queue->Name%>
+%   if (($Verbose) and ($queue->Description) ){
+(<%$queue->Description%>)
+%  }
+</OPTION>
+% }
+% }
+</SELECT>
+% }
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$AttributeName();
+}
+my $q=new RT::Queues($session{'CurrentUser'});
+$q->UnLimit;
+
+my $d = new RT::Queue($session{'CurrentUser'});
+$d->Load($Default);
+
+</%init>
+
+<%args>
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => 30
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$Lite => 0
+$AttributeName => undef
+</%ARGS>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/_attribute_name
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/_attribute_name	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,25 @@
+NAME="<%$Name%>"
+<%init>
+my $AttributeName = ref($Attribute)? $Attribute->{'Name'} :$Attribute;
+unless ($Name) {
+        if (UNIVERSAL::isa($Object, 'DBIx::SearchBuilder::Record')) {
+            if ($Object->id) {
+                $Name = ref($Object)."-".$Object->id."-Set".$AttributeName."-Value";
+            } else {
+                $Name = ref($Object)."-new-".($Object+0)."-Create-".$AttributeName;
+            }
+        } else {
+                $Name = $AttributeName;
+        }        
+}
+if ($Suffix) {
+        $Name .= $Suffix;
+}
+
+</%init>
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Suffix => undef
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/checkbox
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/checkbox	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,23 @@
+<input type="Checkbox" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> <%$state%>>
+<input type="hidden" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute, Suffix => '-previous-value' &> value="<%$Object->$AttributeName()%>">
+<%init>
+my $state;
+
+if ($Default) {
+        $state = $Default;
+}
+elsif ($Object->$AttributeName) {
+        $state = 'CHECKED';
+} else {
+        $state = 'UNCHECKED';
+}
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+$Default=> undef
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/int
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/int	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%init>
+$m->comp('integer', %ARGS);
+return;
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/integer
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/integer	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,26 @@
+<input size="<%$Size%>" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $Attribute)) {
+#        Abort("Bad call to ObjectInput - $Attribute is an invalid attribute");
+}
+unless ($Default) {
+        $Default = $Object->$Attribute();
+}
+
+$Size = length($Default)+3;
+
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$Default=> undef
+$Size => undef
+
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/scalar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/scalar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,24 @@
+<input size="<%$Size%>" <& _attribute_name, Name => $Name, Object => $Object, Attribute => $Attribute&> value="<%$Default%>">
+<%init>
+
+unless ($Attribute) {
+        Abort("Bad call to ObjectInput - no attribute");
+}
+unless (UNIVERSAL::can($Object, $AttributeName)) {
+#        Abort("Bad call to ObjectInput - $AttributeName is an invalid attribute");
+}
+if  (!$Default && $AttributeName) {
+        $Default = $Object->$AttributeName();
+}
+
+</%init>
+
+<%args>
+$Name => undef
+$Object => undef
+$Attribute => undef
+$AttributeName => undef
+$Default=> undef
+$Size => 30
+
+</%args>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/varchar
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Edit/varchar	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%init>
+$m->comp('scalar', %ARGS);
+return;
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Renderer/Label/Label
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Renderer/Label/Label	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,4 @@
+<%args>
+$Value => undef
+</%args>
+<span class="label"><%loc($Value)%></span>

Added: experiments/Bamboo/mason/Bamboo/View/Update
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Update	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,57 @@
+<%ARGS>
+$Object => undef
+</%ARGS>
+<%init>
+    unless ( $Object->id ) {
+        Abort("No such Object");
+    }
+
+    foreach my $attr ( $Object->WritableAttributes ) {
+        my $attr_uri_param_name = ref($Object) . "-" . $ARGS{'id'} . "-" . $attr;
+
+
+        my $value;
+        next unless ( exists $ARGS{$attr_uri_param_name}
+            || $ARGS{ $attr_uri_param_name . "-previous-value" } );
+
+   # If no value is set, but there was a value before, that means the user
+   # unclicked a checkbox. would be nice if html forms conveyed this information
+   # back to the server
+        if ( !exists $ARGS{$attr_uri_param_name} ) {
+            if ( $ARGS{ $attr_uri_param_name . "-previous-value" } == 1 ) {
+                $value = 0;
+            }
+
+        }
+        else {
+                $RT::Logger->debug("Found $attr_uri_param_name");
+             $value = $ARGS{$attr_uri_param_name};
+        }
+        my $AttributeMap = $m->comp( 'AttributeMap', Object => $Object );
+        if ( $AttributeMap->{$attr}->{Validator} ) {
+            if ( $m->comp_exists( "Validator/" . $AttributeMap->{$attr}->{Validator})) {
+                $value = $m->comp(
+                    "Validator/" . $AttributeMap->{$attr}->{Validator},
+                    Object        => $Object,
+                    AttributeName => $attr,
+                    Value         => $value
+                );
+            }
+            else {
+                $m->out( "Couldn't find " . $AttributeMap->{$attr}->{Validator} );
+            }
+        }
+        
+                $RT::Logger->debug("The value is finally $value");
+            next unless ( defined $value && ( $Object->$attr() ne $value ) );
+            my $set = "Set$attr";
+            my ( $val, $msg ) = $Object->$set($value);
+            if ($val) {
+                $_MESSAGES{$attr_uri_param_name} = $msg;
+            }
+            else {
+                $_ERRORS{$attr_uri_param_name} = $msg;
+            }
+
+    }
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Validator/Boolean
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Validator/Boolean	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,12 @@
+<%args>
+$Value => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+if ($Value =~ /on|1|true|yes/i) {
+        return(1);
+} else {
+        return(0);
+}
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/Validator/Date
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/Validator/Date	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,26 @@
+<%args>
+$Value => undef
+$Object => undef
+$AttributeName => undef
+</%args>
+<%init>
+my $value_iso;
+if ($Value) {
+        my $date_obj = RT::Date->new($session{'CurrentUser'});
+        $date_obj->Set(Format => 'Unknown', Value => $Value);
+        $value_iso = $date_obj->ISO(); 
+        $m->out("Setting $Value to ".$value_iso);
+}
+
+my $current_value;
+eval {$current_value = $Object->$AttributeName() };
+
+if (!$Value && !$current_value) {
+        return undef;
+} elsif ($value_iso  ne $current_value ) {
+        return ($value_iso);
+
+} else  {
+        return undef;
+}
+</%init>

Added: experiments/Bamboo/mason/Bamboo/View/WebMethodCall
==============================================================================
--- (empty file)
+++ experiments/Bamboo/mason/Bamboo/View/WebMethodCall	Fri Apr 30 14:26:08 2004
@@ -0,0 +1,62 @@
+<%ARGS>
+$Object => undef
+$FormTag => undef
+$Messages => undef
+$Errors => undef
+$NewObjectIdMap => undef
+</%ARGS>
+<%init>
+
+# objects we're creating
+my $creates = {};
+# method calls we're performing
+my $calls = {};
+
+# Iterate through %ARGS and slice and dice into
+# Object we're working on
+#   Method calls for those objects
+#     Params for  those method calls
+foreach my $attr (keys %ARGS) {
+
+        next unless ($attr =~ /^(.*?)-(.*?)-(.*?)-(.*?)/ );
+        my $object_type = $1;
+        my $object_id = $2;
+        my $method = $3;
+        my $param_name = $4;
+        my $param_value = $ARGS{$attr};
+
+
+        if ($method eq 'Create') {
+                push (@{$creates->{$object_type}->{$object_id}->{$method}->{$param_name}},         $param_value);
+ 
+        } else {
+
+        push (@{$calls->{$object_type}->{$object_id}->{$method}->{$param_name}},         $param_value);
+
+        }
+}
+
+
+# now that we have all the things we're doing, let's create the objects we need to and then perform all the updates to the other objects we're updating.
+
+# for each object type
+#  for each object identifier
+#   create the object with all its parameters
+
+# for each object type
+#  for each object identifier
+#   perform the method call with all its parameters
+
+
+my ( $id, $msg ) = $Object->Create(%attrs);
+if ($id) {
+    $msg ||= loc("Object created");
+    $Messages->{'create'} = $msg;
+    $NewObjectIdMap->{$FormTag} = $id;
+}
+else {
+    $RT::Logger->error("Object creation failed for $FormTag / $Object");
+    $_ERRORS{ $FormTag . "-Create" } = $msg;
+}
+
+</%init>


More information about the Rt-commit mailing list