/** * Helper function to set a field on an object only if the new value is not null. If you wish to * reset the value of a field, pass the empty string for the new value. * * @param object the object to set the value of the field * @param fieldName the name of the field to set * @param newValue the new value to set to the field. It will be ignored if it's {@code null} * @param deprecatedContext the XWikiContext * @return {@code true} if the field was set to newValue, {@code false} otherwise */ protected boolean setIfNotNull( BaseObject object, String fieldName, Object newValue, XWikiContext deprecatedContext) { if (newValue != null) { object.set(fieldName, newValue, deprecatedContext); return true; } return false; }
/** * {@inheritDoc} <br> * This implementation saves the added annotation in the document where the target of the * annotation is. * * @see org.xwiki.annotation.io.IOService#addAnnotation(String, org.xwiki.annotation.Annotation) */ @Override public void addAnnotation(String target, Annotation annotation) throws IOServiceException { try { // extract the document name from the passed target // by default the fullname is the passed target String documentFullName = target; EntityReference targetReference = referenceResolver.resolve(target, EntityType.DOCUMENT); // try to get a document reference from the passed target reference EntityReference docRef = targetReference.extractReference(EntityType.DOCUMENT); if (docRef != null) { documentFullName = serializer.serialize(docRef); } // now get the document with that name XWikiContext deprecatedContext = getXWikiContext(); XWikiDocument document = deprecatedContext.getWiki().getDocument(documentFullName, deprecatedContext); // create a new object in this document to hold the annotation int id = document.createXObject(configuration.getAnnotationClassReference(), deprecatedContext); BaseObject object = document.getXObject(configuration.getAnnotationClassReference(), id); updateObject(object, annotation, deprecatedContext); // and set additional data: author to annotation author, date to now and the annotation target object.set(Annotation.DATE_FIELD, new Date(), deprecatedContext); // TODO: maybe we shouldn't trust what we receive from the caller but set the author from the // context. // Or the other way around, set the author of the document from the annotations author. object.set(Annotation.AUTHOR_FIELD, annotation.getAuthor(), deprecatedContext); // store the target of this annotation, serialized with a local serializer, to be exportable // and importable // in a different wiki // TODO: figure out if this is the best idea in terms of target serialization // 1/ the good part is that it is a fixed value that can be searched with a query in all // objects in the wiki // 2/ the bad part is that copying a document to another space will not also update its // annotation targets // 3/ if annotations are stored in the same document they annotate, the targets are only // required for object // fields // ftm don't store the type of the reference since we only need to recognize the field, not to // also read it. if (targetReference.getType() == EntityType.OBJECT_PROPERTY || targetReference.getType() == EntityType.DOCUMENT) { object.set( Annotation.TARGET_FIELD, localSerializer.serialize(targetReference), deprecatedContext); } else { object.set(Annotation.TARGET_FIELD, target, deprecatedContext); } // set the author of the document to the current user document.setAuthor(deprecatedContext.getUser()); deprecatedContext .getWiki() .saveDocument( document, "Added annotation on \"" + annotation.getSelection() + "\"", deprecatedContext); // notify listeners that an annotation was added ObservationManager observationManager = componentManager.lookup(ObservationManager.class); observationManager.notify( new AnnotationAddedEvent(documentFullName, object.getNumber() + ""), document, deprecatedContext); } catch (XWikiException e) { throw new IOServiceException( "An exception message has occurred while saving the annotation", e); } catch (ComponentLookupException exc) { this.logger.warn( "Could not get the observation manager to send notifications about the annotation add"); } }