[Index]

Property Listeners


A Property has a list of PropertyChangeListener.
public interface PropertyChangeListener extends Serializable {
	public String getId();
	public void changeSuccessfull(Property<?> property,String beforeValue,String afterValue) throws PropertyException;	
	public void changeFailed(Property<?> property,String currentValue,String failedValue,PropertyException exception);
}
Which is executed to perform action after an change of Property has been attempted.

Each PropertyChangeListener is identified with an ID and a Property can not have multiple PropertyChangeListeners with the same ID.

A PropertyChangeListener has two methods:
  • public void changeSuccessfull(Property<?> property,String beforeValue,String afterValue) throws PropertyException;
  • public void changeFailed(Property<?> property,String currentValue,String failedValue,PropertyException exception);
The two method is executed in the order they are added, after what scenario occurs.


PropertyCollections
To the PropertyCollection interface there have been added 3 methods on Collections.
  • public void addPropertyChangeListener(PropertyChangeListener listener) throws NullPointerException; - Which adds a PropertyChangeListener instance to all registered Properties.
  • public void removePropertyChangeListener(PropertyChangeListener listener) throws NullPointerException; - Which removes a PropertyChangeListener instance to all registered Properties.
  • public void removeAllPropertyChangeListeners(); - Which removes all PropertyChangeListener from all registered Properties.

The two implementations of PropertyCollection has the following rules when constructed.

PropertyStaticCollection - Where a LoggingPropertyChangeListener instance is added per default at construction time.

PropertyListCollection - Where NO PropertyChangeListeners is added per default.



Implementations
There are currently two implementations of PropertyChangeListener.

LoggingPropertyChangeListener - which write a log message if the change is successful or not.
//Actual implementation
public class LoggingPropertyChangeListener implements PropertyChangeListener {
	public LoggingPropertyChangeListener() {
		super();
	}
	@Override
	public String getId() {		
		return getClass().getSimpleName();
	}
	@Override
	public void changeSuccessfull(Property property, String beforeValue,String afterValue) {		
		property.getLogger().info("Property ["+property.getName()+"] has been changed from ["+beforeValue+"] to ["+afterValue+"].");
	}
	
	@Override
	public void changeFailed(Property property, String currentValue,String failedValue, PropertyException exception) {
		property.getLogger().error("Property ["+property.getName()+"] was NOT change from ["+currentValue+"] to ["+failedValue+"] it failed with ["+exception.getMessage()+"].",exception);		
	}
}


UpdateLastChangedPropertyChangeListener - Which updates a Property of type Date with "new Date()" if another Property is changed successfully.
This can typical be used to change a "my.password.last.changed" property when a "my.password" is actually sucessfully changed".
It overrides the readonly restrictions (if any) on the Property "my.password.last.changed", because this property will usually be readonly.
//Actual implementation
public class UpdateLastChangedPropertyChangeListener implements PropertyChangeListener {

	private Property<Date> dateProperty;

	public UpdateLastChangedPropertyChangeListener(Property<Date> dateProperty) {
		super();
		this.dateProperty=dateProperty;
	}
	@Override
	public String getId() {
		return getClass().getSimpleName();
	}
	
	public Property<Date> getDateProperty() {
		return dateProperty;
	}
	@Override
	public void changeSuccessfull(Property<?> property, String beforeValue,String afterValue) {
		if (getDateProperty()!=null) {
			boolean p_readonly = getDateProperty().isReadonly();
			if (p_readonly) {
				getDateProperty().setReadonly(false);
			}			
			try {
				getDateProperty().setTypedValue(new Date());
			} catch (PropertyException e) {
				getDateProperty().getLogger().error("Can not change ["+getDateProperty().getName()+"] property timestamp when Property ["+property.getName()+"] was updated, reason ["+e.getMessage()+"].",e);
			}
			if (p_readonly!=getDateProperty().isReadonly()) {
				getDateProperty().setReadonly(p_readonly);
			}
		}
	}
	@Override
	public void changeFailed(Property<?> property, String currentValue,String failedValue, PropertyException exception) {
		property.getLogger().error("Property ["+property.getName()+"] was NOT change from ["+currentValue+"] to ["+failedValue+"] it failed with ["+exception.getMessage()+"].",exception);
	}
}

Where the usages will be
Property<PasswordTypeVO> MY_APP_PASSWORD_PROPERTY = new Property<PasswordTypeVO>("name", new PasswordPropertyType(new AESEncryption()));
Property<Date> MY_APP_PASSWORD_LAST_CHANGED = new Property<Date>("my.app.password.last.changed", new DateTimePropertyType(new Date(0)),false,true);
//
UpdateLastChangedPropertyChangeListener updateListener = new UpdateLastChangedPropertyChangeListener(MY_APP_PASSWORD_LAST_CHANGED);
MY_APP_PASSWORD_PROPERTY.addPropertyChangeListener(updateListener);