You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2016/04/21 01:57:05 UTC

incubator-ranger git commit: RANGER-895: Mask UDF implementation refactor

Repository: incubator-ranger
Updated Branches:
  refs/heads/master 191350ff5 -> 7b8b6bb76


RANGER-895: Mask UDF implementation refactor


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/7b8b6bb7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/7b8b6bb7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/7b8b6bb7

Branch: refs/heads/master
Commit: 7b8b6bb7654d5876a8f88a334108457ceddf0715
Parents: 191350f
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Tue Apr 19 16:30:48 2016 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Wed Apr 20 16:52:59 2016 -0700

----------------------------------------------------------------------
 .../service-defs/ranger-servicedef-hive.json    | 102 ++---
 .../hive/authorizer/RangerHiveAuditHandler.java |  31 +-
 .../hive/authorizer/RangerHiveAuthorizer.java   |  41 +-
 ranger-hive-utils/pom.xml                       |  34 --
 .../hive/udf/EncryptTransformer.java            |  63 ---
 .../hive/udf/MaskFirstNTransformer.java         |  46 ---
 .../hive/udf/MaskLastNTransformer.java          |  46 ---
 .../hive/udf/MaskShowFirstNTransformer.java     |  46 ---
 .../hive/udf/MaskShowLastNTransformer.java      |  46 ---
 .../authorization/hive/udf/MaskTransformer.java | 209 ----------
 .../authorization/hive/udf/RangerBaseUdf.java   | 321 ++++++++++++++-
 .../hive/udf/RangerTransformer.java             |  61 ---
 .../hive/udf/RangerTransformerFactory.java      |  80 ----
 .../authorization/hive/udf/RangerUdfMask.java   | 390 ++++++++-----------
 .../hive/udf/RangerUdfMaskFirstN.java           |  69 ++++
 .../hive/udf/RangerUdfMaskHash.java             |  62 +++
 .../hive/udf/RangerUdfMaskLastN.java            |  69 ++++
 .../hive/udf/RangerUdfMaskShowFirstN.java       |  69 ++++
 .../hive/udf/RangerUdfMaskShowLastN.java        |  69 ++++
 .../hive/udf/ShuffleTransformer.java            | 102 -----
 20 files changed, 889 insertions(+), 1067 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
index 1d97843..eda2d22 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
@@ -253,110 +253,88 @@
 				"name": "MASK",
 				"label": "Mask",
 				"description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
+				"transformer": "rangerUdfMask({col})",
 				"dataMaskOptions": {
 				}
 			},
 			{
 				"itemId": 2,
-				"name": "SHUFFLE",
-				"label": "Shuffle",
-				"description": "Shuffle the value of the column",
-				"transformer": "org.apache.ranger.authorization.hive.udf.ShuffleTransformer",
-				"dataMaskOptions": {
-				}
-			},
-			{
-				"itemId": 3,
-				"name": "MASK_x_SHOW_LAST_4",
+				"name": "MASK_SHOW_LAST_4",
 				"label": "Partial mask: show last 4",
 				"description": "Show last 4 characters; replace rest with 'x'",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskShowLastNTransformer",
-				"dataMaskOptions": {
-					"initParam": "charCount=4; upper=x; lower=x; digit=x; number=1"
-				}
+				"transformer": "rangerUdfMaskShowLastN({col}, 4, 'x', 'x', 'x', -1, '1')"
 			},
 			{
-				"itemId": 4,
-				"name": "MASK_x_SHOW_FIRST_4",
+				"itemId": 3,
+				"name": "MASK_SHOW_FIRST_4",
 				"label": "Partial mask: show first 4",
 				"description": "Show first 4 characters; replace rest with 'x'",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskShowFirstNTransformer",
-				"dataMaskOptions": {
-					"initParam": "charCount=4; upper=x; lower=x; digit=x; number=1"
-				}
+				"transformer": "rangerUdfMaskShowFirstN({col}, 4, 'x', 'x', 'x', -1, '1')"
+			},
+			{
+				"itemId": 4,
+				"name": "MASK_HASH",
+				"label": "Hash",
+				"description": "Hash the value",
+				"transformer": "rangerUdfMaskHash({col})"
 			},
 			{
 				"itemId": 5,
+				"name": "MASK_NULL",
+				"label": "NULL",
+				"description": "Replace with NULL"
+			},
+			{
+				"itemId": 6,
+				"name": "MASK_NONE",
+				"label": "No masking",
+				"description": "No masking"
+			},
+			{
+				"itemId": 7,
 				"name": "MASK_DATE_DAY",
 				"label": "Date: mask day",
 				"description": "Date: mask day",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=1; month=-1; year=-1"
-				}
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', 1, -1, -1)"
 			},
 			{
-				"itemId": 6,
+				"itemId": 8,
 				"name": "MASK_DATE_MONTH",
 				"label": "Date: mask month",
 				"description": "Date: mask month",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=-1; month=0; year=-1"
-				}
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', -1, 0, -1)"
 			},
 			{
-				"itemId": 7,
+				"itemId": 9,
 				"name": "MASK_DATE_YEAR",
 				"label": "Date: mask year",
 				"description": "Date: mask year",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=-1; month=-1; year=0"
-				}
+				"transformer": "rangerUdfMask",
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', -1, -1, 0)"
 			},
 			{
-				"itemId": 8,
+				"itemId": 10,
 				"name": "MASK_DATE_SHOW_DAY",
 				"label": "Date: show only day",
 				"description": "Date: show only day",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=-1; month=0; year=0"
-				}
+				"transformer": "rangerUdfMask",
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', -1, 0, 0)"
 			},
 			{
-				"itemId": 9,
+				"itemId": 11,
 				"name": "MASK_DATE_SHOW_MONTH",
 				"label": "Date: show only month",
 				"description": "Date: show only month",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=1; month=-1; year=0"
-				}
+				"transformer": "rangerUdfMask",
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', 1, -1, 0)"
 			},
 			{
-				"itemId": 10,
+				"itemId": 12,
 				"name": "MASK_DATE_SHOW_YEAR",
 				"label": "Date: show only year",
 				"description": "Date: show only year",
-				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
-				"dataMaskOptions": {
-					"initParam": "day=1; month=0; year=-1"
-				}
-			},
-			{
-				"itemId": 11,
-				"name": "NULL",
-				"label": "NULL",
-				"description": "Replace with NULL"
-			},
-			{
-				"itemId": 12,
-				"name": "NONE",
-				"label": "No masking",
-				"description": "No masking"
+				"transformer": "rangerUdfMask",
+				"transformer": "rangerUdfMask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)"
 			}
 		]
 	},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
----------------------------------------------------------------------
diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
index 0745d1d..a6bb357 100644
--- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
+++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
@@ -41,7 +41,7 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 	public RangerHiveAuditHandler() {
 		super();
 	}
