Coverage Report - org.openpermis.editor.policy.gui.checklist.CheckListModel
 
Classes in this File Line Coverage Branch Coverage Complexity
CheckListModel
72%
16/22
N/A
1.393
CheckListModel$1
N/A
N/A
1.393
CheckListModel$ColumnType
81%
13/16
70%
7/10
1.393
CheckListModel$ColumnType$1
22%
2/9
0%
0/4
1.393
CheckListModel$ColumnType$2
66%
2/3
N/A
1.393
CheckListModel$PoolListener
76%
13/17
100%
6/6
1.393
CheckListModel$SelectionListener
100%
3/3
N/A
1.393
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 package org.openpermis.editor.policy.gui.checklist;
 11  
 
 12  
 import java.util.List;
 13  
 import java.util.ListIterator;
 14  
 
 15  
 import javax.swing.table.AbstractTableModel;
 16  
 
 17  
 import org.jdesktop.observablecollections.ObservableList;
 18  
 import org.jdesktop.observablecollections.ObservableListListener;
 19  
 
 20  
 import org.openpermis.editor.policy.gui.binding.ObservableListAdapter;
 21  
 import org.openpermis.policy.Role;
 22  
 
 23  
 
 24  
 /**
 25  
  * Creates a model that manages a pool of items and a selection list from the pool.
 26  
  * @param <T> type of the items in the check list model.
 27  
  * @since 0.1.0
 28  
  */
 29  24
 public class CheckListModel<T>
 30  
         extends AbstractTableModel
 31  
 {
 32  
 
 33  
         //---- State
 34  
         
 35  
         /**
 36  
          * @since 0.3.0
 37  
          */
 38  
         private static final long serialVersionUID = 4791486544723792077L;
 39  
 
 40  
         /**
 41  
          * The pool of available items that can be chosen.
 42  
          * @since 0.1.0
 43  
          */
 44  
         private final ObservableList<T> pool;
 45  
         
 46  
         /**
 47  
          * Listener that synchronizes the state of the table model and the pool list.
 48  
          * @since 0.1.0
 49  
          */
 50  
         private final PoolListener poolListener;
 51  
         
 52  
         /**
 53  
          * The currently selected items from the pool.
 54  
          * @since 0.1.0
 55  
          */
 56  
         private final ObservableList<T> selection;
 57  
         
 58  
         /**
 59  
          * Listener that refreshes the check list whenever a change occurs.
 60  
          * @since 0.1.0
 61  
          */
 62  
         private final SelectionListener selectionListener;
 63  
         
 64  
         //---- Constructors
 65  
         
 66  
         /**
 67  
          * Creates a new check list model.
 68  
          * @param pool the  poolof available items that can be chosen.
 69  
          * @param selection the currently selected items from the pool.
 70  
          * @since 0.1.0
 71  
          */
 72  7
         public CheckListModel (ObservableList<T> pool, ObservableList<T> selection) {
 73  7
                 this.pool = pool;
 74  7
                 this.poolListener = new PoolListener();
 75  7
                 this.selection = selection;
 76  7
                 this.selectionListener = new SelectionListener();
 77  7
         }
 78  
         
 79  
         //---- Methods
 80  
         
 81  
         /**
 82  
          * Adds listeners to synchronize the list with the table model.
 83  
          * @since 0.1.0
 84  
          */
 85  
         public void configureListeners () {
 86  7
                 this.pool.addObservableListListener(this.poolListener);
 87  7
                 this.selection.addObservableListListener(this.selectionListener);
 88  7
         }
 89  
         
 90  
         /**
 91  
          * Removes the listeners to synchronize the list with the table model added in
 92  
          * {@link #configureListeners()}.
 93  
          * @since 0.1.0
 94  
          */
 95  
         public void unconfigureListeners () {
 96  7
                 this.pool.removeObservableListListener(this.poolListener);
 97  7
                 this.selection.removeObservableListListener(this.selectionListener);
 98  7
         }
 99  
         
 100  
         /**
 101  
          * Returns the type of the column at the specified index.
 102  
          * @param columnIndex the index for which to retrieve the column type.
 103  
          * @return the type requested.
 104  
          * @since 0.1.0
 105  
          */
 106  
         private ColumnType getColumnType (int columnIndex) {
 107  320
                 return ColumnType.values()[columnIndex];
 108  
         }
 109  
         
 110  
         //---- TableModel
 111  
         
 112  
         /**
 113  
          * @since 0.1.0
 114  
          */
 115  
         @Override
 116  
         public boolean isCellEditable (int rowIndex, int columnIndex) {
 117  0
                 return getColumnType(columnIndex).isEditable();
 118  
         }
 119  
         
 120  
         /**
 121  
          * @since 0.1.0
 122  
          */
 123  
         @Override
 124  
         public Class<?> getColumnClass (int columnIndex) {
 125  0
                 return getColumnType(columnIndex).getColumnClass();
 126  
         }
 127  
         
 128  
         /**
 129  
          * @since 0.1.0
 130  
          */
 131  
         @Override
 132  
         public String getColumnName (int columnIndex) {
 133  0
                 return getColumnType(columnIndex).getColumnName();
 134  
         }
 135  
         
 136  
         /**
 137  
          * @since 0.1.0
 138  
          */
 139  
         public int getColumnCount () {
 140  0
                 return ColumnType.values().length;
 141  
         }
 142  
         
 143  
         /**
 144  
          * @since 0.1.0
 145  
          */
 146  
         public int getRowCount () {
 147  9
                 return this.pool.size();
 148  
         }
 149  
         
 150  
         /**
 151  
          * @since 0.1.0
 152  
          */
 153  
         public Object getValueAt (int rowIndex, int columnIndex) {
 154  320
                 return getColumnType(columnIndex).getValue(rowIndex, this.pool, this.selection);
 155  
         }
 156  
         
 157  
         /**
 158  
          * @since 0.1.0
 159  
          */
 160  
         @Override
 161  
         public void setValueAt (Object value, int rowIndex, int columnIndex) {
 162  0
                 getColumnType(columnIndex).setValue(rowIndex, value, this.pool, this.selection);
 163  0
         }
 164  
 
 165  
         //---- ColumnType
 166  
         
 167  
         /**
 168  
          * Describes the type of a column, including getters and setters.
 169  
          * @since 0.1.0
 170  
          */
 171  323
         enum ColumnType {
 172  
                 
 173  1
                 CHECKBOX("Checkbox", Boolean.class, true) {
 174  
                         @Override
 175  
                         public Object getValue (int rowIndex, List<?> itemPool, List<?> selectionList) {
 176  160
                                 return Boolean.valueOf(contains(selectionList, itemPool.get(rowIndex)));
 177  
                         }
 178  
                         @Override
 179  1
                         public <T> void setValue (
 180  
                                 int rowIndex, Object value, List<T> itemPool, List<T> selectionList
 181  
                         ) {
 182  0
                                 final boolean add = Boolean.TRUE.equals(value);
 183  0
                                 final T item = itemPool.get(rowIndex);
 184  0
                                 if (add != contains(selectionList, item)) {
 185  0
                                         if (add) {
 186  0
                                                 selectionList.add(item);
 187  
                                         } else {
 188  0
                                                 selectionList.remove(indexOf(selectionList, item));
 189  
                                         }
 190  
                                 }
 191  0
                         }
 192  
                 },
 193  1
                 ITEM("Item", Object.class, false) {
 194  
                         @Override
 195  
                         public Object getValue (int rowIndex, List<?> itemPool, List<?> selectionList) {
 196  160
                                 return itemPool.get(rowIndex);
 197  
                         }
 198  
                         @Override
 199  1
                         public <T> void setValue (
 200  
                                 int rowIndex, Object value, List<T> itemPool, List<T> selectionList
 201  
                         ) {
 202  0
                                 throw new IllegalStateException(
 203  
                                         "Editing of column [" + getColumnName() + "] not supported."
 204  
                                 );
 205  
                         }
 206  
                 };
 207  
                 
 208  
                 //---- State
 209  
                 
 210  
                 private final String columnName;
 211  
                 private final Class<?> columnClass;
 212  
                 private final boolean editable;
 213  
                 
 214  
                 //---- Constructors
 215  
                 
 216  2
                 private ColumnType (String columnName, Class<?> columnClass, boolean editable) {
 217  2
                         this.columnName = columnName;
 218  2
                         this.columnClass = columnClass;
 219  2
                         this.editable = editable;
 220  2
                 }
 221  
                 
 222  
                 //---- Methods
 223  
                 
 224  
                 /**
 225  
                  * Returns the index of the specified item in the given list.
 226  
                  * @param list the list to find the item in.
 227  
                  * @param item the item to search for by identity.
 228  
                  * @return the index requested or -1 if there is no such item.
 229  
                  * @since 0.1.0
 230  
                  */
 231  
                 protected int indexOf (List<?> list, Object item) {
 232  955
                         for (int i = 0; i < list.size(); i++) {
 233  846
                                 if (
 234  
                                         // The class Role role has an implementation of equals.
 235  
                                         list.get(i) instanceof Role && list.get(i).equals(item)
 236  
                                         || list.get(i) == item
 237  
                                 ) {
 238  51
                                         return i;
 239  
                                 }
 240  
                         }
 241  109
                         return -1;
 242  
                 }
 243  
                 
 244  
                 /**
 245  
                  * Checks if the specified item is in the given list.
 246  
                  * @param list the list to search.
 247  
                  * @param item the item to check.
 248  
                  * @return {@code true} if the item is in the list, {@code false} otherwise.
 249  
                  * @since 0.1.0
 250  
                  */
 251  
                 protected boolean contains (List<?> list, Object item) {
 252  160
                         return indexOf(list, item) != -1;
 253  
                 }
 254  
                 
 255  
                 /**
 256  
                  * Returns the value of this column at the specified row index.
 257  
                  * @param rowIndex the index for which to retrieve the value.
 258  
                  * @param itemPool the pool of items.
 259  
                  * @param selectionList the list of currently selected items.
 260  
                  * @return the value at the given row/column.
 261  
                  * @since 0.1.0
 262  
                  */
 263  
                 public abstract Object getValue (int rowIndex, List<?> itemPool, List<?> selectionList);
 264  
                 
 265  
                 /**
 266  
                  * Sets the value of this column at the specified row index.
 267  
                  * @param rowIndex the index for which to set the value.
 268  
                  * @param itemPool the pool of items.
 269  
                  * @param selectionList the list of currently selected items.
 270  
                  * @since 0.1.0
 271  
                  */
 272  
                 public abstract <T> void setValue (
 273  
                         int rowIndex, Object value, List<T> itemPool, List<T> selectionList
 274  
                 );
 275  
                 
 276  
                 /**
 277  
                  * The name of this column.
 278  
                  * @return the name of this column.
 279  
                  * @since 0.1.0
 280  
                  */
 281  
                 public String getColumnName () {
 282  0
                         return this.columnName;
 283  
                 }
 284  
                 
 285  
                 /**
 286  
                  * The value class of this column.
 287  
                  * @return the value class of this column.
 288  
                  * @since 0.1.0
 289  
                  */
 290  
                 public Class<?>        getColumnClass () {
 291  0
                         return this.columnClass;
 292  
                 }
 293  
                 
 294  
                 /**
 295  
                  * @return the editable.
 296  
                  * @since 0.1.0
 297  
                  */
 298  
                 public boolean isEditable () {
 299  0
                         return this.editable;
 300  
                 }
 301  
                 
 302  
         }
 303  
         
 304  
         //---- PoolListener
 305  
 
 306  
         /**
 307  
          * Synchronizes the check list model if a change in the pool list occurs.
 308  
          * @since 0.1.0
 309  
          */
 310  
         @SuppressWarnings("unchecked")
 311  14
         private class PoolListener
 312  
                 implements ObservableListListener
 313  
         {
 314  
 
 315  
                 /**
 316  
                  * @since 0.1.0
 317  
                  */
 318  
                 public void listElementPropertyChanged (ObservableList list, int index) {
 319  0
                         CheckListModel.this.fireTableRowsUpdated(index, index);
 320  0
                 }
 321  
 
 322  
                 /**
 323  
                  * @since 0.1.0
 324  
                  */
 325  
                 public void listElementReplaced (ObservableList list, int index, Object oldElement) {
 326  0
                         CheckListModel.this.fireTableRowsUpdated(index, index);
 327  0
                 }
 328  
 
 329  
                 /**
 330  
                  * @since 0.1.0
 331  
                  */
 332  
                 public void listElementsAdded (ObservableList list, int index, int length) {
 333  4
                         CheckListModel.this.fireTableRowsInserted(index, index + length);
 334  4
                 }
 335  
 
 336  
                 /**
 337  
                  * @since 0.1.0
 338  
                  */
 339  
                 public void listElementsRemoved (ObservableList list, int index, List oldElements) {
 340  5
                         for (final Object obj : oldElements) {
 341  24
                                 final ListIterator<T> iterator = CheckListModel.this.selection.listIterator();
 342  119
                                 while (iterator.hasNext()) {
 343  95
                                         final T item = iterator.next();
 344  95
                                         if (obj == item) {
 345  9
                                                 iterator.remove();
 346  
                                         }
 347  95
                                 }
 348  24
                         }
 349  5
                         CheckListModel.this.fireTableDataChanged();
 350  5
                 }
 351  
                 
 352  
         }
 353  
         
 354  
         //---- SelectionListener
 355  
         
 356  
         /**
 357  
          * Synchronizes the check list model if a change in the selection list occurs.
 358  
          * @since 0.1.0
 359  
          */
 360  
         @SuppressWarnings("unchecked")
 361  14
         private class SelectionListener
 362  
                 extends ObservableListAdapter
 363  
         {
 364  
                 
 365  
                 /**
 366  
                  * @since 0.3.0
 367  
                  */
 368  
                 @Override
 369  
                 protected void listChanged (ObservableList list) {
 370  18
                         CheckListModel.this.fireTableDataChanged();
 371  18
                 }
 372  
                 
 373  
         }
 374  
         
 375  
 }