/*******************************************************************************
* Copyright 2013
* Ubiquitous Knowledge Processing (UKP) Lab
* Technische Universität Darmstadt
*
* 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 de.tudarmstadt.ukp.csniper.webapp.project;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.springframework.transaction.annotation.Transactional;
import de.tudarmstadt.ukp.csniper.webapp.evaluation.model.AdditionalColumn;
import de.tudarmstadt.ukp.csniper.webapp.evaluation.model.EvaluationResult;
import de.tudarmstadt.ukp.csniper.webapp.project.model.AnnotationType;
import de.tudarmstadt.ukp.csniper.webapp.project.model.Project;
public class ProjectRepository
{
private Log log = LogFactory.getLog(getClass());
@PersistenceContext
private EntityManager entityManager;
@Transactional
public List<Project> listProjects()
{
return entityManager.createQuery("FROM Project", Project.class).getResultList();
}
@Transactional
public Project readProject(long aId)
{
return entityManager.find(Project.class, aId);
}
@Transactional
public Project writeProject(Project aProject)
{
// Only need to persist if it has not been saved to the DB yet. If it already has been
// saved (ID != null), JPA will automatically take care of flushing changes to the DB.
if (aProject.getId() == 0) {
entityManager.persist(aProject);
return aProject;
}
else {
return entityManager.merge(aProject);
}
}
@Transactional
public List<AnnotationType> listAnnotationTypes()
{
return entityManager.createQuery("FROM AnnotationType", AnnotationType.class)
.getResultList();
}
@Transactional
public AnnotationType readAnnotationType(String aName)
{
try {
return entityManager
.createQuery("FROM AnnotationType WHERE name = :name", AnnotationType.class)
.setParameter("name", aName).getSingleResult();
}
catch (NoResultException e) {
AnnotationType t = new AnnotationType();
t.setName(aName);
return t;
}
}
@Transactional
public AnnotationType readAnnotationType(long aId)
{
return entityManager.find(AnnotationType.class, aId);
}
@Transactional
public AnnotationType writeAnnotationType(AnnotationType aProject)
{
if (aProject.getId() == 0) {
entityManager.persist(aProject);
return aProject;
}
else {
return entityManager.merge(aProject);
}
}
/**
* For cancel operations, to detach an object which would otherwise still be stored in the
* persistence context.
*/
@Transactional
public void refreshEntity(Object aEntity)
{
entityManager.refresh(aEntity);
}
@Transactional
public int countEntriesWithAdditionalColumn(String aUserId, AnnotationType aType,
AdditionalColumn aAdditionalColumn)
{
int count = 0;
// TODO this is kind of ugly
List<String> query = new ArrayList<String>();
query.add("FROM EvaluationResult AS er");
query.add("WHERE userId = :userId");
query.add("AND er.item.type = :type");
query.add("AND er.additionalColumns.size > 0");
List<EvaluationResult> results = entityManager
.createQuery(StringUtils.join(query, " "), EvaluationResult.class)
.setParameter("userId", aUserId).setParameter("type", aType.getName())
.getResultList();
for (EvaluationResult r : results) {
if (r.getAdditionalColumns().containsKey(aAdditionalColumn)) {
count++;
}
}
return count;
}
/**
* Gets the maximum column length.<br>
* Why is this method located here? For convenience reasons - we already have access to
* projectRepository on the relevant pages (EvaluationPage, AnnotationTypePage).
*
* @param aColumn
* the column for which the maximum length shall be returned
* @return the maximum length of the specified column in the specified table
*/
@Transactional
public int getDbColumnLength(String aEntityName, String aColumn)
{
BigInteger length = new BigInteger("255");
final List<String> query = new ArrayList<String>();
query.add("SELECT CHARACTER_MAXIMUM_LENGTH");
query.add("FROM INFORMATION_SCHEMA.COLUMNS");
Session session = entityManager.unwrap(Session.class);
session.doWork(new Work()
{
@Override
public void execute(Connection aConnection)
throws SQLException
{
query.add("WHERE table_schema = '"+aConnection.getCatalog()+"'");
}
});
query.add("AND table_name = '" + aEntityName + "'");
query.add("AND column_name = '" + aColumn + "'");
try {
length = (BigInteger) entityManager.createNativeQuery(StringUtils.join(query, " "))
.getSingleResult();
}
catch (NoResultException e) {
// log.debug("No results for query: " + StringUtils.join(query, " "));
}
if (length.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
return Integer.MAX_VALUE;
}
else {
return length.intValue();
}
}
}