1 package com.stateofflow.eclipse.metrics.location;
2
3 public final class MetricLocation implements Comparable<MetricLocation> {
4 public interface Closure {
5 public void execute(MetricLocation location);
6 }
7
8 private final String packageName;
9 private final NamedLineNumber typeInfo;
10 private final NamedLineNumber methodInfo;
11
12 MetricLocation(final String packageName, final NamedLineNumber typeInfo, final NamedLineNumber methodInfo) {
13 this.packageName = packageName;
14 this.typeInfo = typeInfo;
15 this.methodInfo = methodInfo;
16 }
17
18 private int compareMethodInfo(final MetricLocation l2) {
19 if (hasMethod()) {
20 return l2.hasMethod() ? getMethodInfo().compareTo(l2.getMethodInfo()) : 1;
21 } else {
22 return l2.hasMethod() ? -1 : 0;
23 }
24 }
25
26 private int comparePackageNames(final MetricLocation l2) {
27 return getPackageName().compareTo(l2.getPackageName());
28 }
29
30 public int compareTo(final MetricLocation that) {
31 int comparison = comparePackageNames(that);
32 if (comparison != 0) {
33 return comparison;
34 }
35
36 comparison = compareTypes(that);
37 if (comparison != 0) {
38 return comparison;
39 }
40
41 return compareMethodInfo(that);
42 }
43
44 private int compareTypes(final MetricLocation l2) {
45 return getTypeInfo().compareTo(l2.getTypeInfo());
46 }
47
48 public MetricLocation createContainingLocation() {
49 if (hasMethod()) {
50 return new MetricLocation(packageName, typeInfo, null);
51 } else if (hasType()) {
52 return new MetricLocation(packageName, null, null);
53 } else {
54 throw new IllegalStateException("No containing location:" + this);
55 }
56 }
57
58 @Override
59 public boolean equals(final Object thatObj) {
60 if (thatObj == this) {
61 return true;
62 }
63
64 if (thatObj == null || !thatObj.getClass().equals(getClass())) {
65 return false;
66 }
67
68 return equalsMetricLocation((MetricLocation) thatObj);
69 }
70
71 private boolean equalsMetricLocation(final MetricLocation that) {
72 if (!isSameKindOfLocation(that) || !getPackageName().equals(that.getPackageName())) {
73 return false;
74 }
75
76 return !hasType() || getTypeInfo().equals(that.getTypeInfo()) && (!hasMethod() || getMethodInfo().equals(that.getMethodInfo()));
77 }
78
79 public NamedLineNumber getMethodInfo() {
80 if (!hasMethod()) {
81 throw new IllegalStateException("No methodInfo available: " + this);
82 }
83 return methodInfo;
84 }
85
86 public String getPackageName() {
87 return packageName;
88 }
89
90 public NamedLineNumber getTypeInfo() {
91 if (!hasType()) {
92 throw new IllegalStateException("No typeInfo available: " + this);
93 }
94 return typeInfo;
95 }
96
97 @Override
98 public int hashCode() {
99 int hash = packageName.hashCode();
100 if (!hasType()) {
101 return hash;
102 }
103
104 hash ^= typeInfo.hashCode();
105 if (!hasMethod()) {
106 return hash;
107 }
108
109 return hash ^ methodInfo.hashCode();
110 }
111
112 public boolean hasMethod() {
113 return methodInfo != null;
114 }
115
116 public boolean hasType() {
117 return typeInfo != null;
118 }
119
120 private boolean isSameKindOfLocation(final MetricLocation that) {
121 return hasType() == that.hasType() && hasMethod() == that.hasMethod();
122 }
123
124 @Override
125 public String toString() {
126 final StringBuffer sb = new StringBuffer();
127 sb.append("packageName=").append(packageName);
128 sb.append(", type=").append(typeInfo);
129 sb.append(", methodName=").append(methodInfo);
130
131 return sb.toString();
132 }
133
134 public String getCompilationUnit() {
135 return getPackageName() + "." + truncateAt(truncateAt(getTypeInfo().getName(), '$'), '.');
136 }
137
138 private String truncateAt(final String type, final char ch) {
139 return type.indexOf(ch) != -1 ? type.substring(0, type.indexOf(ch)) : type;
140 }
141 }
142