cancel
Showing results for 
Search instead for 
Did you mean: 

How to update content with ContentWriter class

sergio
Champ in-the-making
Champ in-the-making
Hi all.

I need to modify the content (plain/text) of an existing node programatically. At first, I thought to use the ContentWriter class and its put() method.

I have to replace the content of a node entirely so I tried to get the ContentReader associated to the node, to store it into a String variable, to modify the string itself accordingly to my custom needs, then to write the new string to the ContentWriter. I noticed that the put() method does not replace the content but appends a new content to the old one, doesn't it?

How can I update the content of a node? Can I use the ContentReader  class or should I prefer other classes?

Any suggestion will be very appreciated.

All the best,

Sergio
7 REPLIES 7

stijndereede
Champ in-the-making
Champ in-the-making
Hi Sergio,

I don't know what the preferred way is, since I'm not an Alfresco developer or something, but this might work:
Create a new ContentData object and assign it to the node with the nodeService:

ContentData content  = ContentData.createContentProperty("My content.");
nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, content);

sergio
Champ in-the-making
Champ in-the-making
Thank for your adivices, but I think that the method you suggested me is only responsible for modifying the content property of a node and not for modifying the content of the associated file, too.

Did you try the suggested method by yourself to update the content of a node associated file? Did you do it after creating a node or just during its first creation?

At the moment, the only way I am going to try (but I am not sure it could be the most correct at all) consists of creating programmatically a new node, getting its content writer, writing the new content, then renaming the new node as the old one after deleting this one.

Other suggestions for getting this goal will be very appreciated.

All the best,

Sergio

kevinr
Star Contributor
Star Contributor
I need to modify the content (plain/text) of an existing node programatically. At first, I thought to use the ContentWriter class and its put() method.

I have to replace the content of a node entirely so I tried to get the ContentReader associated to the node, to store it into a String variable, to modify the string itself accordingly to my custom needs, then to write the new string to the ContentWriter. I noticed that the put() method does not replace the content but appends a new content to the old one, doesn't it?

How can I update the content of a node?

Use ContentWriter - the put() method will overwrite the existing content (ensure the String you have manipulated does not still contain the old content!)

Kevin

sergio
Champ in-the-making
Champ in-the-making
Hi Kevin.

You are perfectly right! I made a mistake when manipulating different java streams and I was not able to find the problem, at a first glance. So I thought the ContentWriter.put() method did not overwrite the content but appended it in such a way I was not able to understand. Sorry.

Actually, the method ContentWriter.put() does exactly what expected: it is responsible for updating the content of a node.

Many thanks and all the best.

Sergio

tommorris
Champ in-the-making
Champ in-the-making
Related to this post, what if I did want to append text to the existing content of a file?

I've tried append, but it only overwrites the whole content with the new string.

A simplified code example:
ContentService contentService = this.serviceRegistry.getContentService();
ContentWriter contentWriter = contentService.getWriter(nodeCurrentLogFile, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype("text/plain");
OutputStream outputStream = contentWriter.getContentOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);

//printWriter.println(logLine); // Replaces the whole content with logLine.
//printWriter.append(logLine); // Replaces the whole content with logLine.
printWriter.write(logLine, (int) contentWriter.getSize(), logLine.length());  // Replaces the whole content with logLine.

printWriter.flush();
printWriter.close();

Am I missing something fundamental here?

tommorris
Champ in-the-making
Champ in-the-making
Solved this problem. Wasn't thinking properly. Silly me.

Simplified code working example:

ContentWriter contentWriter = contentService.getWriter(nodeCurrentLogFile, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype("text/plain");
FileChannel fileChannel = contentWriter.getFileChannel(false);
ByteBuffer bf = ByteBuffer.wrap(logLine.getBytes());
fileChannel.position(contentWriter.getSize());
fileChannel.write(bf);
fileChannel.force(false);
fileChannel.close();

I'm attempting to do this, but having tried both approaches shown above (FileChannel, PrintWriter), although the write appears to complete, I then get the following exception shown in the log, and no data is present in the file

2019-06-05 09:04:57,497 ERROR [extensions.webscripts.AbstractRuntime] [http-nio-8080-exec-7] Exception from executeScript: Transaction silently rolled back because it has been marked as rollback-only