SPR-6788: fixed compareTo() consistency with equals
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2916 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
48df1fd669
commit
f04ef6a5f1
|
|
@ -27,6 +27,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
@ -311,9 +312,38 @@ public class MediaType implements Comparable<MediaType> {
|
||||||
* @see #sortBySpecificity(List)
|
* @see #sortBySpecificity(List)
|
||||||
*/
|
*/
|
||||||
public int compareTo(MediaType other) {
|
public int compareTo(MediaType other) {
|
||||||
String s1 = this.toString();
|
int comp = this.type.compareToIgnoreCase(other.type);
|
||||||
String s2 = other.toString();
|
if (comp != 0) {
|
||||||
return s1.compareToIgnoreCase(s2);
|
return comp;
|
||||||
|
}
|
||||||
|
comp = this.subtype.compareToIgnoreCase(other.subtype);
|
||||||
|
if (comp != 0) {
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
comp = this.parameters.size() - other.parameters.size();
|
||||||
|
if (comp != 0) {
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
Iterator<String> thisAttributes = new TreeSet<String>(this.parameters.keySet()).iterator();
|
||||||
|
Iterator<String> otherAttributes = new TreeSet<String>(other.parameters.keySet()).iterator();
|
||||||
|
while (thisAttributes.hasNext()) {
|
||||||
|
String thisAttribute = thisAttributes.next();
|
||||||
|
String otherAttribute = otherAttributes.next();
|
||||||
|
comp = thisAttribute.compareToIgnoreCase(otherAttribute);
|
||||||
|
if (comp != 0) {
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
String thisValue = this.parameters.get(thisAttribute);
|
||||||
|
String otherValue = other.parameters.get(otherAttribute);
|
||||||
|
if (otherValue == null) {
|
||||||
|
otherValue = "";
|
||||||
|
}
|
||||||
|
comp = thisValue.compareTo(otherValue);
|
||||||
|
if (comp != 0) {
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -348,7 +378,11 @@ public class MediaType implements Comparable<MediaType> {
|
||||||
builder.append(this.type);
|
builder.append(this.type);
|
||||||
builder.append('/');
|
builder.append('/');
|
||||||
builder.append(this.subtype);
|
builder.append(this.subtype);
|
||||||
for (Map.Entry<String, String> entry : this.parameters.entrySet()) {
|
appendTo(this.parameters, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendTo(Map<String, String> map, StringBuilder builder) {
|
||||||
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
builder.append(';');
|
builder.append(';');
|
||||||
builder.append(entry.getKey());
|
builder.append(entry.getKey());
|
||||||
builder.append('=');
|
builder.append('=');
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,7 @@ public class MediaTypeTests {
|
||||||
MediaType audio = new MediaType("audio");
|
MediaType audio = new MediaType("audio");
|
||||||
MediaType audioWave = new MediaType("audio", "wave");
|
MediaType audioWave = new MediaType("audio", "wave");
|
||||||
MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1"));
|
MediaType audioBasicLevel = new MediaType("audio", "basic", Collections.singletonMap("level", "1"));
|
||||||
|
MediaType audioBasic07 = new MediaType("audio", "basic", 0.7);
|
||||||
|
|
||||||
// equal
|
// equal
|
||||||
assertEquals("Invalid comparison result", 0, audioBasic.compareTo(audioBasic));
|
assertEquals("Invalid comparison result", 0, audioBasic.compareTo(audioBasic));
|
||||||
|
|
@ -189,6 +190,7 @@ public class MediaTypeTests {
|
||||||
expected.add(audio);
|
expected.add(audio);
|
||||||
expected.add(audioBasic);
|
expected.add(audioBasic);
|
||||||
expected.add(audioBasicLevel);
|
expected.add(audioBasicLevel);
|
||||||
|
expected.add(audioBasic07);
|
||||||
expected.add(audioWave);
|
expected.add(audioWave);
|
||||||
|
|
||||||
List<MediaType> result = new ArrayList<MediaType>(expected);
|
List<MediaType> result = new ArrayList<MediaType>(expected);
|
||||||
|
|
@ -199,10 +201,37 @@ public class MediaTypeTests {
|
||||||
Collections.sort(result);
|
Collections.sort(result);
|
||||||
|
|
||||||
for (int j = 0; j < result.size(); j++) {
|
for (int j = 0; j < result.size(); j++) {
|
||||||
assertSame("Invalid media type at " + j, expected.get(j), result.get(j));
|
assertSame("Invalid media type at " + j + ", run " + i, expected.get(j), result.get(j));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareToConsistentWithEquals() {
|
||||||
|
MediaType m1 = MediaType.parseMediaType("text/html; q=0.7; charset=iso-8859-1");
|
||||||
|
MediaType m2 = MediaType.parseMediaType("text/html; charset=iso-8859-1; q=0.7");
|
||||||
|
|
||||||
|
assertEquals("Media types not equal", m1, m2);
|
||||||
|
assertEquals("compareTo() not consistent with equals", 0, m1.compareTo(m2));
|
||||||
|
assertEquals("compareTo() not consistent with equals", 0, m2.compareTo(m1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareToCaseSensitivity() {
|
||||||
|
MediaType m1 = new MediaType("audio", "basic");
|
||||||
|
MediaType m2 = new MediaType("Audio", "Basic");
|
||||||
|
assertEquals("Invalid comparison result", 0, m1.compareTo(m2));
|
||||||
|
assertEquals("Invalid comparison result", 0, m2.compareTo(m1));
|
||||||
|
|
||||||
|
m1 = new MediaType("audio", "basic", Collections.singletonMap("foo", "bar"));
|
||||||
|
m2 = new MediaType("audio", "basic", Collections.singletonMap("Foo", "bar"));
|
||||||
|
assertEquals("Invalid comparison result", 0, m1.compareTo(m2));
|
||||||
|
assertEquals("Invalid comparison result", 0, m2.compareTo(m1));
|
||||||
|
|
||||||
|
m1 = new MediaType("audio", "basic", Collections.singletonMap("foo", "bar"));
|
||||||
|
m2 = new MediaType("audio", "basic", Collections.singletonMap("foo", "Bar"));
|
||||||
|
assertTrue("Invalid comparison result", m1.compareTo(m2) != 0);
|
||||||
|
assertTrue("Invalid comparison result", m2.compareTo(m1) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue