kumaab commented on code in PR #442:
URL: https://github.com/apache/ranger/pull/442#discussion_r1881114027


##########
agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResourceImpl.java:
##########
@@ -19,250 +19,262 @@
 
 package org.apache.ranger.plugin.policyengine;
 
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.ranger.plugin.model.RangerServiceDef;
-import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
-
 public class RangerAccessResourceImpl implements RangerMutableResource {
-       private String              ownerUser;
-       private Map<String, Object> elements;
-       private String              stringifiedValue;
-       private String              stringifiedCacheKeyValue;
-       private String              leafName;
-       private RangerServiceDef    serviceDef;
-
-       public RangerAccessResourceImpl() {
-               this(null, null);
-       }
-
-       public RangerAccessResourceImpl(Map<String, Object> elements) {
-               this(elements, null);
-       }
-
-       public RangerAccessResourceImpl(Map<String, Object> elements, String 
ownerUser) {
-               this.elements  = elements;
-               this.ownerUser = ownerUser;
-       }
-
-       @Override
-       public String getOwnerUser() {
-               return ownerUser;
-       }
-
-       @Override
-       public boolean exists(String name) {
-               return elements != null && elements.containsKey(name);
-       }
-
-       @Override
-       public Object getValue(String name) {
-               Object ret = null;
-
-               if(elements != null && elements.containsKey(name)) {
-                       ret = elements.get(name);
-               }
-
-               return ret;
-       }
-
-       @Override
-       public Set<String> getKeys() {
-               Set<String> ret = null;
-
-               if(elements != null) {
-                       ret = elements.keySet();
-               }
-
-               return ret;
-       }
-
-       @Override
-       public void setOwnerUser(String ownerUser) {
-               this.ownerUser = ownerUser;
-       }
-
-       @Override
-       public void setValue(String name, Object value) {
-               if(value == null) {
-                       if(elements != null) {
-                               elements.remove(name);
-
-                               if(elements.isEmpty()) {
-                                       elements = null;
-                               }
-                       }
-               } else {
-                       if(elements == null) {
-                               elements = new HashMap<>();
-                       }
-                       elements.put(name, value);
-               }
-
-               // reset, so that these will be computed again with updated 
elements
-               stringifiedValue = stringifiedCacheKeyValue = leafName = null;
-       }
-
-       @Override
-       public void setServiceDef(final RangerServiceDef serviceDef) {
-               this.serviceDef = serviceDef;
-               this.stringifiedValue = this.stringifiedCacheKeyValue = 
this.leafName = null;
-       }
-
-       @Override
-       public RangerServiceDef getServiceDef() {
-               return this.serviceDef;
-       }
-
-       @Override
-       public String getLeafName() {
-               String ret = leafName;
-
-               if(ret == null) {
-                       if(serviceDef != null && serviceDef.getResources() != 
null) {
-                               List<RangerResourceDef> resourceDefs = 
serviceDef.getResources();
-
-                               for(int idx = resourceDefs.size() - 1; idx >= 
0; idx--) {
-                                       RangerResourceDef resourceDef = 
resourceDefs.get(idx);
-
-                                       if(resourceDef != null && 
exists(resourceDef.getName())) {
-                                           ret = leafName = 
resourceDef.getName();
-                                           break;
+    private String              ownerUser;
+    private Map<String, Object> elements;
+    private String              stringifiedValue;
+    private String              stringifiedCacheKeyValue;
+    private String              leafName;
+    private RangerServiceDef    serviceDef;
+
+    public RangerAccessResourceImpl() {
+        this(null, null);
+    }
+
+    public RangerAccessResourceImpl(Map<String, Object> elements) {
+        this(elements, null);
+    }
+
+    public RangerAccessResourceImpl(Map<String, Object> elements, String 
ownerUser) {
+        this.elements  = elements;
+        this.ownerUser = ownerUser;
+    }
+
+    @Override
+    public String getOwnerUser() {
+        return ownerUser;
+    }
+
+    @Override
+    public boolean exists(String name) {
+        return elements != null && elements.containsKey(name);
+    }
+
+    @Override
+    public Object getValue(String name) {
+        Object ret = null;
+
+        if (elements != null && elements.containsKey(name)) {
+            ret = elements.get(name);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public RangerServiceDef getServiceDef() {
+        return this.serviceDef;
+    }
+
+    @Override
+    public Set<String> getKeys() {
+        Set<String> ret = null;
+
+        if (elements != null) {
+            ret = elements.keySet();
+        }
+
+        return ret;
+    }
+
+    @Override
+    public String getLeafName() {
+        String ret = leafName;
+
+        if (ret == null) {
+            if (serviceDef != null && serviceDef.getResources() != null) {
+                List<RangerResourceDef> resourceDefs = 
serviceDef.getResources();
+
+                for (int idx = resourceDefs.size() - 1; idx >= 0; idx--) {
+                    RangerResourceDef resourceDef = resourceDefs.get(idx);
+
+                    if (resourceDef != null && exists(resourceDef.getName())) {
+                        ret      = resourceDef.getName();
+                        leafName = ret;
+
+                        break;
                     }
-                               }
-                       }
-               }
-
-               return ret;
-       }
-
-       @Override
-       public String getAsString() {
-               String ret = stringifiedValue;
-
-               if(ret == null) {
-                       if(serviceDef != null && serviceDef.getResources() != 
null) {
-                               StringBuilder sb = new StringBuilder();
-
-                               for(RangerResourceDef resourceDef : 
serviceDef.getResources()) {
-                                       if(resourceDef == null || 
!exists(resourceDef.getName())) {
-                                               continue;
-                                       }
-
-                                       if(sb.length() > 0) {
-                                               sb.append(RESOURCE_SEP);
-                                       }
-
-                                       
sb.append(getValue(resourceDef.getName()));
-                               }
-
-                               if(sb.length() > 0) {
-                                       ret = stringifiedValue = sb.toString();
-                               }
-                       }
-               }
-
-               return ret;
-       }
-
-       @Override
-       public String getCacheKey() {
-               String ret = stringifiedCacheKeyValue;
+                }
+            }
+        }
 
-               if(ret == null) {
-                       if(serviceDef != null && serviceDef.getResources() != 
null) {
-                               StringBuilder sb = new StringBuilder();
+        return ret;
+    }
 
-                               for(RangerResourceDef resourceDef : 
serviceDef.getResources()) {
-                                       if(resourceDef == null || 
!exists(resourceDef.getName())) {
-                                               continue;
-                                       }
+    @Override
+    public String getAsString() {
+        String ret = stringifiedValue;
 
-                                       if(sb.length() > 0) {
-                                               sb.append(RESOURCE_SEP);
-                                       }
+        if (ret == null) {
+            if (serviceDef != null && serviceDef.getResources() != null) {
+                StringBuilder sb = new StringBuilder();
 
-                                       
sb.append(resourceDef.getName()).append(RESOURCE_NAME_VAL_SEP).append(getValue(resourceDef.getName()));
-                               }
-
-                               if(sb.length() > 0) {
-                                       ret = stringifiedCacheKeyValue = 
sb.toString();
-                               }
-                       }
-               }
-
-               return ret;
-       }
-
-       @Override
-       public Map<String, Object> getAsMap() {
-               return elements == null ? Collections.EMPTY_MAP : 
Collections.unmodifiableMap(elements);
-       }
-
-       @Override
-       public RangerAccessResource getReadOnlyCopy() {
-               return new RangerAccessResourceReadOnly(this);
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if(obj == null || !(obj instanceof RangerAccessResourceImpl)) {
-                       return false;
-               }
-
-               if(this == obj) {
-                       return true;
-               }
-
-               RangerAccessResourceImpl other = (RangerAccessResourceImpl) obj;
-
-               return ObjectUtils.equals(ownerUser, other.ownerUser) &&
-                          ObjectUtils.equals(elements, other.elements);
-       }
-
-       @Override
-       public int hashCode() {
-               int ret = 7;
-
-               ret = 31 * ret + ObjectUtils.hashCode(ownerUser);
-               ret = 31 * ret + ObjectUtils.hashCode(elements);
-
-               return ret;
-       }
-
-       @Override
-       public String toString( ) {
-               StringBuilder sb = new StringBuilder();
+                for (RangerResourceDef resourceDef : 
serviceDef.getResources()) {
+                    if (resourceDef == null || !exists(resourceDef.getName())) 
{
+                        continue;
+                    }
 
-               toString(sb);
+                    if (sb.length() > 0) {
+                        sb.append(RESOURCE_SEP);
+                    }
 
-               return sb.toString();
-       }
+                    sb.append(getValue(resourceDef.getName()));
+                }
 
-       public StringBuilder toString(StringBuilder sb) {
-               sb.append("RangerResourceImpl={");
+                if (sb.length() > 0) {
+                    ret              = sb.toString();
+                    stringifiedValue = ret;
+                }
+            }
+        }
 
-               sb.append("ownerUser={").append(ownerUser).append("} ");
+        return ret;
+    }
 
-               sb.append("elements={");
-               if(elements != null) {
-                       for(Map.Entry<String, Object> e : elements.entrySet()) {
-                               
sb.append(e.getKey()).append("=").append(e.getValue()).append("; ");
-                       }
-               }
-               sb.append("} ");
+    @Override
+    public String getCacheKey() {
+        String ret = stringifiedCacheKeyValue;
 
-               sb.append("}");
+        if (ret == null) {
+            if (serviceDef != null && serviceDef.getResources() != null) {
+                StringBuilder sb = new StringBuilder();
 
-               return sb;
-       }
+                for (RangerResourceDef resourceDef : 
serviceDef.getResources()) {
+                    if (resourceDef == null || !exists(resourceDef.getName())) 
{
+                        continue;
+                    }
 
-       protected String getStringifiedValue() { return stringifiedValue; }
+                    if (sb.length() > 0) {
+                        sb.append(RESOURCE_SEP);
+                    }
 
-       protected void setStringifiedValue(String val) { this.stringifiedValue 
= val; }
+                    
sb.append(resourceDef.getName()).append(RESOURCE_NAME_VAL_SEP).append(getValue(resourceDef.getName()));
+                }
+
+                if (sb.length() > 0) {
+                    ret                      = sb.toString();
+                    stringifiedCacheKeyValue = ret;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    @Override
+    public Map<String, Object> getAsMap() {
+        return elements == null ? Collections.emptyMap() : 
Collections.unmodifiableMap(elements);
+    }
+
+    @Override
+    public RangerAccessResource getReadOnlyCopy() {
+        return new RangerAccessResourceReadOnly(this);
+    }
+
+    @Override
+    public void setServiceDef(final RangerServiceDef serviceDef) {
+        this.serviceDef               = serviceDef;
+        this.stringifiedValue         = null;
+        this.stringifiedCacheKeyValue = null;
+        this.leafName                 = null;
+    }
+
+    @Override
+    public void setOwnerUser(String ownerUser) {
+        this.ownerUser = ownerUser;
+    }
+
+    @Override
+    public void setValue(String name, Object value) {
+        if (value == null) {
+            if (elements != null) {
+                elements.remove(name);
+
+                if (elements.isEmpty()) {
+                    elements = null;
+                }
+            }
+        } else {
+            if (elements == null) {
+                elements = new HashMap<>();
+            }
+            elements.put(name, value);
+        }
+
+        // reset, so that these will be computed again with updated elements
+        stringifiedValue         = null;
+        stringifiedCacheKeyValue = null;
+        leafName                 = null;
+    }
+
+    @Override
+    public int hashCode() {
+        int ret = 7;
+
+        ret = 31 * ret + ObjectUtils.hashCode(ownerUser);
+        ret = 31 * ret + ObjectUtils.hashCode(elements);
+
+        return ret;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof RangerAccessResourceImpl)) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        RangerAccessResourceImpl other = (RangerAccessResourceImpl) obj;

Review Comment:
   lines 240-243 may be simplified to:
   ` return ObjectUtils.equals(ownerUser, obj.ownerUser) && 
ObjectUtils.equals(elements, obj.elements);`



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java:
##########
@@ -58,1347 +48,1317 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator {
-       private static final Logger LOG = 
LoggerFactory.getLogger(RangerDefaultPolicyEvaluator.class);
-
-       private static final Logger PERF_POLICY_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policy.init");
-       private static final Logger PERF_POLICY_INIT_ACLSUMMARY_LOG = 
RangerPerfTracer.getPerfLogger("policy.init.ACLSummary");
-       private static final Logger PERF_POLICY_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policy.request");
-       private static final Logger PERF_POLICYCONDITION_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.request");
-
-       private List<RangerValidityScheduleEvaluator> 
validityScheduleEvaluators;
-       private List<RangerPolicyItemEvaluator> allowEvaluators;
-       private List<RangerPolicyItemEvaluator> denyEvaluators;
-       private List<RangerPolicyItemEvaluator> allowExceptionEvaluators;
-       private List<RangerPolicyItemEvaluator> denyExceptionEvaluators;
-       private int                             customConditionsCount;
-       private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators;
-       private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators;
-       private List<RangerConditionEvaluator>  conditionEvaluators;
-       private String perfTag;
-       private PolicyACLSummary aclSummary                 = null;
-       private boolean          disableRoleResolution      = true;
-
-       List<RangerPolicyItemEvaluator> getAllowEvaluators() { return 
allowEvaluators; }
-       List<RangerPolicyItemEvaluator> getAllowExceptionEvaluators() { return 
allowExceptionEvaluators; }
-       List<RangerPolicyItemEvaluator> getDenyEvaluators() { return 
denyEvaluators; }
-       List<RangerPolicyItemEvaluator> getDenyExceptionEvaluators() { return 
denyExceptionEvaluators; }
-       List<RangerDataMaskPolicyItemEvaluator> getDataMaskEvaluators() { 
return dataMaskEvaluators; }
-       List<RangerRowFilterPolicyItemEvaluator> getRowFilterEvaluators() { 
return rowFilterEvaluators; }
-
-       @Override
-       public int getPolicyConditionsCount() {
-               return conditionEvaluators.size();
-       }
-
-       @Override
-       public int getCustomConditionsCount() {
-               return customConditionsCount;
-       }
-
-       @Override
-       public int getValidityScheduleEvaluatorsCount() {
-               return validityScheduleEvaluators.size();
-       }
-
-       @Override
-       public void init(RangerPolicy policy, RangerServiceDef serviceDef, 
RangerPolicyEngineOptions options) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerDefaultPolicyEvaluator.init()");
-               }
-
-               StringBuilder perfTagBuffer = new StringBuilder();
-               if (policy != null) {
-                       
perfTagBuffer.append("policyId=").append(policy.getId()).append(", 
policyName=").append(policy.getName());
-               }
-
-               perfTag = perfTagBuffer.toString();
-
-               RangerPerfTracer perf = null;
-
-               if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_INIT_LOG)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_LOG, 
"RangerPolicyEvaluator.init(" + perfTag + ")");
-               }
-
-               super.init(policy, serviceDef, options);
-
-               policy = getPolicy();
-
-               preprocessPolicy(policy, serviceDef, options);
-
-               if(policy != null) {
-                       validityScheduleEvaluators = 
createValidityScheduleEvaluators(policy);
-
-                       this.disableRoleResolution = 
options.disableRoleResolution;
-
-                       allowEvaluators = createPolicyItemEvaluators(policy, 
serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
-
-                       if 
(ServiceDefUtil.getOption_enableDenyAndExceptionsInPolicies(serviceDef, 
getPluginContext())) {
-                               denyEvaluators           = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
-                               allowExceptionEvaluators = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
-                               denyExceptionEvaluators  = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
-                       } else {
-                               denyEvaluators           = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                               allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                               denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       }
-
-                       dataMaskEvaluators  = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
-                       rowFilterEvaluators = 
createRowFilterPolicyItemEvaluators(policy, serviceDef, options, 
policy.getRowFilterPolicyItems());
-                       conditionEvaluators = 
createPolicyConditionEvaluators(policy, serviceDef, options);
-               } else {
-                       validityScheduleEvaluators = 
Collections.<RangerValidityScheduleEvaluator>emptyList();
-                       allowEvaluators            = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       denyEvaluators             = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       allowExceptionEvaluators   = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       denyExceptionEvaluators    = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       dataMaskEvaluators         = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
-                       rowFilterEvaluators        = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
-                       conditionEvaluators        = 
Collections.<RangerConditionEvaluator>emptyList();
-               }
-
-               RangerPolicyItemEvaluator.EvalOrderComparator comparator = new 
RangerPolicyItemEvaluator.EvalOrderComparator();
-               Collections.sort(allowEvaluators, comparator);
-               Collections.sort(denyEvaluators, comparator);
-               Collections.sort(allowExceptionEvaluators, comparator);
-               Collections.sort(denyExceptionEvaluators, comparator);
-
-               /* dataMask, rowFilter policyItems must be evaulated in the 
order given in the policy; hence no sort
-               Collections.sort(dataMaskEvaluators);
-               Collections.sort(rowFilterEvaluators);
-               */
-
-               RangerPerfTracer.log(perf);
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerDefaultPolicyEvaluator.init()");
-               }
-       }
-
-       @Override
-    public boolean isApplicable(Date accessTime) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.isApplicable(" + 
accessTime + ")");
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerDefaultPolicyEvaluator.class);
+
+    private static final Logger PERF_POLICY_INIT_LOG             = 
RangerPerfTracer.getPerfLogger("policy.init");
+    private static final Logger PERF_POLICY_INIT_ACLSUMMARY_LOG  = 
RangerPerfTracer.getPerfLogger("policy.init.ACLSummary");
+    private static final Logger PERF_POLICY_REQUEST_LOG          = 
RangerPerfTracer.getPerfLogger("policy.request");
+    private static final Logger PERF_POLICYCONDITION_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.request");
+
+    private List<RangerValidityScheduleEvaluator>    
validityScheduleEvaluators;
+    private List<RangerPolicyItemEvaluator>          allowEvaluators;
+    private List<RangerPolicyItemEvaluator>          denyEvaluators;
+    private List<RangerPolicyItemEvaluator>          allowExceptionEvaluators;
+    private List<RangerPolicyItemEvaluator>          denyExceptionEvaluators;
+    private int                                      customConditionsCount;
+    private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators;
+    private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators;
+    private List<RangerConditionEvaluator>           conditionEvaluators;
+    private String                                   perfTag;
+    private PolicyACLSummary                         aclSummary;
+    private boolean                                  disableRoleResolution = 
true;
+
+    static RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, 
String accessType) {
+        RangerPolicyItemAccess ret = null;
+
+        if (policyItem != null && 
CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
+            for (RangerPolicyItemAccess itemAccess : policyItem.getAccesses()) 
{
+                if (itemAccess != null && 
StringUtils.equalsIgnoreCase(itemAccess.getType(), accessType)) {
+                    ret = itemAccess;
+
+                    break;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void init(RangerPolicy policy, RangerServiceDef serviceDef, 
RangerPolicyEngineOptions options) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.init()");
+
+        StringBuilder perfTagBuffer = new StringBuilder();
+        if (policy != null) {
+            perfTagBuffer.append("policyId=").append(policy.getId()).append(", 
policyName=").append(policy.getName());
+        }
+
+        perfTag = perfTagBuffer.toString();
+
+        RangerPerfTracer perf = null;
+
+        if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_INIT_LOG)) {
+            perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_LOG, 
"RangerPolicyEvaluator.init(" + perfTag + ")");
+        }
+
+        super.init(policy, serviceDef, options);
+
+        policy = getPolicy();
+
+        preprocessPolicy(policy, serviceDef, options);
+
+        if (policy != null) {
+            validityScheduleEvaluators = 
createValidityScheduleEvaluators(policy);
+
+            this.disableRoleResolution = options.disableRoleResolution;
+
+            allowEvaluators = createPolicyItemEvaluators(policy, serviceDef, 
options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
+
+            if 
(ServiceDefUtil.getOption_enableDenyAndExceptionsInPolicies(serviceDef, 
getPluginContext())) {
+                denyEvaluators           = createPolicyItemEvaluators(policy, 
serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
+                allowExceptionEvaluators = createPolicyItemEvaluators(policy, 
serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
+                denyExceptionEvaluators  = createPolicyItemEvaluators(policy, 
serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
+            } else {
+                denyEvaluators           = Collections.emptyList();
+                allowExceptionEvaluators = Collections.emptyList();
+                denyExceptionEvaluators  = Collections.emptyList();
+            }
+
+            dataMaskEvaluators  = createDataMaskPolicyItemEvaluators(policy, 
serviceDef, options, policy.getDataMaskPolicyItems());
+            rowFilterEvaluators = createRowFilterPolicyItemEvaluators(policy, 
serviceDef, options, policy.getRowFilterPolicyItems());
+            conditionEvaluators = createPolicyConditionEvaluators(policy, 
serviceDef, options);
+        } else {
+            validityScheduleEvaluators = Collections.emptyList();
+            allowEvaluators            = Collections.emptyList();
+            denyEvaluators             = Collections.emptyList();
+            allowExceptionEvaluators   = Collections.emptyList();
+            denyExceptionEvaluators    = Collections.emptyList();
+            dataMaskEvaluators         = Collections.emptyList();
+            rowFilterEvaluators        = Collections.emptyList();
+            conditionEvaluators        = Collections.emptyList();
+        }
+
+        RangerPolicyItemEvaluator.EvalOrderComparator comparator = new 
RangerPolicyItemEvaluator.EvalOrderComparator();
+        allowEvaluators.sort(comparator);
+        denyEvaluators.sort(comparator);
+        allowExceptionEvaluators.sort(comparator);
+        denyExceptionEvaluators.sort(comparator);
+
+        /* dataMask, rowFilter policyItems must be evaulated in the order 
given in the policy; hence no sort
+        Collections.sort(dataMaskEvaluators);
+        Collections.sort(rowFilterEvaluators);
+        */
+
+        RangerPerfTracer.log(perf);
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.init()");
+    }
+
+    @Override
+    public PolicyACLSummary getPolicyACLSummary() {
+        if (aclSummary == null) {
+            aclSummary = 
createPolicyACLSummary(ServiceDefUtil.getExpandedImpliedGrants(getServiceDef()),
 true);
+        }
+        return aclSummary;
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        sb.append("RangerDefaultPolicyEvaluator={");
+
+        super.toString(sb);
+
+        for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
+            RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
+
+            sb.append("resourceMatcher={");
+            if (resourceMatcher != null) {
+                resourceMatcher.toString(sb);
+            }
+            sb.append("} ");
         }
 
+        sb.append("}");
+
+        return sb;
+    }
+
+    @Override
+    public boolean isApplicable(Date accessTime) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isApplicable({})", 
accessTime);
+
         boolean ret = false;
 
         if (accessTime != null && 
CollectionUtils.isNotEmpty(validityScheduleEvaluators)) {
-                       for (RangerValidityScheduleEvaluator evaluator : 
validityScheduleEvaluators) {
-                               if 
(evaluator.isApplicable(accessTime.getTime())) {
-                                       ret = true;
-                                       break;
-                               }
-                       }
+            for (RangerValidityScheduleEvaluator evaluator : 
validityScheduleEvaluators) {
+                if (evaluator.isApplicable(accessTime.getTime())) {
+                    ret = true;
+                    break;
+                }
+            }
         } else {
-               ret = true;
+            ret = true;
+        }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isApplicable({}) : {}", 
accessTime, ret);
+
+        return ret;
+    }
+
+    @Override
+    public int getPolicyConditionsCount() {
+        return conditionEvaluators.size();
+    }
+
+    @Override
+    public int getCustomConditionsCount() {
+        return customConditionsCount;
+    }
+
+    @Override
+    public int getValidityScheduleEvaluatorsCount() {
+        return validityScheduleEvaluators.size();
+    }
+
+    @Override
+    public void evaluate(RangerAccessRequest request, RangerAccessResult 
result) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(policyId={}, {}, 
{})", getPolicyId(), request, result);
+
+        RangerPerfTracer perf = null;
+
+        if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+            perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.evaluate(requestHashCode=" + 
Integer.toHexString(System.identityHashCode(request)) + ","
+                    + perfTag + ")");
+        }
+
+        if (request != null && result != null) {
+            for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
+                RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
+
+                if (!result.getIsAccessDetermined() || 
!result.getIsAuditedDetermined()) {
+                    final RangerPolicyResourceMatcher.MatchType matchType;
+
+                    if (request instanceof RangerTagAccessRequest) {
+                        matchType = ((RangerTagAccessRequest) 
request).getMatchType();
+                    } else {
+                        matchType = resourceMatcher != null ? 
resourceMatcher.getMatchType(request.getResource(), 
request.getResourceElementMatchingScopes(), request.getContext()) : 
RangerPolicyResourceMatcher.MatchType.NONE;
+                    }
+
+                    final RangerAccessRequest.ResourceMatchingScope 
resourceMatchingScope = request.getResourceMatchingScope() != null ? 
request.getResourceMatchingScope() : 
RangerAccessRequest.ResourceMatchingScope.SELF;
+                    final boolean                                   isMatched;
+
+                    if (request.isAccessTypeAny() || resourceMatchingScope == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+                        isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS || matchType == 
RangerPolicyResourceMatcher.MatchType.DESCENDANT;
+                    } else {
+                        isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+                    }
+
+                    if (isMatched) {
+                        //Evaluate Policy Level Custom Conditions, if any and 
allowed then go ahead for policyItem level evaluation
+                        if (matchPolicyCustomConditions(request)) {
+                            if (!result.getIsAuditedDetermined()) {
+                                if (isAuditEnabled()) {
+                                    result.setIsAudited(true);
+                                    result.setAuditPolicyId(getPolicyId());
+                                }
+                            }
+                            if (!result.getIsAccessDetermined()) {
+                                if (hasMatchablePolicyItem(request)) {
+                                    evaluatePolicyItems(request, matchType, 
result);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        RangerPerfTracer.log(perf);
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(policyId={}, {}, 
{})", getPolicyId(), request, result);
+    }
+
+    @Override
+    public boolean isMatch(RangerAccessResource resource, Map<String, Object> 
evalContext) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(policy-id={}, {}, 
{})", getPolicyId(), resource, evalContext);
+
+        boolean ret = false;
+
+        RangerPerfTracer perf = null;
+
+        if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+            perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + 
evalContext + "," + perfTag + ")");
+        }
+
+        for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
+            RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
+
+            ret = resourceMatcher != null && resourceMatcher.isMatch(resource, 
evalContext);
+
+            if (ret) {
+                break;
+            }
+        }
+
+        RangerPerfTracer.log(perf);
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(policy-id={}, {}, 
{}) : {}", getPolicyId(), resource, evalContext, ret);
+
+        return ret;
+    }
+
+    @Override
+    public boolean isCompleteMatch(RangerAccessResource resource, Map<String, 
Object> evalContext) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch({}, {})", 
resource, evalContext);
+
+        final boolean ret;
+
+        List<RangerPolicyResourceEvaluator> resourceEvaluators = 
getResourceEvaluators();
+
+        if (resourceEvaluators.size() == 1) {
+            RangerPolicyResourceEvaluator resourceEvaluator = 
resourceEvaluators.get(0);
+            RangerPolicyResourceMatcher   resourceMatcher   = 
resourceEvaluator.getPolicyResourceMatcher();
+
+            ret = resourceMatcher != null && 
resourceMatcher.isCompleteMatch(resource, evalContext);
+        } else {
+            ret = false;
+        }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch({}): {}", 
resource, ret);
+
+        return ret;
+    }
+
+    @Override
+    public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources, List<Map<String, RangerPolicyResource>> additionalResources, 
Map<String, Object> evalContext) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch({}, {})", 
resources, evalContext);
+
+        boolean ret = false;
+
+        List<RangerPolicyResourceEvaluator> resourceEvaluators = 
getResourceEvaluators();
+
+        for (int i = 0; i < resourceEvaluators.size(); i++) {
+            RangerPolicyResourceEvaluator     resourceEvaluator = 
resourceEvaluators.get(i);
+            RangerPolicyResourceMatcher       resourceMatcher   = 
resourceEvaluator.getPolicyResourceMatcher();
+            Map<String, RangerPolicyResource> policyResource    = null;
+
+            if (i == 0) {
+                policyResource = resources;
+            } else if (additionalResources != null && 
additionalResources.size() >= i) {
+                policyResource = additionalResources.get(i - 1);
+            }
+
+            ret = resourceMatcher != null && policyResource != null && 
resourceMatcher.isCompleteMatch(policyResource, evalContext);
+
+            if (!ret) {
+                break;
+            }
+        }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch({}, {}): 
{}", resources, evalContext, ret);
+
+        return ret;
+    }
+
+    @Override
+    public boolean isAccessAllowed(Map<String, RangerPolicyResource> 
resources, List<Map<String, RangerPolicyResource>> additionalResources, String 
user, Set<String> userGroups, String accessType) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed({}, {}, 
{}, {})", resources, user, userGroups, accessType);
+
+        boolean ret = isAccessAllowed(user, userGroups, null, null, 
accessType) && isMatch(resources, null);
+
+        if (ret && additionalResources != null) {
+            for (Map<String, RangerPolicyResource> additionalResource : 
additionalResources) {
+                ret = isMatch(additionalResource, null);
+
+                if (!ret) {
+                    break;
+                }
+            }
+        }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed({}, {}, 
{}, {}): {}", resources, user, userGroups, accessType, ret);
+
+        return ret;
+    }
+
+    @Override
+    public void updateAccessResult(RangerAccessResult result, 
RangerPolicyResourceMatcher.MatchType matchType, boolean isAllowed, String 
reason) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerDefaultPolicyEvaluator.updateAccessResult({}, 
{}, {}, {}, {})", result, matchType, isAllowed, reason, getPolicyId());
+        }
+
+        if (!isAllowed) {
+            if (matchType != RangerPolicyResourceMatcher.MatchType.DESCENDANT 
|| !result.getAccessRequest().ignoreDescendantDeny()) {
+                result.setIsAllowed(false);
+                result.setPolicyPriority(getPolicyPriority());
+                result.setPolicyId(getPolicyId());
+                result.setReason(reason);
+                result.setPolicyVersion(getPolicy().getVersion());
+            }
+        } else {
+            if (!result.getIsAllowed()) { // if access is not yet allowed by 
another policy
+                result.setIsAllowed(true);
+                result.setPolicyPriority(getPolicyPriority());
+                result.setPolicyId(getPolicyId());
+                result.setReason(reason);
+                result.setPolicyVersion(getPolicy().getVersion());
+            }
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.isApplicable(" + 
accessTime + ") : " + ret);
+            LOG.debug("<== RangerDefaultPolicyEvaluator.updateAccessResult({}, 
{}, {}, {}, {})", result, matchType, isAllowed, reason, getPolicyId());
+        }
+    }
+
+    @Override
+    public void getResourceAccessInfo(RangerAccessRequest request, 
RangerResourceAccessInfo result) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceAccessInfo({}, 
{})", request, result);
+
+        for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
+            RangerPolicyResourceMatcher           resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
+            RangerPolicyResourceMatcher.MatchType matchType;
+
+            if (request instanceof RangerTagAccessRequest) {
+                matchType = ((RangerTagAccessRequest) request).getMatchType();
+            } else {
+                matchType = resourceMatcher != null ? 
resourceMatcher.getMatchType(request.getResource(), 
request.getResourceElementMatchingScopes(), request.getContext()) : 
RangerPolicyResourceMatcher.MatchType.NONE;
+            }
+
+            final boolean isMatched = matchType != 
RangerPolicyResourceMatcher.MatchType.NONE;
+
+            if (isMatched) {
+                if (CollectionUtils.isNotEmpty(allowEvaluators)) {
+                    Set<String> users  = new HashSet<>();
+                    Set<String> groups = new HashSet<>();
+
+                    getResourceAccessInfo(request, allowEvaluators, users, 
groups);
+
+                    if (CollectionUtils.isNotEmpty(allowExceptionEvaluators)) {
+                        Set<String> exceptionUsers  = new HashSet<>();
+                        Set<String> exceptionGroups = new HashSet<>();
+
+                        getResourceAccessInfo(request, 
allowExceptionEvaluators, exceptionUsers, exceptionGroups);
+
+                        users.removeAll(exceptionUsers);
+                        groups.removeAll(exceptionGroups);
+                    }
+
+                    result.getAllowedUsers().addAll(users);
+                    result.getAllowedGroups().addAll(groups);
+                }
+                if (matchType != 
RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
+                    if (CollectionUtils.isNotEmpty(denyEvaluators)) {
+                        Set<String> users  = new HashSet<>();
+                        Set<String> groups = new HashSet<>();
+
+                        getResourceAccessInfo(request, denyEvaluators, users, 
groups);
+
+                        if 
(CollectionUtils.isNotEmpty(denyExceptionEvaluators)) {
+                            Set<String> exceptionUsers  = new HashSet<>();
+                            Set<String> exceptionGroups = new HashSet<>();
+
+                            getResourceAccessInfo(request, 
denyExceptionEvaluators, exceptionUsers, exceptionGroups);
+
+                            users.removeAll(exceptionUsers);
+                            groups.removeAll(exceptionGroups);
+                        }
+
+                        result.getDeniedUsers().addAll(users);
+                        result.getDeniedGroups().addAll(groups);
+                    }
+                }
+            }
+        }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.getResourceAccessInfo({}, 
{})", request, result);
+    }
+
+    @Override
+    public Set<String> getAllowedAccesses(RangerAccessResource resource, 
String user, Set<String> userGroups, Set<String> roles, Set<String> 
accessTypes) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> 
RangerDefaultPolicyEvaluator.getAllowedAccesses(policy-id={}, {}, {}, {}, {}, 
{})", getPolicyId(), resource, user, userGroups, roles, accessTypes);
+        }
+
+        Set<String> ret = null;
+
+        Map<String, Object> evalContext = new HashMap<>();
+
+        RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
+
+        if (isMatch(resource, evalContext)) {
+            ret = new HashSet<>();
+
+            for (String accessType : accessTypes) {
+                if (isAccessAllowed(user, userGroups, roles, 
resource.getOwnerUser(), accessType)) {
+                    ret.add(accessType);
+                }
+            }
+        } else {
+            LOG.debug("RangerDefaultPolicyEvaluator.getAllowedAccesses - Not 
Matched -- (policy-id={}, {}, {}, {}, {}, {})", getPolicyId(), resource, user, 
userGroups, roles, accessTypes);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== 
RangerDefaultPolicyEvaluator.getAllowedAccesses(policy-id={}, {}, {}, {}, {}, 
{}): {}", getPolicyId(), resource, user, userGroups, roles, accessTypes, ret);
         }
 
         return ret;
     }
 
     @Override
