3.2.3.1. Usage

In both of the cases, a developer can set/update the binary Property via Node.setProperty(String, InputStream), Property.setValue(InputStream) as described in the JSR-170 specification. Also, there is the setter with a ready Value object (obtaining from ValueFactory.createValue(InputStream)).

An example of a specification usage.

// Set the property value with given stream content. 

Property binProp = node.setProperty("BinData", myDataStream);
// Get the property value stream. 
InputStream binStream = binProp.getStream();
// You may change the binary property value with a new Stream, all data will be replaced
// with the content from the new stream.
Property updatedBinProp = node.setProperty("BinData", newDataStream);
// Or update an obtained property
updatedBinProp.setValue(newDataStream);
// Or update using a Value object 
updatedBinProp.setValue(ValueFactory.createValue(newDataStream));
// Get the updated property value stream. 
InputStream newStream = updatedBinProp.getStream();

But if you need to update the property sequentially and with partial content, you have no choice but to edit the whole data stream outside and get it back to the repository each time. In case of really large-sized data, the application will be stuck and the productivity will decrease a lot. JCR stream setters will also check constraints and perform common validation each time.

There is a feature of the eXo JCR extension that can be used for binary values partial writing without frequent session level calls. The main idea is to use a value object obtained from the property as the storage of the property content while writing/reading during runtime.

According to the JSR-170 specification, Value interface provides the state of property that cannot be changed (edited). The eXo JCR core provides the ReadableBinaryValue and EditableBinaryValue interfaces which themselves extend the JCR value. The interfaces allow the user to partially read and change a value content.

The ReadableBinaryValue value can be casted from any values, such as String, Binary, Date, and more.

// get the property value of type PropertyType.STRING 

ReadableBinaryValue extValue = (ReadableBinaryValue) node.getProperty("LargeText").getValue();
// read 200 bytes to a destStream from the position 1024 in the value content
OutputStream destStream = new FileOutputStream("MyTextFile.txt");
extValue.read(destStream, 200, 1024);

But EditableBinaryValue can be applied only to properties of the PropertyType.BINARY type. In other cases, a cast to EditableBinaryValue will fail.

After the value has been edited, the EditableBinaryValue value can be applied to the property using the standard setters (for example, Property.setValue(Value), Property.setValues(Value), Node.setProperty(String, Value)). Only after the EditableBinaryValue has been set to the property, it can be obtained in this session by getters (for example, Property.getValue(), Node.getProperty(String)).

The user can obtain an EditableBinaryValue instance and fill it with data in an interaction manner (or any other appropriated to the targets) and return (set) the value to the property after the content is done.

// get the property value for PropertyType.BINARY Property

EditableBinaryValue extValue = (EditableBinaryValue) node.getProperty("BinData").getValue();
// update length bytes from the stream starting from the position 1024 in existing Value data
extValue.update(dataInputStream, dataLength, 1024);
// apply the edited EditableBinaryValue to the Property
node.setProperty("BinData", extValue);
// save the Property to persistence
node.save();

See a practical example of the iterative usage. In this example, the value is updated with data from the sequence of streams and after the update is done, the value will be applied to the property and be visible during the session.

// update length bytes from the stream starting from the particular 

// position in the existing Value data
int dpos = 1024;
while (source.dataAvailable()) {
  extValue.update(source.getInputStream(), source.getLength(), dpos);
  dpos = dpos + source.getLength();
}
// apply the edited EditableBinaryValue to the Property
node.setProperty("BinData", extValue);
Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus