PageRenderTime 113ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/ru/tehkode/permissions/PermissionEntity.java

https://gitlab.com/Slind/PermissionsEx
Java | 539 lines | 222 code | 80 blank | 237 comment | 34 complexity | 6a839bd95b41014a13f79d98ddadab0c MD5 | raw file
  1. /*
  2. * PermissionsEx - Permissions plugin for Bukkit
  3. * Copyright (C) 2011 t3hk0d3 http://www.tehkode.ru
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. package ru.tehkode.permissions;
  20. import java.util.LinkedList;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.TimerTask;
  24. import java.util.concurrent.ConcurrentHashMap;
  25. import java.util.logging.Logger;
  26. import org.bukkit.Bukkit;
  27. import ru.tehkode.permissions.events.PermissionEntityEvent;
  28. /**
  29. * @author code
  30. */
  31. public abstract class PermissionEntity {
  32. protected PermissionManager manager;
  33. private String name;
  34. protected boolean virtual = true;
  35. protected Map<String, List<String>> timedPermissions = new ConcurrentHashMap<String, List<String>>();
  36. protected Map<String, Long> timedPermissionsTime = new ConcurrentHashMap<String, Long>();
  37. protected boolean debugMode = false;
  38. public PermissionEntity(String name, PermissionManager manager) {
  39. this.manager = manager;
  40. this.name = name;
  41. }
  42. /**
  43. * This method 100% run after all constructors have been run and entity
  44. * object, and entity object are completely ready to operate
  45. */
  46. public void initialize() {
  47. this.debugMode = this.getOptionBoolean("debug", null, this.debugMode);
  48. }
  49. /**
  50. * Return name of permission entity (User or Group)
  51. * User should be equal to Player's name on the server
  52. *
  53. * @return name
  54. */
  55. public String getName() {
  56. return this.name;
  57. }
  58. protected void setName(String name) {
  59. this.name = name;
  60. }
  61. /**
  62. * Returns entity prefix
  63. *
  64. * @param worldName
  65. * @return prefix
  66. */
  67. public abstract String getPrefix(String worldName);
  68. public String getPrefix() {
  69. return this.getPrefix(null);
  70. }
  71. /**
  72. * Returns entity prefix
  73. *
  74. */
  75. /**
  76. * Set prefix to value
  77. *
  78. * @param prefix new prefix
  79. */
  80. public abstract void setPrefix(String prefix, String worldName);
  81. /**
  82. * Return entity suffix
  83. *
  84. * @return suffix
  85. */
  86. public abstract String getSuffix(String worldName);
  87. public String getSuffix() {
  88. return getSuffix(null);
  89. }
  90. /**
  91. * Set suffix to value
  92. *
  93. * @param suffix new suffix
  94. */
  95. public abstract void setSuffix(String suffix, String worldName);
  96. /**
  97. * Checks if entity has specified permission in default world
  98. *
  99. * @param permission Permission to check
  100. * @return true if entity has this permission otherwise false
  101. */
  102. public boolean has(String permission) {
  103. return this.has(permission, Bukkit.getServer().getWorlds().get(0).getName());
  104. }
  105. /**
  106. * Check if entity has specified permission in world
  107. *
  108. * @param permission Permission to check
  109. * @param world World to check permission in
  110. * @return true if entity has this permission otherwise false
  111. */
  112. public boolean has(String permission, String world) {
  113. if (permission != null && permission.isEmpty()) { // empty permission for public access :)
  114. return true;
  115. }
  116. String expression = getMatchingExpression(permission, world);
  117. if (this.isDebug()) {
  118. Logger.getLogger("Minecraft").info("User " + this.getName() + " checked for \"" + permission + "\", " + (expression == null ? "no permission found" : "\"" + expression + "\" found"));
  119. }
  120. return explainExpression(expression);
  121. }
  122. /**
  123. * Return all entity permissions in specified world
  124. *
  125. * @param world World name
  126. * @return Array of permission expressions
  127. */
  128. public abstract String[] getPermissions(String world);
  129. /**
  130. * Return permissions for all worlds
  131. * Common permissions stored as "" (empty string) as world.
  132. *
  133. * @return Map with world name as key and permissions array as value
  134. */
  135. public abstract Map<String, String[]> getAllPermissions();
  136. /**
  137. * Add permissions for specified world
  138. *
  139. * @param permission Permission to add
  140. * @param world World name to add permission to
  141. */
  142. public void addPermission(String permission, String world) {
  143. throw new UnsupportedOperationException("You shouldn't call this method");
  144. }
  145. /**
  146. * Add permission in common space (all worlds)
  147. *
  148. * @param permission Permission to add
  149. */
  150. public void addPermission(String permission) {
  151. this.addPermission(permission, "");
  152. }
  153. /**
  154. * Remove permission in world
  155. *
  156. * @param permission Permission to remove
  157. * @param world World name to remove permission for
  158. */
  159. public void removePermission(String permission, String worldName) {
  160. throw new UnsupportedOperationException("You shouldn't call this method");
  161. }
  162. /**
  163. * Remove specified permission from all worlds
  164. *
  165. * @param permission Permission to remove
  166. */
  167. public void removePermission(String permission) {
  168. for (String world : this.getAllPermissions().keySet()) {
  169. this.removePermission(permission, world);
  170. }
  171. }
  172. /**
  173. * Set permissions in world
  174. *
  175. * @param permissions Array of permissions to set
  176. * @param world World to set permissions for
  177. */
  178. public abstract void setPermissions(String[] permissions, String world);
  179. /**
  180. * Set specified permissions in common space (all world)
  181. *
  182. * @param permission Permission to set
  183. */
  184. public void setPermissions(String[] permission) {
  185. this.setPermissions(permission, "");
  186. }
  187. /**
  188. * Get option in world
  189. *
  190. * @param option Name of option
  191. * @param world World to look for
  192. * @param defaultValue Default value to fallback if no such option was found
  193. * @return Value of option as String
  194. */
  195. public abstract String getOption(String option, String world, String defaultValue);
  196. /**
  197. * Return option
  198. * Option would be looked up in common options
  199. *
  200. * @param option Option name
  201. * @return option value or empty string if option was not found
  202. */
  203. public String getOption(String option) {
  204. // @todo Replace empty string with null
  205. return this.getOption(option, "", "");
  206. }
  207. /**
  208. * Return option for world
  209. *
  210. * @param option Option name
  211. * @param world World to look in
  212. * @return option value or empty string if option was not found
  213. */
  214. public String getOption(String option, String world) {
  215. // @todo Replace empty string with null
  216. return this.getOption(option, world, "");
  217. }
  218. /**
  219. * Return integer value for option
  220. *
  221. * @param optionName
  222. * @param world
  223. * @param defaultValue
  224. * @return option value or defaultValue if option was not found or is not integer
  225. */
  226. public int getOptionInteger(String optionName, String world, int defaultValue) {
  227. try {
  228. return Integer.parseInt(this.getOption(optionName, world, Integer.toString(defaultValue)));
  229. } catch (NumberFormatException e) {
  230. }
  231. return defaultValue;
  232. }
  233. /**
  234. * Returns double value for option
  235. *
  236. * @param optionName
  237. * @param world
  238. * @param defaultValue
  239. * @return option value or defaultValue if option was not found or is not double
  240. */
  241. public double getOptionDouble(String optionName, String world, double defaultValue) {
  242. String option = this.getOption(optionName, world, Double.toString(defaultValue));
  243. try {
  244. return Double.parseDouble(option);
  245. } catch (NumberFormatException e) {
  246. }
  247. return defaultValue;
  248. }
  249. /**
  250. * Returns boolean value for option
  251. *
  252. * @param optionName
  253. * @param world
  254. * @param defaultValue
  255. * @return option value or defaultValue if option was not found or is not boolean
  256. */
  257. public boolean getOptionBoolean(String optionName, String world, boolean defaultValue) {
  258. String option = this.getOption(optionName, world, Boolean.toString(defaultValue));
  259. if ("false".equalsIgnoreCase(option)) {
  260. return false;
  261. } else if ("true".equalsIgnoreCase(option)) {
  262. return true;
  263. }
  264. return defaultValue;
  265. }
  266. /**
  267. * Set specified option in world
  268. *
  269. * @param option Option name
  270. * @param value Value to set, null to remove
  271. * @param world World name
  272. */
  273. public abstract void setOption(String option, String value, String world);
  274. /**
  275. * Set option for all worlds. Can be overwritten by world specific option
  276. *
  277. * @param option Option name
  278. * @param value Value to set, null to remove
  279. */
  280. public void setOption(String permission, String value) {
  281. this.setOption(permission, value, "");
  282. }
  283. /**
  284. * Get options in world
  285. *
  286. * @param world
  287. * @return Option value as string Map
  288. */
  289. public abstract Map<String, String> getOptions(String world);
  290. /**
  291. * Return options for all worlds
  292. * Common options stored as "" (empty string) as world.
  293. *
  294. * @return Map with world name as key and map of options as value
  295. */
  296. public abstract Map<String, Map<String, String>> getAllOptions();
  297. /**
  298. * Save in-memory data to storage backend
  299. */
  300. public abstract void save();
  301. /**
  302. * Remove entity data from backend
  303. */
  304. public abstract void remove();
  305. /**
  306. * Return state of entity
  307. *
  308. * @return true if entity is only in-memory
  309. */
  310. public boolean isVirtual() {
  311. return this.virtual;
  312. }
  313. /**
  314. * Return world names where entity have permissions/options/etc
  315. *
  316. * @return
  317. */
  318. public abstract String[] getWorlds();
  319. /**
  320. * Return entity timed (temporary) permission for world
  321. *
  322. * @param world
  323. * @return Array of timed permissions in that world
  324. */
  325. public String[] getTimedPermissions(String world) {
  326. if (world == null) {
  327. world = "";
  328. }
  329. if (!this.timedPermissions.containsKey(world)) {
  330. return new String[0];
  331. }
  332. return this.timedPermissions.get(world).toArray(new String[0]);
  333. }
  334. /**
  335. * Returns remaining lifetime of specified permission in world
  336. *
  337. * @param permission Name of permission
  338. * @param world
  339. * @return remaining lifetime in seconds of timed permission. 0 if permission is transient
  340. */
  341. public int getTimedPermissionLifetime(String permission, String world) {
  342. if (world == null) {
  343. world = "";
  344. }
  345. if (!this.timedPermissionsTime.containsKey(world + ":" + permission)) {
  346. return 0;
  347. }
  348. return (int) (this.timedPermissionsTime.get(world + ":" + permission).longValue() - (System.currentTimeMillis() / 1000L));
  349. }
  350. /**
  351. * Adds timed permission to specified world in seconds
  352. *
  353. * @param permission
  354. * @param world
  355. * @param lifeTime Lifetime of permission in seconds. 0 for transient permission (world disappear only after server reload)
  356. */
  357. public void addTimedPermission(final String permission, String world, int lifeTime) {
  358. if (world == null) {
  359. world = "";
  360. }
  361. if (!this.timedPermissions.containsKey(world)) {
  362. this.timedPermissions.put(world, new LinkedList<String>());
  363. }
  364. this.timedPermissions.get(world).add(permission);
  365. final String finalWorld = world;
  366. if (lifeTime > 0) {
  367. TimerTask task = new TimerTask() {
  368. @Override
  369. public void run() {
  370. removeTimedPermission(permission, finalWorld);
  371. }
  372. };
  373. this.manager.registerTask(task, lifeTime);
  374. this.timedPermissionsTime.put(world + ":" + permission, (System.currentTimeMillis() / 1000L) + lifeTime);
  375. }
  376. this.callEvent(PermissionEntityEvent.Action.PERMISSIONS_CHANGED);
  377. }
  378. /**
  379. * Removes specified timed permission for world
  380. *
  381. * @param permission
  382. * @param world
  383. */
  384. public void removeTimedPermission(String permission, String world) {
  385. if (world == null) {
  386. world = "";
  387. }
  388. if (!this.timedPermissions.containsKey(world)) {
  389. return;
  390. }
  391. this.timedPermissions.get(world).remove(permission);
  392. this.timedPermissions.remove(world + ":" + permission);
  393. this.callEvent(PermissionEntityEvent.Action.PERMISSIONS_CHANGED);
  394. }
  395. protected void callEvent(PermissionEntityEvent event) {
  396. manager.callEvent(event);
  397. }
  398. protected void callEvent(PermissionEntityEvent.Action action) {
  399. this.callEvent(new PermissionEntityEvent(this, action));
  400. }
  401. @Override
  402. public boolean equals(Object obj) {
  403. if (obj == null) {
  404. return false;
  405. }
  406. if (!getClass().equals(obj.getClass())) {
  407. return false;
  408. }
  409. if (this == obj) {
  410. return true;
  411. }
  412. final PermissionEntity other = (PermissionEntity) obj;
  413. return this.name.equals(other.name);
  414. }
  415. @Override
  416. public int hashCode() {
  417. int hash = 7;
  418. hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
  419. return hash;
  420. }
  421. @Override
  422. public String toString() {
  423. return this.getClass().getSimpleName() + "(" + this.getName() + ")";
  424. }
  425. public String getMatchingExpression(String permission, String world) {
  426. return this.getMatchingExpression(this.getPermissions(world), permission);
  427. }
  428. public String getMatchingExpression(String[] permissions, String permission) {
  429. for (String expression : permissions) {
  430. if (isMatches(expression, permission, true)) {
  431. return expression;
  432. }
  433. }
  434. return null;
  435. }
  436. /**
  437. * Checks if specified permission matches specified permission expression
  438. *
  439. * @param expression permission expression - what user have in his permissions list (permission.nodes.*)
  440. * @param permission permission which are checking for (permission.node.some.subnode)
  441. * @param additionalChecks check for parent node matching
  442. * @return
  443. */
  444. public boolean isMatches(String expression, String permission, boolean additionalChecks) {
  445. return this.manager.getPermissionMatcher().isMatches(expression, permission);
  446. }
  447. public boolean explainExpression(String expression) {
  448. if (expression == null || expression.isEmpty()) {
  449. return false;
  450. }
  451. return !expression.startsWith("-"); // If expression have - (minus) before then that mean expression are negative
  452. }
  453. public boolean isDebug() {
  454. return this.debugMode || this.manager.isDebug();
  455. }
  456. public void setDebug(boolean debug) {
  457. this.debugMode = debug;
  458. }
  459. }