Package com.veeva.vault.sdk.api.annotation
When viewing documents in the Vault UI, users can add and reply to annotations. There are multiple types of
annotations, including Sticky Note (note__sys), Line (line__sys), Anchor (anchor__sys),
and Reply (reply__sys). The interfaces in this package allow you to read information for all annotation
types, and to save and delete them.
You can find full lists and descriptions of annotation types, fields, placemarks, and references in the Developer Portal.
The following example uses AnnotationService to read
all note and line annotations on a document:
// Read all note and line annotations on document 123 v1.0
Set<String> types = VaultCollections.newSet();
types.add("note__sys");
types.add("line__sys");
annotationService.readAnnotations(
annotationService.newReadAnnotationRequestBuilder()
.withDocumentVersionId("123_1_0")
// If we didn't set withAnnotationTypes, Vault would attempt to read
// all visible, non-reply annotation types
.withAnnotationTypes(types)
.build()
).onError(
errorResult -> {
// Check for batch-level errors such as a missing document
if (errorResult.getType() ==
AnnotationReadErrorType.DOCUMENT_NOT_FOUND) {
// Handle this error here
}
}
).onSuccess(
response -> response.streamResults().forEach(annotation -> {
// For each of the resulting annotations, retrieve field
// values and the annotation placemark
String state = annotation.getValue(
"state__sys",
AnnotationValueType.STRING);
String color = annotation.getValue(
"color__sys",
AnnotationValueType.STRING);
String comment = annotation.getValue(
"comment__sys",
AnnotationValueType.STRING);
BigDecimal page = annotation.getPlacemark().getValue(
"page_number__sys",
AnnotationPlacemarkValueType.NUMBER);
// Retrieve specific coordinates for the placemark. There will be 8*n
// coordinates, where n is the number of rectangles that make up the
// annotation placemark. The coordinates for each rectangle are in
// the order (x1, y1, x2, y2, x3, y3, x4, y4). Each two coordinates
// specify the location of a corner of the rectangle.
List<BigDecimal> coordinates = annotation.getPlacemark().getValue(
"coordinates__sys",
AnnotationPlacemarkValueType.NUMBER_LIST
);
for (int i = 8; i <= coordinates.size(); i = i + 8) {
List<BigDecimal> oneRectangle = coordinates.subList(i - 8, i);
// We can work with the coordinate values for each rectangle
// here
}
// Retrieve replies for the given annotation
annotationService.readReplies(
annotationService.newReadReplyRequestBuilder()
.withParentId(
annotation.getValue(
"id__sys",
AnnotationValueType.STRING
)
).build()
).onSuccess(
replyResponse -> replyResponse.streamResults()
.forEach(reply -> {
// Stream the replies
String replyState = reply.getValue(
"state__sys",
AnnotationValueType.STRING);
String replyColor = reply.getValue(
"color__sys",
AnnotationValueType.STRING);
String replyComment = reply.getValue(
"comment__sys",
AnnotationValueType.STRING);
})
).onError(
errorResult -> {
// Check for errors when fetching replies
if (errorResult.getType() ==
AnnotationReadErrorType.ANNOTATION_NOT_FOUND) {
// Handle this error here
}
}
).execute();
})
).execute();
You can also use AnnotationService to create and update annotations.
The following example creates a new note annotation and updates an existing link annotation on the same document:
List<Annotation> annotations = VaultCollections.asList(
// NEW NOTE WITH AREA SELECTION
annotationService.newAnnotationBuilder()
.withTypeName("note__sys")
.withValue("document_version_id__sys", "1234_0_1")
// User mentions are validated
.withValue("comment__sys", "mention for [+sample.user@veeva.com]")
.withValue("color__sys", "orange_light__sys")
.withValue("state__sys", "open__sys")
.appendReplies(VaultCollections.asList(
annotationService.newAnnotationBuilder()
.withTypeName("reply__sys")
.withValue("color__sys", "green_dark__sys")
.withValue("comment__sys", "make sure you follow up")
// Don't specify placemark, it's implied for replies
.build()
)
)
.withPlacemark(
annotationService.newPlacemarkBuilder()
.withTypeName("rectangle__sys")
.withValue("page_number__sys", BigDecimal.valueOf(1))
.withValue("x_coordinate__sys", BigDecimal.valueOf(5.0))
.withValue("y_coordinate__sys", BigDecimal.valueOf(5.0))
.withValue("height__sys", BigDecimal.valueOf(1.0))
.withValue("width__sys", BigDecimal.valueOf(1.0))
.withValue("style__sys", "rectangle_dashed__sys")
.build()
)
.build(),
// UPDATE DOCUMENT LINK
annotationService.newAnnotationBuilderWithId("57")
.withReferences(VaultCollections.asList(
annotationService.newReferenceBuilder()
.withTypeName("document__sys")
.withValue("document_version_id__sys", "12345_2_0")
.withValue("annotation__sys", "102")
.build()
)
)
.build()
);
// Perform the batch save operation
annotationService.batchSaveAnnotations(
annotationService.newBatchSaveRequestBuilder()
.withAnnotations(annotations)
.build()
).onSuccesses(successList -> {
for (AnnotationBatchSaveSuccess success : successList) {
int requestIndex = success.getInputPosition();
// Stream the IDs of the new annotations created or updated by the
// request index above
success.streamSavedAnnotations().forEach(
newAnnotationId -> {
// Use the newAnnotationId as needed
}
);
}
}
).onErrors(batchErrors -> {
for (AnnotationBatchSaveError batchError : batchErrors) {
int requestIndex = batchError.getInputPosition();
String errorMessage = batchError.getError().getMessage();
AnnotationBatchSaveErrorType errorType = batchError.getError()
.getType();
// Use the above error information as needed
}
}
).ignoreErrors().execute();
In the event that a document has identical content on multiple pages, you can copy annotations on text selections from one page to another. The example below illustrates how to retrieve information from a note annotation on page 1 of a document and create an identical annotation with the same text selection and comment on page 2:
annotationService.readAnnotations(
// Set up the read operation to read the annotation by ID
annotationService.newReadAnnotationRequestBuilder()
.withAnnotationIds(VaultCollections.asList("100"))
.build()
).onSuccess(
response -> response.streamResults().forEach(annotation -> {
List<Annotation> annotations = VaultCollections.asList(
// Create a new annotation on the same document as the original
// annotation, copying the comment and text indexes, but set it to
// page 2
annotationService.newAnnotationBuilder()
.withTypeName("note__sys")
.withValue("document_version_id__sys",
annotation.getValue("document_version_id__sys",
AnnotationValueType.STRING))
.withValue("comment__sys",
annotation.getValue("comment__sys",
AnnotationValueType.STRING))
.withPlacemark(
annotationService.newPlacemarkBuilder()
.withTypeName("text__sys")
.withValue("page_number__sys", BigDecimal.valueOf(2))
.withValue("text_start_index__sys",
annotation.getPlacemark().getValue(
"text_start_index__sys",
AnnotationPlacemarkValueType.NUMBER))
.withValue("text_end_index__sys",
annotation.getPlacemark().getValue(
"text_end_index__sys",
AnnotationPlacemarkValueType.NUMBER))
.build()
)
.build()
);
annotationService.batchSaveAnnotations(
annotationService.newBatchSaveRequestBuilder()
.withAnnotations(annotations)
.build()
).execute();
})
).execute();
Use AnnotationMetadataService to read metadata about annotation
types, fields, placemarks, and references. The following example illustrates how to read the allowed colors and text
styles for the Note annotation type:
// Get metadata for the Note annotation type
AnnotationType noteType = annotationMetadataService.getType(
annotationMetadataService.newTypeRequestBuilder()
.withName("note__sys")
.build()
);
// Get metadata for the Color annotation field
AnnotationField colorField = annotationMetadataService.getField(
annotationMetadataService.newFieldRequestBuilder()
.withName("color__sys")
.build()
);
// Get the allowed values for Color for Note types. First, double-check that
// Color is a field that has a value set, and double-check that Color is an
// allowed field for Notes.
Collection<String> allowedColors = new HashSet<>();
if (colorField.hasValueSet() &&
noteType.getFields().contains(colorField.getName())) {
allowedColors.addAll(
annotationMetadataService.getValueSet(
annotationMetadataService.newValueSetRequestBuilder(
AnnotationValueType.STRING)
.withField(colorField.getName())
.withType(noteType.getName())
.build()
)
);
}
// Get metadata for the Text annotation placemark type
AnnotationPlacemarkType textType = annotationMetadataService.getPlacemarkType(
annotationMetadataService.newPlacemarkTypeRequestBuilder()
.withName("text__sys")
.build()
);
// Get metadata for the Style annotation placemark field
AnnotationPlacemarkField styleField = annotationMetadataService
.getPlacemarkField(
annotationMetadataService.newPlacemarkFieldRequestBuilder()
.withName("style__sys")
.build()
);
// Get the allowed values for Style for Text types. First, check that
// Style is a field that has a value set, Text is an allowed placemark
// type for Note annotation types, and Style is an allowed field for
// Text placemarks.
Collection<String> allowedStyles = new HashSet<>();
if (styleField.hasValueSet() &&
noteType.getAllowedPlacemarkTypes().contains(textType.getName()) &&
textType.getFields().contains(styleField.getName())) {
allowedStyles.addAll(
annotationMetadataService.getPlacemarkValueSet(
annotationMetadataService.newPlacemarkValueSetRequestBuilder(
AnnotationPlacemarkValueType.STRING)
.withField(styleField.getName())
.withType(textType.getName())
.build()
)
);
}
-
ClassDescriptionRepresents a document annotation.Creates an instance of
Annotation.Represents a positional error result for batch delete operations calls fromAnnotationService, indicating that one of the inputs in the batch failed.Provides data about an error included in the response of batch delete operations provided byAnnotationService, including the error message and type.Represents the error types included in the response of batch delete operations provided byAnnotationServicewhen a particular input fails with an error.Represents a request to delete multiple annotations by providing aListof annotation IDs.Creates an instance ofAnnotationBatchDeleteRequest.Represents a positional error result for batch save operations calls fromAnnotationService, indicating that one of the inputs in the batch failed.Provides data about an error included in the response of batch save operations provided byAnnotationService, including the error message and type.Represents error types included in the response of batch save operations provided byAnnotationServicewhen a particular input fails with an error.Represents a request to create or update multiple annotations by providing aListofAnnotations.Creates an instance ofAnnotationBatchSaveRequest.Represents the result of processing anAnnotationService.batchSaveAnnotations(AnnotationBatchSaveRequest), indicating that one of theAnnotations passed in the batch successfully created at least one resulting annotation.Provides methods to retrieve common metadata information of the specified annotation field.Provides methods to retrieve the metadata of anAnnotationField.Creates an instance ofAnnotationFieldRequest.Provides methods to retrieve metadata about annotation types, annotation fields, placemark types, placemark fields, reference types, and reference fields.Represents an annotation placemark and provides methods to retrieve field values and type names for any annotation placemark type.Creates an instance ofAnnotationPlacemark.Provides methods to retrieve common metadata information of the specified annotation placemark field.Retrieves an instance ofAnnotationPlacemarkFieldto build the request for retrieving annotation placemark field metadata.Creates an instance ofAnnotationPlacemarkFieldRequest.Provides methods to retrieve common metadata information of the specified annotation placemark type.Retrieves an instance ofAnnotationPlacemarkTypeto build the request for retrieving annotation placemark type metadata.Creates an instance ofAnnotationPlacemarkTypeRequest.Used to request the value set of anAnnotationPlacemarkFieldon a particularAnnotationPlacemarkType.Creates an instance ofAnnotationPlacemarkValueSetRequest.Types of data supported byAnnotationPlacemarks.Represents an error included in the response of read operations provided byAnnotationService.Error types that may occur during read operations provided byAnnotationServicewhen a request fails with an error.A sequence of instructions that can be chained together to read annotations, building up to a final operation that can be executed withAnnotationReadOperation.execute().Requests to read multiple annotations by providing either aListof unique annotation IDs or a document version ID to read annotations from.A builder for anAnnotationReadRequest, including filters on the request.Response from a call toAnnotationService.readAnnotations(AnnotationReadRequest).Represents an annotation reference.Creates an instance ofAnnotationReference.Provides methods to retrieve common metadata information of the specified annotation reference field.Used to request the metadata of anAnnotationReferenceField.Creates an instance ofAnnotationReferenceFieldRequest.Provides methods to retrieve common metadata information of the specified annotation reference type.Used to request the metadata of anAnnotationReferenceType.Creates an instance ofAnnotationReferenceTypeRequest.Used to request the value set of anAnnotationReferenceFieldon a particularAnnotationReferenceType.Creates an instance ofAnnotationReferenceValueSetRequest.Types of data supported byAnnotationReferences.Requests to read the replies of a given parent annotation.Creates an instance ofAnnotationReplyReadRequest.Provides methods to manage document annotations in Vault.Provides methods to retrieve common metadata information of the specified annotation type.Used to request the metadata of anAnnotationType.Creates an instance ofAnnotationTypeRequest.Used to request the value set of anAnnotationFieldon a particularAnnotationType.Creates an instance ofAnnotationValueSetRequest.Types of data supported byAnnotations.