-    public void evaluate(RangerAccessRequest request, RangerAccessResult 
result) {
+    public Set<String> getAllowedAccesses(Map<String, RangerPolicyResource> 
resources, String user, Set<String> userGroups, Set<String> roles, Set<String> 
accessTypes, Map<String, Object> evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(policyId=" + 
getPolicyId() + ", " + request + ", " + result + ")");
+            LOG.debug("==> RangerDefaultPolicyEvaluator.getAllowedAccesses({}, 
{}, {}, {}, {}, {})", getPolicyId(), user, userGroups, roles, accessTypes, 
evalContext);
         }
 
-               RangerPerfTracer perf = null;
+        Set<String> ret = null;
 
-               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.evaluate(requestHashCode=" + 
Integer.toHexString(System.identityHashCode(request)) + ","
-                                       + perfTag + ")");
-               }
+        if (isMatch(resources, evalContext)) {
+            if (CollectionUtils.isNotEmpty(accessTypes)) {
+                ret = new HashSet<>();
+                for (String accessType : accessTypes) {
+                    if (isAccessAllowed(user, userGroups, roles, null, 
accessType)) {
+                        ret.add(accessType);
+                    }
+                }
+            } else {
+                if (isAccessAllowed(user, userGroups, roles, null, null)) {
+                    ret = new HashSet<>();
+                }
+            }
+        }
 
