<commit_before>/*
 * Copyright 2013 <NAME> <<EMAIL>>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ca.corefacility.bioinformatics.irida.repositories.sesame;

import ca.corefacility.bioinformatics.irida.exceptions.EntityNotFoundException;
import ca.corefacility.bioinformatics.irida.exceptions.StorageException;
import ca.corefacility.bioinformatics.irida.model.Relationship;
import ca.corefacility.bioinformatics.irida.model.alibaba.IridaThing;
import ca.corefacility.bioinformatics.irida.model.enums.Order;
import ca.corefacility.bioinformatics.irida.model.roles.impl.Audit;
import ca.corefacility.bioinformatics.irida.model.roles.impl.Identifier;
import ca.corefacility.bioinformatics.irida.model.roles.impl.StringIdentifier;
import ca.corefacility.bioinformatics.irida.repositories.RelationshipRepository;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.DefaultLinks;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.QualifiedRDFPredicate;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.RdfPredicate;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.TripleStore;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.query.*;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.object.ObjectConnection;
import org.slf4j.LoggerFactory;

import java.net.URISyntaxException;
import java.util.*;

/**
 * @author <NAME> <<EMAIL>>
 */
public class RelationshipSesameRepository extends SesameRepository implements RelationshipRepository {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(RelationshipSesameRepository.class);
    public final String linkType = "http://corefacility.ca/irida/ResourceLink";
    AuditRepository auditRepo;
    DefaultLinks linkList;

    public RelationshipSesameRepository(TripleStore store, AuditRepository auditRepo) {
        super(store, "ResourceLink");
        this.auditRepo = auditRepo;
        linkList = new DefaultLinks();
    }

    /**
     * Add a default relationship to the relationship repository repository
     *
     * @param <S>     The class of the subject
     * @param <O>     The class of the object
     * @param subject The class of the subject
     * @param pred    The predicate to link the subject/object
     * @param object  The class of the object
     */
    public <S extends IridaThing, O extends IridaThing> void addRelationship(Class subject, RdfPredicate pred, Class object) {
        linkList.addLink(subject, pred, object);
    }

    /**
     * Build an identifier object from a link binding set
     *
     * @param bs          The <type>BindingSet</type> to construct the identifier from
     * @param bindingName The binding name of the subject from this binding set
     * @return A <type>StringIdentifier</type> for this binding set
     */
    private StringIdentifier buildIdentiferFromBindingSet(BindingSet bs, String bindingName) {
        StringIdentifier id = null;
        try {
            Value uri = bs.getValue(bindingName);
            Value ident = bs.getValue("identifier");
            Value label = bs.getValue("label");
            id = new StringIdentifier();
            id.setIdentifier(ident.stringValue());
            id.setUri(new java.net.URI(uri.stringValue()));
            id.setLabel(label.stringValue());
        } catch (URISyntaxException ex) {
            logger.error("A URISyntaxException occurred at [" + new Date() + "]", ex);
            throw new StorageException(
                    "Failed to build identifier from binding set: [" + bs + "], bindingName: [" + bindingName + "]");
        }

        return id;
    }

