std::string getValue( XmlTransaction &txn, XmlManager &mgr, const XmlDocument &document,
					 const std::string &XPath, XmlQueryContext &context )
{
	/////////////////////////////////////////////////////////////////////////////////
	///////////    Return specific information from a document. /////////////////////
	///////////   !!!!!! Assumes a result set of size 1 !!!!!!! /////////////////////
	/////////////////////////////////////////////////////////////////////////////////

	// Exception handling omitted....

	//Perform the query
	XmlQueryExpression doc_expr = mgr.prepare(txn, XPath, context);
	XmlResults result = doc_expr.execute( txn, XmlValue(document), context);

	//We require a result set size of 1.
	assert( result.size() == 1 );

	//Get the value. If we allowed the result set to be larger than size 1,
	//we would have to loop through the results, processing each as is
	//required by our application.
	XmlValue value;
	result.next(value);

	return value.asString();

}
MgByteReader* MgResourceDefinitionManager::GetResource(
    MgResourceIdentifier* resource, const MgDataBindingInfo* dataBindingInfo)
{
    assert(NULL != resource);
    Ptr<MgByteReader> byteReader;

    MG_RESOURCE_SERVICE_TRY()

    // Get the resource.

    XmlDocument xmlDoc = GetDocument(*resource);
    string document;

    xmlDoc.getContent(document);

    // Bind the data if required.

    if (NULL != dataBindingInfo)
    {
        // Substitute all the tags if necessary.

        XmlValue tagValue;

        if (xmlDoc.getMetaData(MgResourceInfo::sm_metadataUri,
                MgResourceInfo::sm_metadataNames[MgResourceInfo::Tags],
                tagValue))
        {
            STRING resourceTags;
            MgUtil::MultiByteToWideChar(tagValue.asString(), resourceTags);

            // If there is no resource tag, then just do the substitution for
            // the login username and password.

            MgTagManager tagManager(resourceTags);
            tagManager.SubstituteTags(*dataBindingInfo, document);
        }
    }

    // Create a byte reader.

    Ptr<MgByteSource> byteSource = new MgByteSource(
        (unsigned char*)document.c_str(), (INT32)document.length());

    byteSource->SetMimeType(MgMimeType::Xml);
    byteReader = byteSource->GetReader();

    MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgResourceDefinitionManager.GetResource")

    return SAFE_ADDREF((MgByteReader*)byteReader);
}
void getDetails( XmlTransaction &txn, XmlManager &mgr, const XmlContainer &container, const std::string &query, XmlQueryContext &context )
{
	////////////////////////////////////////////////////////////////////////
	//////  Performs an query (in context) against the         ///////
	//////  provided container.                                      ///////
	////////////////////////////////////////////////////////////////////////

	///// some defensive code eliminated for clarity //

	// Perform the query. Result type is by default Result Document
	std::string fullQuery = "collection('" + container.getName() + "')" + query;
	try {
		std::cout << "Exercising query '" << fullQuery << "' " << std::endl;
		std::cout << "Return to continue: ";
		getc(stdin);

		XmlResults results( mgr.query( txn, fullQuery, context ) );
		XmlValue value;
		std::cout << "\n\tProduct : Price : Inventory Level\n";
		while( results.next(value) ) {
			/// Retrieve the value as a document
			XmlDocument theDocument = value.asDocument();

			/// Obtain information of interest from the document. Note that the
			//  wildcard in the query expression allows us to not worry about what
			//  namespace this document uses.
			std::string item = getValue( txn, mgr, theDocument, "fn:string(/*/product)", context);
			std::string price = getValue( txn, mgr, theDocument, "fn:string(/*/inventory/price)", context);
			std::string inventory = getValue( txn, mgr, theDocument, "fn:string(/*/inventory/inventory)", context);

			std::cout << "\t" << item << " : " << price << " : " << inventory << std::endl;

		}
		std::cout << "\n";
		std::cout << (unsigned int) results.size()
			<< " objects returned for expression '"
			<< fullQuery << "'\n" << std::endl;
	}
	//Catches XmlException
	catch(std::exception &e) {
		std::cerr << "Query " << fullQuery << " failed\n";
		std::cerr << e.what() << "\n";
		txn.abort();
		exit(-1);
	}
}
void XmlQueryContext::setVariableValue(const string &name,
				       const XmlValue &value)
{
	CHECK_POINTER;
	if (value.getType() == XmlValue::BINARY)
		throw XmlException(XmlException::INVALID_VALUE,
				   "XmlQueryContext::setVariableValue value cannot be binary");
	queryContext_->setVariableValue(name, new ValueResults(value,
							       queryContext_->getManager()));
}
Exemple #5
0
void doQuery( XmlTransaction &txn, XmlManager &db, const XmlContainer &container, const std::string &query )
{
	////////////////////////////////////////////////////////////////////////
	//////  Performs a simple query (no context) against the   ///////
	//////  provided container.                                      ///////
	////////////////////////////////////////////////////////////////////////

	///// some defensive code eliminated for clarity //

	// Perform the query. Result type is by default Result Document
	std::string fullQuery = "collection('" + container.getName() + "')" + query;
	try {
		std::cout << "Exercising query '" << fullQuery << "' " << std::endl;
		std::cout << "Return to continue: ";
		getc(stdin);

		XmlQueryContext context = db.createQueryContext();

		XmlResults results( db.query( txn, fullQuery, context) );
		XmlValue value;
		while( results.next(value) ) {
			// Obtain the value as a string and print it to stdout
			std::cout << value.asString() << std::endl;
		}

		std::cout << (unsigned int) results.size()
			<< " objects returned for expression '"
			<< fullQuery << "'\n" << std::endl;

	}
	catch(XmlException &e) {
		std::cerr << "Query " << fullQuery << " failed\n";
		std::cerr << e.what() << "\n";
		txn.abort();
		exit( -1 );
	}
	catch(std::exception &e) {
		std::cerr << "Query " << fullQuery << " failed\n";
		std::cerr << e.what() << "\n";
		txn.abort();
		exit( -1 );
	}
}
void doContextQuery( XmlTransaction &txn, XmlManager &mgr, const std::string cname,
					const std::string &query, XmlQueryContext &context )
{
	////////////////////////////////////////////////////////////////////////
	//////  Performs a simple query (with context) against the ///////
	//////  provided container.                                      ///////
	////////////////////////////////////////////////////////////////////////

	///// some defensive code eliminated for clarity //

	// Perform the query. Result type is by default Result Document
	std::string fullQuery = "collection('" + cname + "')" + query;
	try {
		std::cout << "Exercising query '" << fullQuery << "' " << std::endl;
		std::cout << "Return to continue: ";
		getc(stdin);
		std::cout << "\n";

		XmlResults results( mgr.query(txn, fullQuery, context ) );
		XmlValue value;
		while(results.next(value)) {
			// Get the document's name and print it to the console
			XmlDocument theDocument = value.asDocument();
			std::cout << "Document name: " << theDocument.getName() << std::endl;
			std::cout << value.asString() << std::endl;
		}

		std::cout << (unsigned int)results.size()
			<< " objects returned for expression '" << fullQuery
			<< "'\n" << std::endl;

	}
	//Catches XmlException
	catch(std::exception &e) {
		std::cerr << "Query " << fullQuery << " failed\n";
		std::cerr << e.what() << "\n";
		txn.abort();
		exit( -1 );
	}
}
Exemple #7
0
int
main(int argc, char **argv)
{
	// This program uses a named container, which will apear
	// on disk
	std::string containerName = "people.dbxml";
	std::string content = "<people><person><name>joe</name></person><person><name>mary</name></person></people>";
	std::string docName = "people";
	// Note that the query uses a variable, which must be set
	// in the query context
	std::string queryString =
		"collection('people.dbxml')/people/person[name=$name]";
	std::string environmentDir = ".";

	// Berkeley DB environment flags
	u_int32_t envFlags = DB_RECOVER|DB_CREATE|DB_INIT_MPOOL|
		DB_INIT_LOCK|DB_INIT_TXN|DB_INIT_LOG;
	// Berkeley DB cache size (25 MB).  The default is quite small
	u_int32_t envCacheSize = 25*1024*1024;

	// argument parsing should really use getopt(), but
	// avoid it for platform-independence
	if (argc == 3) {
		if (std::string(argv[1]) != std::string("-h"))
			usage(argv[0]);
		environmentDir = argv[2];
	} else if (argc != 1)
		usage(argv[0]);

	// Create and open a Berkeley DB Transactional Environment.
	int dberr;
	DB_ENV *dbEnv = 0;
	dberr = db_env_create(&dbEnv, 0);
	if (dberr == 0) {
		dbEnv->set_cachesize(dbEnv, 0, envCacheSize, 1);
		dbEnv->set_errcall(dbEnv, errcall); // set error callback
		dbEnv->set_lk_detect(dbEnv, DB_LOCK_DEFAULT); // handle deadlocks
		dberr = dbEnv->open(dbEnv, environmentDir.c_str(), envFlags, 0);
	}
	if (dberr) {
		std::cout << "Unable to create environment handle due to the following error: " <<
			db_strerror(dberr) << std::endl;
		if (dbEnv) dbEnv->close(dbEnv, 0);
		return -1;
	}

	try {
		// All BDB XML programs require an XmlManager instance.
		// Create it from the DbEnv
		XmlManager mgr(dbEnv, DBXML_ADOPT_DBENV);

		// Because the container will exist on disk, remove it
		// first if it exists
		if (mgr.existsContainer(containerName))
			mgr.removeContainer(containerName);

		/* Create a container that is transactional.  The container
		* type is NodeContainer, which is the default container type,
		* and the index is on nodes, which is the default for a
		* NodeContainer container.  XmlContainerConfig can be used
		* to set the container type and index type.
		*/
		XmlContainerConfig config;
		config.setTransactional(true);
		XmlContainer cont = mgr.createContainer(
			containerName,
			config);

		// All Container modification operations need XmlUpdateContext
		XmlUpdateContext uc = mgr.createUpdateContext();

		// The following putDocument call will auto-transact
		// and will abort/cleanup if the operation deadlocks or
		// otherwise fails
		cont.putDocument(docName, content, uc);

		// Querying requires an XmlQueryContext
		XmlQueryContext qc = mgr.createQueryContext();

		// Add a variable to the query context, used by the query
		qc.setVariableValue("name", "mary");

		// Use try/catch and while to handle deadlock/retry
		int retry = 0;
		while (retry < 5) { // hard-code 5 retries
			// Create a new transaction for the query
			XmlTransaction txn = mgr.createTransaction();

			try {
				// o Note the passing of txn to both methods
				// o Often the XmlQueryExpression object will be created and
				// saved for reuse in order to amortize the cost of parsing a query
				XmlQueryExpression expr = mgr.prepare(txn, queryString, qc);
				XmlResults res = expr.execute(txn, qc);

				// Note use of XmlQueryExpression::getQuery() and
				// XmlResults::size()
				std::cout << "The query, '" << expr.getQuery() << "' returned " <<
					(unsigned int)res.size() << " result(s)" << std::endl;

				// Process results -- just print them
				XmlValue value;
				std::cout << "Result: " << std::endl;
				while (res.next(value)) {
					std::cout << "\t" << value.asString() << std::endl;
				}

				// done with the transaction
				txn.commit();
				break;
			} catch (XmlException &x) {
				txn.abort(); // unconditional
				if ((x.getExceptionCode() == XmlException::DATABASE_ERROR) &&
					(x.getDbErrno() == DB_LOCK_DEADLOCK)) {
						++retry;
						continue; // try again
				}
				throw; // re-throw -- not deadlock
			}
		}
		// In C++, resources are released as objects go out
		// of scope.
	} catch (XmlException &xe) {
		std::cout << "XmlException: " << xe.what() << std::endl;
	}

	return 0;
}
void AddDocumentCommand::execute(Args &args, Environment &env)
{
	if ((args.size() < 3) || (args.size() > 4)){
		throw CommandException("Wrong number of arguments");
	}
	env.testContainer();
	env.deleteResults();

	if ((args.size() == 4) && (args[3] == "q")) {
		if(env.txn()) {
			XmlTransaction myTxn = env.childTransaction();
			env.results() = new XmlResults(
				env.db().query(myTxn, args[2], env.context()));

			XmlValue value;
			while(env.results()->next(value)) {
				string v = value.asString();
				string name = env.container()->
					putDocument(myTxn, args[1], v, env.uc(),
						    DBXML_GEN_NAME);
				if(env.verbose())
					cout << "Document added, name = " << name << endl;
			}

			myTxn.commit();
		} else {
			env.results() = new XmlResults(env.db().query(args[2],
								      env.context()));
			XmlValue value;
			while(env.results()->next(value)) {
				string v = value.asString();
				string name = env.container()->
					putDocument(args[1], v, env.uc(), DBXML_GEN_NAME);
				if(env.verbose())
					cout << "Document added, name = " << name << endl;
			}

		}
	} else {
		// by string or by file
		bool byString = true;
		if (args.size() == 4 && args[3] == "f")
			byString = false;
		XmlDocument doc = env.db().createDocument();
		doc.setName(args[1]);
		if (byString)
			doc.setContent(args[2]);
		else {
			XmlInputStream *is = env.db().createLocalFileInputStream(args[2]);
			doc.setContentAsXmlInputStream(is);
		}
		if(env.txn()) {
			XmlTransaction myTxn = env.childTransaction();
			env.container()->putDocument(myTxn, doc, env.uc());
			myTxn.commit();
		} else {
			env.container()->putDocument(doc, env.uc());
		}

		// put doc content in last results
		XmlResults res = env.db().createResults();
		res.add(XmlValue(doc));
		env.results() = new XmlResults(res);

		if(env.verbose())
			cout << "Document added, name = " << args[1] << endl;
	}
}
void MgResourceDefinitionManager::DeleteResource(
    MgResourceIdentifier* resource, bool strict)
{
    assert(NULL != resource);

    MG_RESOURCE_SERVICE_TRY()

    string resourcePathname;
    MgUtil::WideCharToMultiByte(resource->ToString(), resourcePathname);

    // Set up an XQuery.

    string query;

    if (resource->IsFolder())
    {
        query  = "for $i in collection('";
        query += m_container.getName();
        query += "')";
        query += "/*[starts-with(dbxml:metadata('dbxml:name'),'";
        query += resourcePathname;
        query += "')]";
        query += " order by dbxml:metadata('dbxml:name', $i) descending return $i";
    }
    else
    {
        query  = "collection('";
        query += m_container.getName();
        query += "')";
        query += "/*[dbxml:metadata('dbxml:name')='";
        query += resourcePathname;
        query += "']";
    }

    // Execute the XQuery.

    XmlManager& xmlManager = m_container.getManager();
    XmlQueryContext queryContext = xmlManager.createQueryContext();
    queryContext.setNamespace(MgResourceInfo::sm_metadataPrefix,
        MgResourceInfo::sm_metadataUri);
    XmlResults results = IsTransacted() ?
        xmlManager.query(GetXmlTxn(), query, queryContext, 0) :
        xmlManager.query(query, queryContext, 0);

    if (0 == results.size())
    {
        if (!strict || (IsResourceContentManager() && resource->IsFolder()))
        {
            return;
        }
        else
        {
            m_repositoryMan.ThrowResourceNotFoundException(*resource,
                L"MgResourceDefinitionManager.DeleteResource",
                __LINE__, __WFILE__);
        }
    }

    // Delete the resources.

    MgResourceIdentifier currResource;
    XmlUpdateContext updateContext = xmlManager.createUpdateContext();
    XmlValue xmlValue;

    while (results.next(xmlValue))
    {
        XmlDocument xmlDoc = xmlValue.asDocument();

        currResource.SetResource(MgUtil::MultiByteToWideChar(xmlDoc.getName()));

        if (!currResource.IsRoot())
        {
            DeleteDocument(currResource, xmlDoc, updateContext);
        }
    }

    if (!resource->IsRoot())
    {
        m_repositoryMan.UpdateDateModifiedResourceSet(resource->GetFullPath(true));
    }

    MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgResourceDefinitionManager.DeleteResource")
}
Exemple #10
0
/** 
 * @breif  
 * 		Get the number of nodes in a xml file
 * 
 * @Param container_type
 * 	should be value defined in container_index enum
 * @Param doc
 * 	the document name of xml file
 * @Param node_path
 * 	the xpath path of node to be search
 *
 * @Returns   
 * 		the node number
 */
