LinkProperties.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package com.simuwang.shiro;
  2. import java.io.*;
  3. import java.util.ArrayList;
  4. import java.util.Enumeration;
  5. import java.util.List;
  6. import java.util.Properties;
  7. public class LinkProperties extends Properties {
  8. private List<Object> keyList = new ArrayList<Object>();
  9. /**
  10. * 默认构造方法
  11. */
  12. public LinkProperties() {
  13. }
  14. /**
  15. * 从指定路径加载信息到Properties
  16. *
  17. * @param path
  18. */
  19. public LinkProperties(String path) {
  20. try {
  21. InputStream is = new FileInputStream(path);
  22. this.load(is);
  23. } catch (FileNotFoundException e) {
  24. e.printStackTrace();
  25. throw new RuntimeException("指定文件不存在!");
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. /**
  31. * 重写put方法,按照property的存入顺序保存key到keyList,遇到重复的后者将覆盖前者。
  32. */
  33. @Override
  34. public synchronized Object put(Object key, Object value) {
  35. this.removeKeyIfExists(key);
  36. keyList.add(key);
  37. return super.put(key, value);
  38. }
  39. /**
  40. * 重写remove方法,删除属性时清除keyList中对应的key。
  41. */
  42. @Override
  43. public synchronized Object remove(Object key) {
  44. this.removeKeyIfExists(key);
  45. return super.remove(key);
  46. }
  47. /**
  48. * keyList中存在指定的key时则将其删除
  49. */
  50. private void removeKeyIfExists(Object key) {
  51. keyList.remove(key);
  52. }
  53. /**
  54. * 获取Properties中key的有序集合
  55. *
  56. * @return
  57. */
  58. public List<Object> getKeyList() {
  59. return keyList;
  60. }
  61. /**
  62. * 保存Properties到指定文件,默认使用UTF-8编码
  63. *
  64. * @param path 指定文件路径
  65. */
  66. public void store(String path) {
  67. this.store(path, "UTF-8");
  68. }
  69. /**
  70. * 保存Properties到指定文件,并指定对应存放编码
  71. *
  72. * @param path 指定路径
  73. * @param charset 文件编码
  74. */
  75. public void store(String path, String charset) {
  76. if (path != null && !"".equals(path)) {
  77. try {
  78. OutputStream os = new FileOutputStream(path);
  79. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, charset));
  80. this.store(bw, null);
  81. bw.close();
  82. } catch (FileNotFoundException e) {
  83. e.printStackTrace();
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. } else {
  88. throw new RuntimeException("存储路径不能为空!");
  89. }
  90. }
  91. /**
  92. * 重写keys方法,返回根据keyList适配的Enumeration,且保持HashTable keys()方法的原有语义,
  93. * 每次都调用返回一个新的Enumeration对象,且和之前的不产生冲突
  94. */
  95. @Override
  96. public synchronized Enumeration<Object> keys() {
  97. return new EnumerationAdapter<Object>(keyList);
  98. }
  99. /**
  100. * List到Enumeration的适配器
  101. */
  102. private class EnumerationAdapter<T> implements Enumeration<T> {
  103. private final List<T> list;
  104. private final boolean isEmpty;
  105. private int index = 0;
  106. public EnumerationAdapter(List<T> list) {
  107. this.list = list;
  108. this.isEmpty = list.isEmpty();
  109. }
  110. public boolean hasMoreElements() {
  111. //isEmpty的引入是为了更贴近HashTable原有的语义,在HashTable中添加元素前调用其keys()方法获得一个Enumeration的引用,
  112. //之后往HashTable中添加数据后,调用之前获取到的Enumeration的hasMoreElements()将返回false,但如果此时重新获取一个
  113. //Enumeration的引用,则新Enumeration的hasMoreElements()将返回true,而且之后对HashTable数据的增、删、改都是可以在
  114. //nextElement中获取到的。
  115. return !isEmpty && index < list.size();
  116. }
  117. public T nextElement() {
  118. if (this.hasMoreElements()) {
  119. return list.get(index++);
  120. }
  121. return null;
  122. }
  123. }
  124. }