/** * Returns a best guess for the conversion to use for a given selected column. This will be one of * the ones associated with this selector (i.e. one of the ones in the conversion selector or the * sole one if there is no conversion selector). * * @param cinfo column description * @return suitable column converter */ private ColumnConverter guessConverter(ColumnInfo cinfo) { /* If there is only one permissible converter, return that. */ if (converter0_ != null) { return converter0_; } /* Otherwise, try to get clever. This is currently done on a * case-by-case basis rather than using an extensible framework * because there's a small number (1) of conversions that we know * about. If there were many, a redesign might be in order. */ String units = info_.getUnitString(); String cunits = cinfo.getUnitString(); if (units != null && cunits != null) { units = units.toLowerCase(); cunits = cunits.toLowerCase(); int nconv = convChooser_.getSize(); if (units.equals("radian") || units.equals("radians")) { if (cunits.startsWith("rad")) { for (int i = 0; i < nconv; i++) { ColumnConverter conv = (ColumnConverter) convChooser_.getElementAt(i); if (conv.toString().toLowerCase().startsWith("rad")) { return conv; } } } else if (cunits.startsWith("deg")) { for (int i = 0; i < nconv; i++) { ColumnConverter conv = (ColumnConverter) convChooser_.getElementAt(i); if (conv.toString().toLowerCase().startsWith("deg")) { return conv; } } } else if (cunits.startsWith("hour") || cunits.equals("hr") || cunits.equals("hrs")) { for (int i = 0; i < nconv; i++) { ColumnConverter conv = (ColumnConverter) convChooser_.getElementAt(i); if (conv.toString().toLowerCase().startsWith("hour")) { return conv; } } } else if (cunits.startsWith("arcmin")) { for (int i = 0; i < nconv; i++) { ColumnConverter conv = (ColumnConverter) convChooser_.getElementAt(i); if (conv.toString().toLowerCase().startsWith("arcmin")) { return conv; } } } else if (cunits.startsWith("arcsec")) { for (int i = 0; i < nconv; i++) { ColumnConverter conv = (ColumnConverter) convChooser_.getElementAt(i); if (conv.toString().toLowerCase().startsWith("arcsec")) { return conv; } } } } } /* Return null if we haven't found a match yet. */ return null; }
/** * Returns a combobox model which allows selection of columns from a table model suitable for a * given argument. The elements of the model are instances of ColumnData (or null). */ private static ComboBoxModel makeColumnModel(TopcatModel tcModel, ValueInfo argInfo) { /* With no table, the model is empty. */ if (tcModel == null) { return new DefaultComboBoxModel(new Object[1]); } /* Make the model. */ ComboBoxModel model = new ColumnDataComboBoxModel(tcModel, argInfo.getContentClass(), argInfo.isNullable()); /* Have a guess what will be a good value for the initial * selection. There is scope for doing this better. */ ColumnData selected = null; String ucd = argInfo.getUCD(); if (ucd != null) { for (int i = 0; i < model.getSize() && selected == null; i++) { Object item = model.getElementAt(i); if (item instanceof ColumnData) { ColumnData cdata = (ColumnData) item; ColumnInfo info = cdata.getColumnInfo(); if (info.getUCD() != null && matchUcds(info.getUCD(), ucd)) { selected = cdata; } } } } String name = argInfo.getName().toLowerCase(); if (name != null) { for (int i = 0; i < model.getSize() && selected == null; i++) { Object item = model.getElementAt(i); if (item instanceof ColumnData) { ColumnData cdata = (ColumnData) item; ColumnInfo info = cdata.getColumnInfo(); String cname = info.getName(); if (cname != null && cname.toLowerCase().startsWith(name)) { selected = cdata; } } } } if (selected != null) { model.setSelectedItem(selected); } return model; }
/** * Constructs a new model for a given table and value type. * * @param tcModel table model * @param info description of the kind of column which is required */ public ColumnSelectorModel(TopcatModel tcModel, ValueInfo info) { info_ = info; selectionListener_ = new SelectionListener(); /* Get a suitable model for selection of the unit converter, if * appropriate. */ String units = info.getUnitString(); ColumnConverter[] converters = ColumnConverter.getConverters(info); if (converters.length > 1) { converter0_ = null; convChooser_ = new DefaultComboBoxModel(converters); convChooser_.addListDataListener(selectionListener_); } else { convChooser_ = null; converter0_ = converters[0]; } setTable(tcModel); }
/** * Turns a TopcatModel into a StarTable, ready for serialization. * * @param tcModel model * @return table */ public StarTable encode(TopcatModel tcModel) { /* Prepare table data and metadata for use and adjustment. */ final StarTable dataModel = tcModel.getDataModel(); List<DescribedValue> paramList = new ArrayList<DescribedValue>(); long nrow = dataModel.getRowCount(); ColumnStarTable extraTable = ColumnStarTable.makeTableWithRows(nrow); /* Mark as serialized TopcatModel. */ paramList.add(new DescribedValue(IS_TCMODEL_INFO, Boolean.TRUE)); paramList.add(new DescribedValue(VERSION_INFO, TopcatUtils.getVersion())); /* Record label. */ paramList.add(new DescribedValue(LABEL_INFO, tcModel.getLabel())); /* Record column sequences. */ ColumnList colList = tcModel.getColumnList(); int nCol = colList.size(); int[] icols = new int[nCol]; boolean[] activs = new boolean[nCol]; for (int jc = 0; jc < nCol; jc++) { icols[jc] = colList.getColumn(jc).getModelIndex(); activs[jc] = colList.isActive(jc); } paramList.add(new DescribedValue(COLS_INDEX_INFO, icols)); paramList.add(new DescribedValue(COLS_VISIBLE_INFO, activs)); /* Record whether to broadcast rows. */ paramList.add(new DescribedValue(SEND_ROWS_INFO, tcModel.getRowSendModel().isSelected())); /* Record sort order. */ SortOrder sortOrder = tcModel.getSelectedSort(); TableColumn sortCol = sortOrder == null ? null : sortOrder.getColumn(); if (sortCol != null) { int icolSort = tcModel.getColumnList().indexOf(sortCol); if (icolSort >= 0) { boolean sense = tcModel.getSortSenseModel().isSelected(); paramList.add(new DescribedValue(SORT_COLUMN_INFO, new Integer(icolSort))); paramList.add(new DescribedValue(SORT_SENSE_INFO, Boolean.valueOf(sense))); } } /* Store row subset flags in a new column. */ List<RowSubset> subsetList = new ArrayList<RowSubset>(tcModel.getSubsets()); boolean hadAll = subsetList.remove(RowSubset.ALL); assert hadAll; RowSubset[] subsets = subsetList.toArray(new RowSubset[0]); if (subsets.length > 0) { String[] subsetNames = new String[subsets.length]; for (int is = 0; is < subsets.length; is++) { subsetNames[is] = subsets[is].getName(); } paramList.add(new DescribedValue(SUBSET_NAMES_INFO, subsetNames)); Object flagsArray = createFlagsArray(dataModel, subsets); if (flagsArray != null) { ColumnData flagsCol = ArrayColumn.makeColumn(SUBSET_FLAGS_INFO.getName(), flagsArray); ColumnInfo info = new ColumnInfo(SUBSET_FLAGS_INFO); info.setContentClass(flagsCol.getColumnInfo().getContentClass()); flagsCol.setColumnInfo(info); extraTable.addColumn(flagsCol); } } /* Record current subset. */ int iset = subsetList.indexOf(tcModel.getSelectedSubset()); if (iset >= 0) { paramList.add(new DescribedValue(CURRENT_SUBSET_INFO, new Integer(iset))); } /* Copy parameters from the input table. * Be paranoid about possible name clashes. */ for (Iterator it = dataModel.getParameters().iterator(); it.hasNext(); ) { Object item = it.next(); if (item instanceof DescribedValue) { DescribedValue dval = (DescribedValue) item; String name = dval.getInfo().getName(); String utype = dval.getInfo().getUtype(); if (!isCodecUtype(utype)) { paramList.add(dval); } } } /* Prepare the output table object. */ List<StarTable> joinList = new ArrayList<StarTable>(); joinList.add(dataModel); if (extraTable.getColumnCount() > 0) { joinList.add(extraTable); } StarTable[] joins = joinList.toArray(new StarTable[0]); StarTable outTable = new MetaCopyStarTable(new JoinStarTable(joinList.toArray(new StarTable[0]))); outTable.setName(dataModel.getName()); /* Set the parameters. */ outTable.getParameters().clear(); outTable.getParameters().addAll(paramList); /* Return the result. */ return outTable; }
/** * Returns the column index of a codec-specific column from the input table. * * @param info metadata description * @return column index for the given info, or -1 if absent */ public int getCodecColumnIndex(ValueInfo info) { String utype = info.getUtype(); return codecIcolMap_.containsKey(utype) ? codecIcolMap_.get(utype) : -1; }
/** * Returns a codec-specific parameter value from the input table. * * @param info metadata description * @return value stored under the given info, or null if absent */ public Object getCodecValue(ValueInfo info) { String utype = info.getUtype(); DescribedValue dval = codecParamMap_.get(utype); return dval == null ? null : dval.getValue(); }