ObjectProperty.java
package space.sunqian.common.object.data;
import space.sunqian.annotations.Immutable;
import space.sunqian.annotations.Nonnull;
import space.sunqian.annotations.Nullable;
import space.sunqian.common.invoke.Invocable;
/**
* This interface represents the property info of {@link ObjectSchema}. It is very similar to the simple property of
* <a href="https://www.oracle.com/java/technologies/javase/javabeans-spec.html">JavaBeans</a>.
* <p>
* Two {@link ObjectProperty}s are considered equal if, and only if both their names and both their owners are equal.
*
* @author sunqian
*/
@Immutable
public interface ObjectProperty extends ObjectPropertyBase {
/**
* Returns the owner {@link ObjectSchema} of this property.
*
* @return the owner {@link ObjectSchema} of this property
*/
@Nonnull
ObjectSchema owner();
/**
* Returns whether this property is readable.
*
* @return whether this property is readable
*/
default boolean isReadable() {
return getter() != null;
}
/**
* Returns whether this property is writable.
*
* @return whether this property is writable
*/
default boolean isWritable() {
return setter() != null;
}
/**
* Returns the property value of the specified instance.
*
* @param inst the specified instance
* @return the property value of the specified instance
* @throws DataObjectException if this property is not readable
*/
default @Nullable Object getValue(@Nonnull Object inst) throws DataObjectException {
Invocable getter = getter();
if (getter == null) {
throw new DataObjectException("The property is not readable: " + name() + ".");
}
return getter.invoke(inst);
}
/**
* Sets the property value of the specified instance.
*
* @param inst the specified instance
* @param value the property value
* @throws DataObjectException if this property is not writable
*/
default void setValue(@Nonnull Object inst, @Nullable Object value) throws DataObjectException {
Invocable setter = setter();
if (setter == null) {
throw new DataObjectException("The property is not writable: " + name() + ".");
}
setter.invoke(inst, value);
}
/**
* Returns whether this {@link ObjectProperty} is equal to the other {@link ObjectProperty}. They are considered
* equal if, and only if both their names and both their owners are equal.
*
* @param other the other {@link ObjectProperty}
* @return whether this {@link ObjectProperty} is equal to the other {@link ObjectProperty}
*/
boolean equals(Object other);
/**
* Returns the hash code of this {@link ObjectProperty}. The hash code is generated via {@link #name()} and
* {@link #owner()} like following codes:
* <pre>{@code
* int result = 1;
* result = 31 * result + name().hashCode();
* result = 31 * result + owner().hashCode();
* return result;
* }</pre>
*
* @return the hash code of this {@link ObjectProperty}
*/
int hashCode();
/**
* Returns a string representation of this {@link ObjectProperty}. The string is generated like following codes:
* <pre>{@code
* return name() + ": " + type().getTypeName();
* }</pre>
*
* @return a string representation of this {@link ObjectProperty}
*/
@Nonnull
String toString();
}