-        if (request != null && result != null) {
-                       for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
-                               RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
-
-                               if (!result.getIsAccessDetermined() || 
!result.getIsAuditedDetermined()) {
-                                       final 
RangerPolicyResourceMatcher.MatchType matchType;
-
-                                       if (request instanceof 
RangerTagAccessRequest) {
-                                               matchType = 
((RangerTagAccessRequest) request).getMatchType();
-                                       } else {
-                                               matchType = resourceMatcher != 
null ? resourceMatcher.getMatchType(request.getResource(), 
request.getResourceElementMatchingScopes(), request.getContext()) : 
RangerPolicyResourceMatcher.MatchType.NONE;
-                                       }
-
-                                       final 
RangerAccessRequest.ResourceMatchingScope resourceMatchingScope = 
request.getResourceMatchingScope() != null ? request.getResourceMatchingScope() 
: RangerAccessRequest.ResourceMatchingScope.SELF;
-                                       final boolean                           
        isMatched;
-
-                                       if (request.isAccessTypeAny() || 
resourceMatchingScope == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
-                                               isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS || matchType == 
RangerPolicyResourceMatcher.MatchType.DESCENDANT;
-                                       } else {
-                                               isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
-                                       }
-
-                                       if (isMatched) {
-                                               //Evaluate Policy Level Custom 
Conditions, if any and allowed then go ahead for policyItem level evaluation
-                                               if 
(matchPolicyCustomConditions(request)) {
-                                                       if 
(!result.getIsAuditedDetermined()) {
-                                                               if 
(isAuditEnabled()) {
-                                                                       
result.setIsAudited(true);
-                                                                       
result.setAuditPolicyId(getPolicyId());
-                                                               }
-                                                       }
-                                                       if 
(!result.getIsAccessDetermined()) {
-                                                               if 
(hasMatchablePolicyItem(request)) {
-                                                                       
evaluatePolicyItems(request, matchType, result);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               RangerPerfTracer.log(perf);
-
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(policyId=" + 
getPolicyId() + ", " + request + ", " + result + ")");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerDefaultPolicyEvaluator.getAllowedAccesses({}, 
{}, {}, {}, {}, {}): {}", getPolicyId(), user, userGroups, roles, accessTypes, 
evalContext, ret);
+        }
+
+        return ret;
+    }
+    /*
+     * This is used only by test code
+     */
+
+    protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerPolicyResourceMatcher.MatchType matchType, RangerAccessResult result) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems({}, 
{}, {})", request, result, matchType);
+
+        Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
+
+        if (CollectionUtils.isNotEmpty(allRequestedAccesses)) {
+            Map<String, RangerAccessResult> accessTypeResults = 
RangerAccessRequestUtil.getAccessTypeResults(request);
+
+            for (String accessType : allRequestedAccesses) {
+                LOG.debug("Checking for accessType:[{}]", accessType);
+
+                RangerAccessResult denyResult  = null;
+                RangerAccessResult allowResult = null;
+                boolean            noResult    = false;
+
+                RangerAccessRequestWrapper oneRequest = new 
RangerAccessRequestWrapper(request, accessType);
+                RangerAccessResult         oneResult  = new 
RangerAccessResult(result.getPolicyType(), result.getServiceName(), 
result.getServiceDef(), oneRequest);
+
+                oneResult.setAuditResultFrom(result);
+
+                RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(oneRequest, oneResult);
+
+                if (matchedPolicyItem != null) {
+                    matchedPolicyItem.updateAccessResult(this, oneResult, 
matchType);
+                } else if (getPolicy().getIsDenyAllElse() && 
(getPolicy().getPolicyType() == null || getPolicy().getPolicyType() == 
RangerPolicy.POLICY_TYPE_ACCESS)) {
+                    updateAccessResult(oneResult, matchType, false, "matched 
deny-all-else policy");
+                }
+
+                if (oneResult.getIsAllowed()) {
+                    allowResult = oneResult;
+                } else if (oneResult.getIsAccessDetermined()) {
+                    denyResult = oneResult;
+                } else {
+                    noResult = true;
+                }
+
+                if (!noResult) {
+                    RangerAccessResult oldResult = 
accessTypeResults.get(accessType);
+                    if (oldResult == null) {
+                        accessTypeResults.put(accessType, allowResult != null 
? allowResult : denyResult);
+                    } else {
+                        int oldPriority = oldResult.getPolicyPriority();
+                        if (oldResult.getIsAllowed()) {
+                            if (denyResult != null) {
+                                if (getPolicyPriority() >= oldPriority) {
+                                    accessTypeResults.put(accessType, 
denyResult);
+                                }
+                            } else {
+                                if (getPolicy().getPolicyType() == null || 
getPolicy().getPolicyType() == RangerPolicy.POLICY_TYPE_ACCESS) {
+                                    if (getPolicyPriority() > oldPriority) {
+                                        accessTypeResults.put(accessType, 
allowResult);
+                                    }
+                                } else {
+                                    if (getPolicyPriority() >= oldPriority) {
+                                        accessTypeResults.put(accessType, 
allowResult);
+                                    }
+                                }
+                            }
+                        } else { // Earlier evaluator denied this access
+                            if (getPolicyPriority() >= oldPriority && 
allowResult != null && (oneRequest.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(oneRequest.getContext()))) {
+                                accessTypeResults.put(accessType, allowResult);
+                            } else {
+                                if (getPolicyPriority() > oldPriority && 
denyResult != null) {
+                                    accessTypeResults.put(accessType, 
denyResult);
+                                }
+                            }
+                        }
+                    }
+                    /* At least one access is allowed or denied - this 
evaluator need not be checked for other accesses as the test below
+                     * implies that there is only one access group in the 
request
+                     */
+                    if (oneRequest.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(oneRequest.getContext())) {
+                        if (oneRequest.ignoreDescendantDeny() && allowResult 
!= null) {
+                            break;
+                        } else if (!oneRequest.ignoreDescendantDeny() && 
denyResult != null) {
+                            break;
+                        }
+                    }
+                }
+            }
+
+            RangerAccessResult compositeAccessResult = 
getCompositeAccessResult(request, result);
+            if (compositeAccessResult != null) {
+                result.setAccessResultFrom(compositeAccessResult);
+            }
+        } else {
+            RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, result);
+            if (matchedPolicyItem != null) {
+                matchedPolicyItem.updateAccessResult(this, result, matchType);
+            } else if (getPolicy().getIsDenyAllElse() && 
(getPolicy().getPolicyType() == null || getPolicy().getPolicyType() == 
RangerPolicy.POLICY_TYPE_ACCESS)) {
+                updateAccessResult(result, matchType, false, "matched 
deny-all-else policy");
+            }
         }
+
+        LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems({}, 
{}, {})", request, result, matchType);
     }
 
-       @Override
-       public boolean isMatch(RangerAccessResource resource, Map<String, 
Object> evalContext) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isMatch(policy-id=" + getPolicyId() + ", " + 
resource + ", " + evalContext + ")");
-               }
+    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, 
Set<String> userGroups, Set<String> roles, String owner, String accessType) {
+        LOG.debug("==> 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem({}, {}, {}, {}, {})", 
user, userGroups, roles, owner, accessType);
+
+        RangerPolicyItemEvaluator ret;
 
-               boolean ret = false;
+        /*
+         *  1. if a deny matches without hitting any deny-exception, return 
that
+         *  2. if an allow matches without hitting any allow-exception, return 
that
+         */
+        ret = getMatchingPolicyItem(user, userGroups, roles, owner, 
accessType, denyEvaluators, denyExceptionEvaluators);
 
-               RangerPerfTracer perf = null;
+        if (ret == null) {
+            ret = getMatchingPolicyItem(user, userGroups, roles, owner, 
accessType, allowEvaluators, allowExceptionEvaluators);
+        }
 
-               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + 
evalContext + "," + perfTag + ")");
-               }
+        LOG.debug("<== 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem({}, {}, {}, {}, {}): {}", 
user, userGroups, roles, owner, accessType, ret);
 
-               for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
-                       RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
+        return ret;
+    }
 
-                       ret = resourceMatcher != null && 
resourceMatcher.isMatch(resource, evalContext);
+    /*
+        This API is called by policy-engine to support components which need 
to statically determine Ranger ACLs
+        for a given resource. It will always return a non-null object. The 
accesses that cannot be determined
+        statically will be marked as CONDITIONAL.
+    */
 
-                       if (ret) {
-                               break;
-                       }
-               }
+    protected boolean isMatch(RangerPolicy policy, Map<String, Object> 
evalContext) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch({}, {})", 
policy.getId(), evalContext);
 
-               RangerPerfTracer.log(perf);
+        final boolean ret = isMatch(policy.getResources(), evalContext);
 
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isMatch(policy-id=" + getPolicyId() + ", " + 
resource + ", " + evalContext + ") : " + ret);
-               }
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch({}, {}): {}", 
policy.getId(), evalContext, ret);
 
-               return ret;
-       }
+        return ret;
+    }
 
-       @Override
-       public boolean isCompleteMatch(RangerAccessResource resource, 
Map<String, Object> evalContext) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ", " + evalContext 
+ ")");
-               }
+    protected boolean isMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext) {
+        LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch({}, {})", 
resources, evalContext);
 
-               final boolean ret;
+        boolean ret = false;
 
-               List<RangerPolicyResourceEvaluator> resourceEvaluators = 
getResourceEvaluators();
+        for (RangerPolicyResourceEvaluator resourceEvaluator : 
getResourceEvaluators()) {
+            RangerPolicyResourceMatcher resourceMatcher = 
resourceEvaluator.getPolicyResourceMatcher();
 
-               if (resourceEvaluators.size() == 1) {
-                       RangerPolicyResourceEvaluator resourceEvaluator = 
resourceEvaluators.get(0);
-                       RangerPolicyResourceMatcher   resourceMatcher   = 
resourceEvaluator.getPolicyResourceMatcher();
+            ret = resourceMatcher != null && 
resourceMatcher.isMatch(resources, evalContext);
 
-                       ret = resourceMatcher != null && 
resourceMatcher.isCompleteMatch(resource, evalContext);
-               } else {
-                       ret = false;
-               }
+            if (ret) {
+                break;
+            }
+        }
 
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + "): " + ret);
-               }
-
-               return ret;
-       }
-
-       @Override
-       public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources, List<Map<String, RangerPolicyResource>> additionalResources, 
Map<String, Object> evalContext) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ", " + evalContext 
+ ")");
-               }
+        LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch({}, {}): {}", 
resources, evalContext, ret);
 
-               boolean ret = false;
-
-               List<RangerPolicyResourceEvaluator> resourceEvaluators = 
getResourceEvaluators();
+        return ret;
+    }
 
