Web API and simple mobile app

profilegfabkux
TM352_18J_EMA_P1_skeleton_projectV2.zip

EMAQ1.zip

EMAQ1/build.xml

Builds, tests, and runs the project EMAQ1.

EMAQ1/nbproject/ant-deploy.xml

<!DOCTYPE <!-- <!DOCTYPE <sun-web-app --> <sun-web-app <!DOCTYPE <!-- <!DOCTYPE <glassfish-web-app --> <glassfish-web-app

EMAQ1/nbproject/build-impl.xml

Must set src.dir Must set test.src.dir Must set build.dir Must set build.web.dir Must set build.generated.dir Must set dist.dir Must set build.classes.dir Must set dist.javadoc.dir Must set build.test.classes.dir Must set build.test.results.dir Must set build.classes.excludes Must set dist.war The Java EE server classpath is not correctly set up - server home directory is missing. Either open the project in the IDE and assign the server or setup the server classpath manually. For example like this: ant -Dj2ee.server.home=<app_server_installation_directory> The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}. Either open the project in the IDE and assign the server or setup the server classpath manually. For example like this: ant -Duser.properties.file=<path_to_property_file> (where you put the property "j2ee.platform.classpath" in a .properties file) or ant -Dj2ee.platform.classpath=<server_classpath> (where no properties file is used) Must set javac.includes No tests executed. The libs.CopyLibs.classpath property is not set up. This property must point to org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part of NetBeans IDE installation and is usually located at <netbeans_installation>/java<version>/ant/extra folder. Either open the project in the IDE and make sure CopyLibs library exists or setup the property manually. For example like this: ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar Must set JVM to use for profiling in profiler.info.jvm Must set profiler agent JVM arguments in profiler.info.jvmargs.agent Must select some files in the IDE or set javac.includes Must select some files in the IDE or set javac.jsp.includes Must select a file in the IDE or set jsp.includes Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable. Launching ${browse.url} Must select one file in the IDE or set run.class Must select one file in the IDE or set run.class Must select one file in the IDE or set debug.class Must select one file in the IDE or set debug.class Must set fix.includes This target only works when run from inside the NetBeans IDE. Must select some files in the IDE or set javac.includes Some tests failed; see details above. Must select some files in the IDE or set test.includes Some tests failed; see details above. Must select some files in the IDE or set test.class Must select some method in the IDE or set test.method Some tests failed; see details above. Must select one file in the IDE or set test.class Must select one file in the IDE or set test.class Must select some method in the IDE or set test.method

EMAQ1/nbproject/genfiles.properties

build.xml.data.CRC32=a727e4a0 build.xml.script.CRC32=5c7f36dd [email protected] # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=a727e4a0 nbproject/build-impl.xml.script.CRC32=242bca95 nbproject/[email protected] nbproject/jaxws-build.xml.stylesheet.CRC32=6608c2cf

EMAQ1/nbproject/jax-ws.xml

EMAQ1/nbproject/project.properties

