OW_IndicationExporter.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_IndicationExporter.hpp"
00038 #include "OW_CIMProperty.hpp"
00039 #include "OW_CIMInstance.hpp"
00040 #include "OW_TempFileStream.hpp"
00041 #include "OW_CIMtoXML.hpp"
00042 #include "OW_Format.hpp"
00043 #include "OW_CIMObjectPath.hpp"
00044 #include "OW_CIMXMLParser.hpp"
00045 #include "OW_CIMException.hpp"
00046 
00047 namespace OW_NAMESPACE
00048 {
00049 
00050 // We always send the lowest possible version. If 1.0 and 1.1 are the same, we send 1.0 so that 1.0 only clients will accept the request.
00051 // If we're using a 1.1 only feature, then we have to send 1.1.
00052 namespace
00053 {
00054 const String PROTOCOL_VERSION_1_1("1.1");
00055 }
00056 
00057 using std::ostream;
00058 using std::istream;
00059 using std::iostream;
00060 IndicationExporter::IndicationExporter( CIMProtocolIFCRef prot )
00061    : m_protocol(prot), m_iMessageID(0)
00062 {
00063    m_protocol->setContentType("application/xml");
00064 }
00065 void
00066 IndicationExporter::exportIndication( const String& ns, const CIMInstance& ci )
00067 {
00068    static const char* const commandName = "ExportIndication";
00069    Array<Param> params;
00070    
00071    Reference<TempFileStream> iostr(new TempFileStream);
00072    sendXMLHeader(*iostr, PROTOCOL_VERSION_1_1);
00073    *iostr << "<EXPPARAMVALUE NAME=\"NewIndication\">";
00074    CIMInstancetoXML(ci, *iostr);
00075    *iostr << "</EXPPARAMVALUE>";
00076    sendXMLTrailer(*iostr);
00077    doSendRequest(iostr, commandName, ns, PROTOCOL_VERSION_1_1);
00078 }
00079 void
00080 IndicationExporter::sendXMLHeader(ostream& ostr, const String& cimProtocolVersion)
00081 {
00082    // TODO: merge this with the code in CIMXMLCIMOMHandle.cpp
00083    // TODO: WRT the versions, have a way of doing a fallback to older
00084    // versions for the sake of compatibility.
00085    if (++m_iMessageID > 65535)
00086    {
00087       m_iMessageID = 1;
00088    }
00089    ostr << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
00090    ostr << "<CIM CIMVERSION=\"2.0\" DTDVERSION=\"2.0\">";
00091    ostr << "<MESSAGE ID=\"" << m_iMessageID << "\" PROTOCOLVERSION=\"" << cimProtocolVersion << "\">";
00092    ostr << "<SIMPLEEXPREQ>";
00093    ostr << "<EXPMETHODCALL NAME=\"ExportIndication\">";
00094 }
00095 void
00096 IndicationExporter::sendXMLTrailer(ostream& ostr)
00097 {
00098    ostr << "</EXPMETHODCALL>";
00099    ostr << "</SIMPLEEXPREQ>";
00100    ostr << "</MESSAGE>";
00101    ostr << "</CIM>";
00102    ostr << "\r\n";
00103 }
00104    
00105 void
00106 IndicationExporter::doSendRequest(Reference<iostream> ostr, const String& methodName,
00107       const String& ns, const String& cimProtocolVersion)
00108 {
00109    CIMProtocolIStreamIFCRef istr = m_protocol->endRequest(ostr, methodName,
00110       ns, CIMProtocolIFC::E_CIM_EXPORT_REQUEST, cimProtocolVersion);
00111    // Debug stuff
00112    /*
00113    TempFileStream buf;
00114    buf << istr.rdbuf();
00115    ofstream ofstr("/tmp/rchXMLDump", ios::app);
00116    ofstr << "******* New dump ********" << endl;
00117    ofstr << buf.rdbuf() << endl;
00118    buf.rewind();
00119    XMLParser parser(&buf);
00120    */
00121    // end debug stuff
00122    CIMXMLParser parser(*istr);
00123    return checkNodeForCIMError(parser, methodName);
00124 }
00125 void
00126 IndicationExporter::checkNodeForCIMError(CIMXMLParser& parser,
00127       const String& operation)
00128 {
00129 // TODO: This code is the same as in CIMXMLCIMOMHandle.cpp.  Put it in a
00130 // common spot.
00131    //
00132    // Check for <CIM> element
00133    //
00134    if (!parser || !parser.tokenIsId(CIMXMLParser::E_CIM))
00135    {
00136       OW_THROWCIMMSG(CIMException::FAILED, "Invalid XML");
00137    }
00138    String cimattr;
00139 // TODO: Decide if we really should check this or not.
00140 #if 0
00141    cimattr = parser.mustGetAttribute(CIMXMLParser::A_CIMVERSION);
00142    if (!cimattr.equals(CIMXMLParser::AV_CIMVERSION_VALUE))
00143    {
00144       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00145                      String("Return is for CIMVERSION " + cimattr).c_str());
00146    }
00147    cimattr = parser.mustGetAttribute(CIMXMLParser::A_DTDVERSION);
00148    if (!cimattr.equals(CIMXMLParser::AV_DTDVERSION_VALUE))
00149    {
00150       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00151                      String("Return is for DTDVERSION " + cimattr).c_str());
00152    }
00153 #endif
00154    //
00155    // Find <MESSAGE>
00156    //
00157    parser.mustGetChildId(CIMXMLParser::E_MESSAGE);
00158    cimattr=parser.mustGetAttribute(CIMXMLParser::A_ID);
00159    if (!cimattr.equals(String(m_iMessageID)))
00160    {
00161       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00162                      String("Return messageid="+cimattr+", expected="
00163                                +String(m_iMessageID)).c_str());
00164    }
00165 // TODO: Decide if we really should check this or not.
00166 #if 0
00167    cimattr = parser.mustGetAttribute(CIMXMLParser::A_PROTOCOLVERSION);
00168    if (!cimattr.equals(CIMXMLParser::AV_PROTOCOLVERSION_VALUE))
00169    {
00170       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00171                      String("Return is for PROTOCOLVERSION "+cimattr).c_str());
00172    }
00173 #endif
00174    // Find <SIMPLEEXPRSP>
00175    //
00176    // TODO-NICE: need to look for complex EXPRSPs!!
00177    //
00178    parser.mustGetChildId(CIMXMLParser::E_SIMPLEEXPRSP);
00179    //
00180    // <EXPMETHODRESPONSE>
00181    //
00182    parser.mustGetChildId(CIMXMLParser::E_EXPMETHODRESPONSE);
00183    String nameOfMethod = parser.getAttribute(CIMXMLParser::A_NAME);
00184    if (nameOfMethod.empty())
00185    {
00186       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00187                      "Response had no method name");
00188    }
00189    if (!nameOfMethod.equalsIgnoreCase(operation))
00190    {
00191       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00192                      String("Called "+operation+" but response was for "+
00193                                nameOfMethod).c_str());
00194    }
00195    parser.mustGetNextTag();
00196    if (parser.tokenIsId(CIMXMLParser::E_ERROR))
00197    {
00198       String errCode = parser.mustGetAttribute(
00199          CIMXMLParser::A_CODE);
00200       String description = parser.getAttribute(
00201          CIMXMLParser::A_DESCRIPTION);
00202       Int32 iErrCode;
00203       try
00204       {
00205          iErrCode = errCode.toInt32();
00206       }
00207       catch (const StringConversionException& e)
00208       {
00209          OW_THROWCIMMSG(CIMException::FAILED, Format("Invalid xml. Error code \"%1\" is not an integer",
00210             e.getMessage()).c_str());
00211       }
00212       OW_THROWCIMMSG(CIMException::ErrNoType(errCode.toInt32()), description.c_str());
00213    }
00214 }
00215    
00216 
00217 } // end namespace OW_NAMESPACE
00218 

Generated on Thu Feb 9 08:48:00 2006 for openwbem by  doxygen 1.4.6