123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- #include <kopano/platform.h>
- #include <memory>
- #include <new>
- #include <utility>
- #include <kopano/tie.hpp>
- #include "ECDatabase.h"
- #include <mapidefs.h>
- #include <mapitags.h>
- #include <kopano/EMSAbTag.h>
- #include "ECSessionManager.h"
- #include "ECConvenientDepthABObjectTable.h"
- #include "ECSession.h"
- #include "ECMAPI.h"
- #include <kopano/stringutil.h>
- using namespace KCHL;
- namespace KC {
- ECConvenientDepthABObjectTable::ECConvenientDepthABObjectTable(ECSession *lpSession, unsigned int ulABId, unsigned int ulABType, unsigned int ulABParentId, unsigned int ulABParentType, unsigned int ulFlags, const ECLocale &locale) : ECABObjectTable(lpSession, ulABId, ulABType, ulABParentId, ulABParentType, ulFlags, locale) {
- m_lpfnQueryRowData = ECConvenientDepthABObjectTable::QueryRowData;
- /* We require the details to construct the PR_EMS_AB_HIERARCHY_PATH */
- m_ulUserManagementFlags &= ~USERMANAGEMENT_IDS_ONLY;
- }
- ECRESULT ECConvenientDepthABObjectTable::Create(ECSession *lpSession,
- unsigned int ulABId, unsigned int ulABType, unsigned int ulABParentId,
- unsigned int ulABParentType, unsigned int ulFlags, const ECLocale &locale,
- ECABObjectTable **lppTable)
- {
- *lppTable = new(std::nothrow) ECConvenientDepthABObjectTable(lpSession,
- ulABId, ulABType, ulABParentId, ulABParentType, ulFlags,
- locale);
- if (*lppTable == nullptr)
- return KCERR_NOT_ENOUGH_MEMORY;
- (*lppTable)->AddRef();
- return erSuccess;
- }
- /*
- * We override the standard QueryRowData call so that we can correctly generate PR_DEPTH and PR_EMS_AB_HIERARCHY_PARENT. Since this is
- * dependent on data which is not available for ECUserManagement, we have to do those properties here.
- */
- ECRESULT ECConvenientDepthABObjectTable::QueryRowData(ECGenericObjectTable *lpGenTable, struct soap *soap, ECSession *lpSession, ECObjectTableList* lpRowList, struct propTagArray *lpsPropTagArray, void* lpObjectData, struct rowSet **lppRowSet, bool bTableData,bool bTableLimit)
- {
- ECRESULT er;
- unsigned int n = 0;
- struct propVal *lpProp = NULL;
- auto lpThis = static_cast<ECConvenientDepthABObjectTable *>(lpGenTable);
-
- er = ECABObjectTable::QueryRowData(lpThis, soap, lpSession, lpRowList, lpsPropTagArray, lpObjectData, lppRowSet, bTableData, bTableLimit);
- if(er != erSuccess)
- return er;
- // Insert the PR_DEPTH for all the rows since the row engine has no knowledge of depth
- for (const auto &row : *lpRowList) {
- lpProp = FindProp(&(*lppRowSet)->__ptr[n], PROP_TAG(PT_ERROR, PROP_ID(PR_DEPTH)));
-
- if(lpProp) {
- lpProp->Value.ul = lpThis->m_mapDepth[row.ulObjId];
- lpProp->ulPropTag = PR_DEPTH;
- lpProp->__union = SOAP_UNION_propValData_ul;
- }
-
- lpProp = FindProp(&(*lppRowSet)->__ptr[n], PROP_TAG(PT_ERROR, PROP_ID(PR_EMS_AB_HIERARCHY_PATH)));
-
- if(lpProp) {
- lpProp->Value.lpszA = s_strcpy(soap, lpThis->m_mapPath[row.ulObjId].c_str());
- lpProp->ulPropTag = PR_EMS_AB_HIERARCHY_PATH;
- lpProp->__union = SOAP_UNION_propValData_lpszA;
- }
- ++n;
- }
- return erSuccess;
- }
- /*
- * Loads an entire multi-depth hierarchy table recursively.
- */
- ECRESULT ECConvenientDepthABObjectTable::Load()
- {
- auto lpODAB = static_cast<ECODAB *>(m_lpObjectData);
- sObjectTableKey sRowItem;
- std::list<CONTAINERINFO> lstObjects;
- CONTAINERINFO root;
- if (lpODAB->ulABType != MAPI_ABCONT)
- return KCERR_INVALID_PARAMETER;
- // Load this container
- root.ulId = lpODAB->ulABParentId;
- root.ulDepth = -1; // Our children are at depth 0, so the root object is depth -1. Note that this object is not actually added as a row in the end.
- root.strPath = "";
- lstObjects.push_back(std::move(root));
- // 'Recursively' loop through all our containers and add each of those children to our object list
- for (const auto &obj : lstObjects) {
- std::unique_ptr<std::list<localobjectdetails_t> > lpSubObjects;
- if (LoadHierarchyContainer(obj.ulId, 0, &unique_tie(lpSubObjects)) != erSuccess)
- continue;
- for (const auto &subobj : *lpSubObjects) {
- CONTAINERINFO folder;
- folder.ulId = subobj.ulId;
- folder.ulDepth = obj.ulDepth + 1;
- folder.strPath = obj.strPath + "/" + subobj.GetPropString(OB_PROP_S_LOGIN);
- lstObjects.push_back(std::move(folder));
- }
- }
- // Add all the rows into the row engine, except the root object (the folder itself does not show in its own hierarchy table)
- for (const auto &obj : lstObjects) {
- if (obj.ulId == lpODAB->ulABParentId)
- continue;
- m_mapDepth[obj.ulId] = obj.ulDepth;
- m_mapPath[obj.ulId] = obj.strPath;
- UpdateRow(ECKeyTable::TABLE_ROW_ADD, obj.ulId, 0);
- }
- return erSuccess;
- }
- } /* namespace */
|