annotation.processing.enabled=true annotation.processing.enabled.in.editor=true annotation.processing.processors.list= annotation.processing.run.all.processors=true annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output auxiliary.org-netbeans-modules-projectapi.jsf_2e_language=Facelets build.classes.dir=${build.web.dir}/WEB-INF/classes build.classes.excludes=**/*.java,**/*.form build.dir=build build.generated.dir=${build.dir}/generated build.generated.sources.dir=${build.dir}/generated-sources build.test.classes.dir=${build.dir}/test/classes build.test.results.dir=${build.dir}/test/results build.web.dir=${build.dir}/web build.web.excludes=${build.classes.excludes} client.urlPart=/credentialsForm.xhtml compile.jsps=false conf.dir=${source.root}/conf debug.classpath=${build.classes.dir}:${javac.classpath} debug.test.classpath=\ ${run.test.classpath} display.browser=true # Files to be excluded from distribution war dist.archive.excludes= dist.dir=dist dist.ear.war=${dist.dir}/${war.ear.name} dist.javadoc.dir=${dist.dir}/javadoc dist.war=${dist.dir}/${war.name} endorsed.classpath=\ ${libs.javaee-endorsed-api-7.0.classpath} excludes= includes=** j2ee.compile.on.save=true j2ee.copy.static.files.on.save=true j2ee.deploy.on.save=true j2ee.platform=1.7-web j2ee.platform.classpath=${j2ee.server.home}/modules/endorsed/javax.annotation-api.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/bean-validator.jar:${j2ee.server.home}/modules/cdi-api.jar:${j2ee.server.home}/modules/javax.batch-api.jar:${j2ee.server.home}/modules/javax.ejb-api.jar:${j2ee.server.home}/modules/javax.el.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent.jar:${j2ee.server.home}/modules/javax.enterprise.deploy-api.jar:${j2ee.server.home}/modules/javax.faces.jar:${j2ee.server.home}/modules/javax.inject.jar:${j2ee.server.home}/modules/javax.interceptor-api.jar:${j2ee.server.home}/modules/javax.jms-api.jar:${j2ee.server.home}/modules/javax.json.jar:${j2ee.server.home}/modules/javax.mail.jar:${j2ee.server.home}/modules/javax.management.j2ee-api.jar:${j2ee.server.home}/modules/javax.persistence.jar:${j2ee.server.home}/modules/javax.resource-api.jar:${j2ee.server.home}/modules/javax.security.auth.message-api.jar:${j2ee.server.home}/modules/javax.security.jacc-api.jar:${j2ee.server.home}/modules/javax.servlet-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl.jar:${j2ee.server.home}/modules/javax.transaction-api.jar:${j2ee.server.home}/modules/javax.websocket-api.jar:${j2ee.server.home}/modules/javax.ws.rs-api.jar:${j2ee.server.home}/modules/javax.xml.registry-api.jar:${j2ee.server.home}/modules/javax.xml.rpc-api.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/weld-osgi-bundle.jar:${j2ee.server.middleware}/mq/lib/jaxm-api.jar j2ee.platform.embeddableejb.classpath=${j2ee.server.home}/lib/embedded/glassfish-embedded-static-shell.jar j2ee.platform.wscompile.classpath=${j2ee.server.home}/modules/webservices-osgi.jar j2ee.platform.wsgen.classpath=${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar j2ee.platform.wsimport.classpath=${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar j2ee.platform.wsit.classpath= j2ee.server.type=gfv3ee6 jar.compress=false javac.classpath= # Space-separated list of extra javac options javac.compilerargs= javac.debug=true javac.deprecation=false javac.processorpath=\ ${javac.classpath} javac.source=1.8 javac.target=1.8 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir} javac.test.processorpath=\ ${javac.test.classpath} javadoc.additionalparam= javadoc.author=false javadoc.encoding=${source.encoding} javadoc.noindex=false javadoc.nonavbar=false javadoc.notree=false javadoc.preview=true javadoc.private=false javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= lib.dir=${web.docbase.dir}/WEB-INF/lib persistence.xml.dir=${conf.dir} platform.active=default_platform resource.dir=setup run.test.classpath=\ ${javac.test.classpath}:\ ${build.test.classes.dir} # Space-separated list of JVM arguments used when running a class with a main method or a unit test # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value): runmain.jvmargs= source.encoding=UTF-8 source.root=src src.dir=${source.root}/java test.src.dir=test war.content.additional= war.ear.name=${war.name} war.name=EMAQ1.war web.docbase.dir=web webinf.dir=web/WEB-INF

EMAQ1/nbproject/project.xml

org.netbeans.modules.web.project EMAQ1 1.6.5

EMAQ1/src/conf/MANIFEST.MF

Manifest-Version: 1.0

EMAQ1/src/java/beans/CredentialsBean.java

EMAQ1/src/java/beans/CredentialsBean.java

/**
 * Backing bean for user's oucu and password, which is needed for
 * each interaction with the MegaMax server. The class includes a
 * method to call the GET method on the widgets REST resource.
 */
package  beans ;

import  java . io . Serializable ;
import  javax . enterprise . context . SessionScoped ;
import  javax . inject . Named ;
import  javax . json . JsonArray ;
import  javax . json . JsonObject ;
import  rest . Widgets ;
import  util . Utilities ;

/**
 * A backing bean to remember the customer's name (oucu) and password over
 * multiple requests within the same session.
 *
 *  @author  TM352
 */
@ Named
@ SessionScoped
public   class   CredentialsBean   implements   Serializable
{
    private   String  name ;
    private   String  pwd ;

    public   CredentialsBean ()
    {
    }

    public   String  getName ()
    {
       return  name ;
    }

    public   void  setName ( String  name )
    {
       this . name  =  name ;
    }

    public   String  getPwd ()
    {
       return  pwd ;
    }

    public   void  setPwd ( String  pwd )
    {
       this . pwd  =  pwd ;
    }

