InternalValue val = values[i];
switch (state.getType()) {
case PropertyType.BINARY:
// special handling required for binary value:
// spool binary value to file in blob store
BLOBFileValue blobVal = (BLOBFileValue) val.internalValue();
long size = blobVal.getLength();
if (size < 0) {
log.warn("Blob has negative size. Potential loss of data. " +
"id={} idx={}", state.getId(), String.valueOf(i));
out.writeInt(0);
values[i] = InternalValue.create(new byte[0]);
blobVal.discard();
} else if (size > minBlobSize) {
out.writeInt(-1);
String blobId = state.getBlobId(i);
if (blobId == null) {
try {
InputStream in = blobVal.getStream();
try {
blobId = blobStore.createId(state.getId(), i);
blobStore.put(blobId, in, size);
state.setBlobId(blobId, i);
} finally {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
} catch (Exception e) {
String msg = "Error while storing blob. id="
+ state.getId() + " idx=" + i + " size=" + size;
log.error(msg, e);
throw new IOException(msg);
}
try {
// replace value instance with value
// backed by resource in blob store and delete temp file
if (blobStore instanceof ResourceBasedBLOBStore) {
values[i] = InternalValue.create(((ResourceBasedBLOBStore) blobStore).getResource(blobId));
} else {
values[i] = InternalValue.create(blobStore.get(blobId), false);
}
} catch (Exception e) {
log.error("Error while reloading blob. truncating. id=" + state.getId() +
" idx=" + i + " size=" + size, e);
values[i] = InternalValue.create(new byte[0]);
}
blobVal.discard();
}
// store id of blob as property value
out.writeUTF(blobId); // value
} else {
// delete evt. blob
out.writeInt((int) size);
byte[] data = new byte[(int) size];
try {
InputStream in = blobVal.getStream();
try {
int pos = 0;
while (pos < size) {
int n = in.read(data, pos, (int) size-pos);
if (n < 0) {
throw new EOFException();
}
pos += n;
}
} finally {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
} catch (Exception e) {
String msg = "Error while storing blob. id="
+ state.getId() + " idx=" + i + " size=" + size;
log.error(msg, e);
throw new IOException(msg);
}
out.write(data, 0, data.length);
// replace value instance with value
// backed by resource in blob store and delete temp file
values[i] = InternalValue.create(data);
blobVal.discard();
}
break;
case PropertyType.DOUBLE:
out.writeDouble(((Double) val.internalValue()).doubleValue());
break;