Introducing 

Prezi AI.

Your new presentation assistant.

Refine, enhance, and tailor your content, source relevant images, and edit visuals quicker than ever before.

Loading…
Transcript

XQJ

XQuery API for Java

Java Standard

Create XQuery

Submit to an

XQuery Engine

Process the results

module namespace e = "http://www.example.com";

declare function e:contains-any-of

($arg as xs:string?,

$searchStrings as xs:string*) as xs:boolean

{ ... code ... };

declare function e:word-count($arg as xs:string?) as xs:integer

{ ... code ... };

declare function e:multiply($a as xs:float, $b as xs:float) as xs:float

{ $a * $b };

public interface Example

{

public boolean containsAnyOf(String arg, String... searchStrings);

public int wordCount(String arg);

public float multiply(float a, float b);

}

public boolean containsAnyOf(String arg, String[] searchStrings);

public boolean containsAnyOf(String arg, List<String> searchStrings);

public boolean containsAnyOf(String arg, Iterator<String> searchStrings);

Overriding default behavior

with Annotations

public interface MyXMLStore

{

@XQFunctionName("insert-xml-content")

public void insertXMLContent(String uri, Source xmlSource);

}

public interface MyXMLStore

{

@XQFunctionName("insert-xml-content")

public void insertXMLContent(String uri,

@XQCastAs("document-node(element())") String value);

}

Plain Old Java Objects Mapping

XQJ Spec never defined how POJOs should be mapped to XDM types

PersonStore personStore = conn.createModuleProxy(

"http://person-store.com",

"/modules/person-store.xqy",

PersonStore.class);

Person john = new Person();

john.firstName = "John";

john.lastName = "Smith";

john.dateOfBirth =

DatatypeFactoryImpl.newXMLGregorianCalendar("1970-04-12");

john.phoneNumbers = new PhoneNumbers(

new String[] { "123-789", "789-123" }

);

personStore.insertPerson("/john-smith.xml", john);

john = null; // John is gone!

john = personStore.getPerson("/john-smith.xml"); // Welcome back John!

(:~ FunctX XQuery Function Library. Copyright (C) 2007 Datypic. :)

module namespace functx = "http://www.functx.com" ;

declare default function namespace "http://www.w3.org/2005/xpath-functions";

declare function functx:add-attributes(

$elements as element()*,

$attrNames as xs:QName*,

$attrValues as xs:anyAtomicType*) as element()?

{

... code ...

};

declare function functx:add-months(

$date as xs:date?,

$months as xs:integer) as xs:date?

{

... code ...

};

declare function functx:add-or-update-attributes(

$elements as element()*,

$attrNames as xs:QName*,

$attrValues as xs:anyAtomicType*) as element()?

{

... code ...

};

// Generated from functx-module.xqy

import javax.xml.xquery.XQException;

import javax.xml.namespace.QName;

import org.w3c.dom.Element;

import javax.xml.datatype.XMLGregorianCalendar;

public interface FunctxModule

{

public Element addAttributes(

Element[] elements,

QName[] attrNames,

String[] attrValues) throws XQException;

public XMLGregorianCalendar addMonths(

XMLGregorianCalendar date,

int months) throws XQException;

public Element addOrUpdateAttributes(

Element[] elements,

QName[] attrNames,

String[] attrValues) throws XQException;

}

CustomerDAO.java

import javax.xml.xquery.XQException;

public interface CustomerDAO

{

public void insertCustomer(Customer pojo) throws XQException;

public void deleteCustomer(Customer pojo) throws XQException;

public Customer findCustomer(String uri) throws XQException;

public void updateCustomer(Customer pojo) throws XQException;

public Iterator<Customer> getAllCustomers() throws XQException;

}

class Customer {

String uri;

String collection;

/** other details **/

}

customer-dao.xqy

(: Generated from CustomerDAO.java :)

module namespace c = "http://example.org";

declare function c:insert-customer($pojo as node()) as empty-sequence()

{

()

};

declare function c:delete-customer($pojo as node()) as empty-sequence()

{

()

};

declare function c:find-customer($uri as xs:string) as node()

{

<?stub?>

};

declare function c:update-customer($pojo as node()) as empty-sequence()

{

()

};

declare function c:get-all-customers() as node()*

{

<?stub?>

};

Thank you!

Questions?

Charles Foster

xquery2java

functx-module.xqy

FunctxModule.java

Code Generation

charles@xqj.net

@fostercharles

java2xquery

JCP 225

Supported by:

DataDirect Technologies

X-Hive (now EMC XDB)

Software AG

IPEDO

Oracle

IBM

BEA Systems

Sun

Sybase

XQuery aware

No XML Parsing

SQL/Relational Database

Stored Procedures

  • Reduce compilation overhead
  • Reduce network traffic
  • Embed business logic in DB
  • Invokable from JDBC 2.0 onwards

XQuery/XML Database

XQuery Modules (Main and Library)

  • Reduce compilation overhead
  • Reduce network traffic
  • Embed business logic in DB
  • No support in XQJ 1.0!

Desiging an API to invoke

stored XQuery code

New Approach to invoke

XQuery code from Java

  • XML is a second class citizen in Java.
  • Java APIs for XML have been inelegant.
  • Invoke XQuery functions as if they were regular Java methods.
  • Introducing an RPC/Service like model to Java's approach to XQuery.
  • Extensions to the XQJ interfaces.

(Off-the-wall - definitely an option).

Key Thought

Initial Implementations

Java methods bare similarity with XQuery functions.

MarkLogic, eXist and Sedna

Client code

Final Notes

Relational Database

POJO

Implementation-defined

class Person

{

String firstName;

String lastName;

XMLGregorianCalendar dateOfBirth;

PhoneNumbers phoneNumbers;

}

class PhoneNumbers

{

public PhoneNumbers(String[] number) {

this.number = number;

}

String[] number;

}

This doesn't have to be Java

This concept could be

applied else where,

e.g. XSLT functions.

Example example =

XQConnection2.createModuleProxy(

"http://www.example.com",

"/modules/example.xqy",

Example.class

);

boolean contains =

example.containsAnyOf("abc", "bc", "xy");

int totalWords =

example.wordCount("The quick brown fox jumps over the lazy dog");

float product =

example.multiply(3f, 4f);

XML Document in a

XML Database

POJO

<person>

<first-name>John</first-name>

<last-name>Smith</last-name>

<date-of-birth>1970-04-12</date-of-birth>

<phone-numbers>

<number>123-789</number>

<number>789-123</number>

</phone-numbers>

</person>

XQuery Library Module

What's the difference?

Java to XQuery name

translation.

(Default Behaviour)

public interface PersonStore

{

public Person getPerson(

String uri);

public void insertPerson(

String uri,

Person person);

}

Java method

XQuery function

insertXmlContent

insert-xml-content

declare function do-work(

$a as xs:int,

$b as xs:double,

$c as xs:string,

$d as document-node()

) as xs:string*

insertXMLContent

insert-x-m-l-content

public String[] doWork(

int a,

double b,

String c,

Document d

);

module namespace ps="http://person-store.com";

declare function ps:get-person(

$uri as xs:string) as element(person)?

{

fn:doc($uri)/element()

};

declare function ps:insert-person(

$uri as xs:string,

$person as element(person))

{

xdmp:document-insert($uri, $person)

};

Java Facade

  • Java Interfaces as Facades for XQuery Library Modules.
  • Java values are mapped to XDM values according to the XQJ Specification.

Building Bridges from Java to XQuery

A new approach to invoke XQuery functions from Java as if they were Java methods.

Learn more about creating dynamic, engaging presentations with Prezi