package com.google.code.joto.ui.filter; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import org.apache.commons.collections.Predicate; import com.google.code.joto.eventrecorder.writer.FilteringRecordEventWriter; import com.google.code.joto.eventrecorder.writer.RecordEventWriter; /** * a swing wrapper model for FilteringRecordEventWriter * * internally use a RecordEventFilterItemTableModel to edit list of filter to apply * */ public class RecordEventFilterCategoryModel { protected RecordEventFilterFileTableModel filterItemTableModel; protected FilteringRecordEventWriter resultFilteringEventWriter; // implicit from resultFilteringEventWriter.getTarget() // protected RecordEventWriter underlyingEventWriter; private String name; private Object owner; private RecordEventFilterFileExternalFrameHolder filterFrameHolder; // ------------------------------------------------------------------------ public RecordEventFilterCategoryModel(RecordEventWriter underlyingEventWriter) { this.resultFilteringEventWriter = new FilteringRecordEventWriter(underlyingEventWriter); this.filterItemTableModel = new RecordEventFilterFileTableModel(); filterItemTableModel.addTableModelListener( new FilteringRecordEventWriterSyncFromTableModelListener(filterItemTableModel, resultFilteringEventWriter)); filterFrameHolder = new RecordEventFilterFileExternalFrameHolder(filterItemTableModel); } // ------------------------------------------------------------------------ public FilteringRecordEventWriter getResultFilteringEventWriter() { return resultFilteringEventWriter; } public RecordEventFilterFileTableModel getFilterItemTableModel() { return filterItemTableModel; } public String getName() { return name; } public void setName(String p) { this.name = p; } public Object getOwner() { return owner; } public void setOwner(Object p) { this.owner = p; } public void addFilterRow(RecordEventFilterFile filter) { filterItemTableModel.addRow(filter); } public RecordEventFilterFileExternalFrameHolder getFilterFrameHolder() { return filterFrameHolder; } // ------------------------------------------------------------------------ /** * inner TableModelListener adapter class * to update FilteringRecordEventWriter when a RecordEventFilterItemTableModel change * * transform List<RecordEventFilterItem> to List<Predicate> (+ filter only active filters) */ public static class FilteringRecordEventWriterSyncFromTableModelListener implements TableModelListener { protected RecordEventFilterFileTableModel sourceModel; protected FilteringRecordEventWriter target; protected List<RecordEventFilterFile> currSourceRowsListened = new ArrayList<RecordEventFilterFile>(); protected PropertyChangeListener innerPropertyChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { onSourceRowPropertyChanged(evt); } }; public FilteringRecordEventWriterSyncFromTableModelListener(RecordEventFilterFileTableModel sourceModel, FilteringRecordEventWriter target) { super(); this.sourceModel = sourceModel; this.target = target; updateSourceToTarget(); } @Override public void tableChanged(TableModelEvent event) { // handle add/remove rows... check all rows are synchronized with PropertyChangeListener // brute force remove+add all.. updatePropertyChangeListeners(); updateSourceToTarget(); } private void updatePropertyChangeListeners() { List<RecordEventFilterFile> newRows = sourceModel.getRows(); for(RecordEventFilterFile oldRow : currSourceRowsListened) { oldRow.removePropertyChangeSupport(innerPropertyChangeListener); } for(RecordEventFilterFile newRow : newRows) { newRow.addPropertyChangeSupport(innerPropertyChangeListener); } currSourceRowsListened.clear(); currSourceRowsListened.addAll(newRows); } private void onSourceRowPropertyChanged(PropertyChangeEvent evt) { updateSourceToTarget(); } private void updateSourceToTarget() { List<RecordEventFilterFile> sourceRows = sourceModel.getRows(); List<Predicate> targetElts = filterItemsToPredicates(sourceRows); target.setEventPredicateElts(targetElts); } public static List<Predicate> filterItemsToPredicates(List<RecordEventFilterFile> srcElts) { List<Predicate> targetElts = new ArrayList<Predicate>(); for(RecordEventFilterFile srcElt : srcElts) { if (srcElt.isActive()) { Predicate predicate = srcElt.getEventPredicate(); if (predicate != null) { targetElts.add(predicate); } } } return targetElts; } } }