00001 00010 // SOAPMethod.cpp: implementation of the SOAPMethod class. 00011 // 00012 // $Log: SOAPMethod.cpp,v $ 00013 // Revision 1.1 2005/03/22 22:22:14 gjpc 00014 // This is the intial check in of the Simple SOAP library. 00015 // 00016 // The code compiles and executes under MSVC .NET and GNU 3.3 00017 // 00018 // It has been run under Debian, SUSE, CYGWIN and WinXP 00019 // 00020 // Revision 1.3 2004/04/23 16:59:26 gjpc 00021 // expanded the Simple SOAP package to allow RPC's within RPC's 00022 // 00023 // 00025 00026 #pragma warning ( disable: 4786 ) 00027 #include "SOAPMethod.h" 00028 #include <assert.h> 00030 // Construction/Destruction 00032 00033 SOAPMethod::SOAPMethod() : 00034 m_bSucceeded( true ) 00035 { 00036 00037 } 00038 00039 SOAPMethod::~SOAPMethod() 00040 { 00041 00042 } 00043 00044 00045 bool SOAPMethod::mustIUnderstand( SOAPElement& theCall ) 00046 { 00047 SOAPElement* pHeader = NULL; 00048 theCall.getElement( "Header", &pHeader ); 00049 bool retval = false; 00050 if ( pHeader != NULL ) 00051 { 00052 // check if anybody has mustUnderstand set to true. 00053 long nNumElements = pHeader->numElements(); 00054 long nNumAttributes = 0; 00055 SOAPAttribute soapAttribute; 00056 for ( long i = 0; i < nNumElements; ++i ) 00057 { 00058 SOAPElement& aHeaderElement = pHeader->elementAt( i ); 00059 if ( aHeaderElement.getAttribute( "mustUnderstand", 00060 soapAttribute ) ) 00061 { 00062 retval = soapAttribute.value() == std::string("1"); 00063 } 00064 } 00065 } 00066 00067 if ( retval ) 00068 { 00069 std::ostringstream szStream; 00070 00071 setFailed(); 00072 getFault()->setFaultCode( SOAPFault::MustUnderstand ); 00073 szStream << "This object does not understand any mustUnderstand header entries." << std::ends; 00074 getFault()->faultString() = szStream.str(); 00075 } 00076 return retval; 00077 } 00078 00079 bool SOAPMethod::extractMethod( SOAPElement &theCall, SOAPElement &theMethod ) 00080 { 00081 if ( mustIUnderstand( theCall ) ) 00082 { 00083 setFailed(); 00084 getFault()->setFaultCode( SOAPFault::MustUnderstand ); 00085 return false; 00086 } 00087 // Grab the body and get the first two elements. 00088 SOAPElement* pBody = NULL; 00089 theCall.getElement( "Body", &pBody ); 00090 if ( NULL == pBody ) 00091 { 00092 setFailed(); 00093 getFault()->faultString() = "NoBody"; 00094 getFault()->detail() = "The SOAP message is missing a Body Element"; 00095 return false; 00096 } 00097 00098 if ( pBody->numElements() == 1 ) 00099 { 00100 theMethod = pBody->elementAt( 0 ); 00101 return true; 00102 } 00103 00104 setFailed(); 00105 getFault()->faultString() = "NoMethod"; 00106 getFault()->detail() = "The SOAP message is missing a Method Element"; 00107 return false; 00108 00109 } 00110 00111 bool SOAPMethod::execute( SOAPElement& argList ) 00112 { 00113 // If this assert fires, you need to implement the method. 00114 // We include a default implementation because 00115 // client-sdie SOAP Methods should never call execute. 00116 assert( false ); 00117 return false; 00118 } 00119 00120 bool SOAPMethod::succeeded() 00121 { 00122 return m_bSucceeded; 00123 } 00124 00125 void SOAPMethod::setFailed() 00126 { 00127 m_pFault = std::auto_ptr<SOAPFault>( new SOAPFault ); 00128 m_bSucceeded = false; 00129 } 00130 00131 SOAPFault* SOAPMethod::getFault() 00132 { 00133 // Don't create it if we didn't need it. 00134 return m_pFault.get(); 00135 } 00136 00137 // here is a helper function to remove some repetitive coding from the executioners 00138 void SOAPMethod::unkownMethodFault( SOAPElement aElement ) 00139 { 00140 std::ostringstream szStream; 00141 00142 setFailed(); 00143 getFault()->faultString() = "Invalid method name."; 00144 getFault()->setSpecificFault( "MethodName" ); 00145 szStream << "The fault occurred because the requsted method is unkown " 00146 << aElement.accessorName() << "." << std::ends; 00147 getFault()->detail() = szStream.str(); 00148 } 00149 00150 // here is a helper function to remove some repetitive coding from the executioners 00151 void SOAPMethod::wrongNumberArgumentsFault( SOAPElement aElement, const char *num ) 00152 { 00153 std::ostringstream szStream; 00154 00155 setFailed(); 00156 getFault()->setSpecificFault( "InvalidArgumentCount" ); 00157 getFault()->faultString() = "Invalid number of arugments."; 00158 szStream << "The fault occurred because the " 00159 << aElement.accessorName() << " " 00160 << "method expected " << num << " argument(s) but received " 00161 << aElement.numElements() 00162 << " arguments."; 00163 getFault()->detail() = szStream.str(); 00164 } 00165 00166 // here is a helper function to remove some repetitive coding from the executioners 00167 bool SOAPMethod::ImustUnderstand( SOAPElement aElement ) 00168 { 00169 if ( mustIUnderstand( aElement ) ) 00170 { 00171 std::ostringstream szStream; 00172 setFailed(); 00173 getFault()->faultString() = "not understanding"; 00174 getFault()->setSpecificFault( "MustUnderstand" ); 00175 szStream << "The fault occurred because the requsted method is unkown" 00176 << aElement.accessorName() << "." << std::ends; 00177 getFault()->detail() = szStream.str(); 00178 return true; 00179 } 00180 return false; 00181 } 00182 00183 std::string SOAPMethod::methodNameAttributes( ) 00184 { 00185 return std::string("SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" "); 00186 }