RANGER-3804: Update policy UI to support multiple resource-sets
diff --git a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
index 9237abd..2bc552b 100644
--- a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
+++ b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
@@ -487,6 +487,9 @@
 		  events: {
 			  'click':  function(event) {
 			  },
+			  'change':  function(event) {
+				  this.trigger('change', this);
+			  },
 		  },
 		  initialize: function(options) {
 		    Form.editors.Base.prototype.initialize.call(this, options);
@@ -691,7 +694,8 @@
                             that.renderResource(def);
                         }
                         //trigger resource event for showing respective access permissions
-                        Vent.trigger('resourceType:change', changeType = 'resourceType', e.currentTarget.value, e.currentTarget.value, e);
+                        var resourceItemIndex = that.form.model && that.form.model.collection.indexOf(that.form.model);
+						Vent.trigger('resourceType:change', { changeType : 'resourceType', value : e.currentTarget.value, resourceName: e.currentTarget.value, event:e, resourceItemIndex : resourceItemIndex });
 					});
 			  	}
 		  },
diff --git a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
index 28f05ae..7cd3194 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/PermissionList.js
@@ -105,8 +105,7 @@
 //				if(XAUtil.isMaskingPolicy(this.rangerPolicyType)) this.renderMaskingTypesForTagBasedPolicies();
 			} else {
 //				To handle scenario : Access permission doesnt changes if we change resource before adding new policy item.
-				this.renderPerms(this.storeResourceRef.changeType, this.storeResourceRef.value,
-						this.storeResourceRef.resourceName, this.storeResourceRef.e );
+				this.renderPerms({ action : "permissionItemAdd" });
 				if(XAUtil.isMaskingPolicy(this.rangerPolicyType)){
 					this.renderMaskingType();
 				}
@@ -279,16 +278,35 @@
 				}
 			}).on('select2-focus', XAUtil.select2Focus);
 		},
-		renderPerms :function(changeType, value, resourceName, e){
+		renderPerms :function({changeType, value, resourceName, event, resourceItemIndex, action}){
 	        var that = this , accessTypeByResource = this.accessTypes;
-	        this.storeResourceRef.changeType = changeType;
-	        this.storeResourceRef.value = value;
-	        this.storeResourceRef.resourceName = resourceName;
-	        this.storeResourceRef.e = e;
+			if(action === 'removed'){
+				var removedItemIndex = _.findIndex(this.storeResourceRef, function(a){ return a.resourceItemIndex == resourceItemIndex;});
+				if(removedItemIndex >= 0){
+					this.storeResourceRef.splice(this.storeResourceRef.findIndex(item => item.resourceItemIndex === resourceItemIndex), 1);
+					_.each(this.storeResourceRef, (obj, index) => {
+						if(index >= removedItemIndex){
+							obj.resourceItemIndex = obj.resourceItemIndex - 1;
+						}
+					});
+				}
+			} else if (changeType || action== 'added') {
+				var resourceChangeObj = { resourceItemIndex, changeType, value, resourceName, event };
+				var found = _.findWhere(this.storeResourceRef, { resourceItemIndex: resourceItemIndex });
+				if(found && changeType){
+					_.extend(_.findWhere(this.storeResourceRef, { resourceItemIndex: resourceItemIndex }), resourceChangeObj );
+				} else {
+					this.storeResourceRef.push(resourceChangeObj)
+				}
+			}
 	        //get permissions by resource only for access policy
-	        accessTypeByResource = this.getAccessPermissionForSelectedResource(changeType, value, resourceName, e);
+			accessTypeByResource = (this.storeResourceRef.length && (changeType || action === 'removed' || action === 'permissionItemAdd'))
+				? [] : accessTypeByResource;
+			_.each(this.storeResourceRef, (obj) => {
+				accessTypeByResource = _.union(accessTypeByResource, this.getAccessPermissionForSelectedResource(obj.changeType, obj.value, obj.resourceName, obj.event));
+			});
 	        //reset permissions on resource change
-	        if(this.permsIds.length > 0 && !_.isUndefined(changeType) && !_.isUndefined(resourceName)){
+	        if(this.permsIds.length > 0 && ( !_.isUndefined(changeType) && !_.isUndefined(resourceName) || action === 'removed') ){
 	                this.permsIds = [];
 	        }
 	        this.perms =  _.map(accessTypeByResource , function(m){return {text : m.label, value : m.name};});
@@ -297,9 +315,9 @@
 			}
 			//if policy items not present. its skip that items and move forward
 			if(_.isObject(this.ui.addPerms)){
-                                if(changeType){
-                                    this.ui.addPerms.editable("destroy");
-                                }
+				if(changeType || action === 'removed' || action== 'added'){
+					this.ui.addPerms.editable("destroy");
+				}
 				//create x-editable for permissions
 				this.ui.addPerms.editable({
 					emptytext : 'Add Permissions',
@@ -1009,7 +1027,31 @@
 			if(this.collection.length == 0){
 				this.collection.add(new Backbone.Model())
 			}
-			this.storeResourceRef = {};
+			this.storeResourceRef = [];
+			var resourceDefByPolicyType = this.getResourceDefByPolicyType();
+			if(!this.model.isNew()){
+				_.each(_.union([this.model.get('resources')], this.model.get('additionalResources')), function(obj, index){
+					var resourceNames = Object.keys(obj);
+					var resourceName = resourceNames[0];
+					if(resourceName.length > 1){
+						var resourceByDef = resourceDefByPolicyType.filter((resource) => resourceNames.includes(resource.name) );
+						var maxLevel = Math.max(...resourceByDef.map(function(o) { return o.level; }));
+						var resource = resourceByDef.find(function(o) { return o.level == maxLevel; });
+						resourceName = resource.name;
+					}
+					this.storeResourceRef.push({'changeType': 'resourceType','resourceName': resourceName, value: resourceName, resourceItemIndex: index });
+				}, this);
+			} else {
+				let getChildResource = (resource) => {
+					var childResource = _.findWhere(resourceDefByPolicyType, {parent : resource.name  });
+					if(childResource){
+						return getChildResource(childResource);
+					}
+					return resource.name;
+				}
+				var resourceName = getChildResource(resourceDefByPolicyType[0])
+				this.storeResourceRef.push({'changeType': 'resourceType','resourceName': resourceName, value: resourceName, resourceItemIndex: 0 });
+			}
 		},
 		onRender : function(){
 			this.makePolicyItemSortable();
@@ -1075,6 +1117,20 @@
 					that.$el.find(ui.item[0]).addClass("dirtyField");
 				},
 			});
+		},
+		getResourceDefByPolicyType : function () {
+			var resourceDefList =   this.rangerServiceDefModel.get('resources');
+			if(XAUtil.isMaskingPolicy(this.model.get('policyType'))){
+				if(!_.isEmpty(this.rangerServiceDefModel.get('dataMaskDef').resources)){
+					resourceDefList = this.rangerServiceDefModel.get('dataMaskDef').resources;
+				}
+			}
+			if(XAUtil.isRowFilterPolicy(this.model.get('policyType'))){
+				if(!_.isEmpty(this.rangerServiceDefModel.get('rowFilterDef').resources)){
+					resourceDefList = this.rangerServiceDefModel.get('rowFilterDef').resources;
+				}
+			}
+			return resourceDefList
 		}
 	});
 
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
index 65c4f66..b1e7a11 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyCreate.js
@@ -178,8 +178,9 @@
 			if(! _.isEmpty(errors)){
 				return;
 			}