-               for (int i = 0; i < resourceEvaluators.size(); i++) {
-                       RangerPolicyResourceEvaluator     resourceEvaluator = 
resourceEvaluators.get(i);
-                       RangerPolicyResourceMatcher       resourceMatcher   = 
resourceEvaluator.getPolicyResourceMatcher();
-                       Map<String, RangerPolicyResource> policyResource    = 
null;
-
-                       if (i == 0) {
-                               policyResource = resources;
-                       } else if (additionalResources != null && 
additionalResources.size() >= i) {
-                               policyResource = additionalResources.get(i - 1);
-                       }
-
-                       ret = resourceMatcher != null && policyResource != null 
&& resourceMatcher.isCompleteMatch(policyResource, evalContext);
+    /*
+        This API is only called during initialization of Policy Evaluator if 
policy-engine is configured to use
+        PolicyACLSummary for access evaluation (that is, if 
disableAccessEvaluationWithPolicyACLSummary option
+        is set to false). It may return null object if all accesses for all 
user/groups cannot be determined statically.
+    */
+
+    protected boolean isAccessAllowed(String user, Set<String> userGroups, 
Set<String> roles, String owner, String accessType) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> 
RangerDefaultPolicyEvaluator.isAccessAllowed(policy-id={}, {}, {}, {}, {}, 
{})", getPolicyId(), user, userGroups, roles, owner, accessType);
+        }
+
+        boolean ret = false;
+
+        RangerPerfTracer perf = null;
+
+        if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+            perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isAccessAllowed(hashCode=" + 
Integer.toHexString(System.identityHashCode(this)) + "," + perfTag + ")");
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Using policyItemEvaluators for checking if access is 
allowed. PolicyId=[{}]", getPolicyId());
+        }
+
+        RangerPolicyItemEvaluator item = this.getDeterminingPolicyItem(user, 
userGroups, roles, owner, accessType);
+
+        if (item != null && item.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW) {
+            ret = true;
+        }
+
+        RangerPerfTracer.log(perf);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== 
RangerDefaultPolicyEvaluator.isAccessAllowed(policy-id={}, {}, {}, {}, {}, {}): 
{}", getPolicyId(), user, userGroups, roles, owner, accessType, ret);
+        }
+
+        return ret;
+    }
+
+    protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef 
serviceDef, RangerPolicyEngineOptions options) {
+        if (policy == null || (!hasAllow() && !hasDeny()) || serviceDef == 
null) {
+            return;
+        }
+
+        /*

Review Comment:
   may be the commented lines can be removed, not sure.



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java:
##########
@@ -584,5 +529,43 @@ private ValueWithBorrow 
getPastFieldValueWithBorrow(RangerValidityRecurrence.Rec
             }
             return ret;
         }
+
+        private static class ValueWithBorrow {
+            int     value;
+            boolean borrow;
+
+            ValueWithBorrow() {
+            }
+
+            ValueWithBorrow(int value) {
+                this(value, false);
+            }
+
+            ValueWithBorrow(int value, boolean borrow) {
+                this.value  = value;
+                this.borrow = borrow;
+            }
+
+            @Override
+            public String toString() {

Review Comment:
   nit: toString() may be the last function in a class.



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java:
##########
@@ -73,41 +71,48 @@ public RangerDefaultPolicyResourceMatcher(boolean 
forceEnableWildcardMatch) {
         this.forceEnableWildcardMatch = forceEnableWildcardMatch;
     }
 
-    @Override
-    public void setServiceDef(RangerServiceDef serviceDef) {
-        if (isInitialized) {
-            LOG.warn("RangerDefaultPolicyResourceMatcher is already 
initialized. init() must be done again after updating serviceDef");
+    public static boolean isHierarchyValidForResources(List<RangerResourceDef> 
hierarchy, Map<String, ?> resources) {
+        if (LOG.isDebugEnabled()) {

Review Comment:
   nit: please check for occurrences of isDebugEnabled in this file.



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerValidityScheduleEvaluator.java:
##########
@@ -96,11 +92,37 @@ public RangerValidityScheduleEvaluator(String startTimeStr, 
String endTimeStr, S
         }
     }
 
-    public boolean isApplicable(long accessTime) {
+    public static long getAdjustedTime(long localTime, TimeZone timeZone) {
+        long ret = localTime;
+
+        if (LOG.isDebugEnabled()) {

Review Comment:
   nit: please check for occurrences of isDebugEnabled in this file.



##########
agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestCacheMap.java:
##########
@@ -28,89 +28,79 @@
 import java.util.Set;
 
 public class TestCacheMap {
-       private static final Logger LOG = 
LoggerFactory.getLogger(TestCacheMap.class);
-       private static CacheMap<String, String> testCacheMap;
-       private static int initialCapacity = 16;
-
-       @BeforeClass
-       public static void setUpBeforeClass() throws Exception {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> TestCacheMap.setUpBeforeClass(), 
initialCapacity:" + initialCapacity);
-               }
-
-               testCacheMap = new CacheMap<String, String>(initialCapacity);
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== TestCacheMap.setUpBeforeClass(), 
initialCapacity:" + initialCapacity);
-               }
-       }
-       @AfterClass
-       public static void tearDownAfterClass() throws Exception {
-       }
-
-       @Test
-       public void runTests() {
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> TestCacheMap.runTests(), First batch of 
" + initialCapacity + " inserts starting from 0");
-               }
-               for (int i = 0; i < initialCapacity; i++) {
-                       String key = String.valueOf(i);
-                       String value = key;
-
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("TestCacheMap.runTests(), Inserting 
into Cache, key:" + key + ", value:" + value);
-                       }
-                       testCacheMap.put(key, value);
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("TestCacheMap.runTests(), Cache Size 
after insert(): " + testCacheMap.size());
-                       }
-               }
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("TestCacheMap.runTests(), First batch of " + 
initialCapacity/2 + " retrieves counting down from " + (initialCapacity/2-1));
-               }
-
-               for (int i = initialCapacity/2 - 1; i >= 0; i--) {
-                       String key = String.valueOf(i);
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("TestCacheMap.runTests(), Searching 
Cache, key:" + key);
-                       }
-                       String value = testCacheMap.get(key);
-                       if (value == null || !value.equals(key)) {
-                               LOG.error("TestCacheMap.runTests(), Did not get 
correct value for key, key:" + key + ", value:" + value);
-                       }
-               }
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("TestCacheMap.runTests(), Second batch of " + 
initialCapacity/2 + " inserts starting from " + initialCapacity);
-               }
-               for (int i = initialCapacity; i < 
initialCapacity+initialCapacity/2; i++) {
-                       String key = String.valueOf(i);
-                       String value = key;
-
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("TestCacheMap.runTests(), Inserting 
into Cache, key:" + key + ", value:" + value);
-                       }
-                       testCacheMap.put(key, value);
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("TestCacheMap.runTests(), Cache Size 
after insert(): " + testCacheMap.size());
-                       }
-               }
-
-               Set<String> keySet = testCacheMap.keySet();
-
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("TestCacheMap.runTests(), KeySet Size:" + 
keySet.size());
-                       LOG.debug("TestCacheMap.runTests(), printing keys..");
-
-                   int i = 0;
-
-                   for (String key : keySet) {
-                               LOG.debug("TestCacheMap.runTests(), index:" + 
i++ + ", key:" + key);
-                       }
-
-                       LOG.debug("<== TestCacheMap.runTests()");
-               }
-
-       }
+    private static final Logger LOG = 
LoggerFactory.getLogger(TestCacheMap.class);
+
+    private static       CacheMap<String, String> testCacheMap;
+    private static final int                      initialCapacity = 16;
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        LOG.debug("==> TestCacheMap.setUpBeforeClass(), initialCapacity:{}", 
initialCapacity);
+
+        testCacheMap = new CacheMap<>(initialCapacity);
+
+        LOG.debug("<== TestCacheMap.setUpBeforeClass(), initialCapacity:{}", 
initialCapacity);
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+    }
+
+    @Test
+    public void runTests() {
+        LOG.debug("==> TestCacheMap.runTests(), First batch of {} inserts 
starting from 0", initialCapacity);
+
+        for (int i = 0; i < initialCapacity; i++) {
+            String key   = String.valueOf(i);
+            String value = key;
+
+            LOG.debug("TestCacheMap.runTests(), Inserting into Cache, key:{}, 
value:{}", key, value);
+
+            testCacheMap.put(key, value);
+
+            LOG.debug("TestCacheMap.runTests(), Cache Size after insert(): 
{}", testCacheMap.size());
+        }
+
+        LOG.debug("TestCacheMap.runTests(), First batch of {} retrieves 
counting down from {}", initialCapacity / 2, (initialCapacity / 2 - 1));
+
+        for (int i = initialCapacity / 2 - 1; i >= 0; i--) {
+            String key = String.valueOf(i);
+
+            LOG.debug("TestCacheMap.runTests(), Searching Cache, key:{}", key);
+
+            String value = testCacheMap.get(key);
+
+            if (value == null || !value.equals(key)) {
+                LOG.error("TestCacheMap.runTests(), Did not get correct value 
for key, key:{}, value:{}", key, value);
+            }
+        }
+
+        LOG.debug("TestCacheMap.runTests(), Second batch of {} inserts 
starting from {}", initialCapacity / 2, initialCapacity);
+
+        for (int i = initialCapacity; i < initialCapacity + initialCapacity / 
2; i++) {
+            String key   = String.valueOf(i);
+            String value = key;
+
+            LOG.debug("TestCacheMap.runTests(), Inserting into Cache, key:{}, 
value:{}", key, value);
+
+            testCacheMap.put(key, value);
+
+            LOG.debug("TestCacheMap.runTests(), Cache Size after insert(): 
{}", testCacheMap.size());
+        }
+
+        Set<String> keySet = testCacheMap.keySet();
+
+        if (LOG.isDebugEnabled()) {

Review Comment:
   nit: isDebugEnabled may be removed.



##########
agents-common/src/main/java/org/apache/ranger/plugin/util/CachedResourceEvaluators.java:
##########
@@ -41,46 +41,15 @@
 import java.util.Set;
 
 public class CachedResourceEvaluators {
-    private final Map<String, Map<Map<String, 
RangerAccessRequest.ResourceElementMatchingScope>, 
Collection<RangerServiceResourceMatcher>>> cache     = new HashMap<>();
-    private final RangerReadWriteLock                                          
                                                             cacheLock = new 
RangerReadWriteLock(true);
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(CachedResourceEvaluators.class);
-    private static final Logger PERF_EVALUATORS_RETRIEVAL_LOG = 
RangerPerfTracer.getPerfLogger("CachedResourceEvaluators.retrieval");
+    private static final Logger                                                
                                                                    LOG         
                  = LoggerFactory.getLogger(CachedResourceEvaluators.class);
+    private static final Logger                                                
                                                                    
PERF_EVALUATORS_RETRIEVAL_LOG = 
RangerPerfTracer.getPerfLogger("CachedResourceEvaluators.retrieval");
+    private final        Map<String, Map<Map<String, 
RangerAccessRequest.ResourceElementMatchingScope>, 
Collection<RangerServiceResourceMatcher>>> cache                         = new 
HashMap<>();

Review Comment:
   we may keep a line space here.



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java:
##########
@@ -25,1375 +25,1481 @@
 import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.authorization.utils.StringUtil;
 import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
+import org.apache.ranger.plugin.util.JavaScriptEdits;
 import org.apache.ranger.plugin.util.MacroProcessor;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerTimeRangeChecker;
 import org.apache.ranger.plugin.util.RangerUserStore;
-import org.apache.ranger.plugin.util.JavaScriptEdits;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
+
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TimeZone;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static org.apache.ranger.plugin.util.RangerCommonConstants.*;
-
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TIME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACTION;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_IP_ADDRESS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_NAME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_FORWARDED_ADDRESSES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REMOTE_IP_ADDRESS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST_DATA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAGS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_UGA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ATTRIBUTES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUPS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUP_ATTRIBUTES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ROLES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__MATCH_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__NAME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__OWNER_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_ANY_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_NO_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_UG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_USER_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_AFTER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BEFORE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BETWEEN;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INCLUDES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INTERSECTS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_REQ;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_RES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_URNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX_JSON;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_ctx;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tag;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tagAttr;
 
 public final class RangerRequestScriptEvaluator {
-       private static final Logger LOG = 
LoggerFactory.getLogger(RangerRequestScriptEvaluator.class);
-
-       private static final Logger PERF_POLICY_CONDITION_SCRIPT_TOJSON         
= RangerPerfTracer.getPerfLogger("policy.condition.script.tojson");
-       private static final Logger PERF_POLICY_CONDITION_SCRIPT_EVAL           
= RangerPerfTracer.getPerfLogger("policy.condition.script.eval");
-       private static final String TAG_ATTR_DATE_FORMAT_PROP                   
= "ranger.plugin.tag.attr.additional.date.formats";
-       private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR              
= "||";
-       private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX        
= "\\|\\|";
-       private static final String DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT    
= "yyyy/MM/dd";
-       private static final String 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME = "ATLAS_DATE_FORMAT";
-       private static final String DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
-       private static final String SCRIPT_SAFE_PREEXEC                         
= "exit=null;quit=null;";
-       private static final String SCRIPT_PREEXEC                              
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
-                       SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
-                       SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
-                       SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ATTRIBUTES + ";" +
-                       SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUPS + ";" +
-                       SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" +
-                       SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_UGA + ";" +
-                       SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ROLES + ";" +
-                       SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG + ";" +
-                       SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAGS + ";" +
-                       SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG_NAMES + ";";
-       private static final Pattern JSON_VAR_NAMES_PATTERN   = 
Pattern.compile(getJsonVarNamesPattern());
-       private static final Pattern USER_ATTRIBUTES_PATTERN  = 
Pattern.compile(getUserAttributesPattern());
-       private static final Pattern GROUP_ATTRIBUTES_PATTERN = 
Pattern.compile(getGroupAttributesPattern());
-       private static final String  STR_QUOTE  = "'";
-       private static final String  STR_COMMA  = ",";
-
-       private static final MacroProcessor MACRO_PROCESSOR = new 
MacroProcessor(getMacrosMap());
-
-       private static String[] dateFormatStrings = null;
-
-       private final RangerAccessRequest              accessRequest;
-       private final ScriptEngine                     scriptEngine;
-       private final Bindings                         bindings;
-       private       boolean                          initDone   = false;
-       private       Map<String, String>              userAttrs  = 
Collections.emptyMap();
-       private       Map<String, Map<String, String>> groupAttrs = 
Collections.emptyMap();
-       private       Map<String, Map<String, Object>> tags       = 
Collections.emptyMap();
-       private       Map<String, Object>              tag        = 
Collections.emptyMap();
-       private       Collection<String>               userGroups = 
Collections.emptySet();
-       private       Collection<String>               userRoles  = 
Collections.emptySet();
-       private       Collection<String>               tagNames   = 
Collections.emptySet();
-       private       Boolean                          result     = false;
-
-       static {
-               init(null);
-       }
-
-       private static final ThreadLocal<List<SimpleDateFormat>> 
THREADLOCAL_DATE_FORMATS =
-                       new ThreadLocal<List<SimpleDateFormat>>() {
-                               @Override protected List<SimpleDateFormat> 
initialValue() {
-                                       List<SimpleDateFormat> ret = new 
ArrayList<>();
-
-                                       for (String dateFormatString : 
dateFormatStrings) {
-                                               try {
-                                                       if 
(StringUtils.isNotBlank(dateFormatString)) {
-                                                               if 
(StringUtils.equalsIgnoreCase(dateFormatString, 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) {
-                                                                       
dateFormatString = DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT;
-                                                               }
-                                                               
SimpleDateFormat df = new SimpleDateFormat(dateFormatString);
-                                                               
df.setLenient(false);
-                                                               ret.add(df);
-                                                       }
-                                               } catch (Exception exception) {
-                                                       // Ignore
-                                               }
-                                       }
-
-                                       return ret;
-                               }
-                       };
-
-
-       public static boolean needsJsonCtxEnabled(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
JSON_VAR_NAMES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasUserAttributeReference(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
USER_ATTRIBUTES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasGroupAttributeReference(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
GROUP_ATTRIBUTES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasUserGroupAttributeReference(String script) {
-               return hasUserAttributeReference(script) || 
hasGroupAttributeReference(script);
-       }
-
-       public static boolean hasUserGroupAttributeReference(Collection<String> 
scripts) {
-               boolean ret = false;
-
-               if (scripts != null) {
-                       for (String script : scripts) {
-                               if (hasUserGroupAttributeReference(script)) {
-                                       ret = true;
-
-                                       break;
-                               }
-                       }
-               }
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerRequestScriptEvaluator.class);
+
+    private static final Logger  PERF_POLICY_CONDITION_SCRIPT_TOJSON          
= RangerPerfTracer.getPerfLogger("policy.condition.script.tojson");
+    private static final Logger  PERF_POLICY_CONDITION_SCRIPT_EVAL            
= RangerPerfTracer.getPerfLogger("policy.condition.script.eval");
+    private static final String  TAG_ATTR_DATE_FORMAT_PROP                    
= "ranger.plugin.tag.attr.additional.date.formats";
+    private static final String  TAG_ATTR_DATE_FORMAT_SEPARATOR               
= "||";
+    private static final String  TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX         
= "\\|\\|";
+    private static final String  DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy/MM/dd";
+    private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME 
= "ATLAS_DATE_FORMAT";
+    private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT      
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
+    private static final String  SCRIPT_SAFE_PREEXEC                          
= "exit=null;quit=null;";
+    private static final String  SCRIPT_PREEXEC                               
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
+            SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
+            SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
+            SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ATTRIBUTES + ";" +
+            SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUPS + ";" +
+            SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" +
+            SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_UGA + 
";" +
+            SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ROLES + ";" +
+            SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG + 
";" +
+            SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAGS 
+ ";" +
+            SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG_NAMES + ";";
+    private static final Pattern JSON_VAR_NAMES_PATTERN                       
= Pattern.compile(getJsonVarNamesPattern());
+    private static final Pattern USER_ATTRIBUTES_PATTERN                      
= Pattern.compile(getUserAttributesPattern());
+    private static final Pattern GROUP_ATTRIBUTES_PATTERN                     
= Pattern.compile(getGroupAttributesPattern());
+    private static final String  STR_QUOTE                                    
= "'";
+    private static final String  STR_COMMA                                    
= ",";
+
+    private static final MacroProcessor MACRO_PROCESSOR = new 
MacroProcessor(getMacrosMap());
+
+    private static       String[]                            dateFormatStrings 
       = {};
+    private static final ThreadLocal<List<SimpleDateFormat>> 
THREADLOCAL_DATE_FORMATS = ThreadLocal.withInitial(() -> {
+        List<SimpleDateFormat> ret = new ArrayList<>();
+
+        for (String dateFormatString : dateFormatStrings) {
+            try {
+                if (StringUtils.isNotBlank(dateFormatString)) {
+                    if (StringUtils.equalsIgnoreCase(dateFormatString, 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) {
+                        dateFormatString = 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT;
+                    }
+                    SimpleDateFormat df = new 
SimpleDateFormat(dateFormatString);
+                    df.setLenient(false);
+                    ret.add(df);
+                }
+            } catch (Exception exception) {
+                // Ignore
+            }
+        }
+
+        return ret;
+    });
+
+    private final RangerAccessRequest                 accessRequest;
+    private final ScriptEngine                        scriptEngine;
+    private final Bindings                            bindings;
+    private       boolean                             initDone;
+    private       Map<String, String>                 userAttrs  = 
Collections.emptyMap();
+    private       Map<String, Map<String, String>>    groupAttrs = 
Collections.emptyMap();
+    private       Map<String, Map<String, Object>>    tags       = 
Collections.emptyMap();
+    private       Map<String, Object>                 tag        = 
Collections.emptyMap();
+    private       Collection<String>                  userGroups = 
Collections.emptySet();
+    private       Collection<String>                  userRoles  = 
Collections.emptySet();
+    private       Collection<String>                  tagNames   = 
Collections.emptySet();
+    private       boolean                             result;
+
+    public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine) {
+        this(accessRequest, scriptEngine, true);
+    }
+
+    public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine, boolean enableJsonCtx) {
+        this.accessRequest = accessRequest.getReadOnlyCopy();
+        this.scriptEngine  = scriptEngine;
+        this.bindings      = scriptEngine.createBindings();
+
+        RangerTagForEval    currentTag = this.getCurrentTag();
+        Map<String, String> tagAttribs = currentTag != null ? 
currentTag.getAttributes() : Collections.emptyMap();
+
+        bindings.put(SCRIPT_VAR_ctx, this);
+        bindings.put(SCRIPT_VAR_tag, currentTag);
+        bindings.put(SCRIPT_VAR_tagAttr, tagAttribs);
+
+        String preExecScript = "";
+
+        if (enableJsonCtx) {
+            bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson());
+
+            preExecScript += SCRIPT_PREEXEC;
+        }
+
+        if (StringUtils.isNotBlank(preExecScript)) {
+            try {
+                scriptEngine.eval(preExecScript, bindings);
+            } catch (ScriptException excp) {
+                LOG.error("RangerRequestScriptEvaluator(): initialization 
failed", excp);
+            }
+        }
+    }
+
+    public static boolean needsJsonCtxEnabled(String script) {
+        boolean ret = false;
+
+        if (script != null) {
+            Matcher matcher = JSON_VAR_NAMES_PATTERN.matcher(script);
+
+            ret = matcher.find();
+        }
+
+        return ret;
+    }
+
+    public static boolean hasUserAttributeReference(String script) {
+        boolean ret = false;
 
-               return ret;
-       }
-
-       public static String expandMacros(String script) {
-               return MACRO_PROCESSOR.expandMacros(script);
-       }
-
-       public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine) {
-               this(accessRequest, scriptEngine, true);
-       }
+        if (script != null) {
+            Matcher matcher = USER_ATTRIBUTES_PATTERN.matcher(script);
 
-       public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine, boolean enableJsonCtx) {
-               this.accessRequest = accessRequest.getReadOnlyCopy();
-               this.scriptEngine  = scriptEngine;
-               this.bindings      = scriptEngine.createBindings();
+            ret = matcher.find();
+        }
 
-               RangerTagForEval    currentTag = this.getCurrentTag();
-               Map<String, String> tagAttribs = currentTag != null ? 
currentTag.getAttributes() : Collections.emptyMap();
+        return ret;
+    }
 
-               bindings.put(SCRIPT_VAR_ctx, this);
-               bindings.put(SCRIPT_VAR_tag, currentTag);
-               bindings.put(SCRIPT_VAR_tagAttr, tagAttribs);
-
-               String preExecScript = "";
+    public static boolean hasGroupAttributeReference(String script) {
+        boolean ret = false;
 
-               if (enableJsonCtx) {
-                       bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson());
+        if (script != null) {
+            Matcher matcher = GROUP_ATTRIBUTES_PATTERN.matcher(script);
 
-                       preExecScript += SCRIPT_PREEXEC;
-               }
+            ret = matcher.find();
+        }
 
-               if (StringUtils.isNotBlank(preExecScript)) {
-                       try {
-                               scriptEngine.eval(preExecScript, bindings);
-                       } catch (ScriptException excp) {
-                               LOG.error("RangerRequestScriptEvaluator(): 
initialization failed", excp);
-                       }
-               }
-       }
+        return ret;
+    }
 
-       public Object evaluateScript(String script) {
-               script = expandMacros(script);
+    public static boolean hasUserGroupAttributeReference(String script) {
+        return hasUserAttributeReference(script) || 
hasGroupAttributeReference(script);
+    }
 
-               return evaluateScriptImpl(script);
-       }
+    public static boolean hasUserGroupAttributeReference(Collection<String> 
scripts) {
+        boolean ret = false;
 
-       public Object evaluateConditionScript(String script) {
-               Object ret = evaluateScript(script);
+        if (scripts != null) {
+            for (String script : scripts) {
+                if (hasUserGroupAttributeReference(script)) {
+                    ret = true;
 
-               if (ret == null) {
-                       ret = getResult();
-               }
+                    break;
+                }
+            }
+        }
 
-               if (ret instanceof Boolean) {
-                       result = (Boolean) ret;
-               }
+        return ret;
+    }
 
-               return ret;
-       }
+    public static String expandMacros(String script) {
+        return MACRO_PROCESSOR.expandMacros(script);
+    }
 
-       private Object evaluateScriptImpl(String script) {
-               Object           ret  = null;
-               RangerPerfTracer perf = null;
+    public static void init(Configuration config) {
+        StringBuilder sb = new 
StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT);
 
-               try {
-                       if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_EVAL)) {
-                               perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_EVAL, 
"RangerRequestScriptEvaluator.evaluateScript(requestHash=" + 
accessRequest.hashCode() + ")");
-                       }
+        
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME);
 
-                       String preExec = SCRIPT_SAFE_PREEXEC;
+        String additionalDateFormatsValue = config != null ? 
config.get(TAG_ATTR_DATE_FORMAT_PROP) : null;
 
-                       if (script.contains(".includes(")) {
-                               preExec += SCRIPT_POLYFILL_INCLUDES;
-                       }
+        if (StringUtils.isNotBlank(additionalDateFormatsValue)) {
+            
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(additionalDateFormatsValue);
+        }
 
-                       if (script.contains(".intersects(")) {
-                               preExec += SCRIPT_POLYFILL_INTERSECTS;
-                       }
+        String[] formatStrings = 
sb.toString().split(TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX);
 
-                       if (JavaScriptEdits.hasDoubleBrackets(script)) {
-                               script = 
JavaScriptEdits.replaceDoubleBrackets(script);
-                       }
+        Arrays.sort(formatStrings, (first, second) -> 
Integer.compare(second.length(), first.length()));
 
-                       ret = scriptEngine.eval(preExec + script, bindings);
-               } catch (NullPointerException nullp) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): eval called with NULL 
argument(s)", nullp);
-               } catch (ScriptException excp) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate 
script", excp);
-               } catch (Throwable t) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate 
script", t);
-               } finally {
-                       RangerPerfTracer.log(perf);
-               }
+        RangerRequestScriptEvaluator.dateFormatStrings = formatStrings;
+    }
 
-               return ret;
-       }
+    public Object evaluateScript(String script) {
+        script = expandMacros(script);
 
-       private String toJson() {
-               RangerPerfTracer perf = null;
+        return evaluateScriptImpl(script);
+    }
 
-               if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_TOJSON)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_TOJSON, 
"RangerRequestScriptEvaluator.toJson(requestHash=" + accessRequest.hashCode() + 
")");
-               }
+    public Object evaluateConditionScript(String script) {
+        Object ret = evaluateScript(script);
 
-               Map<String, Object> ret        = new HashMap<>();
-               Map<String, Object> request    = new HashMap<>();
-               Date                accessTime = accessRequest.getAccessTime();
+        if (ret == null) {
+            ret = getResult();
+        }
 
-               init();
+        if (ret instanceof Boolean) {
+            result = (Boolean) ret;
+        }
 
-               if (accessTime != null) {
-                       request.put(SCRIPT_FIELD_ACCESS_TIME, 
accessTime.getTime());
-               }
+        return ret;
+    }
 
-               request.put(SCRIPT_FIELD_ACCESS_TYPE, 
accessRequest.getAccessType());
-               request.put(SCRIPT_FIELD_ACTION, accessRequest.getAction());
-               request.put(SCRIPT_FIELD_CLIENT_IP_ADDRESS, 
accessRequest.getClientIPAddress());
-               request.put(SCRIPT_FIELD_CLIENT_TYPE, 
accessRequest.getClientType());
-               request.put(SCRIPT_FIELD_CLUSTER_NAME, 
accessRequest.getClusterName());
-               request.put(SCRIPT_FIELD_CLUSTER_TYPE, 
accessRequest.getClusterType());
-               request.put(SCRIPT_FIELD_FORWARDED_ADDRESSES, 
accessRequest.getForwardedAddresses());
-               request.put(SCRIPT_FIELD_REMOTE_IP_ADDRESS, 
accessRequest.getRemoteIPAddress());
-               request.put(SCRIPT_FIELD_REQUEST_DATA, 
accessRequest.getRequestData());
+    public String getResource() {
+        String               ret = null;
+        RangerAccessResource val = 
RangerAccessRequestUtil.getCurrentResourceFromContext(getRequestContext());
 
-               if (accessRequest.getResource() != null) {
-                       Map<String, Object> resource = new 
HashMap<>(accessRequest.getResource().getAsMap());
+        if (val != null) {
+            ret = val.getAsString();
+        }
 
-                       resource.put(SCRIPT_FIELD__OWNER_USER, 
accessRequest.getResource().getOwnerUser());
+        return ret;
+    }
 
-                       request.put(SCRIPT_FIELD_RESOURCE, resource);
-               }
+    public String getResourceZone() {
+        String ret = 
RangerAccessRequestUtil.getResourceZoneNameFromContext(getRequestContext());
 
-               request.put(SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE, 
accessRequest.getResourceMatchingScope());
+        return ret != null ? ret : StringUtils.EMPTY;
+    }
 
-               request.put(SCRIPT_FIELD_USER, getUser());
-               request.put(SCRIPT_FIELD_USER_GROUPS, userGroups);
-               request.put(SCRIPT_FIELD_USER_ROLES, userRoles);
+    public Set<String> getResourceZones() {
+        Set<String> ret = 
RangerAccessRequestUtil.getResourceZoneNamesFromContext(getRequestContext());
 
-               request.put(SCRIPT_FIELD_USER_ATTRIBUTES, userAttrs);
+        return ret != null ? Collections.emptySet() : ret;
+    }
 
-               request.put(SCRIPT_FIELD_USER_GROUP_ATTRIBUTES, groupAttrs);
-               request.put(SCRIPT_FIELD_UGA, new 
UserGroupsAttributes(userGroups, groupAttrs).getAttributes());
+    public String getRequestContextAttribute(String attributeName) {
+        String ret = null;
 
-               ret.put(SCRIPT_FIELD_REQUEST, request);
+        if (StringUtils.isNotBlank(attributeName)) {
+            Object val = getRequestContext().get(attributeName);
 
-               ret.put(SCRIPT_FIELD_TAGS, tags);
-               ret.put(SCRIPT_FIELD_TAG_NAMES, tagNames);
-               ret.put(SCRIPT_FIELD_TAG, tag);
+            if (val != null) {
+                ret = val.toString();
+            }
+        }
 
-               String strRet = JsonUtils.objectToJson(ret);
+        return ret;
+    }
 
-               RangerPerfTracer.log(perf);
+    public boolean isAccessTypeAny() {
+        return accessRequest.isAccessTypeAny();
+    }
 
-               return strRet;
-       }
+    public boolean isAccessTypeDelegatedAdmin() {
+        return accessRequest.isAccessTypeDelegatedAdmin();
+    }
 
-       public static void init(Configuration config) {
-               StringBuilder sb = new 
StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT);
+    public String getUser() {
+        return accessRequest.getUser();
+    }
 
-               
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME);
+    public Set<String> getUserGroups() {
+        return accessRequest.getUserGroups();
+    }
 
-               String additionalDateFormatsValue = config != null ? 
config.get(TAG_ATTR_DATE_FORMAT_PROP) : null;
+    public Set<String> getUserRoles() {
+        return RangerAccessRequestUtil.getUserRoles(accessRequest);
+    }
+
+    public Date getAccessTime() {
+        return accessRequest.getAccessTime() != null ? 
accessRequest.getAccessTime() : new Date();
+    }
+
+    public String getClientIPAddress() {
+        return accessRequest.getClientIPAddress();
+    }
+
+    public String getClientType() {
+        return accessRequest.getClientType();
+    }
+
+    public String getAction() {
+        return accessRequest.getAction();
+    }
+
+    public String getRequestData() {
+        return accessRequest.getRequestData();
+    }
+
+    public String getSessionId() {
+        return accessRequest.getSessionId();
+    }
+
+    public RangerTagForEval getCurrentTag() {
+        RangerTagForEval ret = 
RangerAccessRequestUtil.getCurrentTagFromContext(getRequestContext());
+
+        if (ret == null) {
+            if (LOG.isDebugEnabled()) {

Review Comment:
   nit: isDebugEnabled() can be removed.



##########
agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngineForDeltas.java:
##########
@@ -289,119 +290,117 @@ private void runTests(InputStreamReader reader, String 
testName) {
         policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
         policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
 
-               PolicyEngineTestCase.TestsInfo testsInfo = testCase.testsInfo;
-               do {
-                       runTestCaseTests(policyEngine, testCase.serviceDef, 
testName, testsInfo.tests);
-                       if (testsInfo.updatedPolicies != null && 
CollectionUtils.isNotEmpty(testsInfo.updatedPolicies.policyDeltas)) {
-                               
servicePolicies.setPolicyDeltas(testsInfo.updatedPolicies.policyDeltas);
-                               servicePolicies.setPolicies(null);
-                               if 
(MapUtils.isNotEmpty(testsInfo.updatedPolicies.securityZones)) {
-                                       
servicePolicies.setSecurityZones(testsInfo.updatedPolicies.securityZones);
-                               }
-                               policyEngine = (RangerPolicyEngineImpl) 
RangerPolicyEngineImpl.getPolicyEngine(policyEngine, servicePolicies);
-
-                               testsInfo = null;
-                       } else {
-                               testsInfo = null;
-                       }
-
-               } while (testsInfo != null && testsInfo.tests != null);
-
-       }
+        PolicyEngineTestCase.TestsInfo testsInfo = testCase.testsInfo;
+        do {
+            runTestCaseTests(policyEngine, testCase.serviceDef, testName, 
testsInfo.tests);
+            if (testsInfo.updatedPolicies != null && 
CollectionUtils.isNotEmpty(testsInfo.updatedPolicies.policyDeltas)) {
+                
servicePolicies.setPolicyDeltas(testsInfo.updatedPolicies.policyDeltas);
+                servicePolicies.setPolicies(null);
+                if 
(MapUtils.isNotEmpty(testsInfo.updatedPolicies.securityZones)) {
+                    
servicePolicies.setSecurityZones(testsInfo.updatedPolicies.securityZones);
+                }
+                policyEngine = (RangerPolicyEngineImpl) 
RangerPolicyEngineImpl.getPolicyEngine(policyEngine, servicePolicies);
+
+                testsInfo = null;
+            } else {
+                testsInfo = null;
+            }
+        }
+        while (testsInfo != null && testsInfo.tests != null);
+    }
 
     private void runTestCaseTests(RangerPolicyEngine policyEngine, 
RangerServiceDef serviceDef, String testName, List<TestData> tests) {
         RangerAccessRequest request;
 
-        for(TestData test : tests) {
-                       request = test.request;
-
-                       if 
(request.getContext().containsKey(RangerAccessRequestUtil.KEY_CONTEXT_TAGS) ||
-                                       
request.getContext().containsKey(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES))
 {
-                               // Create a new AccessRequest
-                               RangerAccessRequestImpl newRequest =
-                                               new 
RangerAccessRequestImpl(request.getResource(), request.getAccessType(),
-                                                               
request.getUser(), request.getUserGroups(), null);
-
-                               
newRequest.setClientType(request.getClientType());
-                               
newRequest.setAccessTime(request.getAccessTime());
-                               newRequest.setAction(request.getAction());
-                               
newRequest.setRemoteIPAddress(request.getRemoteIPAddress());
-                               
newRequest.setForwardedAddresses(request.getForwardedAddresses());
-                               
newRequest.setRequestData(request.getRequestData());
-                               newRequest.setSessionId(request.getSessionId());
-
-                               Map<String, Object> context = 
request.getContext();
-                               String tagsJsonString = (String) 
context.get(RangerAccessRequestUtil.KEY_CONTEXT_TAGS);
-                               
context.remove(RangerAccessRequestUtil.KEY_CONTEXT_TAGS);
-
-                               if(!StringUtils.isEmpty(tagsJsonString)) {
-                                       try {
-                                               Type setType = new 
TypeToken<Set<RangerTagForEval>>() {
-                                               }.getType();
-                                               Set<RangerTagForEval> tags = 
gsonBuilder.fromJson(tagsJsonString, setType);
-
-                                               
context.put(RangerAccessRequestUtil.KEY_CONTEXT_TAGS, tags);
-                                       } catch (Exception e) {
-                                               
System.err.println("TestPolicyEngineForDeltas.runTests(): error parsing TAGS 
JSON string in file " + testName + ", tagsJsonString=" +
-                                                               tagsJsonString 
+ ", exception=" + e);
-                                       }
-                               } else if 
(request.getContext().containsKey(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES))
 {
-                                       String resourcesJsonString = (String) 
context.get(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES);
-                                       
context.remove(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES);
-                                       if 
(!StringUtils.isEmpty(resourcesJsonString)) {
-                                               try {
-                                                       /*
-                                                       Reader stringReader = 
new StringReader(resourcesJsonString);
-                                                       
RangerRequestedResources resources = gsonBuilder.fromJson(stringReader, 
RangerRequestedResources.class);
-                                                       */
-
-                                                       Type myType = new 
TypeToken<RangerRequestedResources>() {
-                                                       }.getType();
-                                                       
RangerRequestedResources resources = gsonBuilder.fromJson(resourcesJsonString, 
myType);
-
-                                                       
context.put(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES, resources);
-                                               } catch (Exception e) {
-                                                       
System.err.println("TestPolicyEngineForDeltas.runTests(): error parsing 
REQUESTED_RESOURCES string in file " + testName + ", resourcesJsonString=" +
-                                                                       
resourcesJsonString + ", exception=" + e);
-                                               }
-                                       }
-                               }
-                               newRequest.setContext(context);
-
-                               // accessResource.ServiceDef is set here, so 
that we can skip call to policyEngine.preProcess() which
-                               // sets the serviceDef in the resource AND 
calls enrichers. We dont want enrichers to be called when
-                               // context already contains tags -- This may 
change when we want enrichers to enrich request in the
-                               // presence of tags!!!
-
-                               // Safe cast
-                               RangerAccessResourceImpl accessResource = 
(RangerAccessResourceImpl) request.getResource();
-                               accessResource.setServiceDef(serviceDef);
-
-                               request = newRequest;
-
-                       }
-
-                       RangerAccessResultProcessor auditHandler = new 
RangerDefaultAuditHandler();
-
-                       if(test.result != null) {
+        for (TestData test : tests) {
+            request = test.request;
+
+            if 
(request.getContext().containsKey(RangerAccessRequestUtil.KEY_CONTEXT_TAGS) ||
+                    
request.getContext().containsKey(RangerAccessRequestUtil.KEY_CONTEXT_REQUESTED_RESOURCES))
 {
+                // Create a new AccessRequest
+                RangerAccessRequestImpl newRequest =

Review Comment:
   single line may be used here.
   



##########
agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java:
##########
@@ -25,1375 +25,1481 @@
 import org.apache.ranger.authorization.utils.JsonUtils;
 import org.apache.ranger.authorization.utils.StringUtil;
 import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
+import org.apache.ranger.plugin.util.JavaScriptEdits;
 import org.apache.ranger.plugin.util.MacroProcessor;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerTimeRangeChecker;
 import org.apache.ranger.plugin.util.RangerUserStore;
-import org.apache.ranger.plugin.util.JavaScriptEdits;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.script.Bindings;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
+
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TimeZone;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static org.apache.ranger.plugin.util.RangerCommonConstants.*;
-
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TIME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACTION;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_IP_ADDRESS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_NAME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_FORWARDED_ADDRESSES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REMOTE_IP_ADDRESS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST_DATA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAGS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_UGA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ATTRIBUTES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUPS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUP_ATTRIBUTES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ROLES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__MATCH_TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__NAME;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__OWNER_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__TYPE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_Q;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_ANY_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_NO_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_UG_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_USER_ATTR;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_AFTER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BEFORE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BETWEEN;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_GROUP;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_ROLE;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_Q_CSV;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INCLUDES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INTERSECTS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_REQ;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_RES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGS;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UG;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGA;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_URNAMES;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_USER;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX_JSON;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_ctx;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tag;
+import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tagAttr;
 
 public final class RangerRequestScriptEvaluator {
-       private static final Logger LOG = 
LoggerFactory.getLogger(RangerRequestScriptEvaluator.class);
-
-       private static final Logger PERF_POLICY_CONDITION_SCRIPT_TOJSON         
= RangerPerfTracer.getPerfLogger("policy.condition.script.tojson");
-       private static final Logger PERF_POLICY_CONDITION_SCRIPT_EVAL           
= RangerPerfTracer.getPerfLogger("policy.condition.script.eval");
-       private static final String TAG_ATTR_DATE_FORMAT_PROP                   
= "ranger.plugin.tag.attr.additional.date.formats";
-       private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR              
= "||";
-       private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX        
= "\\|\\|";
-       private static final String DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT    
= "yyyy/MM/dd";
-       private static final String 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME = "ATLAS_DATE_FORMAT";
-       private static final String DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
-       private static final String SCRIPT_SAFE_PREEXEC                         
= "exit=null;quit=null;";
-       private static final String SCRIPT_PREEXEC                              
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
-                       SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
-                       SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
-                       SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ATTRIBUTES + ";" +
-                       SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUPS + ";" +
-                       SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" +
-                       SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_UGA + ";" +
-                       SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ROLES + ";" +
-                       SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG + ";" +
-                       SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAGS + ";" +
-                       SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG_NAMES + ";";
-       private static final Pattern JSON_VAR_NAMES_PATTERN   = 
Pattern.compile(getJsonVarNamesPattern());
-       private static final Pattern USER_ATTRIBUTES_PATTERN  = 
Pattern.compile(getUserAttributesPattern());
-       private static final Pattern GROUP_ATTRIBUTES_PATTERN = 
Pattern.compile(getGroupAttributesPattern());
-       private static final String  STR_QUOTE  = "'";
-       private static final String  STR_COMMA  = ",";
-
-       private static final MacroProcessor MACRO_PROCESSOR = new 
MacroProcessor(getMacrosMap());
-
-       private static String[] dateFormatStrings = null;
-
-       private final RangerAccessRequest              accessRequest;
-       private final ScriptEngine                     scriptEngine;
-       private final Bindings                         bindings;
-       private       boolean                          initDone   = false;
-       private       Map<String, String>              userAttrs  = 
Collections.emptyMap();
-       private       Map<String, Map<String, String>> groupAttrs = 
Collections.emptyMap();
-       private       Map<String, Map<String, Object>> tags       = 
Collections.emptyMap();
-       private       Map<String, Object>              tag        = 
Collections.emptyMap();
-       private       Collection<String>               userGroups = 
Collections.emptySet();
-       private       Collection<String>               userRoles  = 
Collections.emptySet();
-       private       Collection<String>               tagNames   = 
Collections.emptySet();
-       private       Boolean                          result     = false;
-
-       static {
-               init(null);
-       }
-
-       private static final ThreadLocal<List<SimpleDateFormat>> 
THREADLOCAL_DATE_FORMATS =
-                       new ThreadLocal<List<SimpleDateFormat>>() {
-                               @Override protected List<SimpleDateFormat> 
initialValue() {
-                                       List<SimpleDateFormat> ret = new 
ArrayList<>();
-
-                                       for (String dateFormatString : 
dateFormatStrings) {
-                                               try {
-                                                       if 
(StringUtils.isNotBlank(dateFormatString)) {
-                                                               if 
(StringUtils.equalsIgnoreCase(dateFormatString, 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) {
-                                                                       
dateFormatString = DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT;
-                                                               }
-                                                               
SimpleDateFormat df = new SimpleDateFormat(dateFormatString);
-                                                               
df.setLenient(false);
-                                                               ret.add(df);
-                                                       }
-                                               } catch (Exception exception) {
-                                                       // Ignore
-                                               }
-                                       }
-
-                                       return ret;
-                               }
-                       };
-
-
-       public static boolean needsJsonCtxEnabled(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
JSON_VAR_NAMES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasUserAttributeReference(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
USER_ATTRIBUTES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasGroupAttributeReference(String script) {
-               boolean ret = false;
-
-               if (script != null) {
-                       Matcher matcher = 
GROUP_ATTRIBUTES_PATTERN.matcher(script);
-
-                       ret = matcher.find();
-               }
-
-               return ret;
-       }
-
-       public static boolean hasUserGroupAttributeReference(String script) {
-               return hasUserAttributeReference(script) || 
hasGroupAttributeReference(script);
-       }
-
-       public static boolean hasUserGroupAttributeReference(Collection<String> 
scripts) {
-               boolean ret = false;
-
-               if (scripts != null) {
-                       for (String script : scripts) {
-                               if (hasUserGroupAttributeReference(script)) {
-                                       ret = true;
-
-                                       break;
-                               }
-                       }
-               }
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerRequestScriptEvaluator.class);
+
+    private static final Logger  PERF_POLICY_CONDITION_SCRIPT_TOJSON          
= RangerPerfTracer.getPerfLogger("policy.condition.script.tojson");
+    private static final Logger  PERF_POLICY_CONDITION_SCRIPT_EVAL            
= RangerPerfTracer.getPerfLogger("policy.condition.script.eval");
+    private static final String  TAG_ATTR_DATE_FORMAT_PROP                    
= "ranger.plugin.tag.attr.additional.date.formats";
+    private static final String  TAG_ATTR_DATE_FORMAT_SEPARATOR               
= "||";
+    private static final String  TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX         
= "\\|\\|";
+    private static final String  DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy/MM/dd";
+    private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME 
= "ATLAS_DATE_FORMAT";
+    private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT      
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
+    private static final String  SCRIPT_SAFE_PREEXEC                          
= "exit=null;quit=null;";
+    private static final String  SCRIPT_PREEXEC                               
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
+            SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
+            SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
+            SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ATTRIBUTES + ";" +
+            SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUPS + ";" +
+            SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" +
+            SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_UGA + 
";" +
+            SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_USER_ROLES + ";" +
+            SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG + 
";" +
+            SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAGS 
+ ";" +
+            SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_TAG_NAMES + ";";
+    private static final Pattern JSON_VAR_NAMES_PATTERN                       
= Pattern.compile(getJsonVarNamesPattern());
+    private static final Pattern USER_ATTRIBUTES_PATTERN                      
= Pattern.compile(getUserAttributesPattern());
+    private static final Pattern GROUP_ATTRIBUTES_PATTERN                     
= Pattern.compile(getGroupAttributesPattern());
+    private static final String  STR_QUOTE                                    
= "'";
+    private static final String  STR_COMMA                                    
= ",";
+
+    private static final MacroProcessor MACRO_PROCESSOR = new 
MacroProcessor(getMacrosMap());
+
+    private static       String[]                            dateFormatStrings 
       = {};
+    private static final ThreadLocal<List<SimpleDateFormat>> 
THREADLOCAL_DATE_FORMATS = ThreadLocal.withInitial(() -> {
+        List<SimpleDateFormat> ret = new ArrayList<>();
+
+        for (String dateFormatString : dateFormatStrings) {
+            try {
+                if (StringUtils.isNotBlank(dateFormatString)) {
+                    if (StringUtils.equalsIgnoreCase(dateFormatString, 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) {
+                        dateFormatString = 
DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT;
+                    }
+                    SimpleDateFormat df = new 
SimpleDateFormat(dateFormatString);
+                    df.setLenient(false);
+                    ret.add(df);
+                }
+            } catch (Exception exception) {
+                // Ignore
+            }
+        }
+
+        return ret;
+    });
+
+    private final RangerAccessRequest                 accessRequest;
+    private final ScriptEngine                        scriptEngine;
+    private final Bindings                            bindings;
+    private       boolean                             initDone;
+    private       Map<String, String>                 userAttrs  = 
Collections.emptyMap();
+    private       Map<String, Map<String, String>>    groupAttrs = 
Collections.emptyMap();
+    private       Map<String, Map<String, Object>>    tags       = 
Collections.emptyMap();
+    private       Map<String, Object>                 tag        = 
Collections.emptyMap();
+    private       Collection<String>                  userGroups = 
Collections.emptySet();
+    private       Collection<String>                  userRoles  = 
Collections.emptySet();
+    private       Collection<String>                  tagNames   = 
Collections.emptySet();
+    private       boolean                             result;
+
+    public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine) {
+        this(accessRequest, scriptEngine, true);
+    }
+
+    public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine, boolean enableJsonCtx) {
+        this.accessRequest = accessRequest.getReadOnlyCopy();
+        this.scriptEngine  = scriptEngine;
+        this.bindings      = scriptEngine.createBindings();
+
+        RangerTagForEval    currentTag = this.getCurrentTag();
+        Map<String, String> tagAttribs = currentTag != null ? 
currentTag.getAttributes() : Collections.emptyMap();
+
+        bindings.put(SCRIPT_VAR_ctx, this);
+        bindings.put(SCRIPT_VAR_tag, currentTag);
+        bindings.put(SCRIPT_VAR_tagAttr, tagAttribs);
+
+        String preExecScript = "";
+
+        if (enableJsonCtx) {
+            bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson());
+
+            preExecScript += SCRIPT_PREEXEC;
+        }
+
+        if (StringUtils.isNotBlank(preExecScript)) {
+            try {
+                scriptEngine.eval(preExecScript, bindings);
+            } catch (ScriptException excp) {
+                LOG.error("RangerRequestScriptEvaluator(): initialization 
failed", excp);
+            }
+        }
+    }
+
+    public static boolean needsJsonCtxEnabled(String script) {
+        boolean ret = false;
+
+        if (script != null) {
+            Matcher matcher = JSON_VAR_NAMES_PATTERN.matcher(script);
+
+            ret = matcher.find();
+        }
+
+        return ret;
+    }
+
+    public static boolean hasUserAttributeReference(String script) {
+        boolean ret = false;
 
-               return ret;
-       }
-
-       public static String expandMacros(String script) {
-               return MACRO_PROCESSOR.expandMacros(script);
-       }
-
-       public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine) {
-               this(accessRequest, scriptEngine, true);
-       }
+        if (script != null) {
+            Matcher matcher = USER_ATTRIBUTES_PATTERN.matcher(script);
 
-       public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, 
ScriptEngine scriptEngine, boolean enableJsonCtx) {
-               this.accessRequest = accessRequest.getReadOnlyCopy();
-               this.scriptEngine  = scriptEngine;
-               this.bindings      = scriptEngine.createBindings();
+            ret = matcher.find();
+        }
 
-               RangerTagForEval    currentTag = this.getCurrentTag();
-               Map<String, String> tagAttribs = currentTag != null ? 
currentTag.getAttributes() : Collections.emptyMap();
+        return ret;
+    }
 
-               bindings.put(SCRIPT_VAR_ctx, this);
-               bindings.put(SCRIPT_VAR_tag, currentTag);
-               bindings.put(SCRIPT_VAR_tagAttr, tagAttribs);
-
-               String preExecScript = "";
+    public static boolean hasGroupAttributeReference(String script) {
+        boolean ret = false;
 
-               if (enableJsonCtx) {
-                       bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson());
+        if (script != null) {
+            Matcher matcher = GROUP_ATTRIBUTES_PATTERN.matcher(script);
 
-                       preExecScript += SCRIPT_PREEXEC;
-               }
+            ret = matcher.find();
+        }
 
-               if (StringUtils.isNotBlank(preExecScript)) {
-                       try {
-                               scriptEngine.eval(preExecScript, bindings);
-                       } catch (ScriptException excp) {
-                               LOG.error("RangerRequestScriptEvaluator(): 
initialization failed", excp);
-                       }
-               }
-       }
+        return ret;
+    }
 
-       public Object evaluateScript(String script) {
-               script = expandMacros(script);
+    public static boolean hasUserGroupAttributeReference(String script) {
+        return hasUserAttributeReference(script) || 
hasGroupAttributeReference(script);
+    }
 
-               return evaluateScriptImpl(script);
-       }
+    public static boolean hasUserGroupAttributeReference(Collection<String> 
scripts) {
+        boolean ret = false;
 
-       public Object evaluateConditionScript(String script) {
-               Object ret = evaluateScript(script);
+        if (scripts != null) {
+            for (String script : scripts) {
+                if (hasUserGroupAttributeReference(script)) {
+                    ret = true;
 
-               if (ret == null) {
-                       ret = getResult();
-               }
+                    break;
+                }
+            }
+        }
 
-               if (ret instanceof Boolean) {
-                       result = (Boolean) ret;
-               }
+        return ret;
+    }
 
-               return ret;
-       }
+    public static String expandMacros(String script) {
+        return MACRO_PROCESSOR.expandMacros(script);
+    }
 
-       private Object evaluateScriptImpl(String script) {
-               Object           ret  = null;
-               RangerPerfTracer perf = null;
+    public static void init(Configuration config) {
+        StringBuilder sb = new 
StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT);
 
-               try {
-                       if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_EVAL)) {
-                               perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_EVAL, 
"RangerRequestScriptEvaluator.evaluateScript(requestHash=" + 
accessRequest.hashCode() + ")");
-                       }
+        
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME);
 
-                       String preExec = SCRIPT_SAFE_PREEXEC;
+        String additionalDateFormatsValue = config != null ? 
config.get(TAG_ATTR_DATE_FORMAT_PROP) : null;
 
-                       if (script.contains(".includes(")) {
-                               preExec += SCRIPT_POLYFILL_INCLUDES;
-                       }
+        if (StringUtils.isNotBlank(additionalDateFormatsValue)) {
+            
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(additionalDateFormatsValue);
+        }
 
-                       if (script.contains(".intersects(")) {
-                               preExec += SCRIPT_POLYFILL_INTERSECTS;
-                       }
+        String[] formatStrings = 
sb.toString().split(TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX);
 
-                       if (JavaScriptEdits.hasDoubleBrackets(script)) {
-                               script = 
JavaScriptEdits.replaceDoubleBrackets(script);
-                       }
+        Arrays.sort(formatStrings, (first, second) -> 
Integer.compare(second.length(), first.length()));
 
-                       ret = scriptEngine.eval(preExec + script, bindings);
-               } catch (NullPointerException nullp) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): eval called with NULL 
argument(s)", nullp);
-               } catch (ScriptException excp) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate 
script", excp);
-               } catch (Throwable t) {
-                       
LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate 
script", t);
-               } finally {
-                       RangerPerfTracer.log(perf);
-               }
+        RangerRequestScriptEvaluator.dateFormatStrings = formatStrings;
+    }
 
