Hi all,

I've implemented a document adapter service.

What is this?
This is a service that lets you dynamically adapt a document (i.e. a DocumentModel object) to a random Java interface.

What's good for?
Let's say you want to add a document type "AnnotatedDocument" that define a document that can be annotated with random information. The DocumentModel object doesn't have methods to set and get the annotated information. You can modify it to add these methods but this is not acceptable -> Nuxeo5 must allow to dynamically extend the behavior of documents - we cannot hard-code each specific behavior inside the document model itself which is a generic document. Until now we was able to do this by using external services - something like creating a service something like this:

public class AnnotationService {
public void setAnnotation(DocumentModel doc, String name, Object annotation) { // ... set the annotation .. (may use custom storage outside the repository)
   }

   public Object getAnnotation(DocumentModel doc, String name) {
      // ... get the annotation from the storage
      return annotation;
   }

}

Then in web client you use call to this service like this:
AnnotationService annotationSvc = ... fetch the service ...
annotationSvc.setAnnotation(doc, "myannotation", "hello");
...
Object anno = annotationSvc.getAnnotation(doc, "myannotation");
...

And you may be want to use a local object to cache this info to avoid fetching each time the annotation from the backend service which may be on a remote machine

You will end up with many little objects linked to a document model instance which may be painful to manage

So how the document adapter service can help you?

You need to define 3 classes:
1. An interface to adapt the document to :

public interface AnnotatedDocument {
   setAnnotation(String name, Object annotation);
   getAnnotation(String name);
}


2. An adapter factory that knows how to adapt a specific document model instance (giving its document type) to an interface (for example to AnnotatedDocument)

public class AnnotatedDocumentFactory implements DocumentAdapterFactory {
   public Object getAdapter(DocumentModel doc, Class itf) {
       return new AnnotatedDocumentAdapter(doc);
   }
}

3. The adapter itself:

public class AnnotatedDocumentAdapter implements AnnotatedDocument {

   DocumentModel doc;
   Map<String, Object> annotations;
AnnotationService svc;
   public AnnotatedDocumentAdapter(DocumentModel doc) {
       this.doc =doc;
       // initialize the cache
       this.annotations = new HashMap<String, Object>();
       // lookup the (possibly remote) annotation service
       svc = ... JNDI Lookup ...
   }
public Object getAnnotation(String name) {
      Object anno = this.annotations.get(name);
       if (anno ==null) {
          // get annotations using the (possibly remote) annotation service
          // .. anno = ..
       }
       return anno;
   }
public void putAnnotation(String name, Object value) {
       annotations.put(name, value);
      // save annotations using the (possibly remote) annotation service
      // ..
   }
}


And to register your new adapter you must contribute an extension like:

<extension target="org.nuxeo.ecm.core.api.DocumentAdapterService" point="adapters">
       <adapter doctype="File"
           class="org.nuxeo.ecm.core.api.adapter.AnnotatedDocument"
factory="org.nuxeo.ecm.core.api.adapter.AnnotatedDocumentFactory"/>
</extension>
And that's all. Now you can use on the client the following code to use annotations:

-----------------------------------------------

DocumentModel doc = .. get a document model ..
...
AnnotatedDocument annoDoc = doc.getAdapter(org.nuxeo.ecm.annotation.AnnotatedDocument.class);
annoDoc.setAdapter("myannotation", value);
...
// later you can refetch the annotation facet and retrieve current state:
annoDoc = doc.getAdapter(org.nuxeo.ecm.annotation.AnnotatedDocument.class);
annoDoc.getAnnotation("myannotation");

-------------------------------------------------

You can implement any optional "facet" of a document this way.
This is easy to write, to use and also provide total control over the operations you need to perform (like caching etc)

You can look into NXCoreFacade tests if you want to see an example of how this service can be used

Bogdan


_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm

Reply via email to