/******************************************************************************* * Copyright (c) 2009, 2010 Fraunhofer IWU and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Fraunhofer IWU - initial API and implementation *******************************************************************************/ package net.enilink.komma.common.notify; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * An extensible notification implementation. */ public class PropertyNotification implements IPropertyNotification, INotificationChain { /** * An {@link #primitiveType indicator} that the feature is not a primitive * type. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_OBJECT = -1; /** * An {@link #primitiveType indicator} that the feature is a * <code>boolean</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_BOOLEAN = 0; /** * An {@link #primitiveType indicator} that the feature is a * <code>byte</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_BYTE = 1; /** * An {@link #primitiveType indicator} that the feature is a * <code>char</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_CHAR = 2; /** * An {@link #primitiveType indicator} that the feature is a * <code>double</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_DOUBLE = 3; /** * An {@link #primitiveType indicator} that the feature is a * <code>float</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_FLOAT = 4; /** * An {@link #primitiveType indicator} that the feature is a * <code>int</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_INT = 5; /** * An {@link #primitiveType indicator} that the feature is a * <code>long</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_LONG = 6; /** * An {@link #primitiveType indicator} that the feature is a * <code>short</code>. * * @see #primitiveType */ public static final int PRIMITIVE_TYPE_SHORT = 7; /** * A {@link #position position} value which indicates that {@link #isTouch} * should return <code>false</code>. * * @see #primitiveType */ protected static final int IS_SET_CHANGE_INDEX = NO_INDEX - 1; /** * The type of the feature. * * @see #PRIMITIVE_TYPE_OBJECT * @see #PRIMITIVE_TYPE_BOOLEAN * @see #PRIMITIVE_TYPE_BYTE * @see #PRIMITIVE_TYPE_CHAR * @see #PRIMITIVE_TYPE_DOUBLE * @see #PRIMITIVE_TYPE_FLOAT * @see #PRIMITIVE_TYPE_INT * @see #PRIMITIVE_TYPE_LONG * @see #PRIMITIVE_TYPE_SHORT */ protected int primitiveType; /** * The type of the change. * * @see #getEventType() */ protected int eventType; /** * The old value for the case of {@link #PRIMITIVE_TYPE_OBJECT}. * * @see #getOldValue() */ protected Object oldValue; /** * The new value for the case of {@link #PRIMITIVE_TYPE_OBJECT}. * * @see #getNewValue() */ protected Object newValue; /** * The old value for the case of {@link #PRIMITIVE_TYPE_BOOLEAN}, * {@link #PRIMITIVE_TYPE_BYTE}, {@link #PRIMITIVE_TYPE_CHAR}, * {@link #PRIMITIVE_TYPE_INT}, {@link #PRIMITIVE_TYPE_LONG}, and * {@link #PRIMITIVE_TYPE_SHORT}. * * @see #getOldValue() * @see #getOldBooleanValue() * @see #getOldByteValue() * @see #getOldCharValue() * @see #getOldIntValue() * @see #getOldLongValue() * @see #getOldShortValue() */ protected long oldSimplePrimitiveValue; /** * The new value for the case of {@link #PRIMITIVE_TYPE_BOOLEAN}, * {@link #PRIMITIVE_TYPE_BYTE}, {@link #PRIMITIVE_TYPE_CHAR}, * {@link #PRIMITIVE_TYPE_INT}, {@link #PRIMITIVE_TYPE_LONG}, and * {@link #PRIMITIVE_TYPE_SHORT}. * * @see #getNewValue() * @see #getNewBooleanValue() * @see #getNewByteValue() * @see #getNewCharValue() * @see #getNewIntValue() * @see #getNewLongValue() * @see #getNewShortValue() */ protected long newSimplePrimitiveValue; /** * The old value for the case of {@link #PRIMITIVE_TYPE_DOUBLE}, and * {@link #PRIMITIVE_TYPE_FLOAT}. * * @see #getOldValue() * @see #getOldDoubleValue() * @see #getOldFloatValue() */ protected double oldIEEEPrimitiveValue; /** * The old value for the case of {@link #PRIMITIVE_TYPE_DOUBLE}, and * {@link #PRIMITIVE_TYPE_FLOAT}. * * @see #getOldValue() * @see #getOldDoubleValue() * @see #getOldFloatValue() */ protected double newIEEEPrimitiveValue; /** * The position. * * @see #getPosition() */ protected int position; /** * The internal chain. */ protected INotificationChain chain; protected Object property; protected Object source; /** * Creates an instance. * * @param eventType * the type of the change. * @param oldValue * the old value before the change. * @param newValue * the new value after the change. */ public PropertyNotification(int eventType, Object oldValue, Object newValue) { this(eventType, oldValue, newValue, NO_INDEX); } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldValue * the old value before the change. * @param newValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, Object oldValue, Object newValue, boolean isSetChange) { this(eventType, oldValue, newValue, isSetChange ? IS_SET_CHANGE_INDEX : NO_INDEX); } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldValue * the old value before the change. * @param newValue * the new value after the change. */ public PropertyNotification(int eventType, Object oldValue, Object newValue, int position) { this.eventType = eventType; this.oldValue = oldValue; this.newValue = newValue; this.position = position; this.primitiveType = PRIMITIVE_TYPE_OBJECT; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldValue * the old value before the change. * @param newValue * the new value after the change. * @param wasSet * whether the feature was set before the change. */ public PropertyNotification(int eventType, Object oldValue, Object newValue, int position, boolean wasSet) { this.eventType = eventType; this.oldValue = oldValue; this.newValue = newValue; this.position = position; this.primitiveType = PRIMITIVE_TYPE_OBJECT; if (!wasSet) { this.position = IS_SET_CHANGE_INDEX - position - 1; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldBooleanValue * the old value before the change. * @param newBooleanValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, boolean oldBooleanValue, boolean newBooleanValue, boolean isSetChange) { this(eventType, oldBooleanValue, newBooleanValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldBooleanValue * the old value before the change. * @param newBooleanValue * the new value after the change. */ public PropertyNotification(int eventType, boolean oldBooleanValue, boolean newBooleanValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldBooleanValue ? 1 : 0; this.newSimplePrimitiveValue = newBooleanValue ? 1 : 0; this.position = NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_BOOLEAN; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldByteValue * the old value before the change. * @param newByteValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, byte oldByteValue, byte newByteValue, boolean isSetChange) { this(eventType, oldByteValue, newByteValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldByteValue * the old value before the change. * @param newByteValue * the new value after the change. */ public PropertyNotification(int eventType, byte oldByteValue, byte newByteValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldByteValue; this.newSimplePrimitiveValue = newByteValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_BYTE; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldCharValue * the old value before the change. * @param newCharValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, char oldCharValue, char newCharValue, boolean isSetChange) { this(eventType, oldCharValue, newCharValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldCharValue * the old value before the change. * @param newCharValue * the new value after the change. */ public PropertyNotification(int eventType, char oldCharValue, char newCharValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldCharValue; this.newSimplePrimitiveValue = newCharValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_CHAR; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldDoubleValue * the old value before the change. * @param newDoubleValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, double oldDoubleValue, double newDoubleValue, boolean isSetChange) { this(eventType, oldDoubleValue, newDoubleValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldDoubleValue * the old value before the change. * @param newDoubleValue * the new value after the change. */ public PropertyNotification(int eventType, double oldDoubleValue, double newDoubleValue) { this.eventType = eventType; this.oldIEEEPrimitiveValue = oldDoubleValue; this.newIEEEPrimitiveValue = newDoubleValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_DOUBLE; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldFloatValue * the old value before the change. * @param newFloatValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, float oldFloatValue, float newFloatValue, boolean isSetChange) { this(eventType, oldFloatValue, newFloatValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldFloatValue * the old value before the change. * @param newFloatValue * the new value after the change. */ public PropertyNotification(int eventType, float oldFloatValue, float newFloatValue) { this.eventType = eventType; this.oldIEEEPrimitiveValue = oldFloatValue; this.newIEEEPrimitiveValue = newFloatValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_FLOAT; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldIntValue * the old value before the change. * @param newIntValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, int oldIntValue, int newIntValue, boolean isSetChange) { this(eventType, oldIntValue, newIntValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldIntValue * the old value before the change. * @param newIntValue * the new value after the change. */ public PropertyNotification(int eventType, int oldIntValue, int newIntValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldIntValue; this.newSimplePrimitiveValue = newIntValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_INT; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldLongValue * the old value before the change. * @param newLongValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, long oldLongValue, long newLongValue, boolean isSetChange) { this(eventType, oldLongValue, newLongValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldLongValue * the old value before the change. * @param newLongValue * the new value after the change. */ public PropertyNotification(int eventType, long oldLongValue, long newLongValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldLongValue; this.newSimplePrimitiveValue = newLongValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_LONG; } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldShortValue * the old value before the change. * @param newShortValue * the new value after the change. * @param isSetChange * the indication of whether the state has changed. */ public PropertyNotification(int eventType, short oldShortValue, short newShortValue, boolean isSetChange) { this(eventType, oldShortValue, newShortValue); if (isSetChange) { this.position = IS_SET_CHANGE_INDEX; } } /** * Creates an instance. * * @param eventType * the type of the change. * @param oldShortValue * the old value before the change. * @param newShortValue * the new value after the change. */ public PropertyNotification(int eventType, short oldShortValue, short newShortValue) { this.eventType = eventType; this.oldSimplePrimitiveValue = oldShortValue; this.newSimplePrimitiveValue = newShortValue; this.position = PropertyNotification.NO_INDEX; this.primitiveType = PRIMITIVE_TYPE_SHORT; } public PropertyNotification setSource(Object source) { this.source = source; return this; } public Object getSubject() { return null; } public int getEventType() { return eventType; } public PropertyNotification setProperty(Object property) { this.property = property; return this; } public Object getProperty() { return null; } public Object getOldValue() { if (oldValue == null) { switch (primitiveType) { case PRIMITIVE_TYPE_BOOLEAN: oldValue = getOldBooleanValue() ? Boolean.TRUE : Boolean.FALSE; break; case PRIMITIVE_TYPE_BYTE: oldValue = getOldByteValue(); break; case PRIMITIVE_TYPE_CHAR: oldValue = getOldCharValue(); break; case PRIMITIVE_TYPE_DOUBLE: oldValue = getOldDoubleValue(); break; case PRIMITIVE_TYPE_FLOAT: oldValue = getOldFloatValue(); break; case PRIMITIVE_TYPE_LONG: oldValue = getOldLongValue(); break; case PRIMITIVE_TYPE_INT: oldValue = getOldIntValue(); break; case PRIMITIVE_TYPE_SHORT: oldValue = getOldShortValue(); break; } } return oldValue; } public Object getNewValue() { if (newValue == null) { switch (primitiveType) { case PRIMITIVE_TYPE_BOOLEAN: newValue = getNewBooleanValue() ? Boolean.TRUE : Boolean.FALSE; break; case PRIMITIVE_TYPE_BYTE: newValue = getNewByteValue(); break; case PRIMITIVE_TYPE_CHAR: newValue = getNewCharValue(); break; case PRIMITIVE_TYPE_DOUBLE: newValue = getNewDoubleValue(); break; case PRIMITIVE_TYPE_FLOAT: newValue = getNewFloatValue(); break; case PRIMITIVE_TYPE_LONG: newValue = getNewLongValue(); break; case PRIMITIVE_TYPE_INT: newValue = getNewIntValue(); break; case PRIMITIVE_TYPE_SHORT: newValue = getNewShortValue(); break; } } return newValue; } public boolean isTouch() { switch (eventType) { case PropertyNotification.RESOLVE: case PropertyNotification.REMOVING_ADAPTER: { return true; } case PropertyNotification.ADD: case PropertyNotification.ADD_MANY: case PropertyNotification.REMOVE: case PropertyNotification.REMOVE_MANY: case PropertyNotification.MOVE: { return false; } case PropertyNotification.SET: case PropertyNotification.UNSET: { if (position == IS_SET_CHANGE_INDEX) { return false; } else { switch (primitiveType) { case PRIMITIVE_TYPE_BOOLEAN: case PRIMITIVE_TYPE_BYTE: case PRIMITIVE_TYPE_CHAR: case PRIMITIVE_TYPE_LONG: case PRIMITIVE_TYPE_INT: case PRIMITIVE_TYPE_SHORT: { return oldSimplePrimitiveValue == newSimplePrimitiveValue; } case PRIMITIVE_TYPE_DOUBLE: case PRIMITIVE_TYPE_FLOAT: { return oldIEEEPrimitiveValue == newIEEEPrimitiveValue; } default: { return oldValue == null ? newValue == null : oldValue .equals(newValue); } } } } default: { return false; } } } public boolean isReset() { switch (eventType) { case PropertyNotification.SET: Object defaultValue = getFeatureDefaultValue(); switch (primitiveType) { case PRIMITIVE_TYPE_BOOLEAN: return defaultValue != null && ((Boolean) defaultValue).booleanValue() == (newSimplePrimitiveValue != 0); case PRIMITIVE_TYPE_BYTE: return defaultValue != null && ((Byte) defaultValue).byteValue() == (byte) newSimplePrimitiveValue; case PRIMITIVE_TYPE_CHAR: return defaultValue != null && ((Character) defaultValue).charValue() == (char) newSimplePrimitiveValue; case PRIMITIVE_TYPE_LONG: return defaultValue != null && ((Long) defaultValue).longValue() == newSimplePrimitiveValue; case PRIMITIVE_TYPE_INT: return defaultValue != null && ((Integer) defaultValue).intValue() == (int) newSimplePrimitiveValue; case PRIMITIVE_TYPE_SHORT: return defaultValue != null && ((Short) defaultValue).shortValue() == (short) newSimplePrimitiveValue; case PRIMITIVE_TYPE_DOUBLE: return defaultValue != null && ((Double) defaultValue).doubleValue() == newIEEEPrimitiveValue; case PRIMITIVE_TYPE_FLOAT: return defaultValue != null && ((Float) defaultValue).floatValue() == (float) newIEEEPrimitiveValue; default: return defaultValue == null ? newValue == null : defaultValue .equals(newValue); } case PropertyNotification.UNSET: return true; default: return false; } } public boolean wasSet() { switch (eventType) { case PropertyNotification.SET: { if (isFeatureUnsettable()) { return position != IS_SET_CHANGE_INDEX; } break; } case PropertyNotification.UNSET: { if (isFeatureUnsettable()) { return position == IS_SET_CHANGE_INDEX; } break; } case PropertyNotification.ADD: case PropertyNotification.ADD_MANY: case PropertyNotification.REMOVE: case PropertyNotification.REMOVE_MANY: case PropertyNotification.MOVE: { return position > IS_SET_CHANGE_INDEX; } default: { return false; } } Object defaultValue = getFeatureDefaultValue(); switch (primitiveType) { case PRIMITIVE_TYPE_BOOLEAN: return defaultValue != null && ((Boolean) defaultValue).booleanValue() != (oldSimplePrimitiveValue != 0); case PRIMITIVE_TYPE_BYTE: return defaultValue != null && ((Byte) defaultValue).byteValue() != (byte) oldSimplePrimitiveValue; case PRIMITIVE_TYPE_CHAR: return defaultValue != null && ((Character) defaultValue).charValue() != (char) oldSimplePrimitiveValue; case PRIMITIVE_TYPE_LONG: return defaultValue != null && ((Long) defaultValue).longValue() != oldSimplePrimitiveValue; case PRIMITIVE_TYPE_INT: return defaultValue != null && ((Integer) defaultValue).intValue() != (int) oldSimplePrimitiveValue; case PRIMITIVE_TYPE_SHORT: return defaultValue != null && ((Short) defaultValue).shortValue() != (short) oldSimplePrimitiveValue; case PRIMITIVE_TYPE_DOUBLE: return defaultValue != null && ((Double) defaultValue).doubleValue() != oldIEEEPrimitiveValue; case PRIMITIVE_TYPE_FLOAT: return defaultValue != null && ((Float) defaultValue).floatValue() != (float) oldIEEEPrimitiveValue; default: return defaultValue == null ? oldValue != null : !defaultValue .equals(oldValue); } } protected boolean isFeatureUnsettable() { return false; } protected Object getFeatureDefaultValue() { return null; } public int getPosition() { return position < 0 ? position < IS_SET_CHANGE_INDEX ? IS_SET_CHANGE_INDEX - position - 1 : NO_INDEX : position; } public boolean merge(INotification notification) { if (!(notification instanceof IPropertyNotification)) { return false; } IPropertyNotification propertyNotification = (IPropertyNotification) notification; switch (eventType) { case PropertyNotification.SET: case PropertyNotification.UNSET: { int notificationEventType = propertyNotification.getEventType(); switch (notificationEventType) { case PropertyNotification.SET: case PropertyNotification.UNSET: { Object notificationSource = propertyNotification.getSubject(); if (notificationSource == getSubject() && getProperty().equals( propertyNotification.getProperty())) { newValue = propertyNotification.getNewValue(); if (propertyNotification.getEventType() == PropertyNotification.SET) { eventType = PropertyNotification.SET; } return true; } } } } case PropertyNotification.REMOVE: { int notificationEventType = propertyNotification.getEventType(); switch (notificationEventType) { case PropertyNotification.REMOVE: { Object notificationSource = propertyNotification.getSubject(); if (notificationSource == getSubject() && getProperty().equals( propertyNotification.getProperty())) { boolean originalWasSet = wasSet(); int originalPosition = getPosition(); int notificationPosition = propertyNotification .getPosition(); eventType = PropertyNotification.REMOVE_MANY; List<Object> removedValues = new ArrayList<Object>(2); if (originalPosition <= notificationPosition) { removedValues.add(oldValue); removedValues.add(propertyNotification.getOldValue()); newValue = new int[] { position = originalPosition, notificationPosition + 1 }; } else { removedValues.add(propertyNotification.getOldValue()); removedValues.add(oldValue); newValue = new int[] { position = notificationPosition, originalPosition }; } oldValue = removedValues; if (!originalWasSet) { position = IS_SET_CHANGE_INDEX - position - 1; } return true; } break; } } break; } case PropertyNotification.REMOVE_MANY: { int notificationEventType = propertyNotification.getEventType(); switch (notificationEventType) { case PropertyNotification.REMOVE: { Object notificationSource = propertyNotification.getSubject(); if (notificationSource == getSubject() && getProperty().equals( propertyNotification.getProperty())) { boolean originalWasSet = wasSet(); int notificationPosition = propertyNotification .getPosition(); int[] positions = (int[]) newValue; int[] newPositions = new int[positions.length + 1]; int index = 0; while (index < positions.length) { int oldPosition = positions[index]; if (oldPosition <= notificationPosition) { newPositions[index++] = oldPosition; ++notificationPosition; } else { break; } } @SuppressWarnings("unchecked") List<Object> list = (List<Object>) oldValue; list.add(index, propertyNotification.getOldValue()); newPositions[index] = notificationPosition; while (++index < newPositions.length) { newPositions[index] = positions[index - 1]; } newValue = newPositions; if (!originalWasSet) { position = IS_SET_CHANGE_INDEX - newPositions[0]; } return true; } break; } } break; } } return false; } public boolean getOldBooleanValue() { if (primitiveType != PRIMITIVE_TYPE_BOOLEAN) throw new IllegalStateException(); return oldSimplePrimitiveValue != 0; } public boolean getNewBooleanValue() { if (primitiveType != PRIMITIVE_TYPE_BOOLEAN) throw new IllegalStateException(); return newSimplePrimitiveValue != 0; } public byte getOldByteValue() { if (primitiveType != PRIMITIVE_TYPE_BYTE) throw new IllegalStateException(); return (byte) oldSimplePrimitiveValue; } public byte getNewByteValue() { if (primitiveType != PRIMITIVE_TYPE_BYTE) throw new IllegalStateException(); return (byte) newSimplePrimitiveValue; } public char getOldCharValue() { if (primitiveType != PRIMITIVE_TYPE_CHAR) throw new IllegalStateException(); return (char) oldSimplePrimitiveValue; } public char getNewCharValue() { if (primitiveType != PRIMITIVE_TYPE_CHAR) throw new IllegalStateException(); return (char) newSimplePrimitiveValue; } public double getOldDoubleValue() { if (primitiveType != PRIMITIVE_TYPE_DOUBLE) throw new IllegalStateException(); return oldIEEEPrimitiveValue; } public double getNewDoubleValue() { if (primitiveType != PRIMITIVE_TYPE_DOUBLE) throw new IllegalStateException(); return newIEEEPrimitiveValue; } public float getOldFloatValue() { if (primitiveType != PRIMITIVE_TYPE_FLOAT) throw new IllegalStateException(); return (float) oldIEEEPrimitiveValue; } public float getNewFloatValue() { if (primitiveType != PRIMITIVE_TYPE_FLOAT) throw new IllegalStateException(); return (float) newIEEEPrimitiveValue; } public int getOldIntValue() { if (primitiveType != PRIMITIVE_TYPE_INT) throw new IllegalStateException(); return (int) oldSimplePrimitiveValue; } public int getNewIntValue() { if (primitiveType != PRIMITIVE_TYPE_INT) throw new IllegalStateException(); return (int) newSimplePrimitiveValue; } public long getOldLongValue() { if (primitiveType != PRIMITIVE_TYPE_LONG) throw new IllegalStateException(); return oldSimplePrimitiveValue; } public long getNewLongValue() { if (primitiveType != PRIMITIVE_TYPE_LONG) throw new IllegalStateException(); return newSimplePrimitiveValue; } public short getOldShortValue() { if (primitiveType != PRIMITIVE_TYPE_SHORT) throw new IllegalStateException(); return (short) oldSimplePrimitiveValue; } public short getNewShortValue() { if (primitiveType != PRIMITIVE_TYPE_SHORT) throw new IllegalStateException(); return (short) newSimplePrimitiveValue; } public String getOldStringValue() { return oldValue == null ? null : oldValue.toString(); } public String getNewStringValue() { return newValue == null ? null : newValue.toString(); } /** * Adds or merges a new notification. * * @param newNotification * a notification. * @return <code>true</code> when the notification is added and * <code>false</code> when it is merged. */ @SuppressWarnings("unchecked") public boolean add(INotification newNotification) { if (newNotification == null) { return false; } else { if (merge(newNotification)) { return false; } if (chain == null) { chain = new NotificationChain( (INotificationBroadcaster) getSubject()); chain.add(this); return chain.add(newNotification); } else { return chain.add(newNotification); } } } /* * Javadoc copied from interface. */ @SuppressWarnings("unchecked") public void dispatch() { Object source = getSubject(); if (chain == null) { if (source instanceof INotificationBroadcaster<?>) { ((INotificationBroadcaster<IPropertyNotification>) source) .fireNotifications(Arrays.asList(this)); } } else { chain.dispatch(); } } @Override public String toString() { StringBuffer result = new StringBuffer(super.toString()); result.append(" (eventType: "); switch (eventType) { case PropertyNotification.SET: { result.append("SET"); break; } case PropertyNotification.UNSET: { result.append("UNSET"); break; } case PropertyNotification.ADD: { result.append("ADD"); break; } case PropertyNotification.ADD_MANY: { result.append("ADD_MANY"); break; } case PropertyNotification.REMOVE: { result.append("REMOVE"); break; } case PropertyNotification.REMOVE_MANY: { result.append("REMOVE_MANY"); break; } case PropertyNotification.MOVE: { result.append("MOVE"); break; } case PropertyNotification.REMOVING_ADAPTER: { result.append("REMOVING_ADAPTER"); break; } case PropertyNotification.RESOLVE: { result.append("RESOLVE"); break; } default: { result.append(eventType); break; } } if (isTouch()) { result.append(", touch: true"); } result.append(", position: "); result.append(getPosition()); result.append(", subject: "); result.append(getSubject()); result.append(", feature: "); result.append(getProperty()); result.append(", oldValue: "); result.append(getOldValue()); result.append(", newValue: "); if (eventType == PropertyNotification.REMOVE_MANY && newValue instanceof int[]) { int[] positions = (int[]) newValue; result.append("["); for (int i = 0; i < positions.length;) { result.append(positions[i]); if (++i < positions.length) { result.append(", "); } } result.append("]"); } else { result.append(getNewValue()); } result.append(", isTouch: "); result.append(isTouch()); result.append(", wasSet: "); result.append(wasSet()); result.append(")"); return result.toString(); } }