    /**
    * Compute a hexadecimal colour string based on an input string
    *
    *  @param  str an arbitrary string
    *  @return  a colour code for use in a web page
    */
    public   String  computeColour ( String  str )
    {
       if   ( str  ==   null )
       {
          return   "#000000" ;
       }

       String  temp  =   String . format ( "#%X" ,  str . hashCode ());
       return  temp . substring ( 0 ,   7 );
    }

    /**
    * Return a string-based HTML representation of a table containing
    * information about widgets on sale at MegaMax. Note, we assume that name
    * and pwd have been set already.
    *
    * This method constructs a rest-client object and uses it to call
    * the MegaMax API. The string response is then converted to a JsonObject and
    * interpreted based on our knowledge of the MegaMax API, using the utility
    * method prettyWidgets().
    *
    *  @return  a string containing an HTML table of widgets that we can output as
    * part of a web page *
    */
    public   String  widgetsGet ()
    {
       //Construct a rest client to access the Widgets resource
       Widgets  wclient  =   new   Widgets ();

       //Get a response from the API for the GET method as a String
       //The user's name and password are assumed to have already been set, so 
       //we just access these values here when calling the API.
       String  response  =  wclient . get_application_json ( String . class ,  name ,  pwd );

       //Convert the response to a JsonObject to allow easier manipulation
       JsonObject  jo  =   Utilities . getAsJsonObject ( response );

       String  status  =  jo . getString ( "status" );

       //Note that any println statements go the GlassFish Server console in NetBeans
       System . out . println ( "Status was "   +  jo . getString ( "status" ));

       String  result ;

       //See if there will be data to process
       if   ( Utilities . statusOkay ( status ))
       {
          JsonArray  data  =  jo . getJsonArray ( "data" );
          System . out . println ( "Data was "   +  jo . getJsonArray ( "data" ));
         result  =   Utilities . prettyWidgets ( data );
       }
       else   //no data to process
       {
          System . out . println ( "Message was "   +  jo . getString ( "message" ));

          //In this case there is no data to process; we just return the "message" value
          //from the MegaMax server telling us what went wrong
         result  =  jo . getString ( "message" );
       }

       //It is good practice to close the rest client, to release resources
      wclient . close ();

       return  result ;
    }
}

EMAQ1/src/java/beans/OrderBean.java

EMAQ1/src/java/beans/OrderBean.java

/**
 * Backing bean for holding order and order items data, request-scoped.
 * Although latitude and longitude are not used in our web application,
 * the API requires them.
 *
 * This class includes methods to call GET and POST operations in the
 * MegaMax API.
 */
package  beans ;

import  rest . Orders ;
import  javax . enterprise . inject . Model ;
import  javax . json . JsonArray ;
import  javax . json . JsonObject ;
import  util . Utilities ;

/**
 *  @author  TM352
 */
@ Model
public   class   OrderBean
{
    //The first three attributes are for the order table
    //The clientId should be set before calling orderPost()
    private   String  clientId ;
    private   String  latitude ,  longitude ;

    //Remaining attributes are additional information for the order items
    //These fields should be set before calling orderItemsPost()   
    private   String  orderId ;   //add items to this order id
    private   String  widgetId ;
    private   String  number ;
    private   String  pence ;

    /**
    * Initial values for some of the model data. We're not using latitude and
    * longitude in this prototype, so setting these to dummy values.
    */
    public   OrderBean ()
    {
      latitude  =   "0" ;
      longitude  =   "0" ;
    }

    public   String  getLatitude ()
    {
       return  latitude ;
    }

    public   void  setLatitude ( String  latitude )
    {
       this . latitude  =  latitude ;
    }

    public   String  getLongitude ()
    {
       return  longitude ;
    }

    public   void  setLongitude ( String  longitude )
    {
       this . longitude  =  longitude ;
    }

    public   String  getOrderId ()
    {
       return  orderId ;
    }

    public   void  setOrderId ( String  orderId )
    {
       this . orderId  =  orderId ;
    }

    public   String  getWidgetId ()
    {
       return  widgetId ;
    }

    public   void  setWidgetId ( String  widgetId )
    {
       this . widgetId  =  widgetId ;
    }

    public   String  getNumber ()
    {
       return  number ;
    }

    public   void  setNumber ( String  num )
    {
       this . number  =  num ;
    }

    public   String  getPence ()
    {
       return  pence ;
    }

    public   void  setPence ( String  pence )
    {
       this . pence  =  pence ;
    }

    public   String  getClientId ()
    {
       return  clientId ;
    }

    public   void  setClientId ( String  clientId )
    {
       this . clientId  =  clientId ;
    }