-	
+
 	AuthzAuditEvent createAuditEvent(RangerAccessResult result, String accessType, String resourcePath) {
 		RangerAccessRequest  request      = result.getAccessRequest();
 		RangerAccessResource resource     = request.getResource();
@@ -59,13 +59,22 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 	AuthzAuditEvent createAuditEvent(RangerAccessResult result) {
 		RangerAccessRequest  request  = result.getAccessRequest();
 		RangerAccessResource resource = request.getResource();
+		String               resourcePath = resource != null ? resource.getAsString() : null;
 
 		String accessType = null;
 
 		if(result instanceof RangerDataMaskResult) {
 			accessType = ((RangerDataMaskResult)result).getMaskType();
+
+			if(StringUtils.equals(accessType, RangerHiveAuthorizer.MASK_TYPE_NONE)) {
+				return null;
+			}
+
+			return createAuditEvent(result, accessType, resourcePath);
 		} else if(result instanceof RangerRowFilterResult) {
 			accessType = ACCESS_TYPE_ROWFILTER;
+
+			return createAuditEvent(result, accessType, resourcePath);
 		} else {
 			if (request instanceof RangerHiveAccessRequest) {
 				RangerHiveAccessRequest hiveRequest = (RangerHiveAccessRequest) request;
@@ -76,14 +85,12 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 			if (StringUtils.isEmpty(accessType)) {
 				accessType = request.getAccessType();
 			}
-		}
 
-		String resourcePath = resource != null ? resource.getAsString() : null;
-
-		return createAuditEvent(result, accessType, resourcePath);
+			return createAuditEvent(result, accessType, resourcePath);
+		}
 	}
 
-	public List<AuthzAuditEvent> createAuditEvents(Collection<RangerAccessResult> results) {
+	List<AuthzAuditEvent> createAuditEvents(Collection<RangerAccessResult> results) {
 
 		Map<Long, AuthzAuditEvent> auditEvents = new HashMap<Long, AuthzAuditEvent>();
 		Iterator<RangerAccessResult> iterator = results.iterator();
@@ -107,7 +114,10 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 						}
 					} else { // new event as this approval was due to a different policy.
 						AuthzAuditEvent auditEvent = createAuditEvent(result);
-						auditEvents.put(policyId, auditEvent);
+
+						if(auditEvent != null) {
+							auditEvents.put(policyId, auditEvent);
+						}
 					}
 				}
 			}
@@ -121,14 +131,17 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 		
 		return result;
 	}
