#
# Copyright 2008 Samuel Borsutzky
#
# This file is part of PerlForms.
#
# PerlForms is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PerlForms 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.
#
# You should have received a copy of the GNU General Public License
# along with PerlForms. If not, see .
#
#
#
package PerlForms;
# beerbt: PerlForms::Dict::Object, NagUtil::REQ, NagUtil ???????
## todo e PerlForms in PerlForms::Base oder ::Simple oder so ändern
## todo c PerlForms->ui in REQ->ui umziehen
## todo c PerlForms->form in REQ->form umziehen
## todo c PerlForms->query in REQ->query umziehen
use strict;
use Carp qw(:DEFAULT cluck);
use vars qw($debug);
$debug=5 unless(defined($debug));
sub new {
# expects:
# descr: Most simple, generic constructor.
my($self)={};
my($class)=shift;
bless($self,$class);
my(%arg)=@_;
$debug>=3 && print(STDERR __PACKAGE__."->new got called by ".caller()." with ".join(",",%arg).".\n");
$self->{req}=$arg{req} if defined $arg{req};
$self->{ui}=$arg{ui} if defined $arg{ui};
$self->{class}=$class;
if($self->can("init")) {
$self->init(%arg);
}
$self;
}
sub date {
shift if(ref($_[0]) and $_[0]->can("VERSION"));
my(@lt);
if(@_ and $_[0] and $_[0]=~/\d/) {
@lt=localtime($_[0]);
} else {
@lt=localtime;
}
return sprintf(
'%02d.%02d.%04d %02d:%02d:%02d',
($lt[3]),
($lt[4]+1),
($lt[5]+1900),
($lt[2]),
($lt[1]),
($lt[0])
)
}
sub faultt {
# expects: prg|req? ui? msg
#
# howto use:
# Am besten ein ui oder - wenn nicht zur Hand - ein req übergeben.
# Gibt es gerade beides nicht, dann nur msg übergeben, und fault baut sich
# den Rest selber.
#
#
$debug && print(STDERR __PACKAGE__."->faultt got called by ".caller()."\n");
my($self)=shift;
my(%arg)=@_;
if(defined($arg{msg})) {
chomp($arg{msg});
print(STDERR __PACKAGE__."->faultt: msg='".$arg{msg}."'\n") if($debug>=4);
}
unless(defined($self->{req})) {
if(defined($arg{req})) {
$self->{req}=$arg{req};
} elsif(ref($self)=~/::REQ/) {
$self->{req}=$self;
} else {
warn(__PACKAGE__."->faultt: Dont have a REQ.\n")
}
}
$self->ui->bad(
defined($arg{msg})?$arg{msg}:"Error, sais ".caller()
) or die(__PACKAGE__."->faultt: \$self->ui->bad failed. ".$!);
if($debug>=3) {
print(STDERR __PACKAGE__."->faultt will cluck now:\n");
cluck(__PACKAGE__."->faultt got called...");
}
exit 1;
}
#
#sub int2ip {
# my($self)=shift if ref($_[0]) and $_[0]->can("VERSION");
# ## $self->int2ip-aufruf geht in die hose!!
# my($ip)=shift;
# # The mysql-data-type int is 31bit long, plus a +/- sign.
# # An IP address is 32bit long.
# # Since i don't want to use the 64bit int of mysql,
# # I use the +/- sign bit, by substracting 2^32 from the ip,
# # thus storing all IP addresses below 128.0.0.0 as a
# # negative value.
# # When decoding back to an IP address, I have to add those 2^32 back.
# $ip+=2147483648;
# $ip=unpack("B32", pack("N", $ip));
# $ip =~ /^(\d{8})(\d{8})(\d{8})(\d{8})$/;
# $ip =~ /^(\d{8})(\d{8})(\d{8})(\d{8})$/ or return;
# my($nip) = unpack("N", pack("B32",substr("0" x 32 . $1, -32))).
# ".".unpack("N", pack("B32",substr("0" x 32 . $2, -32))).
# ".".unpack("N", pack("B32",substr("0" x 32 . $3, -32))).
# ".".unpack("N", pack("B32",substr("0" x 32 . $4, -32)));
# return $nip;
#}
#
#sub ip2int {
# my($self)=shift;
# my($ip)=shift;
# return if(!$ip);
# my($x,$y,$z,$nip);
# foreach $x ( ( $ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ) ) {
# $y = unpack("B32", pack("N",$x));
# $y =~ s/^0+(?=\d)//g;
# $z .= sprintf("%08d",$y);
# }
# $nip=unpack("N",pack("B32",$z));
# # The mysql-data-type int is 31bit long, plus a +/- sign.
# # An IP address is 32bit long.
# # Since i don't want to use the 64bit int of mysql,
# # I use the +/- sign bit, by substracting 2^31 from the ip,
# # thus storing all IP addresses below 128.0.0.0 as a
# # negative value.
# $nip-=2147483648;
# return $nip;
#}
sub pfmodule {
my($self)=shift;
my($what,$obj);
if(defined $_[0]) {
$what=shift;
} elsif(!defined $self->{obj}) {
if(defined($self->{what})) {
$what=$self->{what};
} else {
warn(__PACKAGE__."->pfmodule needs an obj or a what!\n");
return undef;
}
} else {
$obj=$self->{obj}
}
if(defined $what) { ## what ist nur defined, wenn es kein obj gab, oder what als param. übergeben wurde und alles andere somit übeschreibt.
my$req;
if(ref($self)=~/::REQ$/) {
$req=$self;
} elsif(defined $self->{req}) {
$req=$self->{req}
} else {
warn(__PACKAGE__."->pfmodule needs a req!\n");
return undef;
}
# require PerlForms::Dict::Object;
# $obj=PerlForms::Dict::Object->new(req=>$req,what=>$what);
$obj=$self->newobj(what=>$what);
}
if(defined($obj->dict->{pfmodule})) {
return $obj->dict->{pfmodule};
} elsif(defined($self->{prg}) and $self->{prg} eq "ldap") {
return "IPLS::Ldap";
} else {
return "NagUtil";
}
}
sub ui {
# expects: req? ui?
# returns: UI object.
# descr: returns the current UI. If there is not UI yet, it makes one. Can
# also be used to manually set a UI. simply specify the ui parameter.
my($self)=shift;
my(%arg)=@_;
$debug && print(STDERR
__PACKAGE__."->ui got called by ".caller()." with ".join(",",%arg)." (Please ignore the uninitialized value message above!).\n"
);
if(defined($arg{ui}) and ref($arg{ui})) {
$debug && print(STDERR __PACKAGE__."->ui set ui to ".$arg{ui}."\n");
$self->{ui}=$arg{ui};
} elsif(!defined($self->{ui}) or !ref($self->{ui})) {
unless(defined($self->{req})) {
if(defined($arg{req})) {
$self->{req}=$arg{req};
} elsif(ref($self)=~/::HTML::REQ[\W:]*$/) {
$self->{req}=$self;
} else {
require PerlForms::TEXT::REQ
or warn(__PACKAGE__."->ui require PerlForms::TEXT::REQ failed. ".$!);
$self->{req}=new PerlForms::TEXT::REQ(%arg)
or warn(__PACKAGE__."->ui new PerlForms::TEXT::REQ failed. ".$!);
}
if(!defined($self->{req})) {
warn(__PACKAGE__."->ui: new TEXT::REQ failed. ".$!."\n");
return undef;
}
}
if(defined($self->{req}->{ui})) {
$self->{ui}=$self->{req}->{ui}
} elsif($self->{req}->type eq "HTML") {
require PerlForms::HTML::Tabs
or warn(__PACKAGE__."->ui require PerlForms::HTML::UI failed. ".$!);
$self->{ui}=PerlForms::HTML::Tabs->new(%arg,req=>$self->{req},obj=>$self->{obj})
or warn(__PACKAGE__."->ui new PerlForms::HTML::UI failed (caller: ".caller()."). ".$!);
} else {
require PerlForms::TEXT::UI
or warn(__PACKAGE__."->ui require PerlForms::TEXT::UI failed. ".$!);
$self->{ui}=PerlForms::TEXT::UI->new(%arg,req=>$self->{req},obj=>$self->{obj})
or warn(__PACKAGE__."->ui new PerlForms::TEXT::UI failed. ".$!);
}
}
if(defined($self->{req}) and !defined($self->{req}->{ui})) {
$self->{req}->{ui}=$self->{ui}
}
$debug && print(STDERR __PACKAGE__."->ui returning ".$self->{ui}."\n");
return defined $self->{ui}?$self->{ui}:{};
}
## todo PerlForms->form nach REQ->form umziehen
sub form {
my$self=shift;
my%arg=@_;
unless(defined($self->{form})) {
unless(defined($arg{obj}) or defined($arg{what})) {
$arg{obj}=$self->obj(%arg);
}
require PerlForms::HTML::Form;
$self->{form}=Form->new(
%arg,
req=>$self->{req}
);
$self->{ui}=$self->{form}->{ui};
}
$self->{form}
}
sub newlist {
# expects: req? ui?
# returns: UI object.
# descr: returns the current UI. If there is not UI yet, it makes one. Can
# also be used to manually set a UI. simply specify the ui parameter.
my($self)=shift;
my(%arg)=@_;
$debug && print(STDERR
__PACKAGE__."->newlist got called by ".caller()." with ".join(",",%arg)." (Please ignore the uninitialized value message above!).\n"
);
$arg{req}=$self->{req};
$arg{obj}=$self->{obj} if(!defined($arg{obj}) and defined($self->{obj}));
$arg{ui}=$self->{ui} if(!defined($arg{ui}) and defined($self->{ui}));
if($self->{req}->type eq "HTML") {
require PerlForms::HTML::List
or warn(__PACKAGE__."->newlist require PerlForms::HTML::List failed. ".$!);
$self->{ui}=HTML::List->new(%arg)
or warn(__PACKAGE__."->newlist new HTML::List failed (caller: ".caller()."). ".$!);
} else {
require PerlForms::TEXT::List
or warn(__PACKAGE__."->newlist require PerlForms::TEXT::List failed. ".$!);
$self->{ui}=TEXT::List->new(%arg)
or warn(__PACKAGE__."->newlist new TEXT::List failed (caller: ".caller()."). ".$!);
}
$debug && print(STDERR __PACKAGE__."->newlist returning ".$self->{ui}."\n");
return defined $self->{ui}?$self->{ui}:{};
}
sub newobj {
# expects: what|abkuerz
my$self=shift;
my%arg=@_;
$debug && print STDERR __PACKAGE__."->newobj got called by ".caller()."\n";
unless(defined $self->{req}) {
if(ref($self)=~/::REQ$/) {
$self->{req}=$self;
} else {
warn(__PACKAGE__."->newobj needs a req! caller: ".caller().". returning undef.\n");
return undef;
}
}
my$obj;
if(defined $arg{what} or defined $arg{abkuerz} or defined $arg{idattrib}) {
# require PerlForms::Dict::Object;
# $obj=PerlForms::Dict::Object->new(%arg,req=>$self->{req});
$obj=$self->{req}->dict->obj(%arg,req=>$self->{req});
} elsif(defined $self->{obj}) {
$obj=$self->{obj}
} else {
warn(__PACKAGE__."->newobj needs a what or an abkuerz. returning undef.\n");
return undef;
}
$debug && print STDERR __PACKAGE__."->newobj: obj returns: ".$obj->what."\n";
$obj;
}
sub obj {
my$self=shift;
my%arg=@_;
unless(defined($self->{obj})) {
if(defined($arg{obj})) {
$self->{obj}=$arg{obj};
} elsif(defined($self->{what})) {
$self->{obj}=$self->newobj(what=>$self->{what});
} elsif(defined($arg{what})) {
$self->{obj}=$self->newobj(what=>$arg{what});
} else {
return undef
}
}
$self->{obj}
}
sub objs { ## takes a what
## gibt ein PerlForms::Dict::Object für das angeg. what zurück. Sollte es so
## eines für das angeg. what schon geben, dann wird kein neues generiert
## sondern das bestehende zurückgegeben.
## Achtung: Die objs werden in einer Objekt-Variable gespeichert; wenn also
## eines in req->obj schon existiert, wird obj->objs trotzdem ein neues ge-
## nerieren.
my$self=shift;
unless(defined($self->{objs}->{$_[0]})) {
$self->{objs}->{$_[0]}=$self->newobj(what=>$_[0]);
}
warn(__PACKAGE__."->objs: obj couldnt be generated.\n")
unless(defined($self->{objs}->{$_[0]}));
$self->{objs}->{$_[0]}
}
## todo w newthing: Class->newthing macht Sinn/wäre praktisch
## todo d pfmodule: jedes obj soll wissen, zu welchem Pf-Modul es gehört. Anstatt
## pm direkt anzugeben könnte es sich besser aus Pf-Module und what zusam-
## mensetzen.
sub newthing {
# expects: obj|what
my$self=shift;
my%arg=@_;
$debug && print STDERR __PACKAGE__."->newthing got called by ".caller()."\n";
unless(defined($self->{req})) {
if(ref($self)=~/::REQ$/) {
$self->{req}=$self;
} else {
warn(__PACKAGE__."->newthing needs a req! returning undef.\n");
return undef;
}
}
## obj
# $arg{obj}=$self->newobj(%arg) unless(defined($arg{obj}));
# $debug && print STDERR __PACKAGE__."->newthing: obj is defined: ".$arg{obj}->what."\n";
my$obj;
if(defined($arg{obj})) {
$obj=$arg{obj}
} elsif(defined($arg{what})) {
# $obj=$self->newobj(%arg)
$obj=$self->objs($arg{what})
} else {
$obj=$self->obj(%arg)
}
unless(eval 'require '.$obj->pm) {
$debug && print STDERR __PACKAGE__."->newthing: require ".$obj->pm." failed. ".$!."\n";
my$pm=$obj->pm;
$pm=~s/::/\//g;
my$pmfile='"'.$self->{req}->{"fudhome"}.'/lib/'.$pm.'.pm"';
if(-e $pmfile) {
my($cmd)='perl -c ".$pmfile." 2>&1';
my($checkout)=`$cmd`;
$self->faultt(
msg=>"
".__PACKAGE__." eval require ".$obj->pm." failed: ".$@."
Output of the Perl syntax check: ".$checkout."
"
);
# } elsif(defined $obj->pm) {
} elsif(defined($self->{req}->dict->is_what($obj->what))) {
print STDERR __PACKAGE__."->newthing: generating new ".$obj->what." thing.\n";
require PerlForms::Object;
return PerlForms::Object->new(
req=>$self->{req},
ui=>$arg{ui},
obj=>$obj
)
} else {
print STDERR __PACKAGE__."->newthing: pm file ".$pmfile." doesnt exist and ".$obj->what." is not a defined Pf-Object-Class. returning undef.\n";
# $self->faultt(
# msg=>"
# ".__PACKAGE__."newthing eval require ".$obj->pm." failed: ".$@."
# Perl Module file does not exist.
# "
# );
return undef
}
} else {
print STDERR __PACKAGE__."->newthing: require ".$obj->pm." successful.\n";
return eval $obj->pm.'->new(
req=>$self->{req},
ui=>$arg{ui},
obj=>$obj
)' or $self->{req}->faultt(msg=>__PACKAGE__."->newthing eval new failed. ".$@);
}
}
## todo e newthing wo sinnvoll durch thing/s ersetzen
sub thing {
## wird nichts oder mehr als ein wert übergeben (hash vermutet), wird
## $self->{thing} zurückgegeben, vorher ggf. generiert.
my$self=shift;
my%arg=@_;
unless(defined($self->{thing})) {
$self->{thing}=$self->newthing(obj=>$self->obj);
}
$self->{thing}
}
sub things { ## takes a what
## gibt ein PerlForms::Object für das angeg. what zurück. Sollte es so eines
## für das angeg. what schon geben, dann wird kein neues generiert sondern
## das bestehende zurückgegeben.
## Achtung: Die things werden in einer Objekt-Variable gespeichert; wenn also
## ein req->thing schon existiert, wird thing->thing trotzdem ein neues gene-
## rieren.
my$self=shift;
unless(defined($self->{things}->{$_[0]})) {
$self->{things}->{$_[0]}=$self->newthing(what=>$_[0]);
}
warn(__PACKAGE__."->things: thing couldnt be generated.\n")
unless(defined($self->{things}->{$_[0]}));
$self->{things}->{$_[0]}
}
sub query {
# expects: {attribs}
my$self=shift;
# print STDERR __PACKAGE__."->query got called by ".caller()." with ".join(",",@_)."\n";
my$qname=shift;
my%attribs=@_;
unless(defined($self->{"query"})) {
require PerlForms::Query;
$self->{"query"}=PerlForms::Query->new(
req=>$self->{req},
ui=>$self->{ui}
);
}
if(defined($qname) and $self->{"query"}->can($qname)) {
# print STDERR __PACKAGE__."->query running a query-method.\n";
eval('$self->->'.$qname.'(%attribs)')
} else {
# print STDERR __PACKAGE__."->query returning a query object.\n";
$self->{"query"}
}
}
package Main;
1;