<commit_before>//
//  KeyValueTableModel.java
//  xal
//
//  Created by <NAME> on 1/29/09.
//  Copyright 2009 Oak Ridge National Lab. All rights reserved.
//

package xal.tools.swing;

import xal.tools.data.KeyValueAdaptor;
import xal.tools.data.KeyValueRecordListener;
import xal.tools.messaging.MessageCenter;
import xal.tools.StringJoiner;

import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.regex.*;
import javax.swing.table.AbstractTableModel;


/** Table Model whose records are arbitrary objects and whose values are obtained through the Key-Value adaptor */
public class KeyValueTableModel<RecordType> extends AbstractTableModel {
    /** serialization ID */
    private static final long serialVersionUID = 1L;
    
	/** pattern for matching a lower case letter followed immediately by an upper case letter */
	final static private Pattern LOWER_UPPER_PATTERN;
	
	/** message center for posting events */
	final private MessageCenter MESSAGE_CENTER;
	
	/** proxy for events to be forwarded to registered listeners */
	final private KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> EVENT_PROXY;
	
	/** key value adaptor to get the value from a record (row) for the specified key path (column property) */
	final protected KeyValueAdaptor KEY_VALUE_ADAPTOR;
	
	/** column names keyed by key path */
	final private Map<String,String> COLUMN_NAME_MAP;
	
	/** column class keyed by key path */
	final private Map<String,Class<?>> COLUMN_CLASS_MAP;
	
	/** column edit indicator map keyed by key path */
	final private Map<String,ColumnEditRule<RecordType>> COLUMN_EDITABLE_MAP;
	
	/** list of records to display (one record for each table row) */
	private List<RecordType> _records;
	
	/** array of key paths to get the data to display (one key path for each column) */
	private String[] _keyPaths;
	
	
	// static initializer
	static {
		LOWER_UPPER_PATTERN = Pattern.compile( "(\\p{Lower}\\p{Upper})" );
	}
	
	
	/** 
	 * Primary Constructor
	 * @param records the list of objects (one record for each table row)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
    @SuppressWarnings( "unchecked" )    // Java static fields don't support generics so we can't use them to strongly type KeyValueRecordListener.class
	public KeyValueTableModel( final List<RecordType> records, final String ... keyPaths ) {
		MESSAGE_CENTER = new MessageCenter( "KeyValueTableModel" );
		EVENT_PROXY = MESSAGE_CENTER.registerSource( this, KeyValueRecordListener.class );
		
		KEY_VALUE_ADAPTOR = new KeyValueAdaptor();
		
		COLUMN_NAME_MAP = new HashMap<String,String>();
		COLUMN_CLASS_MAP = new HashMap<String,Class<?>>();
		COLUMN_EDITABLE_MAP = new HashMap<String,ColumnEditRule<RecordType>>();
		
		setDataSource( records, keyPaths );
	}
	
	
	/** Empty Constructor */
	public KeyValueTableModel() {
		this( new java.util.ArrayList<RecordType>(), "toString" );
	}
	
	
	/**
	 * Add the specified listener as a receiver of record modification events from this instance.
	 * @param listener object to receive events
	 */
	public void addKeyValueRecordListener( final KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> listener ) {
		MESSAGE_CENTER.registerTarget( listener, this, KeyValueRecordListener.class );
	}
	
	
	/**
	 * Remove the specified listener from receiving record modification events from this instance.
	 * @param listener object to be removed from receiving events
	 */
	public void removeKeyValueRecordListener( final KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> listener ) {
		MESSAGE_CENTER.removeTarget( listener, this, KeyValueRecordListener.class );
	}
	
	
	/** 
	 * Set the records (row) and key paths (column accessors)
	 * @param records the list of objects (one record for each table row)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
	public void setDataSource( final List<RecordType> records, final String ... keyPaths ) {
		setRecords( records );
		setKeyPaths( keyPaths );
	}
	
	
	/** Get the record at the specified row index */
	public RecordType getRecordAtRow( final int row ) {
		return _records.get( row );
	}
	
	
	/** 
	 * Set the records (row)
	 * @param records the list of objects (one record for each table row)
	 */
	public void setRecords( final List<RecordType> records ) {
		_records = records;
		fireTableDataChanged();
	}
	
	
	/**
	 * Set the key paths (column accessors)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
	public void setKeyPaths( final String ... keyPaths ) {
		_keyPaths = keyPaths;
		if ( keyPaths != null ) {
			for ( final String keyPath : keyPaths ) {
                // generate a default column name if one has not already been set
                if ( !COLUMN_NAME_MAP.containsKey( keyPath ) ) {
                    final String name = toColumnName( keyPath );
                    setColumnName( keyPath, name );
                }
			}
		}
		fireTableStructureChanged();<commit_msg>Add a getter for the Key Value Table Model records.<commit_after>//
//  KeyValueTableModel.java
//  xal
//
//  Created by <NAME> on 1/29/09.
//  Copyright 2009 Oak Ridge National Lab. All rights reserved.
//

package xal.tools.swing;

import xal.tools.data.KeyValueAdaptor;
import xal.tools.data.KeyValueRecordListener;
import xal.tools.messaging.MessageCenter;
import xal.tools.StringJoiner;

import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.regex.*;
import javax.swing.table.AbstractTableModel;


/** Table Model whose records are arbitrary objects and whose values are obtained through the Key-Value adaptor */
public class KeyValueTableModel<RecordType> extends AbstractTableModel {
    /** serialization ID */
    private static final long serialVersionUID = 1L;
    
