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