Web API and simple mobile app
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 credentialsEMAQ1/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.
2. View orders
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
EMAQ1/web/orderItemsPost.xhtml
Response to your order from MegaMax
For confirmation, the following is your current order state
Orders List
Order Items list
EMAQ1/web/orderPost.xhtml
Response to your order from MegaMax
For confirmation, the following is your current order state
Orders List
Order Items list
EMAQ1/web/ordersGet.xhtml
#{credentialsBean.name}'s orders list
Orders list
Order Items list
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}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>