/core/src/main/java/org/infinispan/configuration/format/PropertyFormatter.java

https://github.com/wburns/infinispan · Java · 140 lines · 104 code · 12 blank · 24 comment · 29 complexity · 66a2f5e965e381d6bc9a69e0a092fbf4 MD5 · raw file

  1. package org.infinispan.configuration.format;
  2. import java.lang.reflect.Method;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.Iterator;
  6. import java.util.List;
  7. import java.util.Properties;
  8. import org.infinispan.configuration.cache.Configuration;
  9. import org.infinispan.configuration.global.GlobalConfiguration;
  10. import org.infinispan.util.logging.Log;
  11. import org.infinispan.util.logging.LogFactory;
  12. /**
  13. *
  14. * Extracts the configuration into flat key-value property structure by reflection.
  15. *
  16. * @author Michal Linhard (mlinhard@redhat.com)
  17. * @since 6.0
  18. */
  19. public class PropertyFormatter {
  20. private static final Log log = LogFactory.getLog(PropertyFormatter.class);
  21. private static Method plainToString = null;
  22. static {
  23. try {
  24. plainToString = Object.class.getMethod("toString");
  25. } catch (Exception e) {
  26. log.error("Error while initializing", e);
  27. }
  28. }
  29. private String globalConfigPrefix = "";
  30. private String configPrefix = "";
  31. /**
  32. *
  33. * Create a new PropertyFormatter instance.
  34. *
  35. */
  36. public PropertyFormatter() {
  37. this("", "");
  38. }
  39. /**
  40. *
  41. * Create a new PropertyFormatter instance.
  42. *
  43. * @param globalConfigPrefix
  44. * Prefix used for global configuration property keys.
  45. * @param configPrefix
  46. * Prefix used for cache configuration property keys.
  47. */
  48. public PropertyFormatter(String globalConfigPrefix, String configPrefix) {
  49. super();
  50. this.globalConfigPrefix = globalConfigPrefix;
  51. this.configPrefix = configPrefix;
  52. }
  53. private static List<Method> getMethods(Class<?> clazz) {
  54. Class<?> c = clazz;
  55. ArrayList<Method> r = new ArrayList<Method>();
  56. while (c != null && c != Object.class) {
  57. for (Method m : c.getDeclaredMethods()) {
  58. r.add(m);
  59. }
  60. c = c.getSuperclass();
  61. }
  62. return r;
  63. }
  64. private static boolean hasPlainToString(Class<?> cls, Object obj) {
  65. try {
  66. if (cls.getMethod("toString") == plainToString) {
  67. return true;
  68. }
  69. String plainToStringValue = cls.getName() + "@" + Integer.toHexString(System.identityHashCode(obj));
  70. return plainToStringValue.equals(obj.toString());
  71. } catch (Exception e) {
  72. return false;
  73. }
  74. }
  75. private static void reflect(Object obj, Properties p, String prefix) {
  76. try {
  77. if (obj == null) {
  78. p.put(prefix, "null");
  79. return;
  80. }
  81. Class<?> cls = obj.getClass();
  82. if (cls.getName().startsWith("org.infinispan.config") && !cls.isEnum()) {
  83. for (Method m : getMethods(obj.getClass())) {
  84. if (m.getParameterTypes().length != 0 || "toString".equals(m.getName())
  85. || "hashCode".equals(m.getName()) || "toProperties".equals(m.getName())
  86. || m.isAnnotationPresent(Deprecated.class)) {
  87. continue;
  88. }
  89. try {
  90. String prefixDot = prefix == null || "".equals(prefix) ? "" : prefix + ".";
  91. reflect(m.invoke(obj), p, prefixDot + m.getName());
  92. } catch (IllegalAccessException e) {
  93. // ok
  94. }
  95. }
  96. } else if (Collection.class.isAssignableFrom(cls)) {
  97. Collection<?> collection = (Collection<?>) obj;
  98. Iterator<?> iter = collection.iterator();
  99. for (int i = 0; i < collection.size(); i++) {
  100. reflect(iter.next(), p, prefix + "[" + i + "]");
  101. }
  102. } else if (cls.isArray()) {
  103. Object[] a = (Object[]) obj;
  104. for (int i = 0; i < a.length; i++) {
  105. reflect(a[i], p, prefix + "[" + i + "]");
  106. }
  107. } else if (hasPlainToString(cls, obj)) {
  108. // we have a class that doesn't have a nice toString implementation
  109. p.put(prefix, cls.getName());
  110. } else {
  111. // we have a single value
  112. p.put(prefix, obj.toString());
  113. }
  114. } catch (Exception e) {
  115. throw new RuntimeException(e);
  116. }
  117. }
  118. public Properties format(Configuration configuration) {
  119. Properties properties = new Properties();
  120. reflect(configuration, properties, configPrefix);
  121. return properties;
  122. }
  123. public Properties format(GlobalConfiguration configuration) {
  124. Properties properties = new Properties();
  125. reflect(configuration, properties, globalConfigPrefix);
  126. return properties;
  127. }
  128. }