<commit_before>/**
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright 2015 Chiori-chan. All Right Reserved.
 * 
 * @author <NAME>
 * @email <EMAIL>
 */
package com.chiorichan.permission;

import com.chiorichan.permission.structure.ChildPermission;
import com.chiorichan.permission.structure.Permission;
import com.chiorichan.permission.structure.PermissionValue;
import com.chiorichan.util.ObjectUtil;

/**
 * Is returned when Permissible#getPermission() is called
 * and symbolizes the unity of said permission and entity.
 */
public class PermissionResult
{
	public static final PermissionResult DUMMY = new PermissionResult();
	
	private PermissibleEntity entity = null;
	private Permission perm = null;
	private ChildPermission childPerm = null;
	
	public PermissionResult()
	{
		
	}
	
	public PermissionResult( PermissibleEntity entity, Permission perm )
	{
		this.entity = entity;
		this.perm = perm;
		
		childPerm = recursiveEntityScan( entity, perm );
	}
	
	private ChildPermission recursiveEntityScan( PermissibleEntity pe, Permission perm )
	{
		if ( pe.childPermissions.containsKey( perm.getNamespace() ) )
			return pe.childPermissions.get( perm.getNamespace() );
		
		for ( PermissibleGroup group : pe.groups.values() )
		{
			ChildPermission childPerm = recursiveEntityScan( group, perm );
			if ( childPerm != null )
				return childPerm;
		}
		
		return null;
	}
	
	/**
	 * @return was this permission assigned to our entity?
	 */
	public boolean isAssigned()
	{
		return childPerm != null;
	}
	
	/**
	 * @return was this permission assigned to our entity thru a group? Will return false if not assigned.
	 */
	public boolean isInherited()
	{
		if ( !isAssigned() )
			return false;
		
		return childPerm.isInherited;
	}
	
	/**<commit_msg>Implemented a method to prevent infinite looping in the recursiveEntityScan method<commit_after>/**
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright 2015 Chiori-chan. All Right Reserved.
 * 
 * @author <NAME>
 * @email <EMAIL>
 */
package com.chiorichan.permission;

import java.util.List;

import com.chiorichan.permission.structure.ChildPermission;
import com.chiorichan.permission.structure.Permission;
import com.chiorichan.permission.structure.PermissionValue;
import com.chiorichan.util.ObjectUtil;
import com.google.common.collect.Lists;

/**
 * Is returned when Permissible#getPermission() is called
 * and symbolizes the unity of said permission and entity.
 */
public class PermissionResult
{
	public static final PermissionResult DUMMY = new PermissionResult();
	
	private PermissibleEntity entity = null;
	private Permission perm = null;
	private String ref = "";
	private ChildPermission childPerm = null;
	
	public PermissionResult()
	{
		
	}
	
	public PermissionResult( PermissibleEntity entity, Permission perm, String ref )
	{
		if ( ref == null )
			ref = "";
		
		this.entity = entity;
		this.perm = perm;
		this.ref = ref;
		
		childPerm = recursiveEntityScan( entity );
	}
	
	/**
	 * Used as a constant tracker for already checked groups, prevents infinite looping.
	 * e.g., User -> Group1 -> Group2 -> Group3 -> Group1
	 */
	private List<PermissibleGroup> groupStackTrace = null;
	
	private ChildPermission recursiveEntityScan( PermissibleEntity pe )
	{
		if ( pe.childPermissions.containsKey( perm.getNamespace() ) )
			return pe.childPermissions.get( perm.getNamespace() );
		
		boolean isFirst = false;
		ChildPermission result = null;
		
		if ( groupStackTrace == null )
		{
			groupStackTrace = Lists.newArrayList();
			isFirst = true;
		}
		
		for ( PermissibleGroup group : pe.groups.values() )
		{
			if ( !groupStackTrace.contains( group ) )
			{
				ChildPermission childPerm = recursiveEntityScan( group );
				if ( childPerm != null )
				{
					result = childPerm;
					break;
				}
			}
		}
		
		if ( isFirst )
			groupStackTrace = null;
		
		return result;
	}
	
	public String getReference()
	{
		return ref;
	}
	
	/**
	 * @return was this permission assigned to our entity?
	 */
	public boolean isAssigned()
	{
		return childPerm != null;
	}
	
	/**
	 * @return was this permission assigned to our entity thru a group? Will return false if not assigned.
	 */
	public boolean isInherited()
	{
		if ( !isAssigned() )
			return false;
		
		return childPerm.isInherited;
	}
	
	/**
{'fraction_non_alphanumeric': 0.09760869565217391, 'fraction_numerical': 0.004347826086956522, 'mean_word_length': 3.578109452736318, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3955459', 'n_tokens_mistral': 1526, 'n_tokens_neox': 1322, 'n_words': 423}