-               return ret;
-       }
+    public Object evaluateScript(String script) {
+        script = expandMacros(script);
 
-       private String toJson() {
-               RangerPerfTracer perf = null;
+        return evaluateScriptImpl(script);
+    }
 
-               if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_TOJSON)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_TOJSON, 
"RangerRequestScriptEvaluator.toJson(requestHash=" + accessRequest.hashCode() + 
")");
-               }
+    public Object evaluateConditionScript(String script) {
+        Object ret = evaluateScript(script);
 
-               Map<String, Object> ret        = new HashMap<>();
-               Map<String, Object> request    = new HashMap<>();
-               Date                accessTime = accessRequest.getAccessTime();
+        if (ret == null) {
+            ret = getResult();
+        }
 
-               init();
+        if (ret instanceof Boolean) {
+            result = (Boolean) ret;
+        }
 
-               if (accessTime != null) {
-                       request.put(SCRIPT_FIELD_ACCESS_TIME, 
accessTime.getTime());
-               }
+        return ret;
+    }
 
-               request.put(SCRIPT_FIELD_ACCESS_TYPE, 
accessRequest.getAccessType());
-               request.put(SCRIPT_FIELD_ACTION, accessRequest.getAction());
-               request.put(SCRIPT_FIELD_CLIENT_IP_ADDRESS, 
accessRequest.getClientIPAddress());
-               request.put(SCRIPT_FIELD_CLIENT_TYPE, 
accessRequest.getClientType());
-               request.put(SCRIPT_FIELD_CLUSTER_NAME, 
accessRequest.getClusterName());
-               request.put(SCRIPT_FIELD_CLUSTER_TYPE, 
accessRequest.getClusterType());
-               request.put(SCRIPT_FIELD_FORWARDED_ADDRESSES, 
accessRequest.getForwardedAddresses());
-               request.put(SCRIPT_FIELD_REMOTE_IP_ADDRESS, 
accessRequest.getRemoteIPAddress());
-               request.put(SCRIPT_FIELD_REQUEST_DATA, 
accessRequest.getRequestData());
+    public String getResource() {
+        String               ret = null;
+        RangerAccessResource val = 
RangerAccessRequestUtil.getCurrentResourceFromContext(getRequestContext());
 
-               if (accessRequest.getResource() != null) {
-                       Map<String, Object> resource = new 
HashMap<>(accessRequest.getResource().getAsMap());
+        if (val != null) {
+            ret = val.getAsString();
+        }
 
-                       resource.put(SCRIPT_FIELD__OWNER_USER, 
accessRequest.getResource().getOwnerUser());
+        return ret;
+    }
 
-                       request.put(SCRIPT_FIELD_RESOURCE, resource);
-               }
+    public String getResourceZone() {
+        String ret = 
RangerAccessRequestUtil.getResourceZoneNameFromContext(getRequestContext());
 
-               request.put(SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE, 
accessRequest.getResourceMatchingScope());
+        return ret != null ? ret : StringUtils.EMPTY;
+    }
 
-               request.put(SCRIPT_FIELD_USER, getUser());
-               request.put(SCRIPT_FIELD_USER_GROUPS, userGroups);
-               request.put(SCRIPT_FIELD_USER_ROLES, userRoles);
+    public Set<String> getResourceZones() {
+        Set<String> ret = 
RangerAccessRequestUtil.getResourceZoneNamesFromContext(getRequestContext());
 
-               request.put(SCRIPT_FIELD_USER_ATTRIBUTES, userAttrs);
+        return ret != null ? Collections.emptySet() : ret;
+    }
 
-               request.put(SCRIPT_FIELD_USER_GROUP_ATTRIBUTES, groupAttrs);
-               request.put(SCRIPT_FIELD_UGA, new 
UserGroupsAttributes(userGroups, groupAttrs).getAttributes());
+    public String getRequestContextAttribute(String attributeName) {
+        String ret = null;
 
-               ret.put(SCRIPT_FIELD_REQUEST, request);
+        if (StringUtils.isNotBlank(attributeName)) {
+            Object val = getRequestContext().get(attributeName);
 
-               ret.put(SCRIPT_FIELD_TAGS, tags);
-               ret.put(SCRIPT_FIELD_TAG_NAMES, tagNames);
-               ret.put(SCRIPT_FIELD_TAG, tag);
+            if (val != null) {
+                ret = val.toString();
+            }
+        }
 
-               String strRet = JsonUtils.objectToJson(ret);
+        return ret;
+    }
 