	/** pattern for matching a lower case letter followed immediately by an upper case letter */
	final static private Pattern LOWER_UPPER_PATTERN;
	
	/** message center for posting events */
	final private MessageCenter MESSAGE_CENTER;
	
	/** proxy for events to be forwarded to registered listeners */
	final private KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> EVENT_PROXY;
	
	/** key value adaptor to get the value from a record (row) for the specified key path (column property) */
	final protected KeyValueAdaptor KEY_VALUE_ADAPTOR;
	
	/** column names keyed by key path */
	final private Map<String,String> COLUMN_NAME_MAP;
	
	/** column class keyed by key path */
	final private Map<String,Class<?>> COLUMN_CLASS_MAP;
	
	/** column edit indicator map keyed by key path */
	final private Map<String,ColumnEditRule<RecordType>> COLUMN_EDITABLE_MAP;
	
	/** list of records to display (one record for each table row) */
	private List<RecordType> _records;
	
	/** array of key paths to get the data to display (one key path for each column) */
	private String[] _keyPaths;
	
	
	// static initializer
	static {
		LOWER_UPPER_PATTERN = Pattern.compile( "(\\p{Lower}\\p{Upper})" );
	}
	
	
	/** 
	 * Primary Constructor
	 * @param records the list of objects (one record for each table row)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
    @SuppressWarnings( "unchecked" )    // Java static fields don't support generics so we can't use them to strongly type KeyValueRecordListener.class
	public KeyValueTableModel( final List<RecordType> records, final String ... keyPaths ) {
		MESSAGE_CENTER = new MessageCenter( "KeyValueTableModel" );
		EVENT_PROXY = MESSAGE_CENTER.registerSource( this, KeyValueRecordListener.class );
		
		KEY_VALUE_ADAPTOR = new KeyValueAdaptor();
		
		COLUMN_NAME_MAP = new HashMap<String,String>();
		COLUMN_CLASS_MAP = new HashMap<String,Class<?>>();
		COLUMN_EDITABLE_MAP = new HashMap<String,ColumnEditRule<RecordType>>();
		
		setDataSource( records, keyPaths );
	}
	
	
	/** Empty Constructor */
	public KeyValueTableModel() {
		this( new java.util.ArrayList<RecordType>(), "toString" );
	}
	
	
	/**
	 * Add the specified listener as a receiver of record modification events from this instance.
	 * @param listener object to receive events
	 */
	public void addKeyValueRecordListener( final KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> listener ) {
		MESSAGE_CENTER.registerTarget( listener, this, KeyValueRecordListener.class );
	}
	
	
	/**
	 * Remove the specified listener from receiving record modification events from this instance.
	 * @param listener object to be removed from receiving events
	 */
	public void removeKeyValueRecordListener( final KeyValueRecordListener<KeyValueTableModel<RecordType>,RecordType> listener ) {
		MESSAGE_CENTER.removeTarget( listener, this, KeyValueRecordListener.class );
	}
	
	
	/** 
	 * Set the records (row) and key paths (column accessors)
	 * @param records the list of objects (one record for each table row)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
	public void setDataSource( final List<RecordType> records, final String ... keyPaths ) {
		setRecords( records );
		setKeyPaths( keyPaths );
	}
	
	
	/** Get the record at the specified row index */
	public RecordType getRecordAtRow( final int row ) {
		return _records.get( row );
	}


	/** Get the records indexed by row */
	public List<RecordType> getRecords() {
		return _records;
	}
	
	
	/** 
	 * Set the records (row)
	 * @param records the list of objects (one record for each table row)
	 */
	public void setRecords( final List<RecordType> records ) {
		_records = records;
		fireTableDataChanged();
	}
	
	
	/**
	 * Set the key paths (column accessors)
	 * @param keyPaths specifies the array of key paths to get the data to display (one key path for each column)
	 */
	public void setKeyPaths( final String ... keyPaths ) {
		_keyPaths = keyPaths;
		if ( keyPaths != null ) {
			for ( final String keyPath : keyPaths ) {
                // generate a default column name if one has not already been set
                if ( !COLUMN_NAME_MAP.containsKey( keyPath ) ) {
                    final String name = toColumnName( keyPath );
                    setColumnName( keyPath, name );
                }
			}
		}
		fireTableStructureChanged();
{'fraction_non_alphanumeric': 0.08905754635411663, 'fraction_numerical': 0.0019214141608223652, 'mean_word_length': 3.7950253339474895, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5516469', 'n_tokens_mistral': 3074, 'n_tokens_neox': 2847, 'n_words': 1045}