acessing java class methods from query

Help
bob munger
2004-10-22
2012-10-08
  • bob munger

    bob munger - 2004-10-22

    i want to access java class members from my xquery. i've managed to access class methods through static wrappers but i would like to access the class methods directly. here is my test:

    package com.idx.carecast.ca.ws.test;

    import java.io.ByteArrayOutputStream;
    import java.io.Reader;
    import java.io.StringReader;
    import java.util.Properties;

    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.stream.StreamResult;

    import junit.framework.TestCase;
    import net.sf.saxon.Configuration;
    import net.sf.saxon.query.DynamicQueryContext;
    import net.sf.saxon.query.StaticQueryContext;
    import net.sf.saxon.query.XQueryExpression;

    public class WishfullTest extends TestCase {
    private static MsgHdrTO msgHdrDS;
    private static LogonDsTO logonDS;
    private static boolean connected = false;
    protected void setUp() throws Exception {
    super.setUp();
    }
    protected void tearDown() throws Exception {
    super.tearDown();
    }
    public void test() {
    try {
    // build context
    Configuration cfg = new Configuration();
    cfg.setHostLanguage(Configuration.XQUERY);
    StaticQueryContext sqc = new StaticQueryContext(cfg);
    DynamicQueryContext dqc = new DynamicQueryContext(cfg);
    // build query
    String q = "declare namespace wft='java:com.idx.carecast.ca.ws.test.WishfullTest'"
    + "; declare variable $timeto external"
    + "; element TOTest1 { $timeto }"
    + ", element TOTest2 { wft:getField($timeto, 'time') } "
    + ", wft:setField($timeto, 'time', '0') "
    + ", element TOTest3 { wft:getField($timeto, 'time') } ";
    Reader qr = new StringReader(q);
    XQueryExpression xqx = sqc.compileQuery(qr);
    // configure engine
    dqc.setParameter("timeto", new TestClass());
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Properties props = new Properties();
    props.setProperty(OutputKeys.INDENT, "yes");
    props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    xqx.run(dqc, new StreamResult(baos), props);
    System.out.println(baos.toString());
    }
    catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
    }
    }
    public class TestClass {
    String time;
    public TestClass() {
    time = Long.toString(System.currentTimeMillis());
    }
    public String toString() {
    return time;
    }
    public String getField(
    String name) {
    if (name.equalsIgnoreCase("time")) {
    return time;
    }
    return null;
    }
    public void setField(
    String name,
    String value) {
    if (name.equalsIgnoreCase("time")) {
    time = value;
    }
    }
    }
    public static String getField(
    TestClass tc,
    String name) {
    return tc.getField(name);
    }
    public static void setField(
    TestClass tc,
    String name,
    String value) {
    tc.setField(name, value);
    }
    }

    can i access the class methods directly?

    thanks, bob

     
    • Michael Kay

      Michael Kay - 2004-10-22

      I think this should be possible, though I've never tested calling a method on an inner class: I would try it with a "normal" class first.

      The namespace URI should contain the name of the class whose method you are invoking, which is TestClass not WishfullTest.

      Use the -TJ option for diagnostics if you hit problems.

      Michael Kay

       
    • bob munger

      bob munger - 2004-10-22

      thanks. i accidentally stumbled onto the correct syntax for calling class methods when i added an extra arg to my static method. i'm still learning to navigate around the available info. being primed for enlightment i finally read

      file://localhost/J:/Saxon/doc/documentation/extensibility/functions.html

      and it all became clear.

      as you suggested i moved my test transfer object into a seperate object. my query test now looks like this:

              String q = "declare namespace wft='java:com.idx.carecast.ca.ws.test.WishfullTest';\n"
                  + "declare namespace tto='java:com.idx.carecast.ca.ws.test.TestTO';\n"
                  + "declare variable $timeto external;\n"
                  + "element TOTest1 { $timeto },\n"
                  + "element TOTest2 { wft:getField($timeto, 'time') },\n"
                  + "wft:setField($timeto, 'time', '0'),\n"
                  + "element TOTest3 { wft:getField($timeto, 'time') },\n"
                  + "element TOTest4 { tto:getField($timeto, 'time') },\n"
                  + "tto:setField($timeto, 'time', '123456789'),\n"
                  + "element TOTest3 { tto:getField($timeto, 'time') } ";
      

      and i now can access both the static and class methods.

       

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks