<commit_before>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.dao.jena;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;

import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Keyword;
import edu.cornell.mannlib.vitro.webapp.beans.KeywordIndividualRelation;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.KeywordDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualCreationEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;

public class IndividualDaoJena extends JenaBaseDao implements IndividualDao {

    public IndividualDaoJena(WebappDaoFactoryJena wadf) {
        super(wadf);
    }

    private static final Log log = LogFactory.getLog(IndividualDaoJena.class.getName());

    public Collection<DataPropertyStatement> getExternalIds(String individualURI) {
        return this.getExternalIds(individualURI, null);
    }

    public Collection<DataPropertyStatement> getExternalIds(String individualURI, String dataPropertyURI) {
        Collection<DataPropertyStatement> externalIdStatements = new ArrayList<DataPropertyStatement>();
        Individual ind = getIndividualByURI(individualURI);
        HashSet<String> externalIdPropURISet = new HashSet<String>();
        HashSet<String> nonExternalIdPropURISet = new HashSet<String>();
        if (ind != null) {
            Collection<DataPropertyStatement> dpsColl = getWebappDaoFactory().getDataPropertyStatementDao().getDataPropertyStatementsForIndividualByDataPropertyURI(ind, dataPropertyURI);
            Iterator<DataPropertyStatement> dpsIt = dpsColl.iterator();
            while (dpsIt.hasNext()) {
                DataPropertyStatement dps = dpsIt.next();
                if (externalIdPropURISet.contains(dps.getDatapropURI())) {
                    externalIdStatements.add(dps);
                } else if (!nonExternalIdPropURISet.contains(dps.getDatapropURI())) {
                	OntModel tboxOntModel = getOntModelSelector().getTBoxModel();
                    tboxOntModel.enterCriticalSection(Lock.READ);
                    try {
                        Resource dataprop = tboxOntModel.getResource(dps.getDatapropURI());
                        if (dataprop != null && (tboxOntModel.contains(dataprop, DATAPROPERTY_ISEXTERNALID, ResourceFactory.createTypedLiteral(true)) || tboxOntModel.contains(dataprop, DATAPROPERTY_ISEXTERNALID, "TRUE") )) {
                            externalIdPropURISet.add(dps.getDatapropURI());
                            externalIdStatements.add(dps);
                        } else {
                            nonExternalIdPropURISet.add(dps.getDatapropURI());
                        }
                    } finally {
                        tboxOntModel.leaveCriticalSection();
                    }
                }
            }
        }
        return externalIdStatements;
    }

