1#************************************************************************* 2# 3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4# 5# Copyright 2000, 2010 Oracle and/or its affiliates. 6# 7# OpenOffice.org - a multi-platform office productivity suite 8# 9# This file is part of OpenOffice.org. 10# 11# OpenOffice.org is free software: you can redistribute it and/or modify 12# it under the terms of the GNU Lesser General Public License version 3 13# only, as published by the Free Software Foundation. 14# 15# OpenOffice.org is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU Lesser General Public License version 3 for more details 19# (a copy is included in the LICENSE file that accompanied this code). 20# 21# You should have received a copy of the GNU Lesser General Public License 22# version 3 along with OpenOffice.org. If not, see 23# <http://www.openoffice.org/license.html> 24# for a copy of the LGPLv3 License. 25# 26#************************************************************************* 27 28 29# 30# Eis.pm - package for accessing/manipulating the EIS database via SOAP 31# 32 33package Eis; 34use strict; 35 36use SOAP::Lite; 37use Class::Struct; 38use Carp; 39 40# Declaration of class Eis together with ctor and accessors. 41# See 'perldoc Class::Struct' for details 42 43struct Eis => [ 44 # public members 45 uri => '$', # name of webservice 46 proxy_list => '@', # list of proxy URLs 47 current_proxy => '$', # current proxy (index in proxy_list) 48 net_proxy => '$', # network proxy to pass through firewall 49 # private members 50 eis_connector => '$' # SOAP connector to EIS database 51]; 52 53#### public methods #### 54 55# Any not predeclared method call to this package is 56# interpreted as a SOAP method call. We use the AUTOLOAD 57# mechanism to intercept these calls and delgate them 58# to the eis_connector. 59# See the 'Camel Book', 3rd edition, page 337 for an 60# explanation of the AUTOLOAD mechanism. 61sub AUTOLOAD 62{ 63 my $self = shift; 64 my $callee = $Eis::AUTOLOAD; # $callee now holds the name of 65 # called subroutine 66 # 67 return if $callee =~ /::DESTROY$/; 68 $callee = substr($callee, 5); 69 70 my $sl = $self->eis_connector(); 71 if ( !$sl ) { 72 $sl = $self->init_eis_connector(); 73 $self->eis_connector($sl); 74 } 75 76 my $response; 77 while ( 1 ) { 78 # Call callee() on web service. 79 eval { $response = $sl->$callee(@_) }; 80 if ( $@ ) { 81 # Transport error (server not available, timeout, etc). 82 # Use backup server. 83 print STDERR ("Warning: web service unavailable. Trying backup server.\n"); 84 if ( !$self->set_next_proxy() ) { 85 # All proxies tried, out of luck 86 carp("ERROR: Connection to EIS database failed.\n"); 87 return undef; 88 } 89 } 90 else { 91 last; 92 } 93 } 94 95 if ( $response->fault() ) { 96 my $fault_msg = get_soap_fault_message($response); 97 die $fault_msg; # throw $fault_msg as exception 98 } 99 else { 100 return $response->result(); 101 } 102} 103 104#### public class methods #### 105 106# Turn scalar into SOAP string. 107sub to_string 108{ 109 my $value = shift; 110 111 return SOAP::Data->type(string => $value); 112} 113 114#### non public instance methods #### 115 116# Initialize SOAP connection to EIS. 117sub init_eis_connector 118{ 119 my $self = shift; 120 121 # Init current_proxy with first element of the proxy list. 122 my $current = $self->current_proxy(0); 123 124 if ( !$self->uri() ) { 125 carp("ERROR: web service URI not set."); 126 return undef; 127 } 128 129 if ( !$self->proxy_list->[$current] ) { 130 carp("ERROR: proxy list not proper initialized."); 131 return undef; 132 } 133 134 # might be needed to get through a firewall 135 if ( defined($self->net_proxy()) ) { 136 $ENV{HTTPS_PROXY}=$self->net_proxy(); 137 } 138 139 my $proxy = $self->proxy_list()->[$current]; 140 if ( $proxy =~ /^\s*https\:\/\// ) { 141 # SOAP::Lite does not complain if Crypt::SSLeay is not available, 142 # but crypted connections will just not work. Force the detection of 143 # Crypt::SSLeay for https connections and fail with a meaningful 144 # message if it's not available. 145 require Crypt::SSLeay; 146 } 147 return create_eis_connector($self->uri(), $proxy); 148} 149 150# Advance one entry in proxy list. 151sub set_next_proxy 152{ 153 my $self = shift; 154 155 my @proxies = @{$self->proxy_list()}; 156 my $current = $self->current_proxy(); 157 158 if ( $current == $#proxies ) { 159 return 0; 160 } 161 else { 162 $self->current_proxy(++$current); 163 my $next_proxy = $self->proxy_list()->[$current]; 164 $self->eis_connector()->proxy($next_proxy); 165 return 1; 166 } 167} 168 169#### misc #### 170 171# Create new SOAP EIS conector. 172sub create_eis_connector 173{ 174 my $uri = shift; 175 my $proxy = shift; 176 177 my $sl; 178 179 # With version 0.66 of SOAP::Lite the uri() method 180 # has been deprecated in favour of ns(). There 181 # seems to be no way to switch of the deprecation warning 182 # (which may be a bug in this version of SOAP::Lite). 183 # Since older versions do not support the ns() method we 184 # either force everyone to upgrade now, or make the following 185 # dependent on the SOAP::Lite version. 186 my ($vmaj, $vmin) = (0, 0); 187 if( $SOAP::Lite::VERSION =~ m/([0-9]*)\.([0-9]*)/ ) { 188 $vmaj = $1; 189 $vmin = $2; 190 if ( $vmaj > 0 || ( $vmaj == 0 && $vmin >= 66 ) ) { 191 $sl = SOAP::Lite 192 -> ns($uri) 193 -> proxy($proxy); 194 } 195 else { 196 $sl = SOAP::Lite 197 -> uri($uri) 198 -> proxy($proxy); 199 } 200 } 201 else { 202 carp("ERROR: Can't determine SOAP::Lite version."); 203 } 204 205 return $sl; 206} 207 208# Retrieve SOAP fault message. 209sub get_soap_fault_message 210{ 211 my $faulty_response = shift; 212 my $fault_msg = join(', ', $faulty_response->faultcode(), 213 $faulty_response->faultstring(), 214 $faulty_response->faultdetail()); 215 return $fault_msg; 216} 217 218#### 219 2201; # needed by "use" or "require" 221