/testability-explorer/src/main/java/com/google/test/metric/ClassInfo.java

http://testability-explorer.googlecode.com/ · Java · 165 lines · 122 code · 20 blank · 23 comment · 19 complexity · 31e2e997b7b027d618ba0df6187ec854 MD5 · raw file

  1. /*
  2. * Copyright 2007 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.test.metric;
  17. import java.util.ArrayList;
  18. import java.util.Collection;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.TreeMap;
  22. import java.util.TreeSet;
  23. public class ClassInfo {
  24. private final Map<String, MethodInfo> methods = new TreeMap<String, MethodInfo>();
  25. private final Map<String, FieldInfo> fields = new TreeMap<String, FieldInfo>();
  26. private final String name;
  27. private final boolean isInterface;
  28. private final ClassInfo superClass;
  29. private final List<ClassInfo> interfaces;
  30. private final String fileName;
  31. public ClassInfo(String name, boolean isInterface, ClassInfo superClass,
  32. List<ClassInfo> interfaces, String fileName) {
  33. this.isInterface = isInterface;
  34. this.superClass = superClass;
  35. this.interfaces = interfaces;
  36. this.fileName = fileName;
  37. this.name = name.replace("/", ".");
  38. }
  39. public String getName() {
  40. return name;
  41. }
  42. public ClassInfo getSuperClass() {
  43. return superClass;
  44. }
  45. public boolean isInterface() {
  46. return isInterface;
  47. }
  48. public MethodInfo getMethod(String methodName) {
  49. List<ClassInfo> superClasses = new ArrayList<ClassInfo>();
  50. superClasses.add(this);
  51. while (!superClasses.isEmpty()) {
  52. ClassInfo clazz = superClasses.remove(0);
  53. MethodInfo methodInfo = clazz.methods.get(methodName);
  54. if (methodInfo != null) {
  55. return methodInfo;
  56. }
  57. if (clazz.superClass != null) {
  58. superClasses.add(0, clazz.superClass);
  59. }
  60. superClasses.addAll(clazz.interfaces);
  61. }
  62. throw new MethodNotFoundException(this, methodName);
  63. }
  64. public void addMethod(MethodInfo methodInfo) {
  65. methods.put(methodInfo.getName(), methodInfo);
  66. }
  67. @Override
  68. public String toString() {
  69. return name;
  70. }
  71. public FieldInfo getField(String fieldName) {
  72. ClassInfo clazz = this;
  73. while (clazz != null) {
  74. FieldInfo fieldInfo = clazz.fields.get(fieldName);
  75. if (fieldInfo != null) {
  76. return fieldInfo;
  77. }
  78. clazz = clazz.superClass;
  79. }
  80. throw new FieldNotFoundException(this, fieldName);
  81. }
  82. public void addField(FieldInfo fieldInfo) {
  83. fields.put(fieldInfo.getName(), fieldInfo);
  84. }
  85. public Collection<MethodInfo> getMethods() {
  86. return methods.values();
  87. }
  88. public Collection<FieldInfo> getFields() {
  89. return fields.values();
  90. }
  91. public List<ClassInfo> getInterfaces() {
  92. return interfaces;
  93. }
  94. public Collection<MethodInfo> getSetters() {
  95. Collection<MethodInfo> setters = new TreeSet<MethodInfo>();
  96. if (superClass != null) {
  97. setters.addAll(superClass.getSetters());
  98. }
  99. for (MethodInfo method : methods.values()) {
  100. if (method.isSetter()) {
  101. setters.add(method);
  102. }
  103. }
  104. return setters;
  105. }
  106. /** When you have multiple constructors you need to know which one to use for marking
  107. * fields as injectables. The heuristic is that the constructor with most arguments
  108. * will probably be the constructor best suited for testing as it will give you highest
  109. * control over your field injection.
  110. */
  111. public MethodInfo getConstructorWithMostNonPrimitiveParameters() {
  112. // TODO(jwolter): It would seem more accurate a approximation of multiple constructors
  113. // if we would calculate the cost for all of them, and then add in only the highest,
  114. // or an average of them.
  115. MethodInfo constructor = null;
  116. int currentArgsCount = -1;
  117. for (MethodInfo methodInfo : getNonPrivateConstructors()) {
  118. int count = methodInfo.getNonPrimitiveArgCount();
  119. if (currentArgsCount < count) {
  120. constructor = methodInfo;
  121. currentArgsCount = count;
  122. }
  123. }
  124. return constructor;
  125. }
  126. public Collection<MethodInfo> getNonPrivateConstructors() {
  127. TreeSet<MethodInfo> constructors = new TreeSet<MethodInfo>();
  128. for (MethodInfo methodInfo : getMethods()) {
  129. if (methodInfo.isConstructor() && !methodInfo.isPrivate()) {
  130. constructors.add(methodInfo);
  131. }
  132. }
  133. return constructors;
  134. }
  135. public String getFileName() {
  136. return fileName;
  137. }
  138. public ClassInfo copy() {
  139. ClassInfo clazz = new ClassInfo(name, isInterface, superClass, interfaces, fileName);
  140. for (MethodInfo methodInfo : getMethods()) {
  141. clazz.addMethod(methodInfo);
  142. }
  143. return clazz;
  144. }
  145. }