Skip to main content
summaryrefslogblamecommitdiffstats
blob: ce51ef07762b116b5129893519417aa6a67b0a70 (plain) (tree)
1
2
                                                                                
                                                        















                                                                                

                                            
                                





                                                                            
                                                                          


                                                                                




                                                                      

                                                        
                        




















                                                        
                                                                                             






                                                                                        
                                                                                             



                                                                                                   
                                                                                             








                                                                                                                           
                                                                                             



























                                                                                                                              
                                                                                             









                                                                                         
                                                                                             









                                                                                                 
                                                                                             










                                                                                         
                                                                                             








                                                                                                
                                                                                             






















                                                                                             

                                                                                                                  








                                                                                

         

                                                                                          

         

                                                                                                        
                                 
                                                                
                                                             

                                 
                                               
                                                                 































































                                                                                                  
                                          


                                            
                                                     


                                                   
                                                        











                                                                                                                                    
                                                            


                                                    
                                                                                        
                                                         

                                                                                                                   
        






                                                                                                 



                                      

                                                                                                        
                                         

                                                                      

                                         
                                                                        
                                                                             



                                 

                                                                                                              
                                         

                                                                           

                                         
                                                                        
                                                                                



                                 

                                                                                                                  
                                         

                                                                              

                                         
                                                                        
                                                                                   



                                 

                                                                                                             
                                         

                                                                          

                                         
                                                                        
                                                                                 



                                 

                                                                                                        
                                         

                                                                                      

                                         
                                                                        
                                                                                              



                                 

                                                                                                        
                                         

                                                                                   

                                         
                                                                        
                                                                                           



                                 

                                                                                                                   
                                         

                                                                                             

                                         
                                                                        
                                                                                                     


















































































































































































































































                                                                                                                           
/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.tests.internal.model.value.swing;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import junit.framework.TestCase;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
import org.eclipse.jpt.utility.internal.model.AbstractModel;
import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.swing.ColumnAdapter;
import org.eclipse.jpt.utility.internal.model.value.swing.TableModelAdapter;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.utility.model.value.ListValueModel;
import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jpt.utility.tests.internal.TestTools;

@SuppressWarnings("nls")
public class TableModelAdapterTests extends TestCase {
	private Crowd crowd;
	TableModelEvent event;

	public TableModelAdapterTests(String name) {
		super(name);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.crowd = this.buildCrowd();
	}

	@Override
	protected void tearDown() throws Exception {
		TestTools.clear(this);
		super.tearDown();
	}