    /**
     * Build a link identifier from a given URI and identifier string
     *
     * @param uri          The URI to build from
     * @param identifiedBy The unique string for this identifier
     * @return A new instance of an Identifier
     */
    private Identifier buildLinkIdentifier(URI uri, String identifiedBy) {
        Identifier objid = new Identifier();
        objid.setUri(java.net.URI.create(uri.toString()));
        objid.setIdentifier(identifiedBy);

        return objid;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <SubjectType extends IridaThing, ObjectType extends IridaThing> Relationship create(SubjectType subject, ObjectType object) {
        return create(subject.getClass(), (Identifier) subject.getIdentifier(),
                object.getClass(), (Identifier) object.getIdentifier());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Relationship create(Class subjectType, Identifier subject, Class objectType, Identifier object) {
        RdfPredicate predicate = linkList.getLink(subjectType, objectType);
        Relationship link = new Relationship();

        link.setSubject(subject);
        link.setPredicate(predicate);
        link.setObject(object);

        return create(link);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Relationship create(Relationship link) {
        Identifier subject = link.getSubject();
        Identifier object = link.getObject();
        RdfPredicate predicate = link.getPredicate();

        java.net.URI subNetURI = getUriFromIdentifier(subject);
        java.net.URI objNetURI = getUriFromIdentifier(object);
        
        if(!uriExists(subNetURI.toString())){
            throw new EntityNotFoundException("Subject "+ subject.toString()+ " was not found in the database.  A relationship for this element cannot be created" );
        }
        if(!uriExists(objNetURI.toString())){
            throw new EntityNotFoundException("Object "+ subject.toString()+ " was not found in the database.  A relationship for this element cannot be created" );
        }        

        ObjectConnection con = store.getRepoConnection();
        ValueFactory fac = con.getValueFactory();

        try {
            con.begin();
            URI subURI = fac.createURI(subNetURI.toString());
            URI objURI = fac.createURI(objNetURI.toString());
            URI pred = predicate.getPredicateURI(con);

            Identifier identifier = generateNewIdentifier();
            link.setIdentifier(identifier);

            java.net.URI netURI = identifier.getUri();
            URI linkURI = fac.createURI(netURI.toString());

            Statement st = fac.createStatement(subURI, pred, objURI);
            con.add(st);

            URI rdftype = fac.createURI(con.getNamespace("rdf"), "type");
            URI type = fac.createURI(linkType);
            setIdentifiedBy(con, linkURI, identifier.getIdentifier());<commit_msg>Fixed an error report in a throw that didn't report the right information<commit_after>/*
 * Copyright 2013 <NAME> <<EMAIL>>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ca.corefacility.bioinformatics.irida.repositories.sesame;

import ca.corefacility.bioinformatics.irida.exceptions.EntityNotFoundException;
import ca.corefacility.bioinformatics.irida.exceptions.StorageException;
import ca.corefacility.bioinformatics.irida.model.Relationship;
import ca.corefacility.bioinformatics.irida.model.alibaba.IridaThing;
import ca.corefacility.bioinformatics.irida.model.enums.Order;
import ca.corefacility.bioinformatics.irida.model.roles.impl.Audit;
import ca.corefacility.bioinformatics.irida.model.roles.impl.Identifier;
import ca.corefacility.bioinformatics.irida.model.roles.impl.StringIdentifier;
import ca.corefacility.bioinformatics.irida.repositories.RelationshipRepository;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.DefaultLinks;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.QualifiedRDFPredicate;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.RdfPredicate;
import ca.corefacility.bioinformatics.irida.repositories.sesame.dao.TripleStore;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.query.*;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.object.ObjectConnection;
import org.slf4j.LoggerFactory;

import java.net.URISyntaxException;
import java.util.*;

/**
 * @author <NAME> <<EMAIL>>
 */
public class RelationshipSesameRepository extends SesameRepository implements RelationshipRepository {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(RelationshipSesameRepository.class);
    public final String linkType = "http://corefacility.ca/irida/ResourceLink";
    AuditRepository auditRepo;
    DefaultLinks linkList;

    public RelationshipSesameRepository(TripleStore store, AuditRepository auditRepo) {
        super(store, "ResourceLink");
        this.auditRepo = auditRepo;
        linkList = new DefaultLinks();
    }

    /**
     * Add a default relationship to the relationship repository repository
     *
     * @param <S>     The class of the subject
     * @param <O>     The class of the object
     * @param subject The class of the subject
     * @param pred    The predicate to link the subject/object
     * @param object  The class of the object
     */
    public <S extends IridaThing, O extends IridaThing> void addRelationship(Class subject, RdfPredicate pred, Class object) {
        linkList.addLink(subject, pred, object);
    }

    /**
     * Build an identifier object from a link binding set
     *
     * @param bs          The <type>BindingSet</type> to construct the identifier from
     * @param bindingName The binding name of the subject from this binding set
     * @return A <type>StringIdentifier</type> for this binding set
     */
    private StringIdentifier buildIdentiferFromBindingSet(BindingSet bs, String bindingName) {
        StringIdentifier id = null;
        try {
            Value uri = bs.getValue(bindingName);
            Value ident = bs.getValue("identifier");
            Value label = bs.getValue("label");
            id = new StringIdentifier();
            id.setIdentifier(ident.stringValue());
            id.setUri(new java.net.URI(uri.stringValue()));
            id.setLabel(label.stringValue());
        } catch (URISyntaxException ex) {
            logger.error("A URISyntaxException occurred at [" + new Date() + "]", ex);
            throw new StorageException(
                    "Failed to build identifier from binding set: [" + bs + "], bindingName: [" + bindingName + "]");
        }

        return id;
    }

    /**
     * Build a link identifier from a given URI and identifier string
     *
     * @param uri          The URI to build from
     * @param identifiedBy The unique string for this identifier
     * @return A new instance of an Identifier
     */
    private Identifier buildLinkIdentifier(URI uri, String identifiedBy) {
        Identifier objid = new Identifier();
        objid.setUri(java.net.URI.create(uri.toString()));
        objid.setIdentifier(identifiedBy);

        return objid;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <SubjectType extends IridaThing, ObjectType extends IridaThing> Relationship create(SubjectType subject, ObjectType object) {
        return create(subject.getClass(), (Identifier) subject.getIdentifier(),
                object.getClass(), (Identifier) object.getIdentifier());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Relationship create(Class subjectType, Identifier subject, Class objectType, Identifier object) {
        RdfPredicate predicate = linkList.getLink(subjectType, objectType);
        Relationship link = new Relationship();

        link.setSubject(subject);
        link.setPredicate(predicate);
        link.setObject(object);

        return create(link);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Relationship create(Relationship link) {
        Identifier subject = link.getSubject();
        Identifier object = link.getObject();
        RdfPredicate predicate = link.getPredicate();

        java.net.URI subNetURI = getUriFromIdentifier(subject);
        java.net.URI objNetURI = getUriFromIdentifier(object);
        
        if(!uriExists(subNetURI.toString())){
            throw new EntityNotFoundException("Subject "+ subject.toString()+ " was not found in the database.  A relationship for this element cannot be created" );
        }
        if(!uriExists(objNetURI.toString())){
            throw new EntityNotFoundException("Object "+ object.toString()+ " was not found in the database.  A relationship for this element cannot be created" );
        }        

        ObjectConnection con = store.getRepoConnection();
        ValueFactory fac = con.getValueFactory();

        try {
            con.begin();
            URI subURI = fac.createURI(subNetURI.toString());
            URI objURI = fac.createURI(objNetURI.toString());
            URI pred = predicate.getPredicateURI(con);

            Identifier identifier = generateNewIdentifier();
            link.setIdentifier(identifier);

            java.net.URI netURI = identifier.getUri();
            URI linkURI = fac.createURI(netURI.toString());

            Statement st = fac.createStatement(subURI, pred, objURI);
            con.add(st);

            URI rdftype = fac.createURI(con.getNamespace("rdf"), "type");
            URI type = fac.createURI(linkType);
            setIdentifiedBy(con, linkURI, identifier.getIdentifier());
{'fraction_non_alphanumeric': 0.0964425251902118, 'fraction_numerical': 0.0013708958804578791, 'mean_word_length': 3.155511250356024, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, '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': '1571702', 'n_tokens_mistral': 3983, 'n_tokens_neox': 3835, 'n_words': 1041}