StatsSet.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /*
  2. * Copyright (C) 2004-2014 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model;
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.logging.Level;
  25. import java.util.logging.Logger;
  26. import javolution.util.FastMap;
  27. import com.l2jserver.gameserver.model.holders.SkillHolder;
  28. import com.l2jserver.gameserver.model.interfaces.IParserAdvUtils;
  29. /**
  30. * This class is meant to hold a set of (key,value) pairs.<br>
  31. * They are stored as object but can be retrieved in any type wanted. As long as cast is available.<br>
  32. * @author mkizub
  33. */
  34. public class StatsSet implements IParserAdvUtils
  35. {
  36. private static final Logger _log = Logger.getLogger(StatsSet.class.getName());
  37. /** Static empty immutable map, used to avoid multiple null checks over the source. */
  38. public static final StatsSet EMPTY_STATSET = new StatsSet(Collections.<String, Object> emptyMap());
  39. private final Map<String, Object> _set;
  40. public StatsSet()
  41. {
  42. this(new FastMap<String, Object>());
  43. }
  44. public StatsSet(Map<String, Object> map)
  45. {
  46. _set = map;
  47. }
  48. /**
  49. * Returns the set of values
  50. * @return HashMap
  51. */
  52. public final Map<String, Object> getSet()
  53. {
  54. return _set;
  55. }
  56. /**
  57. * Add a set of couple values in the current set
  58. * @param newSet : StatsSet pointing out the list of couples to add in the current set
  59. */
  60. public void add(StatsSet newSet)
  61. {
  62. _set.putAll(newSet.getSet());
  63. }
  64. /**
  65. * Verifies if the stat set is empty.
  66. * @return {@code true} if the stat set is empty, {@code false} otherwise
  67. */
  68. public boolean isEmpty()
  69. {
  70. return _set.isEmpty();
  71. }
  72. /**
  73. * Return the boolean value associated with key.
  74. * @param key : String designating the key in the set
  75. * @return boolean : value associated to the key
  76. * @throws IllegalArgumentException : If value is not set or value is not boolean
  77. */
  78. @Override
  79. public boolean getBoolean(String key)
  80. {
  81. Object val = _set.get(key);
  82. if (val == null)
  83. {
  84. throw new IllegalArgumentException("Boolean value required, but not specified");
  85. }
  86. if (val instanceof Boolean)
  87. {
  88. return ((Boolean) val).booleanValue();
  89. }
  90. try
  91. {
  92. return Boolean.parseBoolean((String) val);
  93. }
  94. catch (Exception e)
  95. {
  96. throw new IllegalArgumentException("Boolean value required, but found: " + val);
  97. }
  98. }
  99. /**
  100. * Return the boolean value associated with key.<br>
  101. * If no value is associated with key, or type of value is wrong, returns defaultValue.
  102. * @param key : String designating the key in the entry set
  103. * @return boolean : value associated to the key
  104. */
  105. @Override
  106. public boolean getBoolean(String key, boolean defaultValue)
  107. {
  108. Object val = _set.get(key);
  109. if (val == null)
  110. {
  111. return defaultValue;
  112. }
  113. if (val instanceof Boolean)
  114. {
  115. return ((Boolean) val).booleanValue();
  116. }
  117. try
  118. {
  119. return Boolean.parseBoolean((String) val);
  120. }
  121. catch (Exception e)
  122. {
  123. return defaultValue;
  124. }
  125. }
  126. @Override
  127. public byte getByte(String key)
  128. {
  129. Object val = _set.get(key);
  130. if (val == null)
  131. {
  132. throw new IllegalArgumentException("Byte value required, but not specified");
  133. }
  134. if (val instanceof Number)
  135. {
  136. return ((Number) val).byteValue();
  137. }
  138. try
  139. {
  140. return Byte.parseByte((String) val);
  141. }
  142. catch (Exception e)
  143. {
  144. throw new IllegalArgumentException("Byte value required, but found: " + val);
  145. }
  146. }
  147. @Override
  148. public byte getByte(String key, byte defaultValue)
  149. {
  150. Object val = _set.get(key);
  151. if (val == null)
  152. {
  153. return defaultValue;
  154. }
  155. if (val instanceof Number)
  156. {
  157. return ((Number) val).byteValue();
  158. }
  159. try
  160. {
  161. return Byte.parseByte((String) val);
  162. }
  163. catch (Exception e)
  164. {
  165. throw new IllegalArgumentException("Byte value required, but found: " + val);
  166. }
  167. }
  168. public byte[] getByteArray(String key, String splitOn)
  169. {
  170. Object val = _set.get(key);
  171. if (val == null)
  172. {
  173. throw new IllegalArgumentException("Byte value required, but not specified");
  174. }
  175. if (val instanceof Number)
  176. {
  177. byte[] result =
  178. {
  179. ((Number) val).byteValue()
  180. };
  181. return result;
  182. }
  183. int c = 0;
  184. String[] vals = ((String) val).split(splitOn);
  185. byte[] result = new byte[vals.length];
  186. for (String v : vals)
  187. {
  188. try
  189. {
  190. result[c++] = Byte.parseByte(v);
  191. }
  192. catch (Exception e)
  193. {
  194. throw new IllegalArgumentException("Byte value required, but found: " + val);
  195. }
  196. }
  197. return result;
  198. }
  199. public List<Byte> getByteList(String key, String splitOn)
  200. {
  201. List<Byte> result = new ArrayList<>();
  202. for (Byte i : getByteArray(key, splitOn))
  203. {
  204. result.add(i);
  205. }
  206. return result;
  207. }
  208. @Override
  209. public short getShort(String key)
  210. {
  211. Object val = _set.get(key);
  212. if (val == null)
  213. {
  214. throw new IllegalArgumentException("Short value required, but not specified");
  215. }
  216. if (val instanceof Number)
  217. {
  218. return ((Number) val).shortValue();
  219. }
  220. try
  221. {
  222. return Short.parseShort((String) val);
  223. }
  224. catch (Exception e)
  225. {
  226. throw new IllegalArgumentException("Short value required, but found: " + val);
  227. }
  228. }
  229. @Override
  230. public short getShort(String key, short defaultValue)
  231. {
  232. Object val = _set.get(key);
  233. if (val == null)
  234. {
  235. return defaultValue;
  236. }
  237. if (val instanceof Number)
  238. {
  239. return ((Number) val).shortValue();
  240. }
  241. try
  242. {
  243. return Short.parseShort((String) val);
  244. }
  245. catch (Exception e)
  246. {
  247. throw new IllegalArgumentException("Short value required, but found: " + val);
  248. }
  249. }
  250. @Override
  251. public int getInt(String key)
  252. {
  253. final Object val = _set.get(key);
  254. if (val == null)
  255. {
  256. throw new IllegalArgumentException("Integer value required, but not specified: " + key + "!");
  257. }
  258. if (val instanceof Number)
  259. {
  260. return ((Number) val).intValue();
  261. }
  262. try
  263. {
  264. return Integer.parseInt((String) val);
  265. }
  266. catch (Exception e)
  267. {
  268. throw new IllegalArgumentException("Integer value required, but found: " + val + "!");
  269. }
  270. }
  271. @Override
  272. public int getInt(String key, int defaultValue)
  273. {
  274. Object val = _set.get(key);
  275. if (val == null)
  276. {
  277. return defaultValue;
  278. }
  279. if (val instanceof Number)
  280. {
  281. return ((Number) val).intValue();
  282. }
  283. try
  284. {
  285. return Integer.parseInt((String) val);
  286. }
  287. catch (Exception e)
  288. {
  289. throw new IllegalArgumentException("Integer value required, but found: " + val);
  290. }
  291. }
  292. public int[] getIntArray(String key, String splitOn)
  293. {
  294. Object val = _set.get(key);
  295. if (val == null)
  296. {
  297. throw new IllegalArgumentException("Integer value required, but not specified");
  298. }
  299. if (val instanceof Number)
  300. {
  301. int[] result =
  302. {
  303. ((Number) val).intValue()
  304. };
  305. return result;
  306. }
  307. int c = 0;
  308. String[] vals = ((String) val).split(splitOn);
  309. int[] result = new int[vals.length];
  310. for (String v : vals)
  311. {
  312. try
  313. {
  314. result[c++] = Integer.parseInt(v);
  315. }
  316. catch (Exception e)
  317. {
  318. throw new IllegalArgumentException("Integer value required, but found: " + val);
  319. }
  320. }
  321. return result;
  322. }
  323. public List<Integer> getIntegerList(String key, String splitOn)
  324. {
  325. List<Integer> result = new ArrayList<>();
  326. for (int i : getIntArray(key, splitOn))
  327. {
  328. result.add(i);
  329. }
  330. return result;
  331. }
  332. @Override
  333. public long getLong(String key)
  334. {
  335. Object val = _set.get(key);
  336. if (val == null)
  337. {
  338. throw new IllegalArgumentException("Integer value required, but not specified");
  339. }
  340. if (val instanceof Number)
  341. {
  342. return ((Number) val).longValue();
  343. }
  344. try
  345. {
  346. return Long.parseLong((String) val);
  347. }
  348. catch (Exception e)
  349. {
  350. throw new IllegalArgumentException("Integer value required, but found: " + val);
  351. }
  352. }
  353. @Override
  354. public long getLong(String key, long defaultValue)
  355. {
  356. Object val = _set.get(key);
  357. if (val == null)
  358. {
  359. return defaultValue;
  360. }
  361. if (val instanceof Number)
  362. {
  363. return ((Number) val).longValue();
  364. }
  365. try
  366. {
  367. return Long.parseLong((String) val);
  368. }
  369. catch (Exception e)
  370. {
  371. throw new IllegalArgumentException("Integer value required, but found: " + val);
  372. }
  373. }
  374. @Override
  375. public float getFloat(String key)
  376. {
  377. Object val = _set.get(key);
  378. if (val == null)
  379. {
  380. throw new IllegalArgumentException("Float value required, but not specified");
  381. }
  382. if (val instanceof Number)
  383. {
  384. return ((Number) val).floatValue();
  385. }
  386. try
  387. {
  388. return (float) Double.parseDouble((String) val);
  389. }
  390. catch (Exception e)
  391. {
  392. throw new IllegalArgumentException("Float value required, but found: " + val);
  393. }
  394. }
  395. @Override
  396. public float getFloat(String key, float defaultValue)
  397. {
  398. Object val = _set.get(key);
  399. if (val == null)
  400. {
  401. return defaultValue;
  402. }
  403. if (val instanceof Number)
  404. {
  405. return ((Number) val).floatValue();
  406. }
  407. try
  408. {
  409. return (float) Double.parseDouble((String) val);
  410. }
  411. catch (Exception e)
  412. {
  413. throw new IllegalArgumentException("Float value required, but found: " + val);
  414. }
  415. }
  416. @Override
  417. public double getDouble(String key)
  418. {
  419. Object val = _set.get(key);
  420. if (val == null)
  421. {
  422. throw new IllegalArgumentException("Float value required, but not specified");
  423. }
  424. if (val instanceof Number)
  425. {
  426. return ((Number) val).doubleValue();
  427. }
  428. try
  429. {
  430. return Double.parseDouble((String) val);
  431. }
  432. catch (Exception e)
  433. {
  434. throw new IllegalArgumentException("Float value required, but found: " + val);
  435. }
  436. }
  437. @Override
  438. public double getDouble(String key, double defaultValue)
  439. {
  440. Object val = _set.get(key);
  441. if (val == null)
  442. {
  443. return defaultValue;
  444. }
  445. if (val instanceof Number)
  446. {
  447. return ((Number) val).doubleValue();
  448. }
  449. try
  450. {
  451. return Double.parseDouble((String) val);
  452. }
  453. catch (Exception e)
  454. {
  455. throw new IllegalArgumentException("Float value required, but found: " + val);
  456. }
  457. }
  458. @Override
  459. public String getString(String key)
  460. {
  461. Object val = _set.get(key);
  462. if (val == null)
  463. {
  464. throw new IllegalArgumentException("String value required, but not specified");
  465. }
  466. return String.valueOf(val);
  467. }
  468. @Override
  469. public String getString(String key, String defaultValue)
  470. {
  471. Object val = _set.get(key);
  472. if (val == null)
  473. {
  474. return defaultValue;
  475. }
  476. return String.valueOf(val);
  477. }
  478. @Override
  479. @SuppressWarnings("unchecked")
  480. public <T extends Enum<T>> T getEnum(String key, Class<T> enumClass)
  481. {
  482. Object val = _set.get(key);
  483. if (val == null)
  484. {
  485. throw new IllegalArgumentException("Enum value of type " + enumClass.getName() + " required, but not specified");
  486. }
  487. if (enumClass.isInstance(val))
  488. {
  489. return (T) val;
  490. }
  491. try
  492. {
  493. return Enum.valueOf(enumClass, String.valueOf(val));
  494. }
  495. catch (Exception e)
  496. {
  497. throw new IllegalArgumentException("Enum value of type " + enumClass.getName() + " required, but found: " + val);
  498. }
  499. }
  500. @Override
  501. @SuppressWarnings("unchecked")
  502. public <T extends Enum<T>> T getEnum(String key, Class<T> enumClass, T defaultValue)
  503. {
  504. Object val = _set.get(key);
  505. if (val == null)
  506. {
  507. return defaultValue;
  508. }
  509. if (enumClass.isInstance(val))
  510. {
  511. return (T) val;
  512. }
  513. try
  514. {
  515. return Enum.valueOf(enumClass, String.valueOf(val));
  516. }
  517. catch (Exception e)
  518. {
  519. throw new IllegalArgumentException("Enum value of type " + enumClass.getName() + " required, but found: " + val);
  520. }
  521. }
  522. @SuppressWarnings("unchecked")
  523. public final <A> A getObject(String name, Class<A> type)
  524. {
  525. Object obj = _set.get(name);
  526. if ((obj == null) || !type.isAssignableFrom(obj.getClass()))
  527. {
  528. return null;
  529. }
  530. return (A) obj;
  531. }
  532. public SkillHolder getSkillHolder(String key)
  533. {
  534. Object obj = _set.get(key);
  535. if ((obj == null) || !(obj instanceof SkillHolder))
  536. {
  537. return null;
  538. }
  539. return (SkillHolder) obj;
  540. }
  541. public void set(String name, Object value)
  542. {
  543. _set.put(name, value);
  544. }
  545. public void set(String key, boolean value)
  546. {
  547. _set.put(key, value);
  548. }
  549. public void set(String key, byte value)
  550. {
  551. _set.put(key, value);
  552. }
  553. public void set(String key, short value)
  554. {
  555. _set.put(key, value);
  556. }
  557. public void set(String key, int value)
  558. {
  559. _set.put(key, value);
  560. }
  561. public void set(String key, long value)
  562. {
  563. _set.put(key, value);
  564. }
  565. public void set(String key, float value)
  566. {
  567. _set.put(key, value);
  568. }
  569. public void set(String key, double value)
  570. {
  571. _set.put(key, value);
  572. }
  573. public void set(String key, String value)
  574. {
  575. _set.put(key, value);
  576. }
  577. public void set(String key, Enum<?> value)
  578. {
  579. _set.put(key, value);
  580. }
  581. public void safeSet(String key, int value, int min, int max, String reference)
  582. {
  583. assert !(((min <= max) && ((value < min) || (value >= max))));
  584. if ((min <= max) && ((value < min) || (value >= max)))
  585. {
  586. _log.log(Level.SEVERE, "Incorrect value: " + value + "for: " + key + "Ref: " + reference);
  587. }
  588. set(key, value);
  589. }
  590. }