de.unikonstanz.winter.crossref.node.doi.CrossrefDoiNodeModel.java Source code

Java tutorial

Introduction

Here is the source code for de.unikonstanz.winter.crossref.node.doi.CrossrefDoiNodeModel.java

Source

/*
 * ------------------------------------------------------------------------
 *  Copyright by KNIME GmbH, Konstanz, Germany
 *  Website: http://www.knime.org; Email: contact@knime.org
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, Version 3, as
 *  published by the Free Software Foundation.
 *
 *  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 Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses>.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs.
 *  Hence, KNIME and ECLIPSE are both independent programs and are not
 *  derived from each other. Should, however, the interpretation of the
 *  GNU GPL Version 3 ("License") under any applicable laws result in
 *  KNIME and ECLIPSE being a combined program, KNIME GMBH herewith grants
 *  you the additional permission to use and propagate KNIME together with
 *  ECLIPSE with only the license terms in place for ECLIPSE applying to
 *  ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the
 *  license terms of ECLIPSE themselves allow for the respective use and
 *  propagation of ECLIPSE together with KNIME.
 *
 *  Additional permission relating to nodes for KNIME that extend the Node
 *  Extension (and in particular that are based on subclasses of NodeModel,
 *  NodeDialog, and NodeView) and that only interoperate with KNIME through
 *  standard APIs ("Nodes"):
 *  Nodes are deemed to be separate and independent programs and to not be
 *  covered works.  Notwithstanding anything to the contrary in the
 *  License, the License does not apply to Nodes, you are not required to
 *  license Nodes under the License, and you are granted a license to
 *  prepare and propagate Nodes, in each case even if such Nodes are
 *  propagated with or for interoperation with KNIME.  The owner of a Node
 *  may freely choose the license terms applicable to such Node, including
 *  when such Node is propagated with or for interoperation with KNIME.
 * ------------------------------------------------------------------------
 *
 * History
 *   Sep 25, 2014 (Patrick Winter): created
 */
package de.unikonstanz.winter.crossref.node.doi;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;

import org.knime.core.data.DataCell;
import org.knime.core.data.DataColumnSpec;
import org.knime.core.data.DataColumnSpecCreator;
import org.knime.core.data.DataRow;
import org.knime.core.data.DataTableSpec;
import org.knime.core.data.IntValue;
import org.knime.core.data.MissingCell;
import org.knime.core.data.StringValue;
import org.knime.core.data.collection.ListCell;
import org.knime.core.data.container.AbstractCellFactory;
import org.knime.core.data.container.CellFactory;
import org.knime.core.data.container.ColumnRearranger;
import org.knime.core.data.date.DateAndTimeCell;
import org.knime.core.data.def.DoubleCell;
import org.knime.core.data.def.IntCell;
import org.knime.core.data.def.StringCell;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.ExecutionMonitor;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.NodeModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;

import com.fasterxml.jackson.databind.JsonNode;

import de.unikonstanz.winter.crossref.CrossrefUtil;

/**
 * @author Patrick Winter, University of Konstanz
 */
public class CrossrefDoiNodeModel extends NodeModel {

    private static final NodeLogger LOGGER = NodeLogger.getLogger(CrossrefDoiNodeModel.class);

    private CrossrefDoiNodeConfig m_config = new CrossrefDoiNodeConfig();

    /**
     * Create this nodes model.
     */
    public CrossrefDoiNodeModel() {
        super(1, 1);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected BufferedDataTable[] execute(BufferedDataTable[] inData, ExecutionContext exec) throws Exception {
        ColumnRearranger rearranger = createColumnRearranger(inData[0].getDataTableSpec());
        BufferedDataTable out = exec.createColumnRearrangeTable(inData[0], rearranger, exec);
        return new BufferedDataTable[] { out };
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException {
        int columnIndex = inSpecs[0].findColumnIndex(m_config.getDoiColumn());
        if (columnIndex < 0 || !inSpecs[0].getColumnSpec(columnIndex).getType().isCompatible(StringValue.class)) {
            throw new InvalidSettingsException("No valid doi column selected");
        }
        return new DataTableSpec[] { createColumnRearranger(inSpecs[0]).createSpec() };
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void loadInternals(final File nodeInternDir, final ExecutionMonitor exec)
            throws IOException, CanceledExecutionException {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void saveInternals(final File nodeInternDir, final ExecutionMonitor exec)
            throws IOException, CanceledExecutionException {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void saveSettingsTo(final NodeSettingsWO settings) {
        m_config.save(settings);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException {
        CrossrefDoiNodeConfig config = new CrossrefDoiNodeConfig();
        config.load(settings);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException {
        CrossrefDoiNodeConfig config = new CrossrefDoiNodeConfig();
        config.load(settings);
        m_config = config;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void reset() {

    }

    /**
     * Creates the column rearranger that adds the additional columns to the
     * input table.
     * 
     * @param inSpec
     *            Spec of the input table
     * @return Column rearranger that adds the additional columns
     * @throws InvalidSettingsException
     *             If the configured doi column could not be found in the input
     *             spec
     */
    private ColumnRearranger createColumnRearranger(final DataTableSpec inSpec) throws InvalidSettingsException {
        final int columnIndex = inSpec.findColumnIndex(m_config.getDoiColumn());
        if (columnIndex < 0) {
            throw new InvalidSettingsException("No valid doi column selected");
        }
        ColumnRearranger rearranger = new ColumnRearranger(inSpec);
        DataColumnSpec[] newColSpecs = new DataColumnSpec[37];
        newColSpecs[0] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Publisher"),
                StringCell.TYPE).createSpec();
        newColSpecs[1] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Title"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[2] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Reference Count"),
                IntCell.TYPE).createSpec();
        newColSpecs[3] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Source"),
                StringCell.TYPE).createSpec();
        newColSpecs[4] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Prefix"),
                StringCell.TYPE).createSpec();
        newColSpecs[5] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Member"),
                StringCell.TYPE).createSpec();
        newColSpecs[6] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Type"),
                StringCell.TYPE).createSpec();
        newColSpecs[7] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Created"),
                DateAndTimeCell.TYPE).createSpec();
        newColSpecs[8] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Deposited"),
                DateAndTimeCell.TYPE).createSpec();
        newColSpecs[9] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Indexed"),
                DateAndTimeCell.TYPE).createSpec();
        newColSpecs[10] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Issued"),
                ListCell.getCollectionType(IntCell.TYPE)).createSpec();
        newColSpecs[11] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Subtitle"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[12] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Container Title"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[13] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Issue"),
                StringCell.TYPE).createSpec();
        newColSpecs[14] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Volume"),
                StringCell.TYPE).createSpec();
        newColSpecs[15] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Page"),
                StringCell.TYPE).createSpec();
        newColSpecs[16] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Article Number"),
                StringCell.TYPE).createSpec();
        newColSpecs[17] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Published Print"),
                ListCell.getCollectionType(IntCell.TYPE)).createSpec();
        newColSpecs[18] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Published Online"),
                ListCell.getCollectionType(IntCell.TYPE)).createSpec();
        newColSpecs[19] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Subject"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[20] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "ISSN"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[21] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "ISBN"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[22] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Archive"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[23] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "License"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[24] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Funder"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[25] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Assertion"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[26] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Author"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[27] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Editor"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[28] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Chair"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[29] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Translator"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[30] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Update To"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[31] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Update Policy"),
                StringCell.TYPE).createSpec();
        newColSpecs[32] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Link"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[33] = new DataColumnSpecCreator(
                DataTableSpec.getUniqueColumnName(inSpec, "Clinical Trial Number"),
                ListCell.getCollectionType(StringCell.TYPE)).createSpec();
        newColSpecs[34] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Alternative ID"),
                StringCell.TYPE).createSpec();
        newColSpecs[35] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "Score"),
                DoubleCell.TYPE).createSpec();
        newColSpecs[36] = new DataColumnSpecCreator(DataTableSpec.getUniqueColumnName(inSpec, "URL"),
                StringCell.TYPE).createSpec();
        CellFactory factory = new AbstractCellFactory(newColSpecs) {
            @Override
            public DataCell[] getCells(DataRow row) {
                DataCell doiCell = row.getCell(columnIndex);
                return informationForDoi(doiCell);
            }
        };
        rearranger.append(factory);
        return rearranger;
    }

    /**
     * Creates a cell array containing all retrieved information for the given
     * DOI.
     * 
     * @param doiCell
     *            Cell containing the DOI
     * @return Cells containing the retrieved information or missing cells if
     *         the doiCell is invalid
     */
    private static DataCell[] informationForDoi(final DataCell doiCell) {
        if (doiCell.isMissing() || !doiCell.getType().isCompatible(StringValue.class)) {
            return CrossrefUtil.createMissingCells(37, null);
        }
        String doi = ((StringValue) doiCell).getStringValue();
        String url = CrossrefUtil.API_BASE_URL + "/works/" + doi;
        JsonNode root = null;
        try {
            root = CrossrefUtil.getJsonForUrl(url);
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
            return CrossrefUtil.createMissingCells(37, e.getMessage());
        }
        DataCell[] cells = new DataCell[37];
        JsonNode message = root.get("message");
        cells[0] = CrossrefUtil.nodeToStringCell(message.get("publisher"));
        cells[1] = CrossrefUtil.nodeToStringListCell(message.get("title"));
        cells[2] = CrossrefUtil.nodeToIntCell(message.get("reference-count"));
        cells[3] = CrossrefUtil.nodeToStringCell(message.get("source"));
        cells[4] = CrossrefUtil.nodeToStringCell(message.get("prefix"));
        cells[5] = CrossrefUtil.nodeToStringCell(message.get("member"));
        cells[6] = CrossrefUtil.nodeToStringCell(message.get("type"));
        cells[7] = nodeToDateCell(message.get("created"));
        cells[8] = nodeToDateCell(message.get("deposited"));
        cells[9] = nodeToDateCell(message.get("indexed"));
        cells[10] = partialDateNodeToIntListCell(message.get("issued"));
        cells[11] = CrossrefUtil.nodeToStringListCell(message.get("subtitle"));
        cells[12] = CrossrefUtil.nodeToStringListCell(message.get("container-title"));
        cells[13] = CrossrefUtil.nodeToStringCell(message.get("issue"));
        cells[14] = CrossrefUtil.nodeToStringCell(message.get("volume"));
        cells[15] = CrossrefUtil.nodeToStringCell(message.get("page"));
        cells[16] = CrossrefUtil.nodeToStringCell(message.get("article-number"));
        cells[17] = partialDateNodeToIntListCell(message.get("published-print"));
        cells[18] = partialDateNodeToIntListCell(message.get("published-online"));
        cells[19] = CrossrefUtil.nodeToStringListCell(message.get("subject"));
        cells[20] = CrossrefUtil.nodeToStringListCell(message.get("ISSN"));
        cells[21] = CrossrefUtil.nodeToStringListCell(message.get("ISBN"));
        cells[22] = CrossrefUtil.nodeToStringListCell(message.get("archive"));
        cells[23] = toStringListCell(message, "license"); // TODO
        cells[24] = toStringListCell(message, "funder"); // TODO
        cells[25] = toStringListCell(message, "assertion"); // TODO
        cells[26] = toStringListCell(message, "author"); // TODO
        cells[27] = toStringListCell(message, "editor"); // TODO
        cells[28] = toStringListCell(message, "chair"); // TODO
        cells[29] = toStringListCell(message, "translator"); // TODO
        cells[30] = toStringListCell(message, "update-to"); // TODO
        cells[31] = CrossrefUtil.nodeToStringCell(message.get("update-policy"));
        cells[32] = toStringListCell(message, "link"); // TODO
        cells[33] = toStringListCell(message, "clinical-trail-number"); // TODO
        cells[34] = CrossrefUtil.nodeToStringCell(message.get("alternative-id"));
        cells[35] = CrossrefUtil.nodeToDoubleCell(message.get("score"));
        cells[36] = CrossrefUtil.nodeToStringCell(message.get("URL"));
        return cells;
    }

    private static DataCell nodeToDateCell(final JsonNode node) {
        if (CrossrefUtil.isNull(node)) {
            return new MissingCell(null);
        }
        JsonNode timestamp = node.get("timestamp");
        if (CrossrefUtil.isNull(timestamp)) {
            return new MissingCell(null);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp.asLong());
        return new DateAndTimeCell(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND));
    }

    private static DataCell partialDateNodeToIntListCell(final JsonNode node) {
        if (CrossrefUtil.isNull(node)) {
            return new MissingCell(null);
        }
        JsonNode dateParts = node.get("date-parts");
        if (CrossrefUtil.isNull(dateParts)) {
            return new MissingCell(null);
        }
        return CrossrefUtil.nodeToIntListCell(dateParts.iterator().next());
    }

    private static DataCell toStringListCell(final JsonNode node, final String field) {
        // TODO
        return new MissingCell(null);
    }

}