Java tutorial
package org.cytoscape.tableimport.internal.task; /* * #%L * Cytoscape Table Import Impl (table-import-impl) * $Id:$ * $HeadURL:$ * %% * Copyright (C) 2006 - 2013 The Cytoscape Consortium * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-2.1.html>. * #L% */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.cytoscape.io.read.CyNetworkReader; import org.cytoscape.io.read.CyNetworkReaderManager; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNode; import org.cytoscape.model.SavePolicy; import org.cytoscape.model.subnetwork.CyRootNetwork; import org.cytoscape.property.AbstractConfigDirPropsReader; import org.cytoscape.property.CyProperty; import org.cytoscape.service.util.CyServiceRegistrar; import org.cytoscape.tableimport.internal.reader.ExcelNetworkSheetReader; import org.cytoscape.tableimport.internal.reader.GraphReader; import org.cytoscape.tableimport.internal.reader.NetworkTableMappingParameters; import org.cytoscape.tableimport.internal.reader.NetworkTableReader; import org.cytoscape.tableimport.internal.reader.SupportedFileType; import org.cytoscape.tableimport.internal.reader.TextDelimiter; import org.cytoscape.tableimport.internal.ui.PreviewTablePanel; import org.cytoscape.tableimport.internal.util.AttributeDataType; import org.cytoscape.tableimport.internal.util.ImportType; import org.cytoscape.tableimport.internal.util.SourceColumnSemantic; import org.cytoscape.tableimport.internal.util.TypeUtil; import org.cytoscape.util.swing.IconManager; import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.layout.CyLayoutAlgorithmManager; import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.model.CyNetworkViewFactory; import org.cytoscape.work.AbstractTask; import org.cytoscape.work.Task; import org.cytoscape.work.TaskIterator; import org.cytoscape.work.TaskMonitor; import org.cytoscape.work.Tunable; import org.cytoscape.work.TunableValidator; import org.cytoscape.work.util.ListMultipleSelection; import org.cytoscape.work.util.ListSelection; import org.cytoscape.work.util.ListSingleSelection; public class LoadNetworkReaderTask extends AbstractTask implements CyNetworkReader, TunableValidator { private InputStream is; private String fileType; private CyNetwork[] networks; private String inputName; private GraphReader reader; private CyNetworkReader netReader; private CyServiceRegistrar serviceRegistrar; private PreviewTablePanel previewPanel; private String networkName; private URI uri; private File tempFile; private TaskMonitor taskMonitor; @Tunable(description = "Text Delimiters:", context = "both") public ListMultipleSelection<String> delimiters; @Tunable(description = "Text Delimiters for data list type:", context = "both") public ListSingleSelection<String> delimitersForDataList; @Tunable(description = "Start Load Row:", context = "both") public int startLoadRow = -1; @Tunable(description = "First row used for column names:", context = "both") public boolean firstRowAsColumnNames; @Tunable(description = "Column for source interaction:", context = "both") public int indexColumnSourceInteraction = -1; @Tunable(description = "Column for target interaction:", context = "both") public int indexColumnTargetInteraction = -1; @Tunable(description = "Column for interaction type:", context = "both") public int indexColumnTypeInteraction = -1; @Tunable(description = "Default interaction type:", context = "both") public String defaultInteraction = TypeUtil.DEFAULT_INTERACTION; @Tunable(description = "List of column data types ordered by column index (e.g. \"string,int,long,double,boolean,intlist\" or just \"s,i,l,d,b,il\"):", context = "nongui") public String dataTypeList; private NetworkTableMappingParameters ntmp; public LoadNetworkReaderTask(final CyServiceRegistrar serviceRegistrar) { this.serviceRegistrar = serviceRegistrar; List<String> tempList = new ArrayList<>(); tempList.add(TextDelimiter.COMMA.getDelimiter()); tempList.add(TextDelimiter.SEMICOLON.getDelimiter()); tempList.add(TextDelimiter.SPACE.getDelimiter()); tempList.add(TextDelimiter.TAB.getDelimiter()); delimiters = new ListMultipleSelection<>(tempList); tempList = new ArrayList<>(); tempList.add(TextDelimiter.PIPE.getDelimiter()); tempList.add(TextDelimiter.BACKSLASH.getDelimiter()); tempList.add(TextDelimiter.SLASH.getDelimiter()); tempList.add(TextDelimiter.COMMA.getDelimiter()); delimitersForDataList = new ListSingleSelection<>(tempList); } public void setInputFile(final InputStream is, final String fileType, final String inputName, final URI uriName, final IconManager iconManager) { this.is = is; this.fileType = fileType; this.inputName = inputName; this.uri = uriName; previewPanel = new PreviewTablePanel(ImportType.NETWORK_IMPORT, iconManager); try { tempFile = File.createTempFile("temp", this.fileType); tempFile.deleteOnExit(); FileOutputStream os = new FileOutputStream(tempFile); int read = 0; byte[] bytes = new byte[1024]; while ((read = is.read(bytes)) != -1) { os.write(bytes, 0, read); } os.flush(); os.close(); this.is = new FileInputStream(tempFile); } catch (Exception e) { this.is = null; e.printStackTrace(); } List<String> tempList = new ArrayList<>(); tempList = new ArrayList<>(); tempList.add(TextDelimiter.TAB.getDelimiter()); tempList.add(TextDelimiter.COMMA.getDelimiter()); delimiters.setSelectedValues(tempList); delimitersForDataList.setSelectedValue(TextDelimiter.PIPE.getDelimiter()); } @Override public void run(final TaskMonitor tm) throws Exception { tm.setTitle("Loading network from table"); tm.setProgress(0.0); tm.setStatusMessage("Loading network..."); taskMonitor = tm; final List<String> attrNameList = new ArrayList<>(); int colCount; String[] attributeNames; final CyNetworkReaderManager networkReaderManager = serviceRegistrar .getService(CyNetworkReaderManager.class); if (is != null) netReader = networkReaderManager.getReader(is, inputName); if (netReader == null) netReader = networkReaderManager.getReader(uri, inputName); if (netReader instanceof CombineReaderAndMappingTask) { Workbook workbook = null; // Load Spreadsheet data for preview. if (fileType != null && (fileType.equalsIgnoreCase(SupportedFileType.EXCEL.getExtension()) || fileType.equalsIgnoreCase(SupportedFileType.OOXML.getExtension())) && workbook == null) { try { workbook = WorkbookFactory.create(new FileInputStream(tempFile)); } catch (InvalidFormatException e) { //e.printStackTrace(); throw new IllegalArgumentException("Could not read Excel file. Maybe the file is broken?", e); } finally { } } netReader = null; if (startLoadRow > 0) startLoadRow--; final int startLoadRowTemp = firstRowAsColumnNames ? 0 : startLoadRow; previewPanel.updatePreviewTable(workbook, fileType, tempFile.getAbsolutePath(), new FileInputStream(tempFile), delimiters.getSelectedValues(), null, startLoadRowTemp); colCount = previewPanel.getPreviewTable().getColumnModel().getColumnCount(); Object curName = null; if (firstRowAsColumnNames) { previewPanel.setFirstRowAsColumnNames(); startLoadRow++; } final SourceColumnSemantic[] types = previewPanel.getTypes(); for (int i = 0; i < colCount; i++) { curName = previewPanel.getPreviewTable().getColumnModel().getColumn(i).getHeaderValue(); if (attrNameList.contains(curName)) { int dupIndex = 0; for (int idx = 0; idx < attrNameList.size(); idx++) { if (curName.equals(attrNameList.get(idx))) { dupIndex = idx; break; } } if (!TypeUtil.allowsDuplicateName(ImportType.NETWORK_IMPORT, types[i], types[dupIndex])) { // TODO add message to user (Duplicate Column Name Found) return; } } if (curName == null) attrNameList.add("Column " + i); else attrNameList.add(curName.toString()); } attributeNames = attrNameList.toArray(new String[attrNameList.size()]); final SourceColumnSemantic[] typesCopy = Arrays.copyOf(types, types.length); final AttributeDataType[] dataTypes = previewPanel.getDataTypes(); final AttributeDataType[] dataTypesCopy = Arrays.copyOf(dataTypes, dataTypes.length); AttributeDataType[] tunableDataTypes = null; if (dataTypeList != null && !dataTypeList.trim().isEmpty()) tunableDataTypes = TypeUtil.parseDataTypeList(dataTypeList); if (tunableDataTypes != null && tunableDataTypes.length > 0) System.arraycopy(tunableDataTypes, 0, dataTypesCopy, 0, Math.min(tunableDataTypes.length, dataTypesCopy.length)); String[] listDelimiters = previewPanel.getListDelimiters(); if (listDelimiters == null || listDelimiters.length == 0) { listDelimiters = new String[dataTypes.length]; if (delimitersForDataList.getSelectedValue() != null) Arrays.fill(listDelimiters, delimitersForDataList.getSelectedValue()); } if (indexColumnSourceInteraction > 0) indexColumnSourceInteraction--; if (indexColumnTargetInteraction > 0) indexColumnTargetInteraction--; if (indexColumnTypeInteraction > 0) indexColumnTypeInteraction--; networkName = previewPanel.getSourceName(); ntmp = new NetworkTableMappingParameters(networkName, delimiters.getSelectedValues(), listDelimiters, attributeNames, dataTypesCopy, typesCopy, indexColumnSourceInteraction, indexColumnTargetInteraction, indexColumnTypeInteraction, defaultInteraction, startLoadRow, null); try { if (this.fileType.equalsIgnoreCase(SupportedFileType.EXCEL.getExtension()) || this.fileType.equalsIgnoreCase(SupportedFileType.OOXML.getExtension())) { final Sheet sheet = workbook.getSheet(networkName); reader = new ExcelNetworkSheetReader(networkName, sheet, ntmp, nMap, rootNetwork, serviceRegistrar); } else { networkName = this.inputName; reader = new NetworkTableReader(networkName, new FileInputStream(tempFile), ntmp, nMap, rootNetwork, serviceRegistrar); } } catch (Exception ioe) { tm.showMessage(TaskMonitor.Level.ERROR, "Unable to read network: " + ioe.getMessage()); return; } loadNetwork(tm); tm.setProgress(1.0); } else { networkName = this.inputName; insertTasksAfterCurrentTask(netReader); } } private void loadNetwork(final TaskMonitor tm) throws IOException { final CyNetwork network = this.rootNetwork.addSubNetwork(); //CytoscapeServices.cyNetworkFactory.createNetwork(); tm.setProgress(0.10); this.reader.setNetwork(network); if (this.cancelled) return; this.reader.read(); tm.setProgress(0.80); if (this.cancelled) return; networks = new CyNetwork[] { network }; tm.setProgress(1.0); } @Override public CyNetworkView buildCyNetworkView(CyNetwork net) { if (netReader != null) { return netReader.buildCyNetworkView(net); } else { final CyNetworkView view = networkViewFactory.createNetworkView(net); final CyLayoutAlgorithm layout = serviceRegistrar.getService(CyLayoutAlgorithmManager.class) .getDefaultLayout(); TaskIterator itr = layout.createTaskIterator(view, layout.getDefaultLayoutContext(), CyLayoutAlgorithm.ALL_NODE_VIEWS, ""); Task nextTask = itr.next(); try { nextTask.run(taskMonitor); } catch (Exception e) { throw new RuntimeException("Could not finish layout", e); } taskMonitor.setProgress(1.0); return view; } } @Override public CyNetwork[] getNetworks() { if (netReader != null) return netReader.getNetworks(); else return networks; } public String getName() { return networkName; } @Override public ValidationState getValidationState(Appendable errMsg) { try { if (indexColumnSourceInteraction <= 0) { if (indexColumnTargetInteraction <= 0) { errMsg.append("The network cannot be created without selecting the source and target columns."); return ValidationState.INVALID; } else { errMsg.append( "No edges will be created in the network; the source column is not selected.\nDo you want to continue?"); return ValidationState.REQUEST_CONFIRMATION; } } else { if (indexColumnTargetInteraction <= 0) { errMsg.append( "No edges will be created in the network; the target column is not selected.\nDo you want to continue?"); return ValidationState.REQUEST_CONFIRMATION; } else { return ValidationState.OK; } } } catch (IOException ioe) { ioe.printStackTrace(); return ValidationState.INVALID; } } // support import network in different collection private CyRootNetwork rootNetwork; public void setRootNetwork(CyRootNetwork rootNetwork) { this.rootNetwork = rootNetwork; } private Map<Object, CyNode> nMap; public void setNodeMap(Map<Object, CyNode> nMap) { this.nMap = nMap; } private CyNetworkViewFactory networkViewFactory; public void setNetworkViewFactory(CyNetworkViewFactory networkViewFactory) { this.networkViewFactory = networkViewFactory; } //----------------------------------------------------------------------------- // temporary implementation AT -- 27 June 2016 private String getString() { StringBuilder str = new StringBuilder("LoadNetworkReaderTask\n"); str.append("delimiters=").append(listToString(delimiters)).append("\n"); str.append("delimitersForDataList=").append(listToString(delimitersForDataList)).append("\n"); str.append("startLoadRow=" + startLoadRow + "\n"); str.append("firstRowAsColumnNames=").append(firstRowAsColumnNames ? "TRUE" : "FALSE").append("\n"); str.append("indexColumnSourceInteraction=" + indexColumnSourceInteraction + "\n"); str.append("indexColumnTargetInteraction=" + indexColumnTargetInteraction + "\n"); str.append("indexColumnTypeInteraction=" + indexColumnTypeInteraction + "\n"); str.append("defaultInteraction=").append(defaultInteraction).append("\n"); str.append("dataTypeList=").append(dataTypeList).append("\n"); return str.toString(); } private void setString(String state) { loadList(delimiters, fieldFromString(state, "delimiters")); loadList(delimitersForDataList, fieldFromString(state, "delimitersForDataList")); startLoadRow = Integer.parseInt(fieldFromString(state, "startLoadRow")); firstRowAsColumnNames = "TRUE".equals(fieldFromString(state, "firstRowAsColumnNames")); indexColumnSourceInteraction = intFromString(state, "indexColumnSourceInteraction"); indexColumnTypeInteraction = intFromString(state, "indexColumnTypeInteraction"); defaultInteraction = fieldFromString(state, "defaultInteraction"); dataTypeList = fieldFromString(state, "dataTypeList"); } private int intFromString(String s, String fieldName) { String fld = fieldFromString(s, fieldName); try { return Integer.parseInt(fld); } catch (NumberFormatException e) { } return 0; } static String DELIM = "\b"; private String listToString(ListSelection<String> set) { StringBuilder builder = new StringBuilder(); for (String s : set.getPossibleValues()) builder.append(s).append(DELIM); return builder.toString(); } private void loadList(ListSelection<String> set, String input) { ArrayList<String> delims = new ArrayList<String>(); String[] parsed = input.split(DELIM); delims.addAll(Arrays.asList(parsed)); set.setPossibleValues(delims); } private String fieldFromString(String s, String field) { int start = s.indexOf(field + "="); if (start > 0) { start += field.length() + 1; int end = s.indexOf("\n", start); if (end > 0) return s.substring(start, end); } return null; } //----------------------------------------------------------------------------- private String getProperty() { CyProperty<Properties> cyProperties = serviceRegistrar.getService(CyProperty.class, "(cyPropertyName=myApp.props)"); String propertyValue = ""; /// cyProperties.getProperty("network.load.config"); if (propertyValue != null && !propertyValue.isEmpty()) setString(propertyValue); return null; } private void saveProperty() { Properties stateProps = new Properties(); stateProps.setProperty("network.load.config", getString()); // TODO put it into the session or config file } //----------------------------------------------------------------------------- private static class PropsReader extends AbstractConfigDirPropsReader { public PropsReader(String name, String fileName) { super(name, fileName, SavePolicy.SESSION_FILE); } public static PropsReader makeReader(String props) { return new PropsReader("network.load.props", props); } } //----------------------------------------------------------------------------- }