    /**
    * Get a list of current orders (all order ids, client ids and dates of
    * orders) and return it as an HTML table
    *
    *  @param  oucu the user's oucu
    *  @param  password the user's password
    *  @return  HTML table of current orders for the identified user
    */
    public   String  ordersGet ( String  oucu ,   String  password )
    {
       Orders  oclient  =   new   Orders ();
       String  response  =  oclient . get_application_json ( String . class ,  oucu ,  password );

       System . out . println ( "orders get Response was "   +  response );

       JsonObject  jo  =   Utilities . getAsJsonObject ( response );
       String  status  =  jo . getString ( "status" );
       JsonArray  data  =  jo . getJsonArray ( "data" );

       System . out . println ( "Status was "   +  jo . getString ( "status" ));
       System . out . println ( "Data was "   +  jo . getJsonArray ( "data" ));

       String  result ;

       if   ( Utilities . statusOkay ( status ))
       {
         result  =   Utilities . prettyOrders ( data );
       }
       else
       {
          System . out . println ( "Message was "   +  jo . getString ( "message" ));

         result  =  jo . getString ( "message" );
       }

       return  result ;
    }

    /**
    * Get a list of current orders (all order ids, client ids and dates of
    * orders)
    *
    *  @param  oucu the user's oucu
    *  @param  password the user's password
    *  @return  an HTML table of the user's current orders
    */
    public   String  orderItemsGet ( String  oucu ,   String  password )
    {
       return   "EMA Q1 (f) orderItemsGet - To be completed" ;
    }

    /**
    * POST a new order - oucu and password from login bean, Client id from order
    * form.
    *
    *  @param  oucu the user's oucu
    *  @param  password the user's password
    *  @return  a JSON status string from the MegaMax server
    */
    public   String  orderPost ( String  oucu ,   String  password )
    {
       return   "EMA Q1(d) orderPost method in OrderBean - To be completed" ;
    }

    /**
    * POST items to an order - oucu and password from login bean, other
    * parameters from the bean state. Before calling this method, an order must
    * have been created already and items must have been added to the order.
    *
    *  @param  oucu the user's oucu
    *  @param  password the user's password
    *  @return  a JSON status string from the MegaMax server
    */
    public   String  orderItemsPost ( String  oucu ,   String  password )
    {
       return   "EMA Q1(e) orderItemsPost method in OrderBean - To be completed" ;
    }

}

EMAQ1/src/java/rest/Orders.java

EMAQ1/src/java/rest/Orders.java

/*
 * RESTful client class for the orders resource in the MegaMax API
 */
package  rest ;

import  javax . ws . rs . ClientErrorException ;
import  javax . ws . rs . client . Client ;
import  javax . ws . rs . client . WebTarget ;
import  javax . ws . rs . core . Form ;

/**
 * Jersey REST client generated for REST resource:EMA_API [orders]<br>
 * USAGE:
 * <pre>
 *        Orders client = new Orders();
 *        Object response = client.XXX(...);
 *        // do whatever with response
 *        client.close();
 * </pre>
 *
 *  @author  ad2472
 */
public   class   Orders
{
    private   WebTarget  webTarget ;
    private   Client  client ;
    private   static   final   String  BASE_URI  =   "http://137.108.92.9/openstack/api/" ;

    public   Orders ()
    {
      client  =  javax . ws . rs . client . ClientBuilder . newClient ();
      webTarget  =  client . target ( BASE_URI ). path ( "orders" );
    }

    /**
    *  @param  responseType Class representing the response
    *  @param  OUCU query parameter
    *  @param  password query parameter
    *  @return  response object (instance of responseType class)
    */
    public   < T >  T get_application_json ( Class < T >  responseType ,   String  OUCU ,   String  password )   throws   ClientErrorException
    {
       String []  queryParamNames  =   new   String []{ "OUCU" ,   "password" };
       String []  queryParamValues  =   new   String []{ OUCU ,  password };
       ;
      javax . ws . rs . core . Form  form  =  getQueryOrFormParams ( queryParamNames ,  queryParamValues );
      javax . ws . rs . core . MultivaluedMap < String ,   String >  map  =  form . asMap ();
       for   ( java . util . Map . Entry < String ,  java . util . List < String >>  entry  :  map . entrySet ())
       {
         java . util . List < String >  list  =  entry . getValue ();
          String []  values  =  list . toArray ( new   String [ list . size ()]);
         webTarget  =  webTarget . queryParam ( entry . getKey (),   ( Object [])  values );
       }
       return  webTarget . request ( javax . ws . rs . core . MediaType . APPLICATION_JSON ). get ( responseType );
    }