    public void addVClass(String individualURI, String vclassURI) {
    	OntModel ontModel = getOntModelSelector().getABoxModel();
        ontModel.enterCriticalSection(Lock.WRITE);
        ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI));
        try {
            Resource indRes = ontModel.getResource(individualURI);
            ontModel.add(indRes, RDF.type, ontModel.getResource(vclassURI));
            updatePropertyDateTimeValue(indRes, MODTIME, Calendar.getInstance().getTime(),ontModel);
        } finally {
            ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),false,individualURI));
            ontModel.leaveCriticalSection();
        }
    }

    public void removeVClass(String individualURI, String vclassURI) {
    	OntModel ontModel = getOntModelSelector().getABoxModel();
        ontModel.enterCriticalSection(Lock.WRITE);
        ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI));
        try {
            Resource indRes = ontModel.getResource(individualURI);
            getOntModel().remove(indRes, RDF.type, ontModel.getResource(vclassURI));
            updatePropertyDateTimeValue(indRes, MODTIME, Calendar.getInstance().getTime(), ontModel);
        } finally {
            ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),false,individualURI));
            ontModel.leaveCriticalSection();
        }
    }

    public List /*of Entity*/ getIndividualsByVClass(VClass vclass ) {
        return getIndividualsByVClassURI(vclass.getURI(),-1,-1);
    }
    
    public List /*of Entity*/ getIndividualsByVClassURI(String vclassURI) {
        return getIndividualsByVClassURI(vclassURI,-1,-1);
    }

    public List getIndividualsByVClassURI(String vclassURI, int offset, int quantity ) {

    	if (vclassURI==null) {
            return null;
        }
        
        List ents = new ArrayList();
        
        Resource theClass = (vclassURI.indexOf(PSEUDO_BNODE_NS) == 0) 
            ? getOntModel().createResource(new AnonId(vclassURI.split("#")[1]))
            : ResourceFactory.createResource(vclassURI);
    
        getOntModel().enterCriticalSection(Lock.READ);
        try {
            StmtIterator stmtIt = getOntModel().listStatements((Resource) null, RDF.type, theClass);
            try {
                while (stmtIt.hasNext()) {
                    Statement stmt = stmtIt.nextStatement();
                    OntResource ind = (OntResource) stmt.getSubject().as(OntResource.class);
                    ents.add(new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory()));
                }
            } finally {
                stmtIt.close();
            }
        } finally {
            getOntModel().leaveCriticalSection();
        }

        java.util.Collections.sort(ents);

        return ents;

    }

    private class IndividualWebappComparator implements java.util.Comparator {
        public int compare (Object o1, Object o2) {
            if (o1 == null) {
                return -1;
            } else if (o2 == null) {
                return 1;
            }<commit_msg>merging basic union class support to trunk<commit_after>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.dao.jena;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.ontology.UnionClass;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;

import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Keyword;
import edu.cornell.mannlib.vitro.webapp.beans.KeywordIndividualRelation;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.KeywordDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualCreationEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;

public class IndividualDaoJena extends JenaBaseDao implements IndividualDao {

    public IndividualDaoJena(WebappDaoFactoryJena wadf) {
        super(wadf);
    }

    private static final Log log = LogFactory.getLog(IndividualDaoJena.class.getName());

    public Collection<DataPropertyStatement> getExternalIds(String individualURI) {
        return this.getExternalIds(individualURI, null);
    }

    public Collection<DataPropertyStatement> getExternalIds(String individualURI, String dataPropertyURI) {
        Collection<DataPropertyStatement> externalIdStatements = new ArrayList<DataPropertyStatement>();
        Individual ind = getIndividualByURI(individualURI);
        HashSet<String> externalIdPropURISet = new HashSet<String>();
        HashSet<String> nonExternalIdPropURISet = new HashSet<String>();
        if (ind != null) {
            Collection<DataPropertyStatement> dpsColl = getWebappDaoFactory().getDataPropertyStatementDao().getDataPropertyStatementsForIndividualByDataPropertyURI(ind, dataPropertyURI);
            Iterator<DataPropertyStatement> dpsIt = dpsColl.iterator();
            while (dpsIt.hasNext()) {
                DataPropertyStatement dps = dpsIt.next();
                if (externalIdPropURISet.contains(dps.getDatapropURI())) {
                    externalIdStatements.add(dps);
                } else if (!nonExternalIdPropURISet.contains(dps.getDatapropURI())) {
                	OntModel tboxOntModel = getOntModelSelector().getTBoxModel();
                    tboxOntModel.enterCriticalSection(Lock.READ);
                    try {
                        Resource dataprop = tboxOntModel.getResource(dps.getDatapropURI());
                        if (dataprop != null && (tboxOntModel.contains(dataprop, DATAPROPERTY_ISEXTERNALID, ResourceFactory.createTypedLiteral(true)) || tboxOntModel.contains(dataprop, DATAPROPERTY_ISEXTERNALID, "TRUE") )) {
                            externalIdPropURISet.add(dps.getDatapropURI());
                            externalIdStatements.add(dps);
                        } else {
                            nonExternalIdPropURISet.add(dps.getDatapropURI());
                        }
                    } finally {
                        tboxOntModel.leaveCriticalSection();
                    }
                }
            }
        }
        return externalIdStatements;
    }

    public void addVClass(String individualURI, String vclassURI) {
    	OntModel ontModel = getOntModelSelector().getABoxModel();
        ontModel.enterCriticalSection(Lock.WRITE);
        ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI));
        try {
            Resource indRes = ontModel.getResource(individualURI);
            ontModel.add(indRes, RDF.type, ontModel.getResource(vclassURI));
            updatePropertyDateTimeValue(indRes, MODTIME, Calendar.getInstance().getTime(),ontModel);
        } finally {
            ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),false,individualURI));
            ontModel.leaveCriticalSection();
        }
    }

    public void removeVClass(String individualURI, String vclassURI) {
    	OntModel ontModel = getOntModelSelector().getABoxModel();
        ontModel.enterCriticalSection(Lock.WRITE);
        ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),true,individualURI));
        try {
            Resource indRes = ontModel.getResource(individualURI);
            getOntModel().remove(indRes, RDF.type, ontModel.getResource(vclassURI));
            updatePropertyDateTimeValue(indRes, MODTIME, Calendar.getInstance().getTime(), ontModel);
        } finally {
            ontModel.getBaseModel().notifyEvent(new IndividualUpdateEvent(getWebappDaoFactory().getUserURI(),false,individualURI));
            ontModel.leaveCriticalSection();
        }
    }

    public List /*of Entity*/ getIndividualsByVClass(VClass vclass ) {
        return getIndividualsByVClassURI(vclass.getURI(),-1,-1);
    }
    
    public List /*of Entity*/ getIndividualsByVClassURI(String vclassURI) {
        return getIndividualsByVClassURI(vclassURI,-1,-1);
    }

    public List getIndividualsByVClassURI(String vclassURI, int offset, int quantity ) {

    	if (vclassURI==null) {
            return null;
        }
        
        List ents = new ArrayList();
        
        Resource theClass = (vclassURI.indexOf(PSEUDO_BNODE_NS) == 0) 
            ? getOntModel().createResource(new AnonId(vclassURI.split("#")[1]))
            : ResourceFactory.createResource(vclassURI);
    
        getOntModel().enterCriticalSection(Lock.READ);
        try {
            if (theClass.isAnon() && theClass.canAs(UnionClass.class)) {
            	UnionClass u = (UnionClass) theClass.as(UnionClass.class);
            	for (OntClass operand : u.listOperands().toList()) {
            		VClass vc = new VClassJena(operand, getWebappDaoFactory());
            		ents.addAll(getIndividualsByVClass(vc));
            	}
            } else {
	            StmtIterator stmtIt = getOntModel().listStatements((Resource) null, RDF.type, theClass);
	            try {
	                while (stmtIt.hasNext()) {
	                    Statement stmt = stmtIt.nextStatement();
	                    OntResource ind = (OntResource) stmt.getSubject().as(OntResource.class);
	                    ents.add(new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory()));
	                }
	            } finally {
	                stmtIt.close();
	            }
            }
        } finally {
            getOntModel().leaveCriticalSection();
        }

        java.util.Collections.sort(ents);

        return ents;

    }

    private class IndividualWebappComparator implements java.util.Comparator {
        public int compare (Object o1, Object o2) {
            if (o1 == null) {
                return -1;
            } else if (o2 == null) {
                return 1;
            }
{'fraction_non_alphanumeric': 0.10691524212281851, 'fraction_numerical': 0.0014295074155697182, 'mean_word_length': 3.0254135698873172, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7490031', 'n_tokens_mistral': 5252, 'n_tokens_neox': 5057, 'n_words': 738}