-			
-			
+			if(this.form.validatePolicyResource()){
+				return;
+			}
 			//validate policyItems in the policy
 			var validateObj1 = this.form.formValidation(this.form.formInputList);
 			if(!this.validatePolicyItem(validateObj1)) return;
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
index a672648..c26eaed 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyForm.js
@@ -26,18 +26,12 @@
 	var localization	= require('utils/XALangSupport');
 	var XAUtil			= require('utils/XAUtils');
     
-	var VXAuditMap		= require('models/VXAuditMap');
-	var VXPermMap		= require('models/VXPermMap');
-	var VXPermMapList	= require('collections/VXPermMapList');
-	var VXGroupList		= require('collections/VXGroupList');
-	var VXAuditMapList	= require('collections/VXAuditMapList');
-	var VXUserList		= require('collections/VXUserList');
 	var PermissionList 	= require('views/policies/PermissionList');
     var vPolicyTimeList 	= require('views/policies/PolicyTimeList');
-	var RangerPolicyResource		= require('models/RangerPolicyResource');
 	var BackboneFormDataType	= require('models/BackboneFormDataType');
     var App             = require('App');
     var vPolicyCondition = require('views/policies/RangerPolicyConditions');
+	var ResourceList 	= require('views/policies/ResourceList');
 
 	require('backbone-forms.list');
 	require('backbone-forms.templates');
@@ -79,10 +73,10 @@
 		initialize: function(options) {
 			console.log("initialized a RangerPolicyForm Form View");
 			_.extend(this, _.pick(options, 'rangerServiceDefModel', 'rangerService'));
-    		this.setupForm();
     		Backbone.Form.prototype.initialize.call(this, options);
 
 			this.initializeCollection();
+			this.setupForm();
 			this.bindEvents();
 			this.defaultValidator={}
 		},
@@ -97,6 +91,7 @@
 			this.formInputAllowExceptionList= XAUtil.makeCollForGroupPermission(this.model, 'allowExceptions');
 			this.formInputDenyList 		= XAUtil.makeCollForGroupPermission(this.model, 'denyPolicyItems');
 			this.formInputDenyExceptionList = XAUtil.makeCollForGroupPermission(this.model, 'denyExceptions');
+			this.formInputResourceList = new Backbone.Collection();
 		},
 		/** all events binding here */
 		bindEvents : function(){
@@ -106,7 +101,6 @@
 			this.on('isEnabled:change', function(form, fieldEditor){
 				this.evIsEnabledChange(form, fieldEditor);
 			});
-			this.on('policyForm:parentChildHideShow',this.renderParentChildHideShow);
 		},
 		ui : {
 			'denyConditionItems' : '[data-js="denyConditionItems"]',
@@ -123,35 +117,26 @@
 			return this.getSchema();
 		},
 		getSchema : function(){
-			var attrs = {},that = this;
-                        var basicSchema = ['name','isEnabled','policyPriority','policyLabels'];
+			var basicSchema = ['name','isEnabled','policyPriority','policyLabels'];
 			var schemaNames = this.getPolicyBaseFieldNames();
-
-			var formDataType = new BackboneFormDataType();
-			attrs = formDataType.getFormElements(this.rangerServiceDefModel.get('resources'),this.rangerServiceDefModel.get('enums'), attrs, this, true);
-                        if(this.model.schemaBase){
-                                var attr1 = _.pick(_.result(this.model,'schemaBase'),basicSchema);
-                                var attr2 = _.pick(_.result(this.model,'schemaBase'),schemaNames);
-                                return _.extend(attr1,_.extend(attrs,attr2));
-                        }
+			if(this.model.schemaBase){
+				var attr1 = _.pick(_.result(this.model,'schemaBase'),basicSchema);
+				var attr2 = _.pick(_.result(this.model,'schemaBase'),schemaNames);
+				return _.extend(attr1,attr2);
+			}
 		},
 		/** on render callback */
 		render: function(options) {
             var that = this;
 			Backbone.Form.prototype.render.call(this, options);
-			//initialize path plugin for hdfs component : resourcePath
-                        if(!_.isUndefined(this.initilializePathPlugin) && this.initilializePathPlugin){
-				this.initializePathPlugins(this.pathPluginOpts);
-			}
 			if(XAUtil.isAccessPolicy(this.model.get('policyType'))){
 				this.evdenyAccessChange();
 			}
 			if(!this.model.isNew()){
 				this.setUpSwitches();
 			}
+			this.renderPolicyResource();
 			this.renderCustomFields();
-			//checkParent
-			this.renderParentChildHideShow();
 
 			//to show error msg on below the field(only for policy name)
             if(this.fields.isEnabled){
@@ -343,60 +328,16 @@
 
 		},
 		setupForm : function() {
+			var that = this;
 			if(!this.model.isNew()){
-				this.selectedResourceTypes = {};
-				var resourceDefList = this.rangerServiceDefModel.get('resources');
-				if(XAUtil.isMaskingPolicy(this.model.get('policyType')) && XAUtil.isRenderMasking(this.rangerServiceDefModel.get('dataMaskDef'))){
-					if(!_.isEmpty(this.rangerServiceDefModel.get('dataMaskDef').resources)){
-						resourceDefList = this.rangerServiceDefModel.get('dataMaskDef').resources;
-					}
-				}
-				if(XAUtil.isRowFilterPolicy(this.model.get('policyType')) && XAUtil.isRenderRowFilter(this.rangerServiceDefModel.get('rowFilterDef'))){
-					if(!_.isEmpty(this.rangerServiceDefModel.get('rowFilterDef').resources)){
-						resourceDefList = this.rangerServiceDefModel.get('rowFilterDef').resources;
-					}
-				}
-				_.each(this.model.get('resources'),function(obj,key){
-					var resourceDef = _.findWhere(resourceDefList,{'name':key}),
-					sameLevelResourceDef = [], parentResource ;
-					sameLevelResourceDef = _.filter(resourceDefList, function(objRsc){
-						if (objRsc.level === resourceDef.level && objRsc.parent === resourceDef.parent) {
-							return objRsc
-						}
-					});
-					//for parent leftnode status
-                    if(resourceDef.parent){
-                    	parentResource = _.findWhere(resourceDefList ,{'name':resourceDef.parent});
-                    }
-                    if(sameLevelResourceDef.length == 1 && !_.isUndefined(sameLevelResourceDef[0].parent)
-                    		&& !_.isEmpty(sameLevelResourceDef[0].parent)
-                    		&& parentResource.isValidLeaf){
-//						optionsAttrs.unshift({'level':v.level, name:'none',label:'none'});
-                    	sameLevelResourceDef.push({'level':sameLevelResourceDef[0].level, name:'none',label:'none'});
-                    }
-					if(sameLevelResourceDef.length > 1){
-						obj['resourceType'] = key;
-                                                if(_.isUndefined(resourceDef.parent)){
-                                                        this.model.set('sameLevel'+resourceDef.level, obj);
-                                                        //parentShowHide
-                                                        this.selectedResourceTypes['sameLevel'+resourceDef.level] = key;
-                                                }else{
-                                                        this.model.set('sameLevel'+resourceDef.level+resourceDef.parent, obj);
-                                                        this.selectedResourceTypes['sameLevel'+resourceDef.level+resourceDef.parent] = key;
-                                                }
+				var additionalResources = [this.model.get('resources')];
+				additionalResources = _.union(additionalResources, this.model.get('additionalResources'));
 
-					}else{
-						//single value support
-						/*if(! XAUtil.isSinglevValueInput(resourceDef) ){
-							this.model.set(resourceDef.name, obj)
-						}else{
-							//single value resource
-							this.model.set(resourceDef.name, obj.values)
-						}*/
-						this.model.set(resourceDef.name, obj)
-					}
-                                },this);
+				_.each(additionalResources, function(resources, index) {
+					that.formInputResourceList.add({resources: resources, id : "resource"+index, policyType: that.model.get('policyType'), ...resources});
+				});
 			}
+
 		},
 		setUpSwitches :function(){
 			var that = this;
@@ -461,96 +402,34 @@
                         }
 
 		},