    /**
    *  @param  responseType Class representing the response
    *  @param  OUCU form parameter
    *  @param  password form parameter
    *  @param  client_id form parameter
    *  @param  latitude form parameter
    *  @param  longitude form parameter
    *  @return  response object (instance of responseType class)
    */
    public   < T >  T post_application_x_www_form_urlencoded ( Class < T >  responseType ,   String  OUCU ,   String  password ,   String  client_id ,   String  latitude ,   String  longitude )   throws   ClientErrorException
    {
       String []  formParamNames  =   new   String []{ "OUCU" ,   "password" ,   "client_id" ,   "latitude" ,   "longitude" };
       String []  formParamValues  =   new   String []{ OUCU ,  password ,  client_id ,  latitude ,  longitude };
       return  webTarget . request ( javax . ws . rs . core . MediaType . APPLICATION_FORM_URLENCODED ). post ( javax . ws . rs . client . Entity . form ( getQueryOrFormParams ( formParamNames ,  formParamValues )),  responseType );
    }

    private   Form  getQueryOrFormParams ( String []  paramNames ,   String []  paramValues )
    {
       Form  form  =   new  javax . ws . rs . core . Form ();
       for   ( int  i  =   0 ;  i  <  paramNames . length ;  i ++ )
       {
          if   ( paramValues [ i ]   !=   null )
          {
            form  =  form . param ( paramNames [ i ],  paramValues [ i ]);
          }
       }
       return  form ;
    }

    public   void  close ()
    {
      client . close ();
    }
   
}

EMAQ1/src/java/rest/Widgets.java

EMAQ1/src/java/rest/Widgets.java

/*
 * RESTful client class for the widgets resource in the MegaMax API.
 */
package  rest ;

import  javax . ws . rs . ClientErrorException ;
import  javax . ws . rs . client . Client ;
import  javax . ws . rs . client . WebTarget ;
import  javax . ws . rs . core . Form ;

/**
 * Jersey REST client generated for REST resource:EMA_API [widgets]<br>
 * USAGE:
 * <pre>
 *        Widgets client = new Widgets();
 *        Object response = client.XXX(...);
 *        // do whatever with response
 *        client.close();
 * </pre>
 *
 *  @author  ad2472
 */
public   class   Widgets
{
    private   WebTarget  webTarget ;
    private   Client  client ;
    private   static   final   String  BASE_URI  =   "http://137.108.92.9/openstack/api/" ;

    public   Widgets ()
    {
      client  =  javax . ws . rs . client . ClientBuilder . newClient ();
      webTarget  =  client . target ( BASE_URI ). path ( "widgets" );
    }

    /**
    * Implements GET for this resource
    *  @param  responseType Class representing the response - use String.class
    *  @param  OUCU query parameter
    *  @param  password query parameter
    *  @return  response object (instance of responseType class)
    */
    public   < T >  T get_application_json ( Class < T >  responseType ,   String  OUCU ,   String  password )   throws   ClientErrorException
    {
       String []  queryParamNames  =   new   String []{ "OUCU" ,   "password" };
       String []  queryParamValues  =   new   String []{ OUCU ,  password };
       ;
      javax . ws . rs . core . Form  form  =  getQueryOrFormParams ( queryParamNames ,  queryParamValues );
      javax . ws . rs . core . MultivaluedMap < String ,   String >  map  =  form . asMap ();
       for   ( java . util . Map . Entry < String ,  java . util . List < String >>  entry  :  map . entrySet ())
       {
         java . util . List < String >  list  =  entry . getValue ();
          String []  values  =  list . toArray ( new   String [ list . size ()]);
         webTarget  =  webTarget . queryParam ( entry . getKey (),   ( Object [])  values );
       }
       return  webTarget . request ( javax . ws . rs . core . MediaType . APPLICATION_JSON ). get ( responseType );
    }

    private   Form  getQueryOrFormParams ( String []  paramNames ,   String []  paramValues )
    {
       Form  form  =   new  javax . ws . rs . core . Form ();
       for   ( int  i  =   0 ;  i  <  paramNames . length ;  i ++ )
       {
          if   ( paramValues [ i ]   !=   null )
          {
            form  =  form . param ( paramNames [ i ],  paramValues [ i ]);
          }
       }
       return  form ;
    }

    public   void  close ()
    {
      client . close ();
    }
   
}

