blob: f4aa2db76747e08d9b4cae242ff7b2c931c1d917 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.internal.databinding.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.jface.databinding.ChangeEvent;
import org.eclipse.jface.databinding.DataBinding;
import org.eclipse.jface.databinding.IChangeListener;
import org.eclipse.jface.databinding.IDataBindingContext;
import org.eclipse.jface.databinding.IUpdatableCollection;
import org.eclipse.jface.databinding.IUpdatableFactory;
import org.eclipse.jface.databinding.IUpdatableValue;
import org.eclipse.jface.databinding.JavaBeansScalarUpdatableValueFactory;
import org.eclipse.jface.databinding.Property;
import org.eclipse.jface.databinding.Updatable;
import org.eclipse.jface.util.Assert;
/**
* @since 3.2
*
*/
public class CopyOfJavaBeanUpdatableCollection extends Updatable implements
IUpdatableCollection {
// private PropertyChangeListener collectionListener = new PropertyChangeListener() {
// public void propertyChange(java.beans.PropertyChangeEvent event) {
// if (!updating) {
// Object[] values = getValues();
// elementListenerSupport.setHookTargets(values);
// fireChangeEvent(ChangeEvent.CHANGE, null,
// null, ChangeEvent.POSITION_UNKNOWN);
// }
// }
// };
//
// private PropertyChangeListener elementListener = new PropertyChangeListener() {
// public void propertyChange(java.beans.PropertyChangeEvent event) {
// if (!updating) {
// Object[] values = getValues();
// int position = Arrays.asList(values).indexOf(event.getSource());
// if(position!=-1){
// fireChangeEvent(ChangeEvent.CHANGE, event.getSource(),
// event.getSource(), position);
// }
// }
// }
// };
//
// private ListenerSupport collectionListenSupport = new ListenerSupport(collectionListener);
// private ListenerSupport elementListenerSupport = new ListenerSupport(elementListener);
private boolean updating = false;
private PropertyDescriptor descriptor;
private Class elementType=null;
private IUpdatableValue objectUpdatable;
/**
* @param object The collection object we're binding
* @param descriptor A java.beans.PropertyDescriptor
* @param elementType The element data type (still needed?)
*/
public CopyOfJavaBeanUpdatableCollection(Object object,
PropertyDescriptor descriptor, Class elementType) {
this.descriptor = descriptor;
this.elementType = elementType;
// Create an IUpdatableValue for the collection itself
IDataBindingContext dbc = DataBinding.createContext(new IUpdatableFactory[] {
new JavaBeansScalarUpdatableValueFactory()
});
objectUpdatable = (IUpdatableValue) dbc.createUpdatable(new Property(object, descriptor.getName()));
objectUpdatable.addChangeListener(changeListener);
}
private IChangeListener changeListener = new IChangeListener() {
public void handleChange(ChangeEvent changeEvent) {
if (!updating) {
fireChangeEvent(changeEvent.getChangeType(), null,
null, ChangeEvent.POSITION_UNKNOWN);
}
}
};
public void dispose() {
super.dispose();
objectUpdatable.dispose();
}
private Collection collection() {
return (Collection)objectUpdatable.getValue();
}
private Object[] array() {
return (Object[])objectUpdatable.getValue();
}
public int getSize() {
if (descriptor.getPropertyType().isArray()) {
return array().length;
}
return collection().size();
}
public int addElement(Object value, int index) {
if (descriptor.getPropertyType().isArray())
Assert.isTrue(false, "cannot add elements"); //$NON-NLS-1$
Collection list = collection();
list.add(value);
if (index <= 0 || index > list.size())
index = list.size();
fireChangeEvent(ChangeEvent.ADD, null, value, index);
return index;
}
private Object findElement(int index) {
Collection list = collection();
Object o = null;
int i=0;
for (Iterator iter = list.iterator(); iter.hasNext(); i++) {
if (index==i) {
o = iter.next();
break;
}
iter.next();
}
return o;
}
public void removeElement(int index) {
if (descriptor.getPropertyType().isArray())
Assert.isTrue(false, "cannot remove elements"); //$NON-NLS-1$
Object o = findElement(index);
if (o!=null) {
collection().remove(o);
fireChangeEvent(ChangeEvent.REMOVE, o, null, index);
}
}
public void setElement(int index, Object value) {
if (updating) {
return;
}
updating = true;
try {
Object oldValue;
if (descriptor.getPropertyType().isArray()) {
oldValue = array()[index];
array()[index] = value;
} else {
Collection c = collection();
oldValue = findElement(index);
try {
// Try to preserve collection order if possible
Method setMethod = c.getClass().getMethod("set", new Class[] {Integer.TYPE, Object.class}); //$NON-NLS-1$
setMethod.invoke(c, new Object[] {new Integer(index), value});
} catch (Exception e) {
// If we can't preserve order
if (oldValue != null) {
c.remove(oldValue);
}
c.add(value);
}
}
fireChangeEvent(ChangeEvent.CHANGE, oldValue, value, index);
} finally {
updating = false;
}
}
public Object getElement(int index) {
if (descriptor.getPropertyType().isArray()) {
return array()[index];
}
return findElement(index);
}
public Class getElementType() {
return elementType;
}
}