handle bit sets in apex
Thu Nov 03 2022 12:05:58 GMT+0000 (Coordinated Universal Time)
Map<String,List<String>> pickValueMap=DependentPickListValueController.GetDependentOptions('SObject','ControllingPickList','DependentPicklist'); ///////////////////////////////////////////////////////////////////////////////////////////////// public class DependentPickListValueController{ public DependentPickListValueController(){} public static Map<String,List<String>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){ Map<String,List<String>> objResults = new Map<String,List<String>>(); //get the string to sobject global map Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe(); //get the type being dealt with Schema.SObjectType pType = objGlobalMap.get(pObjName); Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap(); //get the control values List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues(); //get the dependent values List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues(); //iterate through the values and get the ones valid for the controlling field name PickListUtils.Bitset objBitSet = new PickListUtils.Bitset(); //set up the results for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){ //get the pointer to the entry Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex]; //get the label String pControllingLabel = ctrl_entry.getLabel(); //create the entry with the label objResults.put(pControllingLabel,new List<String>()); } //check the dependent values for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){ //get the pointer to the dependent index Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex]; //get the valid for String pEntryStructure = JSON.serialize(dep_entry); PickListUtils.PicklistDetails objDepPLE = (PickListUtils.PicklistDetails)JSON.deserialize(pEntryStructure, PickListUtils.PicklistDetails.class); //iterate through the controlling values for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){ if (objBitSet.fitBit(objDepPLE.validFor,pControllingIndex)){ //get the label String pControllingLabel = ctrl_ple[pControllingIndex].getLabel(); objResults.get(pControllingLabel).add(objDepPLE.label); } } } return objResults; } } ////////////////////////////////////////////////////////////////// public class PickListUtils{ public PickListUtils(){} public class PicklistDetails{ public string active {get;set;} public string defaultValue {get;set;} public string label {get;set;} public string value {get;set;} public string validFor {get;set;} public PicklistDetails(){} } public class Bitset{ public Map<String,Integer> AlphaNumCharCodes {get;set;} public Map<String, Integer> Base64CharCodes { get; set; } public Bitset(){ findChacterCodes(); } private void findChacterCodes(){ AlphaNumCharCodes = new Map<String,Integer>{ 'A'=>65,'B'=>66,'C'=>67,'D'=>68,'E'=>69,'F'=>70,'G'=>71,'H'=>72,'I'=>73,'J'=>74, 'K'=>75,'L'=>76,'M'=>77,'N'=>78,'O'=>79,'P'=>80,'Q'=>81,'R'=>82,'S'=>83,'T'=>84, 'U'=>85,'V'=> 86,'W'=>87,'X'=>88,'Y'=>89,'Z'=>90 }; Base64CharCodes = new Map<String, Integer>(); //lower case Set<String> pUpperCase = AlphaNumCharCodes.keySet(); for(String pKey : pUpperCase){ //the difference between upper case and lower case is 32 AlphaNumCharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey)+32); //Base 64 alpha starts from 0 (The ascii charcodes started from 65) Base64CharCodes.put(pKey,AlphaNumCharCodes.get(pKey) - 65); Base64CharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey) - (65) + 26); } //numerics for (Integer i=0; i<=9; i++){ AlphaNumCharCodes.put(string.valueOf(i),i+48); //base 64 numeric starts from 52 Base64CharCodes.put(string.valueOf(i), i + 52); } } public Boolean fitBit(String pValidFor,Integer n){ //the list of bytes List<Integer> pBytes = new List<Integer>(); //multiply by 6 since base 64 uses 6 bits Integer bytesBeingUsed = (pValidFor.length() * 6)/8; //will be used to hold the full decimal value Integer pFullValue = 0; //must be more than 1 byte if (bytesBeingUsed <= 1) return false; //calculate the target bit for comparison Integer bit = 7 - (Math.mod(n,8)); //calculate the octet that has in the target bit Integer targetOctet = (bytesBeingUsed - 1) - (n >> bytesBeingUsed); //the number of bits to shift by until we find the bit to compare for true or false Integer shiftBits = (targetOctet * 8) + bit; //get the base64bytes for(Integer i=0;i<pValidFor.length();i++){ //get current character value pBytes.Add((Base64CharCodes.get((pValidFor.Substring(i, i+1))))); } //calculate the full decimal value for (Integer i = 0; i < pBytes.size(); i++){ Integer pShiftAmount = (pBytes.size()-(i+1))*6;//used to shift by a factor 6 bits to get the value pFullValue = pFullValue + (pBytes[i] << (pShiftAmount)); } //shift to the bit which will dictate true or false Integer tBitVal = ((Integer)(Math.Pow(2, shiftBits)) & pFullValue) >> shiftBits; return tBitVal == 1; } } }
Comments