Free Support Forum -

Custom format and location of annotation storage

Hello dear GroupsDocs team! Thank you for your help.

I have a question for you. Can I save information about annotations not in annotation.db and in data.db, but where I want, for example, in an XML file?

Thanks in advance


Hello, dear Alexey, you are welcome!

Unfortunately currently this is not possible with the GroupDocs.Annotation for Java library of version 1.5.0. But the 1.6.0 version of this application will support any DB that is supported with ORMLite library, specific XML output was not implemented.
Can you describe your use-case more, so we may assist you better with this question?

The 1.6.0 version of the GroupDocs.Annotation for Java library is going to be released in the end of this week or on the beginning of the next one.


The issues you have found earlier (filed as ANNOTATIONJAVA-465;ANNOTATIONJAVA-465;ANNOTATIONJAVA-465) have been fixed in this update.

This message was posted using Notification2Forum from Downloads module by groupdocs.notifier.


Dear Team -

the underlying problem is that we need to store all annotations with the document in our repository.

You should publish a GETTER and a SETTER for annotations:
- whenever you want to show an annotation that was previously given, you call that GETTER
–> you will be able to call the GETTER until you have retrieved all annotations for a given document
- whenever you want to store an annotation permanently you’ll call the SETTER and we take care

This could be similar to the method that we can overwrite to point to the document we want to annotate.


(Alexey will provide some “pseudo” code)

your class with default implementation:

class AnnotationManager {
public void save(Annotation annotation){....}

public Annotation getAnnotation(int id){.... return annotation);

public List getAllDocumentAnnotations(int documentId) {...}

our custom Manager:

class MyAnnotationManager extends AnnotationManager{
public void save(Annotation annotation){.... //save in xml/db/json...}

public Annotation getAnnotation(int id){.... return annotation);

public List getAllDocumentAnnotations(int documentId) {...}


and setter of Manager in MainApplication:

AnnotationManager customManager = new MyAnnotatioManager();




thank a lot for your job.

I have a problem with storage in a xml file. I use the example for annotation library version 1.7 with dropwizard.

I have in configuration.yml:

# Storage type
# default | sqlite | mysql | mssql | postgre | json | xml | custom
storageType: custom

# Logic of files storage (only for xml and json storage)
# one | few | many | lot
storeLogic: one

on start the application is in folder “temp” the file “data.db” created. The files “annotation.xml”, “SystemInfo.xml” and “Reply.xml” aren’t created. In folder “temp” there are only Collaborator.xml, Document.xml, Session.xml and User.xml.

also the content is very strange, for example in user.xml:
<?xml version="1.0"?>



what ist hier “a”, “b” etc.?

The files Reply.xml and annotation.xml are created only if at least one annotation are created. But the question about content and the file “data.db”(why do we need the file?) stay actual yet. And why does not the flag “one” work?

Where can I find documentation for the flags in configuration.yml?

Thanks im advance



Dear Norbert and Alexey,

Thank you for this architectural approach proposition. We will discuss it with our developers.
What about storing annotations into XML or JSON files (to keep it in repository). Thanks to your request this feature is already under development and will be released with the next version of the GroupDocs.Annotation for Java library.

Hello Alexey, thanks for your appreciation and getting back in touch.

Let me explain what is happening in the code appropriate to changes you have provided and the Dropwizard example.

When you set "storageType: custom" then the AnnotationHandler instance uses the CustomXmlDataConnector as the meta-data connector, you can see it in the src\main\java\com\groupdocs\annotation\dropwizard\ on the 89 line.

storeLogic: one
In the same you can see that the storage logic is not used in this custom connector. As comments and code on lines 62, 80, 83 tell it is meaningful only for the JsonDataConnector or XmlDataConnector. The CustomXmlDataConnector is just a sample code. Probably, it’s something similar to the FEW storage logic.

on start the application is in folder "temp" the file "data.db" created. The files "annotation.xml", "SystemInfo.xml" and "Reply.xml" aren't created. In folder "temp" there are only Collaborator.xml, Document.xml, Session.xml and User.xml.
data.db is needed for the page caching it has nothing with the annotations meta-data.
annotation.xml, SystemInfo.xml and Reply.xml files are created on demand (try to add some annotations). Also, note that the CustomXmlDataConnector stores annotation.xml files inside the document cache folder.

also the content is very strange, for example in user.xml:
Thank you for this, we’ve checked it and reported to our developers. They started to work on it.

Where can I find documentation for the flags in configuration.yml?
Please, check this documentation page:



us would fit xml /json if a separate xml/json file was created for each word document, not one xml file for all word documents. Would it be possible?

Thanks in advance



Thanks for answer,

i have a problem with the class “AnnotationHandler”. The class has the method “addCollaborator(String userName, String fileGuid, Integer accessRights, int color)”. The metod are used in method “publicAnnotationView getAnnotation(…)” in class “AnnotationResource” in line:
final String userGuid = annotationHandler.addCollaborator(usrName, initialPath, AccessRights.from(AccessRights.All), Utils.colorToInt(;
the method “addCollaborator” is final, but i must it overload for insert in my user.xml.

also there is not a parameter documentId in parameter list in method “selectBy(List var1, Object… var2)” for IUser. So can I not find out the document and its user.xml


The current implementation out of the box will allow to store all annotations into single file. In addition, provided interfaces will allow you to override the default functionality and develop the one that fits your use-case perfectly.

Hello Alexey,

If you want to save user meta-data you need to implement the IUserDao interface and return it in the getUserDao() method of the AbstractDataConnector implementation. You don’t need to override any AnnotationHandler methods.

also there is not a parameter documentId in parameter list in method "selectBy(...
selectBy uses key-value approach. The first argument is a list of the keys, other arguments – are values for the provided keys. Depending on the context (in what IDao implementation the request occurs) different keys are passed in the first argument. You can check it by yourself in the debug mode. All possible keys you can find in the entity interfaces (in the package).


when will appear the new version with this functionality?

best regards



I did it.

In selectBy( …) for IUser there is only one parameter “guid”, the parameter “documentGuid” there is NOT! How can I find out wich document is it?

in line

final String userGuid = annotationHandler.addCollaborator(usrName, initialPath, AccessRights.from(AccessRights.All), Utils.colorToInt(;

i must find the correct user.xml. The file dont exist at time point, because is it first method call.

can we do skype conference?


see the komment:

Do I correctly understand that a document can have only one Session in one time point? It means that a document can annotate only one user at one moment?
It means for example a document cannot annotate two users at the same time?


The new version is planned to be released on October 31.

Hello Alexey,

We had a long conversation with developers about possible solutions in this case. Unfortunately, currently inside the IUserDao.selectBy request there is no way to find out from what document or collaborator was this request. Under these circumstances you can try to gather created users using the collaborator Guid obtained from the AnnotationHandler.addCollaborator method. To make things clear, the Collaborator entity represents the-User-opened-the-Document connection. With collaborator Guid you can use DaoFactory.createCollaboratorDao(); and further calls to obtain necessary Collaborator and User info, or even you can start this chain from the document guid.

But I think it will be better to find a way to store Collaborators and Users integrally in one place (at least Users, because Collaborators can be created again with no data loss, only performance loss). Probably, there may be id collisions. Please, see the entities picture: We did not test such cases and can’t say for sure.


Actually there could be unlimited number of sessions per the particular document. Session is binding the user with the document it opened. As the environment is multithreaded (many users can open a single document in their browsers and server can process multiple requests simultaneously) many users can annotate documents at one time.



i have the beta version of the library version 1.7. You make it so that only annotation.xml is specific for one word-document. All other informations are global, it means there is one xml-file for f.e. all replays for all documents. I would like all annotation’s information for one word-document separatly. I can save replys for document:

protected void saveData(List data) {
String tempPath = Utils.getTempPath();
FileOutputStream fileOutputStream = null;
try {
ISessionDao sessionDao = DaoFactory.createSessionDao();
IDocumentDao documentDao = DaoFactory.createDocumentDao();
IAnnotationDao annotationDao = DaoFactory.createAnnotationDao();

int annotationId = data.get(0).getAnnotationId();
IAnnotation annotation = annotationDao.selectBy(Arrays.asList(IAnnotation.ID), annotationId);
ISession session = sessionDao.selectBy(Arrays.asList(ISession.ID), annotation.getAnnotationSessionId());
IDocument document = documentDao.selectBy(Arrays.asList(IDocument.ID), session.getDocumentId());
String documentGuid = document.getDocumentName();

File file = new File(tempPath + File.separator + documentGuid + File.separator + REPLY_FILE_NAME);

fileOutputStream = new FileOutputStream(file);
saveObjectAsXml(data, fileOutputStream);
} catch (Exception e) {
} finally {

but i can’t load replays because the method List loadData() doesn’t have the information about the document,it means i dont know where is the document?

yet a moment:

when i load a new document you make a new folder for this, it has a name for example “f”. How is the name made? I would like to decide self what is the name.

Could you implement this?

Thanks in advance