View Javadoc
1   package net.avcompris.commons3.core;
2   
3   import static com.google.common.base.Preconditions.checkArgument;
4   import static com.google.common.base.Preconditions.checkNotNull;
5   
6   import java.lang.reflect.Array;
7   import java.lang.reflect.InvocationTargetException;
8   import java.lang.reflect.Method;
9   import java.util.HashMap;
10  import java.util.Map;
11  
12  import com.google.common.collect.HashBasedTable;
13  import com.google.common.collect.Table;
14  
15  import net.avcompris.commons3.api.EnumPermission;
16  import net.avcompris.commons3.api.EnumRole;
17  import net.avcompris.commons3.api.User;
18  
19  public abstract class PermissionUtils<T extends EnumRole> {
20  
21  	private static final Table<EnumRole, EnumPermission, Boolean> CACHED_PERMISSION_TYPES = HashBasedTable.create();
22  
23  	private final Class<T> roleClass;
24  
25  	private final Map<String, EnumRole> roles = new HashMap<>();
26  
27  	public PermissionUtils(final Class<T> roleClass) {
28  
29  		this.roleClass = checkNotNull(roleClass, "roleClass");
30  
31  		checkArgument(roleClass.isEnum(), //
32  				"roleClass should be enum, but was: %s", roleClass.getName());
33  
34  		final Method valuesMethod;
35  
36  		try {
37  
38  			valuesMethod = roleClass.getMethod("values");
39  
40  		} catch (final NoSuchMethodException e) {
41  			throw new IllegalStateException(e);
42  		}
43  
44  		final Object values;
45  
46  		try {
47  
48  			values = valuesMethod.invoke(null);
49  
50  		} catch (final IllegalAccessException | InvocationTargetException e) {
51  			throw new IllegalStateException(e);
52  		}
53  
54  		final int count = Array.getLength(values);
55  
56  		for (int i = 0; i < count; ++i) {
57  
58  			final Object item = Array.get(values, i);
59  
60  			final EnumRole role = roleClass.cast(item);
61  
62  			roles.put(role.getRolename(), role);
63  		}
64  	}
65  
66  	public static boolean has(final User user, final EnumPermission permission) {
67  
68  		checkNotNull(user, "user");
69  
70  		return has(user.getRole(), permission);
71  	}
72  
73  	public EnumRole getRole(final String rolename) {
74  
75  		checkNotNull(rolename, "rolename");
76  
77  		final EnumRole role = roles.get(rolename);
78  
79  		checkArgument(role != null, //
80  				"Unknown role: %s, in class: %s", rolename, roleClass.getName());
81  
82  		return role;
83  	}
84  
85  	public static boolean has(final EnumRole role, final EnumPermission permission) {
86  
87  		checkNotNull(role, "role");
88  		checkNotNull(permission, "permission");
89  
90  		final Boolean cached = CACHED_PERMISSION_TYPES.get(role, permission);
91  
92  		if (cached != null) {
93  
94  			return cached;
95  		}
96  
97  		final boolean checked = check(role, permission);
98  
99  		CACHED_PERMISSION_TYPES.put(role, permission, checked);
100 
101 		return checked;
102 	}
103 
104 	private static boolean check(final EnumRole role, final EnumPermission permission) {
105 
106 		for (final EnumRole superRole : role.getSuperRoles()) {
107 
108 			if (has(superRole, permission)) {
109 
110 				return true;
111 			}
112 		}
113 
114 		for (final EnumPermission p : role.getPermissions()) {
115 
116 			if (p == permission) {
117 
118 				return true;
119 			}
120 		}
121 
122 		return false;
123 	}
124 
125 	public static void assertPermissionTypeClass(final Class<? extends EnumPermission> permissionTypeClass) {
126 
127 		checkNotNull(permissionTypeClass, "permissionTypeClass");
128 
129 		checkArgument(permissionTypeClass.isEnum(), //
130 				"permissionTypeClass should be Enum, but was: %s", permissionTypeClass.getName());
131 	}
132 }