/** * Deletes the specified object from the object set. * * <p>{@inheritDoc} * * @throws NotFoundException if the specified object could not be found. * @throws ForbiddenException if access to the object is forbidden. * @throws ConflictException if version is required but is {@code null}. * @throws PreconditionFailedException if version did not match the existing object in the set. */ @Override public ResourceResponse delete(DeleteRequest request) throws ResourceException { if (request.getResourcePathObject().size() < 2) { throw new NotFoundException( "The object identifier did not include sufficient information to determine the object type and identifier of the object to update: " + request.getResourcePath()); } if (request.getRevision() == null || "".equals(request.getRevision())) { throw new ConflictException( "Object passed into delete does not have revision it expects set."); } final String type = request.getResourcePathObject().parent().toString(); final String localId = request.getResourcePathObject().leaf(); int ver = DocumentUtil.parseVersion( request.getRevision()); // This throws ConflictException if parse fails ODatabaseDocumentTx db = getConnection(); try { ODocument existingDoc = predefinedQueries.getByID(localId, type, db); if (existingDoc == null) { throw new NotFoundException( "Object does not exist for delete on: " + request.getResourcePath()); } db.delete(existingDoc.getIdentity(), new OSimpleVersion(ver)); logger.debug("delete for id succeeded: {} revision: {}", localId, request.getRevision()); return DocumentUtil.toResource(existingDoc); } catch (ODatabaseException ex) { // Without transaction the concurrent modification exception gets nested instead if (isCauseConcurrentModificationException(ex, 10)) { throw new PreconditionFailedException( "Delete rejected as current Object revision is different than expected by caller, the object has changed since retrieval. " + ex.getMessage(), ex); } else { throw ex; } } catch (OConcurrentModificationException ex) { throw new PreconditionFailedException( "Delete rejected as current Object revision is different than expected by caller, the object has changed since retrieval." + ex.getMessage(), ex); } catch (RuntimeException e) { throw e; } finally { if (db != null) { db.close(); } } }
/** * Updates the specified object in the object set. * * <p>This implementation does not require MVCC and uses the current revision if no revision is * specified in the request. * * <p>If successful, this method updates metadata properties within the passed object, including: * a new {@code _rev} value for the revised object's version * * @param request the contents of the object to update * @throws ConflictException if version is required but is {@code null}. * @throws ForbiddenException if access to the object is forbidden. * @throws NotFoundException if the specified object could not be found. * @throws PreconditionFailedException if version did not match the existing object in the set. * @throws BadRequestException if the passed identifier is invalid */ @Override public ResourceResponse update(UpdateRequest request) throws ResourceException { if (request.getResourcePathObject().size() < 2) { throw new NotFoundException( "The object identifier did not include sufficient information to determine the object type and identifier of the object to update: " + request.getResourcePath()); } final String type = request.getResourcePathObject().parent().toString(); final String localId = request.getResourcePathObject().leaf(); String orientClassName = typeToOrientClassName(type); JsonValue obj = request.getContent(); if (request.getRevision() != null && !"".equals(request.getRevision())) { obj.put(DocumentUtil.TAG_REV, request.getRevision()); } ODatabaseDocumentTx db = getConnection(); try { ODocument existingDoc = predefinedQueries.getByID(localId, type, db); if (existingDoc == null) { throw new NotFoundException( "Update on object " + request.getResourcePath() + " could not find existing object."); } ODocument updatedDoc = DocumentUtil.toDocument(obj, existingDoc, db, orientClassName); logger.trace("Updated doc for id {} to save {}", request.getResourcePath(), updatedDoc); updatedDoc.save(); obj.put(DocumentUtil.TAG_REV, Integer.toString(updatedDoc.getVersion())); // Set ID to return to caller obj.put(DocumentUtil.TAG_ID, updatedDoc.field(DocumentUtil.ORIENTDB_PRIMARY_KEY)); logger.debug( "Committed update for id: {} revision: {}", request.getResourcePath(), updatedDoc.getVersion()); logger.trace("Update payload for id: {} doc: {}", request.getResourcePath(), updatedDoc); return newResourceResponse( obj.get(DocumentUtil.TAG_ID).asString(), obj.get(DocumentUtil.TAG_REV).asString(), obj); } catch (ODatabaseException ex) { // Without transaction the concurrent modification exception gets nested instead if (isCauseConcurrentModificationException(ex, 10)) { throw new PreconditionFailedException( "Update rejected as current Object revision is different than expected by caller, the object has changed since retrieval: " + ex.getMessage(), ex); } else { throw ex; } } catch (OConcurrentModificationException ex) { throw new PreconditionFailedException( "Update rejected as current Object revision is different than expected by caller, the object has changed since retrieval: " + ex.getMessage(), ex); } catch (RuntimeException e) { throw e; } finally { if (db != null) { db.close(); } } }