# Home.pm: Class Used for Managing Oracle Homes package RDA::Target::Home; # $Id: Home.pm,v 1.16 2016/01/01 13:01:24 RDA Exp $ # ARCS: $Header: /home/cvs/cvs/RDA_8/src/scripting/lib/RDA/Target/Home.pm,v 1.16 2016/01/01 13:01:24 RDA Exp $ # # Change History # 20160101 MSC Improve environment for invalid home directory. =head1 NAME RDA::Target::Home - Class Used for Managing Oracle Homes =head1 SYNOPSIS require RDA::Target::Home; =head1 DESCRIPTION The objects of the C class are used to manage Oracle and common homes and the auto discovery aspects. It is a subclass of L. The following methods are available: =cut use strict; BEGIN { use Exporter; use RDA::Text qw(get_string); use RDA::Driver::Product; use RDA::Object; use RDA::Object::Rda; use RDA::Object::Target; use RDA::Object::Xml; use RDA::Target::System; } # Define the global public variables use vars qw($STRINGS $VERSION @DUMP @ISA %SDCL); $VERSION = sprintf('%d.%02d', q$Revision: 1.16 $ =~ /(\d+)\.(\d+)/); @DUMP = ( hsh => {'RDA::Target::Base' => 1, 'RDA::Target::Common' => 1, 'RDA::Target::Database' => 1, 'RDA::Target::Db' => 1, 'RDA::Target::Dbi' => 1, 'RDA::Target::Domain' => 1, 'RDA::Target::Home' => 1, 'RDA::Target::Instance' => 1, 'RDA::Target::MwHome' => 1, 'RDA::Target::System' => 1, 'RDA::Target::WlHome' => 1, }, ); @ISA = qw(RDA::Target::System RDA::Object::Target RDA::Object RDA::Driver::Product Exporter); %SDCL = ( inc => [qw(RDA::Object::Target RDA::Object)], met => { 'get_location' => {ret => 0}, 'get_product' => {ret => 0}, 'get_products' => {ret => 1}, 'get_sqlplus' => {ret => 1}, 'get_version' => {ret => 0}, 'has_inventory' => {ret => 0}, }, ); # Define the global private constants # Define the global private variables my %tb_nat = map {$_ => 1} qw(hom tns); # Report the package version sub Version { return $VERSION; } =head2 S<$h = RDA::Target::Home-Enew($oid,$col,$def,$par[,$edt])> The object constructor. It takes the object identifier, the collector object reference, the definition item reference, the parent target reference, and an optional initial attribute hash reference as arguments. Do not use this constructor directly. Create all targets using the L methods. C is represented by a blessed hash reference. The following special keys are used: =over 12 =item S< B<'cfg' > > Reference to the RDA software configuration =item S< B<'col' > > Reference to the collector object =item S< B<'hom' > > Oracle home directory =item S< B<'ini' > > Initial Oracle home directory =item S< B<'jdk' > > JDK directory =item S< B<'oid' > > Object identifier =item S< B<'par' > > Reference to the parent target =item S< B<'raw' > > Raw value indicator =item S< B<'sql' > > SQL*Plus specifications =item S< B<'tns' > > TNS_ADMIN specification =item S< B<'_abr'> > Symbol definition hash =item S< B<'_bkp'> > Backup of environment variables =item S< B<'_chg'> > Symbol change hash =item S< B<'_chl'> > List of the child keys =item S< B<'_def'> > Reference to the target definition item =item S< B<'_env'> > Environment specifications =item S< B<'_fcs'> > Focus hash =item S< B<'_inv'> > Inventory object =item S< B<'_prd'> > OCM product list =item S< B<'_prs'> > Symbol detection parse tree =item S< B<'_shr'> > Share indicator =item S< B<'_src'> > Inventory source =item S< B<'_typ'> > Target type =back Internal keys are prefixed by an underscore. Defined inventory sources are: =over 12 =item S< B<'INV'> > Oracle home inventory =item S< B<'OCM'> > OCM configuration information =back An empty string indicates that no inventory has been found. =cut sub new { my ($cls, $oid, $col, $def, $par, $edt) = @_; my ($alt, $key, $raw, $slf, $val); # Create the Oracle home object $raw = $def->get_first('B_RAW', 0); $slf = bless { cfg => $col->get_config, col => $col, oid => $par->get_unique($oid), par => $par, raw => $raw, _chl => [], _def => $def, _fcs => {}, _shr => $def->get_first(['B_DEDICATED_HOME','B_DEDICATED']) ? 0 : 1, _typ => 'OH', }, ref($cls) || $cls; # Load the target definition if (defined($val = $def->get_first('D_ORACLE_HOME', undef, $raw))) { $slf->{'hom'} = $val; $slf->{'ini'} = $alt if defined($alt = $def->get_first('T_ORACLE_HOME')) && $alt ne $val; } $slf->{'tns'} = undef if $def->get_first('B_NO_TNS_ADMIN'); $slf->{'tns'} = $val if defined($val = $def->get_first('D_TNS_ADMIN', undef, $raw)); # Add the initial attributes if ($edt) { foreach my $key (keys(%{$edt})) { $slf->{$key} = exists($tb_nat{$key}) ? RDA::Object::Rda->native($edt->{$key}) : $edt->{$key}; } } # Validate the configuration die get_string('NO_HOME', $oid) unless exists($slf->{'hom'}); # Detect the presence of a JDK $slf->{'jdk'} = $val if -d ($val = RDA::Object::Rda->cat_dir($slf->{'hom'}, 'jdk')); # Initiate the symbol management when applicable unless (RDA::Object::Rda->is_vms) { $slf->{'_abr'} = {}; $slf->set_symbol($def->get_first('T_OH_ABBR'), $slf->{'hom'}); delete($slf->{'_chg'}); } # Return the object reference return $slf; } sub new_home { my ($cls, $col, $hom) = @_; return bless { cfg => $col->get_config, col => $col, hom => $hom, oid => $hom, _typ => 'OH', }, ref($cls) || $cls; } =head2 S<$h-Efind_jars($typ,$src,$jdk)> This method returns the list of C files required to connect to the specified database. =cut sub find_jars { my ($slf, $typ, $src, $jdk) = @_; my ($dir, $jar, $ver, @jar); if ($typ eq 'oracle') { (undef, $ver) = $slf->get_jdk_version($jdk); if (defined($ver)) { $dir = RDA::Object::Rda->cat_dir($slf->{'hom'}, 'jdbc', 'lib'); return $jar if -f ($jar = RDA::Object::Rda->cat_file($dir, "ojdbc$ver.jar")); @jar = _grep_oracle_jar($dir, 5, $ver); return pop(@jar) if @jar; } else { @jar = _grep_oracle_jar($dir, 0, 99); return shift(@jar) if @jar; } } return } sub _grep_oracle_jar { my ($dir, $min, $max) = @_; my (@jar); if (opendir(DIR, $dir)) { foreach my $fil (readdir(DIR)) { push(@jar, RDA::Object::Rda->cat_file($dir, $fil)) if $fil =~ m/^ojdbc(\d+)\.jar$/ && $1 >= $min && $1 <= $max; } closedir(DIR); } return (sort @jar); } =head2 S<$h-Efind_sqlplus> This method returns a reference to the SQL*Plus context. =cut sub find_sqlplus { my ($slf) = @_; my ($cmd, $hom); # Return the result of a previous detection return $slf->{'sql'} if exists($slf->{'sql'}); # Determine how to execute SQL*Plus on first call $hom = $slf->{'hom'}; if (RDA::Object::Rda->is_unix) { return $slf->{'sql'} = {cmd => $cmd, env => $slf->get_env, typ => 'HOM'} if -f ($cmd = RDA::Object::Rda->cat_file($hom, 'bin', 'sqlplus')); } elsif (RDA::Object::Rda->is_windows || RDA::Object::Rda->is_cygwin) { return $slf->{'sql'} = {cmd => $cmd, env => $slf->get_env, typ => 'HOM'} if -f ($cmd = RDA::Object::Rda->cat_file($hom, 'bin', 'PLUS80.exe')) || -f ($cmd = RDA::Object::Rda->cat_file($hom, 'bin', 'sqlplus.exe')); } # Indicate that SQL*Plus is not present return $slf->{'sql'} = undef; } =head2 S<$h-Eget_env> This method returns the environment variable specifications as a hash reference. =cut sub get_env { my ($slf) = @_; my ($env, $lib, $ora, $sep, $sys, @tbl); # Determine the environment specifications on first usage unless (exists($slf->{'_env'})) { $slf->{'_env'} = $env = {}; unless (RDA::Object::Rda->is_vms) { $env->{'INITIAL_HOME'} = $slf->{'ini'} if exists($slf->{'ini'}) && RDA::Object::Rda->is_unix; $env->{'ORACLE_HOME'} = $ora = $slf->{'hom'}; $env->{'TNS_ADMIN'} = $slf->{'tns'} if exists($slf->{'tns'}); $sys = $slf->get_top('sys'); $sep = $sys->get_separator; if ($ora && -d $ora) { # Adapt the command path @tbl = $sys->get_list('pth'); foreach my $dir (RDA::Object::Rda->cat_dir($ora, 'bin'), RDA::Object::Rda->cat_dir($ora, 'jdk', 'bin')) { unshift(@tbl, $dir) if defined($dir = $sys->is_restricted($dir)); } $env->{'PATH'} = join($sep, @tbl); # Adapt the shared library path if (defined($lib = RDA::Object::Rda->get_shlib)) { my ($dir); @tbl = $sys->get_list('shl'); unshift(@tbl, $dir) if -d ($dir = RDA::Object::Rda->cat_dir($ora, 'lib')); $env->{$lib} = join($sep, @tbl) if @tbl; } } else { $env->{'PATH'} = join($sep, $sys->get_list('pth')); $env->{$lib} = join($sep, $sys->get_list('shl')) if defined($lib = RDA::Object::Rda->get_shlib); } } } # Return the environment specifications return $slf->{'_env'}; } 1; __END__ =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L =head1 COPYRIGHT NOTICE Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. =head1 TRADEMARK NOTICE Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. =cut