/*
* Copyright 2012
* Ubiquitous Knowledge Processing (UKP) Lab and FG Language Technology
* 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.clarin.webanno.automation.service;
import static org.apache.commons.io.IOUtils.copyLarge;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import de.tudarmstadt.ukp.clarin.webanno.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.clarin.webanno.api.DocumentService;
import de.tudarmstadt.ukp.clarin.webanno.api.ProjectLifecycleAware;
import de.tudarmstadt.ukp.clarin.webanno.api.WebAnnoConst;
import de.tudarmstadt.ukp.clarin.webanno.automation.model.AutomationStatus;
import de.tudarmstadt.ukp.clarin.webanno.automation.model.MiraTemplate;
import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature;
import de.tudarmstadt.ukp.clarin.webanno.model.Project;
import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument;
import de.tudarmstadt.ukp.clarin.webanno.support.logging.Logging;
@Component(AutomationService.SERVICE_NAME)
public class MiraAutomationServiceImpl
implements AutomationService, ProjectLifecycleAware
{
private static final String PROJECT = "/project/";
private static final String MIRA = "/mira/";
private static final String MIRA_TEMPLATE = "/template/";
private final Logger log = LoggerFactory.getLogger(getClass());
@Value(value = "${repository.path}")
private File dir;
private @Resource DocumentService documentService;
private @Resource AnnotationSchemaService annotationService;
@PersistenceContext
private EntityManager entityManager;
@Override
public List<String> listTemplates(Project aProject)
{
// list all MIRA template files
File[] files = new File(dir.getAbsolutePath() + PROJECT + aProject.getId() + MIRA
+ MIRA_TEMPLATE).listFiles();
// Name of the MIRA template files
List<String> templateFiles = new ArrayList<String>();
if (files != null) {
for (File file : files) {
templateFiles.add(file.getName());
}
}
return templateFiles;
}
@Override
@Transactional
public List<MiraTemplate> listMiraTemplates(Project aProject)
{
List<MiraTemplate> allTenplates = entityManager.createQuery(
"FROM MiraTemplate ORDER BY trainFeature ASC ", MiraTemplate.class).getResultList();
List<MiraTemplate> templatesInThisProject = new ArrayList<MiraTemplate>();
for (MiraTemplate miraTemplate : allTenplates) {
if (miraTemplate.getTrainFeature() != null
&& miraTemplate.getTrainFeature().getProject().getId() == aProject.getId()) {
templatesInThisProject.add(miraTemplate);
}
}
return templatesInThisProject;
}
@Override
public void removeTemplate(Project aProject, String aFileName, String aUsername)
throws IOException
{
FileUtils.forceDelete(new File(dir.getAbsolutePath() + PROJECT + aProject.getId() + MIRA
+ MIRA_TEMPLATE + aFileName));
Logging.setMDC(aProject.getId(), aUsername);
log.info("Removed template file [{}] from project [{}] ({})", aFileName, aProject.getName(),
aProject.getId());
Logging.clearMDC();
}
@Override
public void createTemplate(Project aProject, File aContent, String aFileName, String aUsername)
throws IOException
{
String templatePath = dir.getAbsolutePath() + PROJECT + aProject.getId() + MIRA
+ MIRA_TEMPLATE;
FileUtils.forceMkdir(new File(templatePath));
copyLarge(new FileInputStream(aContent), new FileOutputStream(new File(templatePath
+ aFileName)));
Logging.setMDC(aProject.getId(), aUsername);
log.info("Removed template file [{}] from project [{}] ({})", aFileName, aProject.getName(),
aProject.getId());
Logging.clearMDC();
}
@Override
@Transactional
public void removeMiraTemplate(MiraTemplate aTemplate)
{
try {
removeAutomationStatus(getAutomationStatus(aTemplate));
}
catch (NoResultException e) {
// do nothing - automation was not started and no status created for this template
}
entityManager.remove(aTemplate);
}
@Override
@Transactional
public void createAutomationStatus(AutomationStatus aStatus)
{
entityManager.persist(aStatus);
}
@Override
public boolean existsAutomationStatus(MiraTemplate aTemplate)
{
try {
entityManager
.createQuery("FROM AutomationStatus WHERE template =:template",
AutomationStatus.class).setParameter("template", aTemplate)
.getSingleResult();
return true;
}
catch (NoResultException ex) {
return false;
}
}
@Override
@Transactional
public AutomationStatus getAutomationStatus(MiraTemplate aTemplate)
{
return entityManager
.createQuery("FROM AutomationStatus WHERE template =:template",
AutomationStatus.class).setParameter("template", aTemplate)
.getSingleResult();
}
@Override
@Transactional
public void removeAutomationStatus(AutomationStatus aStstus)
{
entityManager.remove(aStstus);
}
@Override
public File getMiraModel(AnnotationFeature aFeature, boolean aOtherLayer,
SourceDocument aDocument)
{
if (aDocument != null) {
return new File(getMiraDir(aFeature), aDocument.getId() + "- "
+ aDocument.getProject().getId() + "-model");
}
else if (aOtherLayer) {
return new File(getMiraDir(aFeature), aFeature.getId() + "-model");
}
else {
return new File(getMiraDir(aFeature), aFeature.getLayer().getId() + "-"
+ aFeature.getId() + "-model");
}
}
@Override
public File getMiraDir(AnnotationFeature aFeature)
{
return new File(dir, PROJECT + aFeature.getProject().getId() + MIRA);
}
@Override
@Transactional
public void createTemplate(MiraTemplate aTemplate)
{
if (aTemplate.getId() == 0) {
entityManager.persist(aTemplate);
}
else {
entityManager.merge(aTemplate);
}
}
@Override
@Transactional(noRollbackFor = NoResultException.class)
public MiraTemplate getMiraTemplate(AnnotationFeature aFeature)
{
return entityManager
.createQuery("FROM MiraTemplate WHERE trainFeature =:trainFeature",
MiraTemplate.class).setParameter("trainFeature", aFeature)
.getSingleResult();
}
@Override
public boolean existsMiraTemplate(AnnotationFeature aFeature)
{
try {
entityManager
.createQuery("FROM MiraTemplate WHERE trainFeature =:trainFeature",
MiraTemplate.class).setParameter("trainFeature", aFeature)
.getSingleResult();
return true;
}
catch (NoResultException ex) {
return false;
}
}
@Override
@Transactional(noRollbackFor = NoResultException.class)
public List<SourceDocument> listTabSepDocuments(Project aProject)
{
List<SourceDocument> sourceDocuments = entityManager
.createQuery("FROM SourceDocument where project =:project", SourceDocument.class)
.setParameter("project", aProject).getResultList();
List<SourceDocument> tabSepDocuments = new ArrayList<SourceDocument>();
for (SourceDocument sourceDocument : sourceDocuments) {
if (sourceDocument.getFormat().equals(WebAnnoConst.TAB_SEP)) {
tabSepDocuments.add(sourceDocument);
}
}
return tabSepDocuments;
}
@Override
public void afterProjectCreate(Project aProject)
throws Exception
{
// Nothing to do
}
@Override
public void beforeProjectRemove(Project aProject)
throws Exception
{
for (MiraTemplate template : listMiraTemplates(aProject)) {
removeMiraTemplate(template);
}
for (SourceDocument document : listTabSepDocuments(aProject)) {
documentService.removeSourceDocument(document);
}
}
@Override
@Transactional
public void onProjectImport(ZipFile aZip,
de.tudarmstadt.ukp.clarin.webanno.export.model.Project aExportedProject,
Project aProject)
throws Exception
{
// Nothing at the moment
}
}