OW_XMLListener.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_XMLListener.hpp"
00038 #include "OW_CIMXMLParser.hpp"
00039 #include "OW_CIMErrorException.hpp"
00040 #include "OW_CIMListenerCallback.hpp"
00041 #include "OW_Format.hpp"
00042 #include "OW_XMLEscape.hpp"
00043 #include "OW_TempFileStream.hpp"
00044 #include "OW_CIMFeatures.hpp"
00045 #include "OW_CIMInstance.hpp"
00046 #include "OW_XMLCIMFactory.hpp"
00047 #include "OW_ConfigOpts.hpp"
00048 #include "OW_Assertion.hpp"
00049 #include "OW_ServiceIFCNames.hpp"
00050 
00051 namespace OW_NAMESPACE
00052 {
00053 
00054 using std::ostream;
00056 XMLListener::XMLListener(const CIMListenerCallbackRef& callback)
00057 : RequestHandlerIFCXML(),  m_callback(callback)
00058 {
00059 }
00061 XMLListener::~XMLListener()
00062 {
00063 }
00065 String
00066 XMLListener::getName() const
00067 {
00068    return ServiceIFCNames::XMLListener;
00069 }
00071 RequestHandlerIFC*
00072 XMLListener::clone() const
00073 {
00074    return new XMLListener(*this);
00075 }
00077 int
00078 XMLListener::executeXML(CIMXMLParser& parser, ostream* ostrEntity,
00079    ostream* ostrError, OperationContext& context)
00080 {
00081    clearError();
00082    String messageId = parser.mustGetAttribute(CIMXMLParser::A_ID);
00083    parser.getChild();
00084    if (!parser)
00085    {
00086       OW_THROW(CIMErrorException, CIMErrorException::request_not_loosely_valid);
00087    }
00088    makeXMLHeader(messageId, *ostrEntity);
00089    if (parser.tokenIsId(CIMXMLParser::E_MULTIEXPREQ))
00090    {
00091       parser.getChild();
00092       if (!parser)
00093       {
00094          OW_THROW(CIMErrorException, CIMErrorException::request_not_loosely_valid);
00095       }
00096       while (parser)
00097       {
00098          TempFileStream ostrEnt, ostrErr;
00099          processSimpleExpReq(parser, ostrEnt, ostrErr, messageId, context);
00100          if (hasError())
00101          {
00102             (*ostrEntity) << ostrErr.rdbuf();
00103             clearError();
00104          }
00105          else
00106          {
00107             (*ostrEntity) << ostrEnt.rdbuf();
00108          }
00109 
00110          parser.getNextId(CIMXMLParser::E_SIMPLEEXPREQ, true);
00111       }
00112    }
00113    else if (parser.tokenIsId(CIMXMLParser::E_SIMPLEEXPREQ))
00114    {
00115       processSimpleExpReq(parser, *ostrEntity, *ostrError, messageId, context);
00116    }
00117    else
00118    {
00119       OW_THROW(CIMErrorException, CIMErrorException::request_not_loosely_valid);
00120    }
00121    if (!hasError())
00122    {
00123       (*ostrEntity) << "</MESSAGE></CIM>\r\n";
00124    }
00125    return 0;
00126 }
00128 void
00129 XMLListener::doOptions(CIMFeatures &cf, OperationContext&)
00130 {
00131    cf.extURL = "http://www.dmtf.org/cim/mapping/http/v1.0";
00132    cf.cimProduct = CIMFeatures::LISTENER;
00133    cf.cimom = "/cimom";
00134    cf.protocolVersion = "1.1";
00135    cf.supportedGroups.clear();
00136    cf.supportedGroups.push_back("Indication");
00137    cf.supportedQueryLanguages.clear();
00138    cf.supportsBatch = true;
00139    cf.validation = "";
00140 }
00142 void
00143 XMLListener::processSimpleExpReq(CIMXMLParser& parser,
00144    ostream& ostrEntity, ostream& ostrError, const String& messageId, OperationContext&)
00145 {
00146    try
00147    {
00148       if (!parser.tokenIsId(CIMXMLParser::E_SIMPLEEXPREQ))
00149       {
00150          OW_THROW(CIMErrorException, CIMErrorException::request_not_loosely_valid);
00151       }
00152       parser.mustGetChildId(CIMXMLParser::E_EXPMETHODCALL);
00153       parser.mustGetNextTag();
00154       while (parser.tokenIsId(CIMXMLParser::E_EXPPARAMVALUE)
00155          || parser.tokenIsId(CIMXMLParser::E_IPARAMVALUE) // do this because of a bug in the CIMXML 2.1 DTD
00156       )
00157       {
00158          String paramName = parser.getAttribute(CIMXMLParser::A_NAME);
00159          if (paramName != "NewIndication")
00160          {
00161             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00162                paramName.c_str());
00163          }
00164          parser.mustGetChildId(CIMXMLParser::E_INSTANCE);
00165          CIMInstance inst = XMLCIMFactory::createInstance(parser);
00166          m_callback->indicationOccurred(inst, m_path);
00167          parser.mustGetEndTag(); // pass </EXPPARAMVALUE>
00168       }
00169       parser.mustGetEndTag(); // pass </EXPMETHODCALL>
00170       parser.mustGetEndTag(); // pass </SIMPLEEXPREQ>
00171       ostrEntity << "<SIMPLEEXPRSP>";
00172       ostrEntity << "<EXPMETHODRESPONSE NAME=\"ExportIndication\">";
00173       ostrEntity << "</EXPMETHODRESPONSE>";
00174       ostrEntity << "</SIMPLEEXPRSP>";
00175    }
00176    catch(CIMException& ce)
00177    {
00178       makeXMLHeader(messageId, ostrError);
00179       outputError(ce.getErrNo(), ce.getDescription(), ostrError);
00180    }
00181 }
00183 void
00184 XMLListener::outputError(CIMException::ErrNoType errorCode,
00185    const String& msg, ostream& ostr)
00186 {
00187    setError(errorCode, msg);
00188    ostr << "<SIMPLEEXPRSP>";
00189    ostr << "<EXPMETHODRESPONSE NAME=\"ExportIndication\">";
00190    ostr << "<ERROR CODE=\"" << errorCode << "\"";
00191    // always have to send DESCRIPTION, since there are clients that can't handle it not being there.
00192    //if (!msg.empty())
00193    //{
00194       ostr << " DESCRIPTION=\"" <<
00195       XMLEscape(msg) <<
00196       "\"";
00197    //}
00198    ostr << "></ERROR>";
00199    ostr << "</EXPMETHODRESPONSE>";
00200    ostr << "</SIMPLEEXPRSP>";
00201    ostr << "</MESSAGE></CIM>\r\n";
00202 }
00204 StringArray
00205 XMLListener::getSupportedContentTypes() const
00206 {
00207    StringArray rval;
00208    rval.push_back("text/xml");
00209    rval.push_back("application/xml");
00210    return rval;
00211 }
00213 String
00214 XMLListener::getContentType() const
00215 {
00216    return String("application/xml");
00217 }
00218 
00220 void
00221 XMLListener::init(const ServiceEnvironmentIFCRef& env)
00222 {
00223 }
00224 
00226 void
00227 XMLListener::shutdown()
00228 {
00229 }
00230 
00231 } // end namespace OW_NAMESPACE
00232 

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