7083187: Class CSS.CssValue is missing implementations of equals() and hashCode()

Co-authored-by: Alexey Ivanov <aivanov@openjdk.org>
Reviewed-by: aivanov, prr
This commit is contained in:
Prasanta Sadhukhan 2023-06-19 08:52:06 +00:00
parent 4229baf9b6
commit d2a858e173
2 changed files with 264 additions and 0 deletions

View File

@ -38,6 +38,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Objects;
import javax.swing.ImageIcon;
import javax.swing.SizeRequirements;
@ -2024,6 +2025,18 @@ public class CSS implements Serializable {
boolean isSup() {
return (svalue.contains("sup"));
}
@Override
public int hashCode() {
return (this.svalue != null) ? this.svalue.hashCode() : 0;
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.StringValue strVal
&& Objects.equals(this.svalue, strVal.svalue);
}
}
/**
@ -2201,6 +2214,21 @@ public class CSS implements Serializable {
return Integer.valueOf(getValue(null, null));
}
@Override
public int hashCode() {
return Float.hashCode(value)
| Boolean.hashCode(index)
| Objects.hashCode(lu);
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.FontSize size
&& value == size.value
&& index == size.index
&& Objects.equals(lu, size.lu);
}
float value;
boolean index;
LengthUnit lu;
@ -2301,6 +2329,17 @@ public class CSS implements Serializable {
return family;
}
@Override
public int hashCode() {
return (family != null) ? family.hashCode() : 0;
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.FontFamily font
&& Objects.equals(family, font.family);
}
String family;
}
@ -2364,6 +2403,17 @@ public class CSS implements Serializable {
return (weight > 500);
}
@Override
public int hashCode() {
return Integer.hashCode(weight);
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.FontWeight fontWeight
&& weight == fontWeight.weight;
}
int weight;
}
@ -2424,6 +2474,16 @@ public class CSS implements Serializable {
return c;
}
@Override
public int hashCode() {
return (c != null) ? c.hashCode() : 0;
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.ColorValue color && c.equals(color.c);
}
Color c;
}
@ -2478,6 +2538,16 @@ public class CSS implements Serializable {
}
}
@Override
public int hashCode() {
return (style != null) ? style.hashCode() : 0;
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.BorderStyle border && style.equals(border.style);
}
// CSS.Values are static, don't archive it.
private transient CSS.Value style;
}
@ -2605,9 +2675,25 @@ public class CSS implements Serializable {
return Float.valueOf(getValue(false));
}
@Override
public int hashCode() {
return Float.hashCode(span)
| Boolean.hashCode(percentage)
| Objects.hashCode(units);
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.LengthValue lu
&& percentage == lu.percentage
&& span == lu.span
&& Objects.equals(units, lu.units);
}
/** If true, span is a percentage value, and that to determine
* the length another value needs to be passed in. */
boolean percentage;
/** Either the absolute value (percentage == false) or
* a percentage value. */
float span;
@ -2824,6 +2910,21 @@ public class CSS implements Serializable {
float getVerticalPosition() {
return verticalPosition;
}
@Override
public int hashCode() {
return Float.hashCode(horizontalPosition)
| Float.hashCode(verticalPosition)
| Short.hashCode(relative);
}
@Override
public boolean equals(Object val) {
return val instanceof CSS.BackgroundPosition bp
&& horizontalPosition == bp.horizontalPosition
&& verticalPosition == bp.verticalPosition
&& relative == bp.relative;
}
}
@ -2983,6 +3084,21 @@ public class CSS implements Serializable {
return type + " " + value;
}
@Override
public int hashCode() {
return Float.hashCode(value)
| Short.hashCode(type)
| Objects.hashCode(units);
}
@Override
public boolean equals(Object obj) {
return obj instanceof LengthUnit lu
&& type == lu.type
&& value == lu.value
&& Objects.equals(units, lu.units);
}
// 0 - value indicates real value
// 1 - % value, value relative to depends upon key.
// 50% will have a value = .5

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.text.AttributeSet;
import javax.swing.text.html.StyleSheet;
/*
* @test
* @bug 7083187
* @summary Verifies if CSS.CSSValue attribute is same
* @run main CSSAttributeEqualityBug
*/
public class CSSAttributeEqualityBug {
/**
* CSS declarations which should produce equal attribute sets.
*/
private static final String[] EQUALS = {
"font-size: 42",
"font-size: 42px",
"font-size: 42em",
"font-size: medium",
"font-size: smaller",
"font-size: 200%",
"font-family: sans-serif",
"font-family: 'DejaVu Serif', serif",
"font-weight: bold",
"color: red",
"color: rgb(255, 0, 0)",
"border-style: dashed",
"margin-top: 42",
"margin-top: 42px",
"margin-top: 100%",
"text-decoration: underline",
"background-position: top",
"background-position: top right",
"background-position: 25% 75%",
"background-position: 0 0",
"background-position: 1cm 2cm",
"background-position: 1em 2em",
};
/**
* CSS declarations which should produce different attribute sets.
*/
private static final String[][] NOT_EQUALS = {
{"font-size: 42px", "font-size: 22px"},
{"font-size: 42px", "font-size: 42pt"},
{"font-size: 42em", "font-size: 42ex"},
{"font-size: 100%", "font-size: 200%"},
{"margin-top: 42px", "margin-top: 22px"},
{"margin-top: 42px", "margin-top: 42pt"},
{"margin-top: 100%", "margin-top: 50%"},
};
public static void main(String[] args) {
final List<String> failures = new ArrayList<>();
Arrays.stream(EQUALS)
.map(CSSAttributeEqualityBug::positiveTest)
.filter(Objects::nonNull)
.forEach(failures::add);
Arrays.stream(NOT_EQUALS)
.map(CSSAttributeEqualityBug::negativeTest)
.filter(Objects::nonNull)
.forEach(failures::add);
if (!failures.isEmpty()) {
failures.forEach(System.err::println);
throw new RuntimeException(failures.size()
+ " failure(s) detected: "
+ failures.get(0));
}
}
private static String positiveTest(String cssDeclaration) {
StyleSheet ss = new StyleSheet();
AttributeSet a = ss.getDeclaration(cssDeclaration);
AttributeSet b = ss.getDeclaration(cssDeclaration);
return assertEquals(a, b);
}
private static String negativeTest(String[] cssDeclaration) {
StyleSheet ss = new StyleSheet();
AttributeSet a = ss.getDeclaration(cssDeclaration[0]);
AttributeSet b = ss.getDeclaration(cssDeclaration[1]);
return assertNotEquals(a, b);
}
private static String assertEquals(AttributeSet a,
AttributeSet b) {
return !a.isEqual(b)
? getErrorMessage(a, b, "is not equal to")
: null;
}
private static String assertNotEquals(AttributeSet a,
AttributeSet b) {
return a.isEqual(b)
? getErrorMessage(a, b, "is equal to")
: null;
}
private static String getErrorMessage(AttributeSet a,
AttributeSet b,
String message) {
return a + " " + message + " " + b;
}
}