/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.extension.properties; import static org.teiid.designer.extension.ExtensionPlugin.Util; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.concurrent.CopyOnWriteArrayList; import org.teiid.core.designer.properties.Property; import org.teiid.core.designer.properties.PropertyDefinition; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.CoreStringUtil; /** * A <code>ModelExtensionProperty</code> is a model extension property that may have an overridden value. * * @since 8.0 */ public class ModelExtensionProperty implements Property { /** * A collection of registered property changed listeners. */ private final CopyOnWriteArrayList<PropertyChangeListener> listeners; /** * A non-<code>null</code> value if the value is different than the default value. */ private String overriddenValue; /** * The property definition (never <code>null</code>). */ private final ModelExtensionPropertyDefinition propDefn; /** * The initial value is set to the default value. * * @param propDefn the property definition (cannot be <code>null</code>) * @throws IllegalArgumentException if <code>propDefn</code> is <code>null</code> */ public ModelExtensionProperty( ModelExtensionPropertyDefinition propDefn ) { CoreArgCheck.isNotNull(propDefn, "propDef is null"); //$NON-NLS-1$ this.propDefn = propDefn; this.listeners = new CopyOnWriteArrayList<PropertyChangeListener>(); } /** * @param propDefn the property definition (cannot be <code>null</code>) * @param initialValue the initial property value (can be <code>null</code> or empty) */ public ModelExtensionProperty( ModelExtensionPropertyDefinition propDefn, String initialValue ) { this(propDefn); setValue(initialValue); } /** * @param listener the listener being added (cannot be <code>null</code>) * @return <code>true</code> if the listener was successfully added */ public boolean addListener( PropertyChangeListener listener ) { CoreArgCheck.isNotNull(listener, "listener is null"); //$NON-NLS-1$ return this.listeners.addIfAbsent(listener); } /** * {@inheritDoc} * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals( Object obj ) { if (this == obj) { return true; } if (obj == null) { return false; } if (!getClass().equals(obj.getClass())) { return false; } return this.propDefn.getId().equals(((ModelExtensionProperty)obj).getPropertyDefinition().getId()); } /** * @return the property definition's identifier which includes the namespace prefix and the simple property identifier (never * <code>null</code>) */ public String getId() { return this.propDefn.getId(); } /** * @return the model extension property definition (never <code>null</code>) */ public ModelExtensionPropertyDefinition getModelExtensionPropertyDefinition() { return this.propDefn; } /** * {@inheritDoc} * <p> * This returns a {@link ModelExtensionPropertyDefinition}. * * @see org.teiid.core.designer.properties.Property#getPropertyDefinition() */ @Override public PropertyDefinition getPropertyDefinition() { return this.propDefn; } /** * {@inheritDoc} * * @see org.teiid.core.designer.properties.Property#getValue() */ @Override public String getValue() { return (CoreStringUtil.isEmpty(this.overriddenValue) ? getPropertyDefinition().getDefaultValue() : this.overriddenValue); } /** * {@inheritDoc} * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return getPropertyDefinition().getId().hashCode(); } /** * @return <code>true</code> if the current value is different than the default value */ public boolean hasOverridenValue() { return (this.overriddenValue != null); } /** * Broadcasts property change to registered listeners. * * @param oldValue the old value (can be <code>null</code> or empty) * @param newValue the new value (can be <code>null</code> or empty) */ private void notifyChangeListeners( final Object oldValue, final Object newValue ) { PropertyChangeEvent event = new PropertyChangeEvent(this, this.propDefn.getId(), oldValue, newValue); for (final Object listener : this.listeners.toArray()) { try { ((PropertyChangeListener)listener).propertyChange(event); } catch (Exception e) { Util.log(e); this.listeners.remove(listener); } } } /** * @param listener the listener being removed (cannot be <code>null</code>) * @return <code>true</code> if listener was successfully removed */ public boolean removeListener( PropertyChangeListener listener ) { CoreArgCheck.isNotNull(listener, "listener is null"); //$NON-NLS-1$ return this.listeners.remove(listener); } /** * @param newValue the new property value (can be <code>null</code> or empty) */ public void setValue( String newValue ) { String oldValue = getValue(); // do nothing if setting to same value if (CoreStringUtil.equals(oldValue, newValue)) { return; } if (CoreStringUtil.equals(newValue, getPropertyDefinition().getDefaultValue())) { // make sure overriddenValue is null when setting to default value this.overriddenValue = null; } else { this.overriddenValue = newValue; } // alert listeners notifyChangeListeners(oldValue, getValue()); } /** * The properties that can be changed. */ public enum PropertyName { /** * The property definition. */ PROPERTY_DEFINITION, /** * The property value. */ VALUE } }