diff lib/IMPL/Web/View/Metadata/ObjectMeta.pm @ 407:c6e90e02dd17 ref20150831

renamed Lib->lib
author cin
date Fri, 04 Sep 2015 19:40:23 +0300
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/IMPL/Web/View/Metadata/ObjectMeta.pm	Fri Sep 04 19:40:23 2015 +0300
@@ -0,0 +1,133 @@
+package IMPL::Web::View::Metadata::ObjectMeta;
+use strict;
+
+use IMPL::lang;
+use IMPL::Const qw(:prop :access);
+use IMPL::declare {
+	require => {
+		Exception => 'IMPL::Exception',
+		ArgException => '-IMPL::InvalidArgumentException',
+		OpException => '-IMPL::InvalidOperationException',
+		PropertyInfo => 'IMPL::Class::PropertyInfo',
+		AbstractObject => '-IMPL::Object::Abstract'
+	},
+	base => [
+		'IMPL::Web::View::Metadata::BaseMeta' => sub {
+			my ($model,$type,$args) = @_;
+			$type ||= typeof($model);
+			return ($model,$type,$args);
+		}
+	],
+	props => [
+		isMultiple => PROP_RO,
+		holdingType => PROP_RO
+	]
+};
+
+use constant {
+	Meta => __PACKAGE__
+};
+
+sub CTOR {
+	my ($this,$model,$type,$args) = @_;
+	
+	$type = $this->modelType;
+	
+	$args->{isMultiple} ||= $type && $type eq 'ARRAY';
+	
+	if ($args) {
+		$this->$_($args->{$_}) foreach grep $args->{$_}, qw(isMultiple holdingType);
+	}
+}
+
+sub PopulateProperties {
+	my ($this) = @_;
+	
+	my %seen;
+	my @props;
+	
+	my $modelType = $this->modelType;  
+
+	if ( isclass($modelType,AbstractObject) ) {
+		foreach my $pi (
+			$this->modelType->GetMeta(
+				PropertyInfo,
+				sub { not($seen{$_}++) and $_->access == ACCESS_PUBLIC },
+				1
+			)
+		) {
+			my $pv = $this->model && $pi->getter->($this->model);
+			my $pt;
+			
+			my %args = (name => $pi->name);
+			if ($pi->isList) {
+				$pt = 'ARRAY';
+				$args{isMultiple} = 1;
+				$args{holdingType} = $pi->type;
+			} else {
+				$pt = $pi->type;
+			}
+			
+			push @props, Meta->new($pv, $pt, \%args);
+		}
+	} elsif ( $modelType && $modelType eq 'HASH' ) {
+		while ( my ($k,$v) = each %{$this->model || {}} ) {
+			push @props, Meta->new($v,undef,{name => $k});
+		}
+	}
+	
+	return \@props;
+}
+
+sub GetItems {
+	my ($this) = @_;
+	
+	die OpException->new("The operation must be performed on the container")
+		unless $this->isMultiple;
+		
+	my $i = 0;
+	
+	return [
+		map $this->_GetItemMeta($_,$i++), @{$this->model || []}
+	];
+}
+
+sub GetItem {
+	my ($this,$index) = @_;
+	
+	die OpException->new("The operation must be performed on the container")
+		unless $this->isMultiple;
+		
+	my $item = @{$this->model || []}[$index];
+	
+	return $this->_GetItemMeta($item,$index);
+}
+
+sub _GetItemMeta {
+	my ($this,$item,$index) = @_;
+	
+	return Meta->new(
+		$item,
+		$this->holdingType,
+		{
+			name => $index,
+			container => $this
+		}
+	);
+}
+
+sub GetMetadataForModel {
+	my ($self,$model,$args) = @_;
+	
+	$args ||= {};
+	
+	return $self->new(
+		$model,
+		delete $args->{modelType},
+		$args
+	)
+}
+
+1;
+
+__END__