285 lines
7.4 KiB
Perl
285 lines
7.4 KiB
Perl
package JMX::Jmx4Perl::J4psh::Shell;
|
|
|
|
use strict;
|
|
use Term::ShellUI;
|
|
use Term::ANSIColor qw(:constants);
|
|
use Data::Dumper;
|
|
|
|
=head1 NAME
|
|
|
|
JMX::Jmx4Perl::J4psh::Shell - Facade to Term::ShellUI
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
=head1 METHODS
|
|
|
|
=cut
|
|
|
|
my $USE_TERM_SIZE;
|
|
my $USE_SEARCH_PATH;
|
|
BEGIN {
|
|
$USE_TERM_SIZE = eval 'use Term::Size qw/chars/; 1';
|
|
$USE_SEARCH_PATH = eval 'use File::SearchPath qw/searchpath/; 1';
|
|
no warnings 'redefine';
|
|
*Text::Shellwords::Cursor::join_line = sub {
|
|
my $self = shift;
|
|
my $intoks = shift;
|
|
|
|
my $str = "";
|
|
my $nsp = "";
|
|
my $last_tok = "";
|
|
for (@$intoks) {
|
|
$nsp = /^(['"])(.*)\1/ || $last_tok =~ /^(['"])(.*)\1/ ? "" : " ";
|
|
$str .= $nsp . $_;
|
|
$last_tok = $_;
|
|
}
|
|
$str =~ s/^\s*(.*?)\s*$/$1/;
|
|
return $str;
|
|
};
|
|
}
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $self = ref($_[0]) eq "HASH" ? $_[0] : { @_ };
|
|
bless $self,(ref($class) || $class);
|
|
$self->_init;
|
|
return $self;
|
|
}
|
|
|
|
sub term {
|
|
return shift->{term};
|
|
}
|
|
|
|
sub commands {
|
|
my $self = shift;
|
|
$self->{term}->commands(@_);
|
|
}
|
|
|
|
# Run ShellUI and never return. Provide some special
|
|
# ReadLine treatment
|
|
sub run {
|
|
my $self = shift;
|
|
my $t = $self->term;
|
|
|
|
#$t->{debug_complete}=5;
|
|
$t->run;
|
|
}
|
|
|
|
sub color {
|
|
my $self = shift;
|
|
my @colors = @_;
|
|
my $args = ref($colors[$#colors]) eq "HASH" ? pop @colors : {};
|
|
if ($self->use_color) {
|
|
if ($args->{escape}) {
|
|
return map { "\01" . $self->_resolve_color($_) . "\02" } @colors;
|
|
} else {
|
|
return map { $self->_resolve_color($_) } @colors;
|
|
}
|
|
} else {
|
|
return map { "" } @colors;
|
|
}
|
|
}
|
|
|
|
sub color_theme {
|
|
return shift->_get_set("color_theme",@_);
|
|
}
|
|
|
|
sub use_color {
|
|
my $self = shift;
|
|
my $value = shift;
|
|
if (defined($value)) {
|
|
$self->{use_color} = $value !~ /^(0|no|never|false)$/i;
|
|
}
|
|
return $self->{use_color};
|
|
}
|
|
|
|
|
|
sub _resolve_color {
|
|
my $self = shift;
|
|
my $c = shift;
|
|
my $color = $self->{color_theme}->{$c};
|
|
if (exists($self->{color_theme}->{$c})) {
|
|
return defined($color) ? $color : "";
|
|
} else {
|
|
return $c;
|
|
}
|
|
}
|
|
|
|
# ===========================================================================
|
|
|
|
sub _init {
|
|
my $self = shift;
|
|
|
|
# Create shell object
|
|
my $term = new Term::ShellUI(
|
|
history_file => "~/.j4psh_history",
|
|
keep_quotes => 1,
|
|
);
|
|
$term->{parser}->{space_none} = "\"'";
|
|
$self->{term} = $term;
|
|
my $rl_attribs = $term->{term}->Attribs;
|
|
#$rl_attribs->{basic_word_break_characters} = " \t\n\\'`@$><;|&{(";
|
|
$rl_attribs->{completer_word_break_characters} = " \t\n\\";
|
|
$term->{term}->Attribs($rl_attribs);
|
|
$term->{term}->ornaments(0);
|
|
|
|
my $config = $self->{config};
|
|
# Set color mode
|
|
$self->use_color(defined($self->{use_color}) || defined($config->{UseColor}) || "yes");
|
|
# Init color theme
|
|
$self->_init_theme($config->{theme});
|
|
|
|
my $use_color = "yes";
|
|
if (exists $self->{args}->{color}) {
|
|
$use_color = $self->{args}->{color};
|
|
} elsif (exists $self->{config}->{usecolor}) {
|
|
$use_color = $self->{config}->{usecolor};
|
|
}
|
|
$self->use_color($use_color);
|
|
|
|
# Force pipe, quit if less than a screen-full.
|
|
my @args = (
|
|
'-f', # force, needed for color output
|
|
# '-E', # Exit automatically at end of output
|
|
'-X' # no init
|
|
);
|
|
if ($self->use_color) {
|
|
# Raw control characters
|
|
push @args,'-R';
|
|
}
|
|
if ($ENV{LESS}) {
|
|
my $l = "";
|
|
for my $a (@args) {
|
|
$l .= $a . " " unless $ENV{LESS} =~ /$a/;
|
|
}
|
|
if (length($l)) {
|
|
chop $l;
|
|
$ENV{LESS} .= " " . $l;
|
|
}
|
|
} else {
|
|
$ENV{LESS} = join " ",@args;
|
|
}
|
|
if ($self->{config}->{pager}) {
|
|
$ENV{PAGER} = $self->{config}->{pager};
|
|
} elsif (!$ENV{PAGER}) {
|
|
# Try to find a suitable pager
|
|
if ($USE_SEARCH_PATH) {
|
|
for my $p (qw(less more)) {
|
|
my $pager = searchpath($p, env => 'PATH', exe => 1 );
|
|
if ($pager) {
|
|
$ENV{PAGER} = $pager;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
# No searching available, we rely on Term::Clue for finding the proper
|
|
# pager.
|
|
}
|
|
|
|
if ($ENV{PAGER} && $ENV{PAGER} =~ /more$/) {
|
|
# If we are using "more", disable coloring
|
|
$self->use_color("no");
|
|
}
|
|
}
|
|
|
|
sub default_theme {
|
|
my $self = shift;
|
|
# Initial theme
|
|
my $theme_light = {
|
|
host => YELLOW,
|
|
prompt_context => BLUE,
|
|
prompt_empty => RED,
|
|
label => YELLOW,
|
|
domain_name => BLUE,
|
|
property_key => GREEN,
|
|
property_value => undef,
|
|
mbean_name => YELLOW,
|
|
attribute_name => GREEN,
|
|
operation_name => YELLOW,
|
|
stat_val => RED,
|
|
reset => RESET
|
|
};
|
|
my $theme_dark = {
|
|
host => YELLOW,
|
|
label => YELLOW,
|
|
prompt_context => CYAN,
|
|
prompt_empty => RED,
|
|
domain_name => YELLOW,
|
|
property_key => GREEN,
|
|
property_value => undef,
|
|
mbean_name => YELLOW,
|
|
attribute_name => GREEN,
|
|
operation_name => YELLOW,
|
|
stat_val => RED,
|
|
reset => RESET
|
|
};
|
|
return $theme_dark;
|
|
}
|
|
|
|
|
|
sub readline {
|
|
my $self = shift;
|
|
my $term = $self->term;
|
|
return $term->{term}->ReadLine;
|
|
}
|
|
|
|
sub _init_theme {
|
|
my $self = shift;
|
|
my $theme_config = shift;
|
|
my $theme = $self->default_theme;
|
|
if ($theme_config) {
|
|
for my $k (keys %$theme_config) {
|
|
my $c = $theme_config->{$k};
|
|
$theme->{$k} = $c eq "undef" ? undef : Term::ANSIColor::color($c);
|
|
}
|
|
}
|
|
$self->{color_theme} = $theme;
|
|
return $theme;
|
|
}
|
|
|
|
sub term_width {
|
|
return $USE_TERM_SIZE ? (chars())[0] : 120;
|
|
}
|
|
|
|
sub term_height {
|
|
return $USE_TERM_SIZE ? (chars())[1] : 24;
|
|
}
|
|
|
|
=head1 LICENSE
|
|
|
|
This file is part of jmx4perl.
|
|
|
|
Jmx4perl 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 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
jmx4perl 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 jmx4perl. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
A commercial license is available as well. Please contact roland@cpan.org for
|
|
further details.
|
|
|
|
=head1 PROFESSIONAL SERVICES
|
|
|
|
Just in case you need professional support for this module (or Nagios or JMX in
|
|
general), you might want to have a look at
|
|
http://www.consol.com/opensource/nagios/. Contact roland.huss@consol.de for
|
|
further information (or use the contact form at http://www.consol.com/contact/)
|
|
|
|
=head1 AUTHOR
|
|
|
|
roland@cpan.org
|
|
|
|
=cut
|
|
|
|
1;
|
|
|