Hi Christian,
On 16/04/2015 19:17, Christian Grün wrote:
Hi Karel,
I looked at the code and it turns out, that ModuleLoader#addImport is not being called at all, because condition in QueryParser on line 755:
if(mi.paths.isEmpty()) {
returns false.
In this case, you seem to have specified a path in your query via "at", right?..
import module namespace a='uri' at '...........';
Exactly.
From what I saw, I think change should be around line 775:
final IO io = sc.io(string(path));
How do you propose we continue? Do you have more specific idea how to implement it to core?
In meanwhile I was thinking of pushing very simple incomplete test, that would just execute 2 simple xquery files from classpath (where 1 is module being imported from 2nd). Incomplete part would be of course the url resolving mechanism part.
Karel
Right!
Christian
P.S. Sorry for double send, I forgot to reply all first time. On 15/04/2015 14:15, Karel Hovorka wrote:
Thanks for the reply.
I agree. It definitely should be one api both for LocalSession and ClientSession, otherwise it wouldn't be really helpful. I made example like this, because I saw, that both ClientSession and LocalSession accept Concept class as constructor parameter (even though not all ClientSession constructors require it).
I will checkout master and see if I get any ideas about how to integrate it to current codebase.
Karel On 15/04/2015 12:25, Christian Grün wrote:
Hi Karel,
I thought I'll wait for some more time; maybe Johan has a suggestion as well?
To anticipate my first thoughts:
As we want to keep the LocalSession and ClientSession implementations identical in terms of functionality, I believe it will get difficult to bind arbitrary Java code to a URI resolver. It may easier be possible if you work with the QueryProcessor class, but, still, I'm not sure about all the implications.
But it was already helpful to see how you would like to see the feature integrated.
Is there anything else I can do to help?
Thanks for asking. This is the code that's currently called when resolving module imports:
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/ba...
If you have some time left, I invite you to check out our sources, play around with the code and, optionally, send us a little pull request that demonstrates your ideas. The basex-core package works without any dependencies, but just ask if you need help.
Cheers, Christian
On Wed, Apr 15, 2015 at 1:11 PM, Karel Hovorka Karel.Hovorka@semantico.com wrote:
Karel
On 13/04/2015 10:15, Karel Hovorka wrote:
Hello Johan and Christian,
this is the simpliest snippet, that I am using to run xquery (without giving it any input xml):
System.setProperty("org.basex.QUERYPATH",
“/workspace/project/src/main/resources/xquery/");
Context context = new Context(); LocalSession session = new LocalSession(context); session.setOutputStream(System.out); String xq =
IOUtils.toString(getClass().getResourceAsStream("/xquery/test.xq"), StandardCharsets.UTF_8); LocalQuery query = session.query(xq); query.next();
As you can see, I am setting QUERYPATH and looking files on filesystem, where they are in the project, which works fine for development, but cannot work in production, because files will be in jar or war.
I would imagine this snipped to be changed to something like this:
//System.setProperty("org.basex.QUERYPATH",
“/workspace/project/src/main/resources/xquery/");
Context context = new Context(); context.setURIResolver(new DefaultURIResolver() { //Signature same as org.basex.io.IO.get public IO resolve(String resource) { InputStream in = getClass().getResourceAsStream("/xquery/"
resource); if (in != null) { return new IOStream(in, "/xquery/" + resource); } //fallback, default resolver, basically current IO.get return super.resolve(resource); } }); LocalSession session = new LocalSession(context); session.setOutputStream(System.out);
String xq =
IOUtils.toString(getClass().getResourceAsStream("/xquery/test.xq"), StandardCharsets.UTF_8); LocalQuery query = session.query(xq); query.next();
Not sure, if Context class is the best location for setURIResolver method, but makes sense to me, because uriresolver should be part of a context (not referencing class).
Hope it helps,
Karel
On 11/04/2015 08:40, Christian Grün wrote:
Hi Karel, hi Johan,
I can see that there is some demand for such an extension. However, I still know too less about it in order to make it work the right way. Could you please both give me a little code example how you would like to see the feature embedded in the BaseX APIs you are using?
Thanks in advance, Christian
On Sat, Apr 11, 2015 at 1:56 AM, Johan Mörén johan.moren@gmail.com wrote:
Support for this would be really great if it does not exist yet. I'm running a lot of queries in embeded mode and would like to extract some functions to modules that multiple queries can share to reduce code duplication.
Making it possible to give the query processor a customizable URIResolver would be great since we package our resources in .jar files on deployment.
Regards, Johan Mörén
On Thu, Apr 9, 2015 at 6:13 PM, Karel Hovorka Karel.Hovorka@semantico.com wrote:
We always use custom URIResolver when working with classpath resources afaik.
Similar mechanism might be better than original feature for reasons you stated (duplicity in classpath). You can solve this by choosing correct classloader in *URIResolver.
I've been digging a little into BaseX source and I've found org.basex.io. IO.get method, which does similar thing (loading resource based on string). If this factory method replaces by a customizable factory with default implementation, that might solve the problem. However I know very little about BaseX, and I may be completely wrong here.
Karel
On 09/04/2015 16:47, Christian Grün wrote:
Thanks for the links. If I get it right, you need to explicitly call the URI resolver setter functions to get it working? Or does it mean that modules will automatically be available via "import module" if they are in the Java classpath (which is, if I got it right, the feature you asked for)?
On Thu, Apr 9, 2015 at 5:02 PM, Karel Hovorka Karel.Hovorka@semantico.com wrote:
Exactly, I am refering to "import module". In my experience with xml-related technologies and java, library usually supports customizable class for import resource lookup based on namespaces, paths etc, I can recall 2 examples:
Saxon has class ModuleURIResolver that does just this:
http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XQuery...
Similar class URIResolver and mechanism is in java core for xsl:import/xsl:include lookup:
http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/TransformerFact...
Thanks, Karel
On 09/04/2015 15:41, Christian Grün wrote:
I would like to load xquery files that are on classpath of my java application, not only filesystem. Does this mean, it is not possible with BaseX?
Do you refer to the "import module" when talking about loading xquery files?
The classpath is not considered when importing modules. As multiple directories can be specified in the classpath, it could even happen that different modules would be import candidates, so we'd need additional precedence rules. -- Is this possibly supported by any other query processor you have tried?
Best, Christian
Karel
On 08/04/2015 18:01, Christian Grün wrote:
Hi Karel,
In BaseX, modules either need to be located in the module repository, or the relative path needs to be specified in the import module statement. Some more information on locating modules can be found in our Wiki [1].
Hope this helps, Christian
[1] http://docs.basex.org/wiki/Repository
On Wed, Apr 8, 2015 at 5:56 PM, Karel Hovorka Karel.Hovorka@semantico.com wrote:
Hi,
I am trying to run xquery file on basex, but it depends on xquery module located in classpath. I have found parameter "org.basex.QUERYPATH", that configures module lookup on filesystem. Is there way to lookup modules in classpath?
Thanks,
Karel Hovorka, Semantico LTD