/* * ------------------------------------------------------------------ * This source code, its documentation and all appendant files * are protected by copyright law. All rights reserved. * * Copyright, 2003 - 2010 * University of Konstanz, Germany * Chair for Bioinformatics and Information Mining (Prof. M. Berthold) * and KNIME GmbH, Konstanz, Germany * * You may not modify, publish, transmit, transfer or sell, reproduce, * create derivative works from, distribute, perform, display, or in * any way exploit any of the content, in whole or in part, except as * otherwise expressly permitted in writing by the copyright owner or * as specified in the license file distributed with this product. * * If you have any questions please contact the copyright holder: * website: www.knime.org * email: contact@knime.org * --------------------------------------------------------------------- * * * History * 12.09.2008 (gabriel): created */ package de.mpicbg.knime.scripting.r.generic; import java.awt.BorderLayout; import java.awt.Font; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.zip.ZipEntry; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.text.DefaultCaret; import org.apache.commons.lang.StringUtils; import org.knime.core.node.CanceledExecutionException; import org.knime.core.node.ExecutionMonitor; import org.knime.core.node.NodeLogger; import org.knime.core.node.port.PortObject; import org.knime.core.node.port.PortObjectSpec; import org.knime.core.node.port.PortObjectZipInputStream; import org.knime.core.node.port.PortObjectZipOutputStream; import org.knime.core.node.port.PortType; import org.knime.core.util.FileUtil; import org.rosuda.REngine.Rserve.RConnection; import de.mpicbg.knime.scripting.core.exceptions.KnimeScriptingException; import de.mpicbg.knime.scripting.r.RUtils; import de.mpicbg.knime.scripting.r.node.snippet.RSnippetNodeModel; /** * {@deprecated} * A port object for R model port providing a file containing a R model. * * @author Kilian Thiel, University of Konstanz */ public class RPortObject implements PortObject { /** * Convenience access member for <code>new PortType(RPortObject.class)</code>. */ public static final PortType TYPE = new PortType(RPortObject.class); private static final NodeLogger LOGGER = NodeLogger.getLogger(RPortObject.class); private final File m_fileR; /** * Creates an instance of <code>RPortObject</code> with given file. * * @param fileR The file containing a R model. */ public RPortObject(final File fileR) { m_fileR = fileR; } /** * {@inheritDoc} */ public RPortObjectSpec getSpec() { return RPortObjectSpec.INSTANCE; } /** * {@inheritDoc} */ public String getSummary() { return "R Object"; } /** * Returns the file containing the R model. * * @return the file containing the R model. */ public File getFile() { return m_fileR; } /** * Serializer used to save this port object. * * @return a {@link RPortObject} */ public static PortObjectSerializer<RPortObject> getPortObjectSerializer() { return new PortObjectSerializer<RPortObject>() { /** {@inheritDoc} */ @Override public void savePortObject(final RPortObject portObject, final PortObjectZipOutputStream out, final ExecutionMonitor exec) throws IOException, CanceledExecutionException { out.putNextEntry(new ZipEntry("knime.R")); FileInputStream fis = new FileInputStream(portObject.m_fileR); FileUtil.copy(fis, out); fis.close(); out.close(); } /** {@inheritDoc} */ @Override public RPortObject loadPortObject( final PortObjectZipInputStream in, final PortObjectSpec spec, final ExecutionMonitor exec) throws IOException, CanceledExecutionException { in.getNextEntry(); File fileR = File.createTempFile("~knime", ".R"); FileOutputStream fos = new FileOutputStream(fileR); FileUtil.copy(in, fos); in.close(); fos.close(); return new RPortObject(fileR); } }; } /** * {@inheritDoc} */ public JComponent[] getViews() { JPanel panel = new JPanel(new BorderLayout()); JTextArea jep = new JTextArea(); // prevent autoscrolling DefaultCaret caret = (DefaultCaret)jep.getCaret(); caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); jep.setEditable(false); panel.setName("R Port View"); RConnection connection; try { connection = RUtils.createConnection(); } catch (KnimeScriptingException e) { jep.setText(e.getMessage()); panel.add(new JScrollPane(jep)); e.printStackTrace(); return new JComponent[]{panel}; } jep.setFont(new Font("Monospaced", Font.PLAIN, 14)); try { RUtils.loadGenericInputs(Collections.singletonMap(RSnippetNodeModel.R_OUTVAR_BASE_NAME, new File(getFilePath())), connection); // to get structure information about the output object, one needs to use capture the output // str(...) does not provide any return value connection.voidEval("tempfile <- tempfile(pattern = 'structure_', fileext = '.txt')"); List<String> objects = Arrays.asList(connection.eval("ls()").asStrings()); for(String obj : objects) { // exclude files which where created temporary TODO: it is too dependent on how temporary file variables are named... other solution? if(!(obj.equals("tempfile") || obj.equals("tmpwfile"))) connection.voidEval("capture.output(print(\"" + obj + "\"), str(" + obj + "), file = tempfile, append = TRUE)"); } String[] structure = connection.eval("readLines(tempfile)").asStrings(); connection.voidEval("unlink(tempfile)"); String summary = StringUtils.join(structure, '\n'); jep.setText(summary); } catch (Exception e) { jep.setText("Failed to retrieve the structure of R objects from port file " + getFilePath()); } connection.close(); panel.add(new JScrollPane(jep)); return new JComponent[]{panel}; } /** * @return The path of the R model file if available, otherwise "No file available". */ String getFilePath() { if (m_fileR != null) { return m_fileR.getAbsolutePath(); } return "No file available"; } /** * @return The input of the R model file. */ String getModelData() { StringBuffer buf = new StringBuffer(); if (m_fileR != null && m_fileR.exists() && m_fileR.canRead()) { try { BufferedReader reader = new BufferedReader(new FileReader(m_fileR)); String line; while ((line = reader.readLine()) != null) { buf.append(line); } } catch (Exception e) { LOGGER.warn("R model could not be read from file!"); buf.append("R model could no be read from file!"); } } return buf.toString(); } /** * {@inheritDoc} */ @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof RPortObject)) { return false; } RPortObject rPort = (RPortObject) obj; return m_fileR.equals(rPort.m_fileR); } /** * {@inheritDoc} */ @Override public int hashCode() { return m_fileR.hashCode(); } }