/** * Update the query coverage component. Call this method if the effective selected table may have * changed. */ private void updateQueryCoverage() { if (coverageModel_.isSelected()) { Coverage coverage; if (tcModel_ == null) { coverage = null; } else { int[] rowMap = tcModel_.getViewModel().getRowMap(); ColumnData raData = raSelector_.getColumnData(); ColumnData decData = decSelector_.getColumnData(); ColumnData srData = srSelector_.getColumnData(); if (raData != null && decData != null) { DatasQuerySequenceFactory qsf = new DatasQuerySequenceFactory(raData, decData, srData, rowMap); try { StarTable table = tcModel_.getApparentStarTable(); ConeQueryRowSequence qseq = qsf.createQuerySequence(table); double resDeg = 1.0; coverage = new ConeQueryCoverage(qseq, resDeg); } catch (IOException e) { coverage = null; } } else { coverage = null; } } queryCoverageView_.setCoverage(coverage); updateOverlapCoverage(); } else { queryCoverageView_.setCoverage(null); } }
/** * Constructs and returns a worker thread which can perform a match as specified by the current * state of this component. * * @return new worker thread * @throws RuntimeException if the current state does not fully specify a multi query job; such * exceptions will have comprehensible messages */ private MatchWorker createMatchWorker() { /* Acquire state from this panel's GUI components. */ String sUrl = urlField_.getText(); if (sUrl == null || sUrl.trim().length() == 0) { throw new IllegalArgumentException("No " + service_.getName() + " URL given"); } URL serviceUrl; try { serviceUrl = new URL(sUrl); } catch (MalformedURLException e) { throw (IllegalArgumentException) new IllegalArgumentException("Bad " + service_.getName() + " URL syntax: " + sUrl) .initCause(e); } ConeErrorPolicy erract = (ConeErrorPolicy) erractSelector_.getSelectedItem(); TopcatModel tcModel = tcModel_; if (tcModel == null) { throw new NullPointerException("No table selected"); } final StarTable inTable = tcModel.getApparentStarTable(); int[] rowMap = tcModel.getViewModel().getRowMap(); ColumnData raData = raSelector_.getColumnData(); ColumnData decData = decSelector_.getColumnData(); ColumnData srData = srSelector_.getColumnData(); if (raData == null) { throw new NullPointerException("No RA column given"); } if (decData == null) { throw new NullPointerException("No Dec column given"); } Number parNum = parallelModel_.getNumber(); int parallelism = parNum == null ? 1 : parNum.intValue(); MulticoneMode mcMode = (MulticoneMode) modeSelector_.getSelectedItem(); StarTableFactory tfact = ControlWindow.getInstance().getTableFactory(); /* Assemble objects based on this information. */ ConeSearcher searcher = service_.createSearcher(serviceUrl, tfact); Coverage coverage = coverageModel_.isSelected() ? service_.getCoverage(serviceUrl) : null; DatasQuerySequenceFactory qsf = new DatasQuerySequenceFactory(raData, decData, srData, rowMap); ConeMatcher matcher = mcMode.createConeMatcher(searcher, erract, inTable, qsf, coverage, parallelism); ResultHandler resultHandler = mcMode.createResultHandler(this, tfact.getStoragePolicy(), tcModel, inTable); /* Create MatchWorker encapsulating all of this. */ MatchWorker worker = new MatchWorker(matcher, resultHandler, tcModel, inTable); /* Perform post-construction configuration of constituent objects * as required. */ qsf.setMatchWorker(worker); resultHandler.setMatchWorker(worker); /* Return worker thread. */ return worker; }
/** * Sends a table to a specific list of PLASTIC listeners. * * @param tcModel the table model to broadcast * @param hub hub object * @param plasticId registration ID for this application * @param recipients listeners to receive it; null means do a broadcast */ private void transmitTable( TopcatModel tcModel, final PlasticHubListener hub, final URI plasticId, final URI[] recipients) throws IOException { /* Write the data as a VOTable to a temporary file preparatory to * broadcast. */ final File tmpfile = File.createTempFile("plastic", ".vot"); final String tmpUrl = URLUtils.makeFileURL(tmpfile).toString(); tmpfile.deleteOnExit(); OutputStream ostrm = new BufferedOutputStream(new FileOutputStream(tmpfile)); try { new VOTableWriter(DataFormat.TABLEDATA, true) .writeStarTable(tcModel.getApparentStarTable(), ostrm); } catch (IOException e) { tmpfile.delete(); throw e; } finally { ostrm.close(); } /* Store a record of the table that was broadcast with its * state. */ int[] rowMap = tcModel.getViewModel().getRowMap(); idMap_.put(tmpUrl, new TableWithRows(tcModel, rowMap)); /* Do the broadcast, synchronously so that we don't delete the * temporary file too early, but in another thread so that we * don't block the GUI. */ new Thread("PLASTIC table broadcast") { public void run() { List argList = Arrays.asList(new Object[] {tmpUrl, tmpUrl}); Map responses = recipients == null ? hub.request(plasticId, MessageId.VOT_LOADURL, argList) : hub.requestToSubset( plasticId, MessageId.VOT_LOADURL, argList, Arrays.asList(recipients)); /* Delete the temp file. */ tmpfile.delete(); } }.start(); }
public ResultHandler createResultHandler( final JComponent parent, StoragePolicy policy, final TopcatModel inTcModel, StarTable inTable) { final int[] rowMap = inTcModel.getViewModel().getRowMap(); return new ResultHandler() { public void processResult(StarTable streamTable) throws IOException { RowSequence rseq = streamTable.getRowSequence(); final BitSet matchMask = new BitSet(); try { while (rseq.next()) { long irow = ((Number) rseq.getCell(0)).longValue(); if (irow < Integer.MAX_VALUE) { int jrow = rowMap == null ? (int) irow : rowMap[(int) irow]; matchMask.set(jrow); } } } finally { rseq.close(); } schedule( new Runnable() { public void run() { addSubset(parent, inTcModel, matchMask); } }); } /** * Using input from the user, adds a new (or reused) Row Subset to the given TopcatModel * based on a given BitSet. * * @param parent parent component * @param tcModel topcat model * @param matchMask mask for included rows */ public void addSubset(JComponent parent, TopcatModel tcModel, BitSet matchMask) { int nmatch = matchMask.cardinality(); Box nameLine = Box.createHorizontalBox(); JComboBox nameSelector = tcModel.createNewSubsetNameSelector(); nameSelector.setSelectedItem("multi" + service_.getLabel()); nameLine.add(new JLabel("Subset name: ")); nameLine.add(nameSelector); Object msg = new Object[] { "Multiple " + service_.getName() + " successful; " + "matches found for " + nmatch + " rows.", " ", "Define new subset for matched rows", nameLine, }; int opt = JOptionPane.showOptionDialog( parent, msg, "Multi-" + service_.getName() + " Success", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); String name = getSubsetName(nameSelector); if (opt == JOptionPane.OK_OPTION && name != null) { tcModel.addSubset(new BitsRowSubset(name, matchMask)); } } /** * Returns the subset name corresponding to the currently selected value of a row subset * selector box. * * @param rsetSelector combo box returned by TopcatModel.createNewSubsetNameSelector * @return subset name as string, or null */ private String getSubsetName(JComboBox rsetSelector) { Object item = rsetSelector.getSelectedItem(); if (item == null) { return null; } else if (item instanceof String) { String name = (String) item; return name.trim().length() > 0 ? name : null; } else if (item instanceof RowSubset) { return ((RowSubset) item).getName(); } else { assert false; return item.toString(); } } }; }