/*
* Copyright (c) 2014 Oculus Info Inc.
* http://www.oculusinfo.com/
*
* Released under the MIT License.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oculusinfo.annotation.rest;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.data.CacheDirective;
import org.restlet.data.Status;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ResourceException;
import com.google.inject.Inject;
import com.oculusinfo.annotation.AnnotationData;
import com.oculusinfo.annotation.impl.JSONAnnotation;
import com.oculusinfo.annotation.index.AnnotationIndexer;
import com.oculusinfo.binning.TileIndex;
import com.oculusinfo.factory.util.Pair;
import com.oculusinfo.tile.rendering.LayerConfiguration;
import com.oculusinfo.tile.rest.QueryParamDecoder;
import org.restlet.resource.ServerResource;
public class AnnotationResource extends ServerResource {
private AnnotationService _service;
@Inject
public AnnotationResource( AnnotationService service ) {
_service = service;
}
@Post("json")
public Representation postAnnotation( String jsonData ) throws ResourceException {
try {
String version = (String) getRequest().getAttributes().get("version");
if ( version == null ) {
version = LayerConfiguration.DEFAULT_VERSION;
}
JSONObject json = new JSONObject( jsonData );
String requestType = json.getString( "type" ).toLowerCase();
JSONObject jsonResult = new JSONObject();
if ( requestType.equals("write") ) {
String layer = json.getString("layer");
JSONAnnotation annotation = JSONAnnotation.fromJSON( json.getJSONObject("annotation") );
Pair<String, Long> certificate = _service.write( layer, annotation );
jsonResult.put("uuid", certificate.getFirst() );
jsonResult.put("timestamp", certificate.getSecond().toString() );
} else if ( requestType.equals("remove") ) {
String layer = json.getString("layer");
JSONObject certificate = json.getJSONObject("certificate");
String uuid = certificate.getString("uuid");
Long timestamp = certificate.getLong("timestamp");
_service.remove(layer, new Pair<>( uuid, timestamp ) );
} else if ( requestType.equals("modify") ) {
String layer = json.getString("layer");
JSONAnnotation annotation = JSONAnnotation.fromJSON( json.getJSONObject("annotation") );
Pair<String, Long> certificate = _service.modify(layer, annotation);
jsonResult.put("uuid", certificate.getFirst() );
jsonResult.put("timestamp", certificate.getSecond().toString() );
}
setStatus(Status.SUCCESS_CREATED);
jsonResult.put("status", "success");
jsonResult.put("version", version);
return new JsonRepresentation(jsonResult);
} catch (JSONException e) {
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
"Unable to create JSON object from supplied options string", e);
} catch (IllegalArgumentException e) {
throw new ResourceException(Status.SERVER_ERROR_INTERNAL,
e.getMessage(), e);
}
}
@Get
public Representation getAnnotation() throws ResourceException {
try {
String version = (String) getRequest().getAttributes().get("version");
if ( version == null ) {
version = LayerConfiguration.DEFAULT_VERSION;
}
String layer = (String) getRequest().getAttributes().get("layer");
String levelDir = (String) getRequest().getAttributes().get("level");
String xAttr = (String) getRequest().getAttributes().get("x");
String yAttr = (String) getRequest().getAttributes().get("y");
JSONObject decodedQueryParams = null;
if ( getRequest().getResourceRef().hasQuery() ) {
// decode and build JSONObject from request parameters
decodedQueryParams = QueryParamDecoder.decode( getRequest().getResourceRef().getQuery() );
}
int zoomLevel = Integer.parseInt(levelDir);
int x = Integer.parseInt(xAttr);
int y = Integer.parseInt(yAttr);
TileIndex index = new TileIndex( zoomLevel, x, y, AnnotationIndexer.NUM_BINS, AnnotationIndexer.NUM_BINS );
List<List<AnnotationData<?>>> data = _service.read( layer, index, decodedQueryParams );
JSONObject result = new JSONObject();
JSONObject indexJson = new JSONObject();
indexJson.put("level", zoomLevel);
indexJson.put("xIndex", x);
indexJson.put("yIndex", y);
result.put("index", indexJson );
result.put("version", version);
if ( data != null ) {
JSONArray valuesArray = new JSONArray();
for ( List<AnnotationData<?>> bin : data ) {
JSONObject valueJson = new JSONObject();
JSONArray annotationArray = new JSONArray();
for ( AnnotationData<?> annotation : bin ) {
annotationArray.put( annotation.toJSON() );
}
valueJson.put( "value", annotationArray );
valuesArray.put( valueJson );
}
JSONObject tileJson = new JSONObject();
tileJson.put( "values", valuesArray );
result.put("tile", tileJson );
}
setStatus(Status.SUCCESS_OK);
getResponse().getCacheDirectives().add( CacheDirective.noCache() );
return new JsonRepresentation( result );
} catch (Exception e){
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
"Unable to interpret requested tile from supplied URL.", e);
}
}
}