CS639 Practice Final Exam                       

 

Open books, handouts, solutions, etc.

Show all work on these pages, using backs of pages if needed.  Total points = 150. Note that OrderService.xsd, Link.xsd, and OrderRepresentaton.java are included at the end of the exam.

 

1. Designing XML and Web Services

Cats and dogs have identification collars (or even embedded chips) that give them a unique String id.  Suppose you want to set up a registry of these ids so that lost pets can be returned to their owners.  You decide to keep, for each registered pet, its unique id, its name (string), its owner’s name (one string, for simplicity), and contact information for the owner consisting of one or more email addresses (strings).  You want to provide web services to register a pet, change contact information, and find information on a pet registration given the unique id.  Note that in this case the server does not assign the unique id, but just uses it.

 

  1. Show sample XML to be sent to register a pet:

 

 

 

 

 

 

 

 

 

 

 

 

b.      Give a table summarizing the service contract overview, like Table 4-1 on pg. 57 of “REST in Practice”. It should have 3 rows, for register pet, change info, and find information on pet, and 3 columns, for Verb, URI or template, and Use.

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 2. Suppose you are enhancing the system of pa3 to add a (single) password for access to the “poke” action. Since we haven’t studied proper authorization protocols (described in Chap. 9 of the REST book), you have to supply this password in the body of an appropriate message to do the job.  Assume a single permanent password in use at the site, stored in a file, read at startup, and held in a private static variable in OrderRepository.

  1. Which messages are modified, and how (make a proposal)?

 

  1. What code (method and class) of the pa4 project code (as opposed to the JAX-RS framework) first handles this request?  Note that this code calls into the business layer.  How do you need to change this code?  There are several ways to do it, and some ways require a new domain class. If your way does, note that fact.

 

 

 

 

 

  1. What changes do you propose in the business layer code?

 

 

 

 

 

  1. Do you need a new method in OrderRepository?  If so, specify its signature (no implementation.)  If not, what changes at this layer do you propose?

 

 

 


 

 

 3. Namespaces and XML Schemas

Here is an XML file from a SOAP web services setup (but you don’t need to know SOAP web services for this problem, just XML Schemas):

 

<deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/"

            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <service name="MessageService" provider="java:MSG" use="literal">

    <parameter name="className" value="samples.message.MessageService" />

    <parameter name="allowedMethods" value="echoElements" />

  </service>

  <service name="MessageService2"  provider="java:MSG" use="literal">

    <parameter name="className" value="samples.message.MessageService" />

    <parameter name="allowedMethods" value="process" />

  </service>

</deployment>

 

  1. “MSG” is a local name in what namespace?  (Give its URI)

 

 

  1. service” is a local name in what namespace? (Give its URI)

 

 

 

  1. Write a XML Schema that describes the names in the default namespace of this file, treating everything in double quotes as a string. You can ignore the attributes of <service> but include the description of the attributes of <parameter>. Hint: look at Link.xsd’s treatment of attributes. Here’s a start:

<?xml version="1.0"?>

<xs:schema elementFormDefault="qualified" version="1.0"

xmlns:xs="http://www.w3.org/2001/XMLSchema">

targetNamespace="                         "

xmlns:tns="                           " >

 

 

 

 

 

 


 

(30) 4.  XML Data Binding using JAXB. The schema for element type order is shown in the attached schema. The corresponding OrderRepresentation object, with other objects associated with it, is used heavily in orderService. Its source code is attached at the end of the exam.

 

Given the XML:

 

<?xml version="1.0" encoding="UTF-8"?>

<order xmlns="http://schemas.restbucks.com">

      <id>41</id>

      <item>

            <milk>SEMI</milk>

            <size>LARGE</size>

            <drink>CAPPUCCINO</drink>

      </item>

      <location>TAKEAWAY</location>

      <cost>2</cost>

      <status>UNPAID</status>

</order>

 

a.       Draw a picture of the corresponding POJO object graph, that is, one OrderRepresentation object and other objects (including enum objects) hanging off of it.  Use an oval for each Java object involved, and show ref linkages by arrows.  Indicate class names on each Java object, including objects such as List or Set (objects of some concrete classes for these are in actual use, of course) from the JDK.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

b.      Note that OrderRepresentation has no getter for the List of Items. Explain how the server code gets access to this important data. Specifically, given an instance of OrderRepresentation orderRep, show code that counts the number of items.

 

 

 

 

 


 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://schemas.restbucks.com" xmlns:tns="http://schemas.restbucks.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

  <xs:element name="item" type="tns:item"/>

 

  <xs:element name="order" type="tns:orderRepresentation"/>

 

  <xs:complexType name="orderRepresentation">

    <xs:sequence>

      <xs:element name="id" type="xs:string" minOccurs="0"/>

      <xs:element ref="tns:item" maxOccurs="unbounded"/>

      <xs:element name="location" type="tns:location"/>

      <xs:element name="cost" type="xs:decimal" minOccurs="0"/>

      <xs:element name="status" type="tns:orderStatus" minOccurs="0"/>

    </xs:sequence>

  </xs:complexType>

 

  <xs:complexType name="item">

    <xs:sequence>

      <xs:element name="milk" type="tns:milk"/>

      <xs:element name="size" type="tns:size"/>

      <xs:element name="drink" type="tns:drink"/>

    </xs:sequence>

  </xs:complexType>

 

  <xs:simpleType name="milk">

    <xs:restriction base="xs:string">

      <xs:enumeration value="NONE"/>

      <xs:enumeration value="SKIM"/>

      <xs:enumeration value="SEMI"/>

      <xs:enumeration value="WHOLE"/>

    </xs:restriction>

  </xs:simpleType>

 

  <xs:simpleType name="size">

    <xs:restriction base="xs:string">

      <xs:enumeration value="LARGE"/>

      <xs:enumeration value="SMALL"/>

      <xs:enumeration value="MEDIUM"/>

    </xs:restriction>

  </xs:simpleType>

 

  <xs:simpleType name="drink">

    <xs:restriction base="xs:string">

      <xs:enumeration value="FLAT_WHITE"/>

      <xs:enumeration value="LATTE"/>

      <xs:enumeration value="CAPPUCCINO"/>

      <xs:enumeration value="ESPRESSO"/>

    </xs:restriction>

  </xs:simpleType>

 

  <xs:simpleType name="location">

    <xs:restriction base="xs:string">

      <xs:enumeration value="IN_STORE"/>

      <xs:enumeration value="TAKEAWAY"/>

    </xs:restriction>

  </xs:simpleType>

 

  <xs:simpleType name="orderStatus">

    <xs:restriction base="xs:string">

      <xs:enumeration value="PREPARING"/>

      <xs:enumeration value="READY"/>

    </xs:restriction>

  </xs:simpleType>

</xs:schema>

---------------------------------------------------------------------------------

<?xml version="1.0" standalone="yes"?>

<xs:schema version="1.0" targetNamespace="http://schemas.restbucks.com/dap" xmlns:tns="http://schemas.restbucks.com/dap" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 

  <xs:element name="link" type="tns:link"/>

 

  <xs:complexType name="link">

    <xs:sequence/>

    <xs:attribute name="rel" type="xs:string"/>

    <xs:attribute name="uri" type="xs:string"/>

    <xs:attribute name="mediaType" type="xs:string"/>

  </xs:complexType>

</xs:schema>

 

---------------------------------------------------------------------------------

package com.restbucks.ordering.representations;

 

import java.io.ByteArrayInputStream;

import java.io.StringWriter;

import java.math.BigDecimal;

import java.util.List;

 

import javax.xml.bind.JAXBContext;

import javax.xml.bind.Marshaller;

import javax.xml.bind.Unmarshaller;

import javax.xml.bind.annotation.XmlAccessType;

import javax.xml.bind.annotation.XmlAccessorType;

import javax.xml.bind.annotation.XmlElement;

import javax.xml.bind.annotation.XmlRootElement;

import javax.xml.bind.annotation.XmlType;

 

import com.restbucks.ordering.activities.InvalidOrderException;

import com.restbucks.ordering.domain.Item;

import com.restbucks.ordering.domain.Location;

import com.restbucks.ordering.domain.Order;

import com.restbucks.ordering.domain.OrderStatus;

 

// This annotation is needed, to define the root element's name and namespace

// not otherwise specified here

@XmlRootElement(name = "order", namespace = Representation.RESTBUCKS_NAMESPACE)

// Make sure the schema type is in the same namespace

@XmlType(name = "orderRepresentation", namespace = Representation.RESTBUCKS_NAMESPACE)

// Better in general for us: default of .PUBLIC_MEMBER requires a public getter/setter *pair*

// to ensure inclusion of that property in the XML without an @XmlElement.

// Here cost has a getter but no setter, for example

@XmlAccessorType(XmlAccessType.FIELD)

public class OrderRepresentation {

       @XmlElement(name = "id", namespace = Representation.RESTBUCKS_NAMESPACE)  

       private String id;

    public String getId() {

              return id;

       }

    // we want to override the default here with required = true, but we could let the namespace

    // be defaulted to parent's NS

       @XmlElement(name = "item", required = true, namespace = Representation.RESTBUCKS_NAMESPACE)

    private List<Item> items;

    @XmlElement(name = "location", required = true, namespace = Representation.RESTBUCKS_NAMESPACE)

    private Location location;

 

    @XmlElement(name = "cost", namespace = Representation.RESTBUCKS_NAMESPACE)

    private BigDecimal cost;

  

       @XmlElement(name = "status", namespace = Representation.RESTBUCKS_NAMESPACE)

    private OrderStatus status;

 

    /**

     * For JAXB :-(

     */

    OrderRepresentation() {}

 

// for use with OrderResource's commented-out createOrder version

    public static OrderRepresentation fromXmlString(String xmlRepresentation) {

        try {

            JAXBContext context = JAXBContext.newInstance(OrderRepresentation.class);

            Unmarshaller unmarshaller = context.createUnmarshaller();

            return (OrderRepresentation) unmarshaller.unmarshal(new ByteArrayInputStream(xmlRepresentation.getBytes()));

        } catch (Exception e) {

            throw new InvalidOrderException(e);

        }

    }

 

    public OrderRepresentation(Order order, String id) {

  

        try {

            this.location = order.getLocation();

            this.items = order.getItems();

            this.cost = order.calculateCost();

            this.status = order.getStatus();

            this.id = id;

        } catch (Exception ex) {

            throw new InvalidOrderException(ex);

        }

    }

   

    // for debugging and testing: look at object as XML

    public String toString() {

        try {

            JAXBContext context = JAXBContext.newInstance(OrderRepresentation.class);

            Marshaller marshaller = context.createMarshaller();

 

            StringWriter stringWriter = new StringWriter();

            marshaller.marshal(this, stringWriter);

 

            return stringWriter.toString();

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

    }

   

    // For use only inside server: create an Order from this OrderRepresentation

    // The Order object belongs to the server implementation

    // Luckily, a POJO built from the XML will not have this

    // method.

    public Order getOrder() {

        if (location == null || items == null) {

            throw new InvalidOrderException();

        }

        for (Item i : items) {

            if (i == null) {

                throw new InvalidOrderException();

            }

        }

 

        return new Order(location, status, items);

    }

   

    public OrderStatus getStatus() {

        return status;

    }

 

    public BigDecimal getCost() {

        return cost;

    }

}