CS639 Hypermedia Order Links, advanced JAXB

The Hypermedia service of Chap 5 has a DAP, a domain application protocol

The following XML is returned by “ant restAdd” in orderDap, and put in file order-response.xml. The order id here is f0001d50-e244-4068-84f6-73b800244964, not 1234.The constant strings are in lowercase here, because of additional markup in the enum classes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <ns2:order xmlns="http://schemas.restbucks.com/dap"
                   xmlns:ns2="http://schemas.restbucks.com">

  <link mediaType="application/vnd.restbucks+xml"
        uri=http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964
        rel="http://relations.restbucks.com/cancel"/>

         <link mediaType="application/vnd.restbucks+xml"

uri="http://localhost:8080/orderDap/rest/payment/f0001d50-e244-4068-84f6-73b800244964"

rel="http://relations.restbucks.com/payment"/>

         <link mediaType="application/vnd.restbucks+xml"

uri=http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964

rel="http://relations.restbucks.com/update"/>

  <link mediaType="application/vnd.restbucks+xml"

uri="http://localhost:8080/orderDap/rest/order/f0001d50-e244-4068-84f6-73b800244964"

rel="self"/>

         <ns2:item>

              <ns2:milk>semi</ns2:milk>

              <ns2:size>large</ns2:size>

              <ns2:drink>cappuccino</ns2:drink>

         </ns2:item><ns2:location>takeaway</ns2:location>

         <ns2:cost>2.0</ns2:cost>

         <ns2:status>unpaid</ns2:status>

</ns2:order>

 

Pg. 116 has similar XML, but better prefixes.

 

Pg. 118 has Payment  response with only two links: for another order or for a receipt. The next normal step has to be done by the barista, so the customer doesn’t have much to do at this point.

 

JAXB for XML Attributes, multiple Namespaces

orderDap uses JAXB to generate multi-NS XML, with attributes...

 

JAXB POJO Link has fields rel, uri, mediaType, turned into XML attributes as follows:

 

@XmlRootElement(namespace = Representation.DAP_NAMESPACE)

// Added over paper handout: last-minute edit to make a nice schema

// make sure the schema type is in the same namespace as the element itself

@XmlType(name="link", namespace = Representation.DAP_NAMESPACE, propOrder = {"rel", "uri", "mediaType"})

public class Link {

    @XmlAttribute(name = "rel")

    private String rel;

    @XmlAttribute(name = "uri")

    private String uri;

    @XmlAttribute(name = "mediaType")

    private String mediaType;

...

Link doesn’t really need @XMLRootElement, since it’s never used at top level.

 

Representation.java, an abstract class, extended by OrderRepresentation (4 links), PaymentRepresentation(2 links), and ReceiptRepresentation (1 link), provides hypermedia links setup:

 

public abstract class Representation {

    public static final String RELATIONS_URI = "http://relations.restbucks.com/";

    public static final String RESTBUCKS_NAMESPACE = "http://schemas.restbucks.com";

    public static final String DAP_NAMESPACE = RESTBUCKS_NAMESPACE + "/dap";

    public static final String RESTBUCKS_MEDIA_TYPE = "application/vnd.restbucks+xml";

    public static final String SELF_REL_VALUE = "self";

 

    @XmlElement(name = "link", namespace = DAP_NAMESPACE)        <--DAP NS for <link>s

    protected List<Link> links;                     <--each subclass can have its own links in a List

 

    protected Link getLinkByName(String uriName) {

        if (links == null) {

            return null;

        }

 

        for (Link l : links) {

            if (l.getRelValue().toLowerCase().equals(uriName.toLowerCase())) {

                return l;

            }

        }

        return null;

    }

}

 

OrderRepresentation.java:  in old namespace, but gets List<Link> from superclass, using DAP NS.

 

To simplify annotations, packages representations and domain both have package-info.java setting up the non-DAP NS as default, so we only have to override it for the DAP NS

@XmlRootElement(name = "order")

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "orderRepresentation", propOrder = {

           "items",

           "location",

           "cost",

           "status"

       })

public class OrderRepresentation extends Representation {

 

    @XmlElement(name = "item", required = true)

    private List<Item> items;

    @XmlElement(required = true)

    private Location location;

    private double cost;

    private OrderStatus status;

 

       ...   

public Link getCancelLink() {

        return getLinkByName(RELATIONS_URI + "cancel");

  }

...

Similarly, PaymentRepresentaion and ReceiptRepresentation

 

Note: cost has type double, not best for dollars and cents. orderService uses BigDecimal, a better choice.