use of org.exist.xquery.value.BinaryValue in project exist by eXist-db.
the class XQueryContextTest method countBinaryValueInstances.
private int countBinaryValueInstances(final XQueryContext context) throws NoSuchFieldException, IllegalAccessException {
final Field fldBinaryValueInstances = context.getClass().getDeclaredField("binaryValueInstances");
fldBinaryValueInstances.setAccessible(true);
final Deque<BinaryValue> binaryValueInstances = (Deque<BinaryValue>) fldBinaryValueInstances.get(context);
return binaryValueInstances.size();
}
use of org.exist.xquery.value.BinaryValue in project exist by eXist-db.
the class XQueryContextTest method cleanUp_BinaryValueInstances.
/**
* Test to ensure that BinaryValueInstances are
* correctly cleaned up by the XQueryContext
* between reuse of the context
*/
@Test
public void cleanUp_BinaryValueInstances() throws NoSuchFieldException, IllegalAccessException, IOException {
final XQueryContext context = new XQueryContext();
final XQueryWatchDog mockWatchdog = createMock(XQueryWatchDog.class);
context.setWatchDog(mockWatchdog);
final BinaryValue mockBin1 = createMock(BinaryValue.class);
final BinaryValue mockBin2 = createMock(BinaryValue.class);
final BinaryValue mockBin3 = createMock(BinaryValue.class);
final BinaryValue mockBin4 = createMock(BinaryValue.class);
final BinaryValue mockBin5 = createMock(BinaryValue.class);
final BinaryValue mockBin6 = createMock(BinaryValue.class);
final BinaryValue mockBin7 = createMock(BinaryValue.class);
// expectations on our mocks
mockBin1.close();
expectLastCall().times(1);
mockBin2.close();
expectLastCall().times(1);
mockBin3.close();
expectLastCall().times(1);
mockBin4.close();
expectLastCall().times(1);
mockBin5.close();
expectLastCall().times(1);
mockBin6.close();
expectLastCall().times(1);
mockBin7.close();
expectLastCall().times(1);
mockWatchdog.reset();
expectLastCall().times(3);
// prepare our mocks for our test
replay(mockBin1, mockBin2, mockBin3, mockBin4, mockBin5, mockBin6, mockBin7, mockWatchdog);
/* round 1 */
// use some binary streams
context.registerBinaryValueInstance(mockBin1);
context.registerBinaryValueInstance(mockBin2);
context.registerBinaryValueInstance(mockBin3);
assertEquals(3, countBinaryValueInstances(context));
assertEquals(1, countCleanupTasks(context));
// cleanup those streams
context.runCleanupTasks();
assertEquals(0, countBinaryValueInstances(context));
// reset the context (for reuse(), just as XQueryPool#returnCompiledXQuery(org.exist.source.Source, CompiledXQuery) would do)
context.reset();
assertEquals(0, countCleanupTasks(context));
/* round 2, let's reuse the context... */
// use some more binary streams
context.registerBinaryValueInstance(mockBin4);
context.registerBinaryValueInstance(mockBin5);
assertEquals(2, countBinaryValueInstances(context));
assertEquals(1, countCleanupTasks(context));
// cleanup those streams
context.runCleanupTasks();
assertEquals(0, countBinaryValueInstances(context));
// reset the context (for reuse(), just as XQueryPool#returnCompiledXQuery(org.exist.source.Source, CompiledXQuery) would do)
context.reset();
assertEquals(0, countCleanupTasks(context));
/* round 3, let's reuse the context a second time... */
// again, use some more binary streams
context.registerBinaryValueInstance(mockBin6);
context.registerBinaryValueInstance(mockBin7);
assertEquals(2, countBinaryValueInstances(context));
assertEquals(1, countCleanupTasks(context));
// cleanup those streams
context.runCleanupTasks();
assertEquals(0, countBinaryValueInstances(context));
// reset the context (for reuse(), just as XQueryPool#returnCompiledXQuery(org.exist.source.Source, CompiledXQuery) would do)
context.reset();
assertEquals(0, countCleanupTasks(context));
// verify the expectations of our mocks
verify(mockBin1, mockBin2, mockBin3, mockBin4, mockBin5, mockBin6, mockBin7, mockWatchdog);
}
use of org.exist.xquery.value.BinaryValue in project exist by eXist-db.
the class GetHeightFunction method eval.
/**
* evaluate the call to the xquery get-height() function,
* it is really the main entry point of this class
*
* @param args arguments from the get-height() function call
* @param contextSequence the Context Sequence to operate on (not used here internally!)
* @return A sequence representing the result of the get-height() function call
*
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// was an image speficifed
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
// get the image
Image image = null;
BinaryValue imageData = (BinaryValue) args[0].itemAt(0);
try (InputStream inputStream = imageData.getInputStream()) {
image = ImageIO.read(inputStream);
} catch (IOException ioe) {
logger.error("Unable to read image data!", ioe);
return Sequence.EMPTY_SEQUENCE;
}
if (image == null) {
logger.error("Unable to read image data!");
return Sequence.EMPTY_SEQUENCE;
}
// Get the Height of the image
int iHeight = image.getHeight(null);
// did we get the Height of the image?
if (iHeight == -1) {
// no, log the error
logger.error("Unable to read image data!");
return Sequence.EMPTY_SEQUENCE;
} else {
// return the Height of the image
return new IntegerValue(iHeight);
}
}
use of org.exist.xquery.value.BinaryValue in project exist by eXist-db.
the class GetWidthFunction method eval.
/**
* evaluate the call to the xquery get-width() function,
* it is really the main entry point of this class
*
* @param args arguments from the get-width() function call
* @param contextSequence the Context Sequence to operate on (not used here internally!)
* @return A sequence representing the result of the get-width() function call
*
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// was an image speficifed
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
// get the image
Image image = null;
BinaryValue imageData = (BinaryValue) args[0].itemAt(0);
try (InputStream inputStream = imageData.getInputStream()) {
image = ImageIO.read(inputStream);
} catch (IOException ioe) {
logger.error("Unable to read image data!", ioe);
return Sequence.EMPTY_SEQUENCE;
}
if (image == null) {
logger.error("Unable to read image data!");
return Sequence.EMPTY_SEQUENCE;
}
// Get the width of the image
int iWidth = image.getWidth(null);
// did we get the width of the image?
if (iWidth == -1) {
// no, log the error
logger.error("Unable to read image data!");
return Sequence.EMPTY_SEQUENCE;
} else {
// return the width of the image
return new IntegerValue(iWidth);
}
}
use of org.exist.xquery.value.BinaryValue in project exist by eXist-db.
the class LocalXPathQueryService method execute.
private ResourceSet execute(final DBBroker broker, final Txn transaction, XmldbURI[] docs, final Sequence contextSet, final CompiledExpression expression, final String sortExpr) throws XMLDBException {
final long start = System.currentTimeMillis();
final CompiledXQuery expr = (CompiledXQuery) expression;
Sequence result = null;
final XQueryContext context = expr.getContext();
try {
context.setStaticallyKnownDocuments(docs);
if (lockedDocuments != null) {
context.setProtectedDocs(lockedDocuments);
}
setupContext(null, context);
final XQuery xquery = brokerPool.getXQueryService();
result = xquery.execute(broker, expr, contextSet, properties);
} catch (final Exception e) {
// need to catch all runtime exceptions here to be able to release locked documents
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage(), e);
} finally {
/*
* Run the cleanup tasks, but don't close BinaryValues which
* are in the result set as the user has not yet accessed them.
*
* Final cleanup of those BinaryValues is done by the user
* calling EXistResource#close(), ResourceSet#clear() or CompiledExpression#reset().
*/
final Sequence resSeq = result;
context.runCleanupTasks(o -> {
if (resSeq != null && o instanceof BinaryValue) {
for (int i = 0; i < resSeq.getItemCount(); i++) {
if (resSeq.itemAt(i) == o) {
return false;
}
}
}
return true;
});
}
LOG.debug("query took {} ms.", System.currentTimeMillis() - start);
if (result != null) {
final Properties resourceSetProperties = new Properties(properties);
resourceSetProperties.setProperty(EXistOutputKeys.XDM_SERIALIZATION, "yes");
return new LocalResourceSet(user, brokerPool, collection, resourceSetProperties, result, sortExpr);
} else {
return null;
}
}
Aggregations