int bdbXMLInterface::get_node_element_num (container_index container_type, 
		const string *doc, 
		const string *node_path)
{
	string query_string;
	int res = 0;

	if (m_manager == NULL)
	{
		throw XmlException(XmlException::NULL_POINTER, "m_manager", __FILE__, __LINE__);
//                return xml_exception;
	}


	if (container_type >= CONT_IDX_NUM)
	{
		throw XmlException(XmlException::INVALID_VALUE, "contianer_type", __FILE__, __LINE__);
//                return para_error;
	}

	if (doc == NULL)
	{
		query_string += "count(collection('"
			+ container_names[container_type]
			+ ".dbxml')";
	}
	else
	{
		query_string += "count(doc(\"dbxml:/" 
			+ container_names[container_type] 
			+ ".dbxml/" 
			+ *doc 
			+ "\")";
	}

	if (node_path != NULL)
		query_string += *node_path;

	query_string += ")";
	XmlQueryContext context = m_manager->createQueryContext();

	XmlQueryExpression qe;
	XmlResults results;
	try
	{
		qe = m_manager->prepare(query_string, context);
		results = qe.execute(context);
	}
	catch (XmlException &xe)
	{
		debugOut() << "get_node_element_num: " << query_string << endl;
		debugOut() << "get_node_element_num exception: " << xe.what() << endl;
		throw xe;
	}

	XmlValue value;
	results.next(value);
	if (value.isNumber())
		res = (int)value.asNumber();
	else
		res = 0;

	return res;
}
Exemple #11
0
/** 
 * @breif  
 * 	get the node content of a document as a string
 * 
 * @Param container_type
 * 	should be value defined in container_index enum
 * @Param doc
 * 	the document name of xml file
 * @Param node_path
 * 	the xpath path of node to be search
 * @Param res
 * 	output parameter, return the string value of results
 *
 * @Returns   
 * 	return no_error for success
 * 	otherwise an XmlException was throwed
 */
