package org.juxtasoftware.resource;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.juxtasoftware.dao.ComparisonSetDao;
import org.juxtasoftware.dao.WitnessDao;
import org.juxtasoftware.model.ComparisonSet;
import org.juxtasoftware.model.Witness;
import org.juxtasoftware.service.SetRemover;
import org.juxtasoftware.util.MetricsHelper;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
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 com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ComparisonSetsResource extends BaseResource {
@Autowired private ComparisonSetDao comparionSetDao;
@Autowired private WitnessDao witnessDao;
@Autowired private MetricsHelper metrics;
@Autowired private Integer maxSetWitnesses;
@Autowired private SetRemover remover;
boolean batchDelete;
@Override
protected void doInit() throws ResourceException {
super.doInit();
String lastSeg = getRequest().getResourceRef().getLastSegment().toLowerCase();
this.batchDelete = lastSeg.equals("delete");
}
@Get("html")
public Representation toHtml() {
List<ComparisonSet> sets = this.comparionSetDao.list( this.workspace );
Map<String,Object> map = new HashMap<String,Object>();
map.put("items", sets);
map.put("title", "Juxta Comparison Sets");
map.put("page", "set");
map.put("title", "Juxta Comparison Sets");
return toHtmlRepresentation("set_list.ftl",map);
}
@Get("json")
public Representation toJson() {
List<ComparisonSet> sets = this.comparionSetDao.list( this.workspace );
Gson gson = new GsonBuilder()
.setExclusionStrategies(new SetsExclusion())
.setDateFormat("MM/dd/yyyy HH:mm:ss")
.create();
String json = gson.toJson(sets);
return toJsonRepresentation(json);
}
@Post("json")
public Representation acceptJson( final String jsonData ) {
if ( this.batchDelete) {
return batchDelete(jsonData);
}
LOG.info("Create comparison set from "+jsonData);
// parse out the main set object from string
Gson gson = new Gson();
ComparisonSet set = gson.fromJson(jsonData, ComparisonSet.class);
set.setCreated( new Date() );
set.setWorkspaceId( this.workspace.getId() );
// flag duplicates in the same workspace as an error
if ( this.comparionSetDao.exists(this.workspace, set.getName())) {
setStatus(Status.CLIENT_ERROR_CONFLICT);
return toTextRepresentation("Set "+set.getName()+" already exists in workspace "+
this.workspace.getName());
}
// do the creation
Long id = this.comparionSetDao.create(set);
// If present, lookup each witnessID found and generate a list for this set
JsonParser parser = new JsonParser();
JsonObject jsonObj = parser.parse(jsonData).getAsJsonObject();
if ( jsonObj.has("witnesses")) {
Set<Witness> witnesses = new HashSet<Witness>();
JsonArray ids = jsonObj.get("witnesses").getAsJsonArray();
if ( ids.size() > this.maxSetWitnesses ) {
setStatus(Status.CLIENT_ERROR_PRECONDITION_FAILED);
return toTextRepresentation("Witnesses per set limit ("+this.maxSetWitnesses+") exceeded");
}
for ( Iterator<JsonElement> itr = ids.iterator(); itr.hasNext(); ) {
Long witnessId = itr.next().getAsLong();
Witness witness = this.witnessDao.find( witnessId );
witnesses.add( witness );
}
// add all witnesses to the set
this.comparionSetDao.addWitnesses(set, witnesses);
}
this.metrics.setWitnessCountChanged(this.workspace);
return toTextRepresentation(id.toString());
}
@Delete("json")
public Representation batchDelete( final String jsonContent) {
LOG.info("Batch delete sets "+jsonContent);
JsonParser parser = new JsonParser();
JsonArray jsonArray = parser.parse(jsonContent).getAsJsonArray();
int delCnt = 0;
for ( Iterator<JsonElement> itr = jsonArray.iterator(); itr.hasNext(); ) {
JsonElement ele = itr.next();
Long id = ele.getAsLong();
ComparisonSet set = this.comparionSetDao.find(id);
if ( set != null ) {
try {
this.remover.remove(this.workspace, set);
delCnt++;
} catch ( ResourceException e ) {
LOG.warn(e.toString());
}
} else {
LOG.warn("Set ID "+id+" is not valid for this workspace");
}
}
return toTextRepresentation(""+delCnt);
}
private static class SetsExclusion implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().equals("baseWitnessId");
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
}