FilesJCROM offers a few different strategies when mapping binary/file content. You can do this directly using a byte or java.io.InputStream field: import org.jcrom.annotations.JcrChildNode;
import org.jcrom.annotations.JcrName;
import org.jcrom.annotations.JcrPath;
import org.jcrom.annotations.JcrProperty;
public class MyClass {
@JcrName private String name;
@JcrPath private String path;
@JcrProperty private byte[] myImage;
...
}But the recommended way is to map to a nt:file node, and JCROM supports this with the JcrFile class. To use the JcrFile class, the file node child needs to be annotated with @JcrFileNode. Let's assume we allow users to upload a single image with each WeblogEntry. We can implement this as follows: import java.util.Date;
import java.util.List;
import org.jcrom.JcrFile;
import org.jcrom.annotations.JcrChildNode;
import org.jcrom.annotations.JcrFileNode;
import org.jcrom.annotations.JcrName;
import org.jcrom.annotations.JcrPath;
import org.jcrom.annotations.JcrProperty;
public class WeblogEntry {
@JcrName private String name;
@JcrPath private String path;
@JcrProperty private String title;
@JcrProperty private String excerpt;
@JcrProperty private String body;
@JcrProperty private Date publishDate;
@JcrProperty private List<String> tags;
@JcrChildNode private Author author;
@JcrChildNode private List<Comment> comments;
@JcrFileNode private JcrFile image;
...
}JCROM will automatically create an nt:folder container node for the file, and map the JcrFile instance to an nt:file node within the folder. This is the recommended way of storing files in JCR. The JcrFile node has fields that correspond (and map) to the nt:file properties and child nodes, such as last modified date, mime type, and encoding (optional). For accessing the file content, JcrFile has a JcrDataProvider field. The JcrDataProvider interface looks like this: package org.jcrom;
import java.io.File;
import java.io.InputStream;
public interface JcrDataProvider {
public enum TYPE {FILE, BYTES, STREAM}
public TYPE getType();
public File getFile();
public byte[] getBytes();
public InputStream getInputStream();
}JCROM provides an implementation of this interface, which is used when reading a file node from JCR, and you can also use it when adding content to a JcrFile instance. For example, if we want to upload a file from a source to which we have an input stream: ...
WeblogEntry weblogEntry = ...;
String imageName = ...;
String imageMimeType = ...;
Calendar imageLastModified = ...;
InputStream imageStream = ...;
JcrFile image = new JcrFile();
image.setName(imageName);
image.setMimeType(imageMimeType);
image.setLastModified(imageLastModified);
image.setDataProvider( new JcrDataProviderImpl(JcrDataProvider.TYPE.STREAM, imageStream) );
weblogEntry.setImage(image);
... JcrFile has static methods that can reduce the lines of code you write. For example, to create a JcrFile instance that has a data provider using a java.io.File, you can simply do: String imageName = ...;
String imageMimeType = ...;
File imageFile = ...;
JcrFile jcrFile = JcrFile.fromFile(imageName, imageFile, imageMimeType); If you have more complex requirements for accessing the file content when mapping to JCR, you can create your own implementation of JcrDataProvider, and add that to your JcrFile instance. Often we need to store some custom metadata on our file nodes. For example, we may want to store information about the photographer with the image. To achieve this we must subclass JcrFile, and add the fields for the custom metadata: import org.jcrom.annotations.JcrNode;
import org.jcrom.annotations.JcrProperty;
@JcrNode(nodeType = "nt:unstructured")
public class Image extends JcrFile {
@JcrProperty private String photographer;
public Image() {
super();
}
...
}Note that we have to specify the nt:unstructured node type. The reason for this is that JcrFile will automatically map to the nt:file node type, but that node type does not allow our photographer property. Therefore we have specified the nt:unstructured node type. A better solution would be to create our own node type that would be a sub-type of nt:file, with our custom metadata properties specified, and use that for the mapping. JCROM supports updating metdata only on file nodes. For example, you may just want to update the name of the photographer, leaving the file itself intact. To do this, just make sure that the data provider on JcrFile is null. JCROM supports mapping a list of JcrFile nodes, using a java.util.List (much in the same way as for properties and children).
|
Hello!
I'm having problems with JCRFile with custom metadata... I have a class Attachment that extends JCRFile and have some custom data... I inserted ok in JCR (jackrabbit 1.4)... But, when I go to do a jcrom.fromNode(Attachment.class, myAttachmentNode, "*", -1); I'm not getting none of JCRFile attributes (dataProvider nor name nor mimeType nor enconding nor lastModfied)... Is it really OK?
The name I have Found why... in Mapper.java you have:
if ( !ReflectionUtils.extendsClass(obj.getClass(), JcrFile.class) ) { // this does not apply for JcrFile extensions setNodeName(obj, node.getName()); }Why this does not apply for JCRFile extensions?
this is normal this piece of code
if ( !node.getName().equals(getCleanName(getNodeName(obj))) ) {
Hello!
cms:folder? > nt:folder, nt:hierarchyNode
cms:file? > nt:file, nt:hierarchyNode
I have added "cms:file" and "cms:folder" nodes successfully but i am not able to add "cms:resource" type of node.
How can i add a node which is having extra properties in "nt:resource" type of node using jcrom?
Thank you.