diff --git a/src/java.desktop/share/classes/java/beans/ChangeListenerMap.java b/src/java.desktop/share/classes/java/beans/ChangeListenerMap.java index 00c8ccdd5fcf7..ef05069982426 100644 --- a/src/java.desktop/share/classes/java/beans/ChangeListenerMap.java +++ b/src/java.desktop/share/classes/java/beans/ChangeListenerMap.java @@ -25,7 +25,10 @@ package java.beans; import org.checkerframework.checker.interning.qual.UsesObjectEquals; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; import java.util.ArrayList; import java.util.Collections; @@ -47,9 +50,10 @@ * * @author Sergey A. Malenkov */ -@AnnotatedFor({"interning"}) +@CFComment("nullness: null values are permitted for property names, though not documented in Javadoc") +@AnnotatedFor({"interning", "nullness"}) abstract @UsesObjectEquals class ChangeListenerMap { - private Map map; + private @MonotonicNonNull Map<@Nullable String, L[]> map; /** * Creates an array of listeners. @@ -78,7 +82,7 @@ * @param name the name of the property to listen on * @param listener the listener to process events */ - public final synchronized void add(String name, L listener) { + public final synchronized void add(@Nullable String name, L listener) { if (this.map == null) { this.map = new HashMap<>(); } @@ -103,7 +107,7 @@ public final synchronized void add(String name, L listener) { * @param name the name of the property to listen on * @param listener the listener to process events */ - public final synchronized void remove(String name, L listener) { + public final synchronized void remove(@Nullable String name, L listener) { if (this.map != null) { L[] array = this.map.get(name); if (array != null) { @@ -135,7 +139,7 @@ public final synchronized void remove(String name, L listener) { * @param name the name of the property * @return the corresponding list of listeners */ - public final synchronized L[] get(String name) { + public final synchronized L[] get(@Nullable String name) { return (this.map != null) ? this.map.get(name) : null; @@ -147,7 +151,7 @@ public final synchronized L[] get(String name) { * @param name the name of the property * @param listeners new list of listeners */ - public final void set(String name, L[] listeners) { + public final void set(@Nullable String name, @Nullable L[] listeners) { if (listeners != null) { if (this.map == null) { this.map = new HashMap<>(); @@ -196,7 +200,7 @@ public final synchronized L[] getListeners() { * @param name the name of the property * @return an array of listeners for the named property */ - public final L[] getListeners(String name) { + public final L[] getListeners(@Nullable String name) { if (name != null) { L[] listeners = get(name); if (listeners != null) { @@ -214,7 +218,7 @@ public final L[] getListeners(String name) { * @return {@code true} if at least one listener exists or * {@code false} otherwise */ - public final synchronized boolean hasListeners(String name) { + public final synchronized boolean hasListeners(@Nullable String name) { if (this.map == null) { return false; } diff --git a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java index 983dd8100797a..abf3cb1f609f3 100644 --- a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java +++ b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java @@ -25,6 +25,10 @@ package java.beans; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; + import java.io.Serial; /** @@ -43,6 +47,9 @@ * @since 1.5 * @author Mark Davidson */ +@AnnotatedFor({"nullness"}) +@CFComment({"nullness: don't permit null property name, class documentation may ", + "be a typo caused by cut-and-paste from PropertyChangeEvent"}) public class IndexedPropertyChangeEvent extends PropertyChangeEvent { /** @@ -67,7 +74,7 @@ public class IndexedPropertyChangeEvent extends PropertyChangeEvent { * @param index index of the property element that was changed. */ public IndexedPropertyChangeEvent(Object source, String propertyName, - Object oldValue, Object newValue, + @Nullable Object oldValue, @Nullable Object newValue, int index) { super (source, propertyName, oldValue, newValue); this.index = index; diff --git a/src/java.desktop/share/classes/java/beans/PropertyChangeEvent.java b/src/java.desktop/share/classes/java/beans/PropertyChangeEvent.java index 1badd4bc72a34..aaf5ffb1bb08a 100644 --- a/src/java.desktop/share/classes/java/beans/PropertyChangeEvent.java +++ b/src/java.desktop/share/classes/java/beans/PropertyChangeEvent.java @@ -28,6 +28,9 @@ import java.io.Serial; import java.util.EventObject; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.AnnotatedFor; + /** * A "PropertyChange" event gets delivered whenever a bean changes a "bound" * or "constrained" property. A PropertyChangeEvent object is sent as an @@ -47,6 +50,7 @@ * * @since 1.1 */ +@AnnotatedFor({"nullness"}) public class PropertyChangeEvent extends EventObject { /** @@ -65,8 +69,8 @@ public class PropertyChangeEvent extends EventObject { * * @throws IllegalArgumentException if {@code source} is {@code null} */ - public PropertyChangeEvent(Object source, String propertyName, - Object oldValue, Object newValue) { + public PropertyChangeEvent(Object source, @Nullable String propertyName, + @Nullable Object oldValue, @Nullable Object newValue) { super(source); this.propertyName = propertyName; this.newValue = newValue; @@ -79,7 +83,7 @@ public PropertyChangeEvent(Object source, String propertyName, * @return The programmatic name of the property that was changed. * May be null if multiple properties have changed. */ - public String getPropertyName() { + public @Nullable String getPropertyName() { return propertyName; } @@ -89,7 +93,7 @@ public String getPropertyName() { * @return The new value for the property, expressed as an Object. * May be null if multiple properties have changed. */ - public Object getNewValue() { + public @Nullable Object getNewValue() { return newValue; } @@ -99,7 +103,7 @@ public Object getNewValue() { * @return The old value for the property, expressed as an Object. * May be null if multiple properties have changed. */ - public Object getOldValue() { + public @Nullable Object getOldValue() { return oldValue; } @@ -108,7 +112,7 @@ public Object getOldValue() { * * @param propagationId The propagationId object for the event. */ - public void setPropagationId(Object propagationId) { + public void setPropagationId(@Nullable Object propagationId) { this.propagationId = propagationId; } @@ -122,7 +126,7 @@ public void setPropagationId(Object propagationId) { * @return the propagationId object associated with a bound/constrained * property update. */ - public Object getPropagationId() { + public @Nullable Object getPropagationId() { return propagationId; } @@ -130,21 +134,21 @@ public Object getPropagationId() { * name of the property that changed. May be null, if not known. * @serial */ - private String propertyName; + private @Nullable String propertyName; /** * New value for property. May be null if not known. * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable - private Object newValue; + private @Nullable Object newValue; /** * Previous value for property. May be null if not known. * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable - private Object oldValue; + private @Nullable Object oldValue; /** * Propagation ID. May be null. @@ -152,7 +156,7 @@ public Object getPropagationId() { * @see #getPropagationId */ @SuppressWarnings("serial") // Not statically typed as Serializable - private Object propagationId; + private @Nullable Object propagationId; /** * Returns a string representation of the object. diff --git a/src/java.desktop/share/classes/java/beans/PropertyChangeSupport.java b/src/java.desktop/share/classes/java/beans/PropertyChangeSupport.java index fefe9c81bc3ff..9167d20e058ee 100644 --- a/src/java.desktop/share/classes/java/beans/PropertyChangeSupport.java +++ b/src/java.desktop/share/classes/java/beans/PropertyChangeSupport.java @@ -265,7 +265,7 @@ public void addPropertyChangeListener( * returned. * @since 1.4 */ - @PolyUIEffect public @PolyUI PropertyChangeListener[] getPropertyChangeListeners(@PolyUI PropertyChangeSupport this, String propertyName) { + @PolyUIEffect public @PolyUI PropertyChangeListener[] getPropertyChangeListeners(@PolyUI PropertyChangeSupport this, @Nullable String propertyName) { return this.map.getListeners(propertyName); } @@ -283,7 +283,7 @@ public void addPropertyChangeListener( * @param oldValue the old value of the property * @param newValue the new value of the property */ - @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, String propertyName, @Nullable @FenumTop Object oldValue, @Nullable @FenumTop Object newValue) { + @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, @Nullable String propertyName, @Nullable @FenumTop Object oldValue, @Nullable @FenumTop Object newValue) { if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); } @@ -304,7 +304,7 @@ public void addPropertyChangeListener( * @param newValue the new value of the property * @since 1.2 */ - @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, String propertyName, @FenumTop int oldValue, @FenumTop int newValue) { + @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, @Nullable String propertyName, @FenumTop int oldValue, @FenumTop int newValue) { if (oldValue != newValue) { firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); } @@ -325,7 +325,7 @@ public void addPropertyChangeListener( * @param newValue the new value of the property * @since 1.2 */ - @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, String propertyName, boolean oldValue, boolean newValue) { + @PolyUIEffect public void firePropertyChange(@PolyUI PropertyChangeSupport this, @Nullable String propertyName, boolean oldValue, boolean newValue) { if (oldValue != newValue) { firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); } diff --git a/src/java.desktop/share/classes/java/beans/VetoableChangeSupport.java b/src/java.desktop/share/classes/java/beans/VetoableChangeSupport.java index f015236edf247..bce0a2ca62ec6 100644 --- a/src/java.desktop/share/classes/java/beans/VetoableChangeSupport.java +++ b/src/java.desktop/share/classes/java/beans/VetoableChangeSupport.java @@ -26,6 +26,7 @@ package java.beans; import org.checkerframework.checker.interning.qual.UsesObjectEquals; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.AnnotatedFor; import java.io.IOException; @@ -84,7 +85,7 @@ * @see PropertyChangeSupport * @since 1.1 */ -@AnnotatedFor({"interning"}) +@AnnotatedFor({"interning", "nullness"}) public @UsesObjectEquals class VetoableChangeSupport implements Serializable { private VetoableChangeListenerMap map = new VetoableChangeListenerMap(); @@ -110,7 +111,7 @@ public VetoableChangeSupport(Object sourceBean) { * * @param listener The VetoableChangeListener to be added */ - public void addVetoableChangeListener(VetoableChangeListener listener) { + public void addVetoableChangeListener(@Nullable VetoableChangeListener listener) { if (listener == null) { return; } @@ -136,7 +137,7 @@ public void addVetoableChangeListener(VetoableChangeListener listener) { * * @param listener The VetoableChangeListener to be removed */ - public void removeVetoableChangeListener(VetoableChangeListener listener) { + public void removeVetoableChangeListener(@Nullable VetoableChangeListener listener) { if (listener == null) { return; } @@ -201,8 +202,8 @@ public VetoableChangeListener[] getVetoableChangeListeners(){ * @since 1.2 */ public void addVetoableChangeListener( - String propertyName, - VetoableChangeListener listener) { + @Nullable String propertyName, + @Nullable VetoableChangeListener listener) { if (listener == null || propertyName == null) { return; } @@ -227,8 +228,8 @@ public void addVetoableChangeListener( * @since 1.2 */ public void removeVetoableChangeListener( - String propertyName, - VetoableChangeListener listener) { + @Nullable String propertyName, + @Nullable VetoableChangeListener listener) { if (listener == null || propertyName == null) { return; } @@ -249,7 +250,7 @@ public void removeVetoableChangeListener( * returned. * @since 1.4 */ - public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) { + public VetoableChangeListener[] getVetoableChangeListeners(@Nullable String propertyName) { return this.map.getListeners(propertyName); } @@ -274,7 +275,7 @@ public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) * @param newValue the new value of the property * @throws PropertyVetoException if one of listeners vetoes the property update */ - public void fireVetoableChange(String propertyName, Object oldValue, Object newValue) + public void fireVetoableChange(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue) throws PropertyVetoException { if (oldValue == null || newValue == null || !oldValue.equals(newValue)) { fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue)); @@ -303,7 +304,7 @@ public void fireVetoableChange(String propertyName, Object oldValue, Object newV * @throws PropertyVetoException if one of listeners vetoes the property update * @since 1.2 */ - public void fireVetoableChange(String propertyName, int oldValue, int newValue) + public void fireVetoableChange(@Nullable String propertyName, int oldValue, int newValue) throws PropertyVetoException { if (oldValue != newValue) { fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue)); @@ -332,7 +333,7 @@ public void fireVetoableChange(String propertyName, int oldValue, int newValue) * @throws PropertyVetoException if one of listeners vetoes the property update * @since 1.2 */ - public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue) + public void fireVetoableChange(@Nullable String propertyName, boolean oldValue, boolean newValue) throws PropertyVetoException { if (oldValue != newValue) { fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); @@ -413,7 +414,7 @@ else if (named == null) { * @return true if there are one or more listeners for the given property * @since 1.2 */ - public boolean hasListeners(String propertyName) { + public boolean hasListeners(@Nullable String propertyName) { return this.map.hasListeners(propertyName); }