-               RangerPerfTracer.log(perf);
+    public boolean isAccessTypeAny() {
+        return accessRequest.isAccessTypeAny();
+    }
 
-               return strRet;
-       }
+    public boolean isAccessTypeDelegatedAdmin() {
+        return accessRequest.isAccessTypeDelegatedAdmin();
+    }
 
-       public static void init(Configuration config) {
-               StringBuilder sb = new 
StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT);
+    public String getUser() {
+        return accessRequest.getUser();
+    }
 
-               
sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME);
+    public Set<String> getUserGroups() {
+        return accessRequest.getUserGroups();
+    }
 
-               String additionalDateFormatsValue = config != null ? 
config.get(TAG_ATTR_DATE_FORMAT_PROP) : null;
+    public Set<String> getUserRoles() {
+        return RangerAccessRequestUtil.getUserRoles(accessRequest);
+    }
+
+    public Date getAccessTime() {
+        return accessRequest.getAccessTime() != null ? 
accessRequest.getAccessTime() : new Date();
+    }
+
+    public String getClientIPAddress() {
+        return accessRequest.getClientIPAddress();
+    }
+
+    public String getClientType() {
+        return accessRequest.getClientType();
+    }
+
+    public String getAction() {
+        return accessRequest.getAction();
+    }
+
+    public String getRequestData() {
+        return accessRequest.getRequestData();
+    }
+
+    public String getSessionId() {
+        return accessRequest.getSessionId();
+    }
+
+    public RangerTagForEval getCurrentTag() {
+        RangerTagForEval ret = 
RangerAccessRequestUtil.getCurrentTagFromContext(getRequestContext());
+
+        if (ret == null) {
+            if (LOG.isDebugEnabled()) {
+                logDebug("RangerRequestScriptEvaluator.getCurrentTag() - No 
current TAG object. Script execution must be for resource-based policy.");
+            }
+        }
+        return ret;
+    }
+
+    public String getCurrentTagType() {
+        RangerTagForEval tagObject = getCurrentTag();
+        return (tagObject != null) ? tagObject.getType() : null;
+    }
+
+    public Set<String> getAllTagTypes() {
+        Set<String>           allTagTypes   = null;
+        Set<RangerTagForEval> tagObjectList = getAllTags();
+
+        if (CollectionUtils.isNotEmpty(tagObjectList)) {
+            for (RangerTagForEval tag : tagObjectList) {
+                String tagType = tag.getType();
+                if (allTagTypes == null) {
+                    allTagTypes = new HashSet<>();
+                }
+                allTagTypes.add(tagType);
+            }
+        }
+
+        return allTagTypes;
+    }
+
+    public Map<String, String> getTagAttributes(final String tagType) {
+        Map<String, String> ret = null;
+
+        if (StringUtils.isNotBlank(tagType)) {
+            Set<RangerTagForEval> tagObjectList = getAllTags();
+
+            // Assumption: There is exactly one tag with given tagType in the 
list of tags - may not be true ***TODO***
+            // This will get attributes of the first tagType that matches
+            if (CollectionUtils.isNotEmpty(tagObjectList)) {
+                for (RangerTagForEval tag : tagObjectList) {
+                    if (tag.getType().equals(tagType)) {
+                        ret = tag.getAttributes();
+                        break;
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    public List<Map<String, String>> getTagAttributesForAllMatchingTags(final 
String tagType) {
+        List<Map<String, String>> ret = null;
+
+        if (StringUtils.isNotBlank(tagType)) {
+            Set<RangerTagForEval> tagObjectList = getAllTags();
+
+            // Assumption: There is exactly one tag with given tagType in the 
list of tags - may not be true ***TODO***
+            // This will get attributes of the first tagType that matches
+            if (CollectionUtils.isNotEmpty(tagObjectList)) {
+                for (RangerTagForEval tag : tagObjectList) {
+                    if (tag.getType().equals(tagType)) {
+                        Map<String, String> tagAttributes = 
tag.getAttributes();
+                        if (tagAttributes != null) {
+                            if (ret == null) {
+                                ret = new ArrayList<>();
+                            }
+                            ret.add(tagAttributes);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    public Set<String> getAttributeNames(final String tagType) {
+        Set<String>         ret        = null;
+        Map<String, String> attributes = getTagAttributes(tagType);
+
+        if (attributes != null) {
+            ret = attributes.keySet();
+        }
+
+        return ret;
+    }
+
+    public String getAttributeValue(final String tagType, final String 
attributeName) {
+        String ret = null;
+
+        if (StringUtils.isNotBlank(tagType) || 
StringUtils.isNotBlank(attributeName)) {
+            Map<String, String> attributes = getTagAttributes(tagType);
+
+            if (attributes != null) {
+                ret = attributes.get(attributeName);
+            }
+        }
+        return ret;
+    }
+
+    public List<String> getAttributeValueForAllMatchingTags(final String 
tagType, final String attributeName) {
+        List<String> ret = null;
+
+        if (StringUtils.isNotBlank(tagType) || 
StringUtils.isNotBlank(attributeName)) {
+            Map<String, String> attributes = getTagAttributes(tagType);
+
+            if (attributes != null && attributes.get(attributeName) != null) {
+                if (ret == null) {
+                    ret = new ArrayList<>();
+                }
+                ret.add(attributes.get(attributeName));
+            }
+        }
+        return ret;
+    }
+
+    public String getAttributeValue(final String attributeName) {
+        String ret = null;
+
+        if (StringUtils.isNotBlank(attributeName)) {
+            RangerTagForEval    tag        = getCurrentTag();
+            Map<String, String> attributes = null;
+            if (tag != null) {
+                attributes = tag.getAttributes();
+            }
+            if (attributes != null) {
+                ret = attributes.get(attributeName);
+            }
+        }
+
+        return ret;
+    }
+
+    public boolean getResult() {
+        return result;
+    }
+
+    public void setResult(final boolean result) {
+        this.result = result;
+    }
+
+    public Date getAsDate(String value) {
+        Date ret = null;
+
+        if (StringUtils.isNotBlank(value)) {
+            for (SimpleDateFormat simpleDateFormat : 
THREADLOCAL_DATE_FORMATS.get()) {
+                ret = getAsDate(value, simpleDateFormat);
+                if (ret != null) {
+                    if (LOG.isDebugEnabled()) {

Review Comment:
   please check occurrences for isDebugEnabled in this file.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@ranger.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to