Skip to content

Commit

Permalink
8304959: Public API in javafx.css.Match should not return private API…
Browse files Browse the repository at this point in the history
… class PseudoClassState

Reviewed-by: kcr, angorya
  • Loading branch information
hjohn committed May 31, 2023
1 parent 2a6e48f commit 3fa02ee
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 130 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
Expand All @@ -24,22 +24,23 @@
*/
package com.sun.javafx.css;

import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

import com.sun.javafx.collections.SetListenerHelper;

import javafx.beans.InvalidationListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener;

import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;


/**
* Pseudo-class state and style-classes are represented as bits in a long[]
* which makes matching faster.
*/
abstract class BitSet<T> implements ObservableSet<T> {
abstract class BitSet<T> extends AbstractSet<T> implements ObservableSet<T> {

/** Create an empty set of T */
protected BitSet () {
Expand Down Expand Up @@ -229,10 +230,14 @@ public boolean contains(Object o) {
/** {@inheritDoc} */
@Override
public boolean containsAll(Collection<?> c) {
if (this.getClass() != c.getClass()) {
for (Object obj : c) {
if (!contains(obj)) {
return false;
}
}

if (c == null || this.getClass() != c.getClass()) {
// this not modified!
return false;
return true;
}

BitSet other = (BitSet)c;
Expand All @@ -258,10 +263,14 @@ public boolean containsAll(Collection<?> c) {
/** {@inheritDoc} */
@Override
public boolean addAll(Collection<? extends T> c) {
if (this.getClass() != c.getClass()) {
boolean modified = false;

if (c == null || this.getClass() != c.getClass()) {
// this not modified!
return false;
for (T obj : c) {
modified |= add(obj);
}

return modified;
}

boolean modified = false;
Expand Down Expand Up @@ -330,10 +339,19 @@ public boolean addAll(Collection<? extends T> c) {
/** {@inheritDoc} */
@Override
public boolean retainAll(Collection<?> c) {
if (this.getClass() != c.getClass()) {
boolean modified = false;

if (c == null || this.getClass() != c.getClass()) {
clear();
return true;
for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) {
T obj = iterator.next();

if (!c.contains(obj)) {
iterator.remove();
modified = true;
}
}

return modified;
}

boolean modified = false;
Expand Down Expand Up @@ -412,10 +430,14 @@ public boolean retainAll(Collection<?> c) {
/** {@inheritDoc} */
@Override
public boolean removeAll(Collection<?> c) {
if (this.getClass() != c.getClass()) {
boolean modified = false;

if (c == null || this.getClass() != c.getClass()) {
// this not modified!
return false;
for (Object obj : c) {
modified |= remove(obj);
}

return modified;
}

boolean modified = false;
Expand Down Expand Up @@ -495,31 +517,28 @@ public void clear() {

@Override
public int hashCode() {
int hash = 7;
if (bits.length > 0) {
for (int n = 0; n < bits.length; n++) {
final long mask = bits[n];
hash = 71 * hash + (int)(mask ^ (mask >>> 32));
}
}
return hash;
// Note: overridden because equals is overridden; both equals and hashCode MUST
// respect the Set contract to interact correctly with sets of other types!
return super.hashCode();
}

@Override
public boolean equals(Object obj) {

if (this == obj) {
// Note: overridden to provide a fast path; both equals and hashCode MUST respect
// the Set contract to interact correctly with sets of other types!
if (obj == this) {
return true;
}

if (obj == null || this.getClass() != obj.getClass()) {
return false;
if (getClass() == obj.getClass()) { // fast path if other is exact same type of BitSet
return equalsBitSet((BitSet<?>) obj);
}

final BitSet other = (BitSet) obj;
return super.equals(obj);
}

final int a = this.bits != null ? this.bits.length : 0;
final int b = other.bits != null ? other.bits.length : 0;
private boolean equalsBitSet(BitSet<?> other) {
int a = this.bits != null ? this.bits.length : 0;
int b = other.bits != null ? other.bits.length : 0;

if (a != b) return false;

Expand Down Expand Up @@ -626,4 +645,3 @@ private void notifyObservers(T element, boolean removed) {
}
}
}

Expand Up @@ -97,11 +97,6 @@ public List<SimpleSelector> getSelectors() {
: Collections.EMPTY_LIST;
}

private CompoundSelector() {
this(null, null);
}


@Override public Match createMatch() {
final PseudoClassState allPseudoClasses = new PseudoClassState();
int idCount = 0;
Expand All @@ -110,7 +105,7 @@ private CompoundSelector() {
for(int n=0, nMax=selectors.size(); n<nMax; n++) {
Selector sel = selectors.get(n);
Match match = sel.createMatch();
allPseudoClasses.addAll(match.pseudoClasses);
allPseudoClasses.addAll(match.getPseudoClasses());
idCount += match.idCount;
styleClassCount += match.styleClassCount;
}
Expand Down Expand Up @@ -151,7 +146,9 @@ private CompoundSelector() {
final Set<PseudoClass> pseudoClassIn = tempStates[n];

if (pseudoClassOut != null) {
pseudoClassOut.addAll(pseudoClassIn);
if (pseudoClassIn != null) {
pseudoClassOut.addAll(pseudoClassIn);
}
} else {
triggerStates[n] = pseudoClassIn;
}
Expand Down
37 changes: 21 additions & 16 deletions modules/javafx.graphics/src/main/java/javafx/css/Match.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
Expand All @@ -25,10 +25,11 @@

package javafx.css;

import com.sun.javafx.css.PseudoClassState;

import static javafx.geometry.NodeOrientation.INHERIT;

import java.util.Collections;
import java.util.Objects;
import java.util.Set;

/**
* Used by {@link Rule} to determine whether or not the selector applies to a
Expand All @@ -40,24 +41,26 @@
*/
public final class Match implements Comparable<Match> {

final Selector selector;
final PseudoClassState pseudoClasses;
final int idCount;
private final Selector selector;
private final Set<PseudoClass> pseudoClasses;

final int styleClassCount;
final int idCount;

// CSS3 spec gives weight to id count, then style class count,
// then pseudoclass count, and finally matching types (i.e., java name count)
final int specificity;

Match(final Selector selector, PseudoClassState pseudoClasses, int idCount, int styleClassCount) {
assert selector != null;
Match(final Selector selector, Set<PseudoClass> pseudoClasses, int idCount, int styleClassCount) {
Objects.requireNonNull(selector);
Objects.requireNonNull(pseudoClasses);

this.selector = selector;
this.idCount = idCount;
this.styleClassCount = styleClassCount;
this.pseudoClasses = pseudoClasses;
int nPseudoClasses = pseudoClasses != null ? pseudoClasses.size() : 0;
if (selector instanceof SimpleSelector) {
final SimpleSelector simple = (SimpleSelector)selector;
this.pseudoClasses = Collections.unmodifiableSet(pseudoClasses);
int nPseudoClasses = pseudoClasses.size();
if (selector instanceof SimpleSelector simple) {
if (simple.getNodeOrientation() != INHERIT) {
nPseudoClasses += 1;
}
Expand All @@ -67,17 +70,19 @@ public final class Match implements Comparable<Match> {

/**
* Gets the {@code Selector}.
* @return the {@code Selector}
*
* @return the {@code Selector}, never {@code null}
*/
public Selector getSelector() {
return selector;
}

/**
* Gets the pseudo class state.
* @return the pseudo class state
* Gets the pseudo class states as an immutable set.
*
* @return the pseudo class state, never {@code null}
*/
public PseudoClassState getPseudoClasses() {
public Set<PseudoClass> getPseudoClasses() {
return pseudoClasses;
}

Expand Down
Expand Up @@ -93,7 +93,8 @@ public int getOrdinal() {

/**
* Creates a {@code Match}.
* @return match
*
* @return a match, never {@code null}
*/
public abstract Match createMatch();

Expand Down

1 comment on commit 3fa02ee

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.