OW_CIMServer.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_CIMServer.hpp"
00038 #include "OW_CIMValueCast.hpp"
00039 #include "OW_ConfigOpts.hpp"
00040 #include "OW_Format.hpp"
00041 #include "OW_WQLIFC.hpp"
00042 #include "OW_Assertion.hpp"
00043 #include "OW_CIMParamValue.hpp"
00044 #include "OW_CIMRepository.hpp"
00045 #include "OW_NoSuchProviderException.hpp"
00046 #include "OW_CIMValue.hpp"
00047 #include "OW_CIMProperty.hpp"
00048 #include "OW_CIMQualifierType.hpp"
00049 #include "OW_CIMQualifier.hpp"
00050 #include "OW_CIMMethod.hpp"
00051 #include "OW_CIMParameter.hpp"
00052 #include "OW_CIMObjectPath.hpp"
00053 #include "OW_CIMInstance.hpp"
00054 #include "OW_OperationContext.hpp"
00055 #include "OW_MutexLock.hpp"
00056 #include "OW_UserInfo.hpp"
00057 #include "OW_ResultHandlers.hpp"
00058 #include "OW_AuthorizerManager.hpp" 
00059 #include "OW_ProviderEnvironmentIFC.hpp"
00060 #include "OW_ProviderManager.hpp"
00061 #include "OW_ServiceIFCNames.hpp"
00062 
00063 #include <iterator>
00064 
00065 namespace OW_NAMESPACE
00066 {
00067 
00068 using namespace WBEMFlags;
00069 
00071 namespace
00072 {
00073    const String COMPONENT_NAME("ow.owcimomd.CIMServer");
00074    const char* const DEPRECATED__NamespaceClassName = "__Namespace";
00075 
00076    class AuthorizerEnabler
00077    {
00078    public:
00079       AuthorizerEnabler(const AuthorizerManagerRef& authorizerMgr,
00080          OperationContext& context, bool turnOff=false)
00081       : m_authorizerMgr(authorizerMgr)
00082       , m_context(context)
00083       {
00084          if (turnOff)
00085          {
00086             m_authorizerMgr->turnOff(m_context);
00087          }
00088       }
00089 
00090       ~AuthorizerEnabler()
00091       {
00092          m_authorizerMgr->turnOn(m_context);
00093       }
00094 
00095    private:
00096       AuthorizerManagerRef m_authorizerMgr;
00097       OperationContext& m_context;
00098    };
00099 
00100    class ClonedCIMServerProviderEnvironment : public ProviderEnvironmentIFC
00101    {
00102    public:
00103       ClonedCIMServerProviderEnvironment(
00104          const ServiceEnvironmentIFCRef& env)
00105          : m_env(env)
00106       {}
00107       virtual String getConfigItem(const String &name,
00108          const String& defRetVal="") const
00109       {
00110          return m_env->getConfigItem(name, defRetVal);
00111       }
00112       virtual StringArray getMultiConfigItem(const String &itemName, 
00113          const StringArray& defRetVal, const char* tokenizeSeparator = 0) const
00114       {
00115          return m_env->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00116       }
00117       virtual CIMOMHandleIFCRef getCIMOMHandle() const
00118       {
00119          return m_env->getCIMOMHandle(m_context,
00120             ServiceEnvironmentIFC::E_USE_PROVIDERS);
00121       }
00122       
00123       virtual CIMOMHandleIFCRef getRepositoryCIMOMHandle() const
00124       {
00125          return m_env->getCIMOMHandle(m_context,
00126             ServiceEnvironmentIFC::E_BYPASS_PROVIDERS);
00127       }
00128       
00129       virtual RepositoryIFCRef getRepository() const
00130       {
00131          return m_env->getRepository();
00132       }
00133       virtual LoggerRef getLogger() const
00134       {
00135          return m_env->getLogger(COMPONENT_NAME);
00136       }
00137       virtual LoggerRef getLogger(const String& componentName) const
00138       {
00139          return m_env->getLogger(componentName);
00140       }
00141       virtual String getUserName() const
00142       {
00143          return m_context.getUserInfo().getUserName();
00144       }
00145       virtual OperationContext& getOperationContext()
00146       {
00147          return m_context;
00148       }
00149       virtual ProviderEnvironmentIFCRef clone() const
00150       {
00151          return ProviderEnvironmentIFCRef(new ClonedCIMServerProviderEnvironment(m_env));
00152       }
00153    private:
00154       mutable OperationContext m_context;
00155       ServiceEnvironmentIFCRef m_env;
00156    };
00157 
00158    class CIMServerProviderEnvironment : public ProviderEnvironmentIFC
00159    {
00160    public:
00161       CIMServerProviderEnvironment(OperationContext& context,
00162          const ServiceEnvironmentIFCRef& env)
00163          : m_context(context)
00164          , m_env(env)
00165       {}
00166       virtual String getConfigItem(const String &name,
00167          const String& defRetVal="") const
00168       {
00169          return m_env->getConfigItem(name, defRetVal);
00170       }
00171       virtual StringArray getMultiConfigItem(const String &itemName, 
00172          const StringArray& defRetVal, const char* tokenizeSeparator = 0) const
00173       {
00174          return m_env->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00175       }
00176       virtual CIMOMHandleIFCRef getCIMOMHandle() const
00177       {
00178          return m_env->getCIMOMHandle(m_context,
00179             ServiceEnvironmentIFC::E_USE_PROVIDERS,
00180             ServiceEnvironmentIFC::E_NO_LOCKING);
00181       }
00182       
00183       virtual CIMOMHandleIFCRef getRepositoryCIMOMHandle() const
00184       {
00185          return m_env->getCIMOMHandle(m_context,
00186             ServiceEnvironmentIFC::E_BYPASS_PROVIDERS,
00187             ServiceEnvironmentIFC::E_NO_LOCKING);
00188       }
00189       
00190       virtual RepositoryIFCRef getRepository() const
00191       {
00192          return m_env->getRepository();
00193       }
00194       virtual LoggerRef getLogger() const
00195       {
00196          return m_env->getLogger(COMPONENT_NAME);
00197       }
00198       virtual LoggerRef getLogger(const String& componentName) const
00199       {
00200          return m_env->getLogger(componentName);
00201       }
00202       virtual String getUserName() const
00203       {
00204          return m_context.getUserInfo().getUserName();
00205       }
00206       virtual OperationContext& getOperationContext()
00207       {
00208          return m_context;
00209       }
00210       virtual ProviderEnvironmentIFCRef clone() const
00211       {
00212          return ProviderEnvironmentIFCRef(new ClonedCIMServerProviderEnvironment(m_env));
00213       }
00214    private:
00215       OperationContext& m_context;
00216       ServiceEnvironmentIFCRef m_env;
00217    };
00218 
00219    inline ProviderEnvironmentIFCRef createProvEnvRef(OperationContext& context,
00220       const ServiceEnvironmentIFCRef& env)
00221    {
00222       return ProviderEnvironmentIFCRef(new CIMServerProviderEnvironment(context, env));
00223    }
00224 
00225    inline void logOperation(const LoggerRef& lgr, const OperationContext& context, const char* operation, const String& ns, const String& objectName = String())
00226    {
00227       // avoid the overhead of formatting the message if we're not going to log this.
00228       ELogLevel level = lgr->getLogLevel();
00229       if (level == E_DEBUG_LEVEL || level == E_INFO_LEVEL)
00230       {
00231          String userString;
00232          String user = context.getStringDataWithDefault(OperationContext::USER_NAME);
00233          if (!user.empty())
00234          {
00235             userString = " for user: " + user;
00236          }
00237          String optObjectName;
00238          if (!objectName.empty())
00239          {
00240             optObjectName = ':' + objectName;
00241          }
00242          OW_LOG_INFO(lgr, Format("CIMServer doing operation: %1 on %2%3%4", operation, ns, optObjectName, userString));
00243       }
00244    }
00245 }
00246 
00248 CIMServer::CIMServer(const ServiceEnvironmentIFCRef& env,
00249    const ProviderManagerRef& provManager,
00250    const RepositoryIFCRef& cimRepository,
00251    const AuthorizerManagerRef& authorizerMgr)
00252    : RepositoryIFC()
00253    , m_provManager(provManager)
00254    , m_nsClass_Namespace(CIMNULL)
00255    , m_env(env)
00256    , m_cimRepository(cimRepository)
00257    , m_realRepository(dynamic_pointer_cast<CIMRepository>(m_cimRepository))
00258    , m_authorizerMgr(authorizerMgr)
00259    , m_logger(env->getLogger(COMPONENT_NAME))
00260 {
00261 }
00263 CIMServer::~CIMServer()
00264 {
00265    try
00266    {
00267       close();
00268    }
00269    catch (...)
00270    {
00271       // don't let exceptions escape
00272    }
00273 }
00275 void
00276 CIMServer::open(const String& path)
00277 {
00278 }
00280 void
00281 CIMServer::close()
00282 {
00283 }
00284 
00286 String
00287 CIMServer::getName() const
00288 {
00289    return ServiceIFCNames::CIMServer;
00290 }
00291 
00293 StringArray
00294 CIMServer::getDependencies() const
00295 {
00296    StringArray rv;
00297    rv.push_back(ServiceIFCNames::AuthorizerManager);
00298    rv.push_back(ServiceIFCNames::CIMRepository);
00299    rv.push_back(ServiceIFCNames::ProviderManager);
00300    return rv;
00301 }
00302 
00304 void
00305 CIMServer::init(const ServiceEnvironmentIFCRef& env)
00306 {
00307    // not much to do here, the ctor already did it all.
00308 }
00309 
00311 void
00312 CIMServer::shutdown()
00313 {
00314    m_provManager = 0;
00315    m_env = 0;
00316    m_cimRepository = 0;
00317    m_realRepository = 0;
00318    m_authorizerMgr = 0;
00319 }
00321 void
00322 CIMServer::_checkNameSpaceAccess(OperationContext& context, const String& ns,
00323    Authorizer2IFC::EAccessType acType)
00324 {
00325    if (!m_authorizerMgr->allowAccessToNameSpace(m_env, ns, acType,
00326       context))
00327    {
00328       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00329          Format("Access to namespace %1 is not allowed", ns).c_str());
00330    }
00331 }
00332 #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
00333 
00334 void
00335 CIMServer::createNameSpace(const String& ns,
00336    OperationContext& context)
00337 {
00338    if (!m_authorizerMgr->allowCreateNameSpace(
00339       m_env, ns, context))
00340    {
00341       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00342          Format("Creation of namespace %1 is not allowed",
00343             ns).c_str());
00344    }
00345 
00346    logOperation(m_logger, context, "createNameSpace", ns);
00347    m_cimRepository->createNameSpace(ns,context);
00348 }
00350 void
00351 CIMServer::deleteNameSpace(const String& ns,
00352    OperationContext& context)
00353 {
00354    if (!m_authorizerMgr->allowDeleteNameSpace(
00355       m_env, ns, context))
00356    {
00357       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00358          Format("Deletion of namespace %1 is not allowed",
00359             ns).c_str());
00360    }
00361 
00362    logOperation(m_logger, context, "deleteNameSpace", ns);
00363    m_cimRepository->deleteNameSpace(ns,context);
00364 }
00365 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00366 
00367 void
00368 CIMServer::enumNameSpace(StringResultHandlerIFC& result,
00369    OperationContext& context)
00370 {
00371    if (!m_authorizerMgr->allowEnumNameSpace(
00372       m_env, context))
00373    {
00374       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00375          "Enumeration of namespaces is not allowed");
00376    }
00377 
00378    // Don't need to check ACLs, since this is a result of calling enumInstances.
00379    logOperation(m_logger, context, "enumNameSpace", String());
00380    m_cimRepository->enumNameSpace(result,context);
00381 }
00383 CIMQualifierType
00384 CIMServer::getQualifierType(const String& ns,
00385    const String& qualifierName,
00386    OperationContext& context)
00387 {
00388    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00389 
00390    if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
00391    {
00392       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00393          Format("Read of qualifier %1 is not allowed",
00394             qualifierName).c_str());
00395    }
00396 
00397    logOperation(m_logger, context, "GetQualifier", ns, qualifierName);
00398    return m_cimRepository->getQualifierType(ns,qualifierName,context);
00399 }
00400 #ifndef OW_DISABLE_QUALIFIER_DECLARATION
00401 
00402 void
00403 CIMServer::enumQualifierTypes(
00404    const String& ns,
00405    CIMQualifierTypeResultHandlerIFC& result,
00406    OperationContext& context)
00407 {
00408    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00409 
00410    if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
00411    {
00412       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00413          "Enumeration of qualifiers is not allowed");
00414    }
00415 
00416    logOperation(m_logger, context, "EnumerateQualifiers", ns);
00417    m_cimRepository->enumQualifierTypes(ns,result,context);
00418 }
00420 void
00421 CIMServer::deleteQualifierType(const String& ns, const String& qualName,
00422    OperationContext& context)
00423 {
00424    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
00425 
00426    if (!m_authorizerMgr->allowWriteSchema(m_env, ns,
00427       Authorizer2IFC::E_DELETE, context))
00428    {
00429       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00430          Format("Deletion of qualifier %1 is not allowed",
00431             qualName).c_str());
00432    }
00433 
00434    logOperation(m_logger, context, "DeleteQualifier", ns, qualName);
00435    m_cimRepository->deleteQualifierType(ns,qualName,context);
00436 }
00438 void
00439 CIMServer::setQualifierType(
00440    const String& ns,
00441    const CIMQualifierType& qt, OperationContext& context)
00442 {
00443    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
00444 
00445    if (!m_authorizerMgr->allowWriteSchema(m_env, ns,
00446       Authorizer2IFC::E_MODIFY, context))
00447    {
00448       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00449          Format("Modification of qualifier %1 is not allowed",
00450             qt.getName()).c_str());
00451    }
00452 
00453    logOperation(m_logger, context, "SetQualifier", ns, qt.getName());
00454    m_cimRepository->setQualifierType(ns,qt,context);
00455 }
00456 #endif // #ifndef OW_DISABLE_QUALIFIER_DECLARATION
00457 
00458 CIMClass
00459 CIMServer::getClass(
00460    const String& ns, const String& className, ELocalOnlyFlag localOnly,
00461    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00462    const StringArray* propertyList, OperationContext& context)
00463 {
00464    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00465 
00466    if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
00467    {
00468       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00469          Format("Read of class %1 is not allowed", className).c_str());
00470    }
00471 
00472    logOperation(m_logger, context, "GetClass", ns, className);
00473    CIMClass theClass = _getNameSpaceClass(className);
00474    if (!theClass)
00475    {
00476       theClass = m_cimRepository->getClass(ns,className,localOnly,
00477          includeQualifiers,includeClassOrigin,propertyList,context);
00478    }
00479    return theClass;
00480 }
00482 CIMClass
00483 CIMServer::_instGetClass(const String& ns, const CIMName& className,
00484    ELocalOnlyFlag localOnly,
00485    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00486    const StringArray* propertyList, OperationContext& context)
00487 {
00488    CIMClass theClass = _getNameSpaceClass(className);
00489    if (!theClass)
00490    {
00491       try
00492       {
00493          theClass = m_cimRepository->getClass(ns,className.toString(),localOnly,
00494             includeQualifiers,includeClassOrigin,propertyList,context);
00495       }
00496       catch (CIMException& e)
00497       {
00498          if (e.getErrNo() == CIMException::NOT_FOUND)
00499          {
00500             e.setErrNo(CIMException::INVALID_CLASS);
00501          }
00502          throw e;
00503       }
00504    }
00505    return theClass;
00506 }
00507 #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00508 
00509 CIMClass
00510 CIMServer::deleteClass(const String& ns, const String& className,
00511    OperationContext& context)
00512 {
00513    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
00514 
00515    if (!m_authorizerMgr->allowWriteSchema(m_env, ns,
00516       Authorizer2IFC::E_DELETE, context))
00517    {
00518       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00519          Format("Deletion of class %1 is not allowed",
00520             className).c_str());
00521    }
00522 
00523    logOperation(m_logger, context, "DeleteClass", ns, className);
00524    return m_cimRepository->deleteClass(ns,className,context);
00525 }
00527 void
00528 CIMServer::createClass(const String& ns, const CIMClass& cimClass,
00529    OperationContext& context)
00530 {
00531    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
00532 
00533    if (!m_authorizerMgr->allowWriteSchema(m_env, ns,
00534       Authorizer2IFC::E_CREATE, context))
00535    {
00536       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00537          Format("Creation of class %1 is not allowed",
00538             cimClass.getName()).c_str());
00539    }
00540 
00541    logOperation(m_logger, context, "GetClass", ns, cimClass.getName());
00542    if (cimClass.getName().equalsIgnoreCase(DEPRECATED__NamespaceClassName))
00543    {
00544       OW_THROWCIMMSG(CIMException::ALREADY_EXISTS,
00545          Format("Creation of class %1 is not allowed",
00546             cimClass.getName()).c_str());
00547    }
00548    m_cimRepository->createClass(ns,cimClass,context);
00549 }
00551 CIMClass
00552 CIMServer::modifyClass(
00553    const String& ns,
00554    const CIMClass& cc,
00555    OperationContext& context)
00556 {
00557    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
00558 
00559    if (!m_authorizerMgr->allowWriteSchema(m_env, ns,
00560       Authorizer2IFC::E_MODIFY, context))
00561    {
00562       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00563          Format("Modification of class %1 is not allowed",
00564             cc.getName()).c_str());
00565    }
00566 
00567    logOperation(m_logger, context, "ModifyClass", ns, cc.getName());
00568    return m_cimRepository->modifyClass(ns,cc,context);
00569 }
00570 #endif // #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00571 
00572 void
00573 CIMServer::enumClasses(const String& ns,
00574       const String& className,
00575       CIMClassResultHandlerIFC& result,
00576       EDeepFlag deep, ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers,
00577       EIncludeClassOriginFlag includeClassOrigin, OperationContext& context)
00578 {
00579    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00580 
00581    if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
00582    {
00583       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00584          "Enumeration of classes is not allowed");
00585    }
00586 
00587    logOperation(m_logger, context, "EnumerateClasses", ns, className);
00588    m_cimRepository->enumClasses(ns,className,result,deep,localOnly,
00589       includeQualifiers,includeClassOrigin,context);
00590 }
00592 void
00593 CIMServer::enumClassNames(
00594    const String& ns,
00595    const String& className,
00596    StringResultHandlerIFC& result,
00597    EDeepFlag deep, OperationContext& context)
00598 {
00599    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00600 
00601    if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
00602    {
00603       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
00604          "Enumeration of class names is not allowed");
00605    }
00606 
00607    logOperation(m_logger, context, "EnumerateClassNames", ns, className);
00608    m_cimRepository->enumClassNames(ns,className,result,deep,context);
00609 }
00611 namespace
00612 {
00613    class InstNameEnumerator : public CIMClassResultHandlerIFC
00614    {
00615    public:
00616       InstNameEnumerator(
00617          const String& ns_,
00618          CIMObjectPathResultHandlerIFC& result_,
00619          OperationContext& context_,
00620          const ServiceEnvironmentIFCRef& env_,
00621          CIMServer* server_)
00622          : ns(ns_)
00623          , result(result_)
00624          , context(context_)
00625          , m_env(env_)
00626          , server(server_)
00627       {}
00628    protected:
00629       virtual void doHandle(const CIMClass &cc)
00630       {
00631          LoggerRef lgr(m_env->getLogger(COMPONENT_NAME));
00632          if (lgr->getLogLevel() == E_DEBUG_LEVEL)
00633          {
00634             OW_LOG_DEBUG(lgr, Format("CIMServer InstNameEnumerator enumerated derived instance names: %1:%2", ns,
00635                cc.getName()));
00636          }
00637          server->_getCIMInstanceNames(ns, cc.getName(), cc, result, context);
00638       }
00639    private:
00640       String ns;
00641       CIMObjectPathResultHandlerIFC& result;
00642       OperationContext& context;
00643       const ServiceEnvironmentIFCRef& m_env;
00644       CIMServer* server;
00645    };
00646 }
00648 void
00649 CIMServer::enumInstanceNames(
00650    const String& ns,
00651    const String& className,
00652    CIMObjectPathResultHandlerIFC& result,
00653    EDeepFlag deep,
00654    OperationContext& context)
00655 {
00656    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00657 
00658    logOperation(m_logger, context, "EnumerateInstanceNames", ns, className);
00659 
00660    InstNameEnumerator ie(ns, result, context, m_env, this);
00661    CIMClass theClass = _instGetClass(ns, className,E_NOT_LOCAL_ONLY,
00662       E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context);
00663    ie.handle(theClass);
00664    // If this is the namespace class then just return now
00665    if (className.equalsIgnoreCase(DEPRECATED__NamespaceClassName)
00666       || !deep)
00667    {
00668       return;
00669    }
00670    else
00671    {
00672       // TODO: measure whether it would be faster to use
00673       // enumClassNames + getClass() here.
00674       m_cimRepository->enumClasses(ns,className,ie,deep,E_NOT_LOCAL_ONLY,
00675          E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,context);
00676    }
00677 }
00679 // PRIVATE
00680 void
00681 CIMServer::_getCIMInstanceNames(const String& ns, const CIMName& className,
00682    const CIMClass& theClass, CIMObjectPathResultHandlerIFC& result,
00683    OperationContext& context)
00684 {
00685    InstanceProviderIFCRef instancep = _getInstanceProvider(ns, theClass, context);
00686    if (instancep)
00687    {
00688       instancep->enumInstanceNames(createProvEnvRef(context, m_env),
00689          ns, className.toString(), result, theClass);
00690    }
00691    else
00692    {
00693       m_cimRepository->enumInstanceNames(ns,className.toString(),result,E_SHALLOW,context);
00694    }
00695 }
00697 namespace
00698 {
00699    class InstEnumerator : public CIMClassResultHandlerIFC
00700    {
00701    public:
00702       InstEnumerator(
00703          const String& ns_,
00704          CIMInstanceResultHandlerIFC& result_,
00705          OperationContext& context_,
00706          const ServiceEnvironmentIFCRef& env_,
00707          CIMServer* server_,
00708          EDeepFlag deep_,
00709          ELocalOnlyFlag localOnly_,
00710          EIncludeQualifiersFlag includeQualifiers_,
00711          EIncludeClassOriginFlag includeClassOrigin_,
00712          const StringArray* propertyList_,
00713          const CIMClass& theTopClass_)
00714          : ns(ns_)
00715          , result(result_)
00716          , context(context_)
00717          , m_env(env_)
00718          , server(server_)
00719          , deep(deep_)
00720          , localOnly(localOnly_)
00721          , includeQualifiers(includeQualifiers_)
00722          , includeClassOrigin(includeClassOrigin_)
00723          , propertyList(propertyList_)
00724          , theTopClass(theTopClass_)
00725       {}
00726    protected:
00727       virtual void doHandle(const CIMClass &cc)
00728       {
00729          LoggerRef lgr(m_env->getLogger(COMPONENT_NAME));
00730          if (lgr->getLogLevel() == E_DEBUG_LEVEL)
00731          {
00732             OW_LOG_DEBUG(lgr, Format("CIMServer InstEnumerator Enumerating"
00733                " derived instance names: %1:%2", ns, cc.getName()));
00734          }
00735          server->_getCIMInstances(ns, cc.getName(), theTopClass, cc,
00736             result, localOnly, deep, includeQualifiers,
00737             includeClassOrigin, propertyList, context);
00738       }
00739    private:
00740       String ns;
00741       CIMInstanceResultHandlerIFC& result;
00742       OperationContext& context;
00743       const ServiceEnvironmentIFCRef& m_env;
00744       CIMServer* server;
00745       EDeepFlag deep;
00746       ELocalOnlyFlag localOnly;
00747       EIncludeQualifiersFlag includeQualifiers;
00748       EIncludeClassOriginFlag includeClassOrigin;
00749       const StringArray* propertyList;
00750       const CIMClass& theTopClass;
00751    };
00752 }
00753 
00755 void
00756 CIMServer::enumInstances(
00757    const String& ns,
00758    const String& className,
00759    CIMInstanceResultHandlerIFC& result, EDeepFlag deep,
00760    ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00761    const StringArray* propertyList, EEnumSubclassesFlag enumSubclasses,
00762    OperationContext& context)
00763 {
00764    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
00765 
00766    logOperation(m_logger, context, "EnumerateInstances", ns, className);
00767 
00768    CIMClass theTopClass = _instGetClass(ns, className, E_NOT_LOCAL_ONLY,
00769       E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, 0, context);
00770 
00771    InstEnumerator ie(ns, result, context, m_env, this, deep, localOnly,
00772       includeQualifiers, includeClassOrigin, propertyList, theTopClass);
00773    ie.handle(theTopClass);
00774    // If this is the namespace class then only do one class
00775    if (theTopClass.getName().equalsIgnoreCase(DEPRECATED__NamespaceClassName)
00776       || enumSubclasses == E_DONT_ENUM_SUBCLASSES)
00777    {
00778       return;
00779    }
00780    else
00781    {
00782       // TODO: measure whether it would be faster to use
00783       // enumClassNames + getClass() here.
00784       // do subclasses
00785       m_cimRepository->enumClasses(ns, className, ie, E_DEEP,
00786          E_NOT_LOCAL_ONLY, E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN,
00787          context);
00788    }
00789 }
00790 
00791 namespace
00792 {
00793    /* not going to use this -- the providers are now responsible for their own behavior
00794    class HandleProviderInstance : public CIMInstanceResultHandlerIFC
00795    {
00796    public:
00797       HandleProviderInstance(
00798          bool includeQualifiers_, bool includeClassOrigin_,
00799          const StringArray* propList_,
00800          CIMInstanceResultHandlerIFC& result_)
00801       : includeQualifiers(includeQualifiers_)
00802       , includeClassOrigin(includeClassOrigin_)
00803       , propList(propList_)
00804       , result(result_)
00805       {}
00806    protected:
00807       virtual void doHandle(const CIMInstance &ci)
00808       {
00809          result.handle(ci.clone(false, includeQualifiers,
00810             includeClassOrigin, propList));
00811       }
00812    private:
00813       bool includeQualifiers, includeClassOrigin;
00814       const StringArray* propList;
00815       CIMInstanceResultHandlerIFC& result;
00816    };
00817    */
00818    class HandleLocalOnlyAndDeep : public CIMInstanceResultHandlerIFC
00819    {
00820    public:
00821       HandleLocalOnlyAndDeep(
00822          CIMInstanceResultHandlerIFC& result_,
00823          const CIMClass& requestedClass_,
00824          bool localOnly_,
00825          bool deep_)
00826       : result(result_)
00827       , requestedClass(requestedClass_)
00828       , localOnly(localOnly_)
00829       , deep(deep_)
00830       {
00831       }
00832 
00833    protected:
00834       virtual void doHandle(const CIMInstance &inst)
00835       {
00836          if (deep == true && localOnly == false) // don't filter anything
00837          {
00838             result.handle(inst);
00839             return;
00840          }
00841 
00842          CIMPropertyArray props = inst.getProperties();
00843          CIMPropertyArray newprops;
00844          CIMInstance newInst(inst);
00845          CIMName requestedClassName = requestedClass.getName();
00846          for (size_t i = 0; i < props.size(); ++i)
00847          {
00848             CIMProperty p = props[i];
00849             CIMProperty clsp = requestedClass.getProperty(p.getName());
00850             if (clsp)
00851             {
00852                if (clsp.getOriginClass() == requestedClassName)
00853                {
00854                   newprops.push_back(p);
00855                   continue;
00856                }
00857             }
00858             if (deep == true)
00859             {
00860                if (!clsp
00861                   || !p.getOriginClass().equalsIgnoreCase(clsp.getOriginClass()))
00862                {
00863                   // the property is from a derived class
00864                   newprops.push_back(p);
00865                   continue;
00866                }
00867             }
00868             if (localOnly == false)
00869             {
00870                if (clsp)
00871                {
00872                   // the property has to be from a superclass
00873                   newprops.push_back(p);
00874                   continue;
00875                }
00876             }
00877          }
00878          newInst.setProperties(newprops);
00879          newInst.setKeys(inst.getKeyValuePairs());
00880          result.handle(newInst);
00881       }
00882    private:
00883       CIMInstanceResultHandlerIFC& result;
00884       const CIMClass& requestedClass;
00885       bool localOnly;
00886       bool deep;
00887    };
00888 
00889    class SecondaryInstanceProviderHandler : public CIMInstanceResultHandlerIFC
00890    {
00891    public:
00892       SecondaryInstanceProviderHandler(
00893          OperationContext& context_,
00894          const ServiceEnvironmentIFCRef& env_,
00895          const String& ns_,
00896          const CIMName& className_,
00897          ELocalOnlyFlag localOnly_,
00898          EDeepFlag deep_,
00899          EIncludeQualifiersFlag includeQualifiers_,
00900          EIncludeClassOriginFlag includeClassOrigin_,
00901          const StringArray* propertyList_,
00902          const CIMClass& theTopClass_,
00903          const CIMClass& theClass_,
00904          const SecondaryInstanceProviderIFCRefArray& secProvs_,
00905          CIMInstanceResultHandlerIFC& result_)
00906       : context(context_)
00907       , env(env_)
00908       , ns(ns_)
00909       , className(className_)
00910       , localOnly(localOnly_)
00911       , deep(deep_)
00912       , includeQualifiers(includeQualifiers_)
00913       , includeClassOrigin(includeClassOrigin_)
00914       , propertyList(propertyList_)
00915       , theTopClass(theTopClass_)
00916       , theClass(theClass_)
00917       , secProvs(secProvs_)
00918       , result(result_)
00919       {
00920       }
00921       void doHandle(const CIMInstance& i)
00922       {
00923          CIMInstanceArray savedInstances;
00924          savedInstances.push_back(i);
00925          // now let all the secondary providers have at the instance
00926          for (size_t i = 0; i < secProvs.size(); ++i)
00927          {
00928             secProvs[i]->filterInstances(createProvEnvRef(context, env), ns,
00929                className.toString(), savedInstances, localOnly, deep, includeQualifiers,
00930                includeClassOrigin, propertyList, theTopClass, theClass );
00931          }
00932          for (size_t i = 0; i < savedInstances.size(); ++i)
00933          {
00934             result.handle(savedInstances[i]);
00935          }
00936       }
00937    private:
00938       OperationContext& context;
00939       const ServiceEnvironmentIFCRef& env;
00940       const String& ns;
00941       const CIMName& className;
00942       ELocalOnlyFlag localOnly;
00943       EDeepFlag deep;
00944       EIncludeQualifiersFlag includeQualifiers;
00945       EIncludeClassOriginFlag includeClassOrigin;
00946       const StringArray* propertyList;
00947       const CIMClass& theTopClass;
00948       const CIMClass& theClass;
00949       const SecondaryInstanceProviderIFCRefArray& secProvs;
00950       CIMInstanceResultHandlerIFC& result;
00951    };
00952 
00953 }
00955 void
00956 CIMServer::_getCIMInstances(
00957    const String& ns,
00958    const CIMName& className,
00959    const CIMClass& theTopClass,
00960    const CIMClass& theClass, CIMInstanceResultHandlerIFC& result,
00961    ELocalOnlyFlag localOnly, EDeepFlag deep, EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00962    const StringArray* propertyList, OperationContext& context)
00963 {
00964    InstanceProviderIFCRef instancep(_getInstanceProvider(ns, theClass, context));
00965 
00966    // See if the authorizer allows reading of these instances and give it
00967    // an opportunity to modify the property list
00968    StringArray authorizedPropertyList;
00969    if (!m_authorizerMgr->allowReadInstance(m_env, ns, className.toString(),
00970       propertyList, authorizedPropertyList, context))
00971    {
00972       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize reading of %1"
00973          " instances from namespace %2", className, ns));
00974       return;
00975    }
00976 
00977    // If the authorizer modified the property list, then set the
00978    // property list parm to point to it.
00979    if (authorizedPropertyList.size() > 0)
00980    {
00981       propertyList = &authorizedPropertyList;
00982       OW_LOG_DEBUG(m_logger, Format("Authorizer modified property list for reading"
00983          " of %1 instances from namespace %2", className, ns));
00984    }
00985 
00986    // If we have secondary instance providers, we need to use a new result
00987    // handler so we can pass instances to the seconday instance providers.
00988    // Otherwise, we want to just pass them on to result.  presult will point
00989    // to either result or a SecondaryInstanceProviderHandler.
00990    SecondaryInstanceProviderIFCRefArray secProvs =
00991       _getSecondaryInstanceProviders(ns, className, context);
00992 
00993    SecondaryInstanceProviderHandler secondaryHandler(context, m_env, ns,
00994       className, localOnly, deep, includeQualifiers, includeClassOrigin,
00995       propertyList, theTopClass, theClass, secProvs, result);
00996 
00997    CIMInstanceResultHandlerIFC* presult = &result;
00998    if (!secProvs.empty())
00999    {
01000       presult = &secondaryHandler;
01001    }
01002 
01003    if (instancep)
01004    {
01005       if (m_logger->getLogLevel() == E_DEBUG_LEVEL)
01006       {
01007          OW_LOG_DEBUG(m_logger, Format("CIMServer calling provider to"
01008             " enumerate instances: %1:%2", ns, className));
01009       }
01010 
01011       // not going to use these, the provider ifc/providers are now
01012       // responsible for it.
01013       //HandleLocalOnlyAndDeep handler1(result,theTopClass,localOnly,deep);
01014       //HandleProviderInstance handler2(includeQualifiers, includeClassOrigin, propertyList, handler1);
01015       instancep->enumInstances(
01016          createProvEnvRef(context, m_env), ns, className.toString(), *presult,
01017          localOnly, deep, includeQualifiers, includeClassOrigin,
01018          propertyList, theTopClass, theClass);
01019    }
01020    else
01021    {
01022       HandleLocalOnlyAndDeep handler(*presult, theTopClass, localOnly, deep);
01023       // don't pass along deep and localOnly flags, because the handler has
01024       // to take care of it.  m_cimRepository can't do it right, because we
01025       // can't pass in theTopClass.
01026       m_cimRepository->enumInstances(ns, className.toString(), handler, E_DEEP,
01027          E_NOT_LOCAL_ONLY, includeQualifiers, includeClassOrigin,
01028          propertyList, E_DONT_ENUM_SUBCLASSES, context);
01029    }
01030 }
01032 CIMInstance
01033 CIMServer::getInstance(
01034    const String& ns,
01035    const CIMObjectPath& instanceName,
01036    ELocalOnlyFlag localOnly,
01037    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
01038    const StringArray* propertyList, OperationContext& context)
01039 {
01040    return getInstance(ns, instanceName, localOnly, includeQualifiers, includeClassOrigin,
01041       propertyList, NULL, context);
01042 }
01044 CIMInstance
01045 CIMServer::getInstance(
01046    const String& ns,
01047    const CIMObjectPath& instanceName_,
01048    ELocalOnlyFlag localOnly,
01049    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
01050    const StringArray* propertyList, CIMClass* pOutClass,
01051    OperationContext& context)
01052 {
01053    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01054    logOperation(m_logger, context, "GetInstance", ns, instanceName_.toString());
01055 
01056    CIMObjectPath instanceName(instanceName_);
01057    CIMName className = instanceName.getClassName();
01058    CIMClass cc = _instGetClass(ns, className,
01059       E_NOT_LOCAL_ONLY,
01060       E_INCLUDE_QUALIFIERS,
01061       E_INCLUDE_CLASS_ORIGIN,
01062       0, context);
01063    if (pOutClass)
01064    {
01065       *pOutClass = cc;
01066    }
01067    instanceName.syncWithClass(cc);
01068    InstanceProviderIFCRef instancep = _getInstanceProvider(ns, cc, context);
01069 
01070    // See if the authorizer allows reading of these instances and give it
01071    // an opportunity to modify the property list
01072    StringArray authorizedPropertyList;
01073    if (!m_authorizerMgr->allowReadInstance(m_env, ns, className.toString(), propertyList,
01074       authorizedPropertyList, context))
01075    {
01076       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize reading of %1"
01077          " instances from namespace %2", className, ns));
01078 
01079       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01080          Format("You are not authorized to read %1 instances from"
01081             " namespace %2", className, ns).c_str());
01082    }
01083 
01084    // If the authorizer changed the property list, then use it.
01085    if (authorizedPropertyList.size() > 0)
01086    {
01087       propertyList = &authorizedPropertyList;
01088    }
01089 
01090    CIMInstance ci(CIMNULL);
01091    if (instancep)
01092    {
01093       ci = instancep->getInstance(createProvEnvRef(context, m_env), ns,
01094          instanceName, localOnly, includeQualifiers, includeClassOrigin,
01095          propertyList, cc);
01096       if (!ci)
01097       {
01098          OW_THROWCIMMSG(CIMException::FAILED,
01099             "Provider erroneously returned a NULL CIMInstance");
01100       }
01101       /* don't do this, it's up to the provider ifc/provider to do this correctly.
01102       ci.syncWithClass(cc, true);
01103       ci = ci.clone(localOnly, includeQualifiers, includeClassOrigin,
01104          propertyList);
01105          */
01106    }
01107    else
01108    {
01109       ci = m_cimRepository->getInstance(ns, instanceName, localOnly,
01110          includeQualifiers, includeClassOrigin, propertyList, context);
01111    }
01112    OW_ASSERT(ci);
01113    
01114    SecondaryInstanceProviderIFCRefArray secProvs = _getSecondaryInstanceProviders(ns, className, context);
01115    if (!secProvs.empty())
01116    {
01117       CIMInstanceArray cia; cia.push_back(ci);
01118       // now let all the secondary providers have at the instance
01119       for (size_t i = 0; i < secProvs.size(); ++i)
01120       {
01121          secProvs[i]->filterInstances(createProvEnvRef(context, m_env), ns,
01122             className.toString(), cia, localOnly, E_DEEP, includeQualifiers,
01123             includeClassOrigin, propertyList, cc, cc );
01124       }
01125       OW_ASSERT(cia.size() == 1); // providers shouldn't add/remove from the array.
01126       ci = cia[0];
01127    }
01128    
01129    return ci;
01130 }
01131 
01132 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
01133 
01134 CIMInstance
01135 CIMServer::deleteInstance(const String& ns, const CIMObjectPath& cop_,
01136    OperationContext& context)
01137 {
01138    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
01139    logOperation(m_logger, context, "DeleteInstance", ns, cop_.toString());
01140 
01141    CIMObjectPath cop(cop_);
01142    cop.setNameSpace(ns);
01143    if (m_logger->getLogLevel() == E_DEBUG_LEVEL)
01144    {
01145       OW_LOG_DEBUG(m_logger, Format("CIMServer::deleteInstance.  cop = %1",
01146          cop.toString()));
01147    }
01148 
01149    AuthorizerEnabler ae(m_authorizerMgr, context, true);
01150    CIMClass theClass(CIMNULL);
01151    CIMInstance oldInst = getInstance(ns, cop, E_NOT_LOCAL_ONLY,
01152       E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, NULL, &theClass, context);
01153    cop.syncWithClass(theClass);
01154 
01155    InstanceProviderIFCRef instancep = _getInstanceProvider(ns, theClass,
01156       context);
01157    m_authorizerMgr->turnOn(context);
01158 
01159 #ifndef OW_DISABLE_NAMESPACE_MANIPULATION
01160    // TODO: This is broken!!!  Not only is __Namespace deprecated, but requests for CIM_Namespace won't be checked!
01161    if (theClass.getName().equalsIgnoreCase(DEPRECATED__NamespaceClassName))
01162    {
01163       if (!m_authorizerMgr->allowDeleteNameSpace(m_env, ns, context))
01164       {
01165          OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01166             Format("You are not authorized to delete namespace %1",
01167                ns).c_str());
01168       }
01169    }
01170 #endif
01171 
01172    // Allow authorizer a chance to determine if the deletion is allowed
01173    if (!m_authorizerMgr->allowWriteInstance(m_env, ns, cop,
01174       (instancep) ? Authorizer2IFC::E_DYNAMIC : Authorizer2IFC::E_NOT_DYNAMIC,
01175       Authorizer2IFC::E_DELETE, context))
01176    {
01177       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize deletion of %1"
01178          " instances from namespace %2", theClass.getName(), ns));
01179 
01180       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01181          Format("You are not authorized to delete %1 instances from"
01182             " namespace %2", theClass.getName(), ns).c_str());
01183    }
01184 
01185    m_authorizerMgr->turnOff(context);
01186 
01187    if (instancep) // If there is an instance provider, let it do the delete.
01188    {
01189       instancep->deleteInstance(createProvEnvRef(context, m_env), ns, cop);
01190    }
01191    else
01192    {
01193       // Delete the instance from the instance repository
01194       m_cimRepository->deleteInstance(ns, cop, context);
01195    }
01196    OW_ASSERT(oldInst);
01197    
01198    SecondaryInstanceProviderIFCRefArray secProvs = _getSecondaryInstanceProviders(ns, cop.getClassName(), context);
01199    // now let all the secondary providers know about the delete
01200    for (size_t i = 0; i < secProvs.size(); ++i)
01201    {
01202       secProvs[i]->deleteInstance(createProvEnvRef(context, m_env), ns, cop);
01203    }
01204    
01205    return oldInst;
01206 }
01208 CIMObjectPath
01209 CIMServer::createInstance(
01210    const String& ns,
01211    const CIMInstance& ci,
01212    OperationContext& context)
01213 {
01214    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
01215    CIMName className = ci.getClassName();
01216    logOperation(m_logger, context, "CreateInstance", ns, className.toString());
01217 
01218    CIMClass theClass = _instGetClass(ns, className, E_NOT_LOCAL_ONLY,
01219       E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, 0,
01220       context);
01221    CIMQualifier acq = theClass.getQualifier(
01222          CIMQualifier::CIM_QUAL_ABSTRACT);
01223    if (acq)
01224    {
01225       if (acq.getValue() == CIMValue(true))
01226       {
01227          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
01228                Format("Unable to create instance because class (%1)"
01229                   " is abstract", theClass.getName()).c_str());
01230       }
01231    }
01232    // Make sure instance jives with class definition
01233    CIMInstance lci(ci);
01234    lci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS);
01235    if (m_logger->getLogLevel() == E_DEBUG_LEVEL)
01236    {
01237       OW_LOG_DEBUG(m_logger, Format("CIMServer::createInstance.  ns = %1, "
01238          "instance = %2", ns, lci.toMOF()));
01239    }
01240    CIMObjectPath rval(CIMNULL);
01241    InstanceProviderIFCRef instancep = _getInstanceProvider(ns, theClass, context);
01242 
01243    // Allow authorizer a chance to determine if the creation is allowed
01244    CIMObjectPath cop(ns, lci);
01245 
01246 #ifndef OW_DISABLE_NAMESPACE_MANIPULATION
01247    // TODO: This is broken!!!  Not only is __Namespace deprecated, but requests for CIM_Namespace won't be checked!
01248    if (theClass.getName().equalsIgnoreCase(DEPRECATED__NamespaceClassName))
01249    {
01250       if (!m_authorizerMgr->allowCreateNameSpace(m_env, ns, context))
01251       {
01252          OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01253             Format("You are not authorized to create namespace %1",
01254                ns).c_str());
01255       }
01256    }
01257 #endif
01258    if (!m_authorizerMgr->allowWriteInstance(m_env, ns, cop,
01259       (instancep) ? Authorizer2IFC::E_DYNAMIC : Authorizer2IFC::E_NOT_DYNAMIC,
01260       Authorizer2IFC::E_CREATE, context))
01261    {
01262       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize creation of %1"
01263          " instances  in namespace %2", lci.getClassName(), ns));
01264 
01265       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01266          Format("You are not authorized to create %1 instances in"
01267             " namespace %2", lci.getClassName(), ns).c_str());
01268    }
01269 
01270    if (instancep)
01271    {
01272       rval = instancep->createInstance(createProvEnvRef(context, m_env),
01273          ns, lci);
01274    }
01275    else
01276    {
01277       rval = m_cimRepository->createInstance(ns, lci, context);
01278    }
01279 
01280    SecondaryInstanceProviderIFCRefArray secProvs = _getSecondaryInstanceProviders(ns, className, context);
01281    // now let all the secondary providers know about the create
01282    for (size_t i = 0; i < secProvs.size(); ++i)
01283    {
01284       secProvs[i]->createInstance(createProvEnvRef(context, m_env), ns, lci);
01285    }
01286 
01287    // Prevent lazy providers from causing a problem.
01288    if (!rval)
01289    {
01290       rval = CIMObjectPath(ns, lci);
01291    }
01292    return rval;
01293 }
01295 CIMInstance
01296 CIMServer::modifyInstance(
01297    const String& ns,
01298    const CIMInstance& modifiedInstance,
01299    EIncludeQualifiersFlag includeQualifiers,
01300    const StringArray* propertyList,
01301    OperationContext& context)
01302 {
01303    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
01304 
01305    CIMInstance oldInst(CIMNULL);
01306    CIMClass theClass = _instGetClass(ns, modifiedInstance.getClassName(),
01307       E_NOT_LOCAL_ONLY, E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, 0, context);
01308    InstanceProviderIFCRef instancep(_getInstanceProvider(ns, theClass, context));
01309 
01310    // Make sure instance jives with class definition
01311    CIMInstance lci(modifiedInstance);
01312    lci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS);
01313 
01314    CIMObjectPath cop(ns, lci);
01315 
01316    // syncWithClass() adds back in all the default properties that were't set on lci.
01317    // If the client specified a propertyList, we need to remove any other properties from
01318    // the instance, so providers don't have to worry about making sure properties
01319    // are in the propertyList
01320    if (propertyList)
01321    {
01322       CIMPropertyArray keys(lci.getKeyValuePairs());
01323       CIMPropertyArray newProps;
01324       for (size_t i = 0; i < propertyList->size(); ++i)
01325       {
01326          newProps.push_back(lci.getPropertyT((*propertyList)[i]));
01327       }
01328       lci.setProperties(newProps); // this will rebuild the keys, which may get lost if they're not in the propertyList
01329       lci.setKeys(keys);
01330    }
01331 
01332    // Allow authorizer a chance to determine if the mofify is allowed
01333    if (!m_authorizerMgr->allowWriteInstance(m_env, ns, cop,
01334       (instancep) ? Authorizer2IFC::E_DYNAMIC : Authorizer2IFC::E_NOT_DYNAMIC,
01335       Authorizer2IFC::E_MODIFY, context))
01336    {
01337       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize modification of %1"
01338          " instances in namespace %2", lci.getClassName(), ns));
01339 
01340       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01341          Format("You are not authorized to modify %1 instances in"
01342             " namespace %2", lci.getClassName(), ns).c_str());
01343    }
01344 
01345    logOperation(m_logger, context, "ModifyInstance", ns, modifiedInstance.getClassName());
01346    ELogLevel lvl = m_logger->getLogLevel();
01347    if (lvl == E_DEBUG_LEVEL || lvl == E_INFO_LEVEL)
01348    {
01349       OW_LOG_INFO(m_logger, Format("ModifyInstance: modified instance = %1", lci));
01350       if (propertyList && !propertyList->empty())
01351       {
01352          OStringStream ss;
01353          ss << "PropertyList: ";
01354          std::copy(propertyList->begin(), propertyList->end(), std::ostream_iterator<String>(ss, " "));
01355          OW_LOG_INFO(m_logger, ss.releaseString());
01356       }
01357    }
01358 
01359    if (!instancep)
01360    {
01361       // No instance provider qualifier found
01362       oldInst = m_cimRepository->modifyInstance(ns, lci,
01363          includeQualifiers, propertyList, context);
01364    }
01365    else
01366    {
01367       // Look for dynamic instances
01368       oldInst = getInstance(ns, cop, E_NOT_LOCAL_ONLY, E_INCLUDE_QUALIFIERS,
01369          E_INCLUDE_CLASS_ORIGIN, NULL, NULL, context);
01370 
01371       if (lvl == E_DEBUG_LEVEL || lvl == E_INFO_LEVEL)
01372       {
01373          OW_LOG_INFO(m_logger, Format("ModifyInstance: previous instance = %1", oldInst));
01374       }
01375 
01376       instancep->modifyInstance(createProvEnvRef(context, m_env), ns,
01377          lci, oldInst, includeQualifiers, propertyList, theClass);
01378    }
01379    OW_ASSERT(oldInst);
01380    
01381    SecondaryInstanceProviderIFCRefArray secProvs = _getSecondaryInstanceProviders(ns, modifiedInstance.getClassName(), context);
01382    // now let all the secondary providers know about the modify
01383    for (size_t i = 0; i < secProvs.size(); ++i)
01384    {
01385       secProvs[i]->modifyInstance(createProvEnvRef(context, m_env), ns, lci,
01386          oldInst, includeQualifiers, propertyList, theClass);
01387    }
01388 
01389    return oldInst;
01390 }
01391 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
01392 
01393 bool
01394 CIMServer::_instanceExists(const String& ns, const CIMObjectPath& icop,
01395    OperationContext& context)
01396 {
01397    try
01398    {
01399       getInstance(ns,icop,E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,0,context);
01400       return true;
01401    }
01402    catch(CIMException&)
01403    {
01404       return false;
01405    }
01406 }
01407 #if !defined(OW_DISABLE_PROPERTY_OPERATIONS)
01408 
01409 CIMValue
01410 CIMServer::getProperty(
01411    const String& ns,
01412    const CIMObjectPath& name,
01413    const String& propertyName, OperationContext& context)
01414 {
01415    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01416 
01417    logOperation(m_logger, context, "GetProperty", ns, name.toString() + '.' + propertyName);
01418 
01419    CIMClass theClass = _instGetClass(ns,name.getClassName(),E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context);
01420 
01421    CIMProperty cp = theClass.getProperty(propertyName);
01422    if (!cp)
01423    {
01424       OW_THROWCIMMSG(CIMException::NO_SUCH_PROPERTY,
01425          propertyName.c_str());
01426    }
01427    CIMInstance ci = getInstance(ns, name, E_NOT_LOCAL_ONLY,
01428       E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, NULL, NULL, context);
01429    CIMProperty prop = ci.getProperty(propertyName);
01430    if (!prop)
01431    {
01432       OW_THROWCIMMSG(CIMException::NO_SUCH_PROPERTY,
01433          propertyName.c_str());
01434    }
01435    return prop.getValue();
01436 }
01437 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
01438 
01439 void
01440 CIMServer::setProperty(
01441    const String& ns,
01442    const CIMObjectPath& name,
01443    const String& propertyName, const CIMValue& valueArg,
01444    OperationContext& context)
01445 {
01446    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_WRITE);
01447    AuthorizerEnabler ae(m_authorizerMgr, context, true);
01448 
01449    logOperation(m_logger, context, "SetProperty", ns, name.toString());
01450    OW_LOG_INFO(m_logger, Format("SetProperty: %1=%2", propertyName, valueArg));
01451 
01452    CIMClass theClass = _instGetClass(ns, name.getClassName(),E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context);
01453 
01454    CIMProperty cp = theClass.getProperty(propertyName);
01455    if (!cp)
01456    {
01457       OW_THROWCIMMSG(CIMException::NO_SUCH_PROPERTY,
01458          propertyName.c_str());
01459    }
01460    // Ensure value passed in is right data type
01461    CIMValue cv(valueArg);
01462    if (cv && (cp.getDataType().getType() != cv.getType()))
01463    {
01464       try
01465       {
01466          // workaround for the stupid dmtf string/embedded object hack
01467          if (cv.getType() != CIMDataType::EMBEDDEDCLASS && cv.getType() != CIMDataType::EMBEDDEDINSTANCE)
01468          {
01469             // this throws a FAILED CIMException if it can't convert
01470             cv = CIMValueCast::castValueToDataType(cv, cp.getDataType());
01471          }
01472       }
01473       catch (CIMException& ce)
01474       {
01475          // translate FAILED to TYPE_MISMATCH
01476          if (ce.getErrNo() == CIMException::FAILED)
01477          {
01478             ce.setErrNo(CIMException::TYPE_MISMATCH);
01479          }
01480          throw ce;
01481       }
01482    }
01483    CIMInstance ci = getInstance(ns, name, E_NOT_LOCAL_ONLY,
01484       E_INCLUDE_QUALIFIERS, E_INCLUDE_CLASS_ORIGIN, NULL, NULL, context);
01485    if (!ci)
01486    {
01487       OW_THROWCIMMSG(CIMException::NOT_FOUND, name.toString().c_str());
01488    }
01489    CIMProperty tcp = ci.getProperty(propertyName);
01490    if (cp.isKey() && tcp.getValue() && !tcp.getValue().equal(cv))
01491    {
01492       String msg("Cannot modify key property: ");
01493       msg += cp.getName();
01494       OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
01495    }
01496    
01497    OW_LOG_INFO(m_logger, Format("SetProperty previous value was: %1", cp.getValue()));
01498 
01499    cp.setValue(cv);
01500    ci.setProperty(cp);
01501    StringArray propertyList;
01502    propertyList.push_back(propertyName);
01503    m_authorizerMgr->turnOn(context);
01504    modifyInstance(ns, ci, E_INCLUDE_QUALIFIERS, &propertyList, context);
01505 }
01506 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
01507 #endif //#if !defined(OW_DISABLE_PROPERTY_OPERATIONS)
01508 
01510 CIMValue
01511 CIMServer::invokeMethod(
01512    const String& ns,
01513    const CIMObjectPath& path_,
01514    const String& methodName, const CIMParamValueArray& inParams,
01515    CIMParamValueArray& outParams, OperationContext& context)
01516 {
01517    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READWRITE);
01518 
01519    logOperation(m_logger, context, "invokeMethod", ns, path_.toString() + '.' + methodName);
01520 
01521    // Allow authorizer a chance to determine if the mofify is allowed
01522    if (!m_authorizerMgr->allowMethodInvocation(m_env, ns, path_, methodName,
01523       context))
01524    {
01525       OW_LOG_DEBUG(m_logger, Format("Authorizer did NOT authorize invocation of"
01526          " method %1 on object path %2", methodName, path_.toString()));
01527 
01528       OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
01529          Format("You are not authorized to invoke method %1 on object %2",
01530             methodName, path_.toString()).c_str());
01531    }
01532 
01533    CIMObjectPath path(path_);
01534    CIMClass cc = getClass(ns, path.getClassName(),E_NOT_LOCAL_ONLY,
01535       E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context);
01536    path.syncWithClass(cc);
01537    CIMPropertyArray keys = path.getKeys();
01538    // If this is an instance, ensure it exists.
01539    if (keys.size() > 0)
01540    {
01541       if (!_instanceExists(ns, path, context))
01542       {
01543          OW_THROWCIMMSG(CIMException::NOT_FOUND,
01544             Format("Instance not found: %1", path.toString()).c_str());
01545       }
01546    }
01547    // Get the method from the class definition
01548    CIMMethod method = cc.getMethod(methodName);
01549    if (!method)
01550    {
01551       OW_THROWCIMMSG(CIMException::METHOD_NOT_FOUND, methodName.c_str());
01552    }
01553    CIMValue cv(CIMNULL);
01554    MethodProviderIFCRef methodp;
01555    CIMClass cctemp(cc);
01556    try
01557    {
01558       methodp = m_provManager->getMethodProvider(
01559          createProvEnvRef(context, m_env), ns, cctemp, method);
01560    }
01561    catch (const NoSuchProviderException&)
01562    {
01563    }
01564    if (!methodp)
01565    {
01566       OW_THROWCIMMSG(CIMException::NOT_FOUND,
01567          Format("No provider for method %1", methodName).c_str());
01568    }
01569    CIMParameterArray methodInParams = method.getINParameters();
01570    CIMParameterArray methodOutParams = method.getOUTParameters();
01571 
01572    outParams.resize(methodOutParams.size());
01573    // set the names on outParams
01574    for (size_t i = 0; i < methodOutParams.size(); ++i)
01575    {
01576       outParams[i].setName(methodOutParams[i].getName());
01577    }
01578    CIMParamValueArray orderedParams;
01579    CIMParamValueArray inParams2(inParams);
01580    for (size_t i = 0; i < methodInParams.size(); ++i)
01581    {
01582       CIMName parameterName = methodInParams[i].getName();
01583       size_t paramIdx;
01584       for (paramIdx = 0; paramIdx < inParams2.size(); ++paramIdx)
01585       {
01586          if (inParams2[paramIdx].getName() == parameterName)
01587          {
01588             break;
01589          }
01590       }
01591       if (paramIdx == inParams2.size())
01592       {
01593          // The parameter wasn't specified.
01594          // Parameters are optional unless they have a Required(true)
01595          // qualifier
01596          if (methodInParams[i].hasTrueQualifier(CIMQualifier::CIM_QUAL_REQUIRED))
01597          {
01598             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, Format(
01599                "Parameter %1 was not specified.", parameterName).c_str());
01600          }
01601          else
01602          {
01603             // put a param with a null value
01604             CIMParamValue optionalParam(methodInParams[i].getName());
01605             inParams2.push_back(optionalParam);
01606          }
01607       }
01608       // move the param from inParams2 to orderedParams
01609       orderedParams.push_back(inParams2[paramIdx]);
01610       inParams2.erase(inParams2.begin() + paramIdx);
01611       // make sure the type is right
01612       CIMValue v = orderedParams[i].getValue();
01613       if (v)
01614       {
01615          if (methodInParams[i].getType().getType() != v.getType())
01616          {
01617             try
01618             {
01619                // workaround for the stupid dmtf string/embedded object hack
01620                if (v.getType() != CIMDataType::EMBEDDEDCLASS && v.getType() != CIMDataType::EMBEDDEDINSTANCE)
01621                {
01622                   orderedParams[i].setValue(CIMValueCast::castValueToDataType(
01623                      v, methodInParams[i].getType()));
01624                }
01625             }
01626             catch (CIMException& ce)
01627             {
01628                ce.setErrNo(CIMException::INVALID_PARAMETER);
01629                throw;
01630             }
01631          }
01632       }
01633       // if the in param is also an out param, assign the value to the out
01634       // params array
01635       if (methodInParams[i].hasTrueQualifier(CIMQualifier::CIM_QUAL_OUT))
01636       {
01637          size_t j;
01638          for (j = 0; j < outParams.size(); ++j)
01639          {
01640             if (outParams[j].getName() == parameterName)
01641             {
01642                outParams[j].setValue(orderedParams[i].getValue());
01643                break;
01644             }
01645          }
01646          if (j == outParams.size())
01647          {
01648             OW_ASSERT(0);
01649          }
01650       }
01651    }
01652    // all the params should have been moved to orderedParams.  If there are
01653    // some left, it means we have an unknown/invalid parameter.
01654    if (inParams2.size() > 0)
01655    {
01656       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, Format(
01657          "Unknown or duplicate parameter: %1", inParams2[0].getName()).c_str());
01658    }
01659    StringBuffer methodStr;
01660    if (m_logger->getLogLevel() == E_DEBUG_LEVEL)
01661    {
01662       methodStr += "CIMServer invoking extrinsic method provider: ";
01663       methodStr += ns;
01664       methodStr += ':';
01665       methodStr += path.toString();
01666       methodStr += '.';
01667       methodStr += methodName;
01668       methodStr += '(';
01669       for (size_t i = 0; i < orderedParams.size(); ++i)
01670       {
01671          methodStr += orderedParams[i].getName();
01672          methodStr += '=';
01673          methodStr += orderedParams[i].getValue().toString();
01674          if (i != orderedParams.size() - 1)
01675          {
01676             methodStr += ", ";
01677          }
01678       }
01679       methodStr += ')';
01680       OW_LOG_DEBUG(m_logger, methodStr.toString());
01681    }
01682    cv = methodp->invokeMethod(
01683       createProvEnvRef(context, m_env),
01684          ns, path, methodName, orderedParams, outParams);
01685    
01686    // make sure the type is right on the outParams
01687    for (size_t i = 0; i < methodOutParams.size(); ++i)
01688    {
01689       CIMValue v = outParams[i].getValue();
01690       if (v)
01691       {
01692          if (methodOutParams[i].getType().getType() != v.getType())
01693          {
01694             // workaround for the stupid dmtf string/embedded object hack
01695             if (v.getType() != CIMDataType::EMBEDDEDCLASS && v.getType() != CIMDataType::EMBEDDEDINSTANCE)
01696             {
01697                outParams[i].setValue(CIMValueCast::castValueToDataType(
01698                   v, methodOutParams[i].getType()));
01699             }
01700          }
01701       }
01702    }
01703    if (m_logger->getLogLevel() == E_DEBUG_LEVEL)
01704    {
01705       methodStr.reset();
01706       methodStr += "CIMServer finished invoking extrinsic method provider: ";
01707       CIMObjectPath path2(path);
01708       path2.setNameSpace(ns);
01709       methodStr += path2.toString();
01710       methodStr += '.';
01711       methodStr += methodName;
01712       methodStr += " OUT Params(";
01713       for (size_t i = 0; i < outParams.size(); ++i)
01714       {
01715          methodStr += outParams[i].getName();
01716          methodStr += '=';
01717          methodStr += outParams[i].getValue().toString();
01718          if (i != outParams.size() - 1)
01719          {
01720             methodStr += ", ";
01721          }
01722       }
01723       methodStr += ") return value: ";
01724       methodStr += cv.toString();
01725       OW_LOG_DEBUG(m_logger, methodStr.toString());
01726    }
01727    return cv;
01728 }
01730 InstanceProviderIFCRef
01731 CIMServer::_getInstanceProvider(const String& ns, const CIMClass& cc_,
01732    OperationContext& context)
01733 {
01734    InstanceProviderIFCRef instancep;
01735    CIMClass cc(cc_);
01736    try
01737    {
01738       instancep =
01739          m_provManager->getInstanceProvider(createProvEnvRef(context, m_env), ns, cc);
01740    }
01741    catch (const NoSuchProviderException& e)
01742    {
01743       // This will only happen if the provider qualifier is incorrect
01744       OW_THROWCIMMSG_SUBEX(CIMException::FAILED,
01745          Format("Invalid provider: %1", e.getMessage()).c_str(), e);
01746    }
01747    return instancep;
01748 }
01750 SecondaryInstanceProviderIFCRefArray
01751 CIMServer::_getSecondaryInstanceProviders(const String& ns, const CIMName& className, OperationContext& context)
01752 {
01753    SecondaryInstanceProviderIFCRefArray rval;
01754    try
01755    {
01756       rval = m_provManager->getSecondaryInstanceProviders(createProvEnvRef(context, m_env), ns, className);
01757    }
01758    catch (const NoSuchProviderException& e)
01759    {
01760       // This will only happen if the provider qualifier is incorrect
01761       OW_THROWCIMMSG_SUBEX(CIMException::FAILED,
01762          Format("Invalid provider: %1", e.getMessage()).c_str(), e);
01763    }
01764    return rval;
01765 }
01766 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
01767 
01768 AssociatorProviderIFCRef
01769 CIMServer::_getAssociatorProvider(const String& ns, const CIMClass& cc_, OperationContext& context)
01770 {
01771    AssociatorProviderIFCRef ap;
01772    CIMClass cc(cc_);
01773    try
01774    {
01775       ap =  m_provManager->getAssociatorProvider(
01776          createProvEnvRef(context, m_env), ns, cc);
01777    }
01778    catch (const NoSuchProviderException&)
01779    {
01780       // if it's not an instance or associator provider, then ERROR!
01781       try
01782       {
01783          m_provManager->getInstanceProvider(
01784             createProvEnvRef(context, m_env), ns, cc);
01785       }
01786       catch (const NoSuchProviderException& e)
01787       {
01788          // This will only happen if the provider qualifier is incorrect
01789          OW_THROWCIMMSG_SUBEX(CIMException::FAILED,
01790             Format("Invalid provider: %1", e.getMessage()).c_str(), e);
01791       }
01792    }
01793    return ap;
01794 }
01795 #endif
01796 
01797 CIMClass
01798 CIMServer::_getNameSpaceClass(const CIMName& className)
01799 {
01800    if (className == DEPRECATED__NamespaceClassName)
01801    {
01802       MutexLock l(m_guard);
01803       if (!m_nsClass_Namespace)
01804       {
01805          m_nsClass_Namespace = CIMClass(DEPRECATED__NamespaceClassName);
01806          CIMProperty cimProp(CIMProperty::NAME_PROPERTY);
01807          cimProp.setDataType(CIMDataType::STRING);
01808          cimProp.addQualifier(CIMQualifier::createKeyQualifier());
01809          m_nsClass_Namespace.addProperty(cimProp);
01810       }
01811       return m_nsClass_Namespace;
01812    }
01813    /*
01814    else if (className.equalsIgnoreCase("CIM_Namespace"))
01815    {
01816       if (!m_nsClassCIM_Namespace)
01817       {
01818          m_nsClassCIM_Namespace = CIMClass("CIM_Namespace");
01819       }
01820       return m_nsClassCIM_Namespace;
01821    }
01822    */
01823    else
01824    {
01825       return CIMClass(CIMNULL);
01826    }
01827 }
01829 void
01830 CIMServer::execQuery(
01831    const String& ns,
01832    CIMInstanceResultHandlerIFC& result,
01833    const String &query,
01834    const String& queryLanguage, OperationContext& context)
01835 {
01836    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01837    WQLIFCRef wql = m_env->getWQLRef();
01838    if (wql && wql->supportsQueryLanguage(queryLanguage))
01839    {
01840       logOperation(m_logger, context, "ExecQuery", ns, query);
01841 
01842       CIMOMHandleIFCRef lch = m_env->getCIMOMHandle(context,
01843             ServiceEnvironmentIFC::E_USE_PROVIDERS,
01844             ServiceEnvironmentIFC::E_NO_LOCKING);
01845       try
01846       {
01847          wql->evaluate(ns, result, query, queryLanguage, lch);
01848       }
01849       catch (const CIMException& ce)
01850       {
01851          // translate any error except INVALID_NAMESPACE, INVALID_QUERY,
01852          // ACCESS_DENIED or FAILED into an INVALID_QUERY
01853          if (ce.getErrNo() != CIMException::FAILED
01854             && ce.getErrNo() != CIMException::INVALID_NAMESPACE
01855             && ce.getErrNo() != CIMException::INVALID_QUERY
01856             && ce.getErrNo() != CIMException::ACCESS_DENIED)
01857          {
01858             // the " " added to the beginning of the message is a little
01859             // trick to fool the CIMException constructor from stripping
01860             // away the old "canned" CIMException message.
01861             throw CIMException(ce.getFile(), ce.getLine(),
01862                CIMException::INVALID_QUERY,
01863                String(String(" ") + ce.getMessage()).c_str());
01864          }
01865          else
01866          {
01867             throw ce;
01868          }
01869       }
01870    }
01871    else
01872    {
01873       OW_THROWCIMMSG(CIMException::QUERY_LANGUAGE_NOT_SUPPORTED, queryLanguage.c_str());
01874    }
01875 }
01876 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
01877 
01878 
01879 namespace
01880 {
01881 class InstanceAuthorizer : public CIMInstanceResultHandlerIFC
01882 {
01883 public:
01884    InstanceAuthorizer(
01885       ServiceEnvironmentIFCRef env_,
01886       AuthorizerManagerRef authorizerManager_,
01887       CIMInstanceResultHandlerIFC& result_,
01888       const String& ns_,
01889       EIncludeQualifiersFlag includeQualifiers_,
01890       EIncludeClassOriginFlag includeClassOrigin_,
01891       const StringArray* propertyList_,
01892       OperationContext& context_)
01893    : env(env_)
01894    , authorizerMgr(authorizerManager_)
01895    , result(result_)
01896    , ns(ns_)
01897    , includeQualifiers(includeQualifiers_)
01898    , includeClassOrigin(includeClassOrigin_)
01899    , clientPropertyList(propertyList_)
01900    , authorizedPropertyList()
01901    , context(context_)
01902    {
01903    }
01904 
01905 protected:
01906    virtual void doHandle(const CIMInstance &inst)
01907    {
01908       // See if the authorizer allows reading of these instances and give it
01909       // an opportunity to modify the properties returned.
01910       if (authorizerMgr->allowReadInstance(
01911          env, ns, inst.getClassName(), clientPropertyList,
01912          authorizedPropertyList, context))
01913       {
01914          if (authorizedPropertyList.size() > 0)
01915          {
01916             result.handle(inst.filterProperties(
01917                authorizedPropertyList, includeQualifiers,
01918                includeClassOrigin, false));
01919             authorizedPropertyList.clear();
01920          }
01921          else
01922          {
01923             result.handle(inst);
01924          }
01925       }
01926    }
01927 private:
01928    ServiceEnvironmentIFCRef env;
01929    AuthorizerManagerRef authorizerMgr;
01930    CIMInstanceResultHandlerIFC& result;
01931    String ns;
01932    EIncludeQualifiersFlag includeQualifiers;
01933    EIncludeClassOriginFlag includeClassOrigin;
01934    const StringArray* clientPropertyList;
01935    StringArray authorizedPropertyList;
01936    OperationContext& context;
01937 };
01938 }  // End of unnamed namespace
01939 
01941 void
01942 CIMServer::associators(
01943    const String& ns,
01944    const CIMObjectPath& path,
01945    CIMInstanceResultHandlerIFC& result,
01946    const String& assocClass, const String& resultClass,
01947    const String& role, const String& resultRole,
01948    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
01949    const StringArray* propertyList, OperationContext& context)
01950 {
01951    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01952 
01953    logOperation(m_logger, context, "Associators", ns, path.toString());
01954 
01955    // Allow authorizer to intercept instances that will be returned
01956    InstanceAuthorizer ia(m_env, m_authorizerMgr, result, ns, includeQualifiers,
01957       includeClassOrigin, propertyList, context);                                
01958 
01959    _commonAssociators(ns, path, assocClass, resultClass, role, resultRole,
01960       includeQualifiers, includeClassOrigin, propertyList, &ia, 0, 0,
01961       context);
01962 }
01964 void
01965 CIMServer::associatorsClasses(
01966    const String& ns,
01967    const CIMObjectPath& path,
01968    CIMClassResultHandlerIFC& result,
01969    const String& assocClass, const String& resultClass,
01970    const String& role, const String& resultRole,
01971    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
01972    const StringArray* propertyList, OperationContext& context)
01973 {
01974    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01975 
01976    logOperation(m_logger, context, "AssociatorsClasses", ns, path.toString());
01977 
01978    _commonAssociators(ns, path, assocClass, resultClass, role, resultRole,
01979       includeQualifiers, includeClassOrigin, propertyList, 0, 0, &result,
01980       context);
01981 }
01983 void
01984 CIMServer::associatorNames(
01985    const String& ns,
01986    const CIMObjectPath& path,
01987    CIMObjectPathResultHandlerIFC& result,
01988    const String& assocClass, const String& resultClass,
01989    const String& role, const String& resultRole,
01990    OperationContext& context)
01991 {
01992    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
01993    
01994    logOperation(m_logger, context, "AssociatorNames", ns, path.toString());
01995    
01996    _commonAssociators(ns, path, assocClass, resultClass, role, resultRole,
01997       E_EXCLUDE_QUALIFIERS, E_EXCLUDE_CLASS_ORIGIN, 0, 0, &result, 0, context);
01998 }
02000 void
02001 CIMServer::references(
02002    const String& ns,
02003    const CIMObjectPath& path,
02004    CIMInstanceResultHandlerIFC& result,
02005    const String& resultClass, const String& role,
02006    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02007    const StringArray* propertyList, OperationContext& context)
02008 {
02009    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
02010 
02011    logOperation(m_logger, context, "References", ns, path.toString());
02012    
02013    // Allow authorizer to intercept instances that will be returned
02014       InstanceAuthorizer ia(m_env, m_authorizerMgr, result, ns, includeQualifiers,
02015       includeClassOrigin, propertyList, context);
02016 
02017    _commonReferences(ns, path, resultClass, role, includeQualifiers,
02018       includeClassOrigin, propertyList, &ia, 0, 0, context);
02019 }
02021 void
02022 CIMServer::referencesClasses(
02023    const String& ns,
02024    const CIMObjectPath& path,
02025    CIMClassResultHandlerIFC& result,
02026    const String& resultClass, const String& role,
02027    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02028    const StringArray* propertyList, OperationContext& context)
02029 {
02030    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
02031    
02032    logOperation(m_logger, context, "ReferencesClasses", ns, path.toString());
02033    
02034    _commonReferences(ns, path, resultClass, role, includeQualifiers,
02035       includeClassOrigin, propertyList, 0, 0, &result, context);
02036 }
02038 void
02039 CIMServer::referenceNames(
02040    const String& ns,
02041    const CIMObjectPath& path,
02042    CIMObjectPathResultHandlerIFC& result,
02043    const String& resultClass, const String& role,
02044    OperationContext& context)
02045 {
02046    _checkNameSpaceAccess(context, ns, Authorizer2IFC::E_READ);
02047    
02048    logOperation(m_logger, context, "ReferenceNames", ns, path.toString());
02049    
02050    _commonReferences(ns, path, resultClass, role, E_EXCLUDE_QUALIFIERS, E_EXCLUDE_CLASS_ORIGIN, 0, 0, &result, 0,
02051       context);
02052 }
02054 namespace
02055 {
02056    class assocClassSeparator : public CIMClassResultHandlerIFC
02057    {
02058    public:
02059       assocClassSeparator(
02060          CIMNameArray* staticAssocs_,
02061          CIMClassArray& dynamicAssocs_,
02062          CIMServer& server_,
02063          OperationContext& context_,
02064          const String& ns_,
02065          const LoggerRef& lgr)
02066       : staticAssocs(staticAssocs_)
02067       , dynamicAssocs(dynamicAssocs_)
02068       , server(server_)
02069       , context(context_)
02070       , ns(ns_)
02071       , logger(lgr)
02072       {}
02073    protected:
02074       virtual void doHandle(const CIMClass &cc)
02075       {
02076          if (!cc.isAssociation())
02077          {
02078             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
02079                Format("class %1 is not an association", cc.getName()).c_str());
02080          }
02081          // Now separate the association classes that have associator provider from
02082          // the ones that don't
02083          if (server._isDynamicAssoc(ns, cc, context))
02084          {
02085             dynamicAssocs.push_back(cc);
02086             OW_LOG_DEBUG(logger, "Found dynamic assoc class: " + cc.getName());
02087          }
02088          else if (staticAssocs)
02089          {
02090             staticAssocs->push_back(cc.getName());
02091             OW_LOG_DEBUG(logger, "Found static assoc class: " + cc.getName());
02092          }
02093       }
02094    private:
02095       CIMNameArray* staticAssocs;
02096       CIMClassArray& dynamicAssocs;
02097       CIMServer& server;
02098       OperationContext& context;
02099       String ns;
02100       LoggerRef logger;
02101    };
02102 }
02104 void
02105 CIMServer::_commonReferences(
02106    const String& ns,
02107    const CIMObjectPath& path_,
02108    const CIMName& resultClass, const CIMName& role,
02109    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02110    const StringArray* propertyList, CIMInstanceResultHandlerIFC* piresult,
02111    CIMObjectPathResultHandlerIFC* popresult,
02112    CIMClassResultHandlerIFC* pcresult,
02113    OperationContext& context)
02114 {
02115    CIMObjectPath path(path_);
02116    path.setNameSpace(ns);
02117    path.syncWithClass(getClass(ns, path.getClassName(),E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context));
02118    // Get all association classes from the repository
02119    // If the result class was specified, only children of it will be
02120    // returned.
02121    CIMClassArray dynamicAssocs;
02122    CIMNameArray resultClassNames;
02123    assocClassSeparator assocClassResult(!m_realRepository || resultClass == CIMName() ? 0 : &resultClassNames, dynamicAssocs, *this, context, ns, m_logger);
02124    _getAssociationClasses(ns, resultClass, path.getClassName(), assocClassResult, role, context);
02125    if (path.isClassPath())
02126    {
02127       // Let authorizer determine if user is allowed to read schema items
02128       if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
02129       {
02130          OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
02131             Format("You are not allowed to read classes from namespace %1",
02132                ns).c_str());
02133       }
02134 
02135       // Process all of the association classes without providers
02136       if (m_realRepository)
02137       {
02138          if (resultClass != CIMName())
02139          {
02140             // providers don't do classes, so we'll add the dynamic ones into the list
02141             for (size_t i = 0; i < dynamicAssocs.size(); i++)
02142             {
02143                resultClassNames.append(dynamicAssocs[i].getName());
02144             }
02145             SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(), resultClassNames.end());
02146             m_realRepository->_staticReferencesClass(path, &resultClassNamesSet,
02147                role, includeQualifiers, includeClassOrigin, propertyList, popresult, pcresult, context);
02148          }
02149          else
02150          {
02151             m_realRepository->_staticReferencesClass(path, 0,
02152                role, includeQualifiers, includeClassOrigin, propertyList, popresult, pcresult, context);
02153          }
02154       }
02155       else
02156       {
02157          if (popresult != 0)
02158          {
02159             m_cimRepository->referenceNames(ns,path,*popresult,resultClass.toString(),role.toString(),context);
02160          }
02161          else if (pcresult != 0)
02162          {
02163             m_cimRepository->referencesClasses(ns,path,*pcresult,resultClass.toString(),role.toString(),includeQualifiers,includeClassOrigin,propertyList,context);
02164          }
02165          else
02166          {
02167             OW_ASSERT(0);
02168          }
02169       }
02170    }
02171    else // it's an instance path
02172    {
02173       // Process all of the association classes without providers
02174       if (piresult != 0)
02175       {
02176          // do instances
02177          if (m_realRepository)
02178          {
02179             if (resultClass != CIMName())
02180             {
02181                SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(), resultClassNames.end());
02182                m_realRepository->_staticReferences(path, &resultClassNamesSet, role,
02183                   includeQualifiers, includeClassOrigin, propertyList, *piresult, context);
02184             }
02185             else
02186             {
02187                m_realRepository->_staticReferences(path, 0, role,
02188                   includeQualifiers, includeClassOrigin, propertyList, *piresult, context);
02189             }
02190          }
02191          else
02192          {
02193             m_cimRepository->references(ns,path,*piresult,resultClass.toString(),role.toString(),includeQualifiers,includeClassOrigin,propertyList,context);
02194          }
02195       }
02196       else if (popresult != 0)
02197       {
02198          // do names (object paths)
02199          if (m_realRepository)
02200          {
02201             if (resultClass != CIMName())
02202             {
02203                SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(), resultClassNames.end());
02204                m_realRepository->_staticReferenceNames(path,
02205                   &resultClassNamesSet, role,
02206                   *popresult);
02207             }
02208             else
02209             {
02210                m_realRepository->_staticReferenceNames(path,
02211                   0, role,
02212                   *popresult);
02213             }
02214          }
02215          else
02216          {
02217             m_cimRepository->referenceNames(ns,path,*popresult,resultClass.toString(),role.toString(),context);
02218          }
02219       }
02220       else
02221       {
02222          OW_ASSERT(0);
02223       }
02224 
02225       // we need to remove dups from dynamicAssocs
02226       std::sort(dynamicAssocs.begin(),  dynamicAssocs.end());
02227       dynamicAssocs.erase(std::unique(dynamicAssocs.begin(),  dynamicAssocs.end()), dynamicAssocs.end());
02228       // Process all of the association classes with providers
02229       _dynamicReferences(path, dynamicAssocs, role, includeQualifiers,
02230          includeClassOrigin, propertyList, piresult, popresult, context);
02231    }
02232 }
02234 void
02235 CIMServer::_dynamicReferences(const CIMObjectPath& path,
02236    const CIMClassArray& assocClasses, const CIMName& role,
02237    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02238    const StringArray* propertyList, CIMInstanceResultHandlerIFC* piresult,
02239    CIMObjectPathResultHandlerIFC* popresult, OperationContext& context)
02240 {
02241    // assocClasses should always have something in it
02242    if (assocClasses.size() == 0)
02243    {
02244       return;
02245    }
02246    for (size_t i = 0; i < assocClasses.size(); i++)
02247    {
02248       CIMClass cc = assocClasses[i];
02249       AssociatorProviderIFCRef assocP = _getAssociatorProvider(path.getNameSpace(), cc, context);
02250       if (!assocP)
02251       {
02252          continue;
02253       }
02254       CIMName resultClass(assocClasses[i].getName());
02255       // If the object path enumeration pointer is null, then assume we
02256       // are doing references and not referenceNames
02257       if (piresult != 0)
02258       {
02259          assocP->references(
02260             createProvEnvRef(context, m_env), *piresult,
02261             path.getNameSpace(), path, resultClass.toString(), role.toString(), includeQualifiers,
02262             includeClassOrigin, propertyList);
02263       }
02264       else if (popresult != 0)
02265       {
02266          assocP->referenceNames(
02267             createProvEnvRef(context, m_env), *popresult,
02268             path.getNameSpace(), path, resultClass.toString(), role.toString());
02269       }
02270       else
02271       {
02272          OW_ASSERT(0);
02273       }
02274    }
02275 }
02276 namespace
02277 {
02278    class classNamesBuilder : public StringResultHandlerIFC
02279    {
02280    public:
02281       classNamesBuilder(CIMNameArray& resultClassNames)
02282          : m_resultClassNames(resultClassNames)
02283       {}
02284       void doHandle(const String& op)
02285       {
02286          m_resultClassNames.push_back(op);
02287       }
02288    private:
02289       CIMNameArray& m_resultClassNames;
02290    };
02291 } // end anonymous namespace
02293 void
02294 CIMServer::_commonAssociators(
02295    const String& ns,
02296    const CIMObjectPath& path_,
02297    const CIMName& assocClassName, const CIMName& resultClass,
02298    const CIMName& role, const CIMName& resultRole,
02299    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02300    const StringArray* propertyList,
02301    CIMInstanceResultHandlerIFC* piresult,
02302    CIMObjectPathResultHandlerIFC* popresult,
02303    CIMClassResultHandlerIFC* pcresult,
02304    OperationContext& context)
02305 {
02306    CIMObjectPath path(path_);
02307    path.setNameSpace(ns);
02308    path.syncWithClass(getClass(ns, path.getClassName(),E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context));
02309    // Get association classes from the association repository
02310    CIMClassArray dynamicAssocs;
02311    CIMNameArray assocClassNames;
02312    assocClassSeparator assocClassResult(!m_realRepository || assocClassName == CIMName() ? 0 : &assocClassNames, dynamicAssocs, *this, context, ns, m_logger);
02313    _getAssociationClasses(ns, assocClassName, path.getClassName(), assocClassResult, role, context);
02314    // If the result class was specified, get a list of all the classes the
02315    // objects must be instances of.
02316    CIMNameArray resultClassNames;
02317    if (m_realRepository && resultClass != CIMName())
02318    {
02319       classNamesBuilder resultClassNamesResult(resultClassNames);
02320       m_cimRepository->enumClassNames(ns, resultClass.toString(), resultClassNamesResult, E_DEEP, context);
02321       resultClassNames.append(resultClass);
02322    }
02323    if (path.isClassPath())
02324    {
02325       // Let authorizer determine if user is allowed to read schema items
02326       if (!m_authorizerMgr->allowReadSchema(m_env, ns, context))
02327       {
02328          OW_THROWCIMMSG(CIMException::ACCESS_DENIED,
02329             Format("You are not allowed to read classes from namespace %1",
02330                ns).c_str());
02331       }
02332 
02333       // Process all of the association classes without providers
02334       if (m_realRepository)
02335       {
02336          SortedVectorSet<CIMName> assocClassNamesSet(assocClassNames.begin(),
02337                assocClassNames.end());
02338          SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(),
02339                resultClassNames.end());
02340          m_realRepository->_staticAssociatorsClass(path, assocClassName == CIMName() ? 0 : &assocClassNamesSet,
02341             resultClass == CIMName() ? 0 : &resultClassNamesSet,
02342             role, resultRole, includeQualifiers, includeClassOrigin, propertyList, popresult, pcresult, context);
02343       }
02344       else
02345       {
02346          if (popresult != 0)
02347          {
02348             m_cimRepository->associatorNames(ns,path,*popresult,assocClassName.toString(),resultClass.toString(),role.toString(),resultRole.toString(),context);
02349          }
02350          else if (pcresult != 0)
02351          {
02352             m_cimRepository->associatorsClasses(ns,path,*pcresult,assocClassName.toString(),resultClass.toString(),role.toString(),resultRole.toString(),includeQualifiers,includeClassOrigin,propertyList,context);
02353          }
02354          else
02355          {
02356             OW_ASSERT(0);
02357          }
02358       }
02359    }
02360    else // it's an instance path
02361    {
02362       // Process all of the association classes without providers
02363       if (piresult != 0)
02364       {
02365          // do instances
02366          if (m_realRepository)
02367          {
02368             SortedVectorSet<CIMName> assocClassNamesSet(assocClassNames.begin(),
02369                   assocClassNames.end());
02370             SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(),
02371                   resultClassNames.end());
02372             m_realRepository->_staticAssociators(path, assocClassName == CIMName() ? 0 : &assocClassNamesSet,
02373                resultClass == CIMName() ? 0 : &resultClassNamesSet, role, resultRole,
02374                includeQualifiers, includeClassOrigin, propertyList, *piresult, context);
02375          }
02376          else
02377          {
02378             m_cimRepository->associators(ns,path,*piresult,assocClassName.toString(),resultClass.toString(),role.toString(),resultRole.toString(),includeQualifiers,includeClassOrigin,propertyList,context);
02379          }
02380       }
02381       else if (popresult != 0)
02382       {
02383          // do names (object paths)
02384          if (m_realRepository)
02385          {
02386             SortedVectorSet<CIMName> assocClassNamesSet(assocClassNames.begin(),
02387                   assocClassNames.end());
02388             SortedVectorSet<CIMName> resultClassNamesSet(resultClassNames.begin(),
02389                   resultClassNames.end());
02390             m_realRepository->_staticAssociatorNames(path, assocClassName == CIMName() ? 0 : &assocClassNamesSet,
02391                resultClass == CIMName() ? 0 : &resultClassNamesSet, role, resultRole,
02392                *popresult);
02393          }
02394          else
02395          {
02396             m_cimRepository->associatorNames(ns,path,*popresult,assocClassName.toString(),resultClass.toString(),role.toString(),resultRole.toString(),context);
02397          }
02398       }
02399       else
02400       {
02401          OW_ASSERT(0);
02402       }
02403       // we need to remove dups from dynamicAssocs
02404       std::sort(dynamicAssocs.begin(),  dynamicAssocs.end());
02405       dynamicAssocs.erase(std::unique(dynamicAssocs.begin(),  dynamicAssocs.end()), dynamicAssocs.end());
02406       // Process all of the association classes with providers
02407       _dynamicAssociators(path, dynamicAssocs, resultClass, role, resultRole,
02408          includeQualifiers, includeClassOrigin, propertyList, piresult, popresult,
02409          context);
02410    }
02411 }
02413 void
02414 CIMServer::_dynamicAssociators(const CIMObjectPath& path,
02415    const CIMClassArray& assocClasses, const CIMName& resultClass,
02416    const CIMName& role, const CIMName& resultRole,
02417    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
02418    const StringArray* propertyList, CIMInstanceResultHandlerIFC* piresult,
02419    CIMObjectPathResultHandlerIFC* popresult, OperationContext& context)
02420 {
02421    // AssocClasses should always have something in it
02422    if (assocClasses.size() == 0)
02423    {
02424       return;
02425    }
02426    for (size_t i = 0; i < assocClasses.size(); i++)
02427    {
02428       CIMClass cc = assocClasses[i];
02429       AssociatorProviderIFCRef assocP = _getAssociatorProvider(path.getNameSpace(), cc, context);
02430       if (!assocP)
02431       {
02432          OW_LOG_ERROR(m_logger, "Failed to get associator provider for class: " + cc.getName());
02433          continue;
02434       }
02435       CIMName assocClass(assocClasses[i].getName());
02436       if (piresult != 0)
02437       {
02438          OW_LOG_DEBUG(m_logger, "Calling associators on associator provider for class: " + cc.getName());
02439          assocP->associators(createProvEnvRef(context, m_env), *piresult, path.getNameSpace(),
02440             path, assocClass.toString(), resultClass.toString(), role.toString(), resultRole.toString(),
02441             includeQualifiers, includeClassOrigin, propertyList);
02442       }
02443       else if (popresult != 0)
02444       {
02445          OW_LOG_DEBUG(m_logger, "Calling associatorNames on associator provider for class: " + cc.getName());
02446          assocP->associatorNames(createProvEnvRef(context, m_env), *popresult,
02447             path.getNameSpace(), path, assocClass.toString(), resultClass.toString(), role.toString(), resultRole.toString());
02448       }
02449       else
02450       {
02451          OW_ASSERT(0);
02452       }
02453    }
02454 }
02456 void
02457 CIMServer::_getAssociationClasses(const String& ns,
02458       const CIMName& assocClassName, const CIMName& className,
02459       CIMClassResultHandlerIFC& result, const CIMName& role, OperationContext& context)
02460 {
02461    if (assocClassName != CIMName())
02462    {
02463       // they gave us a class name so we can use the class association index
02464       // to only look at the ones that could provide associations
02465       CIMClass cc = getClass(ns,assocClassName.toString(),E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN,0,context);
02466       result.handle(cc);
02467       // TODO: measure whether it would be faster to use
02468       // enumClassNames + getClass() here.
02469       enumClasses(ns,assocClassName.toString(),result,E_DEEP,E_NOT_LOCAL_ONLY,E_INCLUDE_QUALIFIERS,E_INCLUDE_CLASS_ORIGIN, context);
02470    }
02471    else
02472    {
02473       // need to get all the assoc classes with dynamic providers
02474       CIMObjectPath cop(className, ns);
02475       if (m_realRepository)
02476       {
02477          m_realRepository->_staticReferencesClass(cop,0,role,E_INCLUDE_QUALIFIERS,E_EXCLUDE_CLASS_ORIGIN,0,0,&result,context);
02478       }
02479       else
02480       {
02481          m_cimRepository->referencesClasses(ns,cop,result,assocClassName.toString(),role.toString(),E_INCLUDE_QUALIFIERS,E_EXCLUDE_CLASS_ORIGIN,0,context);
02482       }
02483       // TODO: test if this is faster
02484       //assocHelper helper(result, m_mStore, ns);
02485       //m_mStore.getTopLevelAssociations(ns, helper);
02486    }
02487 }
02489 bool
02490 CIMServer::_isDynamicAssoc(const String& ns, const CIMClass& cc, OperationContext& context)
02491 {
02492    return _getAssociatorProvider(ns, cc, context) ? true : false;
02493 }
02494 #endif // #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
02495 
02497 void
02498 CIMServer::beginOperation(WBEMFlags::EOperationFlag op, OperationContext& context)
02499 {
02500    m_cimRepository->beginOperation(op, context);
02501 }
02502 
02504 void
02505 CIMServer::endOperation(WBEMFlags::EOperationFlag op, OperationContext& context, WBEMFlags::EOperationResultFlag result)
02506 {
02507    m_cimRepository->endOperation(op, context, result);
02508 }
02509 
02511 ServiceEnvironmentIFCRef
02512 CIMServer::getEnvironment() const
02513 {
02514    return m_env;
02515 }
02516 
02518 const char* const CIMServer::INST_REPOS_NAME = "instances";
02519 const char* const CIMServer::META_REPOS_NAME = "schema";
02520 const char* const CIMServer::NS_REPOS_NAME = "namespaces";
02521 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
02522 const char* const CIMServer::CLASS_ASSOC_REPOS_NAME = "classassociation";
02523 const char* const CIMServer::INST_ASSOC_REPOS_NAME = "instassociation";
02524 #endif
02525 
02526 
02527 
02528 } // end namespace OW_NAMESPACE
02529 

Generated on Thu Feb 9 08:47:55 2006 for openwbem by  doxygen 1.4.6