1
votes

In my jackrabbit datastore there are large binary files stored. I can browse the datastore filesystem and open these files without any problems.

Now how can I use these files from within my application? I of course could use the getStream() method of type jcr.binary but then I would just stream all the content of the already exsisting file into a new temporary file right? Since my binarys are very large I don't want that. I'm looking for a way to get the full filesystem path of a binary. The method getpath() of jcr.Property only returns the path within the repository and only with the mapped node names and not the node names which are really stored on my filesystem. In general I have to parse a binary object into a Java.IO.File object and I want to avoid Streaming

Edit: Through reflection I saw that the class of my binary is class org.apache.jackrabbit.core.value.BLOBInDataStore I guess I have to somehow access the File value from there

1
What makes you think that getStream() creates temporary files?Robert Munteanu
not getStream() itself but to use it I have to read in every byte into memorynico1510
And what do you want to do with those blobs that does not involve reading them into memory?Robert Munteanu
I want to get the absolute filepath (not only within the datastore) of the blob and pass it as an argument to an external programm. Is there a way (maybe through reflection) to get to this path from an exisiting filestream? Because somewhere the filestream has to get the information from where to stream the bytes...nico1510
You might not want to use the JCR API to pass files to an external system - a WebDAV mount (out of the box with Jackrabbit) or HTTP is probably simpler. If you mount your JCR repository via WebDAV, for example, you'll see your files at the same paths than in the JCR tree.Bertrand Delacretaz

1 Answers

0
votes

I was right when saying that reflection could be of help. Here's my code which returns the physical filepath of a binary stored in a jackrabbit datastore :

public String getPhysicalBinaryPath(Binary b){
    try {
        Field idField=b.getClass().getDeclaredField("identifier");
        idField.setAccessible(true);
        String identifier = (String)idField.get(b).toString();
        Field storeField=b.getClass().getDeclaredField("store");
        storeField.setAccessible(true);
        Object store = storeField.get(b);
        Field pathField = store.getClass().getDeclaredField("path");
        pathField.setAccessible(true);
        String dataStorePath = (String)pathField.get(store);

        String binaryPath = identifier.substring(0,2)+File.separator+
                            identifier.substring(2,4)+File.separator+
                            identifier.substring(4,6)+File.separator+
                            identifier;

        return dataStorePath+File.separator+binaryPath;

    } catch (IllegalArgumentException ex) {
        Logger.getLogger(Repoutput.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(Repoutput.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchFieldException ex) {
        Logger.getLogger(Repoutput.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SecurityException ex) {
        Logger.getLogger(Repoutput.class.getName()).log(Level.SEVERE, null, ex);
    }

        return "";


}

Edit: This is the official way to do it (you'll have to use the jackrabbit-api)

Binary b = session.getValueFactory().createBinary(in);
Value value = session.getValueFactory().createValue(b);
  if (value instanceof JackrabbitValue) {
   JackrabbitValue jv = (JackrabbitValue) value;
   String id = jv.getContentIdentity();
  }