-	
+
 	@Override
 	public void processResult(RangerAccessResult result) {
 		if(! result.getIsAudited()) {
 			return;
 		}
 		AuthzAuditEvent auditEvent = createAuditEvent(result);
-		addAuthzAuditEvent(auditEvent);
+
+		if(auditEvent != null) {
+			addAuthzAuditEvent(auditEvent);
+		}
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
----------------------------------------------------------------------
diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
index 3c922c9..3cd9e53 100644
--- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
+++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
- package org.apache.ranger.authorization.hive.authorizer;
+package org.apache.ranger.authorization.hive.authorizer;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -27,7 +27,6 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -69,13 +68,12 @@ import com.google.common.collect.Sets;
 import org.apache.ranger.plugin.util.RangerRequestedResources;
 
 public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
-	private static final Log LOG = LogFactory.getLog(RangerHiveAuthorizer.class) ; 
+	private static final Log LOG = LogFactory.getLog(RangerHiveAuthorizer.class) ;
 
 	private static final char COLUMN_SEP = ',';
-	private static final String MASK_TYPE_NULL     = "NULL";
-	private static final String MASK_TYPE_NONE     = "NONE";
-	private static final String MASK_TYPE_CONSTANT = "CONSTANT";
-	private static final String MASK_UDF_NAME      = "rangerUdfMask";
+	public static final String MASK_TYPE_NULL     = "MASK_NULL";
+	public static final String MASK_TYPE_NONE     = "MASK_NONE";
+	public static final String MASK_TYPE_CONSTANT = "CONSTANT";
 
 	private static volatile RangerHivePlugin hivePlugin = null ;
 
@@ -494,10 +492,12 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 					String database = hiveObj.getDbname();
 					String table    = hiveObj.getObjectName();
 
-					String rowFilterExpr = getRowFilterExpression(database, table);
+					String rowFilterExpr = getRowFilterExpression(queryContext, database, table);
 
 					if (StringUtils.isNotBlank(rowFilterExpr)) {
-						LOG.debug("rowFilter(database=" + database + ", table=" + table + "): " + rowFilterExpr);
+						if(LOG.isDebugEnabled()) {
+							LOG.debug("rowFilter(database=" + database + ", table=" + table + "): " + rowFilterExpr);
+						}
 
 						hiveObj.setRowFilterExpression(rowFilterExpr);
 					}
@@ -506,9 +506,9 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 						List<String> columnTransformers = new ArrayList<String>();
 
 						for (String column : hiveObj.getColumns()) {
-							String columnTransformer = getCellValueTransformer(database, table, column);
+							String columnTransformer = getCellValueTransformer(queryContext, database, table, column);
 
-							if(StringUtils.isNotEmpty(columnTransformer)) {
+							if(LOG.isDebugEnabled()) {
 								LOG.debug("columnTransformer(database=" + database + ", table=" + table + ", column=" + column + "): " + columnTransformer);
 							}
 
@@ -535,7 +535,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		return true; // TODO: derive from the policies
 	}
 
-	public String getRowFilterExpression(String databaseName, String tableOrViewName) throws SemanticException {
+	private String getRowFilterExpression(QueryContext context, String databaseName, String tableOrViewName) throws SemanticException {
 		UserGroupInformation ugi = getCurrentUserGroupInfo();
 
 		if(ugi == null) {
@@ -551,7 +551,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler();
 
 		try {
-			QueryContext            context        = null; // TODO: this should be provided as an argument to this method
 			HiveAuthzSessionContext sessionContext = getHiveAuthzSessionContext();
 			HiveAuthenticationProvider authenticator = getHiveAuthenticator();
 			String                  user           = ugi.getShortUserName();
@@ -576,7 +575,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		return ret;
 	}
 
-	public String getCellValueTransformer(String databaseName, String tableOrViewName, String columnName) throws SemanticException {
+	private String getCellValueTransformer(QueryContext context, String databaseName, String tableOrViewName, String columnName) throws SemanticException {
 		UserGroupInformation ugi = getCurrentUserGroupInfo();
 
 		if(ugi == null) {
@@ -592,7 +591,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler();
 
 		try {
-			QueryContext            context        = null; // TODO: this should be provided as an argument to this method
 			HiveAuthzSessionContext sessionContext = getHiveAuthzSessionContext();
 			HiveAuthenticationProvider authenticator = getHiveAuthenticator();
 			String                  user           = ugi.getShortUserName();
@@ -607,15 +605,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 				String                maskType    = result.getMaskType();
 				RangerDataMaskTypeDef maskTypeDef = result.getMaskTypeDef();
 				String                transformer = maskTypeDef.getTransformer();
-				String                initParam   = "";
-
-				if(MapUtils.isNotEmpty(maskTypeDef.getDataMaskOptions())) {
-					initParam = maskTypeDef.getDataMaskOptions().get("initParam");
-
-					if(initParam == null) {
-						initParam = "";
-					}
-				}
 
 				if(StringUtils.equalsIgnoreCase(maskType, MASK_TYPE_NONE)) {
 					ret = columnName;
@@ -625,8 +614,8 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 					String maskedValue = result.getMaskedValue();
 
 					ret = maskedValue == null ? "NULL" : maskedValue;
-				} else {
-					ret = MASK_UDF_NAME + "(" + columnName + ", '" + maskType + "', '" + transformer + "', '" + initParam + "')";
+				} else if(StringUtils.isNotEmpty(transformer)) {
+					ret = transformer.replace("{col}", columnName);
 				}
 
 				/*

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/pom.xml b/ranger-hive-utils/pom.xml
index f3f55b3..b2e88ba 100644
--- a/ranger-hive-utils/pom.xml
+++ b/ranger-hive-utils/pom.xml
@@ -32,48 +32,14 @@
   </parent>
   <dependencies>
     <dependency>
-      <groupId>org.apache.calcite</groupId>
-      <artifactId>calcite-core</artifactId>
-      <version>${calcite.version}</version>
-    </dependency>   
-    <dependency>
-        <groupId>org.apache.calcite.avatica</groupId>
-        <artifactId>avatica</artifactId>
-        <version>${avatica.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>${commons.lang.version}</version>
-    </dependency>
-    <dependency>
-	  <groupId>org.apache.hadoop</groupId>
-	  <artifactId>hadoop-common</artifactId>
-	  <version>${hadoop-common.version}</version>
-    </dependency>
-    <dependency>
 	  <groupId>org.apache.hive</groupId>
 	  <artifactId>hive-common</artifactId>
 	  <version>${hive.version}</version>
     </dependency>
     <dependency>
-	  <groupId>org.apache.hive</groupId>
-	  <artifactId>hive-service</artifactId>
-	  <version>${hive.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.hive</groupId>
       <artifactId>hive-exec</artifactId>
       <version>${hive.version}</version>
     </dependency>
-    <dependency>
-	  <groupId>org.apache.hive</groupId>
-	  <artifactId>hive-metastore</artifactId>
-	  <version>${hive.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/EncryptTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/EncryptTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/EncryptTransformer.java
deleted file mode 100644
index f002f9a..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/EncryptTransformer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-import org.apache.commons.codec.digest.DigestUtils;
-
-import java.sql.Date;
-
-
-public class EncryptTransformer extends RangerTransformer {
-	public EncryptTransformer() {
-	}
-
-	@Override
-	public void init(String initParam) {
-	}
-
-	@Override
-	String transform(String value) {
-		return value == null ? STRING_0 : this.encryptToMd5Hex(value);
-	}
-
-	@Override
-	Short transform(Short value) {
-		return SHORT_0;
-	}
-
-	@Override
-	Integer transform(Integer value) {
-		return INTEGER_0;
-	}
-
-	@Override
-	Long transform(Long value) {
-		return LONG_0;
-	}
-
-	@Override
-	Date transform(Date value) {
-		return DATE_0;
-	}
-
-	String encryptToMd5Hex(String value) {
-		return DigestUtils.md5Hex(value);
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskFirstNTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskFirstNTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskFirstNTransformer.java
deleted file mode 100644
index e37b3ef..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskFirstNTransformer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-
-public class MaskFirstNTransformer extends MaskTransformer {
-	int charCount = 4;
-
-	public MaskFirstNTransformer() {
-		super();
-	}
-
-	@Override
-	public void init(String initParam) {
-		super.init(initParam);
-
-		charCount = getIntOption("charCount", 4);
-	}
-
-	@Override
-	int getMaskStartIndex(String val) {
-		return 0;
-	}
-
-	@Override
-	int getMaskEndIndex(String val) {
-		return charCount;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskLastNTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskLastNTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskLastNTransformer.java
deleted file mode 100644
index 18bc558..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskLastNTransformer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-
-public class MaskLastNTransformer extends MaskTransformer {
-	int charCount = 4;
-
-	public MaskLastNTransformer() {
-		super();
-	}
-
-	@Override
-	public void init(String initParam) {
-		super.init(initParam);
-
-		this.charCount = getIntOption("charCount", 4);
-	}
-
-	@Override
-	int getMaskStartIndex(String val) {
-		return val.length() - charCount;
-	}
-
-	@Override
-	int getMaskEndIndex(String val) {
-		return val.length();
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowFirstNTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowFirstNTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowFirstNTransformer.java
deleted file mode 100644
index 26a4c32..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowFirstNTransformer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-
-public class MaskShowFirstNTransformer extends MaskTransformer {
-	int charCount = 4;
-
-	public MaskShowFirstNTransformer() {
-		super();
-	}
-
-	@Override
-	public void init(String initParam) {
-		super.init(initParam);
-
-		this.charCount = getIntOption("charCount", 4);
-	}
-
-	@Override
-	int getMaskStartIndex(String val) {
-		return charCount;
-	}
-
-	@Override
-	int getMaskEndIndex(String val) {
-		return val.length();
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowLastNTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowLastNTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowLastNTransformer.java
deleted file mode 100644
index cb30e50..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskShowLastNTransformer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-
-public class MaskShowLastNTransformer extends MaskTransformer {
-	int charCount;
-
-	public MaskShowLastNTransformer() {
-		super();
-	}
-
-	@Override
-	public void init(String initParam) {
-		super.init(initParam);
-
-		this.charCount = getIntOption("charCount", 4);
-	}
-
-	@Override
-	int getMaskStartIndex(String val) {
-		return 0;
-	}
-
-	@Override
-	int getMaskEndIndex(String val) {
-		return val.length() - charCount;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskTransformer.java
deleted file mode 100644
index 64de392..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/MaskTransformer.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.sql.Date;
-
-
-public class MaskTransformer extends RangerTransformer {
-	final static int MASKED_UPPERCASE            = 'X';
-	final static int MASKED_LOWERCASE            = 'x';
-	final static int MASKED_NUMBER               = '1';
-	final static int MASKED_DAY_COMPONENT_VAL    = 1;
-	final static int MASKED_MONTH_COMPONENT_VAL  = 0;
-	final static int MASKED_YEAR_COMPONENT_VAL   = 0;
-	final static int UNMASKED_DATE_COMPONENT_VAL = -1;
-
-	int maskedUpperChar   = MASKED_UPPERCASE;
-	int maskedLowerChar   = MASKED_LOWERCASE;
-	int maskedDigitChar   = MASKED_NUMBER;
-	int maskedNumber      = MASKED_NUMBER;
-	int maskedDayValue    = MASKED_DAY_COMPONENT_VAL;
-	int maskedMonthValue  = MASKED_MONTH_COMPONENT_VAL;
-	int maskedYearValue   = MASKED_YEAR_COMPONENT_VAL;
-
-	public MaskTransformer() {
-	}
-
-	@Override
-	public void init(String initParam) {
-		if(StringUtils.isNotEmpty(initParam)) {
-			for(String nvStr : initParam.split(";")) {
-				if(StringUtils.isNotEmpty(nvStr)) {
-					String[] nameValue = nvStr.split("=", 2);
-					String  name  = nameValue != null && nameValue.length > 0 ? nameValue[0] : null;
-					String  value = nameValue != null && nameValue.length > 1 ? nameValue[1] : null;
-
-					if(StringUtils.isNotEmpty(name)) {
-						options.put(name.trim(), value.trim());
-					}
-				}
-			}
-		}
-
-		maskedUpperChar  = getCharOption("upper", MASKED_UPPERCASE);
-		maskedLowerChar  = getCharOption("lower", MASKED_LOWERCASE);
-		maskedDigitChar  = getCharOption("digit", MASKED_NUMBER);
-		maskedNumber     = getCharOption("number", MASKED_NUMBER);
-		maskedDayValue   = getIntOption("day", MASKED_DAY_COMPONENT_VAL);
-		maskedMonthValue = getIntOption("month", MASKED_MONTH_COMPONENT_VAL);
-		maskedYearValue  = getIntOption("year", MASKED_YEAR_COMPONENT_VAL);
-	}
-
-	@Override
-	String transform(String value) {
-		return value == null ? STRING_0 : transformAlphaNum(value);
-	}
-
-	@Override
-	Short transform(Short value) {
-		return value == null ? SHORT_0 : Short.parseShort(transformNum(value.toString()));
-	}
-
-	@Override
-	Integer transform(Integer value) {
-		return value == null ? INTEGER_0 : Integer.parseInt(transformNum(value.toString()));
-	}
-
-	@Override
-	Long transform(Long value) {
-		return value == null ? LONG_0 : Long.parseLong(transformNum(value.toString()));
-	}
-
-	@Override
-	Date transform(Date value) {
-		return mask(value, maskedDayValue, maskedMonthValue, maskedYearValue);
-	}
-
-	String transformNum(String val) {
-		return transformNum(val, maskedNumber, getMaskStartIndex(val), getMaskEndIndex(val));
-	}
-
-	String transformAlphaNum(String val) {
-		return transformAlphaNum(val, maskedUpperChar, maskedLowerChar, maskedDigitChar, getMaskStartIndex(val), getMaskEndIndex(val));
-	}
-
-	Date mask(Date value, int maskedDay, int maskedMonth, int maskedYear) {
-		int year  = maskedYear  == UNMASKED_DATE_COMPONENT_VAL ? value.getYear()  : MASKED_YEAR_COMPONENT_VAL;
-		int month = maskedMonth == UNMASKED_DATE_COMPONENT_VAL ? value.getMonth() : MASKED_MONTH_COMPONENT_VAL;
-		int day   = maskedDay   == UNMASKED_DATE_COMPONENT_VAL ? value.getDate()  : MASKED_DAY_COMPONENT_VAL;
-
-		return new Date(year, month, day);
-	}
-
-	int getMaskStartIndex(String val) {
-		return 0;
-	}
-
-	int getMaskEndIndex(String val) {
-		return val.length();
-	}
-
-
-	String transformNum(String val, int replaceDigit, int startIdx, int endIdx) {
-		if(val == null) {
-			return null;
-		}
-
-		StringBuffer strBuf = new StringBuffer(val.length());
-
-		if(startIdx < 0) {
-			startIdx = 0;
-		}
-
-		if(endIdx > val.length()) {
-			endIdx = val.length();
-		}
-
-		for(int i = 0; i < startIdx; i++) {
-			strBuf.appendCodePoint(val.charAt(i));
-		}
-
-		for(int i = startIdx; i < endIdx; i++) {
-			int c = val.charAt(i);
-
-			switch(Character.getType(c)) {
-				case Character.DECIMAL_DIGIT_NUMBER:
-					c = replaceDigit;
-					break;
-			}
-
-			strBuf.appendCodePoint(c);
-		}
-
-		for(int i = endIdx; i < val.length(); i++) {
-			strBuf.appendCodePoint(val.charAt(i));
-		}
-
-		String ret = strBuf.toString();
-
-		return ret;
-	}
-
-	String transformAlphaNum(String val, int replaceUpperChar, int replaceLowerChar, int replaceDigit, int startIdx, int endIdx) {
-		if(val == null) {
-			return null;
-		}
-
-		StringBuffer strBuf = new StringBuffer(val.length());
-
-		if(startIdx < 0) {
-			startIdx = 0;
-		}
-
-		if(endIdx > val.length()) {
-			endIdx = val.length();
-		}
-
-		for(int i = 0; i < startIdx; i++) {
-			strBuf.appendCodePoint(val.charAt(i));
-		}
-
-		for(int i = startIdx; i < endIdx; i++) {
-			int c = val.charAt(i);
-
-			switch(Character.getType(c)) {
-				case Character.UPPERCASE_LETTER:
-					c = replaceUpperChar;
-					break;
-
-				case Character.LOWERCASE_LETTER:
-					c = replaceLowerChar;
-					break;
-
-				case Character.DECIMAL_DIGIT_NUMBER:
-					c = replaceDigit;
-					break;
-			}
-
-			strBuf.appendCodePoint(c);
-		}
-
-		for(int i = endIdx; i < val.length(); i++) {
-			strBuf.appendCodePoint(val.charAt(i));
-		}
-
-		String ret = strBuf.toString();
-
-		return ret;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerBaseUdf.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerBaseUdf.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerBaseUdf.java
index 0f5a7b2..389b2a5 100644
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerBaseUdf.java
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerBaseUdf.java
@@ -17,42 +17,341 @@
  */
 
 package org.apache.ranger.authorization.hive.udf;
+// org.apache.hadoop.hive.ql.udf.generic.
 
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.common.type.HiveVarchar;
 import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
 import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
+import org.apache.hadoop.hive.serde2.io.DateWritable;
+import org.apache.hadoop.hive.serde2.io.HiveVarcharWritable;
+import org.apache.hadoop.hive.serde2.io.ShortWritable;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.*;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+
+import java.sql.Date;
 
 
 public abstract class RangerBaseUdf extends GenericUDF {
 	private static final Log LOG = LogFactory.getLog(RangerBaseUdf.class);
 
-	protected PrimitiveObjectInspector columnType = null;
-
-	public RangerBaseUdf() {
-		LOG.debug("==> RangerBaseUdf()");
+	final protected RangerBaseUdf.RangerTransformer transformer;
+	protected RangerTransformerAdapter transformerAdapter = null;
 
-		LOG.debug("<== RangerBaseUdf()");
+	protected RangerBaseUdf(RangerBaseUdf.RangerTransformer transformer) {
+		this.transformer = transformer;
 	}
 
-	@Override
 	public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
 		LOG.debug("==> RangerBaseUdf.initialize()");
 
-		ObjectInspector ret = null;
+		checkArgPrimitive(arguments, 0); // first argument is the column to be transformed
 
-		checkArgPrimitive(arguments, 0); // column value
+		PrimitiveObjectInspector columnType = ((PrimitiveObjectInspector) arguments[0]);
 
-		columnType = ((PrimitiveObjectInspector)arguments[0]);
+		transformer.init(arguments, 1);
 
-		ret = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(columnType.getPrimitiveCategory());
+		transformerAdapter = RangerTransformerAdapter.getTransformerAdapter(columnType, transformer);
+
+		ObjectInspector ret = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(columnType.getPrimitiveCategory());
 
 		LOG.debug("<== RangerBaseUdf.initialize()");
 
 		return ret;
 	}
+
+	@Override
+	public Object evaluate(DeferredObject[] arguments) throws HiveException {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerBaseUdf.evaluate(arguments.length=" + arguments.length + ")");
+		}
+
+		Object ret = transformerAdapter.getTransformedWritable(arguments[0]);
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerBaseUdf.evaluate(arguments.length=" + arguments.length + "): ret=" + ret);
+		}
+
+		return ret;
+	}
+
+	@Override
+	public String getDisplayString(String[] children) {
+		return getStandardDisplayString(getClass().getName(), children, ",");
+	}
+
+	static abstract class RangerTransformer {
+		static final Short   SHORT_0   = Short.valueOf((short)0);
+		static final Integer INTEGER_0 = Integer.valueOf((int)0);
+		static final Long    LONG_0    = Long.valueOf((long)0);
+		static final Date    DATE_0    = new Date(0);
+		static final String  STRING_0  = new String("0");
+
+
+		abstract void    init(ObjectInspector[] arguments, int startIdx);
+
+		abstract String  transform(String value);
+		abstract Short   transform(Short value);
+		abstract Integer transform(Integer value);
+		abstract Long    transform(Long value);
+		abstract Date    transform(Date value);
+	}
+}
+
+
+abstract class RangerTransformerAdapter {
+	final RangerBaseUdf.RangerTransformer transformer;
+
+	RangerTransformerAdapter(RangerBaseUdf.RangerTransformer transformer) {
+		this.transformer = transformer;
+	}
+
+	abstract Object getTransformedWritable(DeferredObject value) throws HiveException;
+
+	static RangerTransformerAdapter getTransformerAdapter(PrimitiveObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		final RangerTransformerAdapter ret;
+
+		switch(columnType.getPrimitiveCategory()) {
+			case STRING:
+				ret = new StringTransformerAdapter((StringObjectInspector)columnType, transformer);
+				break;
+
+			case VARCHAR:
+				ret = new HiveVarcharTransformerAdapter((HiveVarcharObjectInspector)columnType, transformer);
+				break;
+
+			case SHORT:
+				ret = new ShortTransformerAdapter((ShortObjectInspector)columnType, transformer);
+				break;
+
+			case INT:
+				ret = new IntegerTransformerAdapter((IntObjectInspector)columnType, transformer);
+				break;
+
+			case LONG:
+				ret = new LongTransformerAdapter((LongObjectInspector)columnType, transformer);
+				break;
+
+			case DATE:
+				ret = new DateTransformerAdapter((DateObjectInspector)columnType, transformer);
+				break;
+
+			default:
+				ret = new NoTransformAdapter(columnType, transformer);
+				break;
+		}
+
+		return ret;
+	}
+}
+
+class DateTransformerAdapter extends RangerTransformerAdapter {
+	final DateObjectInspector columnType;
+	final DateWritable writable;
+
+	public DateTransformerAdapter(DateObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new DateWritable());
+	}
+
+	public DateTransformerAdapter(DateObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, DateWritable writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		Date value = columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			Date transformedValue = transformer.transform(value);
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
+}
+
+class HiveVarcharTransformerAdapter extends RangerTransformerAdapter {
+	final HiveVarcharObjectInspector columnType;
+	final HiveVarcharWritable writable;
+
+	public HiveVarcharTransformerAdapter(HiveVarcharObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new HiveVarcharWritable());
+	}
+
+	public HiveVarcharTransformerAdapter(HiveVarcharObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, HiveVarcharWritable writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		HiveVarchar value = columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			String transformedValue = transformer.transform(value.getValue());
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
+}
+
+class IntegerTransformerAdapter extends RangerTransformerAdapter {
+	final IntObjectInspector columnType;
+	final IntWritable writable;
+
+	public IntegerTransformerAdapter(IntObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new IntWritable());
+	}
+
+	public IntegerTransformerAdapter(IntObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, IntWritable writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		Integer value = (Integer)columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			Integer transformedValue = transformer.transform(value);
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
 }
+
+class LongTransformerAdapter extends RangerTransformerAdapter {
+	final LongObjectInspector columnType;
+	final LongWritable writable;
+
+	public LongTransformerAdapter(LongObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new LongWritable());
+	}
+
+	public LongTransformerAdapter(LongObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, LongWritable writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		Long value = (Long)columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			Long transformedValue = transformer.transform(value);
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
+}
+
+class NoTransformAdapter extends RangerTransformerAdapter {
+	final PrimitiveObjectInspector columnType;
+
+	public NoTransformAdapter(PrimitiveObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		super(transformer);
+
+		this.columnType = columnType;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		return columnType.getPrimitiveWritableObject(object);
+	}
+}
+
+class ShortTransformerAdapter extends RangerTransformerAdapter {
+	final ShortObjectInspector columnType;
+	final ShortWritable writable;
+
+	public ShortTransformerAdapter(ShortObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new ShortWritable());
+	}
+
+	public ShortTransformerAdapter(ShortObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, ShortWritable writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		Short value = (Short)columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			Short transformedValue = transformer.transform(value);
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
+}
+
+class StringTransformerAdapter extends RangerTransformerAdapter {
+	final StringObjectInspector columnType;
+	final Text writable;
+
+	public StringTransformerAdapter(StringObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer) {
+		this(columnType, transformer, new Text());
+	}
+
+	public StringTransformerAdapter(StringObjectInspector columnType, RangerBaseUdf.RangerTransformer transformer, Text writable) {
+		super(transformer);
+
+		this.columnType = columnType;
+		this.writable   = writable;
+	}
+
+	@Override
+	public Object getTransformedWritable(DeferredObject object) throws HiveException {
+		String value = columnType.getPrimitiveJavaObject(object.get());
+
+		if(value != null) {
+			String transformedValue = transformer.transform(value);
+
+			writable.set(transformedValue);
+
+			return writable;
+		}
+
+		return null;
+	}
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformer.java
deleted file mode 100644
index fff4ad5..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.sql.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-
-public abstract class RangerTransformer {
-	static final Short   SHORT_0   = Short.valueOf((short)0);
-	static final Integer INTEGER_0 = Integer.valueOf((int)0);
-	static final Long    LONG_0    = Long.valueOf((long)0);
-	static final Date    DATE_0    = new Date(0);
-	static final String  STRING_0  = new String("0");
-
-	final Map<String, String> options = new HashMap<String, String>();
-
-
-	abstract void    init(String initParam);
-
-	abstract String  transform(String value);
-	abstract Short   transform(Short value);
-	abstract Integer transform(Integer value);
-	abstract Long    transform(Long value);
-	abstract Date    transform(Date value);
-
-
-	int getCharOption(String name, int defValue) {
-		String value = options.get(name);
-
-		return StringUtils.isNotEmpty(value) ? value.charAt(0) : defValue;
-	}
-
-	int getIntOption(String name, int defValue) {
-		String value = options.get(name);
-
-		return StringUtils.isNotEmpty(value) ? Integer.parseInt(value) : defValue;
-	}
-}
-
-

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformerFactory.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformerFactory.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformerFactory.java
deleted file mode 100644
index 83f646a..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerTransformerFactory.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-public class RangerTransformerFactory {
-    private static final Log LOG = LogFactory.getLog(RangerTransformerFactory.class);
-
-
-    public static RangerTransformer getTransformer(String transformType, String transformerImpl, String initParam) {
-        RangerTransformer ret = null;
-
-        if(StringUtils.isEmpty(transformerImpl)) {
-            LOG.warn("maskType: '" + transformType + "': no transformer specified. Will use '" + MaskTransformer.class.getName() + "' as transformer");
-
-            ret = new MaskTransformer();
-        } else {
-            ret = createTransformer(transformerImpl);
-
-            if(ret == null) {
-                LOG.warn("maskType: '" + transformType + "': failed to create transformer '" + transformerImpl + "'. Will use '" + MaskTransformer.class.getName() + "' as transformer");
-
-                ret = new MaskTransformer();
-            }
-        }
-
-        if(initParam == null) {
-            initParam = "";
-        }
-
-        ret.init(initParam);
-
-        return ret;
-    }
-
-	private static RangerTransformer createTransformer(String className) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerTransformerFactory.createTransformer(" + className + ")");
-		}
-
-		RangerTransformer ret = null;
-
-		try {
-			@SuppressWarnings("unchecked")
-			Class<RangerTransformer> transformerClass = (Class<RangerTransformer>)Class.forName(className);
-
-            ret = transformerClass.newInstance();
-		} catch(Throwable t) {
-			LOG.error("RangerTransformerFactory.createTransformer(" + className + "): error instantiating transformer", t);
-		}
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerTransformerFactory.createTransformer(" + className + "): " + ret);
-		}
-
-		return ret;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMask.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMask.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMask.java
index 91caa8b..fac4e57 100644
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMask.java
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMask.java
@@ -21,304 +21,242 @@ package org.apache.ranger.authorization.hive.udf;
 
 import java.sql.Date;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hive.common.type.HiveVarchar;
-import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
-import org.apache.hadoop.hive.ql.metadata.HiveException;
-import org.apache.hadoop.hive.serde2.io.DateWritable;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableConstantIntObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableConstantStringObjectInspector;
-import org.apache.hadoop.hive.serde2.io.HiveVarcharWritable;
-import org.apache.hadoop.hive.serde2.io.ShortWritable;
 import org.apache.hadoop.io.IntWritable;
-import org.apache.hadoop.io.LongWritable;
 import org.apache.hadoop.io.Text;
 
 
 public class RangerUdfMask extends RangerBaseUdf {
-	private static final Log LOG = LogFactory.getLog(RangerUdfMask.class);
-
-	private TransformerAdapter transformerAdapter = null;
-
 	public RangerUdfMask() {
-		LOG.debug("==> RangerUdfMask()");
+		super(new MaskTransformer());
+	}
+}
 
-		LOG.debug("<== RangerUdfMask()");
+class MaskTransformer extends RangerBaseUdf.RangerTransformer {
+	final static int MASKED_UPPERCASE            = 'X';
+	final static int MASKED_LOWERCASE            = 'x';
+	final static int MASKED_NUMBER               = '1';
+	final static int MASKED_OTHER_CHAR           = -1;
+	final static int MASKED_DAY_COMPONENT_VAL    = 1;
+	final static int MASKED_MONTH_COMPONENT_VAL  = 0;
+	final static int MASKED_YEAR_COMPONENT_VAL   = 0;
+	final static int UNMASKED_DATE_COMPONENT_VAL = -1;
+
+	int maskedUpperChar   = MASKED_UPPERCASE;
+	int maskedLowerChar   = MASKED_LOWERCASE;
+	int maskedDigitChar   = MASKED_NUMBER;
+	int maskedOtherChar   = MASKED_OTHER_CHAR;
+	int maskedNumber      = MASKED_NUMBER;
+	int maskedDayValue    = MASKED_DAY_COMPONENT_VAL;
+	int maskedMonthValue  = MASKED_MONTH_COMPONENT_VAL;
+	int maskedYearValue   = MASKED_YEAR_COMPONENT_VAL;
+
+	public MaskTransformer() {
 	}
 
 	@Override
-	public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerUdfMask.initialize(arguments.length=" + arguments.length + ")");
-		}
-
-		ObjectInspector ret = super.initialize(arguments);
-
-		String transformType   = null;
-		String transformerImpl = null;
-		String transformerArgs = null;
-
-		if(arguments.length > 1) { // transformType
-			checkArgPrimitive(arguments, 1);
-
-			if(arguments[1] instanceof WritableConstantStringObjectInspector) {
-				Text value = ((WritableConstantStringObjectInspector)arguments[1]).getWritableConstantValue();
-
-				if(value != null) {
-					transformType = value.toString();
-				}
-			}
-		}
-
-		if(arguments.length > 2) { // transformerImpl
-			checkArgPrimitive(arguments, 2);
-
-			if(arguments[2] instanceof WritableConstantStringObjectInspector) {
-				Text value = ((WritableConstantStringObjectInspector)arguments[2]).getWritableConstantValue();
-
-				if(value != null) {
-					transformerImpl = value.toString();
-				}
-			}
-		}
-
-		if(arguments.length > 3) { // transformerArgs
-			checkArgPrimitive(arguments, 3);
-
-			if(arguments[2] instanceof WritableConstantStringObjectInspector) {
-				Text value = ((WritableConstantStringObjectInspector)arguments[3]).getWritableConstantValue();
-
-				if(value != null) {
-					transformerArgs = value.toString();
-				}
-			}
-		}
-
-		RangerTransformer transformer = RangerTransformerFactory.getTransformer(transformType, transformerImpl, transformerArgs);
-
-		transformerAdapter = TransformerAdapter.getTransformerAdapter(columnType.getPrimitiveCategory(), transformer);
+	public void init(ObjectInspector[] arguments, int startIdx) {
+		maskedUpperChar  = getCharArg(arguments, startIdx + 0, MASKED_UPPERCASE);
+		maskedLowerChar  = getCharArg(arguments, startIdx + 1, MASKED_LOWERCASE);
+		maskedDigitChar  = getCharArg(arguments, startIdx + 2, MASKED_NUMBER);
+		maskedOtherChar  = getCharArg(arguments, startIdx + 3, MASKED_OTHER_CHAR);
+		maskedNumber     = getCharArg(arguments, startIdx + 4, MASKED_NUMBER);
+		maskedDayValue   = getIntArg(arguments, startIdx + 5, MASKED_DAY_COMPONENT_VAL);
+		maskedMonthValue = getIntArg(arguments, startIdx + 6, MASKED_MONTH_COMPONENT_VAL);
+		maskedYearValue  = getIntArg(arguments, startIdx + 7, MASKED_YEAR_COMPONENT_VAL);
+	}
 
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("getTransformerAdapter(category=" + columnType.getPrimitiveCategory() + ", transformer=" + transformer + "): " + transformerAdapter);
+	@Override
+	String transform(String value) {
+		return maskString(value, maskedUpperChar, maskedLowerChar, maskedDigitChar, maskedOtherChar, 0, value.length());
+	}
 
-			LOG.debug("<== RangerUdfMask.initialize(arguments.length=" + arguments.length + "): ret=" + ret);
-		}
+	@Override
+	Short transform(Short value) {
+		String strValue = value.toString();
 
-		return ret;
+		return Short.parseShort(maskNumber(strValue, maskedDigitChar, 0, strValue.length()));
 	}
 
 	@Override
-	public Object evaluate(DeferredObject[] arguments) throws HiveException {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerUdfMask.evaluate(arguments.length=" + arguments.length + ")");
-		}
+	Integer transform(Integer value) {
+		String strValue = value.toString();
 
-		final Object ret;
-
-		if(transformerAdapter != null) {
-			Object columnValue = columnType.getPrimitiveJavaObject(arguments[0].get());
-			
-			ret = transformerAdapter.getTransformedWritable(columnValue);
-		} else {
-			ret = columnType.getPrimitiveWritableObject(arguments[0].get());
-		}
+		return Integer.parseInt(maskNumber(strValue, maskedDigitChar, 0, strValue.length()));
+	}
 
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerUdfMask.evaluate(arguments.length=" + arguments.length + "): ret=" + ret);
-		}
+	@Override
+	Long transform(Long value) {
+		String strValue = value.toString();
 
-		return ret;
+		return Long.parseLong(maskNumber(strValue, maskedDigitChar, 0, strValue.length()));
 	}
 
 	@Override
-	public String getDisplayString(String[] children) {
-		return getStandardDisplayString("RangerUdfMask", children, ",");
+	Date transform(Date value) {
+		return maskDate(value, maskedDayValue, maskedMonthValue, maskedYearValue);
 	}
-}
 
-abstract class TransformerAdapter {
-	final RangerTransformer transformer;
-
-	TransformerAdapter(RangerTransformer transformer) {
-		this.transformer = transformer;
-	}
 
-	abstract Object getTransformedWritable(Object value);
+	String maskString(String val, int replaceUpperChar, int replaceLowerChar, int replaceDigitChar, int replaceOtherChar, int startIdx, int endIdx) {
+		StringBuffer strBuf = new StringBuffer(val.length());
 
-	static TransformerAdapter getTransformerAdapter(PrimitiveCategory category, RangerTransformer transformer) {
-		TransformerAdapter ret = null;
+		if(startIdx < 0) {
+			startIdx = 0;
+		}
 
-		if(transformer != null) {
-			switch(category) {
-				case STRING:
-					ret = new StringTransformerAdapter(transformer);
-				break;
+		if(endIdx > val.length()) {
+			endIdx = val.length();
+		}
 
-				case VARCHAR:
-					ret = new VarCharTransformerAdapter(transformer);
-				break;
+		for(int i = 0; i < startIdx; i++) {
+			strBuf.appendCodePoint(val.charAt(i));
+		}
 
-				case SHORT:
-					ret = new ShortTransformerAdapter(transformer);
-				break;
+		for(int i = startIdx; i < endIdx; i++) {
+			int c = val.charAt(i);
 
-				case INT:
-					ret = new IntegerTransformerAdapter(transformer);
-				break;
+			switch(Character.getType(c)) {
+				case Character.UPPERCASE_LETTER:
+					if(replaceUpperChar != -1) {
+						c = replaceUpperChar;
+					}
+					break;
 
-				case LONG:
-					ret = new LongTransformerAdapter(transformer);
-				break;
+				case Character.LOWERCASE_LETTER:
+					if(replaceLowerChar != -1) {
+						c = replaceLowerChar;
+					}
+					break;
 
-				case DATE:
-					ret = new DateTransformerAdapter(transformer);
-				break;
+				case Character.DECIMAL_DIGIT_NUMBER:
+					if(replaceDigitChar != -1) {
+						c = replaceDigitChar;
+					}
+					break;
 
 				default:
-				break;
+					if(replaceOtherChar != -1) {
+						c = replaceOtherChar;
+					}
+					break;
 			}
-		}
-
-		return ret;
-	}
-}
-
-class StringTransformerAdapter extends TransformerAdapter {
-	final Text writable;
 
-	public StringTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new Text());
-	}
+			strBuf.appendCodePoint(c);
+		}
 
-	public StringTransformerAdapter(RangerTransformer transformer, Text writable) {
-		super(transformer);
+		for(int i = endIdx; i < val.length(); i++) {
+			strBuf.appendCodePoint(val.charAt(i));
+		}
 
-		this.writable = writable;
+		return strBuf.toString();
 	}
 
-	@Override
-	public Object getTransformedWritable(Object value) {
-		String transformedValue = transformer.transform((String)value);
-
-		writable.set(transformedValue);
-
-		return writable;
-	}
-}
+	String maskNumber(String val, int replaceDigit, int startIdx, int endIdx) {
+		if(replaceDigit != -1) {
+			StringBuffer strBuf = new StringBuffer(val.length());
 
-class VarCharTransformerAdapter extends TransformerAdapter {
-	final HiveVarcharWritable writable;
+			if (startIdx < 0) {
+				startIdx = 0;
+			}
 
-	public VarCharTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new HiveVarcharWritable());
-	}
+			if (endIdx > val.length()) {
+				endIdx = val.length();
+			}
 
-	public VarCharTransformerAdapter(RangerTransformer transformer, HiveVarcharWritable writable) {
-		super(transformer);
+			for (int i = 0; i < startIdx; i++) {
+				strBuf.appendCodePoint(val.charAt(i));
+			}
 
-		this.writable = writable;
-	}
+			for (int i = startIdx; i < endIdx; i++) {
+				int c = val.charAt(i);
 
-	@Override
-	public Object getTransformedWritable(Object value) {
-		String transformedValue = transformer.transform(((HiveVarchar)value).getValue());
+				switch (Character.getType(c)) {
+					case Character.DECIMAL_DIGIT_NUMBER:
+						c = replaceDigit;
+					break;
+				}
 
-		writable.set(transformedValue);
+				strBuf.appendCodePoint(c);
+			}
 
-		return writable;
-	}
-}
+			for (int i = endIdx; i < val.length(); i++) {
+				strBuf.appendCodePoint(val.charAt(i));
+			}
 
-class ShortTransformerAdapter extends TransformerAdapter {
-	final ShortWritable writable;
+			return strBuf.toString();
+		}
 
-	public ShortTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new ShortWritable());
+		return val;
 	}
 
-	public ShortTransformerAdapter(RangerTransformer transformer, ShortWritable writable) {
-		super(transformer);
+	Date maskDate(Date value, int maskedDay, int maskedMonth, int maskedYear) {
+		int year  = maskedYear  == UNMASKED_DATE_COMPONENT_VAL ? value.getYear()  : MASKED_YEAR_COMPONENT_VAL;
+		int month = maskedMonth == UNMASKED_DATE_COMPONENT_VAL ? value.getMonth() : MASKED_MONTH_COMPONENT_VAL;
+		int day   = maskedDay   == UNMASKED_DATE_COMPONENT_VAL ? value.getDate()  : MASKED_DAY_COMPONENT_VAL;
 
-		this.writable = writable;
+		return new Date(year, month, day);
 	}
 
-	@Override
-	public Object getTransformedWritable(Object value) {
-		Short transformedValue = transformer.transform((Short)value);
+	String getStringArg(ObjectInspector[] arguments, int index, String defaultValue) {
+		String ret = defaultValue;
 
-		writable.set(transformedValue);
+		ObjectInspector arg = (arguments != null && arguments.length > index) ? arguments[index] : null;
 
-		return writable;
-	}
-}
+		if (arg != null) {
+			if (arg instanceof WritableConstantStringObjectInspector) {
+				Text value = ((WritableConstantStringObjectInspector) arg).getWritableConstantValue();
 
-class IntegerTransformerAdapter extends TransformerAdapter {
-	final IntWritable writable;
+				if (value != null && value.getLength() > 0) {
+					ret = value.toString();
+				}
+			}
+		}
 
-	public IntegerTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new IntWritable());
+		return ret;
 	}
 
-	public IntegerTransformerAdapter(RangerTransformer transformer, IntWritable writable) {
-		super(transformer);
+	int getCharArg(ObjectInspector[] arguments, int index, int defaultValue) {
+		int ret = defaultValue;
 
-		this.writable = writable;
-	}
-
-	@Override
-	public Object getTransformedWritable(Object value) {
-		Integer transformedValue = transformer.transform((Integer)value);
+		String value = getStringArg(arguments, index, null);
 
-		writable.set(transformedValue);
+		if (StringUtils.isNotEmpty(value)) {
+			ret = value.charAt(0);
+		}
 
-		return writable;
+		return ret;
 	}
-}
-
-class LongTransformerAdapter extends TransformerAdapter {
-	final LongWritable writable;
 
-	public LongTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new LongWritable());
-	}
+	int getIntArg(ObjectInspector[] arguments, int index, int defaultValue) {
+		int ret = defaultValue;
 
-	public LongTransformerAdapter(RangerTransformer transformer, LongWritable writable) {
-		super(transformer);
+		ObjectInspector arg = (arguments != null && arguments.length > index) ? arguments[index] : null;
 
-		this.writable = writable;
-	}
+		if (arg != null) {
+			if (arg instanceof WritableConstantStringObjectInspector) {
+				Text value = ((WritableConstantStringObjectInspector) arg).getWritableConstantValue();
 
-	@Override
-	public Object getTransformedWritable(Object value) {
-		Long transformedValue = transformer.transform((Long)value);
+				if (value != null) {
+					try {
+						ret = Integer.parseInt(value.toString());
+					} catch(NumberFormatException excp) {
+						// ignored; defaultValue will be returned
+					}
+				}
+			} else if(arg instanceof WritableConstantIntObjectInspector) {
+				IntWritable value = ((WritableConstantIntObjectInspector)arg).getWritableConstantValue();
 
-		writable.set(transformedValue);
+				if(value != null) {
+					ret = value.get();
+				}
+			}
+		}
 
-		return writable;
+		return ret;
 	}
 }
 
-class DateTransformerAdapter extends TransformerAdapter {
-	final DateWritable writable;
-
-	public DateTransformerAdapter(RangerTransformer transformer) {
-		this(transformer, new DateWritable());
-	}
-
-	public DateTransformerAdapter(RangerTransformer transformer, DateWritable writable) {
-		super(transformer);
-
-		this.writable = writable;
-	}
-
-	@Override
-	public Object getTransformedWritable(Object value) {
-		Date transformedValue = transformer.transform((Date)value);
-
-		writable.set(transformedValue);
-
-		return writable;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskFirstN.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskFirstN.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskFirstN.java
new file mode 100644
index 0000000..f6ece4d
--- /dev/null
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskFirstN.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hive.udf;
+
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+
+public class RangerUdfMaskFirstN extends RangerBaseUdf {
+    public RangerUdfMaskFirstN() {
+        super(new MaskFirstNTransformer());
+    }
+}
+
+class MaskFirstNTransformer extends MaskTransformer {
+    int charCount = 4;
+
+    public MaskFirstNTransformer() {
+        super();
+    }
+
+    @Override
+    public void init(ObjectInspector[] arguments, int argsStartIdx) {
+        super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed in this method below
+
+        charCount = getIntArg(arguments, argsStartIdx, 4);
+    }
+
+    @Override
+    String transform(String value) {
+        return maskString(value, maskedUpperChar, maskedLowerChar, maskedDigitChar, maskedOtherChar, 0, charCount);
+    }
+
+    @Override
+    Short transform(Short value) {
+        String strValue = value.toString();
+
+        return Short.parseShort(maskNumber(strValue, maskedDigitChar, 0, charCount));
+    }
+
+    @Override
+    Integer transform(Integer value) {
+        String strValue = value.toString();
+
+        return Integer.parseInt(maskNumber(strValue, maskedDigitChar, 0, charCount));
+    }
+
+    @Override
+    Long transform(Long value) {
+        String strValue = value.toString();
+
+        return Long.parseLong(maskNumber(strValue, maskedDigitChar, 0, charCount));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskHash.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskHash.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskHash.java
new file mode 100644
index 0000000..5afc66b
--- /dev/null
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskHash.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hive.udf;
+
+import java.sql.Date;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+
+public class RangerUdfMaskHash extends RangerBaseUdf {
+    public RangerUdfMaskHash() {
+        super(new MaskHashTransformer());
+    }
+}
+
+class MaskHashTransformer extends RangerBaseUdf.RangerTransformer {
+    @Override
+    public void init(ObjectInspector[] arguments, int startIdx) {
+    }
+
+    @Override
+    String transform(String value) {
+        return DigestUtils.md5Hex(value);
+    }
+
+    @Override
+    Short transform(Short value) {
+        return value;
+    }
+
+    @Override
+    Integer transform(Integer value) {
+        return value;
+    }
+
+    @Override
+    Long transform(Long value) {
+        return value;
+    }
+
+    @Override
+    Date transform(Date value) {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskLastN.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskLastN.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskLastN.java
new file mode 100644
index 0000000..1ea433d
--- /dev/null
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskLastN.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hive.udf;
+
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+
+public class RangerUdfMaskLastN extends RangerBaseUdf {
+    public RangerUdfMaskLastN() {
+        super(new MaskLastNTransformer());
+    }
+}
+
+class MaskLastNTransformer extends MaskTransformer {
+    int charCount = 4;
+
+    public MaskLastNTransformer() {
+        super();
+    }
+
+    @Override
+    public void init(ObjectInspector[] arguments, int argsStartIdx) {
+        super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed in this method below
+
+        charCount = getIntArg(arguments, argsStartIdx, 4);
+    }
+
+    @Override
+    String transform(String value) {
+        return maskString(value, maskedUpperChar, maskedLowerChar, maskedDigitChar, maskedOtherChar, value.length() - charCount, value.length());
+    }
+
+    @Override
+    Short transform(Short value) {
+        String strValue = value.toString();
+
+        return Short.parseShort(maskNumber(strValue, maskedDigitChar, strValue.length() - charCount, strValue.length()));
+    }
+
+    @Override
+    Integer transform(Integer value) {
+        String strValue = value.toString();
+
+        return Integer.parseInt(maskNumber(strValue, maskedDigitChar, strValue.length() - charCount, strValue.length()));
+    }
+
+    @Override
+    Long transform(Long value) {
+        String strValue = value.toString();
+
+        return Long.parseLong(maskNumber(strValue, maskedDigitChar, strValue.length() - charCount, strValue.length()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowFirstN.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowFirstN.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowFirstN.java
new file mode 100644
index 0000000..a7ce40f
--- /dev/null
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowFirstN.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hive.udf;
+
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+
+public class RangerUdfMaskShowFirstN extends RangerBaseUdf {
+    public RangerUdfMaskShowFirstN() {
+        super(new MaskShowFirstNTransformer());
+    }
+}
+
+class MaskShowFirstNTransformer extends MaskTransformer {
+    int charCount = 4;
+
+    public MaskShowFirstNTransformer() {
+        super();
+    }
+
+    @Override
+    public void init(ObjectInspector[] arguments, int argsStartIdx) {
+        super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed here
+
+        charCount = getIntArg(arguments, argsStartIdx, 4);
+    }
+
+    @Override
+    String transform(String value) {
+        return maskString(value, maskedUpperChar, maskedLowerChar, maskedDigitChar, maskedOtherChar, charCount, value.length());
+    }
+
+    @Override
+    Short transform(Short value) {
+        String strValue = value.toString();
+
+        return Short.parseShort(maskNumber(strValue, maskedDigitChar, charCount, strValue.length()));
+    }
+
+    @Override
+    Integer transform(Integer value) {
+        String strValue = value.toString();
+
+        return Integer.parseInt(maskNumber(strValue, maskedDigitChar, charCount, strValue.length()));
+    }
+
+    @Override
+    Long transform(Long value) {
+        String strValue = value.toString();
+
+        return Long.parseLong(maskNumber(strValue, maskedDigitChar, charCount, strValue.length()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowLastN.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowLastN.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowLastN.java
new file mode 100644
index 0000000..3abe636
--- /dev/null
+++ b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/RangerUdfMaskShowLastN.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.authorization.hive.udf;
+
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+
+public class RangerUdfMaskShowLastN extends RangerBaseUdf {
+    public RangerUdfMaskShowLastN() {
+        super(new MaskShowLastNTransformer());
+    }
+}
+
+class MaskShowLastNTransformer extends MaskTransformer {
+    int charCount;
+
+    public MaskShowLastNTransformer() {
+        super();
+    }
+
+    @Override
+    public void init(ObjectInspector[] arguments, int argsStartIdx) {
+        super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed in this method below
+
+        charCount = getIntArg(arguments, argsStartIdx, 4);
+    }
+
+    @Override
+    String transform(String value) {
+        return maskString(value, maskedUpperChar, maskedLowerChar, maskedDigitChar, maskedOtherChar, 0, value.length() - charCount);
+    }
+
+    @Override
+    Short transform(Short value) {
+        String strValue = value.toString();
+
+        return Short.parseShort(maskNumber(strValue, maskedDigitChar, 0, strValue.length() - charCount));
+    }
+
+    @Override
+    Integer transform(Integer value) {
+        String strValue = value.toString();
+
+        return Integer.parseInt(maskNumber(strValue, maskedDigitChar, 0, strValue.length() - charCount));
+    }
+
+    @Override
+    Long transform(Long value) {
+        String strValue = value.toString();
+
+        return Long.parseLong(maskNumber(strValue, maskedDigitChar, 0, strValue.length() - charCount));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/7b8b6bb7/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/ShuffleTransformer.java
----------------------------------------------------------------------
diff --git a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/ShuffleTransformer.java b/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/ShuffleTransformer.java
deleted file mode 100644
index ee5023a..0000000
--- a/ranger-hive-utils/src/main/java/org/apache/ranger/authorization/hive/udf/ShuffleTransformer.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hive.udf;
-
-import java.sql.Date;
-
-
-public class ShuffleTransformer extends RangerTransformer {
-	public ShuffleTransformer() {
-	}
-
-	@Override
-	public void init(String initParam) {
-	}
-
-	@Override
-	String transform(String value) {
-		String ret = value;
-
-		if(value != null) {
-			final char[] chars = value.toCharArray();
-
-			for(int i = 0; i < chars.length; i++) {
-				int rIdx = (int)(Math.random() * chars.length);
-				char swapTmp = chars[i];
-				chars[i] = chars[rIdx];
-				chars[rIdx] = swapTmp;
-			}
-
-			ret = new String(chars);
-		}
-
-		return ret;
-	}
-
-	@Override
-	Short transform(Short value) {
-		Short ret = value;
-
-		if(value != null) {
-			String strValue = Short.toString(value);
-
-			ret = Short.parseShort(transform(strValue));
-		}
-
-		return ret;
-	}
-
-	@Override
-	Integer transform(Integer value) {
-		Integer ret = value;
-
-		if(value != null) {
-			String strValue = Integer.toString(value);
-
-			ret = Integer.parseInt(transform(strValue));
-		}
-
-		return ret;
-	}
-
-	@Override
-	Long transform(Long value) {
-		Long ret = value;
-
-		if(value != null) {
-			String strValue = Long.toString(value);
-
-			ret = Long.parseLong(transform(strValue));
-		}
-
-		return ret;
-	}
-
-	@Override
-	Date transform(Date value) {
-		Date ret = value;
-
-		if(value != null) {
-			// TODO: date shuffle
-		}
-
-		return ret;
-	}
-}