1 package net.sourceforge.jparam.conversion.weights;
2
3 /***
4 * A class representing the weight of a single scalar conversion, from one
5 * type to another
6 *
7 * Chained conversion are supported
8 *
9 * @author Ron_Sidi
10 *
11 */
12 public class ScalarConversionWeight implements Comparable {
13
14
15 static final int _CONV_IMPOSSIBLE = 0;
16 static final int _CONV_USER = 1;
17 static final int _CONV_TENTATIVE = 2;
18 static final int _CONV_TO_PARENT = 3;
19 static final int _CONV_STANDARD = 4;
20 static final int _CONV_PROMOTION = 5;
21 static final int _CONV_EXACT = 6;
22
23
24 static final String[] WEIGHT_NAME = { "IMPOSSIBLE", "USER", "TENTATIVE",
25 "TO_PARENT", "STANDARD", "PROMOTION" };
26
27
28 public static final ScalarConversionWeight CONV_IMPOSSIBLE = new ScalarConversionWeight(
29 _CONV_IMPOSSIBLE);
30
31 public static final ScalarConversionWeight CONV_USER = new ScalarConversionWeight(
32 _CONV_USER);
33
34 public static final ScalarConversionWeight CONV_TENTATIVE = new ScalarConversionWeight(
35 _CONV_TENTATIVE);
36
37 public static final ScalarConversionWeight CONV_TO_PARENT = new ScalarConversionWeight(
38 _CONV_TO_PARENT);
39
40 public static final ScalarConversionWeight CONV_PROMOTE = new ScalarConversionWeight(
41 _CONV_PROMOTION);
42
43 public static final ScalarConversionWeight CONV_STANDARD = new ScalarConversionWeight(
44 _CONV_STANDARD);
45
46 public static final ScalarConversionWeight CONV_EXACT = new ScalarConversionWeight(
47 _CONV_EXACT);
48
49
50
51 int NUMBER_OF_CONVERSION_TYPES = _CONV_EXACT;
52
53
54 int[] weights = new int[NUMBER_OF_CONVERSION_TYPES];
55
56
57
58
59
60 public int compareTo(Object o) {
61 if (!o.getClass().equals(ScalarConversionWeight.class)) {
62 throw new IllegalArgumentException(
63 "Cannot compare ScalarConversionWeight to something else: "
64 + o.getClass().getName());
65 }
66
67
68
69 ScalarConversionWeight other = (ScalarConversionWeight) o;
70 for (int i = 0; i < weights.length; i++) {
71 if (other.weights[i] != weights[i]) {
72 return (weights[i] - other.weights[i] < 0) ? -1 : 1;
73 }
74 }
75
76
77 return 0;
78 }
79
80
81 /***
82 * This constructor is intentionally private, no one should be able to
83 * create a <code>ScalarConversionWeight</code> directly, either use one
84 * of the supplied constant or concat two weights
85 *
86 * @param conversionType
87 */
88 private ScalarConversionWeight(int conversionType) {
89
90
91 if (conversionType != _CONV_EXACT) {
92 weights[conversionType] = 1;
93 }
94 }
95
96 /***
97 * Create a <code>ScalarConversionWeight</code> representing both
98 * conversions
99 *
100 * @param first
101 * @param second
102 */
103 public ScalarConversionWeight(ScalarConversionWeight first,
104 ScalarConversionWeight second) {
105
106 for (int i = 0; i < weights.length; i++) {
107 weights[i] = first.weights[i] + second.weights[i];
108 }
109
110
111 if (weights[_CONV_USER] > 1) {
112 weights[_CONV_USER] = 1;
113 }
114 }
115
116
117
118
119 public int hashCode() {
120 int hash = 0;
121 for (int i = 0; i < weights.length; i++) {
122 hash = hash * 10 + weights[i];
123 }
124
125 return hash;
126 }
127
128
129
130
131 public boolean equals(Object o) {
132 if (o.getClass().equals(ScalarConversionWeight.class)) {
133 return compareTo(o) == 0;
134 }
135 return false;
136 }
137
138 /***
139 * Return a string representation of this weight, all types of conversion
140 * ordered from hardest to easiest, along with the count of each
141 *
142 * @see java.lang.Object#toString()
143 */
144 public String toString() {
145
146 if (weights[_CONV_IMPOSSIBLE] > 0)
147 return WEIGHT_NAME[_CONV_IMPOSSIBLE];
148
149 StringBuffer result = new StringBuffer();
150 boolean exact = true;
151
152 for (int i = 0; i < NUMBER_OF_CONVERSION_TYPES; ++i) {
153 if (weights[i] != 0) {
154 if (!exact)
155 result.append(" + ");
156 if (weights[i] != 1)
157 result.append(weights[i]).append("*");
158 result.append(WEIGHT_NAME[i]);
159 exact = false;
160 }
161 }
162
163 if (exact) {
164 return "EXACT";
165 }
166 return result.toString();
167 }
168 }