package org.juxtasoftware.resource;
import java.util.HashMap;
import java.util.Map;
import org.juxtasoftware.dao.ComparisonSetDao;
import org.juxtasoftware.dao.JuxtaAnnotationDao;
import org.juxtasoftware.dao.WitnessDao;
import org.juxtasoftware.model.ComparisonSet;
import org.juxtasoftware.model.JuxtaAnnotation;
import org.juxtasoftware.model.Witness;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.ResourceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.interedition.text.Text;
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AnnotationResource extends BaseResource {
private Long annotationId;
private ComparisonSet set;
private Witness witness;
private boolean includeText;
@Autowired private ComparisonSetDao setDao;
@Autowired private JuxtaAnnotationDao annotationDao;
@Autowired private WitnessDao witnessDao;
@Override
protected void doInit() throws ResourceException {
super.doInit();
// get the set and validate that it exists and is in the wprkspace
Long setId = getIdFromAttributes("setId");
if ( setId == null ) {
return;
}
this.set = this.setDao.find( setId);
if ( validateModel(this.set) == false ) {
return;
}
// once the set is workspace validated, just make sure the witness
// exists and is part of the set
Long witnessId = getIdFromAttributes("witnessId");
if ( witnessId == null ) {
return;
}
this.witness = this.witnessDao.find( witnessId);
if ( witness == null ) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND, "Invalid witness identifier specified");
return;
}
if ( this.setDao.isWitness(this.set, this.witness) == false ) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND, "Witness "+witnessId+" does not exist in set "+setId);
return;
}
this.annotationId = getIdFromAttributes("annotationId");
if ( this.annotationId == null ) {
return;
}
this.includeText = false;
if (getQuery().getValuesMap().containsKey("content") ) {
this.includeText = true;
}
}
@Get("html")
public Representation toHtml() {
JuxtaAnnotation annotation = getAnnotation();
if ( annotation == null ) {
return null;
}
Map<String,Object> map = new HashMap<String,Object>();
map.put("witness", this.witness );
map.put("includeText", this.includeText);
map.put("annotation", annotation );
map.put("page", "set");
map.put("title", "Juxta \""+this.witness.getName()+"\" Annotation");
return toHtmlRepresentation("annotation.ftl",map);
}
@Get("json")
public Representation toJson() {
JuxtaAnnotation annotation = getAnnotation();
if ( annotation != null ) {
Gson gson = new GsonBuilder()
.setExclusionStrategies( new TextExclusion() )
.create();
String json = gson.toJson(annotation);
return toJsonRepresentation(json);
}
return null;
}
private JuxtaAnnotation getAnnotation() {
JuxtaAnnotation annotation = this.annotationDao.find(this.annotationId, this.includeText);
if ( annotation == null ) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND, "Invalid annotation identifier specified");
return null;
}
if ( annotation.getText().toString().equals(witness.getText().toString()) == false) {
setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "Witness " + this.witness +
" does not contain annotation "+this.annotationId);
return null;
}
return annotation;
}
@Delete
public void deleteAnnotation() {
LOG.info("Delete annotation " + this.annotationId);
JuxtaAnnotation anno = getAnnotation();
if ( anno != null ) {
this.annotationDao.delete( anno );
} else {
setStatus(Status.CLIENT_ERROR_NOT_FOUND,
"Annotation" +this.annotationId+" does exist in set "+this.set.getId());
}
}
private static class TextExclusion implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == Text.class);
}
}
}