/********************************************************************** ********************************NOTICE********************************* *********************************************************************** ** This source code is private property of Metaware Inc. Permission ** ** to Use / Copy / Distribute / Modify this source code , in any ** ** manner, is strictly prohibited. ** ** ** ** Copyright 1994. Metaware Inc. ** *********************************************************************** *********************************************************************** ***********************************************************************/ #include #include #include #include "Nc2.h" #include "Nc2Priva.h" #include "NCenDefs.h" #include "NCenAdmn.h" #include "DCenDBas.h" #include "SNdIdNmI.h" #include "SNodeIds.h" /************************************************************************** *************************************************************************** ** ** ** Name: : c2_getBranchDisplayInfo ** ** ** ** Purpose: : retrieves information for a branch's sub branches. ** ** ** ** Parameters: : > char *ParentBranchId ** ** < cenint *NodeCount ** ** < C2_NODE_INFO **ChildBranchInfo ** ** ** ** Return Values : For successful call, SUCCESS is returned. ** ** For error, a return_status is returned. ** ** ** ** Description : c2_getBranchDisplayInfo retrieves a filled ** ** C2_NODE_INFO structure for every child branch ** ** c2_getBranchDisplayInfo will allocate the memory ** ** needed for the structures; it is up the user to ** ** free it. The ParentBranchId argument may be a ** ** node Id or NULL. ParentBranchId set to NULL will ** ** retrieve top level branches. ParentBranchId set ** ** to a node ID will retrieve that node's child ** ** branch information. ** ** ** ** Date: : 01/16/97 ** ** ** ** Author: : Sondra R. Hurley ** ** ** *************************************************************************** **************************************************************************/ cenint DLL_STRING c2_getBranchDisplayInfo (char *ParentBranchId, cenint *NodeCount, C2_NODE_INFO **ChildBranchInfo) { cenint LocalStatus = 0; cenint i = 0; cenint DoesExist = 0; cenint HasPermission = 0; cenint node_family_info = 0; char *node_status = NULL; char *tmp_node_id = NULL; cenint seq_num = 0; cenint dash_cnt = 0; cenint id_len = 0; cenint j = 0; /***> Are they asking for 'From the Top' OR Just this node's children branches <***/ if (ParentBranchId == NULL) /* From the Top */ { if (!node_id_name_info_list_new()) return (NULL_NODE_ID_NAME_LIST_PTR); LocalStatus = DB_GetNodesTop(GetRoleID()); if (c2_processStat(LocalStatus, NO) != SUCCESS) return (LocalStatus); /***> Prepare to Fetch the information <***/ *NodeCount = node_id_name_info_list_get_element_count(); if (*NodeCount == 0) return(SUCCESS); *ChildBranchInfo = (C2_NODE_INFO *)calloc((int)*NodeCount, sizeof(C2_NODE_INFO)); node_id_name_info_element_rewind(); /***> Fetch the information using Structure Utilities <***/ for (i = 0; i < *NodeCount; i++) { strcpy ((*ChildBranchInfo)[i].Title, (char *)node_id_name_info_element_get_node_name()); strcpy ((*ChildBranchInfo)[i].BranchId, (char *)node_id_name_info_element_get_node_id()); node_status = (char *)ckstrdup(node_id_name_info_element_get_status()); node_family_info = node_id_name_info_element_get_family_info(); node_id_name_info_element_get_next(); /***> Fill hasSubBranches and hasItems <***/ if ((node_family_info == HAS_SUBNODES) || (node_family_info == HAS_OBJECTS_AND_SUBNODES)) { (*ChildBranchInfo)[i].hasSubBranches = TRUE; } else { (*ChildBranchInfo)[i].hasSubBranches = FALSE; } if ((node_family_info == HAS_OBJECTS) || (node_family_info == HAS_OBJECTS_AND_SUBNODES)) { (*ChildBranchInfo)[i].hasItems = TRUE; } else { (*ChildBranchInfo)[i].hasItems = FALSE; } /***> Fill isVaulted <***/ if (!ckstrcmp(node_status, "Non-Vault")) { (*ChildBranchInfo)[i].isVaulted = FALSE; } else { (*ChildBranchInfo)[i].isVaulted = TRUE; } free(node_status); /***> Fetch the Node Item ID <***/ LocalStatus = c2_getNodeItemId ((*ChildBranchInfo)[i].BranchId, &(*ChildBranchInfo)[i].branchItemId); if (LocalStatus != SUCCESS) { return (LocalStatus); } /***> Is this a Link <***/ (*ChildBranchInfo)[i].isLink = DB_IsNodeABranchLink(&LocalStatus, (*ChildBranchInfo)[i].BranchId); if (c2_processStat(LocalStatus, NO) != SUCCESS) return (LocalStatus); } } else /* Child Branches */ { /***> Parse out just the node_id for use in the next few calls <***/ /* They can pass in just the node_id OR the node_id% (for this branch and all of it's subs) OR the node_id__ (for this branch and it's immediate subs) */ tmp_node_id = (char *)calloc(C2_NODE_ID_LEN, sizeof (char)); id_len = ckstrlen(ParentBranchId); if ((ParentBranchId[strlen(ParentBranchId)-1] == '_') || (ParentBranchId[strlen(ParentBranchId)-1] == '%')) { for (j = 0; j < id_len; j++) { if ((ParentBranchId[j] == '_') || (ParentBranchId[j] == '%')) dash_cnt++; } ckstrncpy (tmp_node_id, ParentBranchId, (id_len - dash_cnt)); } else { ckstrcpy (tmp_node_id, ParentBranchId); } /***> Does node exist? <***/ LocalStatus = c2_node_exists(tmp_node_id, &DoesExist); if (c2_processStat(LocalStatus, NO) != SUCCESS) { free(tmp_node_id); return (LocalStatus); } if (DoesExist == FALSE) { free(tmp_node_id); return (INVALID_NODE); } /***> Does User have permission to view? <***/ LocalStatus = c2_checkPermission(tmp_node_id, VIEW_ITEM, &HasPermission); if (LocalStatus != SUCCESS) { free(tmp_node_id); return(LocalStatus); } if (HasPermission == FALSE) { free(tmp_node_id); return(OPERATION_NOT_ALLOWED); } free(tmp_node_id); /***> Prepare to Fetch the information <***/ if (!node_id_name_info_list_new()) return (NULL_DISTLIST_LIST_PTR); LocalStatus = DB_GetNodesFamilyByHierarchy (GetRoleID(), ParentBranchId); if (c2_processStat(LocalStatus, NO) != SUCCESS) return (LocalStatus); /***> Fetch the information using Structure Utilities <***/ *NodeCount = node_id_name_info_list_get_element_count(); if (*NodeCount == 0) return(SUCCESS); *ChildBranchInfo = (C2_NODE_INFO *)calloc((int)*NodeCount, sizeof(C2_NODE_INFO)); node_id_name_info_element_rewind(); for (i = 0; i < *NodeCount; i++) { strcpy ((*ChildBranchInfo)[i].Title, (char *)node_id_name_info_element_get_node_name()); strcpy ((*ChildBranchInfo)[i].BranchId, (char *)node_id_name_info_element_get_node_id()); node_status = (char *)ckstrdup(node_id_name_info_element_get_status()); node_family_info = node_id_name_info_element_get_family_info(); seq_num = node_id_name_info_element_get_seq_num(); node_id_name_info_element_get_next(); /***> Fill hasSubBranches and hasItems <***/ if ((node_family_info == HAS_SUBNODES) || (node_family_info == HAS_OBJECTS_AND_SUBNODES)) { (*ChildBranchInfo)[i].hasSubBranches = TRUE; } else { (*ChildBranchInfo)[i].hasSubBranches = FALSE; } if ((node_family_info == HAS_OBJECTS) || (node_family_info == HAS_OBJECTS_AND_SUBNODES)) { (*ChildBranchInfo)[i].hasItems = TRUE; } else { (*ChildBranchInfo)[i].hasItems = FALSE; } /***> Fill isVaulted <***/ if (!ckstrcmp(node_status, "Non-Vault")) { (*ChildBranchInfo)[i].isVaulted = FALSE; } else { (*ChildBranchInfo)[i].isVaulted = TRUE; } free(node_status); /***> Fetch the Node Item ID <***/ LocalStatus = c2_getNodeItemId ((*ChildBranchInfo)[i].BranchId, &(*ChildBranchInfo)[i].branchItemId); if (LocalStatus != SUCCESS) { return (LocalStatus); } /***> Is this a Link <***/ (*ChildBranchInfo)[i].isLink = DB_IsNodeABranchLink(&LocalStatus, (*ChildBranchInfo)[i].BranchId); if (c2_processStat(LocalStatus, NO) != SUCCESS) return (LocalStatus); /* printf ("C2: %l3d ID=%s NAME=%50s S#=%d V=%ld L=%ld SB=%ld It=%ld\n", (long)i, (*ChildBranchInfo)[i].BranchId, (*ChildBranchInfo)[i].Title, (long)seq_num, (long)(*ChildBranchInfo)[i].isVaulted, (long)(*ChildBranchInfo)[i].isLink, (long)(*ChildBranchInfo)[i].hasSubBranches, (long)(*ChildBranchInfo)[i].hasItems); */ } /* end of NodeCount for loop */ } /* end of FromtheTop if statement */ return (SUCCESS); } /* end of function c2_getBranchDisplayInfo() */ /************************************************************************** *************************************************************************** ** ** ** Name: : c2_reorderBranches ** ** ** ** Purpose: : Modifies the Branch Display Sequence. ** ** ** ** Parameters: : > char **BranchIds ** ** > cenint BranchCount ** ** ** ** Return Values : For successful call, C2_SUCCESS is returned. ** ** For error, a return_status is returned. ** ** ** ** Description : c2_reorderBranches modifies the Branch Display ** ** Sequence to the sequence passed in by the ** ** user. This routine checks for duplicate branch ** ** Ids, branches that are not 'siblings' and ** ** invalid branch ids. If all of the sub-branches ** ** are not passed in by the user, the remaining ** ** branches will be appended to the end of the ** ** sequence in their branch IDs' alphabetic order. ** ** ** ** Date: : 01/28/98 ** ** ** ** Author: : Sondra R. Hurley ** ** ** *************************************************************************** **************************************************************************/ cenint DLL_STRING c2_reorderBranches (char **BranchIds, cenint BranchCount) { cenint LocalStatus = 0; cenint i = 0; cenint j = 0; cenint HasPerm = 0; char *parent_node_id = NULL; list_ptr ListPtr; cenint node_len = 0; cenint DoesExist = 0; cenint ChildCount = 0; cenint ReturnCount = 0; char **ReturnedNames = NULL; char **ReturnedIds = NULL; char **ChildIds = NULL; cenint *IsThere = NULL; char **AllBranches = NULL; if (BranchCount <= 0) return (NULL_C2_NODE_COUNT); if (BranchIds == NULL) return (NULL_BRANCH_PTR); /****> Check Permission (with Parent Node) <****/ node_len = ckstrlen(BranchIds[0]); parent_node_id = (char *)calloc((int)node_len + 1, sizeof(char)); strncpy (parent_node_id, BranchIds[0], (node_len - 2)); parent_node_id[(node_len - 1)] = '\0'; LocalStatus = c2_checkPermission(parent_node_id, CRE_MOD_LINK_NODE, &HasPerm); if (LocalStatus != C2_SUCCESS) { ckfreeAndSetToNull(&parent_node_id); return (LocalStatus); } if (HasPerm == FALSE) { ckfreeAndSetToNull(&parent_node_id); return (OPERATION_NOT_ALLOWED); } /****> Are there any duplicate Branches? <****/ for (i = 0; i < BranchCount; i++) { for (j = 0; j < BranchCount; j++) { if (i != j) { if (strcmp(BranchIds[i], BranchIds[j]) == 0) { ckfreeAndSetToNull(&parent_node_id); return (INVALID_NODE); } } } } /****> Are all Branches at the same level? <****/ for (i = 0; i < BranchCount; i++) { if (ckstrlen(BranchIds[i]) != node_len) { ckfreeAndSetToNull(&parent_node_id); return (INVALID_NODE); /* not at same level */ } if (ckstrncmp(BranchIds[i], parent_node_id, (node_len - 2) != 0)) { ckfreeAndSetToNull(&parent_node_id); return (INVALID_NODE); /* not same parent */ } /****> Do all Branches exist? <****/ LocalStatus = c2_node_exists (BranchIds[i], &DoesExist); if (LocalStatus != C2_SUCCESS) { ckfreeAndSetToNull(&parent_node_id); return (LocalStatus); } if (DoesExist == FALSE) { ckfreeAndSetToNull(&parent_node_id); return (BRANCH_NOT_EXIST); } } /****> Did they send ALL of the branches? <****/ LocalStatus = c2_getNodesFamilyByHierarchy (parent_node_id, &ReturnCount, &ReturnedNames, &ReturnedIds); if (LocalStatus != C2_SUCCESS) { ckfreeAndSetToNull(&parent_node_id); return (LocalStatus); } ckfreeAndSetToNull(&parent_node_id); /****> c2_getNodesFamilyByHierarchy returns the parent_node_id in the zero position - we don't want it <****/ ChildCount = ReturnCount - 1; IsThere = (cenint *)calloc((int)ChildCount, sizeof(cenint)); ChildIds = (char **)calloc((int)ChildCount, sizeof(char *)); /* Don't need the Names; clear the indicator array */ for (j = 0; j < ReturnCount; j++) { if (j != 0) ChildIds[(j - 1)] = ckstrdup(ReturnedIds[j]); IsThere[j] = 0; ckfreeAndSetToNull(&ReturnedNames[j]); ckfreeAndSetToNull(&ReturnedIds[j]); } for (i = 0; i < ChildCount; i++) { for (j = 0; j < BranchCount; j++) { if (ckstrcmp(ChildIds[i], BranchIds[j]) == 0) IsThere[i] = 1; } } /****> Prepare and Stuff the local array <****/ AllBranches = (char **)calloc((int)(ChildCount), sizeof(char *)); for (j = 0; j < BranchCount; j++) { AllBranches[j] = ckstrdup (BranchIds[j]); } for (i = 0; i < ChildCount; i++) { if (IsThere[i] == 0) { AllBranches[j] = ckstrdup (ChildIds[i]); j++; ckfreeAndSetToNull(&ChildIds[i]); } } ckfree(ChildIds); ckfree(IsThere); /****> Prepare and Stuff the Structure Utilities List <****/ node_ids_list_new(); node_ids_list_select(ListPtr); for (i = 0; i < ChildCount; i++) { node_ids_element_set(AllBranches[i]); } for (i = 0; i < ChildCount; i++) { ckfreeAndSetToNull(&AllBranches[i]); } ckfree(AllBranches); node_ids_element_rewind(); node_ids_list_select(ListPtr); /****> Call the DB <****/ LocalStatus = DB_ModifyBranchSequence(); if (c2_processStat(LocalStatus, YES)) return (LocalStatus); c2_commit(); node_ids_list_select(ListPtr); node_ids_list_free(); return (C2_SUCCESS); } /* end of c2_reorderBranches */ /************************************************************************** *************************************************************************** ** ** ** Name: : c2_copyBranch ** ** ** ** Purpose: : Copies a Branch ** ** ** ** Parameters: ** ** Type Parameter Usage ** ** ------ ----------------------- --------------------------------------** ** >char *sourceBranch Branch where the user is copying from ** ** >char *destinationBranch Parent branch for the new branch ** ** >cenint copyItems Flag: Do we copy the items also? ** ** 1=Yes ** ** >cenint copyLatestVersions Flag: Copy latest version only? 1=Yes ** ** Ignored if the previous parameter ** ** was '0'. ** ** >cenint overrideUniqueness Flag: If there are unique attribute ** ** constraints on the items, should ** ** they be ignored? 1=Yes. ** ** >cenint maintainBranchLinks Flag: If there are branch-branch ** ** links, should they be maintained? ** ** 1=Yes. ** ** >cenint maintainItemLinks Flag: If there are Item-Branch links, ** ** should they be maintained? If 1, ** ** They remain links. If 0 they are ** ** copied. ** ** >cenint maintainRolePermissions Flag: If there are branch-branch ** ** links, should they be maintained? ** ** 1=Yes ** ** >cenint maintainRoleLockouts Flag: If there sub-branches where ** ** roles are locked-out, should that ** ** behavior be maintained? 1=Yes ** ** >cenint maintainCustomDisplay Flag: If there is a custom display ** ** format defined for the sourceBranch,** ** should the destination branch share ** ** that display preference? 1=Yes ** ** >cenint copyLocalClasses Flag: If there are local classes ** ** associated with the sourceBranch, ** ** should the destination branch share ** ** those classes? 1=Yes ** ** >char *newBranchName New name for the destination branch. ** ** If none is supplied, it will get ** ** the name of the source branch. ** **