#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/tree.h>
+#include <unicode/locid.h>
+
#include <unique_ptr.h>
#include <runtime_info.h>
-#include <unicode/locid.h>
-#include <FBaseObject.h>
-#include <FBaseString.h>
#include <FBaseResult.h>
+#include <FBaseSysLog.h>
+#include <FBase_StringConverter.h>
+#include <FBaseColHashMap.h>
+
#include <FIoFile.h>
#include <FIoDirectory.h>
-#include <FSysSystemInfo.h>
-#include <FSys_SettingInfoImpl.h>
-#include <FBaseSysLog.h>
-#include <FAppPkgPackageManager.h>
-#include <FAppPkgPackageInfo.h>
-#include <FBase_StringConverter.h>
#include <FApp_AppInfo.h>
-
-#include "FApp_AppResourceString.h"
+#include <FAppPkgPackageInfo.h>
#include "FAppPkg_PackageManagerImpl.h"
#include "FAppPkg_PackageInfoImpl.h"
+#include "FApp_AppResourceImpl.h"
+#include "FApp_AppResourceString.h"
+
using namespace Tizen::App::Package;
using namespace Tizen::Base;
+using namespace Tizen::Base::Collection;
using namespace Tizen::Io;
-using namespace Tizen::Locales;
-using namespace Tizen::System;
static const char* AR_ROOT_NODE_NAME = "string_table";
static const char* AR_CHILD_NODE_1 = "text";
static const char* AR_ATTRIBUTE = "id";
-static xmlNodePtr gCur = 0;
+struct FreeXmlDoc
+{
+ void operator ()(_xmlDoc* p)
+ {
+ if (p != null)
+ {
+ xmlFreeDoc(p);
+ }
+ }
+};
namespace Tizen { namespace App
{
_AppResourceString::_AppResourceString(void)
: __pDoc(null)
, __pLockOfParser(null)
+ , __pXmlNodeMap(null)
{
}
-
-result
-_AppResourceString::Construct(const Tizen::Locales::Locale& locale)
-{
- return Construct();
-}
-
-
-result
-_AppResourceString::Construct(void)
+_AppResourceString::~_AppResourceString(void)
{
- return Initialize();
+ if (__pDoc != null)
+ {
+ xmlFreeDoc(__pDoc);
+ }
+ if (__pXmlNodeMap)
+ {
+ __pXmlNodeMap->RemoveAll(true);
+ delete __pXmlNodeMap;
+ }
+ delete __pLockOfParser;
}
-result
-_AppResourceString::Construct(const AppId& appId)
+// Exception: E_OUT_OF_MEMORY, E_APP_NOT_INSTALLED, E_SYSTEM
+_AppResourceString*
+_AppResourceString::Get_AppResourceStringN(int type, const Tizen::Base::String& value)
{
- return Initialize(appId);
-}
+ std::unique_ptr< _AppResourceString > pAppResourceString(new (std::nothrow) _AppResourceString);
+ SysTryReturn(NID_APP, pAppResourceString != null, null,
+ E_OUT_OF_MEMORY, "[%s] Unable to allocate memory for _AppResourceString", GetErrorMessage(E_OUT_OF_MEMORY));
-result
-_AppResourceString::Initialize(void)
-{
- result r = E_SUCCESS;
- if (__pLockOfParser == null)
+ String resourceFolder;
+ switch(type)
{
- __pLockOfParser = new (std::nothrow) Tizen::Base::Runtime::Mutex();
- SysTryReturnResult(NID_APP, __pLockOfParser != null, E_OUT_OF_MEMORY, "Failed to initialize resource parser.");
-
- r = __pLockOfParser->Create();
- SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to Create Mutex.", GetErrorMessage(r));
+ case APP_RESOURCE_DEFAULT:
+ case APP_RESOURCE_BY_LIBRARY_NAME:
+ default:
+ resourceFolder = _AppInfo::GetAppRootPath();
+ resourceFolder.Append(L"res/");
+ resourceFolder.Append(value);
+ resourceFolder.Append(L"/");
+ break;
+
+ case APP_RESOURCE_BY_APP_ID:
+ std::unique_ptr< PackageInfo> pPkgInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(value));
+ SysTryReturn(NID_APP, pPkgInfo != null, null,
+ E_APP_NOT_INSTALLED, "[%s] Failed to get the package info", GetErrorMessage(E_APP_NOT_INSTALLED));
+
+ _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo.get());
+ SysTryReturn(NID_APP, pPkgInfoImpl != null, null,
+ E_APP_NOT_INSTALLED, "[%s] Failed to get the package info impl", GetErrorMessage(E_APP_NOT_INSTALLED));
+
+ resourceFolder = pPkgInfoImpl->GetAppRootPath();
+ resourceFolder.Append(L"/res/");
+ break;
}
+ result r = pAppResourceString->Initialize(resourceFolder);
+ SysTryReturn(NID_APP, !IsFailed(r), null,
+ r, "[%s] Failed to initialize AppResourceString", GetErrorMessage(r));
- r = __pLockOfParser->Acquire();
- SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to Acquire Mutex.", GetErrorMessage(r));
-
- r = InitializeStringInfo();
- SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to InitializeStringInfo.", GetErrorMessage(r));
-
- __pLockOfParser->Release();
- return E_SUCCESS;
-
-CATCH:
- delete __pLockOfParser;
- __pLockOfParser = null;
-
- return r;
+ ClearLastResult();
+ return pAppResourceString.release();
}
result
-_AppResourceString::Initialize(const AppId& appId)
+_AppResourceString::Initialize(String& resourceFolder)
{
result r = E_SUCCESS;
if (__pLockOfParser == null)
}
r = __pLockOfParser->Acquire();
- SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to Acquire Mutex.", GetErrorMessage(r));
-
- r = InitializeStringInfo(appId);
- SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to InitializeStringInfo.", GetErrorMessage(r));
+ SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to Acquire Mutex [%s].", GetErrorMessage(r));
+ r = InitializeStringInfo(resourceFolder);
__pLockOfParser->Release();
+
+ SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Failed to InitializeStringInfo.", GetErrorMessage(r));
return E_SUCCESS;
CATCH:
return r;
}
-
-
result
-_AppResourceString::InitializeStringInfo(void)
+_AppResourceString::InitializeStringInfo(String& resourceFolder)
{
- if (__pDoc != null)
- {
- SysLog(NID_APP, "__pDoc is freed to reinitialize.");
- xmlFreeDoc(__pDoc);
- __pDoc = null;
- }
-
char* pValue = null;
int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pValue);
- SysTryReturnResult(NID_APP, ret == 0, E_FAILURE, "[E_SYSTEM] runtime_info_get_value_string returns %d.", ret);
+ SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM, "runtime_info_get_value_string returns %d.", ret);
U_ICU_NAMESPACE::Locale icuLcl(pValue);
-
String language(icuLcl.getISO3Language());
String country(icuLcl.getCountry());
-// SysLog(NID_APP, "res/%ls-%ls.xml", language.GetPointer(), country.GetPointer());
-
String resFilename;
- result r = resFilename.Format(256 * 2 + 10, L"res/%ls-%ls.xml", language.GetPointer(), country.GetPointer());
- SysTryReturn(NID_APP, !IsFailed(r), E_FAILURE, r, "[%s] Failed to format path string", GetErrorMessage(r));
-
- const String& homePath = _AppInfo::GetAppRootPath();
- __pDoc = ParseXmlFile( homePath + resFilename);
+ result r = resFilename.Format(256 * 2 + 10, L"%ls-%ls.xml", language.GetPointer(), country.GetPointer());
+ SysTryReturn(NID_APP, !IsFailed(r), E_SYSTEM, r, "[E_SYSTEM] Failed to format path string [%s]", GetErrorMessage(r));
- // Fall-back
- if (__pDoc == null)
+ if (!resourceFolder.EndsWith(L'/'))
{
- String dirName(L"res/");
- Directory dir;
- DirEnumerator* pDirEnum = null;
- String name;
-
- r = dirName.Insert(homePath, 0);
- SysTryReturn(NID_APP, !IsFailed(r), E_FAILURE, r, "[%s] Failed to insert string.", GetErrorMessage(r));
+ resourceFolder.Append(L'/');
+ }
+ std::unique_ptr< _xmlDoc, FreeXmlDoc > pDoc(ParseXmlFile(resourceFolder + resFilename));
+ if (pDoc == null)
+ {
// open directory
- r = dir.Construct(dirName);
+ Directory dir;
+ r = dir.Construct(resourceFolder);
if (r == E_SUCCESS)
{
// read all directory entries
- pDirEnum = dir.ReadN();
+ DirEnumerator* pDirEnum = dir.ReadN();
if (pDirEnum != null)
{
const String starts = language + L"-";
while (pDirEnum->MoveNext() == E_SUCCESS)
{
// get several properties of each directory entry.
- name = pDirEnum->GetCurrentDirEntry().GetName();
-
- if (name.StartsWith(starts, 0) && name.EndsWith(ends))
+ resFilename = pDirEnum->GetCurrentDirEntry().GetName();
+ if (resFilename.StartsWith(starts, 0) && resFilename.EndsWith(ends))
{
- resFilename = L"res/" + name;
- __pDoc = ParseXmlFile(homePath + resFilename);
+ pDoc.reset(ParseXmlFile(resourceFolder + resFilename));
break;
}
}
}
}
- if (__pDoc == null)
+ if (pDoc == null)
{
- __pDoc = ParseXmlFile(homePath + L"res/eng-GB.xml");
+ pDoc.reset(ParseXmlFile(resourceFolder + L"eng-GB.xml"));
}
- if (__pDoc == null)
+ if (pDoc == null)
{
- __pDoc = ParseXmlFile(homePath + L"res/eng-US.xml");
+ pDoc.reset(ParseXmlFile(resourceFolder + L"eng-US.xml"));
}
- if (__pDoc == null)
+ if (pDoc == null)
{
- __pDoc = ParseXmlFile(homePath + L"res/English.xml");
+ pDoc.reset(ParseXmlFile(resourceFolder + L"English.xml"));
}
- if (__pDoc == null)
- {
- SysLog(NID_APP, "Can't find xml resource file.");
- return E_SUCCESS; //E_FILE_NOT_FOUND;
- }
+ SysTryLogReturn(NID_APP, pDoc != null, E_SUCCESS, "Can't find xml resource file.");
- xmlNodePtr cur = xmlDocGetRootElement(__pDoc);
- SysTryReturnResult(NID_APP, cur != null, E_FAILURE, "Empty document.");
+ xmlNodePtr cur = xmlDocGetRootElement(pDoc.get());
+ SysTryReturnResult(NID_APP, cur != null, E_SYSTEM, "Empty document.");
- if (xmlStrcmp(cur->name, (const xmlChar*) AR_ROOT_NODE_NAME))
- {
- SysLogException(NID_APP, E_FAILURE, "[E_FAILURE] Document root node is not <string_table>.");
- return E_FAILURE;
- }
+ ret = xmlStrcmp(cur->name, (const xmlChar*) AR_ROOT_NODE_NAME);
+ SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM, "Document root node is not <string_table>.");
- gCur = cur;
+ std::unique_ptr< HashMap, AllElementsDeleter > pXmlNodeMap (new (std::nothrow) HashMap());
+ SysTryReturnResult(NID_APP, pXmlNodeMap != null, E_OUT_OF_MEMORY, " Memory allocation failed.");
- return E_SUCCESS;
-}
-
-result
-_AppResourceString::InitializeStringInfo(const AppId& appId)
-{
- if (__pDoc != null)
- {
- SysLog(NID_APP, "__pDoc is freed to reinitialize.");
- xmlFreeDoc(__pDoc);
- __pDoc = null;
- }
-
- char* pValue = null;
- int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pValue);
- SysTryReturnResult(NID_APP, ret == 0, E_FAILURE, "[E_SYSTEM] runtime_info_get_value_string returns %d.", ret);
-
-
- U_ICU_NAMESPACE::Locale icuLcl(pValue);
-
- String language(icuLcl.getISO3Language());
- String country(icuLcl.getCountry());
+ r = pXmlNodeMap->Construct();
+ SysTryReturnResult(NID_APP, !IsFailed(r), E_SYSTEM, "Unable to construct xml node map [%s]", GetErrorMessage(r));
-// SysLog(NID_APP, "res/%ls-%ls.xml", language.GetPointer(), country.GetPointer());
-
- String resFilename;
- result r = resFilename.Format(256 * 2 + 10, L"/res/%ls-%ls.xml", language.GetPointer(), country.GetPointer());
- SysTryReturn(NID_APP, !IsFailed(r), E_FAILURE, r, "[%s] Failed to format path string", GetErrorMessage(r));
-
- PackageInfo* pPkgInfo = null;
- pPkgInfo = _PackageManagerImpl::GetInstance()->GetPackageInfoN(appId);
- SysTryReturnResult(NID_APP, pPkgInfo != null, E_APP_NOT_INSTALLED, "Failed to get the package info");
-
- _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo);
- SysTryReturnResult(NID_APP, pPkgInfoImpl != null, E_APP_NOT_INSTALLED, "Failed to get the package info impl");
-
- const Tizen::Base::String& homePath = pPkgInfoImpl->GetAppRootPath();
-
- __pDoc = ParseXmlFile( homePath + resFilename);
-
- // Fall-back
- if (__pDoc == null)
+ xmlChar* pxmlValue = null;
+ cur = cur->xmlChildrenNode;
+ while (cur != null)
{
- String dirName(L"/res/");
- Directory dir;
- DirEnumerator* pDirEnum = null;
- String name;
-
- r = dirName.Insert(homePath, 0);
- SysTryReturn(NID_APP, !IsFailed(r), E_FAILURE, r, "[%s] Failed to insert string.", GetErrorMessage(r));
-
- // open directory
- r = dir.Construct(dirName);
- if (r == E_SUCCESS)
+ if ((!xmlStrcmp(cur->name, (const xmlChar*) AR_CHILD_NODE_1)))
{
- // read all directory entries
- pDirEnum = dir.ReadN();
- if (pDirEnum != null)
+ pxmlValue = xmlGetProp(cur, (const xmlChar*) AR_ATTRIBUTE);
+ if (cur->type == (xmlElementType) XML_ELEMENT_NODE)
{
- const String starts = language + L"-";
- const String ends = L".xml";
+ xmlChar* pContent = xmlNodeListGetString( pDoc.get(), cur->xmlChildrenNode, 1);
- // loop through all directory entries
- while (pDirEnum->MoveNext() == E_SUCCESS)
- {
- // get several properties of each directory entry.
- name = pDirEnum->GetCurrentDirEntry().GetName();
-
- if (name.StartsWith(starts, 0) && name.EndsWith(ends))
- {
- resFilename = L"/res/" + name;
- __pDoc = ParseXmlFile(homePath + resFilename);
- break;
- }
- }
- // Delete enumerator
- delete pDirEnum;
- }
- }
- }
+ std::unique_ptr< String > pKey(new (std::nothrow) String);
+ SysTryReturnResult(NID_APP, pKey != null, E_OUT_OF_MEMORY, " Memory allocation failed.");
+ Tizen::Base::Utility::StringUtil::Utf8ToString((char*) pxmlValue, *pKey);
- if (__pDoc == null)
- {
- __pDoc = ParseXmlFile(homePath + L"/res/eng-GB.xml");
- }
+ std::unique_ptr< String > pValue(new (std::nothrow) String);
+ SysTryReturnResult(NID_APP, pValue != null, E_OUT_OF_MEMORY, " Memory allocation failed.");
+ Tizen::Base::Utility::StringUtil::Utf8ToString((char*) pContent, *pValue);
- if (__pDoc == null)
- {
- __pDoc = ParseXmlFile(homePath + L"/res/eng-US.xml");
- }
+ pXmlNodeMap->Add(*pKey, *pValue);
+ pKey.release();
+ pValue.release();
+ }
- if (__pDoc == null)
- {
- __pDoc = ParseXmlFile(homePath + L"/res/English.xml");
+ }
+ cur = cur->next;
}
- if (__pDoc == null)
+ if (__pDoc != null)
{
- SysLog(NID_APP, "Can't find xml resource file.");
- return E_DATA_NOT_FOUND;
+ xmlFreeDoc(__pDoc);
+ __pDoc = null;
}
- xmlNodePtr cur = xmlDocGetRootElement(__pDoc);
- SysTryReturnResult(NID_APP, cur != null, E_FAILURE, "Empty document.");
-
- if (xmlStrcmp(cur->name, (const xmlChar*) AR_ROOT_NODE_NAME))
+ if (__pXmlNodeMap)
{
- SysLogException(NID_APP, E_FAILURE, "[E_FAILURE] Document root node is not <string_table>.");
- return E_FAILURE;
+ __pXmlNodeMap->RemoveAll(true);
+ delete __pXmlNodeMap;
}
- gCur = cur;
-
- delete pPkgInfo;
+ __pDoc = pDoc.release();
+ __pXmlNodeMap = pXmlNodeMap.release();
return E_SUCCESS;
}
xmlDocPtr
_AppResourceString::ParseXmlFile(const String& path)
{
- if (File::IsFileExist(path) == false )
- {
- SysLog(NID_APP, "'%ls' isn't exist.", path.GetPointer());
- return null;
- }
-
- std::unique_ptr<char[]> pBuf(_StringConverter::CopyToCharArrayN(path));
- xmlDocPtr docPtr = xmlParseFile(pBuf.get());
-
- if (docPtr == null)
- {
- SysLog(NID_APP, "failed to parse resource file(%ls)", path.GetPointer());
- return null;
- }
-
- SysLog(NID_APP, "'%ls' is parsed successfully.", path.GetPointer());
- return docPtr;
-}
-
-
-_AppResourceString::~_AppResourceString(void)
-{
- if (__pDoc != null)
+ xmlDocPtr pDoc = null;
+ if (File::IsFileExist(path))
{
- xmlFreeDoc(__pDoc);
+ std::unique_ptr<char[]> pBuf(_StringConverter::CopyToCharArrayN(path));
+ pDoc = xmlParseFile(pBuf.get());
}
- delete __pLockOfParser;
+ return pDoc;
}
result
_AppResourceString::GetString(const String resourceId, String& loadedString)
{
- SysTryReturnResult(NID_APP, __pDoc != null, E_INVALID_STATE, "Can't find xml resource file.");
-
#if defined(ENABLE_XPATH)
+ SysTryReturnResult(NID_APP, __pDoc != null, E_FAILURE, "Can't find xml resource file.");
+
xmlXPathContextPtr __pXpathCtx = null;
xmlXPathObjectPtr __pXpathObj = null;
return E_SUCCESS;
#else
- xmlNodePtr cur = null;
- xmlChar* pValue = null;
- xmlChar* pId = null;
-
SysTryReturnResult(NID_APP, !resourceId.IsEmpty(), E_INVALID_ARG, "Wrong resource Id.");
- SysTryReturnResult(NID_APP, gCur != null && __pDoc != null, E_INVALID_STATE,
- "Application string resource was not initialized.");
- SysTryReturnResult(NID_APP, __pLockOfParser != null, E_INVALID_STATE, "__pLockOfParser was not initialized.");
+ SysTryReturnResult(NID_APP, __pDoc != null, E_FAILURE, "Application string resource was not initialized.");
+ SysTryReturnResult(NID_APP, __pLockOfParser != null, E_FAILURE, "__pLockOfParser was not initialized.");
result r = __pLockOfParser->Acquire();
- SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Failed to Acquire Mutex.", GetErrorMessage(r));
+ SysTryReturnResult(NID_APP, !IsFailed(r), E_FAILURE, "Failed to Acquire Mutex [%s].", GetErrorMessage(r));
- pId = (xmlChar*) (_StringConverter::CopyToCharArrayN(resourceId));
- cur = gCur;
- cur = cur->xmlChildrenNode;
- while (cur != null)
+ String* pkeyValue = static_cast< String* > (__pXmlNodeMap->GetValue(resourceId));
+ r = E_FAILURE; //GetLastResult();
+ if (pkeyValue)
{
- if ((!xmlStrcmp(cur->name, (const xmlChar*) AR_CHILD_NODE_1)))
+ loadedString = *pkeyValue;
+ if (HasSpecialString(loadedString))
{
- pValue = xmlGetProp(cur, (const xmlChar*) AR_ATTRIBUTE);
- if (!xmlStrcmp(pValue, (const xmlChar*) pId))
- {
- xmlChar* pContent = xmlNodeListGetString( __pDoc, cur->xmlChildrenNode, 1);
- SysLog(NID_APP, "xml content=%s", pContent);
- loadedString = (char*) (pContent);
-
- if (HasSpecialString(loadedString))
- {
- String rawString(loadedString);
- ConvertToCstyleString(rawString, loadedString);
- }
-
- if (pContent)
- {
- xmlFree(pContent);
- }
-
- if (pValue)
- {
- xmlFree(pValue);
- }
-
- if (pId)
- {
- delete[] (char*) pId;
- }
-
- __pLockOfParser->Release();
- return E_SUCCESS;
- }
- if (pValue)
- {
- xmlFree(pValue);
- }
+ String rawString(loadedString);
+ ConvertToCstyleString(rawString, loadedString);
}
- cur = cur->next;
- }
-
- if (pId)
- {
- delete[] (char*) pId;
+ r = E_SUCCESS;
}
__pLockOfParser->Release();
-
- return E_FAILURE;
+ return r;
#endif
}
_AppResourceString::HasSpecialString(const String& resourceStr)
{
int foundIndex = 0;
-
return((resourceStr.IndexOf("<", 0, foundIndex) == E_SUCCESS)
|| (resourceStr.IndexOf("&", 0, foundIndex) == E_SUCCESS)
|| (resourceStr.IndexOf(">", 0, foundIndex) == E_SUCCESS)
result
_AppResourceString::ConvertToCstyleString(const String& resourceStr, String& convertedStr)
{
- result r = E_SUCCESS;
-
- int i = 0;
- int j = 0;
- int len = 0;
-
SysTryReturnResult(NID_APP, resourceStr.GetLength() > 0, E_INVALID_ARG, "resource string must be greater than 0.");
std::unique_ptr<char[]> pBuffer(_StringConverter::CopyToCharArrayN(resourceStr));
- // len = resourceStr.GetLength(); comment out because GetLength() returns UTF8 length.
SysTryReturnResult(NID_APP, pBuffer != null, E_OUT_OF_MEMORY, "Memory allocation failure.");
- len = strlen(pBuffer.get());// len = String_length((MString)pBuffer);
-
+ int i = 0;
+ int j = 0;
+ int len = strlen(pBuffer.get());// len = String_length((MString)pBuffer);
while (i < len)
{
if (pBuffer[i] == '\\')
}
convertedStr = pBuffer.get();
-
- return r;
+ return E_SUCCESS;
}