Page 1 of 1

call java Base64.Encoder.encodeToString

Posted: Mon May 25, 2015 10:25 pm
by Doug
I'm trying to call the java.util.Base64.Encoder.encodeToString method in an xquery transformation. I'm using Oxygen 17.0 Editor which uses java 1.8 which includes the Base64 class and its nested Encoder class. I'm using SaxonEE 9.6.0.5 in my transformation configuration with "Allow calls to extended functions" enabled. When I attempt to validate the xquery I get:

Engine name: Saxon-EE XQuery 9.6.0.5
Severity: fatal
Description: XPST0017: Cannot find a matching 1-argument function named {java:java.util.Base64.Encoder}encodeToString().

Perhaps there is something about how I have to declare a nested class that I'm doing wrong? My java.lang.String methods all work fine.

My relevant code is:

xquery version "3.0";

declare namespace db="http://docbook.org/ns/docbook";
declare namespace string="java:java.lang.String";
declare namespace encoder="java:java.util.Base64.Encoder";

declare variable $currentFile external;

let $doc := doc($currentFile)
let $bibs := $doc//db:bibliomixed[@xml:id]
for $bib at $pos in $bibs
return
<xml>
{encoder:encodeToString(string:getBytes(string:new(replace(concat(($bib//db:author//db:surname)[1],($bib//db:author//db:firstname)[1], ($bib//db:pubdate)[1],($bib//db:title)[1] ),'[^a-zA-Z0-9]+', ''))))}
</xml>


Thanks,
Doug

Re: call java Base64.Encoder.encodeToString

Posted: Tue May 26, 2015 8:20 am
by Radu
Hi Doug,

There is no Base64 Java class in the java.util package:

http://docs.oracle.com/javase/7/docs/ap ... frame.html

There is a Base64Encoder class in the sun.misc package which you could use:

http://stackoverflow.com/questions/2267 ... tting-byte

There might be also pure XQuery solutions which encode base 64:

https://github.com/abarax/xquery-utilit ... -decode.xq

Regards,
Radu

Re: call java Base64.Encoder.encodeToString

Posted: Tue May 26, 2015 6:19 pm
by Doug
Thanks Radu. I like the pure xquery solution. I'd rather not have the java dependency, at least not this one, because of issues like these. I've made the xf functions work, though I had to go through some data conversion loops and hoops for parameter data type matching. Turns out, I don't like the results anyway. And maybe I don't need to do any encoding anyways. I was aiming at creating an id system from strings in bibliographic entries that would be better for indexing but that could be decoded, unlike a hash, for the sake of human consumption. I'm using the Docbook transformations that come with Oxygen to grab bibliographic entries from a master bibliography. For now I think I'll just go with a slightly compressed human consumable string. Perhaps you or someone has better ideas to get to my original goal that can be shared?

I assume the results would be the same between the xquery and the java Base64 options, so the problem calling the java class method is irrelevant right now, but I think the Base64 class is in util in java 1.8, at least in the jdk: https://docs.oracle.com/javase/8/docs/a ... ase64.html, and I can see the class in the source code in my installation which is my default java installation. Apparently the class is new with Java 8. However, when I rename the jre under Oxygen to force the use of my default java installation (per your instructions in your reply to my other question about the loss of the jdbc:odbc bridge between Oxygen 16 and 17, Oxygen still can't find the encodeToString method.

Re: call java Base64.Encoder.encodeToString

Posted: Wed May 27, 2015 8:58 am
by Radu
Hi Doug,

Indeed in the Java 1.8 runtime libraries there is a java.util.Base64, I was testing with Java 1.7.
The reason this construct encoder:encodeToString does not work is that the method encodeToString is not static.
You would need to call in the XQuery code the equivalent of:

Code: Select all


java.util.Base64.getEncoder().encodeToString(.....)
About this remark:
For now I think I'll just go with a slightly compressed human consumable string.
You could probably create a custom XQuery function which takes the original string, replaces spaces with underlines, maybe converts everything to lower case, removes any stop words like is and the and trims the result to be about 10-20 characters. Maybe it also appends a small hash of the entire text at the end of the result just to make it unique.

Regards,
Radu