-		renderParentChildHideShow : function(onChangeOfSameLevelType, val, e) {
-			var formDiv = this.$el.find('.policy-form');
-			if(!this.model.isNew() && !onChangeOfSameLevelType){
-				_.each(this.selectedResourceTypes, function(val, sameLevelName) {
-					if(formDiv.find('.field-'+sameLevelName).length > 0){
-						formDiv.find('.field-'+sameLevelName).attr('data-name','field-'+val)
-					}
-				});
-			}
-			//hide form fields if it's parent is hidden
-			var resources = formDiv.find('.form-group');
-			_.each(resources, function(rsrc , key ){ 
-				var parent = $(rsrc).attr('parent');
-				var label = $(rsrc).find('label').html();
-				$(rsrc).removeClass('error');
-//				remove validation and Required msg
-				$(rsrc).find('.help-inline').empty();
-				$(rsrc).find('.help-block').empty();
-				if( !_.isUndefined(parent) && ! _.isEmpty(parent)){
-	                var selector = "div[data-name='field-"+parent+"']";
-	                var kclass = formDiv.find(selector).attr('class');
-	                var label = $(rsrc).find('label').html();
-	                if(_.isUndefined(kclass) || (kclass.indexOf("field-sameLevel") >= 0
-	                                && formDiv.find(selector).find('select').val() != parent) 
-	                                || formDiv.find(selector).hasClass('hideResource')){
-	                	$(rsrc).addClass('hideResource');
-	                	$(rsrc).removeClass('error');
-//	                	reset input field to "none" if it is hide
-	                	var resorceFieldName = _.pick(this.schema ,this.selectedFields[key]);
-	                	if(resorceFieldName[this.selectedFields[key]].sameLevelOpts && _.contains(resorceFieldName[this.selectedFields[key]].sameLevelOpts , 'none') 
-	                			&& formDiv.find(selector).find('select').val() != 'none' && onChangeOfSameLevelType){
-						//change trigger and set value to selected node
-							$(rsrc).find('select').val($(rsrc).find('select option:nth-child(1)').text()).trigger('change',"onChangeResources");
-		                }
-	                }else{
-	                    if($(rsrc).find('select').val() == 'none'){
-	                    		$(rsrc).find('input[data-js="resource"]').select2('disable');
-	                            $(rsrc).removeClass('error');
-	                            $(rsrc).find('label').html(label.split('*').join(''));
-	                    }else{
-	                            $(rsrc).find('input[data-js="resource"]').select2('enable');
-	                            $(rsrc).find('label').html(label.slice(-1) == '*' ? label : label +"*");
-	                    }
-	                        $(rsrc).removeClass('hideResource');
-					}
-				}
-			},this);
-			//remove validation of fields if it's hidden
-			//remove validation if fields is not empty
-			_.each(this.fields, function(field, key){
-				if((key.substring(0,key.length-2) === "sameLevel") && field.$el.find('[data-js="resource"]').val()!="" && field.$el.hasClass('error')){
-					field.$el.removeClass('error');
-					field.$el.find('.help-inline').empty();
-				}
-				if(field.$el.hasClass('hideResource')){
-					if($.inArray('required',field.editor.validators) >= 0){
-						this.defaultValidator[key] = field.editor.validators;
-						field.editor.validators=[];
-						var label = field.$el.find('label').html();
-						field.$el.find('label').html(label.replace('*', ''));
-						field.$el.removeClass('error');
-						field.$el.find('.help-inline').empty();
-					}
-				}else{
-	                if(field.$el.find('select').val() == 'none'){
-	                    field.editor.validators=[];
-	                    this.defaultValidator[key] = field.editor.validators;
-	                    field.$el.removeClass('error');
-	                    field.$el.find('.help-inline').empty();
-	                }else{
-	                    if(!_.isUndefined(this.defaultValidator[key])){
-	                    	field.editor.validators.push('required');
-		                    if($.inArray('required',field.editor.validators) >= 0){
-		                        var label = field.$el.find('label').html();
-		                        field.$el.find('label').html(label.slice(-1) == '*'  ? label : label +"*");
-		                    }
+		beforeSave : function(){
+			var additionResources = [];
+			//set sameLevel fieldAttr value with resource name
+			this.formInputResourceList.each(function(model) {
+				let resource = {}
+				_.each(model.attributes, function(val, key) {
+					var isSameLevelResource = key.indexOf("sameLevel") >= 0, isResource = !['policyType', 'resourceForm', 'none', 'resources','id'].includes(key);
+					if ((isSameLevelResource || isResource) && !_.isNull(val)) {
+						var resourceName = isSameLevelResource ? val.resourceType : key;
+						if(resourceName && resourceName != 'none'){
+							model.set(resourceName, val);
+							resource[resourceName] = {
+								values: _.isObject(val.resource[0]) ? _.pluck(val.resource, 'text') : val.resource
+							};
+							if(!_.isUndefined(val.isRecursive)){
+								resource[resourceName]['isRecursive'] = val.isRecursive;
+							}
+							if(!_.isUndefined(val.isExcludes)){
+								resource[resourceName]['isExcludes'] = val.isExcludes;
+							}
+						}
+						if(isSameLevelResource) {
+							model.unset(key);
 						}
 					}
-				}
-			}, this);
-		},
-		beforeSave : function(){
-			var that = this, resources = {};
-			//set sameLevel fieldAttr value with resource name
-			_.each(this.model.attributes, function(val, key) {
-				if(key.indexOf("sameLevel") >= 0 && !_.isNull(val)){
-					this.model.set(val.resourceType,val);
-					that.model.unset(key);
-				}
-			},this);
+				}, this);
+				additionResources.push(resource);
+			});
 			//To set resource values
 			//Check for masking policies
 			var resourceDef = this.rangerServiceDefModel.get('resources');
@@ -564,37 +443,7 @@
 			if(XAUtil.isRowFilterPolicy(this.model.get('policyType')) && XAUtil.isRenderRowFilter(this.rangerServiceDefModel.get('rowFilterDef'))){
 				resourceDef = this.rangerServiceDefModel.get('rowFilterDef').resources;
 			}
-			_.each(resourceDef,function(obj){
-				if(!_.isNull(obj)){
-					var tmpObj =  that.model.get(obj.name);
-					var rPolicyResource = new RangerPolicyResource();
-					//single value support
-//					if(! XAUtil.isSinglevValueInput(obj) ){
-					if(!_.isUndefined(tmpObj) && _.isObject(tmpObj) && !_.isEmpty(tmpObj.resource)){
-						rPolicyResource.set('values',_.map(tmpObj.resource, function(m) {
-							if(obj.type == "path") {
-								return m
-							} else {
-								return m.text
-							}
-						}));
-						if(!_.isUndefined(tmpObj.isRecursive)){
-							rPolicyResource.set('isRecursive', tmpObj.isRecursive)
-						}
-						if(!_.isUndefined(tmpObj.isExcludes)){
-							rPolicyResource.set('isExcludes', tmpObj.isExcludes)
-						}
-						resources[obj.name] = rPolicyResource;
-						that.model.unset(obj.name);
-					}
-//					}else{
-//						//For single value resource
-//						rPolicyResource.set('values',tmpObj.split(','));
-//						resources[obj.name] = rPolicyResource;
-//						that.model.unset(obj.name);
-//					}
-				}
-			});
+
             if(this.model.has('policyLabels')){
                 var policyLabel = _.isEmpty(this.model.get('policyLabels')) ? [] : this.model.get('policyLabels').split(',');
                 this.model.set('policyLabels', policyLabel);
@@ -602,7 +451,9 @@
             if(!_.isUndefined(App.vZone) && App.vZone.vZoneName){
                 this.model.set('zoneName', App.vZone.vZoneName);
             }
-			this.model.set('resources',resources);
+			this.model.set('resources',additionResources[0]);
+			additionResources.shift();
+			this.model.set('additionalResources',additionResources);
 			if(this.model.get('none')) {
 				this.model.unset('none');
 			}
@@ -681,227 +532,6 @@
 			}, this);
 			return policyItemList;
 		},
-		/** all post render plugin initialization */
-		initializePathPlugins: function(options){
-			var that= this,defaultValue = [];
-                        if(!this.model.isNew() && !_.isUndefined(this.model.get('path'))){
-				defaultValue = this.model.get('path').values;
-			}
-			var tagitOpts = {}
-            if(!_.isUndefined(options.lookupURL) && options.lookupURL){
-                tagitOpts["autocomplete"] = {
-                    cache: false,
-                    source: function( request, response ) {
-                        var url = "service/plugins/services/lookupResource/"+that.rangerService.get('name');
-                        var context ={
-                            'userInput' : request.term,
-                            'resourceName' : that.pathFieldName,
-                            'resources' : {}
-                        };
-                        var val = that.fields[that.pathFieldName].editor.getValue('pathField');
-                        context.resources[that.pathFieldName] = _.isNull(val) || _.isEmpty(val) ? [] : val.resource;
-                        var p = $.ajax({
-                            url : url,
-                            type : "POST",
-                            data : JSON.stringify(context),
-                            dataType : 'json',
-                            contentType: "application/json; charset=utf-8",
-                        }).done(function(data){
-                            if(data){
-                                response(data);
-                            } else {
-                                response();
-                            }
-                        }).fail(function(responses){
-                            if (responses && responses.responseJSON && responses.responseJSON.msgDesc) {
-                                XAUtil.notifyError('Error', responses.responseJSON.msgDesc);
-                            } else {
-                                XAUtil.notifyError('Error', localization.tt('msg.resourcesLookup'));
-                            }
-                            response();
-                        });
-                        setTimeout(function(){
-                            p.abort();
-                            console.log('connection timeout for resource path request...!!');
-                        }, 10000);
-                    },
-                    open : function(){
-                        $(this).removeClass('working');
-                    },
-                    search: function() {
-                     	if(!_.isUndefined(this.value) && this.value.includes('||')) {
-                     		var values = this.value.trim().split('||');
-                     		if (values.length > 1) {
-                                for (var i = 0; i < values.length; i++) {
-                                    that.fields[that.pathFieldName].editor.$el.find('[data-js="resource"]').tagit("createTag", values[i]);
-                                }
-                                return ''
-                            } else {
-                                return val
-                            }
-                     	}
-                    }
-                }
-            }
-            tagitOpts['beforeTagAdded'] = function(event, ui) {
-                // do something special
-                that.fields[that.pathFieldName].$el.removeClass('error');
-                that.fields[that.pathFieldName].$el.find('.help-inline').html('');
-                var tags =  [];
-                if(!_.isUndefined(options.regExpValidation) && !options.regExpValidation.regexp.test(ui.tagLabel)){
-                    that.fields[that.pathFieldName].$el.addClass('error');
-                    that.fields[that.pathFieldName].$el.find('.help-inline').html(options.regExpValidation.message);
-                    return false;
-                }
-            }
-            tagitOpts['singleFieldDelimiter'] = '||';
-            tagitOpts['singleField'] = false;
-            this.fields[that.pathFieldName].editor.$el.find('input[data-js="resource"]').tagit(tagitOpts).on('change', function(e){
-                //check dirty field for tagit input type : `path`
-                XAUtil.checkDirtyField($(e.currentTarget).val(), defaultValue.toString(), $(e.currentTarget));
-            });
-		},
-		getPlugginAttr :function(autocomplete, options){
-			var that =this, type = options.containerCssClass, validRegExpString = true, select2Opts=[];
-			if(!autocomplete)
-				return{tags : true,width :'220px',multiple: true,minimumInputLength: 1, 'containerCssClass' : type};
-			else {
-				select2Opts = {
-					containerCssClass : options.type,
-					closeOnSelect : true,
-					tags:true,
-					multiple: true,
-					width :'220px',
-					tokenSeparators: [' '],
-					initSelection : function (element, callback) {
-						var data = [];
-						//to set single select value
-						if(_.isArray(JSON.parse(element.val()))) {
-							$(JSON.parse(element.val())).each(function () {
-								data.push({id: this, text: this});
-							})
-						}
-						callback(data);
-					},
-					createSearchChoice: function(term, data) {
-						term = _.escape(term);					
-						if ($(data).filter(function() {
-							return this.text.localeCompare(term) === 0;
-						}).length === 0) {
-							if(!_.isUndefined(options.regExpValidation) && !options.regExpValidation.regexp.test(term)){
-									validRegExpString = false; 
-							}else if($.inArray(term, this.val()) >= 0){
-								return null;
-							}else{
-								return {
-									id : "<b><i class='text-muted-select2'>Create</i></b> " + term,
-									text: term,
-								};
-							}
-						}
-					},
-					ajax: {
-						url: options.lookupURL,
-						type : 'POST',
-						params : {
-							timeout: 10000,
-							contentType: "application/json; charset=utf-8",
-						},
-						cache: false,
-						data: function (term, page) {
-							return that.getDataParams(term, options);
-						},
-						results: function (data, page) { 
-							var results = [];
-							if(!_.isUndefined(data)){
-								if(_.isArray(data) && data.length > 0){
-									results = data.map(function(m, i){	return {id : m, text: m};	});
-								}
-								if(!_.isUndefined(data.resultSize) &&  data.resultSize != "0"){
-									results = data.vXStrings.map(function(m, i){	return {id : m.value, text: m.value};	});
-								}
-							}
-							return { 
-								results : results
-							};
-						},
-						transport: function (options) {
-							$.ajax(options).fail(function(response) {
-								if (response && response.responseJSON && response.responseJSON.msgDesc) {
-									XAUtil.notifyError('Error', response.responseJSON.msgDesc);
-								} else {
-									XAUtil.notifyError('Error', localization.tt('msg.resourcesLookup'));
-								}
-								this.success({
-									resultSize : 0
-								});
-							});
-						}
-
-					},	
-					formatResult : function(result){
-						return result.id;
-					},
-					formatSelection : function(result){
-						return result.text;
-					},
-					formatNoMatches : function(term){
-						if(!validRegExpString && !_.isUndefined(options.regExpValidation)){
-							return options.regExpValidation.message;
-						}
-						return "No Matches found";
-					}
-				};	
-				//To support single value input
-				if(!_.isUndefined(options.singleValueInput) && options.singleValueInput){
-					select2Opts['maximumSelectionSize'] = 1;
-				}
-				return select2Opts;
-			}
-		},
-		getDataParams : function(term, options) {
-			var resources = {},resourceName = options.type, dataResources = {};
-			var isParent = true, name = options.type, val = null,isCurrentSameLevelField = true;
-			while(isParent){
-				var currentResource = _.findWhere(this.getResources(), {'name': name });
-				//same level type
-				if(_.isUndefined(this.fields[currentResource.name])){
-                                        if(!_.isUndefined(currentResource.parent)){
-                                                var sameLevelName = 'sameLevel'+currentResource.level + currentResource.parent;
-                                        }else{
-                                                var sameLevelName = 'sameLevel'+currentResource.level;
-                                        }
-
-					name = this.fields[sameLevelName].editor.$resourceType.val()
-					val = this.fields[sameLevelName].getValue();
-					if(isCurrentSameLevelField){
-						resourceName = name;
-					}
-				}else{
-					val = this.fields[name].getValue();
-				}
-				resources[name] = _.isNull(val) ? [] : val.resource;
-				if(!_.isEmpty(currentResource.parent)){
-					name = currentResource.parent;
-				}else{
-					isParent = false;
-				}
-				isCurrentSameLevelField = false;
-			}
-			if(resources && !_.isEmpty(resources)) {
-				_.each(resources, function(val, key) {
-					dataResources[key] = _.map(val, function(obj){
-						return obj.text
-					})
-				})
-			}
-			var context ={
-					'userInput' : term,
-					'resourceName' : resourceName,
-					'resources' : dataResources
-				};
-			return JSON.stringify(context);
-		},
 		formValidation : function(coll){
                         var groupSet = false , permSet = false , groupPermSet = false , delegateAdmin = false ,
                         userSet=false, userPerm = false, userPermSet =false,breakFlag =false, condSet = false,customMaskSet = true,
@@ -987,6 +617,23 @@
 			}
 			return this.rangerServiceDefModel.get('resources');
 		},
+		renderPolicyResource : function (){
+			this.policyResourceForm = new ResourceList({
+				collection : this.formInputResourceList,
+				rangerPolicyModel: this.model,
+				rangerServiceDefModel : this.rangerServiceDefModel,
+				rangerService: this.rangerService,
+			}).render();
+			this.$('[data-customfields="policyResources"]').html(this.policyResourceForm.el);
+		},
+		validatePolicyResource : function (){
+			var errors = null;
+			_.some(this.formInputResourceList.models, function(model) {
+				errors = model.get('resourceForm').commit({validate : false});
+				return ! _.isEmpty(errors);
+			});
+			return errors;
+		}
 	});
 	return RangerPolicyForm;
 });
diff --git a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
index ba94e6f..89d35fd 100644
--- a/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
+++ b/security-admin/src/main/webapp/scripts/views/policies/RangerPolicyRO.js
@@ -134,21 +134,29 @@
                     resourceDef = this.serviceDef.get('rowFilterDef').resources;
                 }
             }
-            _.each(resourceDef, function(def, i){
-				if(!_.isUndefined(this.policy.get('resources')[def.name])){
-					var resource = {},
-						policyResources = this.policy.get('resources')[def.name];
-					resource.label = def.label;
-					resource.values = policyResources.values;
-					if(def.recursiveSupported){
-						resource.Rec_Recursive = policyResources.isRecursive ? XAEnums.RecursiveStatus.STATUS_RECURSIVE.label : XAEnums.RecursiveStatus.STATUS_NONRECURSIVE.label;
+			var resources = this.policy.get('resources');
+			if(this.policy.has('additionalResources')){
+				resources = _.union([resources], this.policy.get('additionalResources'));
+			}
+			_.each(resources, function (resourceObj) {
+				var detailResource = [];
+				_.each(resourceDef, function(def, i){
+					if(!_.isUndefined(resourceObj[def.name])){
+						var resource = {}, policyResources = resourceObj[def.name];
+						resource.label = def.label;
+						resource.values = policyResources.values;
+						if(def.recursiveSupported){
+							resource.Rec_Recursive = policyResources.isRecursive ? XAEnums.RecursiveStatus.STATUS_RECURSIVE.label : XAEnums.RecursiveStatus.STATUS_NONRECURSIVE.label;
+						}
+						if(def.excludesSupported){
+							resource.Rec_Exc = policyResources.isExcludes ? XAEnums.ExcludeStatus.STATUS_EXCLUDE.label : XAEnums.ExcludeStatus.STATUS_INCLUDE.label;
+						}
+						detailResource.push(resource);
 					}
-					if(def.excludesSupported){
-						resource.Rec_Exc = policyResources.isExcludes ? XAEnums.ExcludeStatus.STATUS_EXCLUDE.label : XAEnums.ExcludeStatus.STATUS_INCLUDE.label;
-					}
-					details.resources.push(resource);
-				}
-			}, this);
+				}, this);
+				details.resources.push(detailResource);
+			})
+
             details.policyLabels = this.policy.get('policyLabels');
             details.zoneName = this.policy.get('zoneName');
 			var perm = details.permissions = this.getPermHeaders();
diff --git a/security-admin/src/main/webapp/scripts/views/policies/ResourceList.js b/security-admin/src/main/webapp/scripts/views/policies/ResourceList.js
new file mode 100644
index 0000000..aa604a7
--- /dev/null
+++ b/security-admin/src/main/webapp/scripts/views/policies/ResourceList.js
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+ /*
+ *
+ */
+define(function(require) {
+    'use strict';
+    
+	var Backbone		= require('backbone');
+	var Vent = require('modules/Vent');
+	var XAUtils		= require('utils/XAUtils');
+
+	var ZoneResourceForm = require('views/security_zone/ZoneResourceForm');
+
+	var ResourceItem = Backbone.Marionette.ItemView.extend({
+		_msvName : 'ResourceItem',
+		template : require('hbs!tmpl/policies/ResourceItem_tmpl'),
+		ui : {
+			'deleteBtn' : '[data-action="delete"]'
+		},
+		events : {
+			'click [data-action="delete"]'	: 'evDelete',
+
+		},
+
+		initialize : function(options) {
+			_.extend(this, _.pick(options,'rangerPolicyModel', 'rangerServiceDefModel','rangerService','storeResourceRef'));
+		},
+ 
+		onRender : function() {
+			this.renderPolicyResource();
+			if(this.model.collection.length === 1){
+				this.ui.deleteBtn.hide();
+			}else{
+				this.ui.deleteBtn.show();
+			}
+
+			
+		},
+		renderPolicyResource : function (){
+			this.resourceForm = new ZoneResourceForm({
+				model: this.model,
+				rangerServiceDefModel: this.rangerServiceDefModel,
+				rangerService: this.rangerService,
+				isPolicyResource: true
+			});
+			this.resourceForm.render();
+			this.$('[data-customfields="resource-item"]').html(this.resourceForm.el);
+			this.model.attributes.resourceForm = this.resourceForm;
+			var resourceItemIndex = this.model && this.model.collection.indexOf(this.model);
+			var resourceName = this.getLastResourceName()
+			Vent.trigger('resourceType:change', { changeType : 'resourceType', value : resourceName, resourceName : resourceName, resourceItemIndex : resourceItemIndex, action : 'added' });
+
+		},
+		evDelete : function(){
+			var resourceItemIndex = this.model && this.model.collection.indexOf(this.model);
+			Vent.trigger('resourceType:change', { resourceItemIndex : resourceItemIndex, action : 'removed' });
+			this.collection.remove(this.model);
+		},
+		getResourceName : function (resource, resourceDef){
+			var found = _.findWhere(resourceDef,{'parent': resource.name });
+			if(found){
+				return this.getResourceName(found, resourceDef);
+			}else {
+				return resource.name;
+			}
+		},
+		getLastResourceName : function (){
+			var resourceDef = XAUtils.policyTypeResources(this.rangerServiceDefModel, this.model.get('policyType'));
+			return this.getResourceName(resourceDef[0], resourceDef);
+		}
+
+	});
+
+	return Backbone.Marionette.CompositeView.extend({
+		_msvName : 'PermissionItemList',
+		template : require('hbs!tmpl/policies/ResourceList_tmpl'),
+		templateHelpers: function() {
+			return { resourceCnt : this.collection.length };
+		},
+		getItemView : function(item){
+			if(!item){
+				return;
+			}
+			return ResourceItem;
+		},
+		itemViewContainer : ".js-formInput",
+		itemViewOptions : function() {
+			return {
+				'collection' 	: this.collection,
+				'rangerPolicyModel' : this.rangerPolicyModel,
+				'rangerServiceDefModel' : this.rangerServiceDefModel,
+                'rangerService' : this.rangerService,
+			};
+		},
+		ui : {
+			'showAllResourceChbox' : '[data-js="showAllResourceChbox"]',
+		},
+		events : {
+			'click [data-action="addGroup"]' : 'addNew',
+			'click [data-js="showAllResourceChbox"]' : 'onShowAllResource'
+		},
+		collectionEvents: {
+			'add': 'onAdd',
+			'remove': 'onRemove'
+		},
+		initialize : function(options) {
+			_.extend(this, _.pick(options, 'rangerPolicyModel', 'rangerServiceDefModel','rangerService'));
+			if(this.collection.length == 0){
+				this.collection.add(new Backbone.Model({ policyType: this.rangerPolicyModel.get('policyType') }))
+			}
+			this.storeResourceRef = {};
+			this.hideFirstResource = false;
+		},
+		onRender : function(){
+			if(this.hideFirstResource){
+				this.$el.find('.additional-resource:not(:first)').hide();
+				this.hideFirstResource = false;
+			}
+
+		},
+
+		addNew : function(){
+			if (!this.ui.showAllResourceChbox.prop("checked")) {
+				this.ui.showAllResourceChbox.trigger('click');
+			}
+			this.collection.add(new Backbone.Model({ policyType: this.rangerPolicyModel.get('policyType') }));
+		},
+		onShowAllResource : function(){
+
+			if (this.ui.showAllResourceChbox.prop("checked")) {
+				this.$el.find('.additional-resource').show();
+			}else {
+				this.$el.find('.additional-resource:not(:first)').hide()
+			}
+		},
+		onAdd : function (){
+			this.$el.find('[data-js="resource-count"]').html(this.collection.length);
+			this.toggleDeleteBtn();
+		},
+		onRemove : function (){
+			this.onAdd();
+			this.toggleDeleteBtn();
+		},
+		toggleDeleteBtn : function (){
+			if(this.collection.length === 1){
+				this.$el.find('.additional-resource .btn-danger').hide();
+			}else {
+				this.$el.find('.additional-resource .btn-danger').show();
+			}
+		}
+	});
+
+});
diff --git a/security-admin/src/main/webapp/scripts/views/security_zone/ZoneResourceForm.js b/security-admin/src/main/webapp/scripts/views/security_zone/ZoneResourceForm.js
index 900d9da..33b01df 100644
--- a/security-admin/src/main/webapp/scripts/views/security_zone/ZoneResourceForm.js
+++ b/security-admin/src/main/webapp/scripts/views/security_zone/ZoneResourceForm.js
@@ -42,18 +42,17 @@
              * @constructs
              */
 
-            templateData: function() {
-                var policyType = XAUtil.enumElementByValue(XAEnums.RangerPolicyType, this.model.get('policyType'));
+            template: require('hbs!tmpl/security_zone/ZoneResourcesForm_tmpl'),
+            templateData : function(){
                 return {
-                    'id': this.model.id,
-                    'policyType': policyType.label,
-                    'policyTimeBtnLabel': (this.model.has('validitySchedules') && this.model.get('validitySchedules').length > 0) ? localization.tt('lbl.editValidityPeriod') : localization.tt('lbl.addValidityPeriod')
-                };
+                    isPolicyResource : this.isPolicyResource
+                }
             },
 
             initialize: function(options) {
                 console.log("initialized a RangerZoneResourceForm Form View");
-                _.extend(this, _.pick(options, 'rangerServiceDefModel', 'rangerService'));
+                _.extend(this, _.pick(options, 'rangerServiceDefModel', 'rangerService', 'isPolicyResource'));
+                this.isPolicyResource = this.isPolicyResource ? this.isPolicyResource : false;
                 this.setupForm();
                 Backbone.Form.prototype.initialize.call(this, options);
                 this.bindEvents();
@@ -79,11 +78,14 @@
                 var attrs = {},
                     that = this;
                 var formDataType = new BackboneFormDataType();
-                _.each(this.rangerServiceDefModel.get('resources'), function(m) {
-                    if (_.has(m, 'parent')) {
-                        m.mandatory = false;
-                    }
-                })
+                if(!this.isPolicyResource){
+                    _.each(this.rangerServiceDefModel.get('resources'), function(m) {
+                        if (_.has(m, 'parent')) {
+                            m.mandatory = false;
+                        }
+                    })
+                }
+
                 attrs = formDataType.getFormElements(this.rangerServiceDefModel.get('resources'), this.rangerServiceDefModel.get('enums'), attrs, this, true);
                 return attrs;
             },
@@ -150,7 +152,7 @@
 
             /** all custom field rendering */
             renderParentChildHideShow: function(onChangeOfSameLevelType, val, e) {
-                var formDiv = this.$el.find('.zoneResources-form');
+                var formDiv = this.$el.find('.form-resources');
                 if (!this.model.isNew() && !onChangeOfSameLevelType) {
                     _.each(this.selectedResourceTypes, function(val, sameLevelName) {
                         if (formDiv.find('.field-' + sameLevelName).length > 0) {
@@ -342,8 +344,8 @@
                             //to set single select value
                             if (!_.isUndefined(options.singleValueInput) && options.singleValueInput) {
                                 callback({
-                                    id: element.val(),
-                                    text: element.val()
+                                    id: JSON.parse(element.val())[0],
+                                    text: JSON.parse(element.val())[0]
                                 });
                                 return;
                             }
diff --git a/security-admin/src/main/webapp/scripts/views/service/ServiceAuditFilterResources.js b/security-admin/src/main/webapp/scripts/views/service/ServiceAuditFilterResources.js
index 683fa4b..7340236 100644
--- a/security-admin/src/main/webapp/scripts/views/service/ServiceAuditFilterResources.js
+++ b/security-admin/src/main/webapp/scripts/views/service/ServiceAuditFilterResources.js
@@ -144,7 +144,7 @@
 
             /** all custom field rendering */
             renderParentChildHideShow: function(onChangeOfSameLevelType, val, e) {
-                var formDiv = this.$el.find('.zoneResources-form');
+                var formDiv = this.$el.find('.form-resources');
                 if (!this.model.isNew() && !onChangeOfSameLevelType) {
                     _.each(this.selectedResourceTypes, function(val, sameLevelName) {
                         if (formDiv.find('.field-' + sameLevelName).length > 0) {
diff --git a/security-admin/src/main/webapp/styles/xa.css b/security-admin/src/main/webapp/styles/xa.css
index 2da2f29..52f9128 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -1782,7 +1782,7 @@
 }
 .include-toggle{
 	margin-left: 360px;
-	margin-top: -29px;
+	margin-top: -35px;
 	width:80px;
   position: relative;
   top: 7px;
@@ -2248,7 +2248,7 @@
 }
 .include-toggle-1{
   margin-left: 23vw;
-  margin-top: -29px;
+  margin-top: -4px;
 }
 .expanded-contant .include-toggle-1{
   margin-left: 18.4vw;
@@ -4093,7 +4093,7 @@
 */
 .ranger-policy .form-group.field-isEnabled .policy-enable-disable{
     margin-left: 38vw;
-    margin-top: -75px;
+    margin-top: -69px;
     width: 100px
 }
 
@@ -4103,7 +4103,7 @@
 
 .ranger-policy .form-group.field-policyPriority .policy-priority{
     margin-left: 45vw;
-    margin-top: -80px;
+    margin-top: -73px;
     width: 100px
 }
 .expanded-contant .form-group.field-policyPriority .policy-priority {
@@ -4428,10 +4428,6 @@
   top: -30px;
 }
 
-.form-group.field-policyLabels {
-    margin-bottom: 40px;
-}
-
 .ranger-policy .form-group.field-isEnabled > label,
 .ranger-policy .form-group.field-policyPriority > label {
   display: none;
@@ -4717,4 +4713,24 @@
   background: #eeeeee;
   width: 100%;
   display: inline-block;
+}
+
+.js-formInput .policy-resources .select2-container {
+  width: 274px !important;
+}
+.form-resources.policy-resources .form-control.rosource-boder {
+  padding: 0px !important;
+}
+.form-resources.policy-resources .sameLevelDropdown {
+  margin-right: 31px !important;
+  margin-left: -150px !important;
+}
+.show-all-resource {
+  margin-top: -50px;
+}
+.policy-resources .form-group[fieldclass="resorces-css"] {
+  margin-bottom: 0px !important;
+}
+.wrap.position-relative.additional-resource{
+  padding: 20px 20px 0px 20px !important;
 }
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
index e466f62..accef88 100644
--- a/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
+++ b/security-admin/src/main/webapp/templates/helpers/XAHelpers.js
@@ -619,6 +619,9 @@
             }
             return '<div class="margin-bottom-5 display-block"><label><span>'+obj.label+' : </span></label><input type="input" data-id="inputField" name="'+obj.name+'" ></div>'
     });
+ 	Handlebars.registerHelper("inc", function(value, options) {
+		 return parseInt(value) + 1;
+ 	});
 
 	return HHelpers;
 });
diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
index e314e83..864a399 100644
--- a/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
+++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyForm_tmpl.html
@@ -64,6 +64,15 @@
 		</div>
 	</fieldset>
 	<fieldset>
+		<p class="wrap-header bold formHeader">
+			Resources : <span class="badge badge-yellow pull-right"></span>
+		</p>
+		&nbsp;
+		<div>
+			<div data-customfields="policyResources" />
+		</div>
+	</fieldset>
+	<fieldset>
 			<p class="wrap-header bold formHeader">
 				{{conditionType}} Conditions: <span class="badge badge-yellow pull-right"></span>
 			</p>
diff --git a/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
index 1edfe24..d4bcdbe 100644
--- a/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
+++ b/security-admin/src/main/webapp/templates/policies/RangerPolicyRO_tmpl.html
@@ -83,20 +83,6 @@
                         {{/ifCond}}
                     </td>
                 </tr>
-                {{#each PolicyDetails.resources}}
-                    <tr>
-                        <td>
-                            {{this.label}}
-                        </td>
-                        <td>
-                            {{#each this.values}}
-                                <span class="badge badge-info">{{this}}</span>
-                            {{/each}}
-                            <span class="badge badge-dark pull-right m-l-sm">{{this.Rec_Recursive}}</span>
-                            <span class="badge badge-dark pull-right">{{this.Rec_Exc}}</span>
-                        </td>
-                    </tr>
-                {{/each}}
                 <tr>
                     <td>
                         {{tt 'lbl.description'}}
@@ -135,6 +121,34 @@
         </table>
     </div>
 </div>
+<div class="">
+    <p class="formHeader">Policy Resource :</p>
+        {{#each PolicyDetails.resources}}
+            <div class="table-responsive">
+                <table class="table table-bordered table-condensed backgrid">
+                    <thead><th colspan="2" class="text-left">#{{inc @index}}</th></thead>
+                    <tbody>
+                    {{#each this}}
+                        <tr>
+                            <td>
+                                {{this.label}}
+                            </td>
+                            <td>
+                                {{#each this.values}}
+                                <span class="badge badge-info">{{this}}</span>
+                                {{/each}}
+                                <span class="badge badge-dark pull-right m-l-sm">{{this.Rec_Recursive}}</span>
+                                <span class="badge badge-dark pull-right">{{this.Rec_Exc}}</span>
+                            </td>
+                        </tr>
+                    {{/each}}
+                    </tbody>
+                </table>
+            </div>
+            <br/>
+        {{/each}}
+
+</div>
 {{#if PolicyDetails.validitySchedules}}
     <div id="policyItems" class="">
         <p class="formHeader">Validity Period :<i class="fa-fw fa fa-time fa-fw fa fa-large pull-right"></i></p>
diff --git a/security-admin/src/main/webapp/templates/policies/ResourceItem_tmpl.html b/security-admin/src/main/webapp/templates/policies/ResourceItem_tmpl.html
new file mode 100644
index 0000000..1c270e6
--- /dev/null
+++ b/security-admin/src/main/webapp/templates/policies/ResourceItem_tmpl.html
@@ -0,0 +1,26 @@
+{{!-- 
+  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.
+--}}
+<div class="wrap position-relative additional-resource">
+
+    <div class="pull-right">
+        <button type="button" class="btn btn-sm btn-danger " data-action="delete">
+            <i class="fa-fw fa fa-remove"></i>
+        </button>
+    </div>
+
+    <div data-customfields="resource-item"></div>
+</div>
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/templates/policies/ResourceList_tmpl.html b/security-admin/src/main/webapp/templates/policies/ResourceList_tmpl.html
new file mode 100644
index 0000000..931c450
--- /dev/null
+++ b/security-admin/src/main/webapp/templates/policies/ResourceList_tmpl.html
@@ -0,0 +1,37 @@
+{{!-- 
+  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.
+--}}
+<!--div class="col-md-12">
+    <div class="pull-right show-all-resource">
+        <input id="one" type="checkbox" data-js="showAllResourceChbox" style="vertical-align: middle;"/>
+        <label for="one">
+            <i class="icon" aria-hidden="true"></i> <b>Show All (<span data-js="resource-count">{{resourceCnt}}</span>)</b>
+        </label>
+    </div>
+</div-->
+<div class="form-group">
+    <div class="col-md-8 m-t-sm">
+        <div class="js-formInput">
+        </div>
+    </div>
+</div>
+<div class="form-group">
+    <div class="col-md-8 m-t-sm">
+        <button type="button" class="btn btn-primary btn-sm" data-action="addGroup" title="Add">
+            <i class="fa-fw fa fa-plus"></i> Add Resource
+        </button>
+    </div>
+</div>
\ No newline at end of file
diff --git a/security-admin/src/main/webapp/templates/security_zone/ZoneResourcesForm_tmpl.html b/security-admin/src/main/webapp/templates/security_zone/ZoneResourcesForm_tmpl.html
index d3ed5ab..9212e2e 100644
--- a/security-admin/src/main/webapp/templates/security_zone/ZoneResourcesForm_tmpl.html
+++ b/security-admin/src/main/webapp/templates/security_zone/ZoneResourcesForm_tmpl.html
@@ -12,6 +12,10 @@
 language governing permissions and limitations under the License. --}}
 <form class="form-horizontal">
     <fieldset>
-        <b data-fieldsets class="zoneResources-form"></b>
+        {{#if isPolicyResource}}
+        <div data-fieldsets class="form-resources policy-resources"></div>
+        {{else}}
+        <div data-fieldsets class="form-resources zoneResources-form"></div>
+        {{/if}}
     </fieldset>
 </form>
\ No newline at end of file