EMAQ1/src/java/util/Utilities.java

EMAQ1/src/java/util/Utilities.java

/**
 * JSON processing utilities, supported by classes in the javax.json package
 * as part of Java EE. There are also many third party libraries that you can
 * use, such as google-gson.
 *
 * The methods prettyOrders and prettyWidgets illustrate how to build and HTML
 * table from a JsonArray.
 *
 */
package  util ;

import  java . io . StringReader ;
import  javax . json . Json ;
import  javax . json . JsonArray ;
import  javax . json . JsonObject ;
import  javax . json . JsonValue ;

/**
 *  @author  tm352
 */
public   class   Utilities
{
    /**
    * Convert a string representation of a JSON object into a JsonObject.
    *
    *  @param  stringjson A string representation of a JSON response
    *  @return  stringjson converted to javax.json.JsonObject
    */
    public   static   JsonObject  getAsJsonObject ( String  stringjson )
    {
       return   Json . createReader ( new   StringReader ( stringjson )). readObject ();
    }

    /**
    * A utility method to convert a JsonArray to an HTML table. We need to know
    * what the object names are in the array, so we can get their values. One
    * way of finding out is to obtain the keySet()
    *
    *  @param  widgets a JsonArray containing JsonObjects representing rows of the
    * Widgets table on the MegaMax server.
    *
    *  @return  HTML table of widgets details, as a string. This table loads
    * images of widgets using their URLS.
    */
    public   static   String  prettyWidgets ( JsonArray  widgets )
    {
       //opening tag for table - for efficiency we use a StringBuilder      
       StringBuilder  temp  =   new   StringBuilder ( "<table>" );

       //formatting strings for the header of the table and rows. 
       //Each %s is to replaced by a string relating to widgets
       String  header  =   "<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>" ;
       String  row ;

       //row= "<tr><td>%s</td><td>%s</td><td>%s</td></tr>";//plain text row format
       //embedded image version of row format
      row  =   "<tr><td>%s</td><td><img src='%s' alt='Widget image'></td><td>%s</td><td>%s</td></tr>" ;

       //add the header to the table string
      temp . append (( String . format ( header ,   "id" ,   "url" , "description" ,   "pence" )));

       //iterate over the widgets array, formatting each object in the array
       //as a row in our html table
       for   ( int  i  =   0 ;  i  <  widgets . size ();  i ++ )
       {
          //each item in the array is a JsonObject. Get the next object.
          JsonObject  jo  =   ( JsonObject )  widgets . get ( i );

          //print out the names of values in this object
          //System.out.println("keys " + jo.keySet());
          //Each JsonObject represents a row of the table and contains some JsonValues.
          //We get the values, using their known names, and convert them to strings.

          String  id  =  jo . getString ( "id" );
          String  url  =  jo . getString ( "url" );
          String  descrip  =  jo . getString ( "description" );
          String  pence  =  jo . getString ( "pence_price" );

          //And now we can append the next row to the html table
         temp . append ( String . format ( row ,  id ,  url ,  descrip ,  pence ));
       }

       //finally we end the table and return the result as a string
      temp . append ( "</table>" );

       return  temp . toString ();
    }

    /**
    * Prettify Orders data
    *
    *  @param  orders JsonArray of orders
    *  @return  HTML table of orders data, as a String
    */
    public   static   String  prettyOrders ( JsonArray  orders )
    {
       StringBuilder  temp  =   new   StringBuilder ( "<table>" );

       String  header  =   "<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>" ;
       String  row  =   "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" ;

      temp . append ( String . format ( header ,   "order id" ,   "client_id" ,   "date" ,   "latitude" ,   "longitude" ));

       System . out . println ( temp . toString ());

       for   ( int  i  =   0 ;  i  <  orders . size ();  i ++ )
       {
          JsonObject  jo  =   ( JsonObject )  orders . get ( i );

          System . out . println ( "keys "   +  jo . keySet ());

          String  id  =  jo . getString ( "id" );
          String  client_id  =  jo . getString ( "client_id" );
          String  date  =  jo . getString ( "date" );
          String  lat  =  jo . getString ( "latitude" );
          String  lon  =  jo . getString ( "longitude" );

         temp . append ( String . format ( row ,  id ,  client_id ,  date ,  lat ,  lon ));

          System . out . println ( String . format ( row ,  id ,  client_id ,  date ,  lat ,  lon ));
       }

      temp . append ( "</table>" );

       return  temp . toString ();
    }