	public void testGetRowCount() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		assertEquals(0, tableModelAdapter.getRowCount());
		// we need to add a listener to wake up the adapter
		tableModelAdapter.addTableModelListener(this.buildTableModelListener());
		assertEquals(this.crowd.peopleSize(), tableModelAdapter.getRowCount());
	}

	public void testGetColumnCount() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		assertEquals(PersonColumnAdapter.COLUMN_COUNT, tableModelAdapter.getColumnCount());
	}

	public void testGetValueAt() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		tableModelAdapter.addTableModelListener(this.buildTableModelListener());

		List<String> sortedNames = this.sortedNames();
		for (int i = 0; i < this.crowd.peopleSize(); i++) {
			assertEquals(sortedNames.get(i), tableModelAdapter.getValueAt(i, PersonColumnAdapter.NAME_COLUMN));
		}
	}

	public void testSetValueAt() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		this.event = null;
		tableModelAdapter.addTableModelListener(new TestTableModelListener() {
			@Override
			public void tableChanged(TableModelEvent e) {
				TableModelAdapterTests.this.event = e;
			}
		});

		Person person = this.crowd.personNamed("Gollum");
		assertEquals(Person.EYE_COLOR_BLUE, person.getEyeColor());
		assertFalse(person.isEvil());
		assertEquals(0, person.getRank());

		for (int i = 0; i < tableModelAdapter.getRowCount(); i++) {
			if (tableModelAdapter.getValueAt(i, PersonColumnAdapter.NAME_COLUMN).equals("Gollum")) {
				tableModelAdapter.setValueAt(Person.EYE_COLOR_HAZEL, i, PersonColumnAdapter.EYE_COLOR_COLUMN);
				tableModelAdapter.setValueAt(Boolean.TRUE, i, PersonColumnAdapter.EVIL_COLUMN);
				tableModelAdapter.setValueAt(new Integer(-1), i, PersonColumnAdapter.RANK_COLUMN);
				break;
			}
		}
		assertNotNull(this.event);
		assertEquals(Person.EYE_COLOR_HAZEL, person.getEyeColor());
		assertTrue(person.isEvil());
		assertEquals(-1, person.getRank());
	}

	public void testAddRow() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		this.event = null;
		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
		// add a person to the end of the list so we only trigger one event
		this.crowd.addPerson("Zzzzz");
		assertNotNull(this.event);
		assertEquals(TableModelEvent.INSERT, this.event.getType());
		assertEquals(TableModelEvent.ALL_COLUMNS, this.event.getColumn());
	}

	public void testRemoveRow() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		this.event = null;
		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
		// removing a person should only trigger one event, since a re-sort is not needed
		this.crowd.removePerson(this.crowd.personNamed("Gollum"));
		assertNotNull(this.event);
		assertEquals(TableModelEvent.DELETE, this.event.getType());
		assertEquals(TableModelEvent.ALL_COLUMNS, this.event.getColumn());
	}

	public void testChangeCell() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		this.event = null;
		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
		// add a person to the end of the list so we only trigger one event
		Person person = this.crowd.personNamed("Gollum");
		person.setEvil(true);
		assertNotNull(this.event);
		assertEquals(TableModelEvent.UPDATE, this.event.getType());
		assertEquals(PersonColumnAdapter.EVIL_COLUMN, this.event.getColumn());
	}

	public void testLazyListListener() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		TableModelListener listener = this.buildTableModelListener();
		assertTrue(this.crowd.hasNoCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
		tableModelAdapter.addTableModelListener(listener);
		assertTrue(this.crowd.hasAnyCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
		tableModelAdapter.removeTableModelListener(listener);
		assertTrue(this.crowd.hasNoCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
	}

	public void testLazyCellListener() throws Exception {
		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
		TableModelListener listener = this.buildTableModelListener();
		Person person = this.crowd.personNamed("Gollum");
		assertTrue(person.hasNoPropertyChangeListeners(Person.NAME_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.EVIL_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.RANK_PROPERTY));

		tableModelAdapter.addTableModelListener(listener);
		assertTrue(person.hasAnyPropertyChangeListeners(Person.NAME_PROPERTY));
		assertTrue(person.hasAnyPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
		assertTrue(person.hasAnyPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
		assertTrue(person.hasAnyPropertyChangeListeners(Person.EVIL_PROPERTY));
		assertTrue(person.hasAnyPropertyChangeListeners(Person.RANK_PROPERTY));

		tableModelAdapter.removeTableModelListener(listener);
		assertTrue(person.hasNoPropertyChangeListeners(Person.NAME_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.EVIL_PROPERTY));
		assertTrue(person.hasNoPropertyChangeListeners(Person.RANK_PROPERTY));
	}

	private TableModelAdapter<Person> buildTableModelAdapter() {
		return new TableModelAdapter<Person>(this.buildSortedPeopleAdapter(), this.buildColumnAdapter()) {
			@Override
			protected PropertyChangeListener buildCellListener() {
				return this.buildCellListener_();
			}
			@Override
			protected ListChangeListener buildListChangeListener() {
				return this.buildListChangeListener_();
			}
		};
	}

	private ListValueModel<Person> buildSortedPeopleAdapter() {
		return new SortedListValueModelAdapter<Person>(this.buildPeopleAdapter());
	}

	private CollectionValueModel<Person> buildPeopleAdapter() {
		return new CollectionAspectAdapter<Crowd, Person>(Crowd.PEOPLE_COLLECTION, this.crowd) {
			@Override
			protected Iterator<Person> iterator_() {
				return this.subject.people();
			}
			@Override
			protected int size_() {
				return this.subject.peopleSize();
			}
		};
	}

	private Crowd buildCrowd() {
		Crowd result = new Crowd();
		result.addPerson("Bilbo");
		result.addPerson("Gollum");
		result.addPerson("Frodo");
		result.addPerson("Samwise");
		return result;
	}

	private ColumnAdapter buildColumnAdapter() {
		return new PersonColumnAdapter();
	}

	private TableModelListener buildTableModelListener() {
		return new TestTableModelListener();
	}

	private List<String> sortedNames() {
		return new ArrayList<String>(CollectionTools.sortedSet(this.crowd.peopleNames()));
	}

	private TableModelListener buildSingleEventListener() {
		return new TestTableModelListener() {
			@Override
			public void tableChanged(TableModelEvent e) {
				// we expect only a single event
				if (TableModelAdapterTests.this.event == null) {
					TableModelAdapterTests.this.event = e;
				} else {
					fail("unexpected event");
				}
			}
		};
	}


	// ********** classes **********

	public static class PersonColumnAdapter implements ColumnAdapter {
		public static final int COLUMN_COUNT = 7;
	
		public static final int NAME_COLUMN = 0;
		public static final int BIRTH_DATE_COLUMN = 1;
		public static final int GONE_WEST_DATE_COLUMN = 2;
		public static final int EYE_COLOR_COLUMN = 3;
		public static final int EVIL_COLUMN = 4;
		public static final int RANK_COLUMN = 5;
		public static final int ADVENTURE_COUNT_COLUMN = 6;
	
		private static final String[] COLUMN_NAMES = new String[] {
			"Name",
			"Birth",
			"Gone West",
			"Eyes",
			"Evil",
			"Rank",
			"Adventures"
		};
	
	
		public int columnCount() {
			return COLUMN_COUNT;
		}
	
		public String columnName(int index) {
			return COLUMN_NAMES[index];
		}
	
		public Class<?> columnClass(int index) {
			switch (index) {
				case NAME_COLUMN:					return Object.class;
				case BIRTH_DATE_COLUMN:			return Date.class;
				case GONE_WEST_DATE_COLUMN:	return Date.class;
				case EYE_COLOR_COLUMN:			return Object.class;
				case EVIL_COLUMN:					return Boolean.class;
				case RANK_COLUMN:					return Integer.class;
				case ADVENTURE_COUNT_COLUMN:return Integer.class;
				default: 									return Object.class;
			}
		}
	
		public boolean columnIsEditable(int index) {
			return index != NAME_COLUMN;
		}
	
		public WritablePropertyValueModel<Object>[] cellModels(Object subject) {
			Person person = (Person) subject;
			@SuppressWarnings("unchecked")
			WritablePropertyValueModel<Object>[] result = new WritablePropertyValueModel[COLUMN_COUNT];
	
			result[NAME_COLUMN] = this.buildNameAdapter(person);
			result[BIRTH_DATE_COLUMN] = this.buildBirthDateAdapter(person);
			result[GONE_WEST_DATE_COLUMN] = this.buildGoneWestDateAdapter(person);
			result[EYE_COLOR_COLUMN] = this.buildEyeColorAdapter(person);
			result[EVIL_COLUMN] = this.buildEvilAdapter(person);
			result[RANK_COLUMN] = this.buildRankAdapter(person);
			result[ADVENTURE_COUNT_COLUMN] = this.buildAdventureCountAdapter(person);
	
			return result;
		}
	
		private WritablePropertyValueModel<Object> buildNameAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.NAME_PROPERTY, person) {
				@Override
				protected String buildValue_() {
					return this.subject.getName();
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setName((String) value);
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildBirthDateAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.BIRTH_DATE_PROPERTY, person) {
				@Override
				protected Date buildValue_() {
					return this.subject.getBirthDate();
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setBirthDate((Date) value);
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildGoneWestDateAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.GONE_WEST_DATE_PROPERTY, person) {
				@Override
				protected Date buildValue_() {
					return this.subject.getGoneWestDate();
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setGoneWestDate((Date) value);
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildEyeColorAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.EYE_COLOR_PROPERTY, person) {
				@Override
				protected String buildValue_() {
					return this.subject.getEyeColor();
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setEyeColor((String) value);
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildEvilAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.EVIL_PROPERTY, person) {
				@Override
				protected Boolean buildValue_() {
					return Boolean.valueOf(this.subject.isEvil());
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setEvil(((Boolean)value).booleanValue());
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildRankAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.RANK_PROPERTY, person) {
				@Override
				protected Integer buildValue_() {
					return new Integer(this.subject.getRank());
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setRank(((Integer) value).intValue());
				}
			};
		}
	
		private WritablePropertyValueModel<Object> buildAdventureCountAdapter(Person person) {
			return new PropertyAspectAdapter<Person, Object>(Person.ADVENTURE_COUNT_PROPERTY, person) {
				@Override
				protected Integer buildValue_() {
					return new Integer(this.subject.getAdventureCount());
				}
				@Override
				protected void setValue_(Object value) {
					this.subject.setAdventureCount(((Integer) value).intValue());
				}
			};
		}
	
	}


	public static class Crowd extends AbstractModel {
		private final Collection<Person> people;
			public static final String PEOPLE_COLLECTION = "people";
	
		public Crowd() {
			super();
			this.people = new ArrayList<Person>();
		}
	
	
		public Iterator<Person> people() {
			return new CloneIterator<Person>(this.people) {
				@Override
				protected void remove(Person person) {
					Crowd.this.removePerson(person);
				}
			};
		}
	
		public int peopleSize() {
			return this.people.size();
		}
	
		public Person addPerson(String name) {
			this.checkPersonName(name);
			return this.addPerson(new Person(this, name));
		}
	
		private Person addPerson(Person person) {
			this.addItemToCollection(person, this.people, PEOPLE_COLLECTION);
			return person;
		}
	
		public void removePerson(Person person) {
			this.removeItemFromCollection(person, this.people, PEOPLE_COLLECTION);
		}
	
		public void removePeople(Collection<Person> persons) {
			this.removeItemsFromCollection(persons, this.people, PEOPLE_COLLECTION);
		}
	
		public void removePeople(Iterator<Person> persons) {
			this.removeItemsFromCollection(persons, this.people, PEOPLE_COLLECTION);
		}
	
		void checkPersonName(String personName) {
			if (personName == null) {
				throw new NullPointerException();
			}
			if (CollectionTools.contains(this.peopleNames(), personName)) {
				throw new IllegalArgumentException(personName);
			}
		}
	
		public Iterator<String> peopleNames() {
			return new TransformationIterator<Person, String>(this.people.iterator()) {
				@Override
				protected String transform(Person person) {
					return person.getName();
				}
			};
		}
	
		public Person personNamed(String name) {
			for (Iterator<Person> stream = this.people.iterator(); stream.hasNext(); ) {
				Person person = stream.next();
				if (person.getName().equals(name)) {
					return person;
				}
			}
			return null;
		}
	
		@Override
		public String toString() {
			return StringTools.buildToStringFor(this, String.valueOf(this.people.size()) + " people");
		}
	
	}
	
	
	public static class Person extends AbstractModel implements Comparable<Person> {
		private Crowd crowd;
		private String name;
			public static final String NAME_PROPERTY= "name";
		private Date birthDate;
			public static final String BIRTH_DATE_PROPERTY= "birthDate";
		private Date goneWestDate;
			public static final String GONE_WEST_DATE_PROPERTY= "goneWestDate";
		private String eyeColor;
			public static final String EYE_COLOR_PROPERTY= "eyeColor";
			public static final String EYE_COLOR_BLUE = "blue";
			public static final String EYE_COLOR_GREEN = "green";
			public static final String EYE_COLOR_BROWN = "brown";
			public static final String EYE_COLOR_HAZEL = "hazel";
			public static final String EYE_COLOR_PINK = "pink";
			private static Collection<String> validEyeColors;
			public static final String DEFAULT_EYE_COLOR = EYE_COLOR_BLUE;
		private boolean evil;
			public static final String EVIL_PROPERTY= "evil";
		private int rank;
			public static final String RANK_PROPERTY= "rank";
		private int adventureCount;
			public static final String ADVENTURE_COUNT_PROPERTY= "adventureCount";
	
		Person(Crowd crowd, String name) {
			super();
			this.crowd = crowd;
			this.name = name;
			this.birthDate = new Date();
			Calendar c = Calendar.getInstance();
			c.add(Calendar.YEAR, 250);
			this.goneWestDate = new Date(c.getTimeInMillis());
			this.eyeColor = DEFAULT_EYE_COLOR;
			this.evil = false;
			this.rank = 0;
			this.adventureCount = 0;
		}
	
		public static Collection<String> getValidEyeColors() {
			if (validEyeColors == null) {
				validEyeColors = buildValidEyeColors();
			}
			return validEyeColors;
		}
	
		private static Collection<String> buildValidEyeColors() {
			Collection<String> result = new ArrayList<String>();
			result.add(EYE_COLOR_BLUE);
			result.add(EYE_COLOR_GREEN);
			result.add(EYE_COLOR_BROWN);
			result.add(EYE_COLOR_HAZEL);
			result.add(EYE_COLOR_PINK);
			return result;
		}
	
		public Crowd getCrowd() {
			return this.crowd;
		}
	
		public String getName() {
			return this.name;
		}
		public void setName(String name) {
			this.crowd.checkPersonName(name);
			Object old = this.name;
			this.name = name;
			this.firePropertyChanged(NAME_PROPERTY, old, name);
		}
	
		public Date getBirthDate() {
			return this.birthDate;
		}
		public void setBirthDate(Date birthDate) {
			Object old = this.birthDate;
			this.birthDate = birthDate;
			this.firePropertyChanged(BIRTH_DATE_PROPERTY, old, birthDate);
		}
	
		public Date getGoneWestDate() {
			return this.goneWestDate;
		}
		public void setGoneWestDate(Date goneWestDate) {
			Object old = this.goneWestDate;
			this.goneWestDate = goneWestDate;
			this.firePropertyChanged(GONE_WEST_DATE_PROPERTY, old, goneWestDate);
		}
	
		public String getEyeColor() {
			return this.eyeColor;
		}
		public void setEyeColor(String eyeColor) {
			if (! getValidEyeColors().contains(eyeColor)) {
				throw new IllegalArgumentException(eyeColor);
			}
			Object old = this.eyeColor;
			this.eyeColor = eyeColor;
			this.firePropertyChanged(EYE_COLOR_PROPERTY, old, eyeColor);
		}
	
		public boolean isEvil() {
			return this.evil;
		}
		public void setEvil(boolean evil) {
			boolean old = this.evil;
			this.evil = evil;
			this.firePropertyChanged(EVIL_PROPERTY, old, evil);
		}
	
		public int getRank() {
			return this.rank;
		}
		public void setRank(int rank) {
			int old = this.rank;
			this.rank = rank;
			this.firePropertyChanged(RANK_PROPERTY, old, rank);
		}
	
		public int getAdventureCount() {
			return this.adventureCount;
		}
		public void setAdventureCount(int adventureCount) {
			int old = this.adventureCount;
			this.adventureCount = adventureCount;
			this.firePropertyChanged(ADVENTURE_COUNT_PROPERTY, old, adventureCount);
		}
	
		public int compareTo(Person p) {
			return this.name.compareToIgnoreCase(p.name);
		}
	
		@Override
		public String toString() {
			return this.name + 
						"\tborn: " + DateFormat.getDateInstance().format(this.birthDate) + 
						"\tgone west: " + DateFormat.getDateInstance().format(this.goneWestDate) + 
						"\teyes: " + this.eyeColor + 
						"\tevil: " + this.evil + 
						"\trank: " + this.rank +
						"\tadventures: " + this.adventureCount
			;
		}
	
	}


	private class TestTableModelListener implements TableModelListener {
		TestTableModelListener() {
			super();
		}
		public void tableChanged(TableModelEvent e) {
			fail("unexpected event");
		}
	}

}

Back to the top