class SaveNoteAPIController {

    @PreAuthorize("hasPermission(#note.parentId, #note.parentType, 'addComment')")
    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Note addNote(
            @RequestBody Note note, Authentication authentication, HttpSession httpSession) throws AcmUserActionFailedException
    {
        if (note != null)
        {
            log.info("Note ID : {}", note.getId());
        }
        else
        {
            throw new AcmUserActionFailedException("addNote", NoteConstants.OBJECT_TYPE, null,
                    "Could not save note, missing parent type and ID", new NullPointerException());
        }

        try
        {
            Note savedNote = getNoteDao().save(note);

            String noteEvent = note.getId() == null ? NoteConstants.NOTE_ADDED : NoteConstants.NOTE_UPDATED;
            if (savedNote.getType().equals(NoteConstants.NOTE_REJECT_COMMENT))
            {
                noteEvent = String.format("rejectcomment.%s", noteEvent);
            }
            publishNoteEvent(httpSession, savedNote, noteEvent, true);

            return savedNote;
        }
        catch (Exception e)
        {
            // Create a fake note to audit the failure.
            Note fakeNote = new Note();
            fakeNote.setId(note.getId());
            log.info("fake id : ()", fakeNote.getId());
            log.info("fake id 2: {}", note.getId());

            fakeNote.setParentId(note.getParentId());
            fakeNote.setParentType(note.getParentType());
            fakeNote.setParentTitle(note.getParentTitle());
            fakeNote.setNote(note.getNote());
            fakeNote.setCreator(note.getCreator());
            fakeNote.setCreated(note.getCreated());
            fakeNote.setType(NoteConstants.NOTE_GENERAL);
            fakeNote.setTag(note.getTag());

            String noteEvent = note.getId() == null ? NoteConstants.NOTE_ADDED : NoteConstants.NOTE_UPDATED;

            if (fakeNote.getType().equals(NoteConstants.NOTE_REJECT_COMMENT))
            {
                noteEvent = String.format("rejectcomment.%s", noteEvent);
            }

            publishNoteEvent(httpSession, fakeNote, noteEvent, false);
            throw new AcmUserActionFailedException("unable to add note from ", note.getParentType(), note.getParentId(), e.getMessage(), e);
        }
    }

}