    /**
    * JsonObjects have many methods to tell you about them. A JSON value is one
    * of the following: an object (JsonObject), an array (JsonArray), a number
    * (JsonNumber), a string (JsonString), true (JsonValue.TRUE), false
    * (JsonValue.FALSE), or null (JsonValue.NULL). These are all immutable.
    *
    *  @param  obj JsonObject you want to know more about
    *
    */
    public   static   void  tellMeAbout ( JsonObject  obj )
    {
       System . out . println ( "\nAbout your object ......................................" );

       //Iterate over the keys (names)      
       for   ( String  name  :  obj . keySet ())
       {
          //inside a JsonObject, the value is a JsonValue
          JsonValue  jv  =  obj . get ( name );
          System . out . printf ( "%-20s is type %-10s with value %s%n" ,  name ,  jv . getValueType (),  jv );
       }
    }

    /**
    * Iterate over a JSON array, printing out information about it.
    *
    *  @param  ar the JsonArray you want to know more about
    */
    public   static   void  tellMeAbout ( JsonArray  ar )
    {
       System . out . println ( "\nAbout your array ......................................" );

       if   ( ar . size ()   ==   0 )
       {
          System . out . println ( "The array was empty." );
       }
       else
       {
          //Iterate over the values    
          for   ( int  i  =   0 ;  i  <  ar . size ();  i ++ )
          {
             JsonValue  jv  =   ( JsonValue )  ar . get ( i );
             System . out . printf ( "At index %s is %8s  %-10s%n" ,  i ,  jv . getValueType (),  jv );
          }
       }
    }

    /**
    * Check for success or failure of MegaMax API call. Status "error" indicates
    * an issue with completing the API operation, e.g. because an invalid user
    * name or password was provided. Status "failed" is used when the request is
    * valid but inappropriate for the data on the server, e.g. because a
    * provided client_id did not match one known by the server.
    *
    *  @param  status a String representing the status value in a response from
    * the MegaMax API
    *  @return  true if the status contains 'error' or 'fail', otherwise false.
    */
    public   static   boolean  statusOkay ( String  status )
    {
       if   ( status  ==   null )
       {
          return   false ;
       }

       //status includes quotes, so use 'contains'
       return   ! ( status . contains ( "fail" )   ||  status . contains ( "error" ));
    }

}

EMAQ1/web/credentialsForm.xhtml

Local credentials page

Your credentials can be seen on the openstack server

Provide your credentials

EMAQ1/web/options.xhtml

MegaMax API Options

User #{credentialsBean.name}

Bear in mind that you do not log in to the MegaMax server, so the credentials you provided have not been checked.

1. View the available widgets

2. View orders

3. Make an order

4. Go back to the credentials page

EMAQ1/web/orderForm.xhtml

Create a new order or add items to order

Start a new order - Complete for Q1 part (c) Add items to an existing order - Complete for Q1 part (c)

Current orders (for reference)

Order list

Order Items list

Go back to the options page

EMAQ1/web/orderItemsPost.xhtml

Response to your order from MegaMax

For confirmation, the following is your current order state

Orders List

Order Items list

Go back to the orders page

Go back to the options page

EMAQ1/web/orderPost.xhtml

Response to your order from MegaMax

For confirmation, the following is your current order state

Orders List

Order Items list

Go back to the orders page

Go back to the options page

EMAQ1/web/ordersGet.xhtml

#{credentialsBean.name}'s orders list

Orders list

Order Items list

Go back to the options page

EMAQ1/web/resources/css/theme.css