BdRetVal bdbXMLInterface::get_node(container_index container_type, 
		const string *doc, 
		const string *node_path, 
		string &res)
{
	string query_string;

	if (m_manager == NULL)
	{
		throw XmlException(XmlException::NULL_POINTER, "m_manager null", __FILE__, __LINE__);
	}


	if (container_type >= CONT_IDX_NUM)
	{
		throw XmlException(XmlException::INVALID_VALUE, "contianer_type", __FILE__, __LINE__);
	}

	if (doc == NULL)
	{
		query_string += "collection('"
			+ container_names[container_type]
			+ ".dbxml')";
	}
	else
	{
		query_string += "doc(\"dbxml:/" 
			+ container_names[container_type] 
			+ ".dbxml/" 
			+ *doc 
			+ "\")";
	}

	if (node_path != NULL)
		query_string += *node_path;

	XmlQueryContext context = m_manager->createQueryContext();


	XmlQueryExpression qe;
	XmlResults results;
	try
	{
		qe = m_manager->prepare(query_string, context);
		results = qe.execute(context);
	}
	catch (XmlException &xe)
	{
		debugOut() << "get node query string: " << query_string << endl;
		debugOut() << "get_node in prepare xml exception: " << xe.what() << endl;
		throw xe;
	}

	res.clear();
	XmlValue value;
	while (results.next(value))
	{
		res = value.asString();
	}

	return no_error;
}
///////////////////////////////////////////////////////////////////////////////
/// \brief
/// Packages the specified resource.
///
void MgLibraryResourceContentManager::PackageResource(MgResourceIdentifier& resource,
    MgResourcePackageMaker& packageMaker)
{
    ACE_ASSERT(resource.IsFolder());

    MG_RESOURCE_SERVICE_TRY()

    string resourcePathname;
    MgUtil::WideCharToMultiByte(resource.ToString(), resourcePathname);

    // Set up an XQuery.
    XmlManager& xmlMan = m_container.getManager();
    XmlQueryContext queryContext = xmlMan.createQueryContext();
    string query;

    if (m_repositoryMan.m_currUserIsAdmin)
    {
        queryContext.setEvaluationType(XmlQueryContext::Lazy);
        query = "collection('";
    }
    else
    {
        queryContext.setEvaluationType(XmlQueryContext::Eager);
        query = "for $i in collection('";
    }

    query += m_container.getName();
    query += "')";
    query += "/*[starts-with(dbxml:metadata('dbxml:name'),'";
    query += resourcePathname;

    if (m_repositoryMan.m_currUserIsAdmin)
    {
        query += "')]";
    }
    else
    {
        query += "')] order by dbxml:metadata('dbxml:name', $i) return $i";
    }

    // Execute the XQuery.
    XmlResults results = IsTransacted() ?
        xmlMan.query(GetXmlTxn(), query, queryContext, 0) :
        xmlMan.query(query, queryContext, 0);

    MgLibraryRepositoryManager& libraryRepositoryMan = (MgLibraryRepositoryManager&)m_repositoryMan;
    MgResourceDataFileManager* dataFileMan = libraryRepositoryMan.GetResourceDataFileManager();
    ACE_ASSERT(NULL != dataFileMan);
    MgResourceDataStreamManager* dataStreamMan = libraryRepositoryMan.GetResourceDataStreamManager();
    ACE_ASSERT(NULL != dataStreamMan);

    // Get the resources
    MgResourceIdentifier currResource;
    XmlValue xmlValue;

    while (results.next(xmlValue))
    {
        // Note that the permission checks were already done at the time we
        // packaged the resource headers.
        const XmlDocument& xmlDoc = xmlValue.asDocument();
        currResource.SetResource(MgUtil::MultiByteToWideChar(xmlDoc.getName()));

        // Package the resource content.
        if (!packageMaker.PackageResourceContent(currResource, xmlDoc))
        {
            // The current user has no read permission to this resource.
            continue;
        }

        // Skip packaging resource data if there is no resource tag.
        XmlValue tagValue;

        if (!xmlDoc.getMetaData(MgResourceInfo::sm_metadataUri,
            MgResourceInfo::sm_metadataNames[MgResourceInfo::Tags], tagValue))
        {
            continue;
        }

        STRING resourceTags;
        MgUtil::MultiByteToWideChar(tagValue.asString(), resourceTags);

        // Get the file path if it exists.
        MgTagManager tagMan(resourceTags);
        STRING filePath;
        MgTagInfo filePathTag;

        if (tagMan.GetTag(MgResourceTag::DataFilePath, filePathTag, false))
        {
            filePath = dataFileMan->GetResourceDataFilePath();
            filePath += filePathTag.GetAttribute(MgTagInfo::TokenValue);
            filePath += L"/";
        }

        // Enumerate the resource data.
        MgTagMap& tagMap = tagMan.GetTagMap();

        for (MgTagMap::const_iterator i = tagMap.begin();
            i != tagMap.end(); ++i)
        {
            CREFSTRING dataName = (*i).first;

            // Skip the reserved tags.
            if (tagMan.IsReservedTag(dataName))
            {
                continue;
            }

            // Get the resource data.
            const MgTagInfo& tagInfo = (*i).second;
            CREFSTRING mimeType = tagInfo.GetAttribute(MgTagInfo::MimeType);
            CREFSTRING dataType = tagInfo.GetAttribute(MgTagInfo::StorageType);
            Ptr<MgByteReader> byteReader;

            if (MgResourceDataType::File == dataType)
            {
                ACE_ASSERT(!filePath.empty());
                STRING pathname = filePath;
                pathname += dataName;

                byteReader = dataFileMan->GetResourceData(pathname, mimeType);
            }
            else if (MgResourceDataType::Stream == dataType)
            {
                string dataKey;
                MgUtil::WideCharToMultiByte(
                    tagInfo.GetAttribute(MgTagInfo::TokenValue), dataKey);

                byteReader = dataStreamMan->GetResourceData(dataKey, dataName,
                    mimeType);
            }
            else if (MgResourceDataType::String == dataType)
            {
                string data;
                MgUtil::WideCharToMultiByte(
                    tagInfo.GetAttribute(MgTagInfo::TokenValue), data);

                Ptr<MgByteSource> byteSource = new MgByteSource(
                    (BYTE_ARRAY_IN)data.c_str(), (INT32)data.length());

                byteSource->SetMimeType(mimeType);
                byteReader = byteSource->GetReader();
            }
            else
            {
                throw new MgInvalidResourceDataTypeException(
                    L"MgLibraryResourceContentManager.PackageResource",
                    __LINE__, __WFILE__, NULL, L"", NULL);
            }

            // Package the resource data.
            packageMaker.PackageResourceData(currResource, byteReader,
                dataName, dataType);
        }
    }

    MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgLibraryResourceContentManager.PackageResource")
}