Search code examples
binaryjava-iojackrabbitjcr

JCR avoid file streaming


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


Solution

  • 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();
      }