/* CSS for this project Created on : 23-Jan-2017, 14:17:29 Author : TM352 */ .megamax{ font-family:cursive; font-style: italic; color: salmon; } table { table-layout: auto; width: 40%; border: 1px solid black; } th { background-color: #4CAF50; color: white; padding: 10px; text-align: left; border: 1px solid black; } td{ padding: 10px; text-align: left; border: 1px solid black; } h1 { color: maroon; font-family:verdana; } h2 { color: brown; font-family:verdana; font-style: italic; } /* all legends get a colour and size */ legend { color: darkviolet; font-size: x-large; } /* all fieldsets get a background colour! */ fieldset { background-color: lightblue; } /* all labels are right-aligned, amongst other things */ label{ display: inline-block; float: left; clear: left; width: 200px; padding-right:10px; text-align: right; } /* all inputs and textareas have the same width and are left-aligned (but see below for exceptions) */ input, textarea, select { padding: 9px; width: 100px; display: inline-block; float: left; } /* all inputs whose type is checkbox don't get the larger width */ input[type=checkbox]{ width:auto }

EMAQ1/web/WEB-INF/web.xml

javax.faces.PROJECT_STAGE Development Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet /faces/* *.xhtml 30 greeting.xhtml

EMAQ1/web/WEB-INF/web.xml.bak

javax.faces.PROJECT_STAGE Development Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet /faces/* *.xhtml 30 faces/index.xhtml index.html 403 /error403.html

EMAQ1/web/widgetsGet.xhtml

Widgets List

User #{credentialsBean.name}

Go back to the options page

Go back to the credentials page

EMA_API.wadl

<application xmlns="http://wadl.dev.java.net/2009/02" xmlns:ema="http://137.108.92.9/openstack/EMA_API_V9.wadl" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <resources base="http://137.108.92.9/openstack/api/"> <resource path="clients"> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "name", "type": "string" }, { "name": "address", "type": "string" }, { "name": "phone", "type": "string" }, { "name": "email", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> <resource path="clients/{id}"> <param name="id" style="template" type="xs:string"/> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "name", "type": "string" }, { "name": "address", "type": "string" }, { "name": "phone", "type": "string" }, { "name": "email", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> <resource path="order_items"> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "order_id", "type": "string" }, { "name": "widget_id", "type": "string" }, { "name": "number", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="POST"> <request> <representation mediaType="application/x-www-form-urlencoded"> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> <param name="order_id" style="query" type="xs:string"/> <param name="widget_id" style="query" type="xs:string"/> <param name="number" style="query" type="xs:string"/> <param name="pence_price" style="query" type="xs:string"/> </representation> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "order_id", "type": "string" }, { "name": "widget_id", "type": "string" }, { "name": "number", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> <resource path="order_items/{id}"> <param name="id" style="template" type="xs:string"/> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "order_id", "type": "string" }, { "name": "widget_id", "type": "string" }, { "name": "number", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="PUT"> <request> <representation mediaType="application/x-www-form-urlencoded"> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> <param name="order_id" style="query" type="xs:string"/> <param name="widget_id" style="query" type="xs:string"/> <param name="number" style="query" type="xs:string"/> <param name="pence_price" style="query" type="xs:string"/> </representation> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "order_id", "type": "string" }, { "name": "widget_id", "type": "string" }, { "name": "number", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="DELETE"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" } } } ]]> </representation> </response> </method> </resource> <resource path="orders"> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "client", "type": "string" }, { "name": "date", "type": "string" }, { "name": "latitude", "type": "string" }, { "name": "longitude", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="POST"> <request> <representation mediaType="application/x-www-form-urlencoded"> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> <param name="client_id" style="query" type="xs:string"/> <param name="latitude" style="query" type="xs:string"/> <param name="longitude" style="query" type="xs:string"/> </representation> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "client", "type": "string" }, { "name": "date", "type": "string" }, { "name": "latitude", "type": "string" }, { "name": "longitude", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> <resource path="orders/{id}"> <param name="id" style="template" type="xs:string"/> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "client", "type": "string" }, { "name": "date", "type": "string" }, { "name": "latitude", "type": "string" }, { "name": "longitude", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="PUT"> <request> <representation mediaType="application/x-www-form-urlencoded"> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> <param name="client_id" style="query" type="xs:string"/> <param name="latitude" style="query" type="xs:string"/> <param name="longitude" style="query" type="xs:string"/> </representation> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "client", "type": "string" }, { "name": "date", "type": "string" }, ,{ "name": "latitude", "type": "string" }, { "name": "longitude", "type": "string" } ] } } ]]> </representation> </response> </method> <method name="DELETE"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" } } } ]]> </representation> </response> </method> </resource> <resource path="widgets"> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "url", "type": "string" }, { "name": "description", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> <resource path="widgets/{id}"> <param name="id" style="template" type="xs:string"/> <method name="GET"> <request> <param name="OUCU" style="query" type="xs:string"/> <param name="password" style="query" type="xs:string"/> </request> <response status="200"> <representation mediaType="application/json"> <![CDATA[ { "resulttype": "ResultsRoot", { "name": "ResultsRoot", "type": "object", "fields": [ { "name": "status", "type": "string" }, { "name": "data", "type": "array", "itemtype": "ResultEntry" } }, { "name": "ResultEntry", "type": "object", "fields": [ { "name": "id", "type": "string" }, { "name": "url", "type": "string" }, { "name": "description", "type": "string" }, { "name": "pence_price", "type": "string" } ] } } ]]> </representation> </response> </method> </resource> </resources> </application>