<commit_before>/**
 * PODD is an OWL ontology database used for scientific project management
 * 
 * Copyright (C) 2009-2013 The University Of Queensland
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU Affero General Public License as published by the Free Software Foundation, either version 3
 * 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
 * Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */
package au.org.plantphenomics.podd;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openrdf.model.Literal;
import org.openrdf.model.Model;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.Rio;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.bytecode.opencsv.CSVReader;

import com.github.podd.client.api.PoddClientException;
import com.github.podd.client.impl.restlet.RestletPoddClientImpl;
import com.github.podd.utils.InferredOWLOntologyID;
import com.github.podd.utils.PoddRdfConstants;

/**
 * Provides operations specific to HRPPC in relation to putting projects into PODD.
 * 
 * @author <NAME> <EMAIL>
 */
public class HrppcPoddClient extends RestletPoddClientImpl
{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    public static final int MIN_HEADERS_SIZE = 7;
    
    public static final String TRAY_ID = "TrayID";
    public static final String TRAY_NOTES = "TrayNotes";
    public static final String TRAY_TYPE_NAME = "TrayTypeName";
    public static final String POSITION = "Position";
    public static final String PLANT_ID = "PlantID";
    public static final String PLANT_NAME = "PlantName";
    public static final String PLANT_NOTES = "PlantNotes";
    
    public static final Pattern REGEX_PROJECT = Pattern.compile("^PROJECT#(\\d{4})-(\\d{4})");
    
    // PROJECT#YYYY-NNNN_EXPERIMENT#NNNN_GENUS.SPECIES_TRAY#NNNNN
    public static final Pattern REGEX_TRAY = Pattern
            .compile("PROJECT#(\\d{4})-(\\d{4})_EXPERIMENT#(\\d{4})_(\\w+).(\\w+)_TRAY#(\\d{4,5})");
    
    /**
     * Number of groups matching in the tray id regex.
     */
    public static final int TRAY_ID_SIZE = 6;
    
    // PROJECT#YYYY-NNNN_EXPERIMENT#NNNN_GENUS.SPECIES_TRAY#NNNNN_POT#NNNNN
    public static final Pattern REGEX_PLANT = Pattern
            .compile("PROJECT#(\\d{4})-(\\d{4})_EXPERIMENT#(\\d{4})_(\\w+).(\\w+)_TRAY#(\\d{4,5})_POT#(\\d{4,5})");
    
    /**
     * Number of groups matching in the plant id regex.
     */
    public static final int PLANT_ID_SIZE = 7;
    
    public static final Pattern REGEX_POSITION = Pattern.compile("([a-zA-Z]+)([0-9])");
    
    /**
     * Number of groups matching in the position regex.
     */
    public static final int POSITION_SIZE = 7;
    
    public HrppcPoddClient()
    {
        super();
    }
    
    public HrppcPoddClient(final String serverUrl)
    {
        super(serverUrl);
    }
    
    /**
     * Parses the given PlantScan project/experiment/tray/pot list and inserts the items into PODD
     * where they do not exist.
     * 
     * TODO: Should this process create new projects where they do not already exist? Ideally they
     * should be created and roles assigned before this process, but could be fine to do that in
     * here
     */
    public void uploadPlantScanList(final InputStream in) throws IOException, PoddClientException
    {
        final List<InferredOWLOntologyID> currentUnpublishedArtifacts = this.listUnpublishedArtifacts();
        
        // Keep a queue so that we only need to update each project once for
        // this operation to succeed
        final ConcurrentMap<InferredOWLOntologyID, Model> uploadQueue = new ConcurrentHashMap<>();
        
        // Map starting at project name strings and ending with both the URI of
        // the project and the artifact
        final ConcurrentMap<String, ConcurrentMap<URI, InferredOWLOntologyID>> projectUriMap =
                new ConcurrentHashMap<>();
        
        // Map known project names to their URIs, as the URIs are needed to
        // create statements internally
        this.populateProjectUriMap(currentUnpublishedArtifacts, projectUriMap);
        
        // TODO: Implement getObjectsByType(InferredOWLOntology, URI) so that
        // experiments etc can be found easily
        // and the identifier can be mapped as necessary to the identifier in
        // the header
        
        List<String> headers = null;
        try (final InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);<commit_msg>ignore erroneous Eclipse warning with link to the bug tracking a fix<commit_after>/**
 * PODD is an OWL ontology database used for scientific project management
 * 
 * Copyright (C) 2009-2013 The University Of Queensland
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU Affero General Public License as published by the Free Software Foundation, either version 3
 * 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
 * Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */
package au.org.plantphenomics.podd;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openrdf.model.Literal;
import org.openrdf.model.Model;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.Rio;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.bytecode.opencsv.CSVReader;

import com.github.podd.client.api.PoddClientException;
import com.github.podd.client.impl.restlet.RestletPoddClientImpl;
import com.github.podd.utils.InferredOWLOntologyID;
import com.github.podd.utils.PoddRdfConstants;

/**
 * Provides operations specific to HRPPC in relation to putting projects into PODD.
 * 
 * @author <NAME> p_<EMAIL>
 */
public class HrppcPoddClient extends RestletPoddClientImpl
{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    public static final int MIN_HEADERS_SIZE = 7;
    
    public static final String TRAY_ID = "TrayID";
    public static final String TRAY_NOTES = "TrayNotes";
    public static final String TRAY_TYPE_NAME = "TrayTypeName";
    public static final String POSITION = "Position";
    public static final String PLANT_ID = "PlantID";
    public static final String PLANT_NAME = "PlantName";
    public static final String PLANT_NOTES = "PlantNotes";
    
    public static final Pattern REGEX_PROJECT = Pattern.compile("^PROJECT#(\\d{4})-(\\d{4})");
    
    // PROJECT#YYYY-NNNN_EXPERIMENT#NNNN_GENUS.SPECIES_TRAY#NNNNN
    public static final Pattern REGEX_TRAY = Pattern
            .compile("PROJECT#(\\d{4})-(\\d{4})_EXPERIMENT#(\\d{4})_(\\w+).(\\w+)_TRAY#(\\d{4,5})");
    
    /**
     * Number of groups matching in the tray id regex.
     */
    public static final int TRAY_ID_SIZE = 6;
    
    // PROJECT#YYYY-NNNN_EXPERIMENT#NNNN_GENUS.SPECIES_TRAY#NNNNN_POT#NNNNN
    public static final Pattern REGEX_PLANT = Pattern
            .compile("PROJECT#(\\d{4})-(\\d{4})_EXPERIMENT#(\\d{4})_(\\w+).(\\w+)_TRAY#(\\d{4,5})_POT#(\\d{4,5})");
    
    /**
     * Number of groups matching in the plant id regex.
     */
    public static final int PLANT_ID_SIZE = 7;
    
    public static final Pattern REGEX_POSITION = Pattern.compile("([a-zA-Z]+)([0-9])");
    
    /**
     * Number of groups matching in the position regex.
     */
    public static final int POSITION_SIZE = 7;
    
    public HrppcPoddClient()
    {
        super();
    }
    
    public HrppcPoddClient(final String serverUrl)
    {
        super(serverUrl);
    }
    
    /**
     * Parses the given PlantScan project/experiment/tray/pot list and inserts the items into PODD
     * where they do not exist.
     * 
     * TODO: Should this process create new projects where they do not already exist? Ideally they
     * should be created and roles assigned before this process, but could be fine to do that in
     * here
     */
    public void uploadPlantScanList(final InputStream in) throws IOException, PoddClientException
    {
        final List<InferredOWLOntologyID> currentUnpublishedArtifacts = this.listUnpublishedArtifacts();
        
        // Keep a queue so that we only need to update each project once for
        // this operation to succeed
        final ConcurrentMap<InferredOWLOntologyID, Model> uploadQueue = new ConcurrentHashMap<>();
        
        // Map starting at project name strings and ending with both the URI of
        // the project and the artifact
        final ConcurrentMap<String, ConcurrentMap<URI, InferredOWLOntologyID>> projectUriMap =
                new ConcurrentHashMap<>();
        
        // Map known project names to their URIs, as the URIs are needed to
        // create statements internally
        this.populateProjectUriMap(currentUnpublishedArtifacts, projectUriMap);
        
        List<String> headers = null;
        // TODO: Implement getObjectsByType(InferredOWLOntology, URI) so that
        // experiments etc can be found easily
        // and the identifier can be mapped as necessary to the identifier in
        // the header
        // Supressing warning generated erroneously by Eclipse:
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=371614
        try (@SuppressWarnings("resource")
        final InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
{'fraction_non_alphanumeric': 0.09306440198159943, 'fraction_numerical': 0.006192498230714791, 'mean_word_length': 3.3281010719754978, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '141348', 'n_tokens_mistral': 3449, 'n_tokens_neox': 3367, 'n_words': 1020}