How can we change the default value of the contributors metadata? How can we change the default value of the contributors metadata?

Today's question is raised by vjoussot: How can we change the default value of the contributors metadata?

There is actually a broader topic that we can address here. How can we change the Dublin Core metadata values that are automatically assigned by Nuxeo? Because there are different metadata values that we have chosen to assign automatically and that might not be assigned with what you expect. The contributors is an example, but it could also be the creator, the creation date, the modification date, etc. Now I would be careful about this. Some of the Dublin Core metadata are used by other services of Nuxeo. You might change more things than you originally intended. Anyway, "What's Dublin Core?" you may ask. Here's what Wikipedia has to say about it:

The Dublin Core metadata terms are a set of vocabulary terms which can be used to describe resources for the purposes of discovery. The terms can be used to describe a full range of web resources (video, images, web pages, etc.), physical resources such as books and objects like artworks.

So we use it to store the title, description, creation date, modification date, author, contributors, creator, coverage etc... Some are filled through the creation or edit form (like the title or description), some are filled automatically by a listener (like the creator, creation date, contributors).

Now we have two choices here:

We can define a custom_contributors field in Studio and change the contributors widget in every form and table of the application to display it. Then add an automation chain that sets the right contributors and call it from an EventHandler fired on the documentModified and documentCreated events. That's the no code option.

Then we have the coding involved option. We need to find which listener to change the default behavior. Take a look at NuxeoExplorer in the listener extension point, you can find it easily by typing Dublin Core in the search box. You should see the following listener xml contribution:

 <listener name="dclistener" async="false" postCommit="false"
priority="120">
</listener>


So if you want to know exactly what it does, take a look at the DublinCoreListener source code. We could go in details into this listener and the underlying DublinCoreStorageService, and override them to do exactly what we want to do. But we have a simpler solution. We'll simply add another listener that will set the correct value after the DublinCore listener. To declare a new listener, simply use the Document Listener wizard in Nuxeo IDE. Choose the Document Created and Before document modification and make sure the priority is above 120 (the DublinCore listener priority). In the end you should have something like this:

<listener name="dclistener" async="false" postCommit="false"
priority="150">
<event>documentCreated</event>
<event>beforeDocumentModification</event>
</listener>

Now what's left to do is to update the contributors metadata according to our business rules.

public class MyDublinCoreListener implements EventListener {

public void handleEvent(Event event) throws ClientException {
EventContext context = event.getContext();
if (!(context instanceof DocumentEventContext)) {
// event is not tied to a document, we should not be here
return;
}
DocumentEventContext dContext = (DocumentEventContext) context;
DocumentModel doc = dContext.getSourceDocument();

// Retrieve existing contributors
String[] contributorsArray;
try {
contributorsArray = doc.getProperty("dublincore:contributors").getValue(String[].class);
} catch (ClientException e) {
throw new ClientRuntimeException(e);
}

// Here goes some business code to figure out who's actually the last contributor
// Let's say we want the name of the company instead
Principal principal = dContext.getPrincipal();
String myContributor = principal.getName();
UserManager userManager;
try {
userManager = Framework.getService(UserManager.class);
NuxeoPrincipal nuxeoPrincipal = userManager.getPrincipal(myContributor);
myContributor = nuxeoPrincipal.getCompany();
} catch (Exception e){
throw new RuntimeException(e);
}
List<String> contributorsList = new ArrayList<String>();
contributorsList = Arrays.asList(contributorsArray);
// make it resizable
contributorsList = new ArrayList<String>(contributorsList);
// remove the contributor given by the previous listener
if (contributorsList.contains(principal.getName())) {
contributorsList.remove(principal.getName());
}
// add the contributor
if (!contributorsList.contains(myContributor)) {
contributorsList.add(myContributor);
}
// set the array back in the property
String[] contributorListIn = new String[contributorsList.size()];
contributorsList.toArray(contributorListIn);
try {
doc.setProperty("dublincore", "contributors", contributorListIn);
} catch (ClientException e) {
throw new ClientRuntimeException(e);
}
// set the last contributor too
try {
doc.setProperty("dublincore", "lastContributor", myContributor);
} catch (ClientException e) {
throw new ClientRuntimeException(e);
}
}

}


And there you go :)