All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dellroad.stuff.vaadin7.PropertyDef Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2022 Archie L. Cobbs. All rights reserved.
 */

package org.dellroad.stuff.vaadin7;

import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.ui.Table;

import java.io.Serializable;
import java.util.Comparator;

/**
 * Defines a Vaadin property, having a name, which is also the property ID, and its type.
 * This class provides a mechanism for the explicit naming and identification of Vaadin properties.
 *
 * 
 * 
 * 
 *
 * 

* For a given instance, def.{@link #getPropertyId getPropertyId()} is the property ID * and you can access the value using def.{@link #read read(item)}. * *

* Example: *


 *  PropertyDef<Integer> def = new PropertyDef<Integer>("age", Integer.class, -1);
 *  def.addTo(container);
 *  def.addTo(item, property);
 *  ...
 *  int age = def.read(item);
 *  ...
 *  Property prop = this.get(container, itemId);
 * 
* *

* Instances are serializable if the default value is. * * @param property's value type */ public class PropertyDef implements Serializable { /** * Comparator that sorts instances by name. */ public static final Comparator> SORT_BY_NAME = new Comparator>() { @Override public int compare(PropertyDef p1, PropertyDef p2) { return p1.getName().compareTo(p2.getName()); } }; private static final long serialVersionUID = -8991380517167562622L; private final String name; private final Class type; private final T defaultValue; /** * Convenience contructor. * *

* Equivalent to: *

     *  PropertyDef(name, type, null);
     *  
* * @param name property name; also serves as the property ID * @param type property type * @throws IllegalArgumentException if {@code name} or {@code type} is null */ public PropertyDef(String name, Class type) { this(name, type, null); } /** * Primary constructor. * * @param name property name; also serves as the property ID * @param type property type * @param defaultValue default value for the property; may be null * @throws IllegalArgumentException if {@code name} or {@code type} is null */ public PropertyDef(String name, Class type, T defaultValue) { if (name == null) throw new IllegalArgumentException("null name"); if (type == null) throw new IllegalArgumentException("null type"); this.name = name; this.type = type; this.defaultValue = defaultValue; } /** * Get the name of this property. This is also used as the property ID. * * @return property name, never null */ public String getName() { return this.name; } /** * Get the ID of this property. Returns the same thing as {@link #getName()}. * * @return property name, never null */ public String getPropertyId() { return this.getName(); } /** * Get the type of the property value that this instance represents. * * @return property type, never null */ public Class getType() { return this.type; } /** * Get the default value for this property. * * @return property default value */ public T getDefaultValue() { return this.defaultValue; } /** * Create a simple {@link ObjectProperty} using the given value. * * @param value property value * @param readOnly whether property should be read-only * @return new property */ public ObjectProperty createProperty(T value, boolean readOnly) { return new ObjectProperty<>(value, this.getType(), readOnly); } /** * Create a read/write {@link ObjectProperty} using the given value. * *

* Equivalent to: *

     *  {@link #createProperty(Object, boolean) createProperty()}(value, false);
     *  
* * @param value property value * @return new property */ public ObjectProperty createProperty(T value) { return this.createProperty(value, false); } /** * Create a read/write {@link ObjectProperty} using the default value. * *

* Equivalent to: *

     *  {@link #createProperty(Object) createProperty()}(def.getDefaultValue());
     *  
* * @return new property */ public ObjectProperty createProperty() { return this.createProperty(this.getDefaultValue()); } /** * Get the property that this instance represents from the given {@link Item}. * * @param item item with property * @return property, or null if not found * @throws ClassCastException if the property found has a different type than this instance */ public Property get(Item item) { return this.cast(item.getItemProperty(this.getPropertyId())); } /** * Get the property that this instance represents from the given {@link Container}. * * @param container the container containing the items * @param itemId the ID of the item containing the property * @return property, or null if not found * @throws ClassCastException if the property found has a different type than this instance */ public Property get(Container container, Object itemId) { return this.cast(container.getContainerProperty(itemId, this.getPropertyId())); } /** * Verify that the given property has the same Java type as this property definition. * *

* This essentially verifies that property.getType() == this.getType(). * * @param property the property to verify; may be null * @return null if {@code property} is null, otherwise {@code property} * @throws ClassCastException if {@code property} has a different type than this definition */ @SuppressWarnings("unchecked") public Property cast(Property property) { if (property == null) return null; if (property.getType() != this.getType()) { throw new ClassCastException("property type " + property.getType().getName() + " != definition type " + this.getType().getName()); } return (Property)property; } /** * Add a property represented by this instance to the given {@link Container}. * * @param container the container to add the property to * @return true if the operation succeeded, false if not * @throws UnsupportedOperationException if the operation is not supported */ public boolean addTo(Container container) { return container.addContainerProperty(this.getPropertyId(), this.getType(), this.getDefaultValue()); } /** * Add a property represented by this instance to the given {@link Item}. * * @param item the item to add the property to * @param property the property to be added to the item and identified by this instance's name * @return true if the operation succeeded, false if not * @throws UnsupportedOperationException if the operation is not supported */ public boolean addTo(Item item, Property property) { return item.addItemProperty(this.getPropertyId(), property); } /** * Add a property represented by this instance to the given {@link Table}. * * @param table the table to add the property to * @return true if the operation succeeded, false if not * @throws UnsupportedOperationException if the operation is not supported */ public boolean addTo(Table table) { return table.addContainerProperty(this.getPropertyId(), this.getType(), this.getDefaultValue()); } /** * Read the property that this instance represents from the given {@link Item}. * * @param item item with property * @return property value, or null if not found * @throws ClassCastException if the property in {@code item} has the wrong type */ public T read(Item item) { Property property = this.get(item); if (property == null) return null; return this.type.cast(property.getValue()); } /** * Determine whether this instance supports sorting property values. * *

* The implementation in {@link PropertyDef} returns true if this instance's type implements {@link Comparable}. * * @return true if this instance supports sorting property values * @see #sort sort() */ public boolean isSortable() { return Comparable.class.isAssignableFrom(this.type); } /** * Sort two values of this property. Optional operation. * *

* The implementation in {@link PropertyDef} sorts null values first, then delegates to {@link Comparable} * if the values implement it, or else throws {@link UnsupportedOperationException}. * * @param value1 first value, possibly null * @param value2 second value, possibly null * @return negative, zero, or positive based on comparing {@code value1} to {@code value2} * @throws UnsupportedOperationException if this instance does not support sorting property values */ @SuppressWarnings({ "unchecked", "null" }) public int sort(T value1, T value2) { if ((value1 == null) != (value2 == null)) return value1 == null ? -1 : 1; if (value1 == null && value2 == null) return 0; try { return ((Comparable)value1).compareTo(value2); } catch (ClassCastException e) { throw new UnsupportedOperationException(e); } } @Override public int hashCode() { return this.name.hashCode() ^ this.type.hashCode() ^ (this.defaultValue != null ? this.defaultValue.hashCode() : 0); } @Override public boolean equals(Object obj) { if (obj == null || obj.getClass() != this.getClass()) return false; final PropertyDef that = (PropertyDef)obj; return this.name.equals(that.name) && this.type == that.type && (this.defaultValue != null ? this.defaultValue.equals(that.defaultValue) : that.defaultValue == null); } @Override public String toString() { return this.getClass().getSimpleName() + "[name=\"" + this.name + "\",type=" + this.type.getName() + ",defaultValue=" + this.defaultValue + "]"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy